godot-combat-system
Expert patterns for combat systems including hitbox/hurtbox architecture, damage calculation (DamageData class), health components, combat state mac…
它会碰到什么
这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。
技能内容
NEVER Do
- NEVER use direct damage references (
target.health -= 10) — Bypass armor, resistances, and i-frames. AlwaysDamageData+HealthComponent.take_damage. - NEVER forget invincibility frames (i-frames) — Multi-hit shapes otherwise tick every physics frame. Apply a short invuln window after a successful hit.
- NEVER keep hitboxes active permanently — Enable/disable with AnimationPlayer tracks or timed code; permanent monitoring causes ghost hits.
- NEVER use groups for physics-based hit filtering — Prefer collision layers/masks (C++ filter). Groups are secondary logic, not the physics gate.
- NEVER emit damage signals without a DamageData object — Raw numbers lose type, source, knockback, and crit context.
- NEVER use raw strings for elemental damage types — Use
enum/@export_flagsbitfields. String"physical"violates this skill’s own contract. - NEVER use try/catch to validate targets — GDScript has no exceptions. Use
has_method(&"take_damage")/ischecks. - NEVER hardcode hitstun with
OS.delay_msec()— Blocks the OS thread. Use tweens /Engine.time_scale+ignore_time_scaletimers. - NEVER apply RigidBody impulses in
_process()— Use_physics_process/_integrate_forces. - NEVER couple UI lifebars inside the Player script — Emit
health_changed; HUD listens. - NEVER leave CollisionShapes active on dead entities —
set_deferred("disabled", true)on death. - NEVER scale CollisionShapes non-uniformly — Scale the shape resource (
radius,size), not the node transform unevenly. - NEVER use instanced Nodes for base combat stats — Prefer
Resource/RefCountedcontainers;duplicate()per instance. - NEVER use standard strings for high-frequency state names — Prefer
StringName(&"attacking"). - NEVER forget
duplicate()on shared Resource stats — Shared templates = shared health pools.
Golden Path (MANDATORY)
- [damage_data.gd](scripts/damage_data.gd) — typed
DamageDataResource withenum/ flags for damage types (no String elements). - [health_component.gd](scripts/health_component.gd) —
take_damage+ i-frame gate +health_changed/diedsignals. - [hitbox_hurtbox.gd](scripts/hitbox_hurtbox.gd) / [hitbox_component.gd](scripts/hitbox_component.gd) — Area hit delivery into hurtboxes.
- [combat_system_patterns.gd](scripts/combat_system_patterns.gd) — duck-typing, hit-stop, nodeless AoE, frame sync.
Do NOT re-inline Hitbox/Health/Combo/Ability tutorials in scenes. Route abilities to godot-ability-system; compose components per godot-composition; FSMs via godot-state-machine-advanced.
Decision Tree
| Task | Load | Do NOT Load |
|------|------|-------------|
| Define damage payload | damage_data.gd | String damage_type fields |
| HP + i-frames | health_component.gd | Direct health -= n |
| Melee/projectile volumes | hitbox_hurtbox.gd / hitbox_component.gd | Permanent monitoring Areas |
| AoE / hit-stop / duck-type | combat_system_patterns.gd | Spawn temp Areas every tick |
| Ability cooldowns / skill bar | godot-ability-system | Inline AbilityManager novels here |
| Combo buffers | godot-input-handling + state machine | Embedding hit logic in _input |
Damage Type Contract (aligned with NEVER)
# From damage_data.gd — prefer this shape everywhere
enum DamageType { PHYSICAL = 1, FIRE = 2, ICE = 4, LIGHTNING = 8, POISON = 16 }
@export_flags("Physical", "Fire", "Ice", "Lightning", "Poison")
var damage_types: int = DamageType.PHYSICAL
Hitboxes must pass DamageData (or equivalent AttackData built from the same flags), never "Physical" strings.
Available Scripts
- [damage_data.gd](scripts/damage_data.gd) — MANDATORY DamageData Resource + type flags.
- [health_component.gd](scripts/health_component.gd) — MANDATORY Health + i-frames golden path.
- [hitbox_hurtbox.gd](scripts/hitbox_hurtbox.gd) — MANDATORY before Area combat wiring.
- [hitbox_component.gd](scripts/hitbox_component.gd) — 3D Area hitbox companion (flags-aligned).
- [combat_system_patterns.gd](scripts/combat_system_patterns.gd) — MANDATORY for AoE / hit-stop / duck-typing.
- [combo_system.gd](scripts/combo_system.gd) — windowed combo buffer (Do NOT Load if no combos).
- [combat_state.gd](scripts/combat_state.gd) — lightweight combat FSM gate.
- [damage_popup.gd](scripts/damage_popup.gd) — floating damage label tween (pool in production).
- [combat_logger.gd](scripts/combat_logger.gd) — batched combat telemetry JSON.
- [networked_damage_manager.gd](scripts/networked_damage_manager.gd) — server-validate damage RPC shell.
- [hitbox_visualizer.gd](scripts/hitbox_visualizer.gd) — toggle collision debug colors.
Elite Deltas (keep short)
- Combat telemetry: batch JSON flushes via [combat_logger.gd](scripts/combat_logger.gd).
- Authoritative damage: [networked_damage_manager.gd](scripts/networked_damage_manager.gd) — clients request; server validates.
- Hitbox debug: [hitbox_visualizer.gd](scripts/hitbox_visualizer.gd) +
SceneTree.debug_collisions_hint. - Combos / popups / FSM: [combo_system.gd](scripts/combo_system.gd), [damage_popup.gd](scripts/damage_popup.gd), [combat_state.gd](scripts/combat_state.gd).
> MANDATORY for telemetry, networked hits, combos, and moved inline tutorials: [elite-combat-patterns.md](references/elite-combat-patterns.md). Do NOT Load for first DamageData + HealthComponent pass.
Reference
> Progressive disclosure: Skim Official Documentation only for the APIs you are implementing (Areas, layers/masks, Resources, signals, timers, animation hit windows). Open Related Skills when wiring adjacent systems—do not preload the whole lattice.
Official Documentation
- Using Area2D — Hitbox/hurtbox combat is Area overlap detection (
area_entered/ monitoring), not CharacterBody movement queries. - Physics introduction — Prefer collision layers/masks for hit filtering; groups are slower and do not replace physics masks for high-frequency combat.
- Area2D — 2D hit volumes:
monitoring/monitorable,area_entered, and layer/mask bits for team/faction filtering. - Area3D — 3D
HitboxComponent/ hurtbox volumes use the same Area overlap model with 3D layers and shapes. - CollisionShape2D — Enable/disable attack shapes with
set_deferred("disabled", …)so the physics server is not mutated mid-step; never non-uniform-scale the node. - PhysicsShapeQueryParameters3D — Nodeless AoE/explosions via
intersect_shapeonPhysicsDirectSpaceState3Dwithout spawning temporary Area nodes. - AnimationPlayer — Drive hitbox active windows from animation tracks (or method calls) so attacks are not permanently monitoring.
- Resources — Keep
DamageData/ combat stats as data (Resource/RefCounted), andduplicate()shared templates per instance so enemies do not share one health pool. - Using signals — Emit
health_changed/died/ damage events so HUD and VFX subscribe without coupling lifebars into the player script. - SceneTreeTimer — Hit-stop after
Engine.time_scale = 0must usecreate_timer(..., ignore_time_scale=true)or the thaw timer freezes with the world. - Tween — Interruptible hitstun/flash VFX: kill and recreate tweens on consecutive hits instead of stacking parallel flash animations.
- High-level multiplayer — Authoritative damage: clients request hits; the server validates and confirms via
@rpcbefore applyingtake_damage.
Related Skills
Prerequisites
- godot-2d-physics — Area layers/masks,
CollisionShape2Ddeferred disable, and space queries are the physics substrate under hitbox/hurtbox filtering. - godot-signal-architecture — Damage, health, and death signals need clear ownership so combat components stay decoupled from UI and AI listeners.
- godot-composition — Prefer
HealthComponent/HitboxComponentchildren over baking combat into a monolithic Character script. - godot-resource-data-patterns —
DamageData, elemental flags, and combat stats belong in Resource/RefCounteddata with safeduplicate()on spawn.
Complements
- godot-ability-system — Abilities resolve into this skill’s damage/targeting pipeline; keep ability metadata separate from
DamageData. - godot-rpg-stats — Armor, resistances, crit chance, and modifier stacks feed
take_damagebefore health is written. - godot-animation-player — Attack animations own hitbox enable windows, cancel frames, and recovery locks for combos.
- godot-state-machine-advanced — IDLE/ATTACKING/BLOCKING/STUNNED combat states belong in a character FSM that gates
can_act, not ad-hoc bool soup. - godot-input-handling — Combo buffers and attack actions should call into combat/combo systems from the action map rather than embedding hit logic in input callbacks.
Downstream / consumers
- godot-monte-carlo-balancer — After DamageData, i-frames, cooldowns, and crit curves are tunable, Monte Carlo sims prove DPS/TTK bands before shipping difficulty.
- godot-multiplayer-networking — Predicted hits, lag compensation, and authority checks build on the DamageData + server-validate RPC split.
- godot-genre-action-rpg — Action-RPG combat loops assemble hitboxes, abilities, stats, and progression genre glue on top of this skill.
Master
- godot-master — Library router and mirrored module entry; use when discovering peer skills or syncing shared script mirrors after Domain Skill edits.
想直接用这个技能?
本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。