@toolkit-p2p/core
v0.1.0
Published
Core utilities for toolkit-p2p: errors, sanitization, security logging
Readme
@toolkit-p2p/core
Deterministic game engine and transport interface for offline P2P multiplayer games.
Features
- ✅ Deterministic Engine: Reproducible game states with seedable PRNG
- ✅ Host Authority: Host is source of truth; clients predict + reconcile
- ✅ Transport Agnostic: Works with BLE, QR, audio, or custom transports
- ✅ Tiny Packets: Optimized for ≤20 byte inputs
- ✅ Snapshot/Rewind: Periodic authoritative snapshots with client reconciliation
- ✅ TypeScript: Fully typed with strict mode
Installation
pnpm add @toolkit-p2p/coreUsage
import { createEngine } from '@toolkit-p2p/core';
import { bleTransport } from '@toolkit-p2p/transport-ble';
type State = { tick: number; players: Record<string, { x: number; y: number }> };
type Input = { id: string; dx: number; dy: number };
const transport = bleTransport();
const engine = createEngine<State, Input>(transport, {
initialState: { tick: 0, players: {} },
reducer: (state, input) => ({
...state,
players: {
...state.players,
[input.id]: {
x: (state.players[input.id]?.x || 0) + input.dx,
y: (state.players[input.id]?.y || 0) + input.dy,
},
},
tick: state.tick + 1,
}),
authority: 'host',
tickHz: 20,
});
engine.onState((state) => console.log('State:', state));
engine.start();API
Types
Peer- Represents a peer in the networkConnection- Active connection to a peerTransport- Transport layer interface (BLE, QR, audio, etc.)EngineOpts<TState, TInput>- Engine configurationGameEngine<TState, TInput>- Engine instanceMetrics- Diagnostic metrics
Functions
createEngine<TState, TInput>(transport, opts): GameEngine
Create a game engine instance.
Parameters:
transport: Transport- The transport layer to useopts: EngineOpts<TState, TInput>- Engine configuration
Returns: GameEngine<TState, TInput>
createPRNG(seed: number)
Create a seedable pseudo-random number generator (xoshiro128**).
Parameters:
seed: number- Seed value for reproducibility
Returns: { next: () => number } - PRNG instance (returns [0, 1))
Constraints
- Reducer: Must be pure (no side effects, no
Date.now(),Math.random()) - State Size: Keep ≤200 bytes when serialized (snapshot budget)
- Input Size: Keep ≤20 bytes when serialized (packet budget)
- Tick Rate: Default 20 Hz; max 60 Hz recommended
- Players: 3–10 (host + 9 peers)
Testing
pnpm test # Run unit tests
pnpm test:integration # Run integration tests with SimTransport
pnpm typecheck # Type checkLicense
MIT © 2025 Aaron Rosenthal
