Repository navigation
feat: play the real game together in co-op rooms - #7
Merged
Merged
Conversation
The GameRoom ran the netcode stand-in (dots and walkers), and the World's wire was JSON per field, flow fields and all. src/roomWorld.ts is the netcode World over stepWorld: a fresh run seated with the lobby's slots and the room's seed, each PlayerInput turned into an intent and its held action value into a seat action on the tick it changes, presence into setPresence, interpolation of players, zombies, and bullets, and own-player prediction from walkLeadSeat, a new export of the step's own walk. infra/worker/gameRoom.ts runs it in place of the stand-in, a Normal campaign until the lobby picks a difficulty. src/worldCodec.ts reads its codec off the World's Schemas: positions, velocities, directions, and timers quantized by field name, literals and tags as indexes, entity lists keyed by id, nested field masks, list diffs that name only what left or changed, and the tick's events beside each diff. Seeds, flow fields, stats, and single player's gates stay home. Four scripted players over a 60 ms round trip average 5.5 KB/s each, 6.6 KB/s in a crowded wave (src/roomWorld.sim.test.ts). The room now sends its last world before RoomClosed when a run ends between messages. world:check bundles and plays the room's adapter in workerd too, and fails on any runtime netcode code in it. SoundEffect moved to src/soundEffect.ts so the step's types no longer reach Web Audio. The dev page and mp:e2e play the real World, drawn as dots.
The co-op arena drew the stand-in's dots on a canvas of its own, moved by the arrow keys, with no shooting, shop, or waves. An online run is now the game's own scene, HUD, shop, and touch controls, drawn from the room's World (src/coopPlay.ts). Each frame the client derives its intent from its own input and camera, the co-op Submodel sends it with any held press and hands back the World to draw (everyone else 100 ms behind, its own player predicted from walkLeadSeat and reconciled) and the events the drawing reached, each once. The root puts its own seat in the player fields with focusSeat, so every view draws it as the player with its own camera, and makes particles, shake, popups, and sounds from the events on its cosmetic stream. Hit-stop freezes only its own picture while the events wait in the session. Swap, reload, traps, READY, buying, the exit offer, and leaving the counter go to the room as seat actions (src/update/coopRun.ts); the stall's dialog opens when the room puts the player at the counter. There is no pause: the corner holds LEAVE instead, and START WAVE reads READY, then READY! while the others choose. Teammates wear their seat's look, show their names, READY over everyone ready in a break, and a badge of their seat's color at the screen's edge when off screen. A run counts toward the player's own bests and Munchopedia kills when it ends, sends no analytics summary until RunSummary has co-op fields, and leaving the room goes home. tools/audit/coop.ts now plays a real wave with 2 or 3 pages: walking, READY, shooting, a player going down and a teammate reviving them, the wave cleared, a purchase at the stall, READY again, a rejoin, and LEAVE, and reports each page's round trip, bandwidth, and corrections. VIEWPORT=l844 or p390 shoots phones.
MULTIPLAYER.md still described the room's stand-in world and the JSON wire as what remained. It now has "What Phase 2 built": the room's World adapter, presses as held action values, the binary codec, the client drawing the room with the game's own scene, teammates' marks, the rules around an online run, the measured wire (5.15 KB/s a player on average and 6.30 KB/s in a crowded wave with four players), the checks, and what is left for later. AGENTS.md lists the new modules and the co-op audit, and the audit README describes the real wave it plays.
|
|
The four-player wire measurement played 240 s of game time beside the other sim tests on CI's small runner, and the pacing sims timed out waiting for the CPU. It now plays 150 s, still into the crowded waves of wave 4, and the recorded numbers follow it: 5.08 KB/s a player on average, 6.32 KB/s crowded. The root's online run check also returns at once outside a room, so single player's frames skip the run's Message match.
The pacing sims still timed out on CI beside the four-player wire measurement, which held a worker for most of their run. The measurement now plays 100 s, into wave 3's crowds, and each scripted client draws every fourth frame while its inputs and prediction still run every frame. The recorded numbers follow it: 4.87 KB/s a player on average, 6.21 KB/s crowded, 8.81 KB/s at the crowded p95.
The dead air sweep took 37 to 53 s on main's CI runs against a 60 s limit, and timed out at 68 to 85 s on runs that also play the co-op wire measurement. It and the spawn variety sweep now have 150 s and 90 s, which a stalled sweep still trips.
Munch Manor previewURL: https://munch-manor-pr-7.tanner-scadden.workers.dev Analytics API: https://munch-manor-api-pr-7.tanner-scadden.workers.dev/api/health Co-op dev page: https://munch-manor-mp-dev-pr-7.tanner-scadden.workers.dev (the stand-in world in a room: open it in 2 to 4 tabs) Built from commit 6a8ac32. This comment updates on every push, and the preview is destroyed when the pull request closes. |
On the preview, with 30 to 60 ms round trips, the scripted feeder walked into a doorway's crowd and the whole team went down before the revive. The feeder now walks unarmed only into zombies already in the parlour while the others hold their fire, and the link is measured over the fight while the room still sends. MULTIPLAYER.md records the preview run: 2 and 3 pages through a real wave with no problems, round trips of 28 to 40 ms, and 1.7 to 2.1 KB/s a page in wave 1.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Co-op rooms now run and draw the real game instead of the stand-in's dots (MULTIPLAYER.md, "What Phase 2 built"). Co-op stays hidden in production behind
VITE_COOP; previews have it on.src/roomWorld.ts, swapped intoinfra/worker/gameRoom.tsandsrc/coop/seam.ts):stepWorldover the lobby's seats, inputs to intents, presses to seat actions as held values applied once, presence, interpolation, own-player prediction.src/worldCodec.ts) read off the World's Schemas: quantized numbers by field, entity lists keyed by id, nested masks, list diffs, events by tick. Four players over a 60 ms round trip: 4.87 KB/s a player on average, 6.21 KB/s crowded, 8.81 KB/s at the crowded p95 (simulated); on this preview 2 and 3 pages played a real wave with round trips of 28 to 40 ms.src/coopPlay.ts,src/update/coopRun.ts): the game's own scene, HUD, shop, and touch controls from the room's World with the player's own seat focused and own camera; cosmetics and sounds from events; local hit-stop; presses to the room; no pause (LEAVE in the corner); READY in breaks; teammates' names, READY, and edge badges.world:checkwith the room's adapter in workerd,mp:e2ewith the real World, andtools/audit/coop.tsplaying a real wave (shooting, a revive, the stall, READY) with 2 or 3 pages.🤖 Generated with Claude Code