mcpField
G
godot-state-machine-advanced

godot-state-machine-advanced

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

关于 godot-state-machine-advanced

面向 Godot 开发者的状态机技能,涵盖扁平 FSM、分层状态机、下推栈和并发逻辑。它通过脚本与路由规范,帮助构建分层游戏或 AI 行为,并强调安全转换和状态生命周期管理。

主要功能

  1. 01分层状态委派
  2. 02下推状态堆栈与恢复
  3. 03转换守卫与共享上下文
  4. 04并发状态机编排
  5. 05动画与计时器同步

适用场景

  1. 01构建嵌套的移动与攻击状态
  2. 02暂停或中断游戏后恢复
  3. 03阻止无效状态转换
  4. 04协调移动与武器行为

安装

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

$npx skills add https://github.com/thedivergentai/game-dev-agentic-skills --skill godot-state-machine-advanced

安装后在 Claude Code 中输入/godot-state-machine-advanced确认已加载。

包含的文件

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

references/
hsm-implementation-cookbook.md
migration-notes.md
scripts/
hsm_animation_syncer.gd
hsm_concurrent_logic.gd
hsm_hierarchical_base.gd
hsm_logic_state.gd
hsm_pushdown_stack.gd
hsm_reentry_aware_state.gd
hsm_resource_state_loader.gd
hsm_state_context.gd
hsm_state_history_logger.gd
hsm_state_timer_component.gd
hsm_transition_guard.gd
pushdown_automaton.gd

详细介绍

可用脚本

hsm_hierarchical_base.gd

高级 HSM 基础委派器,用于将物理和输入传播到子状态。

hsm_pushdown_stack.gd

专业的下推自动机,用于堆叠可中断状态(暂停/菜单)。

hsm_state_context.gd

解耦的上下文对象模式,用于在状态之间传递持久数据。

hsm_transition_guard.gd

专家级转换验证逻辑,用于防止非法状态变更。

hsm_animation_syncer.gd

自动同步逻辑与 AnimationTree,并根据状态执行跳转逻辑。

hsm_concurrent_logic.gd

用于编排并行状态机(例如,移动 + 攻击)。

hsm_resource_state_loader.gd

使用自定义 Godot 资源(.tres)以数据驱动的方式定义状态。

hsm_reentry_aware_state.gd

处理从堆栈恢复与全新进入事件之间的差异。

hsm_state_history_logger.gd

用于跟踪状态转换历史和堆栈深度的调试环形缓冲区。

hsm_state_timer_component.gd

用于眩晕或冲刺等有限状态的自动转换组件。

必须:对于层级 / 下推 / 守卫,请阅读 hsm_hierarchical_base.gd、hsm_pushdown_stack.gd、hsm_transition_guard.gd(以及用于叶节点行为的 hsm_logic_state.gd)。

决策树 — 选择哪种状态机?

需求选择必须使用的脚本
少量互斥状态,无嵌套扁平 FSMhsm_logic_state.gd + 精简父级
嵌套子状态(移动/空中/攻击子状态)HSMhsm_hierarchical_base.gd
中断叠加状态(眩晕/菜单/对话),之后恢复下推hsm_pushdown_stack.gd + hsm_reentry_aware_state.gd
并行职责(移动 + 武器)并发hsm_concurrent_logic.gd
每个 tick 按评分选择最佳动作效用成本轮询专家模式 §3 + hsm_transition_guard.gd

绝对不要做(状态机专家规则)

层级与委派
  • 绝不要忘记向子状态传播物理/输入 — 在 HSM 中,如果未从父级的 _physics_process 调用 child.physics_update(),子状态逻辑就会失去驱动。
  • 绝不要使用过深的嵌套(>3 层) — 层级过深会造成“状态意大利面”。如果逻辑如此复杂,请考虑使用行为树或效用 AI。
转换与生命周期
  • 绝不要在调用 enter() 前未先调用 exit() — 跳过退出逻辑会使计时器、补间动画或音频循环在后台持续运行,造成资源泄漏。
  • 绝不要在转换帧期间修改状态 — 在 enter() 内重入调用 transition_to() 会导致递归崩溃。如果必须立即进行子转换,请使用 call_deferred。
  • 绝不要将状态名称硬编码为字符串 — 像 transition_to("Idel") 这样的拼写错误会造成隐蔽问题。请使用基于 class_name 的检查或常量。
架构与上下文
  • 绝不要使用全局单例存储状态数据 — 将状态耦合到 GameManager.player_health 会导致状态无法复用。请传递 Context 对象。
  • 绝不要无限推入状态 — 在下推自动机中,每次 push_state 都必须有后续处理计划(pop_state),以避免堆栈溢出。
  • 绝不要假设状态重新进入总是全新开始 — 从堆栈弹出并恢复时,通常应跳过“进入音效/视觉效果”;请使用重新进入标志。

实现 — 脚本是唯一可信来源

切勿复制内联 HierarchicalState / push_state 示例。之前的主体调用了两次 exit(),并忽略了恢复消息。

必须使用以下路径:

下推栈约定(来自脚本 — 单次退出,恢复消息):

# See hsm_pushdown_stack.gd — do not reimplement
func push_state(state_path: String, msg: Dictionary = {}) -> void: ...
func pop_state() -> void:
    # old.exit(); stack.back().enter({"is_resume": true})
    pass

专家级状态机模式

1. HSM 可视化工具(调试工具)

使用专用的 Control 节点和 _draw(),在视口中可视化当前状态栈 / 层级结构,以便立即调试 [3, 11]。

class_name HSMVisualizer extends Control
@export var state_machine: Node

func _draw() -> void:
    var font := ThemeDB.fallback_font
    var pos := Vector2(20, 20)
    # Recursively draw active state names...
    draw_string(font, pos, "Active: " + state_machine.current_state.name)
2. 基于状态的音频(解耦)

避免在状态的 enter() 方法中硬编码 audio.play()。使用监听 state_changed 的同步器,将状态名称映射到 AudioStream 资源 [12, 13]。

class_name StateAudioSyncer extends Node
@export var state_machine: Node
@export var audio_map: Dictionary # { "Jump": preload("jump.wav") }

func _ready() -> void:
    state_machine.state_changed.connect(_on_state_changed)

func _on_state_changed(_old, new_state: Node):
    if audio_map.has(new_state.name):
        $AudioPlayer.stream = audio_map[new_state.name]
        $AudioPlayer.play()
3. 转换成本(效用 AI)

允许状态根据上下文评估自身的“权重”。StateMachine 会轮询同级状态的成本,并转换到成本最低的行为 [17, 18]。

# CostState.gd (Base)
func get_cost(context: Dictionary) -> float:
    return 10.0 # Default weight

# UtilityStateMachine.gd
func _physics_process(_d: float) -> void:
    var best_state: Node = current_state
    var low_cost: float = INF
    for child in get_children():
        var cost = child.get_cost(context)
        if cost < low_cost:
            low_cost = cost
            best_state = child
    if best_state != current_state:
        transition_to(best_state.name)

深入配方(按需查看)

LLM 不知情规则:如果通用 Agent 在阅读前不会知道某项内容,就将其放在这里或 scripts/ 中 — 切勿删除,只能移动。

主题参考资料
状态约定 + 路由hsm-implementation-cookbook.md

参考资料

渐进式披露:仅在研究特定 API 时打开官方文档链接;在路由到相关领域时加载相关技能 — 不要预加载整个知识体系。

官方文档
  • 使用信号 — 通过 state_changed / 转换扇出驱动流程,让监听器(动画、音频、AI)与进入/退出逻辑保持解耦。
  • 场景组织 — 子节点拥有状态,并采用信号向上发送、调用向下传递的方式,让状态机负责协调,同时避免兄弟节点之间的紧密耦合。
  • 什么是 Godot 类 — 对于分层 AI 行为,优先使用组合式状态节点和 class_name,而不是深层继承树。
  • 空闲处理与物理处理 — 说明为何 HSM 必须在每个时钟周期将 _physics_process / _process 转发给当前活动子状态(或层级)。
  • 使用 SceneTree — 使用 call_deferred 进行状态转换,避免在 enter() 中调用 transition_to() 时发生重入崩溃。
  • Godot 通知 — 说明相对于 _ready 和父节点缓存,安全连接初始 enter() 的时机。
  • 资源 — 使用数据驱动的状态定义(.tres)构建模块化 AI,无需将脚本嵌入每个角色。
  • 使用 AnimationTree — 当游戏 HSM 状态映射到混合/状态机图时,说明逻辑如何流转到 AnimationTree。
  • AnimationNodeStateMachinePlayback — 动画同步器使用的 travel() / start() API,可与 HSM 状态名称绑定。
  • Node — 状态节点作为场景树成员所继承的子节点查找、处理模式和生命周期钩子。
  • InputEvent — 父节点转发给活动状态 handle_input 的类型化事件。
  • Timer — 通过触发状态转换信号的一次性计时器,实现有限时长状态(眩晕、冲刺)。
相关技能
前置要求
  • godot-project-foundations — 每个 HSM 根场景和子状态场景所依赖的场景所有权与项目布局约定。
  • godot-gdscript-mastery — 守卫条件、延迟状态转换和上下文对象所需的 class_name、类型化 Dictionaries/载荷和 Callables。
  • godot-signal-architecture — 通过向上发送信号传递状态转换事件,避免状态既发送又监听自身而形成循环图。
配套技能
  • godot-composition — 将 HSM / VSM 作为 StateComponent 放在组合根节点下,而不是让 Actor 脚本变得臃肿。
  • godot-input-handling — 由感知层采样;状态通过 handle_input 接收方向 / 动作,而不是轮询全局变量。
  • godot-characterbody-2d — 移动状态通过 context 传入的 Actor 调用 move_and_slide / velocity API。
  • godot-animation-tree-mastery — 混合树和 AnimationNodeStateMachine 图,HSM 同步器会按状态名称在其中切换。
  • godot-resource-data-patterns — 可调节的状态 Resource(速度、眩晕时长、AI 权重)与运行时 Node 生命周期分离。
  • godot-2d-animation — 当无需完整 AnimationTree、较轻量的同步路径即可满足需求时,使用 Sprite / AnimationPlayer 进行表现。
下游 / 使用方
  • godot-combat-system — 受击硬直、攻击前摇和死亡状态叠层都是格斗角色中典型的下推式 / HSM 使用场景。
  • godot-ability-system — 施法、引导和冷却阶段可自然映射为带守卫条件的转换和定时状态。
  • godot-turn-system — 回合阶段和中断叠层可复用下推式 / 并发状态机编排模式。
  • godot-dialogue-system — 过场动画和对话叠层会压入游戏状态之上,且弹出时必须保留上下文。
主索引
  • godot-master — 库路由器和镜像模块入口;需要了解哪个领域技能负责跨领域架构问题时,请打开此项。

评论

支持 Markdown