Public: anyone can read this; the crew can change it.
forked from trevato/cs
A room is a link you send, and your friend lands on your side #378
Check · Review · Land · Live done — Landed and live in production.
A room is now a link you send, and the side you sit on is yours to pick. The second friend who asks for T sits on T, as long as a bot is still there to give up its seat.
shipped production is serving it deploy ae07c2d
A room is now a link you send, and the side you sit on is yours to pick. The branch has main merged in: main added server-written room results (#377) and a remembered Side and Length for single-player, and both are kept alongside this change. bun run test (typecheck, then 1555 tests) passes.
The link. /?room=CODE fills in the menu's room code field, and the client moves the focus to Join once the game is ready. It never joins by itself, because pointer lock needs a press. The server reads ?room= with roomCodeFrom and escapes it on the way out. A code it rejects (a script, the wrong length, a character outside the alphabet) is ignored, and the page is byte for byte the one with no parameter. Copy this room's link sits beside the code field and shows only when the field holds a valid code. While you play, the link under the stage becomes Link to this room. The link is built in one place, src/roomlink.ts.
The side. Room side (Either, Counter-Terrorists, Terrorists) sits beside the code field and is remembered as cs.roomside. The socket upgrade takes team=t|ct, and sideFrom checks it both in src/server.ts and inside join. freeSeat(room, wanted) puts you in a bot's seat on the side you asked for. If that side is all people, you go to the other side and the room line says so. A missing or junk team keeps today's balancing, and nobody already seated moves. To get the side from the socket to the room, RoomGame.join and Hub.enter in src/engine/rooms.ts take an optional asked argument that the hub passes through without reading. It is documented in GUIDE.md.
Who is here. The room line and the pause panel list each person in the room and their side, from the roster the server sends. The line changes when somebody arrives or leaves.
Where the merge met main:
- The socket's
Joinedtype is nowSeated & { team }, so it carries both the identity that #377 verifies at the upgrade and the side you asked for. - The menu's room paragraph keeps #377's sentence about who a finished match counts for, next to the text about the link and the side.
- The room-side value read back from storage is
savedRoomSide, so it does not clash with the single-playersavedSidethatmainadded.
Not done:
- You cannot see a room's people before you join, because that would let anyone holding a code read the names.
- There is no auto-join from the link.
- The terminal gets nothing new.
- The room tests went into
src/rooms/room.test.ts, because thesrc/rooms/rooms.test.tsthe issue names does not exist.
Tests changed rather than added. session.test.ts compares the whole standing() object, so two expected values gained the new fields. stage.test-helper.ts lists the page's ids and gained roomside and copyroom.
To try it in the preview: press Make a room, then Esc and Leave match, and copy the room's link. Open it in a second browser, pick Terrorists, and press Join.
🤖 Generated with Claude Code
A room is now a link you send, and the side you sit on is yours to pick. The second friend who asks for T sits on T, as long as a bot is still there to give up its seat.
The link.
/?room=CODEfills in the menu's Room code field with the code, and the client moves the focus to Join once the game is ready. It never joins by itself, because pointer lock needs a press. The server reads?room=withroomCodeFromand escapes it on the way out. Anything it rejects (a script, the wrong length, a character outside the alphabet) is ignored:server.test.tschecks that each of those links returns exactly the same bytes as/. Copy this room's link sits beside the code field and appears only when the field holds a valid code. It works like the map's copy link: a real link first, the clipboard when the browser offers one. While you play, the link under the stage becomes Link to this room. The link is built in one place,src/roomlink.ts, because both the page and the client build it.The side. Room side (Either, Counter-Terrorists, Terrorists) sits beside the code field. Like the other menu controls it is at least 44px, and it is remembered like the name (
cs.roomside). The socket upgrade takesteam=t|ct, andsideFrominsrc/rooms/room.tschecks it both insrc/server.tsand insidejoin.freeSeat(room, wanted)puts you in a bot's seat on the side you asked for. If that side is all people, you go to the other side and the room line says so in a sentence (sideFull). A missing or junkteamfalls back to the same balancing as today. Nobody who is already seated is moved, and five friends against five bots is allowed without being rebalanced.Engine change to review. To get the side from the socket to the room,
RoomGame.joinandHub.enterinsrc/engine/rooms.tstake an optionalaskedargument. The hub passes it through without reading it, and it is documented inGUIDE.md. This is a change to the shared engine interface rather than to the game alone.Who is here. The client session now keeps the latest roster: who is here, their side, and your own side.
roomLineturns it into text such asRoom 8UTZQR — In the room. 2 here: ada (T), you (you, CT).That line appears on the menu's room line and in the pause panel, and it changes whenever the server sends a new roster.Not done:
src/rooms/rooms.test.ts, which does not exist, so the room tests went intosrc/rooms/room.test.ts.Tests. Each test below would fail without this change:
room.test.ts: two joins asking for T both land on T; a join asking for a full side lands on the other; junk or no side matches the balanced seat.hub.test.ts: the side reaches the room'sjoin.server.test.ts:team=over real sockets, and the byte-identical junk?room=pages.game.test.ts: the field prefilled, the link, the side control, and escaping.session.test.ts: the room line and the full-side sentence.main.test.ts: Join gets the focus with no join,teamis in the socket URL, the side is remembered, and the link copies.Two existing tests changed.
session.test.tscompares the wholestanding()object, so two expected values gained the new fields.stage.test-helper.tslists the page's ids, so it gainedroomsideandcopyroom. The README's rooms section now says a room is a link and a side.bun run test(typecheck, then 1526 tests) passes.To try it in the preview: press Make a room, then Esc and Leave match, and copy the room's link from the menu. Open it in a second browser, pick Terrorists, and press Join.
🤖 Generated with Claude Code
Closes #315