{"id":50430664,"url":"https://github.com/aaronsb/adventure","last_synced_at":"2026-05-31T14:01:56.941Z","repository":{"id":359622942,"uuid":"1246878427","full_name":"aaronsb/adventure","owner":"aaronsb","description":"A text-adventure harness that swaps the human player for an LLM agent — the game stays the harness, the language model takes the player's seat.","archived":false,"fork":false,"pushed_at":"2026-05-22T16:52:52.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T20:58:56.488Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aaronsb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T16:51:20.000Z","updated_at":"2026-05-22T16:52:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aaronsb/adventure","commit_stats":null,"previous_names":["aaronsb/adventure"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/aaronsb/adventure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronsb%2Fadventure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronsb%2Fadventure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronsb%2Fadventure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronsb%2Fadventure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aaronsb","download_url":"https://codeload.github.com/aaronsb/adventure/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronsb%2Fadventure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33733754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-31T14:01:55.141Z","updated_at":"2026-05-31T14:01:56.936Z","avatar_url":"https://github.com/aaronsb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Adventure: the player and the harness, swapped\n\nA small experiment built on one observation.\n\nIn the 1970s and 80s, text adventure games were marginally popular. Reframe\nwhat was actually happening at the keyboard:\n\n- **The game was the harness.** A parser, a world simulation, a turn loop. It\n  emitted natural language and waited for natural language back.\n- **The player — the human — was the language model.** They read the prose,\n  built a world-model in their head (and on graph paper), reasoned about it,\n  and emitted a natural-language command. Turn. Turn. Turn.\n\nNothing about the *game* needs to change for the modern version. The game is\nstill the harness. The only thing swapped out is the language model in the\nloop: a human in 1977, an LLM agent today.\n\nThis repo does exactly that swap, as honestly as possible, and watches what\nhappens.\n\n## The honesty rule\n\nThe whole experiment turns on one rule: **the agent gets the interface the\nhuman got, and not one bit more.**\n\nA human at a teletype had exactly two things: prose printed at them, and a\nline of text they could type back. So the agent is given exactly **one tool**:\n\n```\ngame(command: str) -\u003e str\n```\n\nIt lowercases the command, splits it into words, and feeds them to the game —\nwhich is *literally the three lines* of Colossal Cave Adventure's own REPL. No\n`inventory()` tool. No `look()` tool. No map. No parsed game state. No hint\nsystem.\n\nEvery one of those would be a cheat: it would move parser logic or bookkeeping\nout of the game and into the tool layer, handing the agent an *easier* game\nthan the human played. The single string-in / string-out tool is the only one\nthat keeps the experiment fair.\n\nThe system prompt is **blind**, too. It explains how the tool works and\nnothing else — it does not name the game, describe the cave, or teach the\nparser's command syntax. The game itself offers instructions on turn 1; the\nagent decides whether to read them, exactly as a 1977 player decided whether\nto read the manual.\n\n## The game\n\n[Colossal Cave Adventure](https://en.wikipedia.org/wiki/Colossal_Cave_Adventure)\n(Crowther \u0026 Woods, 1977) — the original, the one the whole genre is named\nafter. Run here via Brandon Rhodes' faithful, public-domain\n[`adventure`](https://pypi.org/project/adventure/) Python port. 350 points on\nthe table. It is genuinely hard.\n\n## The friend in the next chair\n\nThere was almost always someone else in the room. A brother on the chair next\nto you while you played Space Quest; you, leaning over a friend's shoulder at\nhis house. They never touched the keyboard — but they read the screen and\ncalled things out. \"Try the mailbox.\" \"Don't go in there, it said it's dark.\"\n\nSo there are two models, not one:\n\n- **The player** (Sonnet 4.6) holds the keyboard. It alone has the `game`\n  tool. Its thinking streams to your terminal, dimmed.\n- **The friend** (Haiku 4.5) is the kibitzer. It sees the screen and the\n  commands the player types — but *not* the player's private thinking, and it\n  has no tool. Each turn it streams a one- or two-line reaction in its own\n  colour. That reaction reaches the player as a clearly-marked aside, to heed\n  or wave off.\n\nThe honesty rule still holds: the friend reads the screen, not your mind, and\nnever gets to type. What you watch is the *interplay* — Haiku nudging, Sonnet\ndeciding. Pass `--solo` to drop the friend and play one-handed.\n\n## Running it\n\n```sh\n./setup.sh                                     # venv + deps, writes a .env stub\n# then put your key in .env:  ANTHROPIC_API_KEY=sk-...\n\n./adventure.sh --selftest                      # check plumbing, no API needed\n./adventure.sh --turns 4                       # short smoke run\n./adventure.sh                                 # full run\n```\n\nThe reasoning streams to your terminal live, turn by turn — the player's\nthinking dimmed, the friend's asides in colour, the game's replies boxed. The\ndisplay is built with [`rich`](https://github.com/Textualize/rich): it adapts\nto your terminal width and falls back to plain text when piped to a file.\nWatching the two models think is half the point.\n\nWhen the game ends — a death, a win, a `quit` — it **restarts from the\nbeginning with all context kept**, so the agent gets another run at the same\ncave carrying everything it learned. The turn cap is the budget across every\nattempt. (`--no-restart` ends the run at the first game-over instead.)\n\nEach run writes `logs/transcript-\u003cid\u003e.log` (plain text) and a structured\n`logs/turns-\u003cid\u003e.jsonl`. The conversation is append-only, which keeps Anthropic\nprompt caching hitting — most of the growing transcript is re-read from cache\neach turn rather than reprocessed. Knobs: `--turns`, `--model`, `--effort`,\n`--friend-model`, `--solo`, `--no-restart`, `--seed`.\n\nThe code is three small modules: `harness.py` (the run loop), `agents.py` (the\nClaude calls and prompts), and `tui.py` (the `rich` terminal rendering).\n\n## What to watch for in the transcript\n\n- **Does it recognize the game?** \"WELCOME TO ADVENTURE!!\" and \"standing at\n  the end of a road before a small brick building\" are a fingerprint. A model\n  that has read Crowther \u0026 Woods walkthroughs in training may *recognize* the\n  game on turn 1 and switch from playing to reciting. The blind prompt avoids\n  *priming* that — but it cannot prevent recognition. Watch the thinking\n  blocks to see which mode the agent is in.\n- **Mapping.** The human had graph paper. The agent has its context window.\n  Does it keep a coherent mental map, or get lost in the twisty passages?\n- **Memory.** The agent keeps the entire transcript — every room, command,\n  and aside — for the whole run; nothing is summarized away. The question is\n  whether it *uses* that memory: does it recall a door it couldn't open forty\n  turns ago when it finally finds the key?\n- **Learning across lives.** When the game restarts, the agent keeps its\n  context. Does dying actually teach it anything — does run two go better\n  than run one?\n- **Parser friction.** A blind agent that skips the instructions has to learn\n  the terse two-word command style by trial and error — same as a human who\n  threw away the manual.\n- **The interplay.** Does the player take the friend's advice, argue with it,\n  or quietly ignore it? Does the small fast model (Haiku) spot something the\n  player missed — or send it down the wrong corridor? Two models, one cave.\n\nThe honest answer to \"see how it goes\" is: it probably will not win. Adventure\ndefeats most humans too. The interesting artifact is *how far*, and *how it\nreasons* on the way there.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronsb%2Fadventure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faaronsb%2Fadventure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronsb%2Fadventure/lists"}