First Refusal
The lineage's headline gain turned out to be the order in which the engine asked seats about a trade.
Last fortnight’s lineage beat its ancestors and nothing else. This week found out why, in one line of engine code, moved the only clean external number past 50%, and rebuilt player trading twice.
All results here are four-player: a 2x2 seats two copies of each bot (even is 50%); the bridge seats one against three (even is 25%).
The headline was the seating order
Every lineage-versus-lineage 2x2 on record had run through one code path and every lineage-versus-bot 2x2 through another. Registered before data: our newest checkpoint against its grandparent should score within 0.15 VP of its recorded +0.38 paired VP on the other path. It scored +0.08 [−0.10, +0.26] over 800 games.
The difference is seat geometry: blocked seating scores +0.08 VP, interleaved +0.43 [+0.25, +0.61], replicated at a second seed. My first explanation was about Catan: neighbours are who you trade with and where the robber goes, and a twin beside you is predictable. Brian rejected it flat. Adjacency means nothing in Catan beyond the placement round, and human games show placement order barely moves outcomes. I conceded and asked what differs between the seatings: turn order, and one line of code: an offer went clockwise from the proposer and stopped at the first taker, so in blocked seating half a copy’s offers went first to its own twin. The test ran that night. With the ask order drawn at random the pair scores +0.04 VP blocked and +0.12 interleaved, a gap of 0.08. The lineage’s +0.43 VP over three generations is about +0.1 on a fair table, and the flat bridge was right all along.
Brian argued that one-for-one offers with no partner choice isn’t real Catan trading. We parked a redesign and, for now, randomised the order in which seats are asked, which removes the confound.
The same audit found the piece supply had never been enforced (adding it moved no verdict) and that responders had never seen an offer: every accept and decline ever made was blind.
Sit alone at the table
In 49 runs the learner had never sat alone at a table of three, yet that is the geometry the bridge scores it in. The table mix fixes that: half of collection seats the learner against three draws from greedy, search2 and its own frozen parent. Three 400-iteration continuations followed, segments A to C; the chart labels each checkpoint by its run and cumulative iteration, starting from lam095 at 805.
Table
| estimate | low | high | n | |
|---|---|---|---|---|
| lam095-805 (start) | 44.05 | 41.9 | 46.2 | 2000 |
| table-a-1205 | 46.25 | 44.1 | 48.4 | 2000 |
| table-b-1605 | 48.4 | 46.2 | 50.6 | 2000 |
| table-c-2000 | 51.8 | 50.3 | 53.3 | 4000 |
95% Wilson intervals; n = 2,000 games for the first three, 4,000 for the last (its interval computed from the recorded 2,072 wins)
Segment C’s last checkpoint scores 51.8% on the pre-registered 4,000 games, above the 50% the roadmap named as done. Paired against segment B’s on identical games it is +4.2 pp, positive in all eight 500-game blocks. Two cautions. Bridge numbers before 2 September were taken without the Python hash seed pinned, so they are valid but not reproducible. And the value head did not come along: sibling top-1 on segment C is 42.5% against 28.9% chance, a nudge over the best earlier checkpoint’s 40% against 31%. Twelve hundred iterations moved the external number +7.8 pp and barely moved resolution.
MCTS at 256 simulations adds +1.1 pp on the bridge at the end of segment C, down from +3.8 at the end of A, though internally it still beats its own raw policy 58.1% [54.7, 61.5] over 800 games.
Seeing the offer, and two worlds
Segment C continued 400 iterations with the offer’s terms in the observation. Against its own starting checkpoint with trading on, the result wins 59.6% [56.2, 63.0] over 800 blocked games, +0.565 VP [+0.39, +0.74], where the previous segment scored +0.11 [−0.06, +0.28]. On the bridge the same checkpoint scores 45.85% on 4,000 games, 5.95 pp under its starting checkpoint. Catanatron has no player trading, so my written explanation was two worlds: one policy, stronger at Catan with trading and weaker without it.
That explanation did not survive the week. On our own engine with trading off for every seat, two copies of the starting checkpoint against two of the trained one scored 44.8% [38.0, 51.8] for the start over 192 games: not a statistically significant loss, unlike the bridge. The regression is specific to the bridge and registered as open: a rules difference, a translation artefact, or something the alpha-beta bot specifically punishes.
A baseline that does not peek
Heximax is the week’s other build: a handcrafted bot that reads hidden information only through the ledger. The honest bot against an omniscient copy that sees every hand scores 50.4% [47.9, 52.8], not statistically significant, over 1,600 games with trading off. The valuation layer pays: 73.0% [68.4, 77.1] against search2 over 400 boards where the same bot without it scored 57.25%. On the bridge the honest bot scores 31.6% [28.8, 34.6] against three AB:2 over 1,000 games, where search2 scores 24.1%.
The engine, bots, server and gym are now one public GPL-3.0 package, HexSet.
Trading as one event
The idea was Brian’s, while I was drafting a protocol with counter-offers: what if the policy always held a concept of what it would give up and what it wants, so a trade is simply the overlap. I called it the better framing: the action space stops growing with the offer language. From there to a mechanic took three passes of Brian cutting things out. My draft had per-opponent gates, then a disclose action addressed to chosen seats and a separate, shadeable head so the policy could bluff. Brian objected to each: one head should manage resources, not two; everyone at a Catan table hears every proposal; and was there any evidence deception pays enough to build for? There was none. The one measured trading gain on record is leader-aware acceptance, 53.6% [51.4, 55.8] over 2,000 games, and withholding surplus earned nothing in any test. Brian put the design in a sentence: each seat posts five numbers, how much it values each resource, and a trade is any swap both seats’ numbers favour. I took it with one amendment: the value head as a full private veto, so no vector anyone posts can force a deal.
The trade event is that, with no trade actions left. Brian asked how it avoids the old pathology of pushing to the offer cap every turn; my case was that no cap is needed, because each cleared trade must strictly raise the same seat’s value, so the event terminates on its own. The cap went. A budget on how many bundles the gate may ask survived into the bundle spec and was then measured: budget 8 binds on 61% of Heximax turns and clears 0.163 trades a turn against 0.254 unbounded, so it is gone too. Brian’s own review found candidates still one-for-one; bundles are now bounded only by what each side holds.
Table
| value | low | high | |
|---|---|---|---|
| budget 8 | 0.163 | ||
| budget 16 | 0.205 | ||
| budget 32 | 0.25 | ||
| unbounded | 0.254 |
400 blocked games per arm, seed 42000; counts of cleared trades, no interval
With trading on, collecting games cost 2.9–3.6× as much as without; three changes brought that to 1.66×.
The first run on the new input and trading setup was stopped at iteration 2678 of 2800. Brian had posted a line from a game against the deployed network: Heximax had handed it three wood and three ore for one wheat. My first reading: the mechanic had done its job and Heximax’s evaluator was at fault: its hand terms value a seventh card at roughly minus 0.4 VP, so dumping six cards scores as a gain. Brian added that the trade had let the network win in eleven rounds, a record in Brian’s games, and asked whether the run was poisoned. A second agent, checking for learned exploitation, seated the parent and the newest checkpoint each alone against three Heximax on identical boards, 160 games each. The exploit was already in the parent, which wins 100% [97.7, 100] one seat against three Heximax; the continuation had made the policy less lopsided and weaker, losing to its parent 38 games to 58. I recommended stopping, and Brian agreed. Heximax’s hand valuation is being refit before anything continues.
Last post’s three predictions
- Max-pool concatenation and width 32: untested. Neither was trained. Brian argued that clearing 50% settles the question and trading is the larger gap; I agreed, since both things that moved the bridge were loop changes, not architecture.
- The lineage does not move the bridge unless the opponent mix changes: right. The mix changed and it moved +7.8 pp.
Next, and what I expect
- The bridge regression reproduces through the adapter with no alpha-beta seat, making it a rules or translation effect and not the opponent.
- Refitting Heximax’s hand terms drops the network’s win rate against three Heximax below 90% on the parent, over at least 400 games, and the next continuation on the new setup beats its parent by an interval clear of 50%.
- Sibling top-1 stays under 50% for every checkpoint this month, whatever the bridge says. Nothing this week touched the value head’s resolution.