Chess on the ATmosphere
checkmate.blue
chess
1# checkmate.blue Roadmap
2
3## High Priority
4
5### Time Controls
6
7Chess clocks with configurable time + increment. The lexicon already has optional time control fields.
8
9- Bullet (1+0, 2+1), Blitz (3+0, 3+2, 5+0, 5+3), Rapid (10+0, 15+10), Classical (30+0)
10- Clock display on the game page with countdown timers for each player
11- Timeout detection: if a player's clock runs out, flag the game as lost on time
12- **Challenge:** No server to enforce clocks. Both clients track time independently using `lastMoveAt` timestamps from PDS records. Drift is possible but acceptable for casual play -- the bot (once deployed) could serve as an authoritative time arbiter for disputed games.
13
14### Client-Side Integrity Checks
15
16Detect tampered or invalid game records from the opponent and halt the game gracefully.
17
18- When applying an opponent's PGN, verify the new move history starts with the exact sequence we already have (no rewritten history)
19- Reject PGNs with illegal moves (chess.js `loadPgn` failure)
20- On mismatch, show a "Game state mismatch detected" banner and disable further moves
21- No PDS writes about corruption -- purely client-side detection and UI
22
23### Homepage & Game Discovery (Phase 4)
24
25Makes the platform feel alive and gives new visitors something to see.
26
27**Active games list:** Show ongoing games on the homepage sorted by most recent activity. Only canonical records (no `parentGameUri`). Display as cards with player handles, move count, last activity, and a link to spectate.
28
29**Completed games feed:** Recently finished games with results, player handles, and links to view the final position.
30
31**Blocker:** Depends on Constellation supporting global collection queries. Current options if that lands:
32- Query Constellation for all `blue.checkmate.game` records globally
33- Filter to `status: active` (or `completed`) with `parentGameUri` absent
34- Sort by `lastMoveAt`
35
36Without global queries, the alternatives are a known-players list (doesn't scale), a Jetstream firehose client-side index (complex, ephemeral), or a lightweight indexing endpoint (breaks the static SPA constraint).
37
38### Open Challenge Board (Phase 7)
39
40Browse and accept open challenges from anyone, not just targeted invites.
41
42- Public list of open challenges on the homepage via Constellation
43- Filter out expired challenges client-side (older than 24h)
44- **Same blocker as Phase 4** -- needs Constellation global query support
45
46---
47
48## Medium Priority
49
50### Lazy-Load Auth / Reduce Bundle Size
51
52The `@atproto/api` + OAuth bundle is ~854 KB (169 KB gzipped) and loads for every visitor including spectators. Dynamically import the auth module only when the user clicks "Sign in" so unauthenticated visitors never pay the cost.
53
54- Wrap `createOAuthClient` and `auth.init` behind a dynamic `import()`
55- Spectators and first-time visitors see the page instantly without loading the AT Protocol SDK
56- Authenticated users load the SDK on demand (cached after first load)
57
58### Push Notifications
59
60Browser Notification API for turn alerts, especially useful when both players aren't staring at the screen.
61
62- Request notification permission on game join
63- Notify when it's your turn (opponent made a move)
64- Notify on rematch offers, challenge invitations
65- Respect user preference (opt-in, stored in `localStorage`)
66
67### Keyboard Move Input
68
69Type moves in algebraic notation (e.g., "e4", "Nf3") instead of dragging pieces.
70
71- Input field on the game page, submit with Enter
72- Validate against legal moves via chess.js
73- Accessibility win -- screen reader friendly
74- Could support UCI notation too (e.g., "e2e4")
75
76### Rematch Timeout
77
78Auto-cleanup when a rematch goes unanswered.
79
80- After creating a rematch game, start a 5-minute countdown
81- If no opponent joins within 5 minutes, delete the waiting record via `deleteRecord` and redirect to the homepage
82- Opponent's "Dismiss" hides the notification on their end (no protocol change needed)
83
84### Orphaned Game Cleanup
85
86Let users clean up stale games that were never accepted or finished.
87
88- On the homepage or a "My Games" section, show the user's own records stuck in `waiting` status
89- Allow one-click deletion of orphaned records via `deleteRecord`
90- Consider auto-prompting on game pages: if a `waiting` game is older than 24 hours, offer to delete it
91
92### Chess Variants
93
94Support for non-standard starting positions. Add a `variant` field to the `blue.checkmate.game` lexicon and store the starting FEN in the record.
95
96**Chess960 / Fischer Random:** Randomized back-rank starting positions (960 possible arrangements). Eliminates opening theory. chess.js supports it natively. Store position number (1-960) in the record. Castling rules differ slightly (king/rook end on standard squares regardless of start position).
97
98**Daily Really Bad Chess:** Each day, a deterministic seed generates a random board with non-standard piece composition (asymmetric -- each side gets different random pieces). All players get the same board, play against the bot, compare results. Wordle-style daily challenge.
99
100- chess.js handles arbitrary FENs and generates legal moves per standard piece movement rules
101- Stockfish plays from any FEN position -- evaluation is tuned for standard chess but move generation is correct at any depth
102- Disable castling in the FEN for non-standard boards (king/rooks won't be in expected squares)
103- Seed generation: hash the date string to get a deterministic board, store the FEN in the game record
104- Leaderboard: fewest moves to checkmate, or fastest time (requires time tracking)
105
106---
107
108## Lower Priority
109
110### Board and Piece Themes
111
112Chessground supports multiple board and piece styles. Let players customize their experience.
113
114- Board themes: brown, blue, green, wood, marble, etc.
115- Piece sets: cburnett (current default), merida, alpha, Leipzig, etc.
116- Store preference in `localStorage`
117- Theme picker in a settings menu or on the game page
118
119### Player Profiles
120
121`/profile/{handle}` page showing a player's game history and record.
122
123- List completed games with results, opponents, and links to view
124- Win/loss/draw stats (queried from the player's own PDS records)
125- Without the bot's index, limited to games discoverable from the player's own repo
126
127### Follow-Graph Challenges
128
129Use the Bluesky social graph to suggest opponents.
130
131- "Challenge someone you follow" -- fetch the user's follow list, display as challenge targets
132- Shows who's online or recently active on checkmate.blue (if discoverable)
133- More social than typing in a handle manually
134
135### Puzzles
136
137Daily tactics puzzles from a public database (Lichess has a CC-licensed set with millions of puzzles).
138
139- No opponent needed -- good for engagement when nobody's online
140- Random puzzle or daily puzzle (same for everyone)
141- Track solve streak in `localStorage`
142
143### In-Game Chat
144
145Real-time messaging between players during a game.
146
147- **ATmosphere-native approach:** `blue.checkmate.message` record collection. Each player writes messages to their own PDS, opponent reads via Jetstream. Same pattern as moves. Each player owns their messages.
148- Downside: adds a new lexicon, more PDS writes, Jetstream latency
149- Alternative: link to a Bluesky thread as a public "game lobby"
150
151### Premoves / Move List Panel / Takebacks
152
153Quality-of-life features for the playing experience.
154
155- **Premoves:** queue a move while waiting for opponent (chessground supports natively)
156- **Move list panel:** algebraic notation alongside the board, clickable to step through positions
157- **Takebacks:** same pattern as draw offers -- request/accept/decline via a record field
158
159### Opening Name Display / Board Coordinates
160
161Minor polish.
162
163- Show opening name (e.g., "Sicilian Defense, Najdorf") from the ECO database
164- Toggle rank/file labels on the board (chessground supports this)
165
166### Dynamic OG Tags (Phase 2b)
167
168Per-route Open Graph meta tags for richer link previews when sharing game URLs.
169
170- Cloudflare Worker intercepts requests from known bot user agents
171- Fetches game/challenge data from the PDS
172- Returns minimal HTML with correct `og:title`, `og:description`, `og:image`
173- All other requests pass through to the static SPA
174
175| Route | og:title | og:description |
176|-------|----------|---------------|
177| `/` | checkmate.blue | Chess on the ATmosphere |
178| `/game/{did}/{rkey}` | Chess Game - {white} vs {black} | {status} - {move count} moves |
179| `/challenge/{did}/{rkey}` | Chess Challenge from {handle} | {handle} wants to play chess |
180| `/profile/{handle}` | {handle} on checkmate.blue | Chess profile |
181
182**Blocker:** Needs Cloudflare (or equivalent edge worker) set up in front of the static site.
183
184---
185
186## Separate Project: checkmate.blue Bot
187
188**Not part of this repo.** A Jetstream listener service that watches `blue.checkmate.game` records and posts game results from a `@checkmate.blue` bot account. Separate repo, separate deployment, runs as a persistent process. See `specs/bot.md` for the full specification.
189
190Responsibilities: game result posts, playable chess engine (3 difficulty levels), global game indexing with REST API, result verification, abandoned game detection.
191
192---
193
194## Completed
195
196- **Phase 1: Challenge & Invite Flow** -- Post to Bluesky, DM via clipboard, color selection, check-before-join guard
197- **Phase 2a: Branding** -- `#checkmate` wordmark, path-based favicon, PWA icons, OG image with composite board
198- **Phase 3: Spectator Mode** -- read-only view, unauthenticated viewing, dual Jetstream, game-full fallback
199- **Phase 5: Game Result Sharing** -- editable share-to-Bluesky post with facets, grapheme counting, link card embed
200- **Phase 6: Polish** -- sounds, rematch with live notification, PGN export, Lichess analysis, abandon detection, PWA
201- **Accessibility** -- WCAG 2.1 AA (focus indicators, ARIA roles, reduced motion, route titles, contrast)