Skip to main content

Battle Start

GCS ยท Setup

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โ€‹

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.

Automatic start with GameCardEncounterBootstrapโ€‹

GameCardEncounterBootstrap lives on the same GameObject as GameCardManager. Its fields control only the automatic-start path:

FieldDefaultWhat it controls
Default EncounterNone in a new componentThe encounter passed to GameCardManager.StartBattle when automatic start runs.
Auto Start On PlayOnStarts Default Encounter from Start. Turn this off when another system chooses the encounter.
Use GES EventsOffChooses whether the bootstrap invokes its UnityEvent or raises the configured GES events after starting the battle.
On BootstrapEmptyInvoked after the bootstrap calls StartBattle when Use GES Events is off.
On Bootstrap EventsEmptyRaised in list order after StartBattle when Use GES Events is on.

GameCardEncounterBootstrap with a default encounter assigned and Auto Start On Play enabled

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.

EventArgumentsExact timing
GCSEventNames.OnBattleStartedNoneThe player, enemies, opening deck, and opening hand exist; enemy intents are resolved next, followed by the first player-turn transition.
GCSEventNames.OnBattleRewardOfferedBattleRewardOfferedEventArgsVictory has been detected and GCS is waiting for the player to choose or skip the reward.
GCSEventNames.OnBattleEndedBattleEndedEventArgsDefeat 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โ€‹

  1. The scene has one GameCardManager with the required databases active.
  2. Automatic flow: Default Encounter is assigned and Auto Start On Play is on.
  3. Controlled flow: Auto Start On Play is off and your coordinator calls GCSApi.StartBattle.
  4. Lifecycle subscriptions are created before the start call and disposed on disable.
  5. Victory flow handles the reward before expecting OnBattleEnded.