I've been on the rope-end of other people's deadlines for a long time. Magazine closes where the cover hasn't been approved and the printer is already calling. Brand campaigns that ship Tuesday whether legal signed off or not. A studio at 2am with the model on her third coffee and the light gone wrong. Pentest reports due Friday because someone's board meeting is Monday. Different rooms, same shape. You learn the rhythm. You learn whose panic is real and whose is theater. You learn what shipping looks like when somebody else has the rope around their neck.
Now it's my sprint.
This is the game I've been building. The deadline is mine. The rope is mine. And every one of those rooms โ the studio, the agency, the engagement โ is finally pointed at my own ship date.
The plan I'm about to lay out was a four-week plan when I wrote it. The clock has flexed since โ the Steam date pushed back slightly, polish revealed work that polish always reveals โ but the spine is the same. One AI collaborator. A pile of code, a pile of writing, and a clock.
The unlock that made the sprint real.
A couple of days ago I asked Claude a simple question:
"Why do my story branches feel hidden when I play, even though I know they're written?"
Claude went into the code and came back with the answer in fifteen minutes.
I had ~290 stories written. The selector that picked the next chapter cycled through twelve. Twelve. The other ninety-five percent of my writing was sitting in the codebase, never reached, because the routine progression was hardcoded to a list of three stories per age bracket and rotated through them on a modulo.
I'd written a library and built a peephole.
This is the lesson nobody warns you about when you're shipping with AI. The AI will help you make the content. It will not necessarily help you expose the content unless you ask the right question. And you don't always know what the right question is until you've played the thing yourself, alone, in silence, and felt that something is missing even though you remember writing it.
The fix isn't more content. The fix is the picker.
The prompt that found it.
The killer prompt looks pedestrian on the page. It is not.
"Why do my story branches feel hidden when I play, even though I know they're written?"
Three things make it work, and they are the three things I want you to steal:
-
Symptom-first, not solution-first. I didn't say audit the chapter selector or check for off-by-one in the rotation logic. I described the feeling. Hidden. The model has to read the codebase to map the feeling onto the cause, which is exactly what you want. The moment you name the bug, you've narrowed the model's search to whatever you already suspected. Most of the time you suspect wrong.
-
The contradiction is the prompt. Even though I know they're written is the engine. You're handing the model a fact โ the content exists โ and a feeling โ it doesn't surface. The gap between fact and feeling is the bug. Models are good at closing that gap if you give them both halves.
-
No prescriptions, no guardrails, no scope. I didn't say don't touch the database or only look at the UI layer. The picker turned out to live in a service file two layers from where I would've started. If I'd scoped the question, the model would've stayed scoped, and I would still be polishing the wrong thing.
The general shape: describe the symptom, name the contradiction, ask why. Run that on any project where you suspect there's more under the hood than the user can see, and you will be amazed at what the AI digs up that you'd been stepping over for months.
The picker problem (it's not just games).
What I'm calling the picker is whatever decides what comes next in your product. In a game, it's the next chapter. In a SaaS app, it's what surfaces on the dashboard. In a content site, it's what fills the recommendation slot. In an editor, it's what the AI suggests.
Most products start with a hardcoded picker because that's the fastest path to a working prototype. Then you write more content, add more flows, build more features โ and the picker stays primitive. You ship a library through a peephole.
Symptoms:
- Users say "I feel like there isn't much here" even though there's a lot.
- Your team gets bored testing the same paths.
- The metrics on your "long tail" content are zero, and you assume nobody wants it. Nobody's seeing it.
- New content takes weeks to surface because somebody has to manually wire it into the picker.
The fix is what I started calling the Living Pool. Tag every piece of content with eligibility metadata โ what state it requires, what tone it carries, what feels right when. Then write a scorer that reads the world state and picks the right thing dynamically. Not era-gated. Not hardcoded. Lived.
The shape of the architecture, in pseudocode:
- Every content item gets:
- Hard gates (must-be-true conditions)
- Soft tags (emotional register, theme, location)
- A baseline weight
- The picker:
- Filters by hard gates
- Drops anything in the recently-played window
- Scores remaining items by state-relevance + variety + lifecycle echo
- Weighted-random pick from the top N
- The world tracks:
- Recently played IDs (anti-repeat)
- Recent tones (anti-emotional-fatigue)
- Last speaker (anti-monotony)
In Dart, the scorer ends up looking like this โ readable enough that you can argue with it instead of guessing what it's doing:
double scoreItem(ContentItem item, WorldState world) {
if (!item.gates.every((g) => g.satisfiedBy(world))) return -1;
if (world.recentlyPlayed.contains(item.id)) return -1;
var score = item.baselineWeight;
score += item.tags.relevanceTo(world.currentMood) * 2.0;
score -= world.recentTones.fatiguePenaltyFor(item.tone);
score += item.lifecycleEcho(world.phase);
return score;
}
That's it. That's the architecture. It works for chapters, for events, for emails, for content recommendations, for AI prompts in your toolchain. The shape is the same.
The reason it matters is simple: I had ~290 stories of content sitting in the database. Once I unlocked the picker, the player got the whole library. That's not feature work. That's ten times my game's apparent size, free, just from fixing one service file.
The sprint, in four weeks.
Once you've identified your big unlock โ the thing that makes the rest worth polishing โ the sprint plan writes itself.
Week 1 โ The big unlock + critical narrative fixes.
Build the picker. Migrate the existing content into the new pool with conservative defaults. Fix the one or two narrative paths the user has flagged as broken.
Don't tag every piece of content yet. Just make the new picker work, and verify that the player can suddenly reach what they couldn't before.
The deliverable at end of Week 1 isn't polish. It's the unlock. The "huh, there's a lot more here" moment.