fix(games): carry game kind on live events + fix the New Game lock funnel
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 21s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m56s

Address review of the active-game limit lock:

- Live-event GameViews (opponent_moved, match_found, game_started, ...) did
  not carry game_kind, so a lobby patch from an event zeroed a game's kind
  and the client's per-kind count under-counted — a capped kind read as
  free (a disabled start instead of the lock, and a wrong per-kind result).
  Thread Kind through notify.GameSummary → the event GameView.

- New Game screen refreshes the lobby games on mount so the per-kind count
  reflects the current set, not a stale cached snapshot.

- The guest funnel's login button routes to the profile screen (the account
  controls), not settings.

- Copy: the guest prompt is "sign in to use all the game's features"; the
  durable notice is "finish your active games to start a new one".

Regression tests: the notify opponent-moved payload carries kind; the client
lock locks only the reached kind (vs_ai at cap leaves random open).
This commit is contained in:
Ilia Denisov
2026-07-10 10:55:48 +02:00
parent 3306a016a0
commit e40adfb0c7
9 changed files with 36 additions and 10 deletions
+8
View File
@@ -74,4 +74,12 @@ describe('isKindLocked', () => {
it('a durable account stays well under its higher cap', () => {
expect(isKindLocked([game(GameKind.random, 'active')], durable, GameKind.random)).toBe(false);
});
it('locks only the reached kind: at the vs_ai cap, random with no games stays open', () => {
const limits = { vsAi: 3, random: 2, friends: 1 };
const games = [game(GameKind.vsAi, 'active'), game(GameKind.vsAi, 'active'), game(GameKind.vsAi, 'active')];
expect(isKindLocked(games, limits, GameKind.vsAi)).toBe(true);
expect(isKindLocked(games, limits, GameKind.random)).toBe(false);
expect(isKindLocked(games, limits, GameKind.friends)).toBe(false);
});
});