Live

Cantastories

Lateral-thinking puzzles with an AI narrator and judge.

Year
2026
Area
Web, AI
Stack
.NET · React · PostgreSQL · Redis · LLM multi-provider · Docker

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.