# Project Overview — Easy-Multiplayer

## Two Framings, One System

**Public framing (face value):**
Easy-Multiplayer — write singleplayer game code, get multiplayer for free.

**Engineering framing (what we're actually building):**
A **decentralized synchronized simulation system** — generic infrastructure for keeping many independent processes' simulations consistent over an unreliable network, with bounded rollback, semantic relevance pruning, and emergent participation. Games are the primary target use case, but the architecture is not game-specific.

Both framings matter. Public API uses game-friendly vocabulary (player, tick, input). Internal layers use simulation-generic vocabulary (participant, step, intent). New internal code should prefer the latter.

## Terminology

| Public (game-facing) | Internal (simulation-generic) | Notes |
|---|---|---|
| Game | Simulation | What's being kept in sync |
| Player | Participant | An actor that contributes inputs |
| Spectator / passive player | Passive participant | A peer whose `getLocalInputs` returns `null` |
| Tick | Simulation step | One deterministic state advancement |
| Game state | Simulation state | The thing snapshotted, hashed, restored |
| Input | Intent | Locally interpreted from raw hardware before entering simulation |
| Tick | Tick | Universal — unchanged |

## Core Innovation

The architecture is built around **semantic simulation relevance**:

- Only semantically relevant inputs matter
- Only semantically relevant corrections cause rollback
- Only semantically relevant knowledge must synchronize
- Silence is meaningful

This makes the system fundamentally different from GGPO-style rollback: it scales gracefully when most participants are passive, because passive participants generate no inputs, ship no packets, and create no rollback pressure.

## What v2 Adds Over the Current Code

(See `ARCHITECTURE.md` for the layered model, `GOALS.md` for the goal-by-goal breakdown, and `easy_multiplayer_redesign_concretized_architecture.md` for the vision document.)

- Abstract pluggable Transport layer (replaces hard-coded Trystero wiring)
- Sparse change-only input protocol
- Silence = unchanged (separate transport-level heartbeat for liveness)
- Context-aware intent construction (`getLocalInputs(localGameState)`)
- Predicate context freezing (with debug-mode mutation detection)
- Rolling hash windows + uncertainty-aware desync detection
- Tunable acceptance / grace windows
- Disconnect-as-queryable-simulation-event
- Lightweight authority + severe-desync recovery
- Memory finalization tied to grace window expiry
- **Bus-based rollback** (forthcoming, Phase C+) — parallel re-simulation workers so the visible simulation doesn't freeze during long rollbacks

## Success Criteria

- [ ] Developer can build a multiplayer game by providing: a tick function with `query`, `getLocalInputs(localState)`, and state export/import
- [ ] The same scenarios pass under both `MemoryTransport` (test) and `TrysteroTransport` (real)
- [ ] Predicate-based rollback elimination empirically reduces rollback frequency vs. naive baseline by ≥80% in a representative scenario
- [ ] Scales to 1 active + 100 passive participants with bounded message volume per passive peer
- [ ] Memory stays bounded over a 30-minute simulated session
- [ ] Determinism violations (Math.random, Date.now, etc.) are detected with clear diagnostics
- [ ] English scenario catalog of 200+ scenarios with at least 80% mechanically tested in the harness
- [ ] Visible simulation never freezes during rollback once buses are implemented (Phase C+)

## Non-Goals (this phase)

- Dynamic interest areas / spatial relevance (future research)
- Cryptographic input validation / anti-cheat
- Non-browser runtimes
- Bundling / build tooling
- Rendering (rendering-agnostic by design; Three.js integration stays optional)

## Open Research Questions

Most prior open questions were resolved during the 2026-05-25 planning session — see `DECISIONS.md` #11–21 (predicate freezing strategy, bootstrap mechanism, parameter tunability, disconnect handling philosophy, terminology framing).

Still open (tracked in `KNOWN_ISSUES.md`):

- Bus rollback implementation: parallel vs time-sliced, max concurrent buses, minimum tick gap between buses
- Determinism enforcement: override globals vs detection tool vs both
- Bootstrap "catching-up" peer state — how is it surfaced to the game layer?
- Default tunable values (acceptance window, grace window, hash interval, attendance interval)
