Two state leaks and a level exploit - #29
Merged
Merged
Conversation
THE TARIFF NEVER ARMED ON THE TUTORIAL ENTRY. STATE.tariff.cycleOn was
written in exactly one place, window.startGame. window.startTutorialGame
runs beginRun() — which resetState()s it back to false — and then only
showCeremony(). So the entry point a FIRST-TIME player takes silently
played a flat-rate game while everyone who pressed Power On got the
day/night meter. The one mechanic most worth meeting early was the one
the beginner could not.
THE INSPECT SELECTION OUTLIVED A RUN. clearWorld() hid the panel and
restarted building ids at b1, but selectedId is module-scope in
handlers.js and nothing cleared it — so the next run's b1 is a different
building and tickInspect re-opened the inspector on it a frame later,
with nobody having clicked anything.
single_point_of_cold WAS WON BY BULLDOZING THE PLANT AND REBUYING IT.
The failure is permanent on purpose (chiller_fail sets repairAt =
Infinity) because the lesson is that a second failure mode beats a
second identical unit. But demolish refunds half of , turning the
level's into — enough for an identical replacement, straight
around the lesson. Banning the type closes it, and preBuilt places with
{ free: true } so the level still hands you its own plant.
The repo's own copy rule caught the first attempt at that last one: a
level that bans a building it names in the briefing owes the player a
reason. Both locales now give one.
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.
Three more from the audit. 558 → 560 tests.
The tariff never armed on the Tutorial entry.
STATE.tariff.cycleOn = truewas written in exactly one place:window.startGame.window.startTutorialGamecallsbeginRun()— whichresetState()s it back to false — and then onlyshowCeremony(). So the entry point a first-time player takes silently played a flat-rate game, while everyone who pressed Power On got the day/night meter. The mechanic most worth meeting early was the one the beginner could not meet.The inspect selection outlived a run.
clearWorld()hid the panel and restarted building ids atb1, butselectedIdis module-scope inhandlers.jsand nothing cleared it. The next run'sb1is a different building, sotickInspectre-opened the inspector on it a frame later with nobody having clicked anything.single_point_of_coldwas won by bulldozing the plant and buying an identical one. The failure is permanent by design —chiller_failsetsrepairAt = Infinity— because the level's entire lesson is that a second failure mode beats a second identical unit. But demolish refunds half of $260, turning the level's $200 into $330: enough for a replacement, straight around the lesson. Banning the type closes it, andpreBuiltplaces with{ free: true }, so the level still hands you its own plant.The repo's own copy rule caught my first attempt at that last one — a level that bans a building it names in the briefing owes the player a reason. Both locales now give one, and it is a true reason: a chiller is not a same-day purchase, and an identical second one would only rebuild the same single point.
All three are mutation-checked; reverting any one turns its own test red.