Repository navigation
Add validated v17 gun-control successor - #11
Draft
subodhbgwt wants to merge 31 commits into
Draft
subodhbgwt wants to merge 31 commits into
subodhbgwt wants to merge 31 commits into
Conversation
gate.py - the per-game "<bot> first" label was a wrong WORD, not wrong data: it always named the bot passed as bot_a (verified against fcode run and the replay - bot_a is team 0). Execution interleaves ABABAB, so nobody is "first". Label is now "as A" and the CSV column is side_a, with a legacy alias so the 9926 historical rows migrate instead of blanking. gate_results.csv was never wrong; whole-history A-seat rates are strongly structured (bridge 84%, skerry 22%), which a scrambled column could not produce. - per-map lines now print the seat split and flag SEAT-LOCKED maps, on decided games only so a crashed bot cannot dress 0/16 draws up as a seat lock. The old collapsed number hid the lock: 8/16 is exactly what a locked map yields when the candidate holds each seat half the time. - default opponent is now generalist-v3, not the stale champion (== oogerebus3, which inverted the ranking of ten bots). - prints the 95% CI and warns when it spans 50%. MEASUREMENT-FINDINGS.md - CORRECTED the noise floor. One draw per n cannot estimate a spread: three repeats of the same 168-game identical-code control gave 49%, 56%, 51% - the middle one PROMOTES a bot over itself. The band is +/-8, not +/-3, and a 168-game PROMOTE is a 1-in-10 coin flip. Use seeds=8. - games are not reproducible at all: 46 of 48 bots call random.* unseeded and --seed seeds the ENGINE, not the bot. Two identical SERIAL runs flipped 8/20 winners on sprint (10/20 with --tle 0); seeding the bot RNG gave 0/16. Not the worker pool, not the TLE. - ladder diagnosis, 200 live games: rank #1/86 at 62%, but 29% in the 150-299 turn window against the top four, with the enemy core fully healing our siege in 12 of 23 losses. Does NOT reproduce locally, so a local gate can only prove nothing broke. heal_audit.py - offline core damage vs healing per side, no API needed. bots/exp_heal_lock_retreat (+ trace twin, + 9 deterministic tests) - role-2 sieger leaves a provably non-converting siege when home is threatened. - 336-game gate vs generalist-v3: 52% (CI 47-57), kills 149-142. No regression, no measurable gain - as expected, since local games never enter the failure regime. Activation proven by replay: 1696 retreats over 168 games. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diagnosis, from 200 live games and 110 downloaded replays: the ladder's ranking function is how fast you get a gun onto the enemy core. Powered by SmartFridge lands its first at t19, Pantheon at t24, we managed t60. An econ probe showed titanium was NEVER the constraint - the core holds >120 Ti from round 0 and peaks at 470 by t45 with 5 builders - so a single constant was making us arrive last while sitting on unspent resources. exp_early_siege (variant A): SIEGE_START 45 -> 25. First gun t84 -> t58. 61% vs generalist-v3 at 336 games (CI 55-66, kills 183-111), 90% vs OogwayOld (control 86%), 93% vs lastpop2 (control 90%). exp_siege_on_sight (variant B): the gate becomes state, not a round number - enemy core located and titanium above the unchanged floor, both true from ~t5. 67% vs generalist-v3 at 336 games (CI 61-71, kills 211-91) and 63% head to head vs variant A. SHIPPED as live v2 at 17:20; v1 retained for rollback. spar_rush: sparring partner only, our engine with SIEGE_START = 5. Never submit it. Nothing in bots/ rushed, so no local gate could see how a candidate handles one - and it found a hole 500+ games against our own lineage hid: generalist-v3 scores 39% against it (kills 58-91) while beating our own lineage 86-93%. WORKFLOW.md now requires gating every candidate against it. Still open: gun-to-core conversion. Pantheon lands 89% of its guns within 6 tiles of the enemy core and 1% in its own half; we land roughly 30%. That is a bigger measured gap than the timing one this commit closes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The kill budget is real: 500 HP core, 10 dmg/2 ammo per gunner shot, ammo 1:1 same-turn, so a kill is 200 Ti against a 500 bank and ~55 of Pantheon's 58 median turns are logistics rather than shooting. Every attempt to exploit that still lost, and the causes are all different: exp_core_pressure 46% (43% vs rush) - own-half guns are real defensive value exp_relay 33% - launcher road delayed the first gun t35 -> t58 strike-v1 27% - 100% placement, 1.9 guns/game, starved with no econ strike-mass 13% - same starvation with 12 builders spar_pantheon 49% (kills 79-79) - allocation gain, economy loss, cancel exp_siege3 1 building, 0 titanium collected, dead t62 THE WALL: role allocation and economy are the same knob here. Economy work only happens in the non-sieger branch, so every builder moved to delivery is one removed from income (2 siegers -> 4.6 guns + 4.0 harvesters; 3 -> 0 and 0; all -> 4.5 and 0). Pantheon gets 18.7 guns on the enemy core from an economy the same size as ours, so their builders farm AND deliver. Architectural, not a parameter. Engine facts banked: launch() throws a friendly builder 7 tiles from 1-2 tiles away on a 1-turn cooldown for 20 Ti, so launchers ~6 apart give a hop per turn - we build zero, Pantheon builds zero, SmartFridge builds ~1 at t17. Ammo is 1:1 and same-turn. Whether enemy builders can be launched is UNRESOLVED; the probe's friendly control also failed, so it proves nothing. exp_siege_on_sight (live v2) remains the best bot we have. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
exp_opportunist 48% - any builder near their core plants a core-capable gun.
Economy preserved (4.2 harvesters) but on-core guns did not rise: economy
builders never travel far enough for the opportunity to exist.
exp_cadre - fixed 3-builder economy cadre, everyone later sieges, with
a cheaper spawn threshold. 2.1 guns on core, 2.8 harvesters. A builder is
30 Ti = THREE gunners, so a marginal builder must deliver >3 guns to pay for
itself. Population is not the lever either.
exp_forward_armor 52% (CI 45-60, kills 76-71) - barriers at the siege seat
when no firing seat is available. Pantheon builds ~40/game with 39% in the
4-6 band; we reached 1.2. The only variant above 50 with a positive kill
differential, so it is being resolved at 336.
exp_roadcrew - dedicated builder lays the launcher road so siegers never
stop. Still slower to first gun (t45 vs t36) and only 1.4 of 4 launchers
completed. That is the THIRD way of funding the relay to fail; the mechanic
does not pay in this engine.
Nothing has beaten exp_siege_on_sight (live v2). Thirteen experiments now agree
that in this architecture a builder either farms or delivers and never both,
and that titanium spent on builders is titanium not spent on guns. Pantheon
gets 18.7 guns on the enemy core from a 4.1-harvester economy; we get 4.6 from
4.0. That difference is in how their bot is written, not in a setting reachable
from here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… is not it builder_trace.py (new): the replay records a create event with the new entity's position but not who built it, so this tracks every builder's position per turn and attributes each building to the adjacent friendly builder. That yields a per-builder timeline. Pantheon, one game: builder 3 t3 harvester, t5-t33 nine conveyors pure economy builder 5 t9 harvester, t11-t25 eight conveyors pure economy builder 88 t34,37,39,41 four gunners pure delivery builder 97 t44,50 two gunners pure delivery They do NOT interleave farming and delivery - they specialise exactly as we do, which kills the "their builders do both" hypothesis from the previous commit. exp_phase: first CADRE_SIZE builders farm, everyone later sieges (the ordering the trace implies, with the parent's spawn rule untouched, unlike exp_cadre). Better economy - 5.2 harvesters, 41.9 conveyors vs 3.8 and 32.8 - and the same total guns, but they land late and in the wrong place: first gun t51 vs t34, 1.5 on the enemy core vs 3.5. exp_phase2 flattens the spawn curve on top; more guns (10.8 vs 7.8 total) and still 2.0 on core at t56. CORRECTION: I read ids 88/97 as evidence Pantheon fields ~90 units. Ids are global across both teams and all entity types, and they create ~80 entities a game (40 barriers, 21 guns, 18 conveyors), so those ids only mean "created late". Unit counts are comparable - our median is 12 at game end. The scale hypothesis is dead, and so is the concurrency one: their gun builders travel DURING the economy phase, which is what exp_siege_on_sight already does. Fifteen experiments, no improvement on live v2. The remaining difference is per-unit efficiency inside the firing band, which none of these variants has isolated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
exp_ammo 36% (CI 29-43, kills 45-101). I read the parent's `if globalAmmo < 20: convert(20 - globalAmmo)` as a hard ceiling on ammunition. It is not - runCore executes every turn, so it is a per-turn TOP-UP to 20, i.e. ~10 shots and 100 damage per turn sustained, enough to kill a core in five turns. Ammo was never starved. The variant then made things worse by reserving only 150 Ti against a 120 gun floor, starving the siege it was meant to feed; retuning to 260 still left core damage at 256 against the parent's 535. Pantheon's win condition, resolved from 120 rounds: 86% core_destroyed at a median of t50, 14% titanium_collected at t1000, and 59% of all wins under 60 turns. They kill fast. An earlier note that their average core damage (357) was below a core's 500 HP was WRONG - that average mixed their losses and their 1000-turn games together. LIVE RESULT for exp_siege_on_sight (v2), 215 rounds: overall 106-109 (49%) against v1's 156-129 (55%), BUT 70 of v2's rounds were against Pantheon and SmartFridge versus 35 of v1's. Like-for-like on the same schedule v2 is 49% against v1's expected 46% - about +3 points, 1 SD. vs OopsGotYourElo 70% (v1: 52%), vs Besvikomat 57% (v1: 46%), vs SmartFridge 23% (v1: 10%). Rating 1652, rank #3 of 89, up from #5. Sixteen local experiments, all rejected; the one change that shipped is holding up on the ladder. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Teammate pushed v3-v6 while I was iterating. Per-version LIVE records show one
thing that matters enormously:
v2 (ours) 54% (180 rounds) vs Pantheon 1-14 (7%)
v3 56% (205 rounds) vs Pantheon 1-19 (5%)
v6 56% ( 80 rounds) vs Pantheon 10-5 (67%) Orizon 1-9
v6 is the only bot any of us has fielded that beats Pantheon - the matchup I
spent sixteen experiments failing to crack. Its mechanism is a TEAM-WIDE RECALL:
the core raises a flag when it is genuinely hurt AND a real shooter is in vision
(hp < 400 + nearestEnemyGunner), and units come home. Crucially it is a SCORED
state worth 7-9, below attack's core-defence ceiling of 12, so a unit that can
build a killing gunner still builds it.
exp_recall - ported as a hard override. REGRESSION: 44% vs our v2 (CI 39-49,
kills 120-169). It pulled siegers off live firing seats.
exp_recall2 - ported as the soft priority v6 actually uses: build the gun if
there is one, answer the recall only when travelling or when no
seat is available. 51% vs our v2 (CI 46-57, kills 147-143) - no
regression, which is the right profile for a defensive mechanism.
METHODOLOGY WARNING: oogbest-v6 scores 45% against our v2 locally and 52%
against spar_rush - the same 52% our v2 scores - yet live it goes 67% against
Pantheon where ours goes 7%. spar_rush DOES NOT MODEL PANTHEON, and no local
gate we have can see this matchup. The WORKFLOW.md section I added this morning
making it a mandatory gate overstates what it proves.
Also unaddressed: every version loses to Orizon (#3), Prompt Engineers Anonymous
(#4) and The Flotte Experience (#5) at ~10-24%. Three top-five teams, one shared
weakness, and nobody has looked at their replays.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Profiled Orizon (#3), Prompt Engineers Anonymous (#4) and The Flotte Experience (#5) in games AGAINST US, so map and matchup are controlled: team 1st gun guns on OUR core conv harv barr vs us Oogway (us) t24 2.2 13.4 3.0 0.0 Orizon t18 16.0 8.0 1.9 0.2 13-2 Prompt Engineers t26 14.0 3.2 1.0 0.0 17-3 Flotte t22 6.5 0.0 0.0 5.7 22-3 Pantheon t22 18.7 17.7 4.1 39.8 10-5 Every team above us puts 3-8x more guns on our core than we put on theirs, and every one runs a leaner economy than we do. Flotte runs NO economy - zero conveyors, zero harvesters, barriers instead - beats us 22-3, and loses to OopsGotYourElo 5-15, a team we beat 70%. That is a counter to us specifically. RETRACTION: I dismissed guns-on-core as "churn" on the grounds that Pantheon's guns live 8 turns to our 30. That compared Pantheon vs top opponents against our bot vs my own failed variants - not like for like. Four teams measured in games against us show the same gap. The metric was right and the sixteen rejected experiments failed on execution, not on thesis. Flotte proves zero economy works - the configuration strike-v1 attempted and botched at 1.9 guns. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
exp_transition 56% vs shipped v7 at 336 rounds (CI 50-61, kills 173-124).
Found by tracing the teams that beat us, builder by builder, in games AGAINST
US - not by reasoning about mechanisms:
ORIZON b10: t6 harv, t8 conv, t12 harv, t14 conv, t16 conv -> STOPS FOREVER
b4: t30,31,37,43 gunner b6: t33,34,35 gunner
PROMPTENG b3: t1 harv, t3 conv, t5 conv -> STOPS AT t5
b5: t28,30,31 gunner b9: t28,36,39 gunner
US (v7) b16: t7 conv, t9 conv, t19 GUNNER, t27 harv, then TEN conveyors
through t43
b4: t1 harv ... t22, t24, t26 conv
They build a small economy, stop dead, and spend everything after on guns. We
never stop - 18.4 conveyors a game to Orizon's 7, and one builder puts down a
gunner at t19 and goes back to harvesting at t27. That is why every team above
us lands 6-18 guns on our core and we land 2-4.
The mechanism is a TRANSITION, not an allocation, which is why exp_phase (role
cadre) and spar_pantheon (economy damped from t0) both missed it: the economy
has to be built FULLY and then abandoned. One condition: after ECON_CUTOFF the
harvest and route states score zero.
Profile now matches the target: total guns 14.0 (Orizon 14.0), on-core 3.8 ->
6.9, conveyors 39.5 -> 15.9.
Sweeping ECON_CUTOFF over 10/14/20/26/32/40 before shipping - the traces put
their transitions at t5-t16, so 26 is probably late.
Also measured: v7 and v6 are indistinguishable live (44% vs 45% expected
like-for-like, n=50), and v6's Pantheon rate has regressed 67% -> 48% as its
sample grew. Both share the same holes: Orizon ~10%, Prompt Engineers 20%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…def rejected Cutoff sweep over nine values: t10 35%, t14 50%, t20 56%, t26 56%, t32 62%, t40 62%, t50 53%, t65 58%, t80 58%. Their timings do NOT transfer - Orizon stops at t16 and Prompt Engineers at t5, but copying that gives 35-50% because our economy is slower. Confirmed the two leaders at 336 to pay back the selection bias of a nine-way sweep: t32 55% (CI 50-60, spans 50), t40 58% (CI 53-63, excludes 50). Shipped t40 as v8 econ-transition. v8 unrated vs the top five: 6-19 (24%) against v7's 7-25 (28%). A TRADE, not a gain - Prompt Engineers 1-4 -> 4-1 and Orizon 0-5 -> 1-4 (the two teams whose plan this copies), but Pantheon 2-3 -> 0-5, Flotte 2-3 -> 0-5, SmartFridge 2-3 -> 1-4 (the three that rush our core). exp_trans_def tested the obvious explanation - that zeroing economy states empties our half when a rush lands - by letting the recall outrank the transition. REJECTED: 46% vs v8 (CI 41-52, kills 138-167), 45% vs spar_rush. So that mechanism is wrong and v8 stays live. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… vs rushers The Flotte Experience (#5) beats us 22-3. Traced: 100% of their 28 barriers across 5 games sit within 4 tiles of their OWN core, laid from t4 by a dedicated builder before any threat exists. In the game traced we built ELEVEN gunners from t13 to their eight from t18 and still lost 5-0 - our guns need seats at range 4-6 from their core and those tiles were taken. Our waller walls manhattan 1 with conveyors, which blocks adjacency but not the FIRING SEATS. exp_prearmor adds the seat zone (manhattan 2-4, enemy side only, and only tiles that pass can_fire_from against our core footprint). 3 Ti for 30 HP; our own barriers are passable to our units so it costs no movement. vs shipped v8 (336): 51% (CI 46-57, kills 153-149) - no regression vs spar_rush (168): 60% (CI 52-67, kills 92-55) - v7/v8 both ~52% Not shipped: 51% does not clear the 55% bar I set for autonomous shipping. Building 3.3 barriers/game against Flotte's 5.6, so the mechanism is under-delivering - tuning that next. NOT aegis-v1 or bastion: both were REACTIVE armour built after a threat appeared and were correctly rejected. This is pre-placed, which is the point. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FLANKING - from the Battlecode 2021 postmortem (Stone Tao), whose breakthrough was attacking from multiple directions at once, and confirmed as a real gap here: quadrants covered around the enemy core by guns within 6 tiles is 2.75/4 for the teams that beat us against 1.83/4 for us. Cause is in our code - _direct_siege_plans sorts seats by distance FROM THE BUILDER, so siegers converge on whichever face they approach from. exp_flank adds a quadrant- coverage term ahead of distance. REJECTED: 44% vs v8 (CI 39-50, kills 130-166). Seats in unoccupied quadrants are further away, so more turns go to walking and fewer guns get placed. A mechanism can be real in the data, endorsed by a winning postmortem, and still lose in our engine. PREARMOUR - not shippable. 51% vs v8, and the rush advantage did not replicate: 60% then 52% on a rerun of the identical bot, pooled 187/336 = 56%. Count 10 at radius 4 gives 49%. Two process failures of mine, both caught by redoing the boring version: 1. Swept armour count AND radius together (6/4 -> 10/5, 14/5), so the regression could not be attributed. The clean single-variable test (10/4) showed count alone is not the cause. 2. Built a story on a 60% that a rerun cut to 52%, and compared it against v7's baseline when prearmour is built on v8. The proper control - v8 vs spar_rush at 336 - was never run until now. v8 econ-transition remains live and remains the only confirmed gain. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The remaining experiment, sparring, frozen and concept bots that were never committed - exp_* variants, spar partners, trace twins, and the older lineages. Keeps the whole fleet reproducible alongside the gate results and MEASUREMENT-FINDINGS.md rather than living only on one machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Everything else from the session and the wider project that had never been committed: the tests/ suite, conveyor_audit.py, artifacts/, the packaged zips and *_results.json evidence files, plus the working HANDOFF.md and WORKFLOW.md edits and the remaining root sources. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # AGENTS.md # HANDOFF.md # WORKFLOW.md
…ected Unrated scrims with the live v22 (rank #2, 1935 Diamond): Pantheon 0-5 (dead t42,45,73,74,100 - all core destroyed) CtrlAltDefeat 4-1 Orizon 3-2 Flotte 4-1 Pantheon is the only team beating us and the only team above us. Replay profile of those five games (they are teamA): first gun guns on core total guns barriers launchers PANTHEON t13 10.2 13.2 5.2 1.0 EREBUS v22 t31 6.4 16.6 0.0 0.0 Placement, measured: 100% of their 26 barriers sit within 6 tiles of OUR core (forward armour on the siege position they hold), and 100% of their 5 launchers sit within 4 tiles of THEIR OWN core (a launch pad, not a chain). Note this is the OPPOSITE of Flotte, whose barriers are 100% at their own core for seat denial - two top teams using the same building for opposite purposes. exp_v23_launchpad - one pad by our core, defender-built, throws outbound builders 7 tiles. 52% vs live v22 (CI 47-58, kills 156-145). First gun t24 -> t22 only. exp_v23_launchpad2 - adds routing: attackers still near home detour onto the pad. STILL t22, and the cap is not globally enforced so it built 6.1 pads/game (~120 Ti wasted). That over-build is the decisive evidence: six pads did not beat one, so pad availability is not the bottleneck and the mechanism does not explain their t13. exp_v23_fwd_armor - barriers where our guns are, inside the enemy band, only when something is shooting that tile. 47% vs live v22 (CI 42-52, kills 138-157). Also 93% vs spar_rush with kills 157-5, but that number is UNINTERPRETED - no fresh parent control was run, and spar_rush is built from the v8-era engine which this lineage outclasses anyway. Frozen parent bots/live-v22-control extracted byte-for-byte from the active submission; identical to exp_v21_eco_release_only_damaged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Traced Pantheon's launcher from their 0-5 sweep, turn by turn:
t1 launcher built 2 tiles from their own core (18 from ours)
t2 builder 3 (3,4) -> (4,10) d7 t3 builder 5 -> (4,10) d8
t4 builder 8 -> (1,6) d5 t5 builder 11 -> (1,17) d5
then the thrown builder BOLTS: b5 goes 14,13,12,11,10,9,8,7,6,5 one tile a
turn, no detours, no economy, and the first gunner lands t13 at distance 4.
The throw buys ~6 tiles; the bolt does the rest. Without it that is a t21 gun.
Seven implementations, each fixing the last one's real bug:
v3 pad at t1, 1/game, correct placement -> ZERO launches. Launchers never
call setupMap(), so a launcher's own enemyCorePos is permanently None
(mapPathfinding notes the same trap for gunners).
v4 builders publish the target to slot 9 -> 8.5 launches from t2, but first
gun t24 -> t26: the pad was throwing the ECONOMY crew across the map.
v5 attackers claim the ride via slot 10 -> 17.1 launches, first gun t20.
GATE 40% (kills 103-188). Pantheon launches 3-4 times a whole game.
v6 one-ride-per-builder flag -> 0.8 launches, tempo gone. The flag was set on
CLAIMING and only one claim survives the single slot per turn, so every
builder that lost the race marked itself done.
v7 geometry instead of a flag (throw must clear the pickup radius) -> 8.8
launches, first gun t20. GATE 38% (kills 96-198).
v8 rider given the same allEnemyCore fallback as the launcher -> DEADLOCK:
riders stand at the pad waiting for a throw that never comes (b3 frozen
t6 -> t89).
v9 wait timeout -> oscillation: b3/b8 bounce 21<->22 all game, 1 launch.
combo (v7 + forward armour) -> 40% (kills 100-186).
CONCLUSION SO FAR: the mechanism is real and reproduced - pad at t1, throws from
t2, first gun t24 -> t20 - and it loses every time, by 2:1 on core kills. Being
early and alone in their half gets our builders killed; the armour that should
fix that does not (47% alone, 40% combined). What we have NOT reproduced is the
BOLT: our thrown builders re-enter the ride logic and ping-pong near the pad
instead of marching. That is the next thing to fix, and it is a rider problem,
not a pad problem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Best result 45% (CI 40-51, kills 114-176) vs live v22. Progression: v1 pad on the exit lane, gated on resources+role 52% v5 riders claim, 17.1 launches/game, first gun t20 40% v7 geometry-limited, 8.8 launches 38% v11 no detour, 3.8 launches = Pantheon's exact rate 45% v12 pad moved off the exit lane, bolt restored 45% THREE LATENT BUGS IN THIS CODEBASE found while chasing it, all worth knowing independently of the launcher: 1. LAUNCHERS NEVER CALL setupMap(). Every entity gets its own Player and only builders call it, so a launcher's mapPf.enemyCorePos is permanently None. v3 built a perfect pad that could never fire. mapPathfinding.py documents the same trap for gunners. Anything map-dependent in a non-builder entity has to come from the store. 2. mapPf.moveTo DEAD-ENDS AGAINST OUR OWN CONVEYOR RING - our conveyors are not passable to us. HANDOFF records this costing aegis-v1 seven turns "2 tiles short"; it is why every version that walked riders to the pad oscillated. 3. OUR OWN BUILDINGS BLOCK OUR OWN EXIT. Placing the pad on the tile nearest the enemy - the obvious choice - puts it in the doorway every builder leaves through. Traced: b3 bouncing 22 to 21 and back for eight turns where the pad-less parent marched straight out. One tile perpendicular restored the march (22,21,20,18,17,16,15,14,13,12,11,10,9,8). We place a lot of conveyors in that same corridor. Pantheon's mechanism is now reproduced faithfully - pad at t1, 3.8 throws/game from t2, thrown builders bolt - and it still costs about 5 points. The remaining gap to their t13 is in what the ATTACKER ROUTINE does after landing, not the pad. oarena (github.com/frkns/oarena) installed for 2D replay viewing: its venv needs a .pth pointing at the fcode site-packages, since a venv made from another venv does not inherit it. Serves on :7878, doctor all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FIX 1 - non-builder entities have no map (exp_v23_fix_storemap). Every entity gets its own Player and only builderBot() calls setupMap(), so in a gunner, sentinel or launcher the pathfinder is empty: mapPf.enemyCorePos and teamCore are permanently None. mapPathfinding already works around this for gunners (coreThreatSpots reads the team core from slot 7) but nothing published the ENEMY core. Builders now publish it to slot 9 and enemyCoreFromStore() reads it. LATENT fix - the live bot has no non-builder logic needing it, so behaviour is unchanged and there is nothing to gate. Its value is that the next launcher or gunner routine written against mapPf.enemyCorePos will not silently never fire, which cost a whole day of launcher work here. FIX 2 - pathfinder dead-end (exp_v23_fix_stuck). 49% (CI 44-55, kills 147-147). The parent waits 2 + (id % 8) turns - three to ten - before reacting to a blocked step, then moves in a RANDOM legal direction. This sidesteps on the first blocked turn and picks the neighbour that reduces distance to target, falling through to the original random walk only if nothing improves. HANDOFF blames this dead-end for aegis-v1 standing "2 tiles short for 7 turns". Neutral at 336 games: the stall is real but rare enough not to move the aggregate. FIX 3 - our own buildings block our own exit (exp_v23_fix_lane). 49% (CI 44-55, kills 154-147). MEASURED FIRST rather than assumed: 41% of the live bot's conveyors (5.75 a game) land within two tiles of the core->enemy axis, the corridor every attacker leaves through, and our conveyors are impassable to our own units. Reserving the single-tile lane out to 6 tiles (not the whole corridor, which is often where the ore is) is neutral. All three are safe robustness fixes with no regression, and none is a win. The honest read: these bugs are real and cost individual units turns, but the aggregate is dominated by something else. Fix 1 is still worth keeping because it removes a silent-failure trap rather than a cost. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ed good LAUNCHER AS AN EYE (exp_v24_launcher_eye). Pantheon told us they get full symmetry shortly after placing a launcher. The constants support it: LAUNCHER_VISION_RADIUS_SQ 26 vs a builder's 20, and symmetry is eliminated by observing terrain, so a pad at home is the widest permanent sensor we own. Implemented as mapPathfinding.setupMapObserver(): getNewTiles -> updateBoard -> updateSymmetry for a non-builder entity, deliberately SKIPPING shareTiles, whose 12-bit channel is keyed on myNum and belongs to the builders. MEASURED with an instrumented twin - round at which each bot first resolves the enemy core, 8 maps: launcher-eye 1, 2, 3, 3, 3, 3, 4, 4, 9, 10 ... median t18 live v22 4, 5, 5, 5, 5, 6, 6, 6, 15, 16 ... median t18 So it DOES resolve 2-3 turns earlier for the earliest units - the effect is real and is what Pantheon described. It just does not pay: 20 Ti, a builder action at t1 and a blocked tile for 2-3 turns on a few units. GATE 43% (CI 37-48, kills 126-177). THE OTHER RESULT THAT MATTERS: v24 is NOT a regression. fresh unrated, v24 active: Pantheon 3-2, CtrlAltDefeat 3-2 same scrim earlier today with v22: Pantheon 0-5 ladder like-for-like v24 vs v22: -5 points at 1.2 sigma (NOT significant); the raw 80% vs 60% was schedule - v24 has played 40 rounds against Pantheon. vs Pantheon our first gun is now t21 to their t14, with ZERO launchers, where this morning it was t31 to t13. Whatever v23/v24 changed bought most of the tempo the launcher was supposed to buy. Remaining measured asymmetry vs Pantheon: they build 3.2 barriers/game, we build none. Also in this push: the three latent-bug fixes (all gate neutral, all safe) and twelve launcher-as-transport variants (all rejected, best 45%). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… redoing it Thirteen attempts, all rejected, best 45%. Documents Pantheon's exact traced pattern (pad t1 off-axis, 3-4 throws t2-t5, thrown builder bolts one tile a turn, first gun t13), the three codebase landmines that silently kill the mechanism (non-builders have no map; moveTo dead-ends on our own conveyors; our own buildings block our own exit), what each of the thirteen variants proved so nobody repeats them, and the one piece still unsolved: a thrown builder needs a committed bolt state so runAttack's gunner-spot search stops pulling it sideways. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…not aim Phase 0, 70 replays of v29's own losing matches. v29 is 419-81 (84%) over 500 rounds, #2 at 1966; Pantheon #1 at 2016. The only sub-50 matchup is Pantheon (24-26, 48%); everything else is 68-100%. 23 of 26 losses are core_destroyed at a median of t62, 12 of them inside t60. D1 52.7% of our guns sit in our OWN half; opponents put 29.1% there. D3 our guns are NOT inefficient - 9-turn median lifetime to their 5, and 37.9 core damage each to their 25.7 (489 a game against 358). D2 but we win the race to first gun on their core in 15 of 64 games (23%): t20 to their t14 in fast games, t29 to t15 in slow ones. E1 exp_v30_tempo_first - defer home defence until the team lands its first gun on their core (a lone uncovered turret no longer buys a counter-gun; two still do; after first blood it is exactly v29). Mechanism confirmed: first gun t29 -> t25, home gun share 44% -> 26.9%, which is the 29.1% the top teams run. GATE 49% (CI 44-54, kills 149-146) - neutral. E2 exp_v30_core_eye - runCore never touched mapPf at all, despite CORE_VISION_RADIUS_SQ 36 against a builder's 20 and never moving. Added an observer path (no shareTiles: that channel is keyed on myNum). Also fixed a real bug in it: a CORE does not appear in its own get_nearby_buildings(), so teamCore stayed None and updateSymmetry returned immediately. PREMISE FALSIFIED before gating: earliest symmetry resolution is identical with and without it - [1,1,2,2,3,3,4,4,6,6] both - so the team already knows where their core is by t1-t6. Knowledge is not the constraint. CONCLUSION: our first gun at t22-30 is essentially TRAVEL TIME across ~20 tiles. Not aim, not allocation (spar_v29_rush, v29 with nearly every builder attacking, still only reaches t25), not efficiency. That is precisely what a launcher throw shortcuts, and it is why Pantheon reaches t7-14. Also: spar_rush is now obsolete as a sparring partner - v29 beats it 97%, since it was built from the v8-era engine. Replaced by spar_v29_rush (v29 chassis, all but one builder attacking) which reaches t25. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…arent
E1 defer defence until first blood 49% (CI 44-54, kills 149-146)
E2 core as symmetry eye premise falsified before gating
E3 bolt state, band 9 52% (CI 46-57, kills 155-141) <- best
band sweep: 6 -> 45%, 9 -> 52%, 13 -> 51%, 18 -> 48%
E4 stack (bolt + defer) 45% (CI 40-50, kills 134-164)
E3 BOLT is the one worth keeping in mind. Measured cause: runAttack calls
findGunnerSpot() every turn once the core is known and moveTo()s the seat it
returns, but that seat is rescored each turn FROM THE BUILDER'S OWN POSITION, so
a distant attacker chases a moving target instead of closing. We spend 1.50
turns per tile of progress against our opponents' 1.12. Committing to the march
outside a 9-tile band moves first gun t29 -> t25.
E4 STACK IS WORSE THAN EITHER HALF, which vindicates the WORKFLOW rule I
deviated from: stack only independently-passing features. Deferring defence AND
committing attackers forward leaves us undefended and overextended at once.
A PROCESS FAILURE WORTH RECORDING: the first stack run reported 52% and was an
UNMODIFIED COPY of the bolt. The edit anchor appeared twice in the file
(runDefend and another threat handler), the assert fired, write_text never ran,
and the shell went on to compile and gate the untouched file. The number looked
plausible because it matched the bolt exactly. Now fixed with a longer unique
anchor, and the edits are verified by counting them in the WRITTEN file rather
than trusting a clean exit. This is the third silent-failure of the day after
the launcher with no map and the core observer that could not find its own core.
CONCLUSION: Phase 0's diagnosis stands and is well evidenced - we lose the race
to first gun in 77% of games, our first gun is travel-bound (symmetry resolves
t1-6; even all-out attack reaches only t25), and our guns are the most efficient
on the board (489 core damage a game to their 358). But no tempo fix prices out
against our own parent, because the parent does not punish slow tempo. Measuring
this needs Pantheon, and that needs a candidate active on the ladder.
Nothing here is recommended for the ladder. v29 stays.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s 54%
CLI updated 2.3.3 -> 2.3.4 in both venvs; maps already current (21).
SIX CONSTANTS CHANGED. Gunners nerfed on four axes at once, sentinels buffed on
two: GUNNER_BASE_COST 10->20, GUNNER_DAMAGE 10->7, GUNNER_AMMO_COST 2->4,
GUNNER_MAX_HP 40->25, SENTINEL_FIRE_COOLDOWN 3->2, SENTINEL_MAX_HP 30->40.
dmg/turn dmg/ammo dmg/Ti HP reach
gunner 7.0 1.75 0.35 25 cardinal 3, diagonal 2
sentinel 9.0 1.80 0.60 40 cardinal 5, diagonal 4
Sentinels are now better on every axis except cooldown - 71% more damage per
titanium, 60% more HP, and TWO TILES more reach. Reach was measured with a probe
bot rather than assumed: gunnerLines is hardcoded 3/2 in mapPathfinding and a
gunner seat is not a sentinel seat, so sentinel work needs its own seat list.
Also, a 500 HP core now costs ~280 ammo instead of 100.
NEW NOISE FLOOR ON 2.3.4: byte-identical v30 against itself, 336 games, scores
54% (CI 49-60) with core kills 162-142. So:
- anything under ~57-58% at n=336 is unproven;
- KILL DIFFERENTIALS ARE NOT CORROBORATION. Identical code produced +20. I
have been quoting differentials as supporting evidence all session (bolt
155-141, defer 149-146) and that was wrong - both numbers move together.
- every pre-patch gate result in this repo is stale.
exp_v31_sentinel: attack seats use the new sentinel geometry and build sentinels;
defence deliberately left on gunners (one change at a time). Confirmed active at
9.2 sentinels/game against the parent's zero, and 9.6 threats on the enemy core
against 7.9. Gating now.
WORKFLOW.md updated with both the rebalance table and the new noise floor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The merge took origin/main's WORKFLOW.md, which does not carry the noise-floor section, so the previous edit's anchor genuinely did not exist and the write was skipped. Re-inserted against a verified anchor, and the write is now confirmed by re-reading the file rather than trusting a clean exit. Records the six changed constants, the inverted gunner/sentinel economy (sentinels: 0.60 dmg/Ti vs 0.35, 40 HP vs 25, reach 5/4 vs 3/2), the ~280 ammo now needed per core kill, and the measured 2.3.4 noise floor: byte-identical code scores 54% with a +20 kill differential, so sub-58% results and positive kill differentials both prove nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s every meta ENGINE: both venvs -> 2.3.6, maps current. Diffed GameConstants out of the 2.3.6 wheel against our 2.3.4 snapshot: ZERO constant changes. 2.3.5/2.3.6 are engine or CLI fixes; the gunner rebalance remains the live balance. NOISE FLOOR, second draw: byte-identical v37 vs itself on 2.3.6 = 46% (CI 41-52, kills 138-158). With the 2.3.4 draw of 54% (kills 162-142), identical code spans 46-54% and its kill differential swings +20 to -20. So: anything in 46-54 at n=336 is nothing, and KILL DIFFERENTIALS CARRY NO INFORMATION - I quoted them as corroboration repeatedly earlier in this work and that was wrong. LADDER RESHUFFLED after the rebalance. Pivot #1 (1922), sporks #2 (1875 on only 90 matches), team lazy #3, Pantheon SEVENTH at 1806 - down from #1/2016, the purest volume-rush bot hit hardest by the gunner nerf. Erebus #9 of 101 (1792), last ten 3W-7L. v37's "sentinel-line seal" is NOT broken and does NOT build sentinels: it is cornerShields - 12 barriers, 36 Ti, on the tiles every enemy sentinel line into our core must cross. Zero sentinels built is by design. v36 shipped without it, which is why v36-era replays show zero barriers. WE ARE NOT LOSING ON DAMAGE. In matches we lost: Coreflood 461 vs 316, sporks 641 vs 302, team lazy 580 vs 519, Pivot 1021 vs 959 - we out-damage all four. NO SINGLE META EXISTS ANY MORE: team # gunner barr conv harv 1st gun ON CORE Pivot 1 19.6 8.2 16.0 4.6 t27 8.8 sporks 2 14.8 2.4 50.2 7.8 t70 7.0 team lazy 3 8.8 0.0 15.4 3.2 t25 6.2 EREBUS 9 13.1 0.0 11.1 2.5 t26 4.0 Pivot plays guns+barriers, sporks plays a t70 first gun with 50 conveyors and is #2, team lazy plays lean everything. Rush and economy are both winning for different teams. THE ONE INVARIANT: every team above us lands more guns on the enemy core than we do - 8.8 / 7.0 / 6.2 against our 4.0. That has survived every patch, every meta shift and ~25 experiments. It is not tempo (sporks is slower and #2), not efficiency (we out-damage them), and not unit choice (nobody uses sentinels). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ic3d00
added a commit
that referenced
this pull request
Aug 24, 2026
…g the finals bot; two economy experiments rejected THE INCIDENT: ic3d saw v204 activate itself. Cause was mine - I killed the A/B runs with 'pkill -f autoeval.py' three times and reported 'autoeval stopped' each time, but pkill is a BASH BUILTIN and does not kill Windows processes. All six autoeval.py instances launched tonight were still alive and cycling the active submission against each other. My verification was wrong too: 'ps -ef | grep' returns nothing for Windows processes and I read that silence as confirmation. Every one of those processes carried --final 198, so at 08:15 they would have OVERRIDDEN the intended finals bot. Killed via Stop-Process by PID; v205 confirmed active. tools/versionwatch.py now reports (never changes) the active submission every 5 minutes. Deliberately report-only: a teammate may legitimately switch the bot and a watchdog that fights them would be worse than the bug. On Windows use Get-CimInstance Win32_Process + Stop-Process, never pkill/ps. ECONOMY EXPERIMENTS, both REJECTED on direct measurement rather than win rate. The metric is harvesters built per builder, because that is what the Bean 5-0 turned on (they had 9 harvesters off FOUR builders, we had 6 off SIX): unpressured 2.13 under pressure v198 1.25 under pressure v205 1.37 <- best, and the answer to 'does v205 fix it' under pressure fp36 economy reserve 1.11 <- WORSE fp35 HARV_TI 45->28 lab 74/150 = 49% CI [41,57], indistinguishable Production collapses ~40% under pressure and v205 recovers only about a tenth of that, so NO, v205 does not fix the underlying bug - it fixes one oscillation source that feeds it. fp36 reserved half the crew from every defensive step so they would keep farming through a siege (the shape MFF1 and The Blades both endorsed); it produced FEWER harvesters, 30 against 41. Caveat: the metric is partly confounded by game length, and there was no time to normalise it. v205 stays: best measured production under pressure, 3-2 over Clankers, 1982 Diamond rank #11 - our highest of the campaign.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Why
All seven observed v17 losses were multi-gunner core destructions. Source review found that gunners ignored lone enemy builders, could spend 10 titanium rotating between equal targets, and did not prioritize enemy gunners actively aimed at our core.
Validation
The imported production source retains its original trailing whitespace so the frozen Python files remain byte-identical to the downloaded archive.