Wintersalmon | Blog

270 generations of self-play: the clever tricks lost to raw capacity

10 min read

The clever tricks lost; capacity won

The YINSH bot that plays on my home cluster is one strand of a larger experiment — building board games as the daily vehicle for an LLM-driven dev flow — and it is the strand that keeps teaching me where the real limits are. Stepping back before I upgrade the hardware, the scoreboard after 270 generations of the AI training itself is blunt: the two things that moved the needle were a bigger network and a stricter referee, while almost every cheap, clever trick I tried to squeeze more strength out of the same GPU lost. That is not a failure story. It is the clearest possible signal for what to do next.

TL;DR

  • The AI ratcheted from gen-005 to gen-270 — hundreds of thousands of games it played against itself on a single RTX 3070 Ti, with no human examples — and shipped a real bot to production along the way.
  • What won: a bigger brain (96×8 → 128×10 network, +113 Elo in one generation), a stricter promotion referee, and time-aware scoring (+150 Elo).
  • What lost: clever-but-faster search at play time (−338 Elo), teaching the AI to “notice” threats (detection worked, strength didn’t budge), and every attempt to curate the training data.
  • The pattern: the ceiling is capacity — how much the network can hold — not the ideas around it. Gen-270 has now gone 70 generations with zero promotions.
  • What’s next: a GPU upgrade, so the next network can be bigger — the one lever that has broken every plateau it ever hit.

How far it came: gen-005 to gen-270

A “generation” is one round of a simple loop: the AI plays thousands of games against itself, a fresh network trains to copy the best moves, and a strict test decides whether it is genuinely stronger. Strength is scored in Elo, the chess rating scale — a +100 Elo gap means the stronger player wins about 64% of the time.

Milestone What changed Result
gen-005 → gen-077 first working loop, 96×8 network self-taught climb; gen-067 shipped to production
gen-201 rebuilt as a 128×10 network (3.36M parameters) +113 Elo in one generation — broke the old ceiling
gen-240 time-aware scoring (value discount) +150 Elo, and stronger at low search budgets
gen-270 current champion then 70 generations, zero promotions

The gen-005 → gen-077 climb was mostly about measuring correctly. A noisy promotion test lets lucky challengers through and buries real gains; tightening it (I cover this in [[2026-06-29-capacity-was-the-limiter]]) let the true improvements compound. Then the small 96×8 network stalled — three long runs never beat gen-077. Rebuilding it bigger, as a 128×10 network, crossed the ceiling on the first attempt. That was the proof: the limit had been the network’s size, not the training.

What worked: a bigger brain, a clearer referee, time-aware value

Three wins, and a theme — each is either more capacity or more rigor, never a cheap shortcut.

  • A bigger network. 96×8 → 128×10 (1.73M → 3.36M parameters) bought +113 Elo immediately (#1284). A bigger brain simply holds more of what the search discovers.
  • A stricter referee. Tightening the promotion test — the win-margin bar and up to 1000 confirming games — stopped false promotions and let true gains stack. It was the quiet unlock behind the entire early climb.
  • Time-aware scoring. Teaching the value estimate to prefer winning sooner (a small discount on the eventual result) added +150 Elo and, better, made the AI stronger when it thinks less — exactly what a deployed bot needs ([[2026-07-05-winning-sooner-not-just-winning]]).

Under the hood the loop also got faster and sturdier: streaming the training data cut host memory from 19.2 GB to 1.5 GB (#1241), and moving the referee’s games off the critical path made promotion checks ~2.8× faster (#1314, #1315). None of that made the AI smarter — but it made every experiment above affordable.

What didn’t: the graveyard of clever tricks

The interesting half. Each of these was a plausible, cheap idea to gain strength without new hardware. Each failed, and the failures rhyme.

Clever trick The idea Result
Gumbel search at play time same move quality from ~50 look-aheads instead of 800 −338 Elo — it needed more thinking, not less
Threat-detection head an output that flags “opponent is about to score” detection 99.7% accurate, strength unchanged
Attacker / threat-heavy data feed it more losing-under-pressure positions no measurable effect versus the control
Data curation keep only the “high-quality” self-play games no signal — fast, slow, aggressive games all equally useful
Offline value patch hand-correct the AI’s over-optimism about losing worked in a probe, distorted real play — shelved

The through-line: I kept trying to make a fixed-size network use information better — notice threats, vary its openings, study curated games — and the network’s answer was always the same shrug. The threat run is the sharpest example. Over a 10-hour session the AI learned to count imminent threats with 99.7% accuracy, yet the part that decides “am I winning?” stayed exactly as blind as before (the human-facing version of that blindness is [[2026-06-30-yinsh-missed-mate]]). Detecting a danger and acting on it turned out to be different skills, and a small side-output couldn’t bridge them at this size.

It was like handing a student sharper flashcards when the real limit was how much they could hold in their head. The faster search, the extra data, the threat labels — all real, all ignored, because the container was already full.

The pattern: it was capacity all along

Put the two halves side by side and the shape is obvious. Every lever that added capacity (a bigger network) or removed noise (a stricter gate, cleaner scoring) worked. Every lever that tried to extract more from the same capacity lost. Gen-270 has run 70 generations (271–340) without a single promotion, its best challengers stuck around a 0.45–0.48 win rate against it. That is not idea-starvation — I have a backlog of ideas. It is a full container.

What’s next: the lever is hardware, not another trick

So the next move is the one the data has pointed at all along: more capacity, which means more GPU. A larger network (160×12 and beyond) is the single lever that has broken every plateau it faced, and I can warm-start it from gen-270 so it inherits everything already learned instead of starting from zero. That needs VRAM headroom one RTX 3070 Ti doesn’t have — hence the upgrade.

The cheap tricks aren’t all dead, either; several were shelved because they only pay off once there is capacity to spare. Few-look-ahead Gumbel self-play (2–4× more practice games), a playout-cap that varies search depth, and one genuinely open idea — teaching the AI to act on the threats it can already detect — all sit ready. But they are passengers. The engine is a bigger network on a bigger GPU.

Two hundred and seventy generations in, the lesson is almost anticlimactic: I spent weeks proving that cleverness is cheaper than capacity, but rarely a substitute for it. The next post starts on the other side of a hardware upgrade.

Keywords

  • Self-play — the AI plays games against itself to generate its own training examples, with no human games needed.
  • Generation — one full round of the loop: play against itself, train a fresh network, then test whether it earned promotion to champion.
  • Elo — a single strength number (the chess rating scale); a +100 gap means the stronger side wins about 64% of the time.
  • Search / look-ahead (MCTS) — before each move the AI imagines many continuations and plays what holds up best; more look-aheads mean stronger but slower play.
  • Network capacity (parameters) — how many adjustable numbers the network has (here 1.73M, then 3.36M); more capacity means it can hold more of what it learns.
  • Promotion gate — a strict statistical test that only crowns a challenger as the new champion when it provably wins more games.
  • Value discount — scoring a win that arrives sooner as slightly better than one that arrives later, so the AI prefers to finish rather than dawdle.
  • Warm-start — building a new, larger network but copying the old one’s learned weights in first, so it starts from what was already known.
  • VRAM — the memory on the GPU; a bigger network needs more of it, which is the physical reason a bigger brain needs a bigger card.

References

  • [[2026-06-29-capacity-was-the-limiter]] — the first ceiling break in depth: why three 96×8 runs stalled and a 128×10 rebuild crossed +113 Elo on the first try.
  • [[2026-07-05-winning-sooner-not-just-winning]] — the time-aware value discount that added +150 Elo and helped most at low search budgets.
  • [[2026-07-05-the-speedup-that-sped-up-nothing]] — the Gumbel-at-play-time dead end (−338 Elo); it needed more thinking, not less.
  • [[2026-07-04-thinking-smarter-not-harder]] — where Gumbel search does belong (cheaper self-play), and the rule that it must not get less creative.
  • [[2026-06-30-yinsh-missed-mate]] — the human-facing version of the threat-blindness the aux-head run tried and failed to fix.
  • docs/task-log/20260614-yinsh-ai-impl-plan/23-bigger-net-128x10-result.md — the +113 Elo capacity break, with the three stalled 96×8 runs as the control.
  • docs/task-log/20260708-yinsh-strategy-diversity/03-training-threat-detection-plan.md — the threat-detection head: 99.7% detection accuracy, null strength payoff, and the B2 follow-up.
  • #1284 bigger network · #1241 streaming trainer (19.2 GB → 1.5 GB) · #1314, #1315 gate throughput (~2.8×) · #1400 the auxiliary threat head.
  • AlphaZero (DeepMind) — the self-play + search + train loop this pipeline copies.
  • Policy improvement by planning with Gumbel (Danihelka et al., 2022) — the search idea that worked for training data but lost at play time.
  • KataGo (Wu, 2019) — the precedent for auxiliary heads (ownership/score) that did help a value net; here the same trick did not transfer.

AI workflow note

The research and drafting were split deliberately. A Claude Code Explore agent first swept roughly fifteen task-log documents and the generation history and returned a cited factual brief — every generation number, Elo margin, and PR — before a single sentence of prose was written; drafting from that brief kept the “cite real data” bar honest instead of reconstructing numbers from memory. The failure mode worth naming: earlier in this project I repeatedly over-read single-generation results as trends (a +13% blip looked like a breakthrough, then reverted), so this recap treats every number as a multi-generation average, never a point. The pattern that worked was forcing the retrospective to separate “what added capacity or rigor” from “what tried to be clever with neither” — the split is what made the hardware conclusion fall out on its own.


Hungjoon

I'm Hungjoon, a software engineer based in South Korea. This is my long-form notebook — homelab, Kubernetes, AI infra, and whatever else keeps me up at night.