运行时监控
把一场真实战斗的当前状态与执行记录放在同一窗口中,让每次内容修改都有可以核对的运行证据
通过以下菜单打开窗口:
Tools > TinyGiants > GCS > Game Card Monitor

完成系统初始化后,也可以从 Game Card System 面板 的 Editor & Monitor 卡片打开同一个窗口

系统面板只有在初始化状态通过检查后才会启用这个按钮,菜单入口本身没有这项门禁
在 FlowGraph Editor 中完成静态结构检查后,将同一项 Card、Status 或 Enemy 放进真实战斗,Game Card Monitor 会将这些触发、结算、状态变化与事件通知呈现为可以逐层核对的运行证据
在复现操作之前打开 Monitor
Game Card Monitor 可在 Edit Mode 中提前打开,但只有进入 Play Mode 并 启动一场战斗 后才会出现运行内容
需要注意的是
- 窗口打开时才会订阅 Flow、Phase、Gate、Event 与详细事件通道,晚于问题发生时间打开时,已经结束的执行将不会被补录
Battle、Pile与Unit直接读取当前运行状态,即使窗口打开较晚,你仍然可以查看到此刻的战斗快照
| 页眉状态 | 当前含义 |
|---|---|
INACTIVE | 当前不在 Play Mode |
LIVE | 每 0.3 秒刷新界面,并继续接收运行采样 |
PAUSED | 自动刷新以及 Phase、Gate、Flow 与 Dispatcher Probe 采样暂停,战斗本身仍继续运行 |
退出 Play Mode 或回到 Edit Mode 时,当前窗口捕获的历史会清空,因此稳定的复现顺序是先打开 Monitor,再进入或重新开始最小战斗,最后执行需要检查的操作
七个标签页组成两类证据
| 标签页 | 主要证据 | 当前边界 |
|---|---|---|
Battle | Phase、Turn、Side、Cards Played、Encounter、待定选择、Gate、玩家、敌人、Pending Intents 与规则原始值 | Energy 分母、Hand Cap 与 Draw / Turn 不代表经过全部 Hook 修正后的有效上限 |
Pile | Hand、Draw、Discard、Exhaust 的逐卡实例与 Master 数量 | Master 只显示数量,只有 Hand 显示当前有效费用 |
Unit | HP、护甲、玩家当前能量、状态层数、存活状态和敌人 Pattern Walk | 不显示当前 Intent,Intent 在 Battle 中查看 |
Phase | 当前 Phase、Turn、Choice Pending 与阶段转换历史 | 只保留订阅后的最新 256 条转换 |
Gate | 当前 holder、TimeoutSeconds 配置值、Active Reasons 与 Acquire、Release 历史 | 只保留最新 256 条变化,不记录单独的 timeout 事件 |
Flow | 拥有者、触发位置、本次同步执行段访问的节点数与耗时 | 只保留最新 256 次执行,不显示逐节点路径与后续异步 continuation |
Event | 43 个内置事件中固定订阅的 21 类详细广播,以及采样期间捕获的 dispatch probe | 详细事件保留 1000 条但界面只显示最新 200 条,probe 保留 256 条 |
这两类证据需要按顺序组合,先从 Battle、Pile 与 Unit 确认当前结果,再用 Phase、Gate、Flow 与 Event 追查这些结果的产生过程
- Battle
- Pile
- Unit
- Phase
- Gate
- Flow
- Event
Battle 是窗口默认打开的标签页,会显示当前是否存在活动战斗、战斗所处阶段,以及玩家和敌人此刻的状态

上图的 Snapshot 显示一场处于 PlayerPhase 的 Fenmoss Hollow 战斗:
- 当前为第 1 回合、玩家侧行动,本回合已经打出 1 张卡
- 同一快照中的玩家
Scout拥有70 / 70HP 与2 / 3Energy,敌人Plague Stalker则剩余13 / 16HP - 玩家区显示 HP、护甲、状态数量和当前能量,敌人区显示 Tier、存活状态与 Pending Intents
- 截图中的
Debuff ?表示这项 Intent 没有可用的预览数值,但系统已经为该敌人提前生成了一项待执行意图
Battle 与 Phase、Gate 反映的是同一套战斗状态机,完整阶段关系见 战斗状态机
确认战斗本身有效后,Pile 会把运行时卡牌实例拆到 Hand、Draw、Discard 与 Exhaust 四个列表中,并在顶部汇总 Master 数量

上图的 Snapshot 显示 Hand 4、Draw 12、Discard 1、Exhaust 0 与 Master 0:
- 每一行包含 Instance ID、卡牌名称、Type 与可选的 Upgraded 标记
- Hand 中还会显示经过 Hook 和费用修正后的当前 Cost
卡牌结算后通常会进入 Discard,带 Exhaust Keyword 的卡牌则进入 Exhaust,四个牌堆之间的运行规则见 卡牌、手牌与牌堆
Pile 确认卡牌位置后,Unit 会把玩家与全部敌人的运行状态逐个展开
玩家卡片显示 HP、护甲、当前能量与状态层数,敌人卡片显示 HP、护甲、存活状态、状态层数,以及已经持久化的 Pattern 进度

上图的 Snapshot 显示 Scout、Plague Stalker 与 Poison:
Scout保持70 / 70HP,Plague Stalker为13 / 16HP 并持有Poison × 2- Battle 中已经出现
Debuff ?Pending Intent,说明无状态的 Weighted Random Pattern 已经选出 Leaf Intent,只是没有写入PatternState
Phase 顶部读取当前 Phase 与 Turn,历史区按照最新在前的顺序记录 OldPhase → NewPhase 与对应回合

上图的 Snapshot 显示 PlayerPhase 以与 History:
- 上图确认当前处于
PlayerPhase第 1 回合,History数量为 0 并显示No transitions yet,这说明 Monitor 订阅后尚未捕获到阶段转换 - 发生后续转换时,最新一条会保持在历史顶部,回合开始、回合结束或敌人阶段相关行为没有触发时,可以先在这里确认对应阶段是否真的到达
Phase 没有继续推进时,Gate 会显示 Animation Gate 当前的 holder 数量、TimeoutSeconds 配置值、持有原因,以及最近的 Acquire 与 Release

上图中的 Holders 0、Active Reasons (0) 与 No gate activity captured 显示:
-
当前 Gate 空闲,
Timeout 5s只显示当前配置值 -
Gate 被持有时,Live 区会按 reason 汇总当前次数,历史区则分别记录
ACQUIRE、RELEASE、reason 与变化后的 holder 总数
Flow 接收执行器上报的行为图摘要,适合确认 Card、Status、Enemy 或 Battle 的预期行为分支是否已经交给执行器

上图记录了 Poison Arrow 从 OnCardPlayed 运行一次,本次同步执行段共访问 10 个节点并耗时 63.81 ms,Summary 则汇总当前缓冲区中各次同步执行段的捕获次数、总耗时与总访问节点数,单次同步执行超过 8 ms 时耗时徽标会使用警示颜色
Max Loop固定为 0,不能用来判断真实循环深度- Wait 或 Choice 后继续运行的 continuation 不会追加到原记录中
- Flow 不提供逐节点名称、分支路径、端口值或断点
需要核对这些细节时,应回到 FlowGraph Editor,运行时怎样沿控制流与数据流完成一轮执行见 FlowGraph 执行模型
Event 将 Monitor 主动订阅的 GCS 广播与事件通道的原始 Dispatcher Probes 组合在了一起

上图中的 GCS Channel 按最新在前的顺序显示能量、状态、HP 与出牌广播,OnCardPlayed Poison Arrow #16 → unit 2 证明 Monitor 的固定订阅收到了这次出牌事件
-
下方的 Dispatcher Probes 记录每次内部 dispatch 的事件名与
subs数量 -
probe 存在且
subs 0表示事件已经 dispatch,但当时没有订阅者 -
subs > 0只表示至少存在一个订阅者,Monitor 自身对详细事件的订阅也可能包含在数量中,不能据此确认目标外部监听器已经接入
GCS Channel 只为 43 个内置事件中的 21 类生成可读详情,Dispatcher Probes 则覆盖采样期间实际发生的 dispatch,其中也可能包含自定义事件名
排查问题
排查时先核对当前前置条件,再沿执行时序、事件边界和最终结果逐层缩小问题范围
战斗没有进入活动状态
Battle显示No active battle时,只能确认当前没有可读取的GameCardManager.ViewEvent中没有OnBattleStarted时,先清空 Filter,并确认 Monitor 是否在复现前打开- 继续排除 Clear、Clear All、退出 Play Mode 与超过容量后的记录淘汰
- 只有排除这些记录边界后,缺少
OnBattleStarted才能说明详细订阅没有收到这次启动广播 - 如果 Monitor 在战斗开始后才打开,空 Event 历史不能反推启动广播从未发生
- 回到 战斗启动 检查 Bootstrap、Manager 与 Encounter,再从 Unity Console 的第一条错误继续定位
卡牌无法打出
Battle核对当前 Phase、玩家 Energy 与目标单位是否仍在场Pile核对卡牌实例是否位于 Hand,以及当前有效 Cost 是否符合预期Unit核对候选目标的队伍、存活、HP 与状态,Unit 不记录玩家实际点击了哪个目标Event当前没有显示OnCardPlayed,只能确认现有过滤结果与保留记录没有提供成功出牌的广播证据,不能给出TryPlayCard被拒绝的具体原因
目标范围与队伍规则见目标选择,创作数据的静态问题可回到卡牌编辑器检查,运行时拒绝仍应结合调用返回值和 Console 判断
卡牌已经打出但结果不对
Event中的OnCardPlayed证明出牌广播已经发生Flow中匹配的 Owner 与 Trigger 证明对应行为图被执行器调用,节点数只统计本次同步执行段,不代表每个预期节点都经过Unit核对 HP、护甲与状态,Pile核对卡牌最终进入 Discard 还是 Exhaust- 运行状态正确而画面没有更新时,再转向 Prefab、UI、动画、音频与 VFX
战斗停止推进
Phase确认最后一次转换停在哪个阶段Gate核对当前 holder、Active Reasons 与最新 Acquire、Release- 同一个 reason 只有 Acquire 而没有 Release 时,回查对应表现请求的完成回调
- 常规阶段不会替 Gate holder 计时或自动释放
- 只有代码进入显式等待路径时,才可能根据
TimeoutSeconds在 Unity Console 写入 warning
敌人没有行动
Phase确认是否进入过 EnemyPhaseBattle核对这名敌人的 Pending Intent,Unit核对存活状态、Skip 次数与 Pattern WalkFlow核对 Enemy Owner 与LeafIntent执行摘要- 没有 Intent 或 Flow 记录时,回到 敌人创作 检查
Pattern → Leaf Intent → Action链路
状态没有在预期时机更新
Unit核对目标单位是否持有状态以及当前 StacksEvent核对OnStatusChanged与相关 dispatch probePhase核对状态依赖的回合或阶段是否到达Flow核对 Status Owner 与对应 Entry 或 Hook 的执行摘要
状态字段与行为入口的职责见 状态创作,仍无法定位时继续使用 运行时错误排查
将机制问题与表现问题分开
核对当前状态、执行时序与事件记录后,可以根据运行时状态是否发生预期变化决定下一条检查路径:
如上图中的“状态写入已经发生”只确认被观察到的那项运行时结果,不代表整张行为图或 Controller 的所有分支都正确,因此,表现仍应沿 表现层 的绑定链逐项核对
| 证据组合 | 可以优先判断的方向 |
|---|---|
| Flow 有记录,运行状态未变化 | 回查具体节点路径、输入端口、目标解析与 Hook 写入 |
| 运行状态变化正确,画面没有对应反馈 | 优先检查 UI、Prefab、动画、音频与 VFX 引用 |
Event probe 存在且 subs 0 | dispatch 已发生,当时没有订阅者 |
Event probe 显示 subs > 0 但外部系统没有响应 | 只能确认至少存在一个订阅者,不能证明目标监听器已经接入 |
| Gate holder 长时间不归零 | 检查对应表现流程是否在所有分支上执行 Release |
Monitor 自身对 21 类详细事件的订阅也可能包含在 subs 数量中,在外部系统没有响应时,需要继续核对目标监听器的订阅时机、参数类型、回调逻辑与 disposal,当定位到具体层级后,回到对应编辑器修正,再重新进入 Play Mode 验证
想要了解六类内容怎样通过 Database 与 Encounter 组成一场战斗,请见数据库管理,想了解从公开 API 到表现层的运行分层,请见运行时架构