Skip to Content
DocumentationSimulation Context

Simulation Context

Every handler receives a SimContext with access to the full simulation state.

API Reference

MethodDescription
ctx.clockCurrent simulation time
ctx.schedule(type, time, payload)Schedule a new event
ctx.cancelEvent(event)Cancel a scheduled event
ctx.getEntity(id)Get an entity by ID
ctx.addEntity(entity)Add an entity
ctx.removeEntity(id)Remove an entity
ctx.getAllEntities()Get all entities
ctx.storeGlobal simulation store (typed as TStore)
ctx.statsStatistics collector (numeric metrics)
ctx.random()Seeded random number (0–1)
ctx.distContext-bound distribution helper
ctx.warmUpCompletedWhether the warm-up period has ended
ctx.log(level, message)Log a message

Global Store

The store is a typed, persistent object for accumulating custom data across handlers and hooks. Initialize it via options.store and access it as ctx.store.

type Events = { tick: { value: number } }; type Store = { count: number; total: number }; const sim = new SimulationEngine<Events, Store>({ store: { count: 0, total: 0 }, }); sim.on('tick', (event, ctx) => { ctx.store.count++; ctx.store.total += event.payload.value; }); const result = sim.run(); console.log(result.store); // { count: ..., total: ... }

Mutations happen in-place — no proxy or Immer wrapper. The framework does not enforce any schema on the store shape; that is your domain.

The store is deep-cloned via structuredClone, so reset() always restores the exact original state.

Lifecycle Hooks

sim.beforeEach((event, ctx) => { /* before each event */ }); sim.afterEach((event, ctx) => { /* after each event */ }); sim.onEnd((ctx) => { /* when simulation finishes */ });
Last updated on