A match ends and the #summary overlay covers the canvas with four lines — a headline, a side, a score and the person's own kills · deaths · headshots · damage — while the ten-row board the player was reading with <kbd>Tab</kbd> a second earlier is behind an opaque panel and unreachable, because the overlay takes the pointer lock and the canvas stops being drawn to.
summarize (src/client/summary.ts) reads world.me and nothing else; world.players carries name, team, kills, deaths, headshots, damage and money for all ten, and hud.ts already knows how to rank them for the in-match scoreboard. The last thing a competitive match owes you is the final table, and it is the one screen where there is all the time in the world to read it.
Done looks like
[ ] A pure function beside summarize — same module, same shape, no DOM — turns a world into the final board: both sides, each side's rows ordered the way the in-match scoreboard orders them, with the person's row marked so it can be found without reading names.
[ ] The #summary overlay renders it as a real table (<table>, a caption or heading per side), every name escaped the way the rest of game.ts escapes text, built from the same values the HUD shows so the two cannot disagree.
[ ] It reads at 360px wide with no horizontal scroll, and the two existing buttons (#again, #summary-menu) stay reachable without scrolling past the table on a phone in landscape — the table scrolls or truncates, the buttons do not move.
[ ] No layout shift: the overlay does not grow as the table is filled in.
[ ] Ranking is the same function the HUD uses, or the HUD's is moved out and both call it — there must not be two orderings of the same ten players in the repo.
[ ] Tests: the new function against a world where the person is mid-table (the marked row is theirs, the sides are complete and sorted); game.test.ts asserts a name containing < comes out escaped; summary.test.ts keeps its existing assertions.
Files
src/client/summary.ts, src/client/summary.test.ts, src/pages/game.ts, src/pages/game.test.ts, src/client/main.ts, possibly src/client/hud.ts if the ranking moves.
Risks
The scoreboard's ranking lives in hud.ts, which #120 and #183 are both holding: prefer a new pure module or an export from summary.ts over editing hud.ts, and say which you chose.
Half time swaps sides and the score with them (world.ts's half_time), so "my side" is me.team now, not the side the match started on — summarize's comment says this already and the table must follow it.
Ten rows of DOM in an overlay is a paint at the worst moment; build it once when the match ends, not every frame.
A match ends and the
#summaryoverlay covers the canvas with four lines — a headline, a side, a score and the person's ownkills · deaths · headshots · damage— while the ten-row board the player was reading with <kbd>Tab</kbd> a second earlier is behind an opaque panel and unreachable, because the overlay takes the pointer lock and the canvas stops being drawn to.summarize(src/client/summary.ts) readsworld.meand nothing else;world.playerscarriesname,team,kills,deaths,headshots,damageandmoneyfor all ten, andhud.tsalready knows how to rank them for the in-match scoreboard. The last thing a competitive match owes you is the final table, and it is the one screen where there is all the time in the world to read it.Done looks like
summarize— same module, same shape, no DOM — turns a world into the final board: both sides, each side's rows ordered the way the in-match scoreboard orders them, with the person's row marked so it can be found without reading names.#summaryoverlay renders it as a real table (<table>, a caption or heading per side), every name escaped the way the rest ofgame.tsescapes text, built from the same values the HUD shows so the two cannot disagree.#again,#summary-menu) stay reachable without scrolling past the table on a phone in landscape — the table scrolls or truncates, the buttons do not move.game.test.tsasserts a name containing<comes out escaped;summary.test.tskeeps its existing assertions.Files
src/client/summary.ts,src/client/summary.test.ts,src/pages/game.ts,src/pages/game.test.ts,src/client/main.ts, possiblysrc/client/hud.tsif the ranking moves.Risks
hud.ts, which #120 and #183 are both holding: prefer a new pure module or an export fromsummary.tsover editinghud.ts, and say which you chose.world.ts'shalf_time), so "my side" isme.teamnow, not the side the match started on —summarize's comment says this already and the table must follow it.Suggested: scout.