PureTD: Reinforcement Learning for Backgammon Money Games with No Evaluation-time Search
Organizations: Independent Researcher
Abstract
We revisit Tesauro's TD-Gammon for backgammon money games in the setting of no evaluation-time search. Both checker play and cube action (use of the doubling cube) are learned from scratch via self-play reinforcement learning (RL), with minimal hand-coded logic and no expert features. In this setting, we demonstrate that pure self-play RL suffices to train models that reach near-state-of-the-art playing strength. Specifically, for cubeful money games, our search-free model evaluates faster and is substantially stronger than the open-source engines GNU Backgammon and Open Sage running a one-move (1-ply) look-ahead search. Our method of training a cubeful model also outperforms the standard approach of training a cubeless model and deriving cubeful equity with Janowski-style formulas, when the two models are equally sized.
Figures & tables
| cube_centered | cube_own | cube_opp_own | is_cube_action | Decision for the player on roll |
|---|---|---|---|---|
| 1 | 0 | 0 | 0 | checker decision |
| 1 | 0 | 0 | 1 | cube offer (initial cube) |
| 0 | 1 | 0 | 0 | checker decision |
| 0 | 1 | 0 | 1 | cube offer (recube) |
| 0 | 0 | 1 | 0 | checker decision |
| 0 | 0 | 1 | 1 | not a legal configuration |
| Engine | vs. PureTD 0-ply (mEq/game) |
|---|---|
| gnubg , 0-ply | |
| gnubg , 1-ply | |
| Open Sage, 0-ply | |
| Open Sage, 1-ply |
| Engine | XG++ PR | vs. PureTD 0-ply (mEq/game) |
|---|---|---|
| PureTD, 0-ply | — | |
| gnubg , 0-ply | ||
| gnubg , 1-ply | ||
| Open Sage, 0-ply | ||
| Open Sage, 1-ply |
| Engine | Depth | Equity vs. PureTD (mEq/game) | dec/s (Zen 5) | dec/s (Zen 3) |
|---|---|---|---|---|
| PureTD | 0-ply | — | ||
| gnubg | 0-ply | ( ) | ( ) | |
| Open Sage | 0-ply | ( ) | ( ) | |
| gnubg | 1-ply | ( ) | ( ) | |
| Open Sage | 1-ply | ( ) | ( ) |
| Checker dec/s | Cube dec/s | |||||
|---|---|---|---|---|---|---|
| Engine | Depth | Equity vs. PureTD (mEq/game) | Zen 5 | Zen 3 | Zen 5 | Zen 3 |
| PureTD | 0-ply | — | ||||
| gnubg | 0-ply | ( ) | ( ) | ( ) | ( ) | |
| Open Sage | 0-ply | ( ) | ( ) | ( ) | ( ) | |
| gnubg | 1-ply | ( ) | ( ) | ( ) | ( ) | |
| Open Sage | 1-ply | ( ) | ( ) | ( ) | ( ) | |
| Engine | 0-ply | 1-ply | 2-ply |
|---|---|---|---|
| PureTD | |||
| gnubg | |||
| Open Sage |
| PureTD, 0-ply | Prob5Jan, 0-ply | |
|---|---|---|
| vs. PureTD 0-ply (mEq/game) | — | |
| XG++ PR | ||
| Checker PR | ||
| Cube PR |
| Model | XG++ PR | Checker PR | Cube PR | vs. PureTD, 0-ply (mEq/game) |
|---|---|---|---|---|
| PureTD | — | |||
| Lin-style ablation |
| Model | Hidden layers | Params | vs. production (mEq/game) | Checker dec/s (Zen 5) |
| Cubeful money | ||||
| 1-layer | 103k | ( ) | ||
| 2-layer | 366k | ( ) | ||
| 3-layer | 497k | ( ) | ||
| 4-layer (production) | 563k | — | ||
| 5-layer | 629k | ( ) | ||
Appendix figures & tables16 assets
Supplementary material from the paper’s appendix.
Appendix
| Engine | 1-ply move filter | Cubeless (mEq/game) | Cubeful (mEq/game) | Cubeful XG++ PR |
|---|---|---|---|---|
| gnubg | default pruning | |||
| gnubg | unpruned | |||
| Open Sage | default pruning | |||
| Open Sage | unpruned | — | — |
| Engine | Depth | Zen 5 | Zen 3 |
|---|---|---|---|
| PureTD | 0-ply | ||
| gnubg | 0-ply | ||
| Open Sage | 0-ply | ||
| PureTD | 1-ply | ||
| gnubg | 1-ply | ||
| Open Sage | 1-ply |
| Checker dec/s | Cube dec/s | ||||
|---|---|---|---|---|---|
| Engine | Depth | Zen 5 | Zen 3 | Zen 5 | Zen 3 |
| PureTD | 0-ply | ||||
| gnubg | 0-ply | ||||
| Open Sage | 0-ply | ||||
| PureTD | 1-ply | ||||
| gnubg | 1-ply | ||||
| Cubeless checker | Cubeful checker | Cubeful cube | |||||
|---|---|---|---|---|---|---|---|
| Backend | Depth | Zen 5 | Zen 3 | Zen 5 | Zen 3 | Zen 5 | Zen 3 |
| PyTorch | 0-ply | ||||||
| Optimized | 0-ply | ||||||
| PyTorch | 1-ply | ||||||
| Optimized | 1-ply | ||||||
| Matchup | Games | Uncapped | ||||
|---|---|---|---|---|---|---|
| gnubg 0-ply | ||||||
| gnubg 1-ply | ||||||
| Open Sage 0-ply | ||||||
| Open Sage 1-ply | ||||||
| Prob5Jan |
| Engine | XG++ PR (self-play) | XG++ PR (head-to-head) |
|---|---|---|
| PureTD, 0-ply | ||
| gnubg , 1-ply (unpruned) |
| Stage | Architecture Change | Type | Ep. (M) | Start LR | End LR |
|---|---|---|---|---|---|
| s1 | scratch | S | 1e-3 | const | |
| s2 | width | S | 5e-5 | const | |
| s3 | depth | S | 5e-5 | const | |
| s4 | width | S | 5e-5 | const | |
| s5 | depth | S | 5e-5 | const | |
| s6 | width | S | 5e-5 | 5e-6 |
| Stage | Architecture Change | Type | Ep. (M) | Start LR | End LR |
|---|---|---|---|---|---|
| p5_seed | cubeless equity prob5 five-output head (wu20) | S | 1e-4 | 1e-5 | |
| p5_const | — | E | 1.8e-4 | const | |
| p5_descent | — | E | 1.8e-4 | 2e-6 | |
| p5_restart | — | E | 9e-5 | 9e-6 |
| Stage | Architecture Change | Type | Ep. (M) | Start LR | End LR |
|---|---|---|---|---|---|
| cf_adapt | cubeless equity cubeful, inputs (wu20) | S | 1e-4 | const | |
| cf_seed | — | S | 6e-5 | 5e-7 | |
| cf_const | — | E | 1.8e-5 | const | |
| cf_descent | — | E | 1.8e-5 | 3e-7 | |
| cf_restart | — | E | 1.62e-5 | 2.7e-7 |
| Play | Edge | Branching factor | 95% CI |
|---|---|---|---|
| Cubeless | The on-roll player’s full turn | ||
| Cubeful | The on-roll player’s full turn, both the cube decision and the checker play | ||
| Cubeful | The on-roll player’s turn, decomposed into the cube-offer decision and the checker play | ||
| Cubeful | As above, and when a cube is offered, an added node for the opponent’s take/pass decision |
| Decision class | Difference per game [95% CI] | |
|---|---|---|
| PureTD doubles, Prob5Jan does not double | ||
| PureTD does not double, Prob5Jan doubles | ||
| PureTD takes, Prob5Jan passes | ||
| PureTD passes, Prob5Jan takes | ||
| All cube decisions | ||
| Checker play |
| Item | Identifier |
|---|---|
| Engine commit | e8847f498f7be8798c0b71314e83c8b4075f2043 |
| Fox v0.34 file | fox_v0.34_2026-09-26.ogxf |
| MD5 | 240a6a1605d58c44decf4fc3db413559 |
| Aureus v0.12 file | aureus_v0.12_2026-09-26.ogxf |
| MD5 | 379f8f20dd2b0ce05f9e24f05098fb87 |
| Model | Depth | Cubeless vs. prob5 (mEq/game) | Games | Cubeful vs. PureTD (mEq/game) | Games |
|---|---|---|---|---|---|
| Fox v0.34 | 0-ply | ||||
| Fox v0.34 | 1-ply | ||||
| Aureus v0.12 | 0-ply |
| Cubeless checker dec/s | Cubeful checker dec/s | Cube decision dec/s | ||||
|---|---|---|---|---|---|---|
| Engine | Zen 5 | Zen 3 | Zen 5 | Zen 3 | Zen 5 | Zen 3 |
| PureTD, 0-ply (reference) | ||||||
| gnubg , 0-ply | ( ) | ( ) | ( ) | ( ) | ( ) | ( ) |
| Hedgehog Fox v0.34, 0-ply | ( ) | ( ) | ( ) | ( ) | ( ) | ( ) |
| Hedgehog Aureus v0.12, 0-ply | ( ) | ( ) | ( ) | ( ) | ( ) | ( ) |
| gnubg , 1-ply | ( ) | ( ) | ( ) | ( ) | ( ) | ( ) |