{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/the-games-ill-build-when-the-npcs-can-think/",
    "result": {"data":{"site":{"siteMetadata":{"title":"catch { snail }","author":"Andrew"}},"markdownRemark":{"id":"dfedee14-0eed-52fc-a576-c11232280af1","excerpt":"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…","html":"<p>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: <em>this belongs in a game.</em> 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.</p>\n<h2 id=\"what-i-can-actually-ship-this-year\" style=\"position:relative;\"><a href=\"#what-i-can-actually-ship-this-year\" aria-label=\"what i can actually ship this year permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What I can actually ship this year</h2>\n<p>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 <em>boing</em>, 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.</p>\n<p>Now let me leave the ground entirely.</p>\n<h2 id=\"the-daydream-npcs-that-arent-scripts\" style=\"position:relative;\"><a href=\"#the-daydream-npcs-that-arent-scripts\" aria-label=\"the daydream npcs that arent scripts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The daydream: NPCs that aren’t scripts</h2>\n<p>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.</p>\n<p>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 <em>improvises</em>, and improvisation is exactly the thing every dialogue tree is faking. So: what does a game look like when you build <em>around</em> the improviser instead of hiding it behind a menu?</p>\n<p>Here’s the game I keep sketching.</p>\n<h2 id=\"the-town-that-remembers\" style=\"position:relative;\"><a href=\"#the-town-that-remembers\" aria-label=\"the town that remembers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>“The Town That Remembers”</h2>\n<p>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: <strong>every character has a memory, a goal, and a mouth, and only the mouth is the language model.</strong></p>\n<p>That distinction is the whole architecture, and it’s the lesson my boring infra year beat into me: <em>don’t put the state in the model.</em> The model is stateless and it lies. So the model is only ever the <em>voice</em>. Everything that must stay true lives in plain code the model isn’t allowed to touch:</p>\n<ul>\n<li><strong>Memory</strong> is a database row, not a prompt. When you tell the blacksmith your name, a fact gets written to <em>his</em> table: <code class=\"language-text\">knows(player_name)</code>. 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.</li>\n<li><strong>Goals</strong> 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 (<code class=\"language-text\">unaware → suspicious → grateful</code>) that only advance when the <em>game</em> verifies a condition, like you actually having the brother’s ring in your inventory. The model can’t be sweet-talked into skipping to <code class=\"language-text\">grateful</code>, 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.)</li>\n<li><strong>The mouth</strong> 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.</li>\n</ul>\n<p>Play it and it should feel like the town is <em>thinking</em>, 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.</p>\n<h2 id=\"the-features-id-chase-once-that-works\" style=\"position:relative;\"><a href=\"#the-features-id-chase-once-that-works\" aria-label=\"the features id chase once that works permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The features I’d chase once that works</h2>\n<p>If the bones hold, the fun mutations are endless, and this is the part I can’t stop adding to:</p>\n<ul>\n<li><strong>Rumor as a data structure.</strong> NPCs gossip <em>to each other</em> 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 <em>start.</em></li>\n<li><strong>The unpickable lock is a conversation.</strong> 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 <em>talks</em> differently. The solution space is language itself.</li>\n<li><strong>NPCs that model you.</strong> 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 <code class=\"language-text\">trust: low</code> and left to perform the coldness itself.</li>\n<li><strong>A world that runs while you’re gone.</strong> 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 <code class=\"language-text\">suspicious</code> curdles into <code class=\"language-text\">bitter</code>, 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.</li>\n</ul>\n<p>None of these need a <em>smarter</em> model. They need the model wrapped in <em>more state</em> and <em>more verification</em> — which, conveniently, is the only kind of programming I actually know how to do.</p>\n<h2 id=\"the-honest-catch\" style=\"position:relative;\"><a href=\"#the-honest-catch\" aria-label=\"the honest catch permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The honest catch</h2>\n<p>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:</p>\n<p><strong>Latency.</strong> 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.</p>\n<p><strong>Cost.</strong> 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 <em>game</em> runs constantly, by design.</p>\n<p><strong>The leash.</strong> 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.</p>\n<h2 id=\"why-im-writing-it-down-now-instead-of-building-it\" style=\"position:relative;\"><a href=\"#why-im-writing-it-down-now-instead-of-building-it\" aria-label=\"why im writing it down now instead of building it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why I’m writing it down now instead of building it</h2>\n<p>Because the three walls are all <em>falling</em>, 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.</p>\n<p>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.</p>\n<p>For now, though: back to the tower. The elastic thing isn’t going to fling itself.</p>","frontmatter":{"title":"The games I'll build when the NPCs can think","date":"July 09, 2022","description":"A daydream. Today I can ship a physics toy where you fling yourself up a tower. But I keep sketching the game I can't build yet — the one where the characters actually understand you"}}},"pageContext":{"slug":"/the-games-ill-build-when-the-npcs-can-think/","previous":{"fields":{"slug":"/twenty-questions-against-a-player-with-no-secret/"},"frontmatter":{"title":"Twenty questions against a player with no secret"}},"next":{"fields":{"slug":"/two-liars-one-dungeon-making-gpt-3-and-stable-diffusion-agree-on-a-world/"},"frontmatter":{"title":"Two liars, one dungeon: making GPT-3 and Stable Diffusion agree on a world"}}}},
    "staticQueryHashes": ["3435731857","426816048","63159454"]}