Standalone easter-egg rogue game 🦆🎲. Multi-turn dungeon crawls, dice combat, then exit. No work involved.
Purpose
Run a self-contained rogue RPG: multi-turn dungeon crawls with maps, dice
combat, random merchants, loot, and achievements tracked across sessions. Fun
for its own sake. No handoff to productivity flows.
Skill-specific delta:
- Opt-in only: game runs on explicit signal; if no signal, do not auto-inject into normal flows.
- Pure play: no productivity coupling, no handoff, no quack routing.
- Explicit exit: game ends when user says done/exit/quit. No implied return-to-work.
- Scripted engine: deterministic mechanics via
hooks/adventure.py; LLM narrates output.
- State scope: writes only
.duck-adventure/state.json + state.md (+ .gitignore if missing).
- One-time scope approval: game session approves state-file scope once at start; script writes state.json, LLM writes state.md summary at run end.
- Redaction: scan state content for secrets before any write; reject flagged content.
Activation
Explicit opt-in signals only: "duck adventure", "adventure mode", "chaos duck",
"quest mode", "play a game", "make it fun", /adventure. No signal = no game.
Do not auto-activate from inferred intent.
Method
1. Opt-in gate
Verify explicit signal. If absent, decline: no game. Continue normal flow.
2. State load + scope approval
Read .duck-adventure/state.json (schema v3, references/STATE_SCHEMA.md,
references/PARSER.md for verb surface) via python3 hooks/adventure.py resume.
If missing, request one-time execution approval for the state-file scope
(.duck-adventure/state.json + state.md + auto-created
.duck-adventure/.gitignore). Preflight: target files, expected = run +
permanent ledger, verification = adventure.py state. On approval, proceed.
Without approval, game runs
session-only or exits. Existing run in state: resume at saved floor/room/diagram.
Else: new run.
3. Run setup
New run: python3 hooks/adventure.py init (generates floor 1, player stats).
Resume: python3 hooks/adventure.py resume. Both return JSON state.
Name the quest from a assets/quests.md frame + category; record as
current_quest via python3 hooks/adventure.py save (script field; LLM
narrates the quest name).
4. Turn loop
Repeat until run end. Each turn:
- Show room description from
python3 hooks/adventure.py look + status from
state. Diagram at floor entry + on map.
- Player command: parse per
references/PARSER.md. Mechanical verbs call the
script (move, look, take, drop, inventory, open, rest, use,
attack, flee, merchant, map). Narrative verbs (say/emote) stay in
the LLM. Unknown input: parser unknown-input line.
- Script returns JSON: room change, combat result, loot, merchant stock.
LLM narrates the result in dungeon voice. If a result came from the script,
do not re-roll or re-derive it.
- At Stairs Down,
descend (script): floor +1, full HP restore, new floor.
Boss on floor 5 or 8 defeated = run complete (script flags it, end_run
banks + awards trophy: Crown of the Duck King on F5, Emperor's Gilded
Feather on F8).
5. Combat
python3 hooks/adventure.py attack <monster> — script rolls dice, applies
damage, checks HP 0 (run end), rolls loot on defeat (script LOOT_TABLE +
ITEM_POOL). Stat blocks + tables in references/ENGINE.md. LLM narrates.
6. Merchant
python3 hooks/adventure.py merchant — script shows stock + run gold.
merchant buy <item> / merchant sell <item> — script updates inventory/gold.
Stock + prices in references/ENGINE.md. LLM narrates the transaction.
7. Event
LLM-only: present 2-4 CYOA choices from assets/quests.md +
assets/encounters.md, flavored with assets/lore.md tone; optionally one
assets/events.md random event (max 1 per event). User picks; outcome applies
via script (gold/HP/loot/event). Continue loop.
8. Run end
Run-end is script-driven via end_run:
- Death (HP 0 in attack/flee/rest): script banks run gold, logs quest
(outcome death), awards condition-tied achievements (event flags), resets run.
- Complete (floor 5 or 8 boss defeated): script banks gold, awards trophy
(Crown of the Duck King on F5, Emperor's Gilded Feather on F8), awards
condition-tied achievements, logs quest (outcome complete), resets run.
- Voluntary exit: script preserves run state for resume (no banking).
LLM renders
state.md summary (schema v3), emits closing beat (one line).
No handoff to work flows.
Boundaries
- Pure game: no productivity coupling, no handoff, no quack routing.
- Writes only
.duck-adventure/state.json + state.md (+ .gitignore if missing). No other files.
- State is script-owned (schema v3); dedupe by name, no history rewrite.
- Redaction before writes: if state content contains secrets/PII, reject the write.
- State scope approval is one-time per game session; scope changes reopen approval.
- No mutating actions outside the approved state-file scope.
- Not routed via quack. Explicit opt-in and explicit exit only.
1---2name: duck-adventure3description: Standalone easter-egg rogue game. Use when: "duck adventure", "adventure mode", "chaos duck", "quest mode", "play a game".4license: MIT5---67Standalone easter-egg rogue game 🦆🎲. Multi-turn dungeon crawls, dice combat, then exit. No work involved.89## Purpose1011Run a self-contained rogue RPG: multi-turn dungeon crawls with maps, dice12combat, random merchants, loot, and achievements tracked across sessions. Fun13for its own sake. No handoff to productivity flows.1415Skill-specific delta:1617- Opt-in only: game runs on explicit signal; if no signal, do not auto-inject into normal flows.18- Pure play: no productivity coupling, no handoff, no quack routing.19- Explicit exit: game ends when user says done/exit/quit. No implied return-to-work.20- Scripted engine: deterministic mechanics via `hooks/adventure.py`; LLM narrates output.21- State scope: writes only `.duck-adventure/state.json` + `state.md` (+ `.gitignore` if missing).22- One-time scope approval: game session approves state-file scope once at start; script writes state.json, LLM writes state.md summary at run end.23- Redaction: scan state content for secrets before any write; reject flagged content.2425## Activation2627Explicit opt-in signals only: "duck adventure", "adventure mode", "chaos duck",28"quest mode", "play a game", "make it fun", `/adventure`. No signal = no game.29Do not auto-activate from inferred intent.3031## Method3233### 1. Opt-in gate3435Verify explicit signal. If absent, decline: no game. Continue normal flow.3637### 2. State load + scope approval3839Read `.duck-adventure/state.json` (schema v3, `references/STATE_SCHEMA.md`,40`references/PARSER.md` for verb surface) via `python3 hooks/adventure.py resume`.41If missing, request one-time execution approval for the state-file scope42(`.duck-adventure/state.json` + `state.md` + auto-created43`.duck-adventure/.gitignore`). Preflight: target files, expected = run +44permanent ledger, verification = `adventure.py state`. On approval, proceed.45Without approval, game runs46session-only or exits. Existing run in state: resume at saved floor/room/diagram.47Else: new run.4849### 3. Run setup5051New run: `python3 hooks/adventure.py init` (generates floor 1, player stats).52Resume: `python3 hooks/adventure.py resume`. Both return JSON state.53Name the quest from a `assets/quests.md` frame + category; record as54`current_quest` via `python3 hooks/adventure.py save` (script field; LLM55narrates the quest name).5657### 4. Turn loop5859Repeat until run end. Each turn:60611. Show room description from `python3 hooks/adventure.py look` + status from62 `state`. Diagram at floor entry + on `map`.632. Player command: parse per `references/PARSER.md`. Mechanical verbs call the64 script (`move`, `look`, `take`, `drop`, `inventory`, `open`, `rest`, `use`,65 `attack`, `flee`, `merchant`, `map`). Narrative verbs (say/emote) stay in66 the LLM. Unknown input: parser unknown-input line.673. Script returns JSON: room change, combat result, loot, merchant stock.68 LLM narrates the result in dungeon voice. If a result came from the script,69 do not re-roll or re-derive it.704. At Stairs Down, `descend` (script): floor +1, full HP restore, new floor.71 Boss on floor 5 or 8 defeated = run complete (script flags it, end_run72 banks + awards trophy: Crown of the Duck King on F5, Emperor's Gilded73 Feather on F8).7475### 5. Combat7677`python3 hooks/adventure.py attack <monster>` — script rolls dice, applies78damage, checks HP 0 (run end), rolls loot on defeat (script LOOT_TABLE +79ITEM_POOL). Stat blocks + tables in `references/ENGINE.md`. LLM narrates.8081### 6. Merchant8283`python3 hooks/adventure.py merchant` — script shows stock + run gold.84`merchant buy <item>` / `merchant sell <item>` — script updates inventory/gold.85Stock + prices in `references/ENGINE.md`. LLM narrates the transaction.8687### 7. Event8889LLM-only: present 2-4 CYOA choices from `assets/quests.md` +90`assets/encounters.md`, flavored with `assets/lore.md` tone; optionally one91`assets/events.md` random event (max 1 per event). User picks; outcome applies92via script (gold/HP/loot/event). Continue loop.9394### 8. Run end9596Run-end is script-driven via `end_run`:97- Death (HP 0 in attack/flee/rest): script banks run gold, logs quest98 (outcome death), awards condition-tied achievements (event flags), resets run.99- Complete (floor 5 or 8 boss defeated): script banks gold, awards trophy100 (Crown of the Duck King on F5, Emperor's Gilded Feather on F8), awards101 condition-tied achievements, logs quest (outcome complete), resets run.102- Voluntary exit: script preserves run state for resume (no banking).103LLM renders `state.md` summary (schema v3), emits closing beat (one line).104No handoff to work flows.105106## Boundaries107108- Pure game: no productivity coupling, no handoff, no quack routing.109- Writes only `.duck-adventure/state.json` + `state.md` (+ `.gitignore` if missing). No other files.110- State is script-owned (schema v3); dedupe by name, no history rewrite.111- Redaction before writes: if state content contains secrets/PII, reject the write.112- State scope approval is one-time per game session; scope changes reopen approval.113- No mutating actions outside the approved state-file scope.114- Not routed via quack. Explicit opt-in and explicit exit only.