# Learned engine experiments — October 2026

## Decision and measured result

Ship the raw-state `104 → 128 ReLU → 1` evaluator, sparse JavaScript inference,
depth-aware transposition reuse, MTD(f) for pawn-only play, PVS for analysis and
mixed-piece play, a 1,719-position opening book, and exact two-to-four-pawn endings.
The selected checkpoint is `round2-128`. Mixed-piece positions retain the
classical evaluator; the learned evaluator becomes applicable once only pawns
remain. No new adjudication rules were introduced.

Against the exact previously deployed commit
`21971929f13660766edbb906002d45e24bafd405`:

| Equal time per move | Games | Wins | Draws | Losses | Score | Paired 95% interval |
|---|---:|---:|---:|---:|---:|---:|
| 80 ms | 400 | 271 | 64 | 65 | 75.75% | 72.5–78.875% |
| 800 ms | 40 | 23 | 8 | 9 | 67.5% | 58.75–76.25% |

All these pawn games resolved under the actual game rules. The 800 ms sample is
a smaller confirmation at the app's Standard thinking time. Final openings use
fresh seeds, paired colors, random legal opening moves, and some balanced
seven-pawn subsets. Only one pair in the large test starts from the untouched
standard position. Consequently, the opening book supplied just seven moves in
the 400-game test, and none in the 800 ms test. These results primarily measure
general play rather than memorized openings. Exact endgame lookups supplied 32
and six root moves respectively; interior uses were not separately counted.

Scores count wins as 1 and draws as 0.5. Intervals use 10,000 bootstrap resamples
of opening pairs, seeded 718. They measure sampling uncertainty for this opening
distribution; they do not account for all hardware, time-control, or model
selection effects. Timed Node processes exercise the actual browser JavaScript
engine, but are not measurements from a visitor's browser. There is no calibrated
human rating and no evidence yet that it will reliably beat the user.

Mixed-piece checks do not establish a strength gain. An initial 12-game knight
sample was 3 W / 3 D / 5 L / 1 unresolved, motivating an expanded fresh-seed test.
At 80 ms, the expanded 160 knight games were 66 W / 15 D / 67 L / 12 unresolved:
49.66% among resolved games, essentially level. The 72 fully resolved opening
pairs scored 49.31%, with interval 43.40–55.56%. Bishop and all-piece spot checks
were respectively 6 W / 0 D / 2 L / 4 unresolved and 5 W / 6 D / 1 L over 12
games each, too small for a reliable strength conclusion. Repeated positions or
180-ply caps count as unresolved, never as game-rule draws. Reporting resolved
scores can be biased if censoring differs by engine; raw counts are retained.

## Where the original 30K estimate came from

The initial sketch was a dense `193 → 128 → 32 → 3` network:

`(193+1)×128 + (128+1)×32 + (32+1)×3 = 29,059` parameters.

Those inputs were two 64-square occupancy planes, a 64-square en-passant plane,
and a turn bit. The three outputs represented win/draw/loss. This was an
architecture sketch, not an empirical optimum, and it spent parameters and
leaf-evaluation work on redundant state and an additional dense layer.

For this ruleset, a complete nonterminal pawn-only position needs:

* 48 squares for the player-to-move's pawns;
* 48 squares for the opponent's pawns;
* eight possible en-passant files, with all zero meaning no right.

Black-to-move positions are rank-reflected and colors exchanged. Turn information
is thus implicit in the oriented representation; it is not thrown away. Pawn
directions and advancement remain distinguishable. There is no repetition or
move-count draw rule requiring an additional history state. Pending promotions,
pawnless cases and terminal results are handled exactly outside the network.

The deployed topology has one global ReLU hidden layer and one scalar logit:

`(104+1)×128 + (128+1)×1 = 13,569` parameters.

Its float32 weights occupy 54,276 bytes before encoding/compression. A draw has
target 0.5. The logit is scaled by 300 and bounded for search; the UI's displayed
value is not a calibrated probability or a pawn-equivalent score. A scalar
expected outcome deliberately does not distinguish a certain draw from an
uncertain win/loss mixture.

This representation is sufficient, not a claim of minimum possible encoding or
minimum sufficient learned features. A single global layer permits interactions
between distant files and reserve tempi immediately. Sparse first-layer sums
touch only occupied input features. A convolutional trunk would share local
patterns, but ranks and edge files have different roles, and several layers
would add inference cost at each leaf. That tradeoff did not justify an untested
CNN within this CPU run. Fully connected networks are not assumed universally
superior.

## Learning and compute

Training used eight available CPU cores, 8 GiB memory, native C++ self-play, and
NumPy Adam/BCE fitting with one BLAS thread per trainer. No paid compute, GPU,
external inference service, or visitor data was used. The selected fit took
124.34 seconds in its recorded run; architecture comparisons and game generation
account for much more of the experiment than that single fit. Bounded process
pools checkpointed work and logged commands, time, exit status, and seeds.

The selected corpus contains 455,116 samples:

| Generation round | Attempted games | Search budget |
|---|---:|---|
| Bootstrap | 7,200 | 20,000 nodes per move |
| First learned iteration | 9,600 | 40,000 nodes per move |
| Second learned iteration | 7,200 | 60,000 nodes per move |
| Randomized-cap branch | 6,000 | 12,000 fast / 84,000 full nodes |
| Exact small endings | 12,000 independent positions | Solved outcome targets |

Only completed self-play games contribute outcome labels. Attempted games are
not all necessarily represented. The model metadata reports 38,613 sample-group
IDs, including independent exact positions. A separate 6,000-game Gumbel-inspired
branch was tested but was not included in the selected model's corpus.

The target mixes final outcome (65%) and searched value (35%). Draw outcome is
0.5 and search values use a logistic transform. This is fitted value learning /
approximate policy iteration, not an implementation of TDLeaf eligibility traces
or full AlphaZero. Self-play includes legal opening variation, starting subsets,
sparse positions, and earlier-model opponents. Ten percent of game groups are
held for validation; horizontal reflection stays within the assigned split.
Identical positions may still recur in different games, so playing tests are the
more important generalization check. Validation games also guide checkpoint
selection and are not a final unbiased test set.

The 140-epoch selected run chose epoch 135, with mixed-target BCE 0.44830,
outcome BCE 0.44938, and outcome Brier loss 0.09620. These are corpus metrics,
not measures of optimal-play accuracy. Data SHA-256 hashes are in the model JSON.
The packed deployed weights have SHA-256
`8e70bd24533a0448f29fef249c1614839f6db870cf5f3433fe9a229b27088709`.

## Architecture and replay experiments

Widths 16, 32, 64, 128 and 256 were tested, along with a 64→16 second hidden
layer and a 392-input model adding explicit blocked, supported and passed-pawn
maps. The initial 32-unit network was the best practical bootstrap choice;
larger models became useful after more search-generated experience.

Representative discovery comparisons (all scores include half credit for draws):

| Candidate vs reference | Conditions | Games | Candidate score |
|---|---|---:|---:|
| Initial 32 vs classical evaluator | Same native search, 20K nodes | 200 | 59.25% |
| Initial 32 vs classical evaluator | Existing JavaScript search, 60 ms | 80 | 76.875% |
| Round1 64 vs initial 32 | Native, 12 ms | 300 | 56.17% |
| Round1 128 vs initial 32 | Native, 12 ms | 300 | 56.17% |
| Round2 raw 128 vs round1 64 | JavaScript, 80 ms | 120 | 57.92% |
| Round2 augmented 64 vs round1 64 | JavaScript, 80 ms | 120 | 55.0% |
| Recent-rounds-only 128 vs selected full replay | Native | 400 | 48.375% |
| Latest-round-only 128 vs selected full replay | Native | 400 | 45.375% |

The raw 128-unit browser comparison was 51 wins, 37 draws, 32 losses; its paired
interval was 52.92–62.92%. The augmented model was 54 wins, 24 draws, 42 losses,
with interval 48.33–61.67%. These separate comparisons do not prove raw 128 is
stronger than augmented 64. They support selecting the smaller, simpler model
without a clear fixed-time improvement from the extra maps. The augmented model
had lower validation BCE (0.43545), as did raw 256 (0.44361), illustrating why
prediction loss alone did not determine deployment. Raw 256 also failed to
establish a useful playing advantage sufficient to justify twice the leaf cost.

Replay-window experiments did not improve the selected model. This is evidence
of a practical plateau in the tested recipes, not proof that further learning
cannot improve it. No weights were manually adjusted to fit the user's games.
The second supplied game is a regression fixture; the model now values White's
position after 4.c5 at +2.82 display units versus the previous +0.14. This is a
changed estimate, not a proof of a forced win or a causal explanation of the net.

## Gumbel and KataGo-inspired pilot

After obtaining a useful learned value function, a native pilot implemented
Gumbel root selection/sequential halving, completed-Q values, mixed-value
estimates, and deterministic improved-policy selection below the root. Exact
terminal outcomes can propagate through the tree. A legal-action-masked policy
head was trained from 31,158 searched labels using a frozen 32-unit value trunk
plus raw-state skip inputs. Held-out best-move accuracy was approximately 60%.

The pilot was deliberately smaller than full AlphaZero: it did not jointly
retrain a deep policy/value trunk through many generations of visit-distribution
targets. Its results therefore assess this affordable implementation, not the
upper bound of Gumbel AlphaZero.

Corrected equal-time tests against PVS using the same initial value network:

| Simulation ceiling / 8 ms time cap | Games | Score | Finding |
|---|---:|---:|---|
| 1,024 | 200 | 50.25% | 83 W / 35 D / 82 L; no clear advantage |
| 4,096 | 200 | 48.75% | No clear advantage |
| 16,384 | 200 | 48.75% | No clear advantage |

An early implementation allocated a large capped search unfairly across root
candidates. That was corrected with round-robin allocation before the above
comparisons. Earlier `gumbel-policy-*` logs are exploratory/invalid for final
method comparisons; use `gumbel-balanced-*` for the corrected evidence.

Another 6,000 games used randomized 128/896 simulation caps. Retraining with
those samples did not clearly improve the value evaluator; tested variants
scored around 49–51% against the prior reference. Policy-assisted PVS likewise
scored 51.5% over 200 games and was not adopted. A KataGo-inspired fast/full
playout-cap experiment used full-search samples selectively; it was useful as a
tested data-generation branch, but not a standalone replacement for the selected
full corpus. No Go ownership target was transplanted into this game.

The practical conclusion is to keep the Gumbel/policy machinery reproducible,
but deploy the stronger evidenced fixed-time configuration. A larger joint
policy/value experiment remains plausible; this pilot supplies no evidence that
it would be a better use of the current CPU budget than the tested search/value
system. It would need fresh paired evaluation, not an architectural promise.

## Search experiments

PVS was already present in the previous deployment. This work tested ordinary
alpha-beta, PVS, aspiration windows, MTD(f), and conservative late-move reductions.
MTD(f) repeatedly calls null-window searches and reuses bounds; a null window is
not a null move. No passing, null-move pruning, or stand-pat assumption was added.

With the same network and fixed browser-JavaScript time, MTD(f) scored 93 wins,
33 draws, 74 losses in 200 games against PVS: 54.75%, interval 50.75–58.75%.
It is used only for pawn-only play. Full-root analysis retains comparable scores
for every candidate through PVS. Mixed-piece positions keep tactical extensions;
pure-pawn play spends its budget on full-depth search and exact ending probes.
Late-move reductions and aspiration variants lacked enough consistent evidence
to ship. Incremental two-word Zobrist hashing reduced one fixed-node benchmark
from 6.03 to 5.49 seconds; it is an optimization, not a strength estimate.

The transposition table stores depth and normalized decisive scores, reusing
compatible entries across iterative deepening. Tests compare hashed versus full
position keys and MTD(f) versus full-window PVS at fixed depth. Hash collisions
have the ordinary tiny finite-key risk; the exact tablebase uses collision-free
indices. Recent-position preferences remain preferences, never draw rules.

## Precomputation and future iteration

The book contains 1,719 canonical positions generated with 1.84 billion nodes
in 224.44 wall seconds with six native workers. It covers the computer's first
three decisions along its selected replies, enumerating human alternatives.
Budgets are 4M, 2M and 1M nodes per position by round. It is not an exhaustive
opening solution. Symmetry supplies both colors and mirrored files. All stored
moves and transformations were checked against authoritative legal moves.

The exact ending data covers every two-, three-, and four-pawn placement with
both sides retaining at least one pawn. The four-pawn table has 2,724,120 entries;
the two/three-pawn table has 106,032 legal placements in a 223,488-byte layout.
The gzip payloads are approximately 165 KB and 17 KB, before base64 encoding.
Color/turn symmetry covers both turns. Active en passant is handled recursively
through exact legal successors. Outcomes include distance to a result; the
engine prefers faster wins and longer resistance in losses. No material-based
draws or repetition draws were invented.

The builder, datasets and checkpoints permit another self-play iteration and a
regenerated/deeper book without changing the app architecture. Five-pawn tables
grow combinatorially and were not built or promised. The app does not silently
train online, collect games, or run a recurring training job.

## Validation and retained evidence

* 60 automated tests pass, including existing import/export, rules and analysis
  tests plus learned evaluator, book, hashing, search and tablebase checks.
* Native/JavaScript rules agree on 5,000 positions and 45,567 legal successors,
  with 30 shallow search comparisons.
* Independent JavaScript solving checks every two-pawn placement for both turns,
  1,500 random three/four-pawn positions, en passant, and counterpromotion.
* Model inference was compared between native and JavaScript implementations;
  packed selected weights were also compared against reference inference.
* Interactive browser/screenshot QA was unavailable in this build environment.
  UI integration is covered by DOM/worker doubles and asset checks.

`final-summary.json` contains final counts and intervals. Raw match traces,
training logs, command records and model metadata are retained alongside the
source. Historical failed test logs, if present, describe intermediate states;
`final-tests.log` and `final-differential.log` are the final verification records.

## Primary references

* Baxter, Tridgell and Weaver, [TDLeaf](https://arxiv.org/abs/cs/9901001).
* [Official Stockfish NNUE documentation](https://official-stockfish.github.io/docs/nnue-pytorch-wiki/docs/nnue.html).
* Danihelka et al., [Policy Improvement by Planning with Gumbel](https://davidstarsilver.wordpress.com/wp-content/uploads/2025/04/gumbel-alphazero.pdf), ICLR 2022.
* Wu, [Accelerating Self-Play Learning in Go](https://arxiv.org/abs/1902.10565), 2019.

These informed experimental choices; none guarantees strength or sample
efficiency for this variant.


## Subsequent rules correction: queen-reply-v2

The mixed-piece rules now permit capturing a newly promoted queen and continuing
play. The on-move stopping order is: moving-side queen (win unless there is an
unattacked opposing queen, then draw), no pawns or queens on either side (draw), then
stalemate (loss unless mutual or the opponent has neither pawns nor a queen).
Promotion of the last pawn wins unless the new queen can be captured on the
immediate reply; that capture draws if no pawns or queens remain. The pending
queen is resolved before pawn exhaustion. Exact rule adjudication replaces a
static estimate at a pending reply, and captures can lead to searched continuing
positions. Legacy game files remain governed by `promotion-reply-v1` until the
user explicitly applies current rules.

The earlier 60-test report above is historical. The corrected version passes
69 tests, including the attached 17...a1=Q 18.Bxa1 regression, both-color captures,
search continuation, criterion priorities, format round trips, and differential
checks across 4,000 seeded pawn positions and their legal successors. Existing
pawn weights, tables, and book data are retained unchanged. Historical
mixed-piece match results above were not rerun under this new ruleset.
