FastAPI Story Project
ArchivedApril 1, 2024
A choose-your-own-adventure story engine built with Python and FastAPI. A recollection of the genre that made reading feel like gaming — and a reflection on how branching narratives are fundamentally tree traversal problems that map perfectly to both game design and software architecture.
Purpose
Built a choose-your-own-adventure engine using FastAPI as the backend. The reader reaches a decision point, picks a choice, and the API returns the next story segment. The narrative branches into a tree. Some paths lead to victory. Some lead to disaster. The reader's choices are the input. The story is the output.
Stack
What I Learned
- Choose Your Own Adventure books were the gateway drug for an entire generation of gamers and programmers. Published by Bantam Books starting in 1979, they presented stories in second person ("You enter the cave...") with decision points ("If you turn left, go to page 47. If you turn right, go to page 83"). The genre sold over 250 million copies. For many kids, it was the first time reading felt interactive — the first time a book responded to your choices.
- The data model for a branching narrative is a directed acyclic graph (or a tree with merging paths). Each node is a story segment with text content and a list of choices. Each choice points to another node. Terminal nodes are endings (victory, defeat, or ambiguous). The graph can be stored as JSON: { id: "cave-entrance", text: "You enter the dark cave...", choices: [{ text: "Turn left", next: "left-tunnel" }, { text: "Turn right", next: "right-tunnel" }] }. FastAPI serves this as a REST API: GET /story/{nodeId} returns the current segment and available choices.
- FastAPI was chosen because it is the fastest way to build a Python REST API — type-hinted endpoints, automatic OpenAPI documentation, async support, and Pydantic validation out of the box. For a story engine, the endpoints are trivial: GET /story/start, GET /story/{id}, POST /story/choice with a body containing the chosen path. The simplicity of the API mirrors the simplicity of the interaction: read, choose, continue.
- Branching narratives have a combinatorial explosion problem: if every decision point has 3 choices and you have 10 decision points, the tree has 3^10 = 59,049 possible paths. No author can write 59,049 unique segments. The solution: convergence points (multiple paths merge back to the same node), shared segments (reuse text across paths with minor variations), and pruning (some choices lead to immediate endings, cutting off entire branches). Managing this complexity is the narrative design challenge.
- The second-person perspective ("You walk into the room") is a deliberate design choice that increases immersion. It positions the reader as the protagonist, not an observer. This same technique appears in UX writing ("Your order has been placed") and in how this blog addresses the reader directly. Second person creates complicity between the author and the reader.
Key Insights
- Choose Your Own Adventure books are structurally identical to state machines — the reader is in a state (a story node), makes a choice (an event), and transitions to a new state (the next node). The narrative graph IS a state machine. This connects directly to the Tasks page on this site: a task is an event that changes state. In a CYOA book, a choice is an event that changes the story. The abstraction is the same.
- The genre had a renaissance with interactive fiction engines (Twine, Ink, ChoiceScript), Netflix's Bandersnatch, and AI-driven narrative (where the choices are not pre-authored but generated in real time by an LLM). AI choose-your-own-adventure is particularly interesting because the tree is infinite — the story generates new branches on demand. The tradeoff: pre-authored branches are crafted and satisfying. AI-generated branches are infinite but often generic. The best implementations combine both: authored key moments with AI-generated connective tissue.
- For Potato Literature, a choose-your-own-adventure potato story is an obvious product. "You are a potato. You have just been harvested. If you want to become a french fry, turn to page 12. If you want to become vodka, turn to page 34." The format is perfect for the brand: absurd premise, earnest execution, interactive engagement. This is on the someday list.
- FastAPI as a tool taught a broader lesson: Python for backend prototyping is unmatched in speed-to-working-API. The same story engine in Java would require Spring Boot setup, annotations, DTOs, and configuration. In FastAPI, it is a single file with decorated functions. For prototypes, experiments, and side projects, Python + FastAPI removes the ceremony and lets you focus on the idea.
This post was composed through a conversation between Brett Owers and Claude Code (Anthropic). The content reflects Brett's recollection of each project and the lessons drawn from it. Some details may be approximate or omitted — the purpose is to paint an honest picture of a software engineer's development over time, not to serve as a precise historical record.