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
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:
@@ -37,6 +37,7 @@ func toWireGame(g GameSummary) wire.GameView {
|
||||
TurnTimeoutSecs: g.TurnTimeoutSecs,
|
||||
MultipleWordsPerTurn: g.MultipleWordsPerTurn,
|
||||
VsAI: g.VsAI,
|
||||
Kind: g.Kind,
|
||||
MoveCount: g.MoveCount,
|
||||
EndReason: g.EndReason,
|
||||
Seats: seats,
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestGameOverPayloadRoundTrips(t *testing.T) {
|
||||
func TestOpponentMovedPayloadRoundTrips(t *testing.T) {
|
||||
uid, gid := uuid.New(), uuid.New()
|
||||
move := engine.MoveRecord{Player: 1, Action: engine.ActionPlay, Words: []string{"STOOL"}, Score: 24, Total: 130}
|
||||
summary := notify.GameSummary{ID: gid.String(), MoveCount: 9, ToMove: 0, Seats: []notify.SeatStanding{{Seat: 1, Score: 130}}}
|
||||
summary := notify.GameSummary{ID: gid.String(), MoveCount: 9, ToMove: 0, Kind: 2, Seats: []notify.SeatStanding{{Seat: 1, Score: 130}}}
|
||||
in := notify.OpponentMoved(uid, gid, move, summary, 42)
|
||||
if in.Kind != notify.KindOpponentMoved {
|
||||
t.Fatalf("kind = %q", in.Kind)
|
||||
@@ -132,7 +132,7 @@ func TestOpponentMovedPayloadRoundTrips(t *testing.T) {
|
||||
if m == nil || m.Player() != 1 || string(m.Action()) != "play" || m.Total() != 130 {
|
||||
t.Fatalf("move wrong: %+v", m)
|
||||
}
|
||||
if g := ev.Game(nil); g == nil || g.MoveCount() != 9 || g.ToMove() != 0 {
|
||||
if g := ev.Game(nil); g == nil || g.MoveCount() != 9 || g.ToMove() != 0 || g.Kind() != 2 {
|
||||
t.Fatalf("game summary wrong: %+v", ev.Game(nil))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ type GameSummary struct {
|
||||
EndReason string
|
||||
Seats []SeatStanding
|
||||
LastActivityUnix int64
|
||||
// Kind is the game's origin for the active-game limits (0 unknown, 1 vs_ai, 2 random, 3 friends);
|
||||
// it rides live events so a lobby patch keeps the per-kind count correct.
|
||||
Kind int
|
||||
}
|
||||
|
||||
// AlphabetLetter is one variant alphabet entry (a display-only row) embedded in an
|
||||
|
||||
Reference in New Issue
Block a user