Runtime Errors
Play Mode diagnosis with the Monitor as your instrument: startup failures, actions refused by phase timing, card plays that misfire, event subscriptions that stay silent, and visuals lagging behind state.
For developers whose content validates clean but whose battle still misbehaves once Play Mode starts.Runtime errors appear only after the scene enters Play Mode, which is exactly why the Game Card Monitor exists. Before reading any code, let it answer three questions: did the runtime state change, which phase is the battle in, and which flows and events actually ran. Each failure class below names the tab that exposes it.
Startup failuresโ
Play Mode starts, no battle appears, and the Monitor Battle tab shows nothing active. Work down this list:
GameCardManagerexists in the scene and all six databases are assigned.- A
GameCardEncounterBootstrap(or your ownGCSApi.StartBattlecall) references an encounter, and Auto Start On Play is enabled if the battle should begin on its own. - The encounter's player unit and enemy lineup resolve to content inside the active databases.
When setup looks right and the battle still refuses to start, read the first Console error and ignore the rest. Later errors are usually consequences of the first one.
Actions refused by timingโ
A card will not play, End Turn appears dead, or an API call seems ignored. Almost always the battle is not in the phase the action requires:
- Read the current phase from
GCSApi.Phaseor the MonitorPhasetab. Card plays and End Turn needPlayerPhase; duringPlayerTurnStart,PlayerTurnEnd,EnemyPhase, and the two end states they are refused by design. - Check the Monitor
Gatetab. The battle holds between phases while animations run; the tab lists every current gate holder with its acquire and release log. A presentation script that acquires the gate and never releases it freezes the battle in a way that looks like input being ignored. - Confirm the selected target is still alive, and that no status vetoes the play through
Card Playable Hook.

GCSApi.CanPlayCard(card) gives you the playability verdict from code, which is handy inside custom UI.
Card play misbehaviorโ
The card disappears without effect, stays in hand, lands in the wrong pile, or the energy math surprises you. In that order of likelihood:
- Open the Monitor
Flowtab and confirm the card's behavior graph actually executed. A play with no flow entry means the graph's entry node does not match, exactly the "plays but nothing happens" case. - Check the card's tags.
Exhaust,Retain, andUnplayableeach change where the card goes or whether it can be played at all. - Check the encounter's battle rules for hand discard and hand size; a card "vanishing" at turn end is often the discard rule doing its job.
- Cost surprises come from cost modifiers and
Card Cost Hookgraphs, not from the printed cost.
If custom nodes are involved, verify every battle mutation goes through ctx.Controller. State changed any other way bypasses events, hooks, and the Monitor alike, and the symptoms get strange.
Subscriptions that stay silentโ
Custom UI does not refresh, a listener fires twice, or it never fires at all. The Monitor Event tab shows every event the battle raised, with payloads, which immediately splits the problem: if the event appears there, the runtime raised it and your subscription is at fault; if it never appears, the thing you are waiting for never happened.

The usual subscription mistakes:
- Subscribing before the battle manager exists, so the handler attaches to nothing.
- Never disposing. Every
GCSApisubscription returns anIDisposable; keep it and dispose it when the listening object goes away, or reloads will stack duplicate handlers:
IDisposable _played;
void OnEnable() => _played = GCSApi.OnCardPlayed(args => Refresh());
void OnDisable() => _played?.Dispose();
- A typed listener with the wrong argument type, or an event name that does not exactly match
GCSEventNames. - Confusing the two event layers:
Raise Internal Event/On Internal Eventconnect graphs to each other, while C# code listens to the runtime events behindGCSApi.Subscribe.
For GES-bridged events, also confirm GES is installed (the TG_GES_INSTALLED define is managed automatically when it is detected) and that the GES event GUID on the node matches an event in an active GES database.
Mechanics work, visuals do notโ
Damage lands in the Monitor but the screen disagrees: stale HP bars, missing VFX, silent audio, an enemy with no visible body. Since the state is confirmed correct, the search space is presentation only. Inspect, in rough payoff order: scene UI references, unit prefabs, card templates and artwork, status icons, and the VFX, SFX, and animation references on the graph's FX nodes.
Capture a repro before asking for helpโ
When a runtime problem resists diagnosis, record the scene path, the encounter name, the phase shown in the Monitor, the action being performed, the first Console error, and what the Battle, Pile, Unit, Flow, and Event tabs showed. That set separates state bugs from presentation bugs from setup bugs, and it turns "it sometimes breaks" into something answerable.