Getting Started
Installation
npm install simloopCore Concepts
Simloop is built around a few fundamental concepts:
| Concept | Description |
|---|---|
| Simulation Clock | A logical clock (number, representing arbitrary time units). Advances discretely to the timestamp of the next event. |
| Event | A timestamped action to be executed. Carries a time, a type (string tag), and a generic payload. |
| Event Queue | A min-heap priority queue ordered by (time, insertionOrder). Guarantees deterministic behavior for simultaneous events. |
| Entity | A stateful object participating in the simulation. Has a unique id and user-defined state. |
| Store | A typed object (TStore) that lives for the duration of the simulation run. Accessible as ctx.store. |
| Simulation Context | The object passed to event handlers. Provides access to the clock, entities, event-scheduling, statistics, logger, and store. |
| Simulation Engine | The orchestrator. Owns the clock, queue, entity registry, store, and lifecycle. |
Your First Simulation
Here’s a minimal single-server queue simulation:
import { SimulationEngine } from 'simloop';
type Events = {
'customer:arrive': { customerId: string };
'customer:serve': { customerId: string };
};
const sim = new SimulationEngine<Events>({ seed: 42, maxTime: 100 });
sim.on('customer:arrive', (event, ctx) => {
ctx.stats.increment('arrivals');
// Serve immediately
ctx.schedule('customer:serve', ctx.clock + 2, {
customerId: event.payload.customerId,
});
// Schedule next arrival
const nextArrival = ctx.dist.exponential(0.2)();
ctx.schedule('customer:arrive', ctx.clock + nextArrival, {
customerId: `C${ctx.stats.get('arrivals').count + 1}`,
});
});
sim.on('customer:serve', (event, ctx) => {
ctx.stats.increment('served');
});
sim.init((ctx) => {
ctx.schedule('customer:arrive', 0, { customerId: 'C1' });
});
const result = sim.run();
console.log(result.stats);Last updated on