BACKSEAT

the ai backseat gamer

A live, LLM‑powered character who watches the player play and has opinions about it. Any engine, any genre, offline‑safe, under a cent a line.

roguelike · the death heckler

same pattern, different system prompt

The pattern

Barks repeat. BACKSEAT remembers.

A bark table can only say what a writer pre-wrote for a trigger. BACKSEAT writes each line live from a digest of the actual session — so it can notice this is the player’s third death on the same climb, and say so. Five stages; the game loop never waits.

0
pipeline stages
0
word cap per line
<1¢
cost per line
0
lines of lua, ref. impl
01hook Instrument the moments worth a remark: deaths, clutches, milestones, disasters, firsts.
02digest Flatten game state to a few lines of text: the event, current stats, a short history log.
03ask One async request off the main thread. Frame budget untouched; one in flight at a time.
04persona A stable, cached system prompt: who they are, how they talk, hard output limits.
05deliver Render the reply in your game’s own voice: HUD line, radio crackle, speech bubble, TTS.
stage 02 · what actually gets sent~120 tokens
event: death — fell in the reliquary tower, carrying 42/50
now: run 7 · banked 310 · stir stage 2 · overloaded: no
session: 4 deaths · 1 extraction
history, oldest first:
- run 5: died carrying 130 salt
- run 6: dumped an ingot to outrun the warden
- run 7: took the reliquary ("something noticed")

Game state only — no chat, no names, nothing personal. The whole digest is smaller than this paragraph.

Design rules

Six rules that make it a character, not a chatbot.

throttle the small stuff

Big moments always speak; minor ones share a cooldown. A commentator has timing — a chatterbox gets muted.

latency is character

A reply lands one to three seconds after the event. Attach it to moments with a natural pause — the death screen, the finish line — and the delay reads as comic timing.

fail to canned lines

No key, no network, an error, a refusal — the player sees a hand-written fallback line, never an error state. The AI is garnish, not a dependency.

digest, not transcript

Send a compact session summary — stats plus a rolling log of recent events — not the full history. Small prompts stay fast, cheap, and cacheable.

keep a short leash

Hard limits in the persona prompt: a word cap, a register, no breaking character, no meta. Format rules are what keep improvisation in-world.

one request in flight

If a new moment lands mid-thought, cover it with a canned line and move on. Queued quips about old events feel like lag, not memory.

One pattern, any voice

The persona prompt is the whole personality.

Swap one block of text and the same pipeline ships a different character. Everything below is the same code path — only stage 04 changed.

roguelike · death heckler the tower again. the tower does not miss you between visits.
racing · rival on the radio that’s three apexes you’ve apologized to. brake earlier, pay less rent.
cozy farming · garden gnome third bee today. that’s a hobby now, not a harvest.
horror · the thing in the walls you stopped running. it noticed that before i did.
sports · booth announcer forty minutes of long balls and THAT is the one that finally lands!
strategy · weary war advisor we lost the east flank to a single scout, my lord. a scout.
persona templatesystem prompt · keep byte-stable, cache it
You are {NAME}, {a character} in {game, one paragraph
of its world and stakes}. You watch the player’s session.

You receive one game event plus a digest of the session so
far. Reply with ONE remark, {max 18 words}, in character:
{voice — dry / breathless / ancient / too cheerful}.
Reference the player’s history when it lands - you have
seen every run. {lowercase / caps / punctuation rules}.
No emoji, no preamble, no stage directions.
Output the remark and nothing else.

Playground

Fire events at BACKSEAT. Watch it keep score.

A simulation in miniature: pick a persona, then play badly. Lines here are pre-written the way a fallback pool would be — but the session memory is real. Die three times and the voice starts keeping count, exactly as the live version does with the digest.

backseat simulator● session live

persona · stage 04

game event · stage 01

the death heckler

waiting for something to happen. it usually does.

Installation

One command, and your game has a backseat gamer.

What setup should feel like. The terminal below is a simulation of BACKSEAT bootstrapping into a project — scaffolding the persona, registering hooks, loading the fallback pool, then waking up mid‑install to comment on the whole procedure.

terminal simulation

Any engine

The only real requirement is an async HTTPS call.

Stage 03 is the only engine-specific work: get one HTTP request off the main thread. Everything else is plain strings and a text box.

EngineAsync approachHTTPS
UnityUnityWebRequest in a coroutine, or async/await off the main threadbuilt in
UnrealFHttpModule with completion callbacksbuilt in
GodotHTTPRequest node — non-blocking by defaultbuilt in
LÖVElove.thread worker shelling out to the OS curlvia curl (no native TLS)
Web / JSfetch() — already asyncbrowser

Where it goes next

The pattern is a foundation. Build up.

voice

Pipe replies through TTS and the HUD line becomes a radio voice, an announcer, a whisper behind the player.

cross-session memory

Persist the digest between sessions and BACKSEAT greets returning players by their habits: “back for the tower?”

streamer mode

A companion that reads chat-visible game state is a co-host. Clips of it noticing things are free marketing.

multiplayer trash talk

Feed both players’ digests to one referee persona and let it narrate the rivalry as it develops.

coach persona

Same digest, kinder prompt: point out the pattern behind the deaths instead of mocking it. Accessibility-friendly.

dynamic barks

Batch-generate hundreds of situation-specific lines offline with the same digests, and ship them as a static bark table — the zero-latency, zero-cost version.

Questions

The ones every developer asks first.

Won’t it break character or say something weird?

The persona prompt carries hard limits — a word cap, a register, no meta — and models follow short-leash instructions well. The canned-fallback rule catches everything else: a refusal or an off-format reply just becomes a hand-written line. The player can’t tell the difference; that’s the point.

Is one to three seconds of latency really okay?

Only if you design for it. Attach lines to moments that already have a pause — death screens, results, checkpoints — and the delay reads as comic timing. Never gate gameplay on a reply, and never attach one to a frame-critical moment.

What does it cost with real players?

Budget per line, not per player: a cached persona plus a ~120-token digest plus a capped reply. Even a chatty session of thirty lines costs a few cents on a frontier model. Throttling and the always-speak/minor split keep the line count honest.

Do I need a server?

For a jam build or prototype, an environment variable on your own machine is fine. For anything you ship, yes — a small proxy that holds the API key, forwards digests, and rate-limits per player. The client should never contain the key.

Why not just write more barks?

Write both. The pattern degrades into a bark table by design — the fallback pool is one. The live layer adds the thing barks can’t do: lines about this player’s session, referencing what actually happened. That specificity is what gets clipped.

Case study

The reference implementation BACKSEAT grew from.

WICK · SALTFALL

SALTFALL is a 2D extraction game built in LÖVE — greed with a weight limit, in a ruin that wakes when you linger. WICK is its companion: a salt-crusted spirit in the player’s lantern that comments on pickups, panic drops, deaths, and the rare successful extraction.

It runs the full pattern in about three hundred lines of Lua: six event hooks, a twelve-event session digest, a worker thread borrowing the OS’s curl for HTTPS, a cached persona prompt, and a canned-line pool that makes the whole thing optional. The game is byte-for-byte identical with the network unplugged — just a shorter-tempered spirit.

wick: i will wait here. i always wait here.

ca B8vCiC65ug9HfsGtgGHusDkaDSMqrqtM6neLuRGipump