case study
Yapoleon's Court
An AI game the LLM can't game.
The authority boundary behind all of this work is stated once, in the model cannot own the money. This page covers what is specific to Yapoleon's Court.

01 the problem
A competitive game backed by an LLM the player is actively trying to game — running on a paid API, in front of minors — is a stack of production hazards. The model can be prompt-injected. It can be flattered into a high score. A bad actor can burn through your API bill. And the model can say things a family audience shouldn't hear.
02 the solution
Built the game so the model *can't* be gamed — structurally, not with hope. The Gemini call returns taste only (five bounded axes plus one in-voice line). The favor delta is derived server-side by a pure function the model can't see or reach. Prompt injection, sycophancy-gaming, and denial-of-wallet are handled at the architecture layer. A deterministic red-line pre-filter runs before any model call, so flagged input costs zero.
03 decisions & tradeoffs
Model returns taste, server derives the score
Making the favor delta a field the LLM can output makes it a field the LLM can be talked into inflating. Removing the field entirely is stronger than any prompt hardening.
Structured, low-temperature output only
Predictable schema across every turn, cheaper to reason about, easier to write invariant tests against. Voice comes from prompt, not temperature.
Deterministic pre-filter before model call
Red-line content should never spend a token. Rules-based short-circuit is faster, cheaper, and auditable in a way an LLM classifier isn't.
Cached degrade mode over hard failure under load
Concurrency damper serves an in-voice cached reaction with zero model calls when spend or load spikes. Still routes a neutral score through the same derive-favor function. Meter never breaks, character never breaks.
04 tech stack
Google Gemini
Server-side proxy, low-temperature structured taste-only output
React + TypeScript
Web app, share-card generator, favor meter UI
Vercel serverless
API routes with atomic-slot concurrency damper (TOCTOU-safe)
Supabase
Auth, standing and rivalry persistence across days
05 results
- Judge calibrated against 30 demands × weak/mid/strong: 96.7% strong, 72.2% mid, 0% weak; a fixed rhetorical mold wins 0% of off-axis days; 1,095 calls, 0 errors
- Denial-of-wallet bounded five ways: 3-turn daily cap, per-IP + per-user rate limits, atomic concurrency slot, cached degrade mode, Vercel spend hard-stop
- Content pre-filter short-circuits red-line input before any model call — zero cost on flagged requests
- Prompt injection handled structurally (player reply rides as data being judged, never in the system instruction)
Next step
Want something like this?
Book a 30-minute call. I will tell you plainly whether I can help and what I would test first.