Battle Start
Use the bootstrap for a scene that always runs one encounter, or call GCSApi.StartBattle from your own map, mission, or transition flow. Lifecycle events tell the rest of your game when control enters and leaves combat.
When a GCS battle is one step inside a larger game loop rather than the whole scene.GameCardManager makes content available. Starting a battle is a separate decision: choose the GameEncounter, decide when it should begin, and decide what the rest of your game does after victory or defeat.
Choose the start pathโ
- One encounter per scene
- Map or campaign flow
Use GameCardEncounterBootstrap when entering Play Mode should always lead to one configured encounter. This fits demos, isolated battle tests, and a battle scene loaded specifically for one encounter.
Turn automatic start off and call GCSApi.StartBattle(encounter) from your own game-flow code. This fits maps, mission lists, branching campaigns, matchmaking, and any flow that chooses an encounter at runtime.
Automatic start with GameCardEncounterBootstrapโ
GameCardEncounterBootstrap lives on the same GameObject as GameCardManager. Its fields control only the automatic-start path:
| Field | Default | What it controls |
|---|---|---|
Default Encounter | None in a new component | The encounter passed to GameCardManager.StartBattle when automatic start runs. |
Auto Start On Play | On | Starts Default Encounter from Start. Turn this off when another system chooses the encounter. |
Use GES Events | Off | Chooses whether the bootstrap invokes its UnityEvent or raises the configured GES events after starting the battle. |
On Bootstrap | Empty | Invoked after the bootstrap calls StartBattle when Use GES Events is off. |
On Bootstrap Events | Empty | Raised in list order after StartBattle when Use GES Events is on. |

The inspector checks whether Default Encounter is reachable through an active encounter database. A ready status means the selection and database registration agree. If automatic start is on but the field is empty, Play Mode logs a warning and starts nothing.
The bootstrap's UnityEvent and GES list are post-start outputs of this component. They do not run when your code calls GCSApi.StartBattle, so do not use them as the only lifecycle signal for a map or campaign.
Start an encounter without the bootstrapโ
Keep GameCardManager in the battle scene, turn Auto Start On Play off, and pass the selected encounter to the public API:
using TinyGiants.GCS.Runtime;
using UnityEngine;
public sealed class EncounterLauncher : MonoBehaviour
{
[SerializeField] private GameEncounter encounter;
public void StartConfiguredEncounter()
{
if (encounter == null) return;
GCSApi.StartBattle(encounter);
}
public void StartEncounter(GameEncounter selectedEncounter)
{
if (selectedEncounter == null) return;
GCSApi.StartBattle(selectedEncounter);
}
}
A map node, UI button, quest system, or your own GES event handler can call either public method. GCS has no built-in "start encounter" event in GCSEventNames: GCSApi.StartBattle is the command, while the battle lifecycle events are notifications.
Direct start still needs the manager's active card, status, enemy, player, and deck databases to cover the content referenced by the selected encounter. Keeping the encounter itself in an active encounter database also keeps it visible to the Workbench, pickers, and GCSApi.Encounters().
Observe battle start and battle endโ
Subscribe before calling StartBattle. OnBattleStarted is raised synchronously while the battle state is being created, so a subscription added afterward misses that battle.
| Event | Arguments | Exact timing |
|---|---|---|
GCSEventNames.OnBattleStarted | None | The player, enemies, opening deck, and opening hand exist; enemy intents are resolved next, followed by the first player-turn transition. |
GCSEventNames.OnBattleRewardOffered | BattleRewardOfferedEventArgs | Victory has been detected and GCS is waiting for the player to choose or skip the reward. |
GCSEventNames.OnBattleEnded | BattleEndedEventArgs | Defeat raises it immediately with Won == false. Victory raises it with Won == true only after the reward is selected or skipped. |
GCSApi.Subscribe returns an IDisposable. Store each handle and dispose it when the listening object disables or is destroyed.
Complete map-to-battle loopโ
Place this coordinator and GameCardManager on objects that stay active while both MapRoot and BattleRoot are switched. BattleRoot should contain presentation objects, not the manager. The coordinator activates battle presentation before StartBattle, which lets its presenters subscribe before OnBattleStarted is raised.
using System;
using TinyGiants.GCS.Runtime;
using UnityEngine;
public sealed class MapEncounterFlow : MonoBehaviour
{
[SerializeField] private GameObject mapRoot;
[SerializeField] private GameObject battleRoot;
public event Action<GameEncounter> EncounterStarted;
public event Action<GameEncounter, bool> EncounterFinished;
private IDisposable battleStartedSubscription;
private IDisposable battleEndedSubscription;
private GameEncounter activeEncounter;
private void OnEnable()
{
battleStartedSubscription = GCSApi.Subscribe(
GCSEventNames.OnBattleStarted,
OnBattleStarted);
battleEndedSubscription = GCSApi.Subscribe<BattleEndedEventArgs>(
GCSEventNames.OnBattleEnded,
OnBattleEnded);
}
private void OnDisable()
{
battleStartedSubscription?.Dispose();
battleStartedSubscription = null;
battleEndedSubscription?.Dispose();
battleEndedSubscription = null;
}
public void StartMapEncounter(GameEncounter encounter)
{
if (encounter == null || GCSApi.Manager == null) return;
activeEncounter = encounter;
battleRoot.SetActive(true);
mapRoot.SetActive(false);
GCSApi.StartBattle(encounter);
}
private void OnBattleStarted()
{
EncounterStarted?.Invoke(activeEncounter);
}
private void OnBattleEnded(BattleEndedEventArgs args)
{
battleRoot.SetActive(false);
mapRoot.SetActive(true);
EncounterFinished?.Invoke(activeEncounter, args.Won);
activeEncounter = null;
}
}
Subscribe transitions or analytics to EncounterStarted, and connect save, map-node, reward, or progression logic to EncounterFinished. The important boundary is that GCS owns the battle, while your coordinator owns the game flow before and after it.
If the player abandons an unfinished battle or leaves the battle scene early, call GCSApi.DisposeBattle() before switching away. Disposal clears the live battle without raising OnBattleEnded, so run cancellation-specific map logic yourself.
Pre-Play checkโ
- The scene has one
GameCardManagerwith the required databases active. - Automatic flow:
Default Encounteris assigned andAuto Start On Playis on. - Controlled flow:
Auto Start On Playis off and your coordinator callsGCSApi.StartBattle. - Lifecycle subscriptions are created before the start call and disposed on disable.
- Victory flow handles the reward before expecting
OnBattleEnded.