Skip to content

refactor(worker): make game mutations atomic - #100

Merged
Poooel merged 19 commits into
mainfrom
atomic-game-state-mutations
Aug 10, 2026
Merged

refactor(worker): make game mutations atomic#100
Poooel merged 19 commits into
mainfrom
atomic-game-state-mutations

Conversation

@Poooel

@Poooel Poooel commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • move lobby initialization and game mutations into GameStateDurableObject commands
  • replace separate read and save RPCs with one atomic command per endpoint
  • preserve broadcasts, rematch behavior, and AI scheduling on newly created games

* fix(worker): return structured errors

* fix(front): validate game state messages (#102)

* feat(common): add game state schema

* fix(front): validate game state messages

* feat(game): version game state messages (#103)

* feat(common): version game state messages

* feat(game): use versioned state messages

* fix(worker): reject invalid plays (#104)

* feat(game): validate plays

* fix(worker): reject invalid plays

* fix(worker): reject client websocket messages (#105)

* feat(game): version state mutations (#106)

* feat(game): add state revisions

* feat(worker): increment state revisions

* fix(front): ignore stale game states

* feat(worker): create player identities (#107)

* chore(worker): configure player databases

* feat(common): add player credentials contract

* feat(worker): create player identities

* fix(ci): keep d1 migrations out of deploy

* feat(front): bootstrap player identity (#108)

* feat(front): bootstrap player identity

* refactor(front): remove legacy name ids

* feat: authenticate player mutations (#109)

* feat(worker): authenticate player mutations

* feat(front): send player credentials

* feat: authenticate websocket sessions (#110)

* feat(common): add websocket ticket contract

* feat(worker): authenticate websocket sessions

* feat(front): connect with websocket tickets

* feat: transfer player identities (#111)

* feat(common): add player transfer codes

* feat(worker): verify transferred identities

* feat(front): add identity transfer controls

* feat: make game mutations idempotent (#112)

* feat(worker): make game mutations idempotent

* feat(front): retry game mutations safely

* feat: add ranked player profiles (#113)

* feat(common): add elo rating model

* feat(worker): add ranked player profiles

* feat: add ranked matchmaking queue (#114)

* feat(common): add matchmaking contracts

* feat(worker): add ranked matchmaking queue

* fix(worker): parse game settings query parameters

* fix(front): restore friendly player names

* test: add automated test suite (#116)

* chore(test): configure automated test runners

* test(common): cover rules and message contracts

* test(front): cover player identity lifecycle

* test(worker): cover identity and matchmaking APIs

* test(e2e): cover game and identity flows

* ci(test): run suites before deployment

* fix(common): isolate deserialized game state

* test(front): cover reconnect and request failures

* test(worker): cover security and matchmaking edges

* test(e2e): cover reconnect and localization
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 1, 2026

Copy link
Copy Markdown

Deploying knucklebones with  Cloudflare Pages  Cloudflare Pages

Latest commit: 66104a6
Status: ✅  Deploy successful!
Preview URL: https://698e0473.knucklebones-8ep.pages.dev
Branch Preview URL: https://atomic-game-state-mutations.knucklebones-8ep.pages.dev

View logs

Poooel added 17 commits August 1, 2026 09:29
* feat(protocol): add shared runtime contracts

* feat(protocol): enforce versioned transport boundaries
* feat(game): make play commands authoritative

* refactor(front): submit column-only play intents
* feat(identity): issue per-device credentials

* feat(identity): manage device credentials
* feat(identity): add one-time transfer tokens

* feat(front): redeem secure transfer codes
* feat(identity): add recovery credentials

* feat(front): add identity recovery flow
* feat(identity): rate limit credential flows

* refactor(identity): version browser storage keys
* feat(websocket): track authenticated sessions

* feat(front): track room presence events
* feat(game): add disconnect outcomes

* feat(worker): adjudicate ranked disconnects

* feat(front): show reconnect deadlines
* fix(worker): restrict frontend origins

* ci(worker): apply migrations before deploy

* test(worker): consume error responses once

* docs(worker): clarify migration requirements
* feat(worker): add structured operational events

* docs(worker): define operational alerts
* feat(worker): secure ranked room assignments

* fix(front): report incompatible protocol versions
* feat(protocol): report sanitized client diagnostics

* test(worker): consume validation responses immediately
* fix(ranking): make Elo rounding symmetric

* feat(ranking): add ranked match persistence

* feat(matchmaking): reserve ranked assignments

* feat(matchmaking): activate ranked assignments

* feat(ranking): settle ranked results once

* feat(matchmaking): add ranked queue experience

* feat(matchmaking): apply rating-aware queue timing

* feat(matchmaking): recover expired assignments

* feat(ranking): add explicit resignation

* perf(matchmaking): avoid database reads while queued

* feat(ranking): record lifecycle metrics

* feat(ranking): label ranked game rooms

* feat(ranking): gate matchmaking rollout

* fix(identity): keep transfer modal closed

* fix(identity): initialize in background

* fix(layout): mount sidebar actions before paint

* refactor(identity): remove startup gate

* fix(game): wait for identity before opening socket

* test(e2e): wait for background identity setup

* fix(home): prevent ranked button layout shift

* feat(language): cycle through chinese locale

* fix(game): preserve settings across language changes

* Revert "fix(game): preserve settings across language changes"

This reverts commit dfc588b.

* fix(language): preserve current route

* feat(language): switch locales without reloading

* fix(button): show pointer for interactive controls

* fix(button): show pointer for icon controls

* fix(footer): update repository link

* fix(identity): generate transfer code on open

* fix(identity): align revoke checkboxes

* fix(identity): simplify recovery phrase actions

* feat(matchmaking): improve queue wait feedback

* feat(matchmaking): show queue population

* fix(matchmaking): cancel queue on page exit

* feat(matchmaking): require match acceptance

* feat(matchmaking): allow declining matches

* fix(matchmaking): avoid transient error flash

* feat(game): explain forfeit outcomes

* fix(sidebar): move ranked details below round

* feat(ranked): rematch the same opponent

* fix(sidebar): keep ranked details at bottom

* fix(board): show pointer for playable columns

* fix(spectator): hide end game actions

* feat(ux): show match rating gap and transfer QR

* fix(ranked): show settled rating after every result

* fix(sidebar): start closed on mobile

* feat(ranked): add turn timer and timeout forfeits

* fix(dev): reset local state before startup

* fix(ranked): finalize timeout handling

* fix(ranked): guarantee settlement and harden match lifecycle

- Retry ranked settlement on alarm after transient failures and escalate
  with a stuck-settlement alert after repeated attempts
- Forfeit on no-legal-move or rejected auto-move instead of hanging the alarm
- Keep releaseRankedMatch scoped to pending assignments and requeue only
  when it actually released the row
- Expire stale ranked rematch reservations on alarm and skip blocked
  players in matchmaking instead of failing the selection
- Roll optimistic moves back only when no newer authoritative state arrived
- Surface identity failures with a retry action instead of loading forever

* fix(ranked): always show play ranked button

* fix(ranked): reconnect websockets and stop disconnect-notice flicker

Enable WebSocket auto-reconnect with exponential backoff in useGameSetup so
losing connectivity (or refreshing) recovers on its own instead of idling on
a stale board. Drop the client-side ranked-assignment expiry timer that raced
the initial state load and bounced the player between the loading page and the
matchmaking lobby; the server now owns that redirect via the init 409 and the
game.error broadcast. On the worker, debounce the reconnect-deadline broadcast
by 5s so quick reconnects do not spam the opponent with disconnect notices,
and return a definite 409 when initializing against an expired assignment.
@Poooel
Poooel merged commit dc6959b into main Aug 10, 2026
2 checks passed
@Poooel
Poooel deleted the atomic-game-state-mutations branch August 10, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant