Read .github/copilot-instructions.md before making substantive engine changes. It is the detailed source of truth for this repository's engine workflow, generator behavior, Decision Queue patterns, and card-implementation rules.
Use this file as the compact default guidance:
- Prefer the
tcgengine-card-editorMCP workflow for card work. Standard sequence:get_card_infoget_zone_schemaget_helper_functionsget_implemented_examplessave_card_abilities
- Treat
.github/copilot-instructions.mdas canonical for await/codegen constraints. In particular:- Do not put
awaitinside conditionals or loops. - Do not rely on pre-
awaitlocals after anawait; recompute what you need. - Precompute chooser strings before
await $player.MZChoose(...)/ similar calls.
- Do not put
- Do not manually edit generated files such as
<RootName>/GeneratedCode/GeneratedMacroCode.php,GeneratedMacroCount.js, or generatedGeneratedUI_*.jsoutputs unless the task is specifically about the generator. - For card implementations, prefer the MCP card editor workflow: inspect card info, inspect schema/helpers/examples, save abilities through MCP, and let the generator update derived macro code.
- Add new non-generated helper logic under
<RootName>/Custom/in the most appropriate file instead of patching generated code. - Prefer built-in macro prereqs/restrictions before adding manual activation guards in
GameLogic.php. If a restriction is card-local and expressible as a generated prereq, implement it in the macro/prereq layer so selection, UI, and legality checks stay aligned. - Prefer schema/generator-backed numerical modifier macros for scalar cost adjustments. In Grand Archive this includes
MemoryCostModifier,ReserveCostModifier,PlayCostModifier, andActivationCostModifier; use the modifier framework before adding one-off cost math to manual switchboards. - When working in Grand Archive, use established helpers and effective runtime wrappers such as
EffectiveCardType,EffectiveCardSubtypes,EffectiveCardClasses, andEffectiveCardElementrather than raw card-dictionary lookups on field objects. - For per-turn single-card stat changes, use
AddTurnEffect(...)plus the correspondingObjectCurrentPower,ObjectCurrentHP, orObjectCurrentLevelswitch case inGameLogic.php. - For persistent field-object overrides, use
ApplyPersistentOverride(...); for temporary suppression, useAddTurnEffect($mzCard, 'NO_ABILITIES'). - Field-presence passives belong in
ObjectCurrentPower,ObjectCurrentHP, orObjectCurrentLevel, using the established passive-deduping pattern. - Keep Decision Queue custom handlers short, non-interactive, and tolerant of malformed parameters. Interactive flows should use the supported decision types and established
awaitpatterns described in.github/copilot-instructions.md. - Register game-specific custom Decision Queue handlers and additional activation costs in
<RootName>/Custom/GameLogic.php, not in generated code. - Use the appropriate custom file for new helpers:
- combat helpers ->
CombatLogic.php - materialize helpers ->
MaterializeLogic.php - general runtime/game helpers ->
GameLogic.php
- combat helpers ->
- If you change schema or generator behavior, regenerate outputs and account for the timestamped
GeneratedUI_*.jsfile behavior noted in.github/copilot-instructions.md.
Priority note:
- If this file and
.github/copilot-instructions.mdever conflict, follow the more specific rule for the files you are editing and prefer the detailed engine guidance in.github/copilot-instructions.md.