Skip to main content

Entries and Hooks

GCS ยท FlowGraph Authoring

Entries start a graph after something happened; hooks let a graph change a value before GCS commits it. This page catalogs all 33 entries and 18 hooks with their firing moments, outputs, and hosts.

Keep this open while authoring. Picking the right timing point is most of the work.

Entries and hooks are the timing language of FlowGraph. Before you place any other node, decide when the behavior should start, and whether it reacts to a moment or rewrites a value.

Poison status behavior graph in the FlowGraph window, showing a status-hosted entry driving its per-turn effect

The demo's Poison status is a typical status-hosted graph: an On Turn Start entry deals damage scaled by the status's own stacks, with the presentation trailing behind. Statuses are the most reactive host in GCS, which is why most of the tables below list them.


Entry or hook?โ€‹

You want to...Use
React after a battle moment happenedAn entry
Change a value before GCS commits itA hook
Drive an enemy's turnOn Enemy Behavior Start plus Intent pattern nodes
Trigger one graph from anotherRaise Internal Event plus On Internal Event
Bridge into GESRaise GES Event plus On GES Event

Entries are easy to reason about because the event is already over when they run. Hooks need more care: they sit inside a calculation that may still be modified or cancelled by other hooks.


Who can listen to whatโ€‹

Each host only gets the entries that make sense for it, and the Add Node menu enforces this. In short: cards react to their own pile lifecycle and turn boundaries, statuses react to nearly everything that happens to units, and enemies have exactly one entry that starts their turn.

HostAvailable timing points
CardThe seven card entries, On Turn Start, On Turn End, On Draw Pile Shuffled, both event entries, all hooks
StatusBattle, turn, phase, damage, HP, armor, energy, status, and unit entries, On Card Drawn, both event entries, all hooks
EnemyOn Enemy Behavior Start, both event entries, Intent patterns

If a behavior seems to need an entry its host cannot use ("this card reacts whenever any unit dies"), author it as a status instead and let the card apply that status.


Where a turn's entries fireโ€‹

One player turn plus the enemy phase, in firing order:

Two details trip people up. The draw phase does not run on turn 1, because the opening hand is drawn at battle start. And inside the enemy phase each enemy gets its own private sequence: its statuses fire On Turn Start, it acts through On Enemy Behavior Start, then its statuses fire On Turn End. A Poison on an enemy therefore ticks on that enemy's own step, not on yours.


Battle and turn entriesโ€‹

None of these output data; they are pure timing.

EntryHostsFiresUse for
On Battle StartStatusOnce, when the battle begins.Opening buffs, starting variables, first-turn setup. Per-turn work belongs in On Turn Start.
On Battle EndStatusOnce, when the battle ends, won or lost.Cleanup and end-of-battle effects. Victory screens belong to scene UI, not graphs.
On Turn StartCard, StatusOn a status: the start of the owning unit's own turn. On a card: for every card sitting in hand when the player turn starts.Energy changes, status ticks, per-turn counters.
On Turn EndCard, StatusOn a status: the end of the owning unit's own turn. On a card: for every card in hand at player turn end, before the hand is discarded.End-of-turn damage, decay, delayed cleanup.
On Draw PhaseStatusAt player turn start, right before the per-turn draw. Not on turn 1; the opening hand is drawn at battle start.Draw-phase reactions. For each individual card, use On Card Drawn.
On Discard PhaseStatusAt player turn end, before the hand is discarded.End-of-turn discard reactions.
On Draw Pile ShuffledCardWhenever the discard pile is reshuffled back into the draw pile.Shuffle reactions and relic-style mechanics.

Card entriesโ€‹

Every card entry outputs the Card involved, so downstream nodes can read its cost or type through Card Info. All are card-hosted; On Card Drawn is the one statuses can also listen to.

EntryHostsFiresUse for
On Card DrawnCard, StatusOnce per card, as the draw puts it into hand.Draw triggers and draw-based counters.
On Card PlayedCardWhen GCS accepts the play. This is where a card's main effect lives.The card's own effect. To change cost or playability instead, use hooks.
On Card DiscardedCardWhen the card is discarded, by the end-of-turn discard or by an effect.Discard synergies.
On Card ExhaustedCardWhen the card exhausts: an Exhaust card being played, an Ethereal card at turn end, or an effect that exhausts it.Exhaust synergies and cleanup.
On Card RetainedCardWhen the card stays in hand across turn end, through the Retain keyword or battle rules that keep the whole hand.Retain synergies.
On Card Added To HandCardWhen an effect creates or moves the card into hand outside the draw step.Generated-card reactions. For drawn cards, use On Card Drawn.
On Card Added To DeckCardWhen an effect adds the card to the draw pile.Deck-building and summon-card reactions.

Damage, HP, armor, and unit entriesโ€‹

These are all status-hosted: the unit that should react carries a status, and the status carries the graph. In their outputs, Source is the unit that caused the change and Target is the unit it happened to.

EntryOutputsFiresUse for
On Damage DealtAmount, Source, TargetAfter damage from the owner lands. Amount is the damage that got through.Follow-ups after outgoing damage: lifesteal, on-hit riders. To raise the damage itself, use Damage Dealt Hook.
On Damage TakenAmount, Source, TargetAfter the owner takes damage from any source.Thorns, retaliation, hit reactions. To reduce incoming damage, use Damage Taken Hook.
On Attack TakenAmount, Source, TargetAfter an attack hits the owner. Status ticks and other non-attack damage do not fire it.Attack-only reactions.
On HP GainedAmount, Source, TargetAfter the owner is healed.Heal reactions. To change the heal amount, use HP Gain Hook.
On HP LostAmount, Source, TargetAfter the owner loses HP, damage or otherwise.Bleed and sacrifice reactions.
On Armor GainedAmount, Source, TargetAfter the owner gains armor.Shield-gain synergies.
On Armor LostAmount, Source, TargetAfter the owner loses armor.Armor-break reactions.
On Unit SpawnedUnitAfter a unit is summoned onto the battlefield.Summon reactions.
On Unit DiedWas Kill, Source, TargetTwice per death: once for statuses on the dying unit with Was Kill off, once for statuses on the killer with Was Kill on. Source is the killer, Target the unit that died.Death rattles on the victim side, kill rewards on the killer side. Branch on Was Kill when one status serves both.

Energy and status entriesโ€‹

Also status-hosted.

EntryOutputsFiresUse for
On Energy GainedAmountAfter the player gains energy.Energy-gain reactions. To change the amount, use Energy Gain Hook.
On Energy SpentAmountAfter the player spends energy.Spend reactions and counters. To change card cost, use Card Cost Hook.
On Status InflictedStatus, Stacks, Source, TargetAfter the owner applies a status to someone.Source-side effects: "whenever you inflict a debuff". To change the stack count, use Inflict Status Hook.
On Status ReceivedStatus, Stacks, Source, TargetAfter a status lands on the owner.Receiver-side reactions.
On Status ExpiredStatus, TargetWhen a status on the owner runs out naturally, its stacks or duration hitting zero.Expiration effects.
On Status RemovedStatus, Stacks, TargetWhen a status on the owner is removed by an effect: cleanse, purge, dispel.Purge reactions, distinct from natural expiry.
On Status Stacks ChangedStatus, Stacks, TargetWhenever a status's stack count on the owner moves, up or down. Stacks is the new count.Threshold effects such as "at 5 stacks".

Enemy and event entriesโ€‹

EntryOutputsHostsFires
On Enemy Behavior StartNoneEnemyThe root of every enemy graph. GCS runs it to pick the enemy's telegraphed intent and again when the enemy acts on its step of the enemy phase.
On Internal EventValues via Event ArgAllWhen a Raise Internal Event with the matching EventName runs anywhere in the battle.
On GES EventValues via Event ArgAllWhen the assigned Game Event System event is raised, inside or outside GCS.

Mire Reaper enemy graph: On Enemy Behavior Start feeding a Weighted Random Pattern that picks between Leaf Intent branches

The demo's Mire Reaper shows the enemy shape: On Enemy Behavior Start feeds a Weighted Random Pattern, and each branch ends in a Leaf Intent that telegraphs what the enemy will do next turn.


Hook entriesโ€‹

A hook does not wait for a moment; it runs while the matching value is being calculated, before the result lands. The hook exposes the pending value through its outputs. To change it, compute the new value and run Write Hook. To stop the operation entirely, run Cancel Hook. Hooks are available to card and status graphs; in practice almost all of them live on statuses.

Every hook entry carries three shared settings:

SettingMeaning
PriorityWhen several hooks intercept the same value, they run in priority order, so a "double damage" and a "cap damage at 10" can be sequenced deliberately.
ScopeBattle keeps the hook active for the whole battle; Turns limits it.
TurnsHow many turns the hook stays active when Scope = Turns.
HookOutputsFires whileUse for
Damage Dealt HookValue, Source, TargetOutgoing damage from the owner is computed.Raise or reduce damage before it applies. For after-the-hit reactions, use On Damage Dealt.
Damage Taken HookValue, Source, TargetIncoming damage to the owner is computed.Mitigation, vulnerability, resistance.
Attack Taken HookValue, Source, TargetAn incoming attack (not status damage) is computed.Attack-only mitigation or amplification.
HP Gain HookValue, Source, TargetHealing on the owner is computed.Amplify or suppress healing.
HP Loss HookValue, Source, TargetA non-damage HP loss on the owner is computed.Modify sacrifice-style loss. For damage, use the damage hooks.
Armor Gain HookValue, Source, TargetArmor the owner is about to gain is computed.Dexterity-style armor scaling.
Armor Loss HookValue, Source, TargetArmor the owner is about to lose is computed.Block preservation.
Armor Reset HookValue, TargetThe start-of-turn armor reset is computed.Keep armor across turns, barricade-style.
Energy Gain HookValueEnergy the player is about to gain is computed.Scale energy gains.
Energy Spend HookValueEnergy the player is about to spend is computed.Discounts and surcharges on spending.
Energy Per Turn HookValueThe per-turn energy refill is computed.Change the energy baseline.
Inflict Status HookStatus, Stacks, Source, TargetStacks the owner is about to inflict on someone are computed.Amplify the debuffs you apply.
Receive Status HookStatus, Stacks, Source, TargetStacks about to land on the owner are computed.Status resistance or vulnerability.
Status Damage HookValue, Source, TargetA status tick's damage is computed. Set the hook's Status field to choose which status it affects.Scale Poison or Burn ticks without touching attack damage.
Card Cost HookCard, ValueA card's energy cost is evaluated.Cost discounts and penalties.
Card Playable HookCard, PlayableGCS checks whether a card may be played.Lock cards out, for example while Silence is active.
Draw Count HookValueThe number of cards about to be drawn is computed.Extra or reduced draw.
Hand Size HookValueThe maximum hand size is evaluated.Raise or lower the hand cap.

The hook writing patternโ€‹

A hook graph almost always has this shape:

  1. Start from the hook entry and read Value (plus Source, Target, Card, or Status as needed).
  2. Compute the new value with Condition, Math Binary, Unit Info, or Card Info.
  3. Run Write Hook with Kind = Int for numbers or Kind = Bool for playability.
  4. Reach for Cancel Hook only when the intended outcome is "this does not happen at all".

Worked example, "this unit takes 2 less damage while it has Plated Armor stacks":

  1. Damage Taken Hook
  2. Unit Status Stacks for the hook's Target and the Plated Armor status
  3. Condition with Op = Greater against 0
  4. Branch
  5. On True, Math Binary subtracts 2 from Value
  6. Write Hook with Kind = Int
warning

A hook graph that never reaches Write Hook changes nothing. The graph runs, the VFX plays, and the original value goes through untouched. If the Issues badge is clean but the value never moves, this is the first thing to check.


The event entry patternโ€‹

Internal events keep a sender and receiver loosely connected:

  1. The sender runs Raise Internal Event with an EventName and optional argument bindings.
  2. The receiver's graph starts from On Internal Event with the same name.
  3. The receiver reads each named value through Event Arg.

The validator flags an On Internal Event entry with an empty name, so name the event before anything else. Use the GES pair only when the behavior genuinely crosses into Game Event System; for logic that stays inside GCS, internal events are simpler to debug.