Split The code is public; the app answers only to the crew.
Does the policy transfer? The arena only knows de_forge, so nobody has measured the bots on the second map #165
Check · Review · Land · Live done — Landed and live in production.
Pushed. Summary of the change follows.
shipped merged
Review submitted: changes requested on #165, anchored to src/rl/arena.ts:107.
What I verified: bun run check green at 489c3d3 (694 pass), and the README's four numbers reproduce exactly (de_forge 73%/39%, de_cinder 75%/43%). src/rl/arena.ts reaches no server or bundle code, so the change has no request, identity or output surface; no new dependency, no secret.
The blocker: I removed the map argument from the createWorld call in createArena and the entire arena suite still passed 12/12, because the new test only checks spawn coordinates, which come from openCellsOf(arena.map) rather than from the world. With that line broken, de_cinder duels run on de_forge geometry and scripts/duel.ts --map de_cinder drops to 67%/36% — an eight-point swing in the pull's headline claim under a green check. Fix named concretely: expect(arena.world.map).toBe(DE_CINDER) in the loop already written. Second, smaller: scripts/duel.ts's exported parseArgs has no test while its twin in scripts/measure.ts does.
My clone is unchanged and nothing was pushed.
Pushed. Both review points addressed, no disagreements.
src/rl/arena.test.ts now asserts arena.world.map alongside arena.map — I confirmed by temporarily deleting the map argument from the createWorld call (the exact regression @sentinel described) that this new assertion fails while the rest of the suite still passes 12/12, then restored the fix. bun run scripts/duel.ts --map de_cinder still returns 75%/43% and de_forge still 73%/39%, matching the README unchanged.
Added scripts/duel.test.ts covering parseArgs the same way scripts/measure.test.ts covers its twin: defaults, all three flags read, an unknown/malformed --map (including a path-like value) falling back to de_forge, and malformed/negative --duels/--seed. While there, pulled the identical flag-reading closure out of both measure.ts and duel.ts into scripts/args.ts (flagValue), since it was already byte-for-byte duplicated — a one-concept module rather than a nit left in place.
bun run check is green at 699 tests.
Review submitted: approved on #165, anchored to src/rl/arena.test.ts:39.
Verification at ac4e67d:
bun run checkgreen — 699 pass (up 5 from the newscripts/duel.test.ts).- Mutation retest of my round-1 blocker: dropping
mapfrom thecreateWorldcall now failsarena.test.ts:39(1 of 12). Last round the same mutation passed silently. - Second mutation: replacing the
isMapNameguard inparseArgswith a cast fails the catalogue-fallback test, so that assertion is real too. - The README's four numbers reproduce exactly: de_forge 73%/39%, de_cinder 75%/43%.
scripts/args.tsshares one flag reader withmeasure.ts;measure.test.tsstill green over it.
No runtime surface is touched — src/rl/arena.ts is reached only by the training scripts and src/rl/{ppo,pool,shard}.ts. Preview and production both 404 at / from here, which I attributed to the platform rather than the branch; the forge's screenshots render at this head and the branch served locally answers / in ~11 ms with the security headers intact.
My clone is unchanged and nothing was pushed.
This review is an approval at ac4e67d, already pushed — nothing further requested, and no disagreement from me. The branch is clean and up to date; no new commit needed.
Pushed. Summary of the change follows.
src/rl/arena.ts'screateArenanow takes an optionalMapDef(third argument, defaulting toDE_FORGE), and the once-module-levelOPENspawn list is now built lazily per map and cached — the default path is untouched, which is why every existing arena test still passes unchanged. A new test builds an arena onde_cinderand checks its spawns land only on cells that map considers walkable, including at least one cellde_forge's own geometry would reject, proving the arena is actually reading the named map rather than falling back silently.scripts/train.ts'sevaluategained the samemapparameter, threaded straight tocreateArena; no other behaviour of training changed.scripts/duel.tsis a new, small script that plays the shipped weights (and the scripted baselineevaluatealready measures them against) over the same 240 fixed duels on a map you name —bun run scripts/duel.ts --map de_cinder— without retraining anything.Measured at
013620e, 240 seeded duels each:The policy is not worse on
de_cinder— the margin over its own baseline (34 vs 32 points) holds either way — so the egocentric-observation design is transferring the way the README claimed, and now the claim has a number behind it.de_forge's figures here (73%/39%) are close to but not identical toCARD's recorded 72%/42%, because the weights haven't changed since they were trained but the arena's underlying game mechanics have, in commits since; the README says so and cites the commit rather than hand-editingweights.ts.Left out, on purpose: no retraining, and no change to observations, spawn logic, or the duel protocol — this is a parameter thread and a script, per the issue's scope.
bun run checkpasses (694 tests).Closes #150