bc20: Battlecode 2020 "Soup" as the second year module - #1
Merged
Conversation
Adds `src/battlecode/years/bc20/` — world, flood, pollution, blockchain, cows, maps, knobs, rules and the two chassis — plus the committed data the sim reads: 18 converted `.map20` maps, the JDK-generated float32 water-level table, and the 2020 sprite atlas cut from the official client. The year-neutral machinery (`match`, `results`, `replay`, `render`, `broadcast`, `decide`, `server`, the wasm entry) now goes through `years/dispatch.nim`, the one place a year is named; `sheet.nim` is thinned to the envelope and each year's knob table moves to `years/<year>/knobs.nim`, with the tolerant-parsing primitives extracted UNCHANGED into `sheet_common.nim`. bc26 semantics are untouched: every existing test passes in debug and release.
Adds the `bc20` manifest variant (num_agents 2 inside its own game_config),
the four-year-neutral `results_schema.games.items.required` with each year's
statistics as optional siblings, the fourth docs page, the two bc20 baseline
player entries and the four bc20 policies. bc26's variant, its player entries
and the certification fixture are byte-identical.
Bumps GameVersion to GV04 with ReplayCompatibleGameVersions [GV03, GV04]:
nothing a GV03 recording carries changed meaning, so every hosted bc26 replay
keeps rendering.
Adds tests/test_bc20_{flood,dirt,drone,burial,blockchain,pollution,cows,
scoring,sheet,maps,baselines,knobs,perf}.nim — including the D1 no-chassis
assertion, the D2 survival gate and the ten-knob teeth gate.
The viewer: `client/replay_broadcast.html` gains an APPENDED bc20 game block with all-new `#bc20-*` ids, a `data-year` CSS gate and CSS for all ten beat kinds; the D3 dismissible doctrine overlay (close button, Esc, re-open chip) sits above `var(--band)`, never in it. `chrome_common.js`, `broadcast_core.js`, `config.nims` and both `static_replay*.js` are byte-for-byte untouched, so no loader is spliced. The renderer fixture gains a bc20 ROW: three widths x two years, checked with --strict-text-bounds. The oracle: `tools/oracle/Bc20Oracle.java` and `tools/parity_trace_bc20.nim` emit the same 67 559-line vector file from the pinned 2020 engine sources and from the Nim port -- the water table, both pollution coefficients over all 65 536 values, Math.round(float), the IDGenerator streams, java.util.Random, the OVERFLOWING cow seed and Transaction's comparator. They diff clean. `tools/oracle/examplefuncsplayer20/` carries the one-hunk determinism patch. CI: a `parity-oracle-bc20` job (JDK 8, two BLOCKING tiers plus a reported engine-from-source attempt), `docker-smoke` runs TWO episodes, `wasm-viewer` executes the bundle against BOTH replays, and the `test` job re-generates and byte-diffs every bc20 generated artefact against the pinned 2020 checkout.
GameVersion becomes GV05 (main spent GV04 on the D1/D2 chassis change) with ReplayCompatibleGameVersions [GV04, GV05]: the bc20 addition changes no bc26 semantics, so a GV04 recording still re-derives, while GV03 stays out because the D2 chassis change means it does not. Conflict resolution took MAIN's side for every bc26 semantic: the post-D1 knob table (no `chassis` key, `parseChassis` for playback) moves verbatim into `years/bc26/knobs.nim`, `baselines.chassisFor` keeps setting the filler path's chassis directly, and `replay.parseSeat` keeps restoring it. bc20's own `parseChassis` is renamed `parseChassisKind` so the two never collide. `#bc20-doctrines` adopts main's stricter D3 discipline: it auto-closes on the first advancing frame and after six seconds, its body is capped and scrolls, and CI's obscured-board gate now runs against BOTH years' replays.
`docs/RULES-BC20.md` is the 2020 rule set, its ten knobs and a fourteen-item Divergences list — including the two the design note could not have known: the chassis walls before `wall_hq_round` when the map's own flood schedule demands it (`maptestsmall`'s HQ ring floods at round 256), and the wall bar is evaluated at the last round the game can reach rather than at `round + 400`. `docs/PARITY.md` gains the bc20 oracle: what the 67 559 vector lines pin, and why the round-loop tier is blocked — `net.sf.jsi:jsi:1.1.0-SNAPSHOT` was published only to jcenter (shut down 2022) and the Sonatype OSS SNAPSHOTS repo (expired), and `world/ObjectInfo.java` imports it directly, so the unmodified upstream build cannot produce `:engine:jar` in 2026. The job attempts it anyway and prints the exact failure to the summary. `NOTICE` names battlecode20 (GPL-3.0, compatible with this repo's AGPL-3.0 under AGPLv3 section 13) file by file, StoneT2000/Battlecode2020 (AGPL-3.0) as the behaviour `bowl-of-chowder` distils, and IvanGeffner/battlecode2020 as cited-never-used. `tests/test_bc20_replay.nim` adds record -> re-derive for every bc20 end reason including the wall-clock stop, a strict UTF-8 parse of the written bytes, and the assertion that the blockchain is re-derived from events + config + seed with nothing stored.
daveey
force-pushed
the
bc20-year-module
branch
from
September 4, 2026 05:29
c4e2890 to
0a0106f
Compare
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.
Adds the
bc20year module — MIT Battlecode 2020 "Soup" — besidebc26,behind the year-module boundary the 2026 build cut for exactly this.
Implements
docs/plans/2026-09-04-battlecode-2020-soup-design.md.DO NOT MERGE YET — the coordinator decides merge timing.
What lands
src/battlecode/years/bc20/— the sim: the numbered resolution rules 1–9mirroring
GameWorld.runRound, the flood (a committed JDK-generatedfloat32 water table, because
Math.exp/Math.sinare HotSpot intrinsics),soup and refining, the seven build types, dig/dump elevation, drone
carry/drop-in-water, net guns, pollution (a refinery's local +500 lasts
exactly one round), the 64-int blockchain with its cost model and the
static-
Randomre-seed-per-spawn quirk, the ported cows, the six-rungtiebreak ladder, and a 1500-round cap applied through the engine's own
round >= rounds - 1.bowl-of-chowder(behaviour port, AGPL-3.0 provenance,parameterised by the ten knobs, with real defensive play) and
examplefuncsplayer(statement-for-statement, and it may not gainbehaviour — it is one side of the differential oracle).
chassiskey (D1), 18 converted.map20maps, and the 2020 sprite atlas cut from the official client.bc20(num_agents: 2insidegame_config), theyear-neutral
results_schema.games.items.requiredwith each year's stats asoptional siblings, a fourth docs page, two more baselines, four more
policies. bc26's variant, its player entries and the certification fixture
are byte-identical.
#bc20-*ids and adata-yearCSS gate.chrome_common.js,broadcast_core.js,config.nimsand bothstatic_replay*.jsare untouched.GameVersion→ GV05,ReplayCompatibleGameVersions["GV04", "GV05"].Evidence
parity-oracle-bc20: a 67 559-line vector file emitted from the pinned2020 engine sources under JDK 8 and from the Nim port, diffed byte for byte
— the water table, both pollution coefficients over all 65 536 values,
Math.round(float), theIDGeneratorstreams,java.util.Random, theoverflowing cow seed and
Transaction.compareTo. Blocking.docker-smokeruns two episodes (bc26 cert fixture + a 300-round bc20scripted game) and
wasm-viewerexecutes the bundle against bothreplays.
tests/test_bc20_*.nimshards, including the D1 no-chassisassertion, the D2 survival gate and a ten-knob teeth gate. No existing test
was weakened or deleted.
docs/RULES-BC20.md§Divergences lists every deliberate difference from the2020 engine, including the one the oracle cannot cover: the full round-loop
tier needs
:engine:jar, andnet.sf.jsi:jsi:1.1.0-SNAPSHOTno longer existson any repository the upstream build names.