Commit graph

10 commits

Author SHA1 Message Date
42d1732816 fix(frontend): scope player identity to a tab, not the browser
Two tabs of the same browser share localStorage, so both got the same
persisted playerId and stepped on each other: matchmaking's waiting
queue is keyed by playerId and dedupes a second queue:join as a no-op,
so two tabs searching never both count as waiting; and re-identifying
with the same playerId hijacks the ws registry's socket binding, tearing
down the first tab's connection (surfacing as room:join replying 'room
already has two players' once its creator's socket is dead).

Move playerId/name from localStorage to sessionStorage: still stable
across reloads within a tab (reconnect-by-refresh keeps the same
identity), but each new tab gets a fresh UUID, so two tabs of one
browser behave like two separate players. Not IP-related; no such
restriction existed.
2026-09-13 19:52:32 -03:00
cbc4d8a2eb feat(frontend): rebalance time modes to 2/4 min and rework scoring weights
- Bump time modes from 1/2 to 2/4 minutes across backend protocol, bot,
  timer HUD, and net message types (more room to read a snippet before
  guessing).
- Extract per-category token counts/weights into a shared
  engine/categoryStats.ts, replacing three independently-drifting
  copies of the same formula in ThemeGuessGame/botMatch/multiplayerMatch.
- Switch scoring.ts from a plain weighted average to a power-mean
  combine so whiffing a high-weight category can't be masked by acing
  the rest; retune colorUtils' similarity falloff divisor to match.
- Update solo config flow, opponent view, and renderer for the new time
  options and scoring feedback.
2026-09-13 17:36:41 -03:00
74a6ab471f feat(backend): add private-room theme-voting flow 2026-09-10 12:40:44 -03:00
a7cc3e7d8c feat(backend): add private rooms with create/join and match repeat
Implements PROTOCOL.md's private-room flow: room:create/room:join
with a collision-checked numeric code, up to a 5-match repeating
series per room via game/session.js, random-theme selection that
excludes the previous match's theme, and room:closed for matchLimit
or quit (rooms never touch matchmaking's ban store). themeMode:
'chosen' gets a narrow resolveChosenTheme() stand-in pending #7's
real theme-voting flow.

Also adds a minimal opponentName lookup to registry.js
(registerSocket's new optional name arg + getPlayerName) since
room:joined needs it, mirroring the same addition landing on #5's
branch.
2026-09-10 12:16:13 -03:00
ea003453af feat(backend): add matchmaking queue with random mode and quit ban
Registers queue:join/queue:leave handlers that FIFO-pair waiting players,
randomly assign timeMode (1 or 2, uniform) and theme via themeIds.js, and
hand off to game/session.js's createSession. Tracks a 2-minute
matchmaking-only quit ban (in-memory, resets on restart) via onEnd's
'quit' reason, scoped to sessions this module produced. Exports
isBanned() and registerMatchmakingHandlers(), wired into index.js at
boot.

Also extends ws/registry.js with a playerId -> display name store
(registerSocket's new optional third arg, getPlayerName()) so
match:found.opponentName (and future room:joined.opponentName) can be
populated; connectionHandler.js's identify handler now passes name
through.
2026-09-10 12:15:52 -03:00
611b588db6 chore(backend): add shared theme id catalog for matchmaking/rooms 2026-09-10 12:04:33 -03:00
fea76e94cc feat(backend): add match/round session engine 2026-09-10 12:03:42 -03:00
66db5b1931 feat(backend): add WS connection lifecycle and player identity registry 2026-09-10 11:54:48 -03:00
629f52caa3 docs(backend): add multiplayer protocol spec 2026-09-10 11:45:28 -03:00
970206fb99 feat(backend): scaffold matchmaking server project
Bare HTTP + WebSocket bootstrap (health check route, ws upgrade,
connection logging) with matchmaking/ and rooms/ reserved but
unimplemented. No matchmaking logic yet.

Also adds root README.md (project overview) and AGENTS.md (architecture
map, code style, git workflow).
2026-09-10 10:37:52 -03:00