Skip to content

Definitions and prefabs ​

A definition is template data: what a "soldier" or a "big slime" starts with. A DefinitionRegistry stores definitions, resolves inheritance, validates them, and hands the result to a factory you write. gamekit never constructs classes by name and never scans folders for content.

ts
import { DefinitionRegistry, Prefab, ResolvedDefinition } from "gamekit";

class Unit {
    name: string;
    hp: int;
    attack: int;
    constructor(name: string, hp: int, attack: int) {
        this.name = name;
        this.hp = hp;
        this.attack = attack;
    }
}

const defs: DefinitionRegistry = new DefinitionRegistry();
defs.define("base_unit", { hp: 10, attack: 1 });
defs.define("soldier", { attack: 3 }, ["base_unit"]);
defs.define("veteran", { hp: 18 }, ["soldier"]);

const veteran: ResolvedDefinition = defs.resolve("veteran");
console.log("veteran: " + veteran.provenance.join(" -> "));

// You supply the factory. gamekit never constructs classes by name.
const makeUnit: Function = (def: ResolvedDefinition, context: any): Unit =>
    new Unit(def.id, def.data.hp as int, def.data.attack as int);
const prefab: Prefab = defs.createPrefab("veteran", makeUnit);
const unit: Unit = prefab.instantiate() as Unit;
console.log(unit.name + " hp " + unit.hp + " attack " + unit.attack);
text
veteran: base_unit -> soldier -> veteran
veteran hp 18 attack 3

Registering ​

CallWhat it does
define(id, data, inherits?)Creates and registers a definition.
register(definition)Registers a new Definition(id, data, inherits).
addValidator(fn)Adds a check that runs on resolve. A failure throws InvalidDefinition.
resolve(id), get(id), getRequired(id)The merged ResolvedDefinition (id, data, provenance). get returns null when missing.
instantiate(id, factory, context?)Resolves and calls factory(definition, context).
createPrefab(id, factory)A Prefab whose instantiate(context?) does the same each time.

Data is deep-copied when registered and again when resolved, so changing a runtime object never changes the registry.

Inheritance ​

inherits lists parents. They merge left to right, then the child's own data on top:

  • Plain objects and Maps merge key by key.
  • Numbers, strings, arrays and mismatched types are replaced by the child's value.
  • provenance lists every definition that contributed, in order.

Errors name the whole chain ​

ErrorWhen
DuplicateRegistrationAn id is registered twice.
MissingRegistrationA parent does not exist. provenance shows the chain, such as veteran -> soldier -> base_unit.
CyclicDefinitionInheritance loops. cycle shows the loop.
InvalidDefinitionA validator failed. Names the definition, the reason and its ancestry.

One definition, many kinds of object ​

The factory decides what to build. The same "slime" definition can become a live Entity with components in the world and a plain card in a bestiary screen. The spawning recipe builds world entities from definitions inside a phase.

Reference: DefinitionRegistry, ResolvedDefinition, Prefab.