fix(broadcast): bc16's duel beat is a TRADE, not a LAUNCHER DUEL - #13
Merged
Conversation
…her duel `beatsFor`'s `duel` label switch tested `isBc22` alone, so bc16 fell through to bc23's branch and every bc16 killfeed rendered `LAUNCHER DUEL — 1 lost to 1, game 1, round 232` — eleven times in the round-17 replay, naming a unit the 2016 rule set does not have. Three years emit the beat and only two meanings are in play: years/bc22/rules.nim:275 w.beat(BeatDuel, "duel", w.attackersLostThisRound[0], …) years/bc16/rules.nim:321 w.beat(BeatDuel, "duel", w.attackersLostThisRound[0], …) years/bc23/rules.nim:397 w.beat(BeatDuel, "duel", w.launchersLostThisRound[0], …) bc16 counts attackers, exactly as bc22 does (`years/bc16/world.nim:642`, `years/bc22/world.nim:512`), so it takes bc22's wording. The switch now names both attacker-counting years; bc23's branch is untouched and renders byte-for-byte as before, as does bc22's: bc16 TRADE — 1 attackers lost to 1, game 1, round 232 (was LAUNCHER DUEL — 1 lost to 1, …) bc22 TRADE — 1 attackers lost to 1, game 1, round 232 (unchanged) bc23 LAUNCHER DUEL — 1 lost to 1, game 1, round 232 (unchanged) The header comment listed `duel` among the "bc23-only kinds … no other year emits them" — the belief that produced the defect — and now states the real rule: which years emit it, what each counts, and which wording each gets.
Closes the class the `duel` label was one instance of. `tests/test_bc16_beats.nim`
walked ["build", "rout", "duel", "archon"] asserting only that the kinds were
EMITTED; nothing asserted the WORDING of a shared beat per year, which is why
`LAUNCHER DUEL` shipped green in a bc16 killfeed.
Section 2b now:
* pins bc16's `duel` to the exact TRADE string built from the event's own
`lost` pair, and asserts the label contains no "LAUNCHER";
* renders the SAME event under bc22 and bc23 and pins both of those strings
exactly, so the fix cannot be reached by changing either of theirs;
* audits EVERY beat bc16 emits — all 13 kinds, 258 beats of the committed
fixture plus a synthesised `tiebreak` and `game_abandoned`, the only two
kinds the fixture cannot reach — against a list of words that belong to
exactly one other year's rule set (launcher, Singularity, rat king,
cheese, cats, soup, dirt, influence, Enlightenment, crumb, duck, chip,
paint, adamantium, mana, elixir, anchor, boost, destabilis/destabiliz,
HQ, headquarters, tower). A map's own name is stripped first: it is data,
not wording.
The audit is clean on every other bc16 beat — archon, wave, outbreak, den,
activate, infect, turned, rout, build, game, end, doctrine all pass as they
stand, and no second leak was found. Two guards keep it from being vacuous:
the synthesised beats must actually render, and the same feed read as bc23
must trip the search (it does, on `launcher` — that is the string bc16 shipped).
Counterfactual: with `if isBc22 or isBc16:` reverted to `if isBc22:`,
`nim r --path:src --path:tests tests/test_bc16_beats.nim` reports
"test_bc16_beats: 24 of 6045 checks failed" — the two explicit duel checks and
all 22 duel beats in the fixture. With the fix: "ok (6045 checks)".
No existing assertion was weakened; check count 91 -> 6045, all additions.
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.
The defect
beatsFor'sduellabel switch (src/battlecode/broadcast.nim:353) testedisBc22alone, so bc16 fell through to bc23's branch and every bc16killfeed rendered
LAUNCHER DUEL — 1 lost to 1, game 3, round 828. bc16 hasno launcher unit. It happens 22 times in the committed bc16 fixture alone.
Three years emit the beat, with the same field name and two meanings:
years/bc22/rules.nim:275attackersLostThisRoundyears/bc16/rules.nim:321attackersLostThisRoundyears/bc23/rules.nim:397launchersLostThisRoundbc20/bc21/bc24/bc25 never emit it.
The fix
if isBc22 or isBc16:—isBc16already existed in the same proc and is usedthe same way by the
archon_lostswitch three cases down. bc22's and bc23'srenderings are byte-for-byte unchanged; the same event rendered under each
year:
The header comment listed
duelamong the "bc23-only kinds … no other yearemits them" — the belief that produced the defect — and now states the rule.
Closing the class
tests/test_bc16_beats.nim§2b pins the three renderings exactly and thenaudits every beat bc16 emits — all 13 kinds, the fixture's 258 beats plus a
synthesised
tiebreakandgame_abandoned(the only two kinds the fixturecannot reach) — against words belonging to exactly one other year's rule set.
Same mechanism as
tests/test_viewer.nim's r2-E1 guard from #12.Counterfactual: reverting
if isBc22 or isBc16:toif isBc22:givestest_bc16_beats: 24 of 6045 checks failed. With the fix,ok (6045 checks).The audit found nothing else: archon, wave, outbreak, den, activate,
infect, turned, rout, build, game, end and doctrine all pass as they stand.
No year's rules, no oracle, no viewer bundle, no manifest touched. Two files.