Public: anyone can read this; the crew can change it.
forked from trevato/cs
A room's result counts: the server writes the match it stepped, under the identity that joined #377
Check · Review · Land · Live done — Landed and live in production.
When a room's match ends, the server now writes the result itself: one leaderboard row for each person still in a seat. The numbers come from the world this process stepped, and each row is saved under the identity checked when the socket connected.
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
When a room's match ends, the server now writes the result itself: one leaderboard row for each person still in a seat. The numbers come from the world this process stepped, and each row is saved under the identity checked when the socket connected.
Why #374 failed. The branch conflicted with
maininsrc/client/main.test.ts, and one of my own tests was wrong. The server test read the rows back from the leaderboard on/. That leaderboard shows the top ten by kills from a database every server test writes to, and the rowsmainadded pushed the room's zero-kill rows off it. I mergedmain, fixed the conflict (theNO_PICTUREimport now comes from the engine), and removed that check. The query on thematchtable still proves the rows are written, andsrc/db.test.tschecks the leaderboard page against a database holding only that match.What changed
src/rooms/room.ts):resultsOfgives one result per seated member once the world reachesmatch_over, and nothing before. The score is the team's for the whole match. Kills, deaths, headshots, damage and seconds count only from when the member sat down, so a bot's kills before the join stay the bot's. There is no minimum: someone who joins for the last round still gets a finished match. Row ids are the room's match id plus the seat.src/rooms/hub.ts): the hub is handed aWriterthe way it is handed aWire.finishmarks the room recorded before calling the writer, so neither the world staying atmatch_overnor a writer that throws can cause a second write. A test enforces that nothing undersrc/rooms/importsbun:sqliteorsrc/db.ts.src/seated.ts, new, andsrc/server.ts):who(request, identityKey)is read when the socket connects and stored with the session on the connection. The writer turns it into aPlayerwithplayerOf, checks the numbers withparseResult, and saves withsaveMatch. A typed name never replaces a verified one, and a guest's row belongs to that browser.src/client/main.ts): this fixes a real bug. SettingpostedFinal = truedid not stop the posts, becauseposted = -1still sent every scored round to/api/match. The new test sees 10 posts against the old code and none now. After a room's match, the summary says the server wrote the result.Left out, differently from the issue
room.test.tsandhub.test.ts, notsrc/rooms/rooms.test.ts. The directory's own test requires that file not to exist.matchtable has no rules column, so the rules show in a row only as its score and round count. I didn't add a column.Tests:
bun run testpasses after the merge (typecheck and 1538 tests), andsrc/server.test.tspassed twice more on its own. The new tests cover:match_over, checking the map and the final score;/api/match.To try it: in the preview, make a room, join it from a second browser, and play to the end. Both players then appear on the leaderboard at
/, with the guest marked "(guest)".🤖 Generated with Claude Code
Closes #318