Mission: Bitwise-deterministic distributed simulation where independent nodes executing the same inputs always converge to identical state.
DDS-TS is a TypeScript framework for building deterministic distributed simulations that guarantee:
- ✅ Bitwise determinism across different platforms (Node.js, browsers, edge runtimes)
- ✅ Automatic divergence detection with detailed debugging reports
- ✅ Rollback & replay for handling late inputs and time-travel debugging
- ✅ Transport-agnostic networking with built-in consensus protocols
- ✅ No floating-point math - all arithmetic uses Q32.32 fixed-point
npm install
npm run build
node dist/examples/counter.jsSame initial state + same ordered inputs ⇒ identical state hash
const engine = new SimulationEngine({ initialState, step });
engine.run(1000); // Always produces same resultWall-clock time is never authoritative; simulation advances only by logical ticks.
nextState = f(previousState, inputs[tick]) // Pure, no side effects/dds-ts
├── core/ # Deterministic simulation kernel
├── math/ # Fixed-point & WASM math (Q32.32)
├── net/ # Transport-agnostic networking
├── consensus/ # Tick agreement & verification
├── rollback/ # Rewind & replay engine
├── verify/ # State hashing & divergence detection
├── tools/ # Debugging, visualization
└── examples/ # Sample simulations
import { SimulationEngine, FixedMath, FIXED_ONE } from 'dds-ts';
interface State {
count: Fixed;
}
function step(state: State, inputs: InputEvent[]): State {
let count = state.count;
for (const input of inputs) {
if (input.type === 'increment') {
count = FixedMath.add(count, FIXED_ONE);
}
}
return { count };
}
const engine = new SimulationEngine({
initialState: { count: 0n } as unknown as CanonicalData,
step: step as unknown as StepFunction<CanonicalData>,
});
engine.addInput({ tick: 10, type: 'increment', payload: null });
engine.run(20);
console.log('Final:', FixedMath.toInt(engine.getState().count));Never use JavaScript's Math or floating-point numbers!
import { FixedMath, FIXED_ONE } from 'dds-ts/math';
// ✓ Correct - deterministic
const a = FixedMath.fromInt(5);
const b = FixedMath.sin(a);
// ✗ Wrong - non-deterministic
const x = Math.sqrt(5.0);Automatic hash verification across peers:
const hash = engine.getCurrentHash();
network.broadcastHash(tick, hash);
// On receive
const isValid = engine.verifyHash(tick, remoteHash);
if (!isValid) {
console.error('DIVERGENCE DETECTED!');
// System halts automatically
}Handle late inputs with automatic rollback:
const rollback = new RollbackEngine({ snapshotInterval: 100 });
// Late input detected
const { state } = rollback.rollback(
targetTick,
currentTick,
stepFunction,
inputs,
initialState
);Synchronize multiple peers:
const transport = new MemoryTransport('peer1');
const network = new NetworkManager(transport);
const consensus = new LockstepConsensus('peer1');
// Broadcast inputs to all peers
network.broadcastInput(input);
// Verify hash agreement
network.onHash((peerId, tick, hash) => {
engine.verifyHash(tick, hash);
});- Same simulation runs on browser, Node.js, and edge runtime
- Produces identical hashes for ≥10,000 ticks
- Survives packet loss + reordering
- Detects and explains forced divergence
Always verify your simulation is deterministic:
import { DeterminismTester } from 'dds-ts/tools';
const tester = new DeterminismTester();
const result = tester.test(initialState, step, inputs, {
runs: 10, // Run 10 times
ticks: 1000 // For 1000 ticks each
});
if (!result.passed) {
console.error('DETERMINISM VIOLATED!');
process.exit(1);
}- GETTING_STARTED.md - Quick start guide
- ARCHITECTURE.md - System design & architecture
- DEVELOPMENT.md - Development guide
- PROJECT_FILES.md - File structure
- COMPLETION_CHECKLIST.md - Implementation status
Run the included examples:
# Simple counter
node dist/examples/counter.js
# 2D particle physics
node dist/examples/particles.js
# Determinism verification
node dist/examples/determinism-test.js
# Distributed simulation
node dist/examples/distributed.js
# Run all tests
node dist/test-all.jsWhen continuing this project:
- ✅ Maintain determinism at all costs
- ✅ Document every tradeoff
- ✅ Test across platforms
- ✅ Never silently ignore divergence
- ❌ Never introduce Math.random or Date.now
- ❌ Never use Maps/Sets without sorting
- ❌ Never optimize without verification
The system is minimally complete when:
- ✅ Same simulation runs on browser, Node.js, and edge runtime
- ✅ Produces identical hashes for ≥10,000 ticks
- ✅ Survives packet loss + reordering
- ✅ Detects and explains forced divergence
Status: ✅ All requirements met
- Byzantine fault tolerance
- GPU-accelerated deterministic math
- Formal verification of step functions
- Robotics / physics specialization layers
MIT
If two nodes ever disagree silently, the project has failed.
This implementation detects and halts on divergence, never continues with incorrect state.