Case study
Silicon Dreams
A web-based choose-your-own-adventure game that uses background workers to generate narrative and images from player choices, keeping the web UX responsive while enforcing usage metering.
Problem
- Interactive narrative needs fast feedback: generating text + images can take seconds, so synchronous requests would degrade UX.
- Complex state must evolve over time: choices, inventory, flags, characters, and player stats must persist across turns.
- Cost and abuse controls are needed: AI generation is metered with a token balance and enforced in the background task.
- Reliability matters with external APIs: transient failures need retries and fallbacks rather than hard-failing a game turn.
Solution
- Split UX into “request” + “poll”: the POST handler enqueues work, and the client polls a status endpoint until ready.
- Ran the generation pipeline in a Celery task so slow AI calls never block web requests.
- Used provider abstractions for narrative + images to swap implementations without rewriting the orchestration flow.
- Stored turn state as JSON for flexible evolution, alongside relational models for core user/game stats.
- Enforced usage metering server-side with atomic balance updates and explicit out-of-tokens handling.
- Uploaded generated images to S3-compatible object storage and stored resulting URLs in game state.
Architecture
Results
Responsive UX
Slow AI work runs async while the UI polls for readiness
Durable state
Game turns persist via JSON state + relational stats
Cost controls
Token-metered generation with server-side enforcement
Resilient calls
Retries/backoff + fallbacks for external API failures
How this maps to client use cases
- Any app that calls slow/variable-latency providers can use the same enqueue + poll pattern to keep the UI responsive.
- Product teams can ship “infinite content” experiences by treating state as data and generating the next step from that state.
- Usage-based pricing/free-tier controls can be enforced with server-side balances and atomic deductions.