The games I'll build when the NPCs can think
July 09, 2022
I’ve spent a year wiring GPT-3 into small useful things, and lately every one of those experiments leaves the same residue in my notebook: this belongs in a game. Not as a chatbot bolted onto a menu — as the thing the whole game is made of. So this post is a daydream with one foot on the ground. First the ground.
What I can actually ship this year
The honest version of my game ambitions is small and physical. One absurd verb, done well: you’re an elastic thing — a tongue, a rubber arm — and you fling yourself up a ridiculous tower by grabbing and snapping, wobbly physics doing all the comedy. No AI, no story, no NPCs. Just a satisfying, clippable boing, and a leaderboard. That’s a weekend engine and a month of polish, and it’s the correct first game for someone who has never shipped one. I mention it so you know the rest of this post is written by someone who respects how hard “make a fun thing move” actually is.
Now let me leave the ground entirely.
The daydream: NPCs that aren’t scripts
Every NPC I’ve ever met in a game is a vending machine. You press its dialogue button, it drops a pre-written can. Even the “good” ones — the branching, reactive, beautifully-written ones — are finite trees a human authored in advance. You can feel the walls. Talk long enough and you find the edge of what someone imagined you might say.
The GPT experiments this year killed my patience for that, because I’ve now watched a machine improvise on the spot, in register, about things nobody scripted. It hallucinates, it’s inconsistent, it’s a confident liar — I’ve written three posts’ worth of complaints. But it improvises, and improvisation is exactly the thing every dialogue tree is faking. So: what does a game look like when you build around the improviser instead of hiding it behind a menu?
Here’s the game I keep sketching.
“The Town That Remembers”
A small village. Twenty NPCs. No quest markers, no dialogue wheel — you just talk, in your own words, typed or eventually spoken. And the design rule is a single sentence: every character has a memory, a goal, and a mouth, and only the mouth is the language model.
That distinction is the whole architecture, and it’s the lesson my boring infra year beat into me: don’t put the state in the model. The model is stateless and it lies. So the model is only ever the voice. Everything that must stay true lives in plain code the model isn’t allowed to touch:
- Memory is a database row, not a prompt. When you tell the blacksmith your name, a fact gets written to his table:
knows(player_name). Tomorrow he greets you by it — not because the model “remembered,” but because the game handed that fact back into his prompt. The model supplies fluent words; the database supplies continuity. Same split I use for everything: creativity in the model, truth in the schema. - Goals are a state machine. The blacksmith wants his missing brother found. That goal isn’t vibes in a prompt — it’s a real objective with states (
unaware → suspicious → grateful) that only advance when the game verifies a condition, like you actually having the brother’s ring in your inventory. The model can’t be sweet-talked into skipping tograteful, because the model doesn’t hold the lever. You can’t gaslight a state machine. (I learned that from a git hook, of all things.) - The mouth is the only improvised part. Given “you are the blacksmith, you know these facts, you want this goal, the player just said X,” generate one in-character line. Wrong answers here cost nothing, because a weird sentence is litter, not a corrupted save.
Play it and it should feel like the town is thinking, but under the hood it’s the oldest trick in my toolbox: a fluent liar wrapped in a cage of verifiable state, allowed to be creative exactly where creativity is free and forbidden from touching anything that has to stay true.
The features I’d chase once that works
If the bones hold, the fun mutations are endless, and this is the part I can’t stop adding to:
- Rumor as a data structure. NPCs gossip to each other between your visits. Tell one villager a secret and watch it diffuse through the town’s social graph, mutating slightly at each hop — a game of telephone you seeded. By the time it reaches the mayor it’s wrong in a way you caused. That’s not a cutscene; that’s an emergent story you can’t author, only start.
- The unpickable lock is a conversation. No lockpick minigame. The guard has a goal (keep his job) and a pressure point (his debt), both in his state, and the “puzzle” is finding, in your own words, the thing that moves him. Every player solves it differently because every player talks differently. The solution space is language itself.
- NPCs that model you. Each character keeps a little estimate of what they think of you — trust, fear, debt — updated by what you actually do, and it colors their voice. Lie to someone and get caught, and the model isn’t told “be angry”; it’s handed
trust: lowand left to perform the coldness itself. - A world that runs while you’re gone. Goals tick forward on a clock. The brother you didn’t look for gets found by someone else, or doesn’t, and the blacksmith’s
suspiciouscurdles intobitter, and now the whole town remembers you as the one who didn’t help. Consequence without a scripted branch — just state, advancing, indifferent to whether you’re watching.
None of these need a smarter model. They need the model wrapped in more state and more verification — which, conveniently, is the only kind of programming I actually know how to do.
The honest catch
I can’t ship this yet, and I want to be clear about why, because it’s not just “models aren’t good enough.” Three real walls:
Latency. A conversation with a villager that pauses two seconds per line is unplayable. Dialogue needs to feel like dialogue, and right now the round trip doesn’t.
Cost. At today’s per-token prices, a chatty player could run up real money in an afternoon. A game whose marginal cost per hour is a variable is a business model I don’t know how to price. My little on-call experiments cost pennies because they run rarely; a game runs constantly, by design.
The leash. Everything in this design is the model on a short leash held by state and verification — because unleashed, it’ll cheerfully tell you the blacksmith has a brother he doesn’t have, invent a shop that isn’t there, promise a reward the game can’t pay. The entire craft is building the cage. The model provides ten percent of this game: the words. The other ninety percent is the boring machinery that keeps the words from lying — memory, goals, checks, the same infrastructure discipline as everything else I build, just pointed at make-believe.
Why I’m writing it down now instead of building it
Because the three walls are all falling, visibly, on a timescale of months. Prices have dropped every time I’ve checked. Models got instructable this spring in a way they weren’t last year. Speed is the laggard, but nobody’s betting against it.
So this post is a stake in the ground. When latency and cost cross the line — and I think it’s a “when” measured in a small number of years, not an “if” — the design is already sitting here, waiting, and it was never really about the AI. It was about giving twenty database rows a mouth, and letting a town remember you.
For now, though: back to the tower. The elastic thing isn’t going to fling itself.