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 3Registering
| Call | What 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.
provenancelists every definition that contributed, in order.
Errors name the whole chain
| Error | When |
|---|---|
DuplicateRegistration | An id is registered twice. |
MissingRegistration | A parent does not exist. provenance shows the chain, such as veteran -> soldier -> base_unit. |
CyclicDefinition | Inheritance loops. cycle shows the loop. |
InvalidDefinition | A 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.