Progress / Phase 3
Phase 3: Many Players
1,000 bots and 10 or more real players share the world, your own movement feels instant thanks to prediction and reconciliation, and each player only receives what is near them.
Phase 30 / 37 · 0%
This phase is still ahead.
3.1 Shared deterministic movement
0 of 3 done- Decision Position representation: fixed-point integers (for example 1/16 pixel) so client and server compute identical results.
- Movement extracted into a pure step function with identical rules on both sides, documented in
docs/design/movement.md. - Shared test vectors: Go generates input sequences and expected positions; GDScript replays them and must match exactly.
3.2 Prediction and reconciliation
0 of 4 done- Client applies local input immediately and keeps a buffer of unacknowledged inputs.
- On each snapshot, the client rewinds to the server’s state for its player and replays pending inputs.
- Small errors are smoothed out visually; large errors snap. Corrections are counted in the debug overlay.
- Prediction can be toggled from the debug menu for side-by-side comparison.
3.3 Interest management
0 of 4 done- Decision Spatial index: a uniform grid (recommended) with a cell size chosen by measurement, updated as entities move.
- Per-player area of interest with hysteresis (enter radius smaller than leave radius) so entities don’t flicker at the edge.
- Enter and leave messages driven by area changes; snapshots include only entities in the area.
- Tests at cell boundaries and with fast movement, and a benchmark of grid updates and queries with 1,000 entities.
3.4 Bandwidth
0 of 4 done- Measure bytes per snapshot and per client per second, shown in the debug overlay and exported by the server.
- Decision Snapshot optimization on top of ADR 0008’s changed-only snapshots: quantization and smaller encodings of changed entities (for example position deltas). Implement it and measure the savings.
- Encode once with interest management: each changed entity encoded once per tick and shared by every recipient that can see it, with a benchmark showing encode cost independent of recipient count.
- Per-client bandwidth with 100 bots spread across the map, before and after interest management, in
docs/perf/phase-03.md.
3.5 Metrics and profiling
0 of 3 done- Prometheus text-format metrics on a localhost-only admin port: connections, players per zone, tick duration histogram, inbox and send-queue depth, drops, evictions, messages and bytes in and out, goroutines and GC.
- pprof on the same localhost-only admin port; one profiling pass at 1,000 bots completed and any hotspot fixed, with before and after in
docs/perf/. - Decision GC settings: measure
GOGCandGOMEMLIMITunder Case 2 load and record the chosen defaults.
3.6 Load testing
0 of 7 done- Bot swarm:
lorehallow-bot -n 100with wander, follow and idle behaviors and configurable latency. - The bot generator runs 5,000 bots from one process, with its own CPU and memory reported, and can spread bots across several source addresses to get past ephemeral-port limits.
-
make loadtestcovers the scaling.md scenariosidle,spread,crowd,churn,slowandhostile(stormandreconnectjoin in Phase 4,burstin Phase 6). - Load test script reporting tick time p50 and p99, CPU, memory and bandwidth at 10, 50 and 100 bots, with results in
docs/perf/phase-03.md. - Every Tier 1 target in scaling.md, and Case 1 Tier 2 (1,000 connections), measured on
dev-m5and recorded indocs/perf/phase-03.md. - Race detector clean during a load test run.
- One-hour soak (scaling.md short soak) on
dev-m5.
3.7 Art Batch 04: a crowd of people
0 of 2 done- Draw Batch 04 by hand: three or four player appearance variants and a townsfolk placeholder, so a crowd reads as different people.
- Intake and integrate; bots pick random appearances.
3.8 Walkthrough
0 of 2 done-
docs/walkthroughs/phase-03-many-players.md: prediction, reconciliation, fixed-point simulation, interest management, and measuring and reducing bandwidth. - Devlog draft, release notes, tag
v0.3.0and publish builds.
Acceptance criteria
0 of 8 done- With 150 ms simulated latency, your own movement responds on the next frame and corrections aren’t noticeable in normal play.
- With 100 bots spread across the map, per-client bandwidth is at least 70% lower than broadcasting everything.
- Case 1 Tier 2 (1,000 connections), Case 2 Tier 1 (100 active players) and Case 3 Tier 1 (100 in one area) in scaling.md are met on
dev-m5. - With 10% slow clients and 100 hostile bots, healthy players’ tick p99 and bandwidth stay within 10% of a clean run (scaling.md).
- The one-hour soak passes: no memory growth, flat goroutines, no tick drift.
- 100 bots on the production host keep server tick p99 under 12.5 ms (a quarter of the tick budget).
- Owner Playtest: at least 3 real players plus 200 bots on the live server feels smooth.
- The walkthrough explains prediction, reconciliation and interest management with diagrams.
