Hivemind β Bughouse TwinBoard-S, clock lineage
Networks for Hivemind, a UCI engine for Bughouse chess, trained to play on real clocks.
The TwinBoard-S networks learned bughouse with a single time-advantage bit: one team may sit (wait instead of moving) for the whole game. This lineage continues from the last of them and learns from self-play on a simulated clock instead, where a team may sit only while it actually leads, and every action it takes while on turn on both boards costs it its own move time.
Files
| File | Purpose |
|---|---|
twin-s-clock.onnx |
Latest promoted network (iteration 13) β use this one |
twin-s-clock.pt |
Its training checkpoint |
twin-s-clock-itN.onnx / .pt |
Every RL iteration's network and checkpoint, promoted or not |
twin-s-clock-it0.onnx / .pt |
The starting point: twin-s-noattn iteration 10, before any clock training |
Clock inputs
Same TwinBoardNet (twin-s, no attention) as the TwinBoard-S networks, reading 39 planes per board
(78 in all): the 37 planes of input representation version 3, plus two clock planes that both boards carry
with the same values, from the point of view of the team to move:
| Plane | Value |
|---|---|
| Lead | sign(lead) Β· min(1, log2(1 + n) / 10), where n = |lead| / the leading team's move time β how many actions the leader can afford to wait |
| Speed | log2(own move time / opponents' move time) / 5, clamped to Β±1 |
Iteration 0 reads only the 37 version-3 planes; the engine drops the clock planes for it. Training widens its first layer with zero weights for the two new planes, so iteration 1 starts out computing exactly what iteration 0 does.
Search with the clock model so the network gets real clock inputs:
setoption name TimeModel value clock
setoption name TimeLeadMs value 4200 # our lead over the diagonal opponents
setoption name TeamMoveTimeMs value 2300 # what one of our actions costs our clock
setoption name OpponentMoveTimeMs value 1500
Do not use iteration 0, or any earlier TwinBoard-S network, with TimeModel clock: they read the lead as a
permanent right to sit, and their evaluation jumps by about 26 pawns as the lead crosses zero.
Results
Through iteration 11 an iteration was promoted only if it scored at least 50 % against the network that played
its self-play; from iteration 12 it is promoted unless the upper end of its 95 % Elo CI against that network is
below 0. The chart covers iterations 1β10.
Every iteration but 9 has won its promotion match (bottom panel); iteration 9 drew level with iteration 8
(493β498β9) and was not promoted, so iteration 10 played the same generator and was matched against iteration 8.
Adding up the promoted iterations' wins (dashed line) puts iteration 10 about 290 Elo above iteration 0.
Played head-to-head against iteration 0 (solid line), iterations 2β7 all land between +155 and +200 Elo. Each
step's gain over the network before it holds up in its own match, but most of it does not show up against
iteration 0, which searches on the binary time advantage it was trained on rather than the clock. Read the
head-to-head line as the conservative measure. The match against iteration 0 stopped after iteration 7; from
iteration 11 every iteration is matched against iteration 10 instead (twin-s-clock-anchor-it10.onnx in the
training setup), a baseline that reads the clock.
| Iteration | Self-play games | Positions trained (new + replayed) | Steps | vs the previous network | vs iteration 0 (1β7) / iteration 10 (11+) |
|---|---|---|---|---|---|
| 1 | 60,000 by iteration 0 | 4.25 M | 6,226 | β | 140β58β2 (70.5 %, +151, CI +109 to +199), 200 games at 200 ms |
| 2 | 100,000 | 7.04 M + 4.25 M | 12,389 | 55β45β0 (+35, CI β10 to +81), 100 games at 1 s | 721β269β10 (+169, CI +149 to +190) |
| 3 | 106,750 | 6.84 M + 11.29 M | 15,536 | 535β462β3 (+25, CI +13 to +38) | 703β282β15 (+156, CI +137 to +176) |
| 4 | 109,700 | 7.89 M + 20.49 M | 21,563 | 512β485β3 (+9, CI β3 to +21) | 755β235β10 (+200, CI +180 to +222) |
| 5 | 105,150 | 8.66 M + 27.51 M | 26,123 | 521β473β6 (+17, CI +6 to +27) | 706β287β7 (+155, CI +137 to +174) |
| 6 | 102,000 | 7.30 M + 30.80 M | 25,740 | 518β477β5 (+14, CI +2 to +27) | 742β250β8 (+187, CI +167 to +208) |
| 7 | 200,500 | 14.31 M + 34.24 M | 37,683 | 527β470β3 (+20, CI +9 to +30) | 745β248β7 (+189, CI +170 to +210) |
| 8 | 100,500 | 7.19 M + 64.79 M | 42,166 | 191β183β1 (+7, CI β28 to +43), stopped after 375 games | β |
| 9 | 100,500 | 7.16 M + 64.94 M | 42,205 | 493β498β9 (β2, CI β12 to +9), not promoted | β |
| 10 | 100,500 | 7.09 M + 62.90 M | 41,106 | 520β479β1 (+14, CI +4 to +24) | β |
| 11 | 100,300 | 7.13 M + 0 | 10,440 | 482β506β12 (β8, CI β20 to +3), not promoted | 470β523β7 (β18, CI β30 to β7) |
| 12 | 101,500 | 7.36 M + 8.50 M | 14,932 | 488β496β16 (β3, CI β14 to +8) | 503β491β6 (+4, CI β7 to +15) |
| 13 | 103,000 | 7.43 M + 19.57 M | 20,443 | 503β488β9 (+5, CI β6 to +16) | 230β231β0 (β1, CI β33 to +31), interim: 461 of 1,000 games |
Each iteration's self-play is played by the latest promoted network at about 800 nodes per move on a simulated clock. Training starts from the previous iteration's checkpoint and takes 1.5 passes over the new positions and 0.5 over a replay window of the previous ones (the previous 3 iterations through iteration 7, 6 from iteration 8). The local training state was lost after iteration 10, so iteration 11 started from the published iteration 10 checkpoint with no replay, and the window is refilling from iteration 11 onwards. From partway through iteration 10, self-play keeps each team's search tree between its moves (tree reuse), which carries over about 13 % of each search's visits; the training targets are still the root visit counts of 800-node searches.
Matches are 1,000 games at 100 ms per move unless noted, played in colour-swapped pairs that share the opening, the starting lead and both teams' simulated move times (0.1β3 s per action). Both sides of a match always use the same engine build. Iteration 0 searches on the binary time advantage taken from the real clock, since it cannot read the clock planes. Scores are winsβlossesβdraws for the newer network; CIs are 95 %. Iteration 1 won about 70 % whether it started ahead, behind or level on the clock.
Policy strength without search
To see how much each iteration improved the network itself, separately from search, every iteration played 3,000 games against iteration 10 with its raw policy: one node per move (the root's network evaluation only, no tree search), on the same simulated clock and openings.
| Iteration | vs iteration 10 (WβLβD) | Score | Elo (95 % CI) |
|---|---|---|---|
| 1 | 1166β1740β94 | 40.4 % | β67 (β77 to β58) |
| 2 | 1221β1664β115 | 42.6 % | β52 (β61 to β43) |
| 3 | 1307β1598β95 | 45.2 % | β34 (β43 to β25) |
| 4 | 1317β1576β107 | 45.7 % | β30 (β39 to β22) |
| 5 | 1339β1551β110 | 46.5 % | β25 (β33 to β16) |
| 6 | 1356β1542β102 | 46.9 % | β22 (β30 to β13) |
| 7 | 1422β1494β84 | 48.8 % | β8 (β16 to 0) |
| 8 | 1384β1525β91 | 47.7 % | β16 (β24 to β8) |
| 9 | 1447β1461β92 | 49.8 % | β2 (β10 to +6) |
| 11 | 1478β1399β123 | 51.3 % | +9 (0 to +18) |
| 12 | 1502β1402β96 | 51.7 % | +12 (+4 to +20) |
| 13 | 1508β1387β105 | 52.0 % | +14 (+6 to +22) |
The policy improves at almost every step, but much less than the search results above: about 80 Elo from iteration 1 to 13 against about 290 summed over the promotion matches. Gains shrink as training goes on (about 60 Elo from 1 to 7, about 22 from 7 to 13). Iterations 11β13 all have stronger policies than iteration 10 even where search hides it: iteration 11 lost to iteration 10 with search (β18) but is +9 on policy alone.