Appearance
Entities
Entities represent the stateful objects within the game: pieces, cards, property, or functional tokens. The entities array acts as the blueprint registry for all manipulatable entities.
pieces for board games
For movement-driven board games (Chess, Checkers, ...), the same array is conventionally written as pieces instead of entities — it's the identical blueprint registry, just named for what it holds. Board pieces also commonly declare a movement grammar and lightweight triggers/actions shorthand directly on the blueprint; see Movement & Piece Actions.
Blueprint Instantiation
When you declare an entity inside the entities array, you are defining a blueprint rather than a single, unique object.
During the game's setup phase within individual Zones, you can instantiate multiple copies of these blueprints (e.g., spawning 16 duplicated Pawns in Chess or 24 identical Checkers).
Because of this architecture, whenever you reference entities using an ID selector (e.g., $entity.@Pawn or $entity.@RedChecker), the engine resolves your query as a collection of instances. Depending on the current game state, this collection could contain one, zero, or many matched instances. Operations and queries run against these selectors treat them as arrays, which allows you to efficiently query properties using aggregation, like .count or .sum.
Setup Symbols
An entity may declare an optional symbol for compact board setup notation. The symbol is a lookup key for the canonical id, not a replacement for it, and must be unique within the game:
yaml
pieces:
- id: Rook
symbol: RWith standard FEN setup, both R and r resolve to the Rook ID; letter case assigns White or Black ownership respectively. Rules and selectors continue to reference the readable Rook ID.
Entity Types and Subtypes
Entities act as data bags for state.
- Types: Usually defined as
piece,card,property, ortoken. - Properties: The mutable or static variables attached to the entity. These can define any numerical, string, or boolean value to act as arbitrary state properties like health, cost, class, tags, or value.
Entity Tags
You can label entities with top-level tags to support selector-based targeting in conditions and effects.
yaml
entities:
- id: WhiteKing
type: piece
tags:
- King
- Whitejson
{
"entities": [
{
"id": "WhiteKing",
"type": "piece",
"tags": ["King", "White"]
}
]
}Selectors can then query by tag, for example: $player.current.entities(tag: 'King').
Tracking Mutable Stats
You can track values like Health, Mana, or Cost natively inside the properties schema.
yaml
entities:
- id: BasicInfantry
type: piece
properties:
max_health: 3
current_health: 3
attack_power: 1
cost: 2
class: "Human"
role: "Soldier"json
{
"entities": [
{
"id": "BasicInfantry",
"type": "piece",
"properties": {
"max_health": 3,
"current_health": 3,
"attack_power": 1,
"cost": 2,
"class": "Human",
"role": "Soldier"
}
}
]
}Engine-Computed Read-Only Fields
Some entity values are engine-computed projections that you can reference in conditions, but must not define under properties.
Examples include:
available_moves: Derived by evaluating legal actions for entities in the referenced selector scope.is_targeted: True when the referenced entity is currently threatened/targeted by an opposing legal action.
Definition: is_targeted
is_targeted is an engine-computed, read-only boolean projection on entity selectors.
true: At least one legal opposing action can currently target the referenced entity.false: No legal opposing action can currently target the referenced entity.
Evaluation notes:
- The value is resolved against the current board state at rule-evaluation time.
- For selector collections,
is_targetedevaluates per selected entity and then resolves astrueif any selected entity is targeted. - For single-entity selectors (for example, a player's King), it resolves directly to that entity's targeted status.
Example use in a legality guard:
$player.current.entities(tag: 'King').is_targeted == false
yaml
entities:
- id: Checker
type: piece
properties:
is_king: 0
win_conditions:
- name: RedWinsNoMoves
condition: [email protected]_moves.sum == 0
winner: Red
- name: Checkmate
condition: $player.current.entities(tag: 'King').is_targeted == true and $player.current.valid_actions.count == 0
winner: $player.opponentjson
{
"entities": [
{
"id": "Checker",
"type": "piece",
"properties": {
"is_king": 0
}
}
],
"win_conditions": [
{
"name": "RedWinsNoMoves",
"condition": "[email protected]_moves.sum == 0",
"winner": "Red"
},
{
"name": "Checkmate",
"condition": "$player.current.entities(tag: 'King').is_targeted == true and $player.current.valid_actions.count == 0",
"winner": "$player.opponent"
}
]
}Do not declare read-only fields such as available_moves or is_targeted manually in an entity schema; the engine resolves them at evaluation time.
Appendix: Entities Reference
Valid Entity Types
When defining an entity in the schema, you must declare one of the following string types:
piece: A standard moving entity (e.g., a chess piece, a meeple).card: A draftable, playable element generally moving between hands and a board (e.g., poker cards, spell cards).playing_card: A built-in entity type representing a single card from a traditional 52-card deck. When instantiated in a set of 52, the engine automatically calculates and assigns uniquerankandsuitproperties for each card.token: Stackable or generic markers without complex state.property: Board-based entities that are owned but not typically moved (e.g., Monopoly properties).equipment: Entities explicitly bound to and sharing the life-cycle of another entity (e.g., attachable weapons or armor).