Entities and KeyRefs

This page explains Isometry's central data model: every part of your game is a typed data record, addressed by a campaign-unique key, and entities reference one another by key through KeyRefs. Understanding this shape is what lets you build an entire game in YAML without writing code.

Introduction

In Isometry, you do not write game logic. You write data. A hero, a map, a healing spell, a patrol route, and a damage number are all the same kind of thing under the hood: an entity, a pure-data record loaded from YAML.

There are exactly 33 entity types. Each entity carries fields that describe one piece of your game, and many of those fields point at other entities. A pointer from one entity to another is a KeyRef: the key of the target entity, stored as a plain string. The engine resolves those references when the campaign loads.

Once this clicks, every other page in the manual reads the same way: define entities, wire them together with KeyRefs.

Prerequisites

The shape of an entity

Every entity file follows one shape, with no exceptions:

<Type>:
  <key>:
    <field>: <value>

The outer key is the entity type, one of the 33 valid type names. The next key is the entity key, a name you choose that must be unique across the whole campaign. The inner dictionary holds the entity's fields.

Here is an example Main entity, the single record that defines a campaign's starting state:

Main:
  demoMain:
    actor: heroActor
    map: demoMap

Main is the type. demoMain is the key. The two fields, actor and map, are both KeyRefs — covered in the next section.

Note: The entity key is the top-level YAML key, not a field inside the entity. You never write a "key" field; the key is the name you nest the entity under.

Entities are pure data

An entity holds data and nothing else. There is no behavior inside an Actor or a Map record. Each entity type only declares its fields. Logic lives elsewhere — actions, strategies, and the engine itself act on entity data. This separation is why the same loader handles every type.

Many entities in one file

You are not limited to one entity per file. A single YAML file can contain several types and several keys; the loader merges every YAML and JSON file in the campaign into one dataset before validating. A heroActor.yaml can do exactly this — holding an Actor and a Vector side by side:

Actor:
  heroActor:
    name: Hero
    sprite: heroSprite
Vector:
  heroStartPos:
    x: 200
    y: 100

Organize files however suits you. The engine sees the merged whole, so file boundaries are for your convenience, not the engine's.

Referencing other entities with KeyRefs

Entities rarely stand alone. An actor needs a sprite; a campaign needs a starting map. A KeyRef is how one entity points at another: you write the target entity's key as a string.

In the Main entity above, "actor": "heroActor" is a KeyRef to the Actor whose key is heroActor. "map": "demoMap" is a KeyRef to the Map whose key is demoMap. The field value is the target key — nothing more.

A KeyRef resolves to a single entity. The field is just a string.

sprite: heroSprite

This says: the actor's sprite is the Sprite entity keyed heroSprite.

Pointing at many entities with a KeyRefArray

When a field needs to reference several entities, use a KeyRefArray: an array of keys. Each element is itself a KeyRef.

A hero's skills are a KeyRefArray:

skills: [attackSkill, healSkill]

This references two Skill entities by their keys. KeyRefArrays appear all over the Actor type — resources, measures, triggers, and timers are all lists of keys.

Tip: A KeyRef holds one key string; a KeyRefArray holds an array of key strings. If a field can point at more than one entity, it is a KeyRefArray.

A worked example: the hero actor

The Actor type ties the most concepts together. Here is an example heroActor, the player-controlled character:

Actor:
  heroActor:
    name: Hero
    speed: 1.0
    sprite: heroSprite
    base: 8
    public:
    - health
    private:
    - health
    - mana
    - gold
    skills:
    - attackSkill
    - healSkill
    perception: 25
    salience: 1
    menu: heroMenu
    resources:
    - health
    - mana
    - gold
    measures:
    - luckMeasure
    triggers:
    - deathTrigger
    timers:
    - regenTimer
    group: playerGroup

Read the fields by kind:

Every key in this file — heroSprite, attackSkill, health, playerGroup, and the rest — is defined as its own entity elsewhere in the campaign. The Actor record only points; it does not contain those entities.

Each guide covers the fields of the types it builds.

Keys must be unique

An entity key must be unique within its type. If two entities in the same type share a key, the loader keeps the first and warns about the conflict, dropping the duplicate's data. Choose distinct keys.

References are checked before the campaign loads

KeyRefs are checked up front. Before any entity is created, the campaign validator cross-checks that every referenced key actually exists. A KeyRef pointing at a key that no entity defines is a validation error, and the campaign refuses to load with a clear message. You catch broken references at load time, not mid-game.

Clean keys versus internal aliases

Always write the clean key like name; the underscore forms such as name_ are internal and never used in campaign files. A resource's bounds are min and max, never min_ or max_.

name: Hero

See also