Skip to main content

Optional GES Integration

GCS ยท Integrations

Bridge battles and Game Event System in both directions: raise GES events from graphs, and start graph entries when GES events fire.

For projects that already use GES as their game-wide event layer. GCS itself never requires it.

GCS runs on its own. The Game Event System integration exists for projects that already route quests, achievements, analytics, or scene logic through GES GameEvent assets, and it works in both directions. A card, status, or enemy graph can notify GES, and a GES raise can start an entry inside a graph.

Two directions, one boundaryโ€‹

Everything else stays untouched. The 43 built-in GCS runtime events keep flowing through the internal channel whether GES is installed or not; only these two explicit paths cross the boundary.


Detection and setupโ€‹

The integration needs Game Event System in the same Unity project. GCS ships an editor detector that looks for the TinyGiants.GES.Runtime assembly definition and syncs the TG_GES_INSTALLED scripting define across the common build target groups (Standalone, Android, iOS, WebGL, plus the active one).

Setup is passive:

  1. Import GES, or keep it if it is already in the project.
  2. Let Unity compile and reload.
  3. The detector finds TinyGiants.GES.Runtime and adds TG_GES_INSTALLED.
  4. The Raise GES Event and On GES Event nodes are now fully wired.

Removing GES reverses this: the detector drops the define and GCS falls back to its internal channel.


Outbound: the Raise GES Event nodeโ€‹

Add Raise GES Event (Event category in the add-node menu) wherever a graph should notify the rest of the game. With GES installed, the GES Event row on the node is a picker: click it and choose from a dropdown of every GES event, grouped by event database. Picking an event also fills its argument and sender types automatically, so you never type GUIDs or type names by hand.

The node serializes these fields:

FieldMeaning
GesEventGuidWhich GES event to raise. Set by the picker.
GesArgTypeFullNameThe argument type. Filled by the picker from the event itself; empty means a no-argument raise.
GesArgSourceWhere the argument value comes from: fixed text or a live battle value.
GesArgFixedValueThe fixed value, as text, for primitive arguments.
GesArgObjectValueThe argument when its type is a Unity object.
GesArgJsonJSON used to construct complex argument objects.
GesSenderTypeFullNameThe sender type for sender-aware events. Filled by the picker.
GesSenderArgSourceWhere the sender value comes from.
GesSenderFixedValueThe fixed sender value, as text.
GesSenderObjectValueThe sender when its type is a Unity object.
GesSenderJsonJSON used to construct complex sender objects.

How the value gets built depends on its type. Unity object types come from the object reference field. Primitive-like types (int, float, bool, string, long, double, short, byte) come from the selected source. Any other type is deserialized from the JSON field.

The live sources read the current effect context: source unit id, default target unit id, attacker unit id, last damage, last armor, last heal, card instance id, card source GUID, battle turn number, and player energy. A quest that wants "how much damage did the finishing blow deal" picks the last damage source on the kill effect and is done.

What the bridge does at runtime

After assemblies load, the integration installs itself as the GCS event channel:

GCSEvents.Channel = new GCSEventChannelGESBridge();

When a Raise GES Event node runs, the bridge looks the event up on GameEventManager.Instance by GUID and raises it with no argument, an argument, or sender plus argument, matching what the node carries. Sender-aware raises use the event's GameEvent<TSender, TArgs> overload when it exists and fall back to an argument-only raise when it does not. A missing manager or an unknown GUID logs a warning instead of breaking the battle.


Inbound: the On GES Event entryโ€‹

The On GES Event entry (Entry category) starts a graph when a GES event fires during a battle. Pick the event on the node the same way.

When a battle starts, GCS binds to every GES event that is active at that moment. An event that only becomes active mid-battle is not picked up until the next battle starts. From then on, any raise of a picked event triggers matching entries on:

  • cards currently in the draw, hand, discard, or exhaust pile
  • statuses sitting on living units
  • behavior graphs of living enemies

All three GES event shapes work: void, single argument, and sender plus argument. The GES payload itself is not forwarded into the graph; the entry fires, and the graph reads battle state as usual.

Validation has your back

The FlowGraph validator flags an On GES Event entry with no event picked, so an empty reference never ships silently.


Behavior without GESโ€‹

GCS still compiles and runs, and every built-in event keeps working. A graph that reaches a Raise GES Event node does not crash; the internal channel logs a warning instead:

[GCSEventChannelInternal] RaiseGesEvent('...') ignored: GES integration not installed.

This is deliberate. Shared cards and test content can live in projects without GES, and the Console still tells you the integration is missing rather than swallowing the call.


What belongs on each sideโ€‹

Use the bridge for moments the rest of the game cares about: unlocking an achievement when a boss dies, advancing a quest when a card type is played, notifying a metagame controller after victory, reporting milestones to analytics, or poking scene systems that already listen through GES.

Keep ordinary combat logic inside GCS: damage, healing, statuses, card movement, energy, targeting, and battle-only reactions. A card should stay readable from its own FlowGraph. The bridge is an integration boundary, not a second place to author card behavior.


Troubleshootingโ€‹

SymptomCheck
Raise GES Event logs that the integration is not installed.Confirm GES is in the project and TinyGiants.GES.Runtime exists, then let Unity reload so TG_GES_INSTALLED updates.
Warning: GameEventManager not found in scene.Add or initialize the GES manager in the scene before the battle raises the event.
Warning: the GES event GUID was not found.Repick the event on the node; the stored GUID no longer matches an existing GES event.
The argument arrives as null.The argument type must resolve and the selected source must produce a value of that type. Repicking the event refills the type.
A sender-aware event raises with the argument only.The target GES event type has no matching sender-plus-argument raise, so the bridge fell back.
On GES Event never fires.The event must be picked on the node and active when the battle starts, and its owner (card, status, or enemy) must be in a pile or alive when the raise happens.
GCS events fire but GES listeners stay silent.The bridge forwards only explicit Raise GES Event calls. It does not mirror built-in GCS events into GES.