{"id":31562632,"url":"https://github.com/rybla/generative-text-adventure","last_synced_at":"2026-07-11T22:31:17.520Z","repository":{"id":301452816,"uuid":"1009061194","full_name":"rybla/generative-text-adventure","owner":"rybla","description":"A text adventure game procedurally LLM-generated with persistent state.","archived":false,"fork":false,"pushed_at":"2025-06-30T21:52:51.000Z","size":911,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-01T06:08:16.874Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/rybla.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}},"created_at":"2025-06-26T14:10:57.000Z","updated_at":"2025-07-28T23:41:20.000Z","dependencies_parsed_at":"2025-06-27T00:41:26.289Z","dependency_job_id":"b9bc6538-e1b5-494d-ab8e-e3d9bbf3a953","html_url":"https://github.com/rybla/generative-text-adventure","commit_stats":null,"previous_names":["rybla/generative-text-adventure"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rybla/generative-text-adventure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybla%2Fgenerative-text-adventure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybla%2Fgenerative-text-adventure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybla%2Fgenerative-text-adventure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybla%2Fgenerative-text-adventure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rybla","download_url":"https://codeload.github.com/rybla/generative-text-adventure/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rybla%2Fgenerative-text-adventure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35377012,"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-07-11T02:00:05.354Z","response_time":104,"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":"2025-10-05T04:48:21.190Z","updated_at":"2026-07-11T22:31:17.515Z","avatar_url":"https://github.com/rybla.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# generative-text-adventure\n\nPeople have already tried using LLMs for free-form text adventure games, such as AI Dungeon and others. Two major persistent issues are:\n- world coherence the LLMs will just go along with whatever the player wants, and there's no structure or rules to how things play out\n- world persistence: as the game continues, older events fall out of context and can't be recovered\n\nThere are many different strategies for addressing these issues. I have been experimenting with this strategy:\n\nI encoded the game world as structured data and defined a structured interface for the LLM to interact with the game world (such as moving items, moving the player, etc). An LLM gets a fixed-size context of what the current situation is regarding the player -- a description of the player and their current location, without any historical context. When the player prompts their next actions, an LLM first interprets this natural-language description of what the player wants to do next into a sequence of actions to perform in order to update the game world (using the structured interface). This feature leverages structured output features of advanced models (such as 2.5 models). Finally, these actions are programmatically interpreted to actually update the game world accordingly. In this way, the model _must_ follow the rules of the game defined by this interface since it can _only_ generate valid actions. Since the game world's information is stored in a structured way, it can be saved indefinitely, facilitating infinite world persistence, and also only a fixed-size slice of relevant features can be presented to the model as context when deciding how to interpret the players prompt their next actions so the context is never overflowed, overcoming the context size limitations.\n\n\n## Development\n\nTo install dependencies:\n\n```bash\nbun install\n```\n\nTo start a development server:\n\n```bash\nbun dev\n```\n\nTo run for production:\n\n```bash\nbun start\n```\n\nThis project was created using `bun init` in bun v1.2.14. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frybla%2Fgenerative-text-adventure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frybla%2Fgenerative-text-adventure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frybla%2Fgenerative-text-adventure/lists"}