Appearance
Actions
Actions are the engine's explicit state transition commands. They are the only way the game state can be modified during the phases defined in your Flow of Time. Actions can be taken to modify entities, zones, or a combination of both.
By adhering to a strict declarative structure, Actions replace "magic scripts" with explicit mathematical mutations mapping inputs to state outcomes.
Defining Actions
Actions can be contextualized in two locations:
- Global Actions: Actions defined at the root that can be called by players generally (e.g.,
PlayCard,PassTurn,MovePiece). - Entity Actions: Actions distinctly tied to an entity that an entity is capable of executing (e.g., a potion's
Consumeor a character'sHeal).
Anatomy of an Action
An Action definition requires:
name: The identifier used in phasevalid_actionswhitelists.requires_target: (Optional) Restricts what the player must select before executing the action.mutations: An array of explicit operations modifying the state of properties or zone locations.
yaml
actions:
- name: PlayCard
requires_target: $zone.@MainBoard
mutations:
- target: $entity.selected
destination: $target.zone
operation: MoveZone
- target: $player.current
property: mana
operation: -
value: $entity.selected.costjson
{
"actions": [
{
"name": "PlayCard",
"requires_target": "$zone.@MainBoard",
"mutations": [
{
"target": "$entity.selected",
"destination": "$target.zone",
"operation": "MoveZone"
},
{
"target": "$player.current",
"property": "mana",
"operation": "-",
"value": "$entity.selected.cost"
}
]
}
]
}:::
Mutations
Mutations declaratively explain the absolute mathematical change requested by the action.
Common operations include:
=(set)+(add)-(subtract)MoveZone(change an entity's parent zone)Destroy(remove an entity from the game)
Mutating Entities and Zones
You can modify combinations of entities and zones inside a single action.
yaml
entities:
- id: HealingPotion
type: card
actions:
- name: Consume
requires_target: $entity.piece
mutations:
# Mutates an entity's property
- target: $target.entity
property: current_health
operation: +
value: 2
# Mutates a zone (by moving the entity to a new zone)
- target: $entity.self
destination: $zone.@DiscardPile
operation: MoveZonejson
{
"entities": [
{
"id": "HealingPotion",
"type": "card",
"actions": [
{
"name": "Consume",
"requires_target": "$entity.piece",
"mutations": [
{
"target": "$target.entity",
"property": "current_health",
"operation": "+",
"value": 2
},
{
"target": "$entity.self",
"destination": "$zone.@DiscardPile",
"operation": "MoveZone"
}
]
}
]
}
]
}Reactions (Interrupts & Responses)
Rather than having a disconnected "Listener" concept, your actions and entities natively hold the reaction information. When an entity is capable of reacting to an opponent's move or an engine engine hook, you declare reactions inside an action or an entity. This explicitly yields priority to another player or system to take a specific action (such as playing a Trap Card, casting a Counterspell, or applying an Armor buff).
Reactions use a trigger lifecycle hook (Before or After) to determine when they interrupt typical flow.
yaml
entities:
- id: IronArmor
type: equipment
reactions:
- name: PreventDamage
trigger: $Before.$DamageTaken
condition: $entity.self.is_equipped == true
mutations:
- target: $event.damage_value
operation: -
value: 1
- id: TrapCard
type: card
actions:
- name: Counterspell
reactions:
- trigger: $Before.$ActionPlayed
condition: $event.action.type == 'spell'
mutations:
- target: $event.action
operation: Canceljson
{
"entities": [
{
"id": "IronArmor",
"type": "equipment",
"reactions": [
{
"name": "PreventDamage",
"trigger": "$Before.$DamageTaken",
"condition": "$entity.self.is_equipped == true",
"mutations": [
{
"target": "$event.damage_value",
"operation": "-",
"value": 1
}
]
}
]
},
{
"id": "TrapCard",
"type": "card",
"actions": [
{
"name": "Counterspell",
"reactions": [
{
"trigger": "$Before.$ActionPlayed",
"condition": "$event.action.type == 'spell'",
"mutations": [
{
"target": "$event.action",
"operation": "Cancel"
}
]
}
]
}
]
}
]
}Triggered Actions
Unlike a background effect or a forced reaction, a Triggered Action is an engine-prompted opportunity for a player to take a specific action after another action occurs, assuming specific conditions are met.
Common use cases include explicit follow-up choices, like responding to a specific play with an optional ability, or chaining abilities together. You define these using the triggered_actions block.
When a trigger fires, the engine automatically grants temporary priority to the eligible player. By defining optional: true (which is the default), the engine presents the player with the choice to either accept or decline executing the action. If optional: false is set, the action forces the player to resolve it (potentially requiring targets or specific choices).
yaml
triggered_actions:
- name: EnPassant
trigger: $After.@MovePiece
condition: >
$event.entity.tags.contains('Pawn') and
$event.action.distance == 2
optional: true
requires_target: $event.entity
mutations:
- target: $target.entity
destination: $zone.@Graveyard
operation: MoveZone
- target: $entity.self
destination: $event.entity.passed_location
operation: MoveZonejson
{
"triggered_actions": [
{
"name": "EnPassant",
"trigger": "$After.@MovePiece",
"condition": "$event.entity.tags.contains('Pawn') and $event.action.distance == 2",
"optional": true,
"requires_target": "$event.entity",
"mutations": [
{
"target": "$target.entity",
"destination": "$zone.@Graveyard",
"operation": "MoveZone"
},
{
"target": "$entity.self",
"destination": "$event.entity.passed_location",
"operation": "MoveZone"
}
]
}
]
} }
]
}
] }
:::
::: tip Functional Asynchronicity
By pushing trap-cards and continuous lifecycle rules into the object's `reactions`, priority is explicitly yielded to other actors, resolving complex interactions structurally without messy UI scripting!
:::
::: tip Strict Contracts
Because the engine only evaluates exactly the mutations you array inside an action, you never have to worry about an action producing a silent side-effect elsewhere in your game!
:::
## Appendix: Operations & Triggers Reference
### Valid Mutation Operations
When defining an action's `mutations`, the `operation` key must utilize one of the following:
**Arithmetic Operations:**
- `=`: Set explicit value.
- `+`: Addition assignment.
- `-`: Subtraction assignment.
- `*`: Multiplication assignment.
- `/`: Division assignment.
**Engine API Operations:**
- `MoveZone`: Reparents the entity (requires a `destination` key).
- `Destroy`: Deletes the entity entirely from all memory blocks.
- `Cancel`: Negates an event stack item entirely (used specifically during React/Response priority shifts).
- `SetProperty`: Modifies an explicit dynamic trait.
- `RequireDiscard`: Demands a user discards generic elements from a set.
- `Promote`: Alters an entity's internal identity explicitly.
- `DrawCard`: Moves the `0` index item from a stack deck to a player's hand space.
### Valid Reaction Triggers
When placing a `reaction` structure on an entity or an action intercept, you must hook into the priority state loops using standard `Before` or `After` prefixes.
Available lifecycle events:
- `Before.DamageTaken` / `After.DamageTaken`
- `Before.OnZoneEnter` / `After.OnZoneEnter`
- `Before.ActionPlayed` / `After.ActionPlayed`
- `Before.PhaseExecute` / `After.PhaseExecute`