# Murder Mystery Game > A playable murder mystery generator whose cases are proved solvable before play begins. > https://murder-mystery-game.skillsafe.ai/ ## What it is A murder mystery game. Each case has a victim, a setting, a closed circle of five invented suspects with stated alibis and motives, a room where the body was found, a half-hour window, and thirteen clues. You search rooms, question suspects in plain English, follow contradictions, and finally name somebody. The app then tells you two separate things: whether you were right, and whether you could have known. ## The problem it exists to solve The obvious way to build a generated mystery is to ask a language model for a case and then ask it, at the end, who did it. That produces something that reads like a mystery and cannot be solved. The culprit is arbitrary, no clue actually excludes anybody, and a careful player and a careless one have the same one-in-five chance. The verdict screen is a coin toss with atmosphere. Murder Mystery Game inverts the order. The solution structure is built FIRST — culprit, murder room, window, who claims to have been where — and every clue is derived from that structure by a deterministic, seeded generator running in the browser. No model writes any part of the case. ## How fairness is proved, not asserted Before a case is shown to a player it goes through thirteen checks in `casefile.js`. A case that fails any of them is discarded and regenerated from the next seed. The three that carry the weight: 1. **Determinable.** Apply the deduction rule the app teaches the player — an alibi that holds clears somebody, only a broken alibi convicts, a motive proves nothing — over the complete clue set. Exactly one suspect must survive, and it must be the culprit. Two survivors means the case is a guess; none means it is broken. 2. **Reachable.** Clues carry prerequisites: you cannot get the second half of a contradiction before the first half tells you where to look, and you cannot force a concession out of a suspect without the evidence that corners them. So the check is not "do these clues exist" but "can a player standing in the opening scene actually get to them". That is a fixpoint closure computed over the prerequisite graph, and every load-bearing clue must be inside it. Typical depth is three waves. 3. **Fair on the free lane too.** Physical and record clues are found by searching rooms, which is client-side and costs nothing. Testimony clues are conceded under questioning, which is metered. So solvability is proved twice: once over the whole clue set, and once over the free subset alone, which must still bring the field down to two names — the culprit among them — with at least one crack already showing in the culprit's account. The other eight checks cover roster integrity, distinct claimed rooms none of which is the murder room, no clue that clears the culprit or breaks an innocent, every clue's source and prerequisite existing, a chain of at least two independent breaks, a findable motive for the culprit, and an evidence depth between two and eight waves. The generator is seeded and deterministic, so a case code (`MB--`) rebuilds the same case everywhere, culprit included. That makes cases shareable, and it is also why the offline test harness can assert the fairness property over thousands of generated cases rather than a handful. ## What the model does and does not do The model voices suspects. It is never the custodian of anything. - It is **never told who did it**, except in the single case where it is currently playing that person — the private briefing for one suspect is the only place the solution appears, and a culprit who does not know they are lying cannot lie convincingly. - It is **never asked what the evidence is**. Each envelope names the exact, short list of concessions that suspect could make right now, computed on the client from prerequisites the client owns. Anything outside that list is refused. - Every turn restates the whole case file inside a **5,000-character budget** with a seven-rung degradation ladder. The setting frame, house style, older answers, roster roles and manner lines are what get sacrificed. The case identity, victim, window, full roster with every stated alibi, the briefing, the concession list and the detective's question are on **no rung**. ## The four refusals A suspect's answer that contradicts the case file is **discarded and re-asked**, not narrated with a warning attached. The player is told it cost an extra turn. 1. **A rewritten alibi.** The reply's `WHERE` line names a room that is not this person's stated one. Alibis are what the whole deduction runs on. 2. **An unearned confession.** Any first-person admission. If the culprit could crack under pressure there would be no case; if an innocent could, the answer would be wrong. 3. **An invented person.** A titled name that is not one of the five and not the victim. The closed circle is the genre's one promise. 4. **An unauthorised concession.** A clue id that was not on the list, or whose prerequisites are unmet. Matching is deliberately strict here and deliberately generous when the model merely refers to something the player already holds — the asymmetry is the point. Softer disagreements (a place the file does not have, a colleague placed somewhere the roster does not, a repeated answer) are surfaced to the player next to the answer they belong to, and the answer stands. ## Verdicts Three grades, and the app says plainly which one was earned: - **Solved** — you named the culprit AND had at least two links of the chain plus a clearing clue for every innocent. - **Right name, unproved case** — correct, but the evidence was not there yet. A good instinct is not a solved case. - **Wrong** — and if you were carrying the clue that cleared the person you accused, it says so. Either way the full solution is shown: the chain that breaks the culprit's account, the motive, what cleared each of the other four, and what each of them was actually hiding. ## The five settings Ashgrove Hall (a snowed-in country house), The Meridian Express (a night train), The Lyric Theatre (a repertory company after curtain), Cadence Station (a winter observatory), and The Calliope (a liner mid-crossing). Each ships its own rooms, cast, examinable objects and clue phrasings. ## Content Classic parlour-mystery register: a body, motives, deduction. **No method, no forensic detail, no gore, and no describing the body.** How anybody died is not part of the game and the system prompt refuses it. Every person in every case — victim, suspects, culprit — is invented. No real person, living or dead, appears in any role. ## Cost and access Generating a case, reading the case file, and searching every room and every object are free and never call the model. Questioning a suspect is metered (`gpt-terra`) and needs a signed-in account. A hold is shown as reserved before the first question; the actual charge appears on every answer and is totalled. Investigations are saved to a declared `investigations` collection on the user's own account and resume on another device. Exports: the notebook as Markdown, the clue table as CSV, the whole case as JSON — and while a case is open the JSON and CSV are deliberately spoiler-free. ## Programmatic use `https://murder-mystery-game.skillsafe.ai/api.html` documents the whole loop against `https://api.skillsafe.ai/v1/app-api`: create a session, build the envelope, `POST /sessions/{id}/messages`, stream it, and parse the labelled-line reply. It also documents the four refusals as checks the caller should run, because a caller that skips them has handed the case back to the model. Note that a session turn accepts **no idempotency key**. Resending one appends a second copy to server-side history, which is worse than a double charge. Reconcile instead: `GET /sessions/{id}`, count `role: "assistant"` messages, compare against the number accepted *on this session*, and adopt the reply the server already holds. Counting per case rather than per session breaks the moment the session is rotated.