Skip to content

Achievements on arcade via tak.arcade (RFC 0014) - #215

Merged
dmccoystephenson merged 1 commit into
mainfrom
feat/arcade-achievements
Oct 3, 2026
Merged

dmccoystephenson merged 1 commit into
mainfrom
feat/arcade-achievements

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

FishE now reports achievements to arcade (https://danielstephenson.dev/play, Stephenson-Software RFC 0014) through tak.arcade.unlock, which was added to tak in tak#21.

Achievements (12)

id title description trigger
first-catch First Catch Catch your first fish milestone announced
master-fisher Master Fisher Catch 1,000 fish milestone announced
big-earner Big Earner Earn $1,000 total milestone announced
first-mate First Mate Hire your first crew member milestone announced
took-the-helm Took the Helm Captain a voyage yourself milestone announced
letter-of-marque Letter of Marque (hidden) Put a boat to piracy for a day milestone announced
first-export First Export Ship your first fish to another village milestone announced
homeowner Homeowner Buy your first home milestone announced
waterfront-manor Waterfront Manor Own the finest home in the village milestone announced
property-mogul Property Mogul Buy 5 investment properties over your career milestone announced
reached-goal Reached Goal Reach $10,000 goal announced
retired Retired Retire with your fortune made Home -> Retire (the ending)
  • The ten milestones carry an arcadeId in MILESTONES. arcadeDeclarations() produces the declaration list, and the gateway's config/play/boards.yaml entry for fishe was generated from it, so the two cannot drift. first-catch and reached-goal are the ids already used by arcade-social's example.
  • src/achievements/arcade.py wraps every call in try/except. Each unlock happens where the game already announces the milestone or goal, and in Home.retire(). On load, catchUp(stats) re-asserts whatever stats.earnedMilestones already holds, so achievements earned before this change (or while signed out) are credited. That path only reads the list.
  • Save state is untouched. Nothing new is written to player.json, stats.json or timeService.json, and no schema changes. A test checks that a save written with unlocks recorded is byte-identical to one written with them stubbed out.
  • tak is pinned at 963cd3c (tak#21) in requirements.txt and in the Dockerfile, which still had v0.2.0.

Verification

  • tests/achievements/test_arcade.py (25 tests) checks that every declared id is reached through the real game-loop, goal and retire code paths, that a milestone is reported once, that a new game reports nothing, that a loaded save re-asserts what it holds, that a raising bridge never reaches the game, and that saves come out byte-identical. The full suite passes locally (947 tests).
  • In Chromium (Playwright), the built bundle was served as https://fishe.play.danielstephenson.dev with arcade-social faked. A save written by origin/main code loaded and played on. The expected POST /v1/achievements/<id> requests were sent (catch-up, first catch, goal, retire). With /v1/session answering 401, no unlock POST was sent. No page errors were seen.

drafted by Claude on behalf of Daniel Stephenson

🤖 Generated with Claude Code

Twelve arcade achievements for FishE: ten curated milestones carry an
arcadeId (Letter of Marque is declared hidden), plus reaching the goal and
retiring. Each is unlocked through tak.arcade.unlock at the moment the game
announces it, and a loaded save re-asserts the ones it has already earned.
Unlocks are fire-and-forget and touch no save state.

Pins tak at 963cd3c (tak.arcade) in requirements.txt and the Dockerfile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116e9DMUhtNXM5bHUdMhDAn
@dmccoystephenson
dmccoystephenson merged commit fbfea5e into main Oct 3, 2026
1 check passed
@dmccoystephenson
dmccoystephenson deleted the feat/arcade-achievements branch October 3, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant