Skip to main content

API guide

Guide

Use the unified GCSApi to start battles, submit player actions, read live state, modify battle state safely, and subscribe to events

Import TinyGiants.GCS.Runtime to start a battle, submit actions, or subscribe to updates through GCSApi.

using TinyGiants.GCS.Runtime;

Check state before calling​

Check GCSApi.IsReady before starting a battle. It becomes true when a GameCardManager is present. Check IsBattleActive before offering actions that need an active battle.

if (!GCSApi.IsReady)
{
return;
}

if (!GCSApi.IsBattleActive)
{
GCSApi.StartBattle(encounter);
}

Start a battle​

Pass a GameEncounter to StartBattle to replace the current battle and deal the opening hand. GCS raises OnBattleStarted after drawing the opening hand, then resolves enemy Intents.

public GameEncounter Encounter;

public void Begin()
{
GCSApi.StartBattle(Encounter);
}

Subscribe to OnBattleStarted before starting the battle to populate the hand and unit views. Use OnEnemyUnitIntentChanged to refresh the Intent display as each plan is resolved.

private IDisposable _battleStarted;

void OnEnable()
{
_battleStarted = GCSApi.OnBattleStarted(RefreshAll);
}

void OnDisable()
{
_battleStarted?.Dispose();
}

Play a card​

Read the hand, test playability, then call TryPlayCard

public void TryPlayFirstCard(UnitState target)
{
foreach (var card in GCSApi.Hand())
{
if (!GCSApi.CanPlayCard(card)) continue;
GCSApi.TryPlayCard(card, target);
return;
}
}

RequiresTarget returns true for Single Enemy, Single Ally, Other Ally, and Any Unit. Open the target picker for these modes. GCS resolves self, group, random, and untargeted cards when you submit them.

var activeCard = GCSApi.GetActiveCard(card);
if (GCSApi.RequiresTarget(activeCard))
{
ShowTargetPicker(card);
}
else
{
GCSApi.TryPlayCard(card);
}

TryPlayCard returns false when there is no active battle, the card is not in hand, energy is insufficient, the card has the Unplayable keyword, or a play Hook cancels the action

End the player turn​

public void EndTurnButton()
{
if (GCSApi.Phase == BattlePhase.PlayerPhase)
{
GCSApi.EndPlayerTurn();
}
}

EndPlayerTurn advances to the enemy phase and does nothing outside PlayerPhase, so a stray click on a stale button cannot break the turn order

Read state required by UI​

Common UI data has corresponding named query methods

turnLabel.text = GCSApi.TurnNumber.ToString();
energyLabel.text = $"{GCSApi.PlayerEnergy}/{GCSApi.MaxEnergy}";

var player = GCSApi.Player();
hpLabel.text = $"{GCSApi.Hp(player)}/{GCSApi.MaxHp(player)}";

foreach (var enemy in GCSApi.AliveEnemies())
{
RenderEnemy(enemy, GCSApi.CurrentIntentTag(enemy), GCSApi.CurrentIntentValue(enemy));
}

After an event fires, refresh from current API state. A cached copy may already be stale; runtime state is the source that UI should present

Mutate battle state safely​

External systems modify state through named GCSApi methods. These calls enter the runtime Controller, so Hooks still run and events are published normally

var player = GCSApi.Player();
GCSApi.GainArmor(player, 5);
GCSApi.DrawCards(1);
GCSApi.ApplyStatus(player, shieldedStatus, 2, player);
Update state through the public mutation APIs

Writing to UnitState.CurrentHp, UnitState.Statuses, or pile lists directly skips Hooks and events, so status reactions and UI refreshes do not receive the change. Use GCSApi mutation methods or the Controller

Victory is checked by the phase machinery

Win and loss are evaluated on phase transitions and after card plays, not on every HP write; dropping an enemy to zero HP through a mutation helper registers at the next check rather than ending the battle on the spot

Subscribe to events​

Built-in events provide shortcut subscription methods that return an IDisposable used to release the listener

private readonly List<IDisposable> _subs = new();

void OnEnable()
{
_subs.Add(GCSApi.OnEnergyChanged(_ => RefreshEnergy()));
_subs.Add(GCSApi.OnUnitHpChanged(_ => RefreshUnits()));
_subs.Add(GCSApi.OnCardDrawn(_ => RefreshHand()));
}

void OnDisable()
{
foreach (var sub in _subs) sub.Dispose();
_subs.Clear();
}

Use Subscribe<TArgs> for custom event names or direct access to the event channel

_subs.Add(GCSApi.Subscribe<DamageEventArgs>(
GCSEventNames.OnDamageDealt,
args => LogDamage(args.SourceUnitId, args.TargetUnitId, args.Amount)));

Parameterless events use Subscribe(string, Action); every built-in name is a constant on GCSEventNames, and the payload classes live in GCSEventArgs; custom events raised through RaiseGameEvent deliver their payload as IReadOnlyDictionary<string, object>, so subscribe with that as TArgs

Discover content​

GCSApi enumerates the active databases and their entities

foreach (var card in GCSApi.Cards())
{
AddCardToBrowser(card);
}

var poison = GCSApi.FindStatus(poisonGuid);

Enumeration methods build fresh lists and can allocate; cache the result for menus that refresh every frame

Maintain the Master Deck​

The Master Deck is the Run-level deck used to create card instances for later battles. StartBattle fills the draw pile from those instances

GCSApi.ClearMasterDeck();
GCSApi.AddCardToMasterDeck(strike);
GCSApi.AddCardToMasterDeck(defend, isUpgraded: true);
GCSApi.StartBattle(encounter);

Changing the Master Deck does not rewrite the piles of a battle that has already started

Save and continue​

Call GCSApi.BeginSaveAsync to capture a checkpoint while battle input is locked. Write session.Checkpoint through WriteLocalSaveAsync or your save provider, then dispose the session after committing or leaving the scene.

Use GCSSaveController to wire Save, Save and Quit, or Continue. To drive a custom flow, call RestoreCheckpointAsync and rebuild the view from OnCheckpointRestored. Save and restore covers scene mappings, custom state, and errors.

Extension registries​

Tools and debug panels can read the four extension registries through these methods

var nodes = GCSApi.NodeTypes();
var cardTypes = GCSApi.CardTypes();
var tags = GCSApi.CardTags();
var tokens = GCSApi.DescriptionTokens();

The results include custom nodes, card types, tags, and description tokens discovered in every loaded assembly that references TinyGiants.GCS.Runtime. See the API reference for the full signatures and return types.