Live
Cantastories
Lateral-thinking puzzles with an AI narrator and judge.
The problem
Writing stories is the easy part. Keeping the game fair is the problem: a model that improvises breaks the deal with the player, and a model that costs too much per game breaks the budget.
Constraints
- Perceived latency: the answer has to arrive while the question is still in mind.
- Bounded cost per session: no unconstrained model calls.
- Always appropriate content: filter before the model, not after.
- No repeated stories: selection has to remember what has already been played.
Architecture
- .NET backend with PostgreSQL for stories, sessions and usage; Redis for real-time state.
- Narrator and judge are two distinct roles, with different prompts and parameters.
- Asynchronous batch for non-urgent stories, real-time channel for in-game ones.
- Deploy: GitHub Actions runs the tests and publishes the image to ghcr.io only when they pass.
Decisions that matter
Story selection is a score, not a random pick
Never used, rarely used, never used by that player, time decay, category and difficulty: a story is chosen by adding weights. Chance only breaks ties.
Blocked phrases close the game before the model
A list of phrases ends the session without spending tokens and without revealing the story. The filter is free and deterministic.
An LLM link can die silently
A model retired by the provider throws no error: it simply stops answering well. Usage monitoring is part of the product, not an extra.
Where it got to
Live on cantastories.it, with two-stage validation editable from the admin panel and rejected stories tracked in a dedicated table.