mcpField
G
godot-combat-system

godot-combat-system

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

关于 godot-combat-system

godot-combat-system 是面向 Godot 开发者的战斗系统技能,涵盖伤害、生命值、命中框和常见战斗模式。它以类型化 DamageData 和组件化实践为核心,帮助避免常见战斗逻辑问题。

主要功能

  1. 01类型化 DamageData 资源与伤害标志
  2. 02支持伤害和无敌帧的 HealthComponent
  3. 03命中框与受击框连接方式
  4. 04范围伤害、硬直与鸭子类型模式
  5. 05可选连击、遥测和调试脚本

适用场景

  1. 01实现包含抗性和暴击信息的类型化伤害
  2. 02构建近战或投射物命中窗口
  3. 03无需临时 Area 节点实现范围攻击
  4. 04检查战斗事件或验证网络伤害

安装

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

$npx skills add https://github.com/thedivergentai/game-dev-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