Reveal the village one option at a time - #141
Merged
Merged
Conversation
A new game now opens on the docks with a single thing to do - fish - and every other option arrives later, one per screen, as the player earns it. Each arrival is announced with the reason it appeared, so the newly-added menu entry explains itself on the screen it first shows up on. - add src/progression, a data-driven unlock table (id, announcement, condition over Player/Stats) alongside src/achievements' milestones - persist the granted ids on Stats.unlockedFeatures, with a matching schema entry and reader/writer field - start the game at the docks, and grant already-earned unlocks silently on load so an established save is never re-locked - gate the docks, shop, bank, tavern and home menus on the unlocks, with the docks growing downward so a known option keeps its number - add Quit to the docks, since that is where a new player starts - hide the $10,000 goal line until the player's first $1,000 - stage Sam's tour of the village to the places found so far Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
A new game now opens on the docks with a single thing to do — fish. Every other option in the village arrives later, one per screen, as the player earns it, and each arrival is announced with the reason it appeared:
This is pacing, not difficulty — nothing is made harder or more expensive, and an established save opens with the whole village available exactly as before.
src/progression, a data-driven unlock table (id, announcement, condition overPlayer/Stats) built the same way assrc/achievements' milestones — add a row and it is tracked, gated and announced automatically.Stats.unlockedFeatures, with the matchingschemas/stats.jsonentry andStatsJsonReaderWriterfield.$10,000goal line from the status header until the player's first$1,000— "$20 / $10,000" on cast one gives away the whole arc.Design notes
One reveal per screen, always. A single long cast can land a first catch and empty the energy bar at once. Announcing both would produce exactly the wall of new options this exists to avoid, so
getNextUnlockgrants one; the rest are still earned and arrive on the following screens.No deadlocks. Go Home unlocks on the first sale or on energy dropping below the 10 needed to fish, so a player who fishes themselves flat before selling anything can always still get their energy back.
Test plan
python3 -m compileall -q src testsSDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy python3 -m pytest --verbose -vv --cov=src --cov-report=term-missing --cov-report=xml:cov.xml— 676 passed (was 638);src/progressionat 100% coverageblack src tests+autoflakeperformat.shshowOptions. Verified live on the console front-end (opening menu, first-catch reveal, save/reload) and on the web front-end over HTTP (GET /state/POST /input) — both show the staged menus and the empty goal line. The pygame front-end renders the sameoptionListand already hides an emptygoalProgress.unlockedFeaturespersists, and a legacystats.jsonwith no such field catches up on load.