mcpField
G
godot-combat-system

godot-combat-system

github.com/thedivergentai开发917460 次安装2 周前更新
代码仓库

关于 godot-combat-system

面向 Godot 开发者的战斗系统技能,涵盖类型化伤害数据、生命值组件及攻击箱/受击箱模式。内容强调安全的物理处理与组件边界,并提供相关战斗功能的实现指引。

主要功能

  1. 01类型化 DamageData 资源与伤害标记
  2. 02带无敌帧和信号的生命值处理
  3. 03攻击箱与受击箱连接
  4. 04范围伤害、受击停顿及战斗模式
  5. 05可选连击、遥测与调试工具

适用场景

  1. 01构建近战或投射物战斗
  2. 02添加生命值、护甲伤害计算和无敌帧
  3. 03实现范围攻击与受击停顿
  4. 04添加连击记录或战斗遥测

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/thedivergentai/game-design-agentic-skills --skill godot-combat-system

安装后在 Claude Code 中输入/godot-combat-system确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
elite-combat-patterns.md
migration-notes.md
scripts/
combat_logger.gd
combat_state.gd
combat_system_patterns.gd
combo_system.gd
damage_data.gd
damage_popup.gd
health_component.gd
hitbox_component.gd
hitbox_hurtbox.gd
hitbox_visualizer.gd
networked_damage_manager.gd

详细介绍

绝对不要做

  • 绝对不要直接引用伤害(target.health -= 10)——这会绕过护甲、抗性和无敌帧。始终使用 DamageData + HealthComponent.take_damage。
  • 绝对不要忘记无敌帧(i-frames)——否则多段命中形状会在每个物理帧都触发。成功命中后,务必应用一个短暂的无敌窗口。
  • 绝对不要让命中框永久处于激活状态——使用 AnimationPlayer 轨道或定时代码启用/禁用;永久监测会导致幽灵命中。
  • 绝对不要使用分组筛选基于物理的命中——优先使用碰撞层/掩码(C++ 筛选器)。分组用于次要逻辑,而不是物理门控。
  • 绝对不要在没有 DamageData 对象的情况下发出伤害信号——原始数值会丢失类型、来源、击退和暴击上下文。
  • 绝对不要使用原始字符串表示元素伤害类型——使用 enum / @export_flags 位字段。字符串 "physical" 违反了此技能自身的约定。
  • 绝对不要用 try/catch 验证目标——GDScript 没有异常。使用 has_method(&"take_damage") / is 检查。
  • 绝对不要使用 OS.delay_msec() 硬编码受击硬直——这会阻塞 OS 线程。使用补间 / Engine.time_scale + ignore_time_scale 定时器。
  • 绝对不要在 _process() 中应用 RigidBody 冲量——使用 _physics_process / _integrate_forces。
  • 绝对不要在 Player 脚本中耦合 UI 生命条——发出 health_changed 信号;由 HUD 监听。
  • 绝对不要让已死亡实体上的 CollisionShapes 保持激活——死亡时调用 set_deferred("disabled", true)。
  • 绝对不要对 CollisionShapes 使用非等比缩放——缩放形状资源(radius、size),而不是不均匀地缩放节点变换。
  • 绝对不要使用实例化的 Nodes 存储基础战斗属性——优先使用 Resource / RefCounted 容器;每个实例都调用 duplicate()。
  • 绝对不要在高频状态名称中使用普通字符串——优先使用 StringName(&"attacking")。
  • 绝对不要忘记对共享的 Resource 属性调用 duplicate()——共享模板 = 共享生命值池。

黄金路径(强制)

  1. damage_data.gd — 带有伤害类型 enum / 标志位的类型化 DamageData Resource(不含 String 元素)。
  2. health_component.gd — take_damage + 无敌帧门控 + health_changed / died 信号。
  3. hitbox_hurtbox.gd / hitbox_component.gd — Area 将命中传递给受击框。
  4. combat_system_patterns.gd — 鸭子类型、受击停顿、无节点 AoE、帧同步。

不要在场景中重新内联 Hitbox/Health/Combo/Ability 教程。将能力路由到 godot-ability-system;按照 godot-composition 组合组件;通过 godot-state-machine-advanced 实现 FSM。

决策树

任务加载不要加载
定义伤害载荷damage_data.gdString damage_type 字段
HP + 无敌帧health_component.gd直接使用 health -= n
近战/投射物体积hitbox_hurtbox.gd / hitbox_component.gd永久监测的 Areas
AoE / 受击停顿 / 鸭子类型combat_system_patterns.gd每个 tick 都生成临时 Areas
能力冷却 / 技能栏godot-ability-system在此处内联冗长的 AbilityManager 教程
连击缓冲godot-input-handling + 状态机在 _input 中嵌入命中逻辑

伤害类型约定(与“绝对不要做”保持一致)

# 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

命中框必须传递 DamageData(或使用相同标志位构建的等效 AttackData),绝不能传递 "Physical" 字符串。

可用脚本

精英级增量改进(保持简短)

遥测、网络命中、连击以及移出的内嵌教程均必需:elite-combat-patterns.md。首次实现 DamageData + HealthComponent 时不要加载。

参考

渐进式披露: 仅查阅你要实现的 API 对应的官方文档(Areas、层/遮罩、Resources、信号、计时器、动画命中窗口)。接入相邻系统时再打开相关技能——不要预先加载整个技能网络。

官方文档
  • 使用 Area2D — Hitbox/hurtbox 战斗使用 Area 重叠检测(area_entered / monitoring),而非 CharacterBody 移动查询。
  • 物理学简介 — 命中筛选优先使用碰撞层/遮罩;分组速度较慢,不能替代高频战斗中的物理遮罩。
  • Area2D — 2D 命中体积:用于队伍/阵营筛选的 monitoring/monitorable、area_entered 和层/遮罩位。
  • Area3D — 3D HitboxComponent / hurtbox 体积使用相同的 Area 重叠模型,并采用 3D 层和形状。
  • CollisionShape2D — 使用 set_deferred("disabled", …) 启用/禁用攻击形状,避免在物理步进期间修改物理服务器;切勿对节点进行非均匀缩放。
  • PhysicsShapeQueryParameters3D — 使用 PhysicsDirectSpaceState3D 上的 intersect_shape 实现无需生成临时 Area 节点的无节点 AoE/爆炸效果。
  • AnimationPlayer — 通过动画轨道(或方法调用)控制 hitbox 的生效时段,避免攻击持续监测。
  • 资源 — 将 DamageData / 战斗属性作为数据(Resource / RefCounted)保存;为每个实例 duplicate() 共享模板,避免敌人共用一个生命值池。
  • 使用信号 — 发出 health_changed / died / 伤害事件,让 HUD 和 VFX 通过订阅接收信息,而不将生命条逻辑耦合到玩家脚本中。
  • SceneTreeTimer — 在 Engine.time_scale = 0 后进行受击停顿,必须使用 create_timer(..., ignore_time_scale=true),否则解冻计时器会随世界一起冻结。
  • Tween — 可中断的受击硬直/闪光 VFX:连续受击时,应终止并重新创建 tween,而不是叠加并行闪光动画。
  • 高级多人游戏 — 权威伤害处理:客户端请求命中;服务器通过 @rpc 验证并确认后,再应用 take_damage。
相关技能
前置条件
  • godot-2d-physics — Area 层/遮罩、延迟禁用 CollisionShape2D 和空间查询,是 hitbox/hurtbox 筛选所依赖的物理基础。
  • godot-signal-architecture — 伤害、生命值和死亡信号需要明确归属,确保战斗组件与 UI 和 AI 监听器保持解耦。
  • godot-composition — 优先使用 HealthComponent / HitboxComponent 子节点,而不是把战斗逻辑塞进单体 Character 脚本。
  • godot-resource-data-patterns — DamageData、元素标记和战斗属性应存放在 Resource/RefCounted 数据中,并在生成时安全地调用 duplicate()。
配套内容
  • godot-ability-system — 技能会进入本技能的伤害/目标选择流水线;请将技能元数据与 DamageData 分开存放。
  • godot-rpg-stats — 护甲、抗性、暴击几率和修正器叠加会在写入生命值前馈入 take_damage。
  • godot-animation-player — 攻击动画负责连招的判定框启用窗口、取消帧和恢复锁定。
  • godot-state-machine-advanced — IDLE/ATTACKING/BLOCKING/STUNNED 战斗状态应属于负责控制 can_act 的角色 FSM,而不是杂乱的临时布尔变量。
  • godot-input-handling — 连招缓冲和攻击动作应通过动作映射调用战斗/连招系统,而不是在输入回调中嵌入命中逻辑。
下游/使用方
  • godot-monte-carlo-balancer — 在 DamageData、无敌帧、冷却时间和暴击曲线都可调后,通过蒙特卡洛模拟验证 DPS/TTK 区间,再发布难度设置。
  • godot-multiplayer-networking — 命中预测、延迟补偿和权限检查基于 DamageData 与服务端验证 RPC 的拆分方案构建。
  • godot-genre-action-rpg — 动作 RPG 战斗循环基于本技能,组合判定框、技能、属性和成长系统等类型特有的衔接逻辑。
主入口
  • godot-master — 库路由器和镜像模块入口;发现相关技能或在编辑 Domain Skill 后同步共享脚本镜像时使用。

评论

支持 Markdown