Embeddable npm runtime — session lifecycle, command dispatch, snapshot extraction, and fork/restore patterns.
The session facade wraps the deterministic kernel tick loop in a managed lifecycle. It is the recommended integration surface for host applications — prefer it over calling the kernel directly. Exported under the session subpath.
Tier-1 stable API. Covered by the semantic versioning contract in STABLE_API.md.
A forked session shares no mutable state with its parent. Both branches can be stepped independently. Determinism is preserved: given the same command sequence, both produce identical tick-by-tick outcomes.
import { createSession, runSession, forkSession, serializeSession, } from '@its-not-rocket-science/ananke/session'; const session = createSession({ worldSeed: 42, tickRateHz: 20, entities: [ { id: 1, label: 'knight', archetype: 'FIGHTER' }, { id: 2, label: 'archer', archetype: 'ARCHER' }, ], }); const result = runSession(session, [ { tick: 0, type: 'MOVE', entityId: 1, target: { x_Sm: 10000, y_Sm: 0 } }, { tick: 5, type: 'ATTACK', entityId: 1, targetId: 2 }, ]); console.log(result.events); // typed SimEvent[] console.log(result.finalTick); // last stepped tick const snapshot = serializeSession(session); // → JSON string
{
"anankeVersion": "0.5.0",
"sessionId": "s_42_1748736000",
"worldSeed": 42,
"tickRateHz": 20,
"currentTick": 100,
"entities": {
"1": { "id": 1, "label": "knight", "vitals": { "shock_Q": 1820 }, "...": "..." },
"2": { "id": 2, "label": "archer", "vitals": { "shock_Q": 3200 }, "...": "..." }
},
"forkDepth": 0,
"parentSessionId": null
}
All numeric fields using fixed-point arithmetic store integer Q values (scale 65536). Divide by 65536 to get the floating-point equivalent for display purposes only — never use floats in the simulation path.