-
Notifications
You must be signed in to change notification settings - Fork 0
chess
Fourth test game. A fundamentally different domain — turn-based, perfect information, two-player, no physics. Tests whether the system generalizes beyond real-time action games.
- No physics: No movement, no collisions, no spatial continuity. Pure rules and strategy. If the system works on chess, it's truly game-agnostic — not just "action-game-agnostic."
- Turn-based: One event per turn, not continuous streams. Tests whether the architecture handles radically different event densities.
- Two-player: First game with adversarial interaction. Both players' moves are events. The model must learn two interleaved strategies.
- Perfect information: No hidden state, no randomness. Everything is in the position. If the model fails, it's not because of partial observability.
- Existing data: Millions of recorded games with player ratings. We don't need to build agents — data already exists (Lichess database, PGN files).
- Known archetypes: Aggressive, positional, tactical, defensive, romantic, hypermodern — chess styles are well-studied and well-labeled. Ground truth for archetype validation.
- Extremely well-understood grammar: Opening theory, middlegame themes, endgame technique. If the model learns chess grammar, we can validate against centuries of human analysis.
| Aspect | Action Games | Chess |
|---|---|---|
| Time | Continuous | Discrete turns |
| Players | 1 (+ enemies) | 2 adversarial |
| Physics | Grid movement, collisions | None |
| Randomness | Food/enemy spawns | None (deterministic) |
| Event density | High (many events/tick) | Low (1 move/turn) |
| State size | Small-medium | 64 squares x 13 piece types |
| Data availability | Must generate | Millions of games exist |
| Known archetypes | Informal | Formally studied |
- 8x8 grid
- Standard initial position
- No configuration needed — chess is chess
- 6 piece types x 2 colors = 12 entity types
- Pawn, Knight, Bishop, Rook, Queen, King
- Each uniquely identified by type + starting square (standard algebraic notation handles this)
Standard chess moves. Algebraic notation is already a well-designed tokenization:
e4 # pawn to e4
Nf3 # knight to f3
Bxc6 # bishop captures on c6
O-O # kingside castle
e8=Q # pawn promotes to queen
Standard chess rules. The relevant ones for grammar learning:
piece moves to empty square → MOVE
piece moves to opponent square → CAPTURE, piece removed
pawn reaches 8th rank → PROMOTION, pawn replaced
king in check → CHECK (constrains next move)
no legal moves + in check → CHECKMATE
no legal moves + not in check → STALEMATE
king + rook, neither moved → CASTLE (special move)
pawn captures en passant → EN_PASSANT (conditional on previous move)
board: 64 squares, each empty or containing a piece
turn: WHITE or BLACK
castling: {K, Q, k, q} availability
en_passant: target square or none
halfmove_clock: moves since last capture/pawn move (50-move rule)
fullmove: move number
This is FEN (Forsyth-Edwards Notation) — already a standard compact state encoding.
Chess already has a tokenization system. Each move IS a token.
[BOS] [WHITE] e4 [BLACK] e5 [WHITE] Nf3 [BLACK] Nc6 [WHITE] Bb5 ...
Vocabulary: ~1800 possible unique moves in algebraic notation (piece x source disambiguation x destination x capture x promotion). In practice, ~200-500 distinct moves appear with reasonable frequency.
Pros: Natural, compact, interpretable, standard.
Cons: Encodes "what" but not "why." Bxc6 doesn't say it was a trade, or a sacrifice, or a tactic.
Add semantic tags to moves:
[WHITE] e4 [OPENING] [CENTER_CONTROL]
[BLACK] e5 [OPENING] [CENTER_CONTROL]
[WHITE] Nf3 [DEVELOPMENT] [ATTACKS e5]
[BLACK] Nc6 [DEVELOPMENT] [DEFENDS e5]
[WHITE] Bb5 [OPENING:RUY_LOPEZ] [PIN Nc6]
Pros: Rich semantic signal. Model can learn that "Bb5 after Nf3+Nc6" = Ruy Lopez. Cons: Annotation requires a chess engine or knowledge base. Not game-agnostic (the semantic tags are chess-specific).
Each move is followed by its mechanical effects:
[WHITE] [PIECE knight] [FROM g1] [TO f3] [ATTACKS e5 d4]
[BLACK] [PIECE knight] [FROM b8] [TO c6] [DEFENDS e5]
[WHITE] [PIECE bishop] [FROM f1] [TO b5] [ATTACKS c6]
[BLACK] [PIECE pawn] [FROM a7] [TO a6] [THREATENS b5]
Pros: Game-agnostic — this is the same event format as other games (entity, action, position, effects). Purely mechanical, no chess knowledge baked in. Cons: Verbose. Attacked/defended squares are computable from the position — is it useful to state them?
Start with Approach 1 (raw algebraic) for simplicity and because the data already exists in this format. It's essentially "pure deltas" — each move IS a state change. Add player color tokens as turn markers.
Then compare against Approach 3 to see if explicit consequences help the model.
[FEN] rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
FEN is already compact. Use it directly as a snapshot token (or tokenize each rank as a separate token).
Snapshot frequency: Every N moves. Or at phase transitions (opening → middlegame at move ~10-15, middlegame → endgame when material drops below threshold).
Chess has well-documented playing styles:
- Seeks sharp positions, sacrifices material for initiative
- Event signature: early pawn advances, piece sacrifices (captures where material is lost), checks, short games
- Historical examples: Tal, Kasparov, Nezhmetdinov
- Builds slow advantages, avoids tactics, grinds down opponent
- Event signature: many quiet moves (no captures/checks), pawn structure manipulation, piece maneuvering, long games
- Historical examples: Karpov, Petrosian, Carlsen (partially)
- Avoids risk, plays for draws with black, waits for opponent mistakes
- Event signature: symmetric pawn structures, early piece exchanges, few pawn breaks, draw offers
- Historical examples: Petrosian, early Kramnik
- Controls center from distance rather than occupying it
- Event signature: fianchetto patterns (g3+Bg2 or b3+Bb2), delayed central pawn pushes, knight maneuvers
- Historical examples: Nimzowitsch, Reti, Larsen
- Sacrifices pawns in the opening for rapid development and attack
- Event signature: early pawn sacrifices (gambits), rapid piece development, kingside attacks
- Historical examples: Morphy, Anderssen
A player's opening repertoire is their strongest stylistic fingerprint. The first 5-10 moves cluster players into style groups with high accuracy. The model should discover this naturally — opening sequences predict the character of the rest of the game.
Chess is arguably the easiest game to tokenize. Algebraic notation is compact, unambiguous, and standard. The challenge isn't "how to tokenize" but "what to add beyond the move."
FEN is 60-80 characters. If tokenized character-by-character, that's a lot of tokens per snapshot. Better to tokenize FEN at a higher level — one token per piece-on-square, or one token per rank.
The event stream alternates between two players. The model must learn to predict both sides. This is different from single-player games where there's one decision-maker.
Options:
- Interleave naturally:
[W] e4 [B] e5 [W] Nf3 ... - Separate streams: Train on white's moves and black's moves separately
- Include both: Each "event" is a pair
(white_move, black_move)
Interleaving is most natural and preserves the adversarial dynamic.
Opening, middlegame, and endgame are not marked in the move list. They're emergent categories. Can the model learn them? This is exactly the "stance detection" question from analysis.md — chess phases are stances.
Should we include engine evaluations (centipawn scores) as tokens? This would give the model access to "how good is this position" information.
[WHITE] e4 [EVAL +0.3] [BLACK] e5 [EVAL +0.2]
Tempting, but it bakes in an external model's judgment. For the Wittgensteinian framing, the grammar should emerge from use, not from an oracle's labels. Leave eval out for now, use it only for validation.
- Lichess open database: Billions of games, freely available, rated, includes time controls
- PGN format: Standard notation, trivially parseable
- Player ratings: Games are labeled with Elo ratings — can filter by skill level
- Time controls: Bullet (1 min), blitz (3-5 min), rapid (10-15 min), classical (30+ min) — different time controls produce different play styles
- Use rated games only (players are trying)
- Filter by Elo range to control skill level
- Separate by time control (bullet players play differently than classical players)
- Include player IDs for archetype clustering (same player across many games)
No data generation needed. We can start with 10,000 games and scale to millions. This is the first game where data is not the bottleneck — model capacity is.
Chess is the proving ground for game-agnosticism. If the same pipeline that learns Snake physics and Survivor archetypes can also learn:
- Legal moves from position
- Opening theory
- Tactical patterns (forks, pins, skewers) from event sequences
- Player style from move choices
...then the system genuinely captures "game grammar" as a universal concept, not just "action game event patterns."
Chess also provides the clearest archetype validation. We can take a known aggressive player (Tal) and a known positional player (Karpov), feed their games through the system, and check: does the model separate them?
- Tokenization granularity: Is one-token-per-move the right level? Or should each move be decomposed into piece + from + to + effects?
- Should the model see both sides? Training on full games teaches both attack and defense. Training on one side at a time focuses style detection. Which is more useful?
-
Rating as token: Should the players' Elo be part of the context?
[ELO 2400] [WHITE] e4 ...This would let the model learn rating-conditional behavior. Powerful but is it cheating? - Time spent per move: Available in Lichess data. A long think followed by a move carries different information than an instant move. Include as a token?
- Opening book cutoff: Many players follow memorized openings for 10-15 moves. Should we start sequences after book moves? Or include them to let the model learn opening theory?