Skip to main content

Extend card types, tags, and description tokens

Guide

Add project-specific card types, tags, and description tokens that appear in the existing authoring controls and runtime text

Newly registered entries go directly into the corresponding fields in Game Card Editor and FlowGraph; the Type, Rarity, and Tags fields in the Card-mode Inspector all receive their options from registries

Game Card Editor in Card mode, with registry options in the Type, Rarity, and Tags fields of the card Inspector

The image above shows where registration results enter the content-authoring interface; Card Type provides the primary classification and color, Card Tag provides reusable keywords, and Description Token turns runtime values into player-facing text inside Description

Card types

A card type is a card's primary classification, such as Basic, Skill, or Curse; projects can also add their own primary categories; the type participates in card filtering, type-matching cost rules, card-frame color, and the type dropdowns in Game Card Editor and FlowGraph

Inherit CardType and add [CardType]

using TinyGiants.GCS.Runtime;
using UnityEngine;

[CardType]
public sealed class PowerCardType : CardType
{
public override string Id => "Power";
public override string DisplayName => "Power";
public override Color UIColor => new Color(0.2f, 0.7f, 0.4f);
public override Color NumberAccent => new Color(0.45f, 1f, 0.65f);
}
PropertyMeaning
IdThe stable stored value used for rule matching; it must be unique and non-empty, and must not change after cards reference it
DisplayNameThe label shown in editors and on cards
UIColorThe card frame and theme color
NumberAccentOptional accent for cost and value numbers, defaulting to UIColor
tip

GCS includes five types: Basic, Skill, Curse, Support, and Burst; custom types appear beside them in the corresponding dropdowns

Card tags

A card tag marks a reusable rule or trait outside the primary type; several cards can share the same tag; GCS includes Ethereal, Exhaust, Innate, Retain, and Unplayable, while a project can add tags such as Volatile, Combo, or Bloodbound

Inherit CardTag and add [CardTag]

using TinyGiants.GCS.Runtime;

[CardTag]
public sealed class VolatileCardTag : CardTag
{
public override string Id => "Volatile";
public override string DisplayName => "Volatile";
}
PropertyMeaning
IdThe stable stored value and rule-matching key, which must be unique and non-empty
DisplayNameThe keyword label shown in Game Card Editor
IconOptional badge Sprite for the keyword, left empty by default
tip

Use a tag when several cards share a trait; use a type when a card needs a primary classification with its own visual identity

Description tokens

Description Tokens let card text update with runtime values; a card description can contain {name} or {name:args}, and the Formatter calls the Token registered under that name to produce replacement text; use {{ and }} when the text needs literal braces

GCS includes 21 Tokens, and the Demo provides 4 more that depend on preset status names; confirm that the existing entries do not already cover the required value before creating a project extension

Built-in tokenNames
Card values{Damage}, {Block}, {Heal}, {DrawCount}, {EnergyCost}, {EffectiveCost}, {X}
Status stacks{Stacks}, {StackOf}
Unit values{HP}, {MaxHP}, {Armor}, {MissingHP}
Battle counters{TurnNumber}, {HandSize}, {DrawSize}, {DiscardSize}, {ExhaustSize}
Conditional text{IfUpgraded}, {IfHasStatus}, {IfPlayerTurn}

When a project needs new dynamic text, implement IDescriptionToken and add [DescriptionToken("name")]

using TinyGiants.GCS.Runtime;

[DescriptionToken("Rage", Description = "Bonus damage from the caster's missing HP.")]
public sealed class RageToken : IDescriptionToken
{
public string Resolve(CardDescriptionContext ctx, string args)
{
var source = ctx?.Source;
if (source == null) return "0";
return ((source.MaxHp - source.CurrentHp) / 5).ToString();
}
}

Card text:

Deal 6 damage, plus {Rage} for your missing HP.

CardDescriptionContext carries:

FieldMeaning
CardThe card definition being described
InstanceThe card instance when the description is evaluated during battle
SourceThe source unit when known
TargetThe current target when known
BattleThe battle state when a battle is active
tip

Outside battle, Instance, Source, Target, and Battle may all be null; the Token must handle these cases so the card still renders correctly in editor lists and previews

Read registration results

GCS scans loaded assemblies that reference TinyGiants.GCS.Runtime, registers every concrete class with the corresponding attribute, and exposes the results through the public API

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

The dropdowns in Game Card Editor and FlowGraph read the same registries, so new entries appear after compilation and Domain Reload finish

Keep IDs stable

Registry IDs and Token names are stable contracts in saved content

ExtensionStable key
Card typeCardType.Id
Card tagCardTag.Id
Description tokenDescriptionTokenAttribute.Name
tip

A Display Name can change; an ID or Token name must not be changed directly after a saved card, filter, Description, or FlowGraph references it

Design options around the authoring workflow

  • Use card types for primary classifications, with an easy-to-distinguish color for each type

  • Use card tags for reusable keyword behavior and filtering

  • Use Description Tokens for text that must update with runtime state

  • Keep choices that can be expressed with dropdowns out of manually typed fixed IDs

  • Keep Display Names short enough to fit fully on cards and nodes

Troubleshoot registration

When a custom type, tag, or Token does not appear, check these items in order:

  1. Confirm that the class belongs to a runtime assembly that references TinyGiants.GCS.Runtime
  2. Confirm that the class is concrete, not abstract
  3. Confirm that [CardType], [CardTag], or [DescriptionToken("name")] is present
  4. Wait for Unity to finish compilation and Domain Reload
  5. Check the Console; an empty Id is skipped with a warning, while a duplicate Id replaces the entry registered earlier, so the project must guarantee uniqueness