运行时架构
GCS 运行时的分层结构:manager、状态机、状态视图、controller、流图执行、事件与表现层。
写自定义战斗 UI 或玩法代码之前先读这一页,让你的代码通过正确的入口修改状态,而不是直接改内部列表。GCS 运行时把创作好的内容变成一场实时战斗。值得记住的边界只有一句话:内容资产描述可能发生什么,战斗状态存储此刻正在发生什么,而 controller 是改变这些状态的唯一安全通道。
运行时分层
| 层 | 主要类型 | 职责 | 对你代码的要求 |
|---|---|---|---|
| Manager | GameCardManager, GCSApi | 持有当前启用的数据库、当前战斗、run master deck 和公开入口。 | 外部代码从 GCSApi 开始。 |
| State machine | BattleStateMachine | 拥有战斗阶段、回合转换、选择等待、奖励等待和敌人回合。 | 绝不强行改阶段。调用 StartBattle、TryPlayCard、EndPlayerTurn。 |
| State view | IBattleState, BattleStateView | 暴露回合、能量、单位、牌堆、已打出/已抽取历史和有效卡牌费用。 | 通过 GCSApi.Battle 或 GCSApi helper 读取。 |
| Controller | IBattleController, BattleStateView | 修改生命、护甲、能量、状态、卡牌、延迟触发、变量和召唤敌人。 | 通过 GCSApi 或 FlowGraph 节点修改,不要手动编辑列表和字段。 |
| Flow execution | GameCardFlowExecutor, EffectActionContext | 携带 source、target、card、battle、controller 和数据库运行卡牌/状态/敌人流图(FlowGraph)。 | 图通过 context helper 和 controller action 读写。 |
| Events | GCSEvents, IGCSEventChannel, GCSEventNames | 战斗状态变化时通知 UI、集成和自定义系统。 | 用 GCSApi shortcut 或 typed named events 订阅。 |
| Presentation | UnitView, FloatingTextSystem, FX nodes, demo UI | 通过 UI、动画、VFX、SFX、浮动文本和镜头反馈展示状态变化。 | 表现层只观察运行时结果,绝不拥有玩法规则。 |
公开入口
GCSApi 是文档化的运行时 facade。它的覆盖面刻意做得比较广,这样自定义 UI、示例代码、工具和玩法集成都不需要依赖内部类。
用它来做:
- 启动和释放战斗。
- 打出手牌并结束玩家回合。
- 读取战斗阶段、回合、能量、单位状态、敌人意图、牌堆和状态层数。
- 应用受控的状态修改。
- 读取当前启用的数据库,按 GUID 查找内容。
- 维护 run master deck。
- 订阅事件。
- 发现扩展注册表。
GCSApi.Manager、GCSApi.Battle 和 GCSApi.Controller 为集成工作而暴露,但多数代码应优先使用命名 helper 方法。它们意图更清楚,遇到没有战斗时也会返回安全默认值。
读状态与改状态
GCS 把只读状态和可写控制分开。
| 表面 | 类型 | 能力 |
|---|---|---|
GCSApi.Battle | IBattleState | 读取当前回合、能量、玩家、牌堆、存活敌人、已打出/已抽牌历史和有效卡牌费用。 |
GCSApi.Controller | IBattleController | IBattleState 能读的全部内容,加上会走运行时规则的修改方法。 |
GCSApi helpers | Static methods | 为同一组常见读写提供安全、命名清晰的 shortcut。 |
直接编辑 UnitState.Statuses、CardPile.Cards 或 UnitState.CurrentHp 会绕过 hooks、事件、UI 更新和校验。请使用 controller 背书的方法。
战斗状态模型
一场实时战斗包含:
| 状态 | 含义 |
|---|---|
TurnNumber | 从 1 开始,每次敌人阶段结算后递增。 |
IsPlayerTurn | 玩家回合开始、行动、结束阶段为 true;敌人阶段为 false。 |
PlayerEnergy | 本回合还可用的能量。 |
PlayerUnit | 玩家的单位状态。 |
AliveEnemyUnits | 仍然存活的敌人。死亡单位会被排除。 |
HandPile, DrawPile, DiscardPile, ExhaustPile | 运行时卡牌区域。 |
PlayedThisTurn | 当前回合打出的卡牌,按打出顺序排列。 |
DrawnThisTurn | 当前回合抽到的卡牌,按抽牌顺序排列。 |
抽牌堆的顺序约定:最后一个元素就是下一张被抽到的牌。
Play Mode 下打开 Game Card Monitor 的 Battle 页签,就能实时看到这个模型:当前遭遇战、阶段、回合、玩家快照和敌人列表。

单位状态模型
UnitState 是战斗使用的实时单位记录。
| 字段或属性 | 含义 |
|---|---|
UnitId | UI 和事件使用的运行时 id。 |
Source | 该单位背后的 GameUnit 创作资产。 |
CurrentHp, MaxHp | 当前和最大生命。 |
CurrentArmor | 当前护甲。 |
CurrentEnergy | 单位上的能量值。玩家本场战斗的能量池请读 GCSApi.PlayerEnergy。 |
Statuses | 按 GameStatus 记录的运行时层数。 |
StatusAppliers | 每个状态由哪个单位施加(已知时记录)。 |
ActiveHooks | 状态和卡牌贡献的运行时 hooks。 |
WasAttackedThisTurn | 本回合该单位是否被攻击过。 |
SkipNextTurns | 待跳过的回合数。 |
IsDead | 当前 HP 小于等于 0 时为 true。 |
HpPercent | 当前 HP 占最大 HP 的整数百分比。 |
外部读取优先用 GCSApi.Hp、GCSApi.MaxHp、GCSApi.Armor、GCSApi.HpPercent、GCSApi.HasStatus 和 GCSApi.StatusesOn。
流图执行上下文
FlowGraph 运行时,GCS 会构建一个携带以下内容的执行上下文:
| 上下文值 | 含义 |
|---|---|
| Source | 对该行为负责的单位。 |
| Host | 当前托管该行为的单位或拥有者。 |
| Target | 已选择或已解析的目标。 |
| Battle | 只读战斗状态。 |
| Controller | 走运行时规则的修改表面。 |
| Card | 图与卡牌相关时的当前卡牌实例。 |
| Status database | 当前启用的状态查询。 |
| Card database | 当前启用的卡牌查询。 |
| Enemy unit database | 当前启用的敌人查询。 |
内置节点自动使用这个上下文。自定义节点同样应该通过 context 和 controller 读取输入、修改状态,不要走无关的全局查询。
想查看这个上下文如何进入实际执行,打开 Game Card Monitor 的 Flow 页签。执行器上报的每一次图运行都会在这里列出,最新的排在最前:

等待与异步表现
表现或玩家选择还在结算时,战斗状态机可以暂停推进。
| 机制 | 用途 |
|---|---|
| Choice wait | Choice 节点暂停执行,直到玩家选择或跳过。 |
| Animation gate | 动画和表现可以扣住阶段转换,直到 gated action 完成。 |
| Flow wait | Wait 节点按秒或按 animation id 延迟后续执行。 |
| Reward wait | 战斗胜利后,奖励选择让战斗保持等待,直到应用或跳过。 |
这也是为什么自定义 UI 应该响应事件和状态变化,而不是假设一次 API 调用会立即完成每个可见步骤。
事件是通知,不是状态存储
事件告诉系统刚刚变了什么。它们不是事实来源。自定义 UI 应该用事件判断何时刷新,然后通过 GCSApi 读取当前状态:
- 订阅相关事件。
- 在 handler 中从
GCSApi读取当前状态。 - 更新 view model 或 UI widget。
- UI 销毁时释放订阅。
即使短时间内触发多个事件,UI 也能保持正确。
集成边界
| 需求 | 推荐表面 |
|---|---|
| 自定义战斗 UI | GCSApi read helpers 加 typed event shortcuts。 |
| 出牌控制 | GCSApi.CurrentHand、GCSApi.CanPlayCard、GCSApi.TryPlayCard、GCSApi.RequiresTarget。 |
| 单位面板 | GCSApi.Player()、GCSApi.AliveEnemies()、单位 helper、HP/状态/意图事件。 |
| 内容浏览器 | GCSApi.Cards、Decks、PlayerUnits、EnemyUnits、Statuses、Encounters 和 Find* helper。 |
| 外部系统的运行时修改 | GCSApi mutation helpers 或 GCSApi.Controller。 |
| 自定义事件桥接 | GCSApi.Subscribe、GCSApi.Events、GCSApi.RaiseGameEvent,或 GES bridge events。 |
除非你就在改 demo 本身,否则不要依赖 sample hand views、reward views 或场景专属 presenter 这类 demo 专用组件。