policesquadquest/README.md
type-two 865c7a83a2 Case Twelve: The Late Movie — the finale, and a reproducible win-path suite
Sixteen cases. All lint clean, all win paths verified by tools/verify.sh.

John's multiverse finale, with his own Stay Tuned correction folded in as the
frame — which is what made it work. The television is not a neutral doorway,
it is a subscription: a satellite dish on the property annex roof that is on no
asset register, aimed down through the roof at a 1958 set with no plug, and a
man in a maroon blazer at ten to midnight who does the one thing that has ever
worked on a Drebin — hands over the paperwork and asks him to sign. Frank Jr
reads the terms first. Nobody has read the terms in four hundred years, and
that is what wins the case six rooms later via Clause 14.

Five channels, each a genre with a rule the family breaks with a form: an
iron-curtain spy picture where the unapproved encore becomes the only
state-approved act of resistance in history; a carrier-deck melodrama where the
unlandable jet lands because somebody finally read the manual, and the
saxophone stops mid-phrase because you cannot underscore procedure; a 90s
buddy-cop show that locks onto Sr the moment it reads DAYS TO RETIREMENT, and
is beaten by a Form 14 reassignment, because a man who has been reassigned
cannot be killed in the line of duty; a UK procedural whose silence technique
loses to a man who simply has nothing he needs to say; and a cartoon, survivable
twice, if you fill in the injury form afterwards.

The Twilight Zone kid is the actual antagonist — not the salesman, who only
sells the dish. A boy of nine on the crater set, lit from below by a television
that isn't there, who can do anything and only wants nobody to leave.

The win: they supply sixty-seven years of Drebin paperwork as the contractual
replacement programme, in good order, and the instrument must broadcast it on
all 666 channels — and none of it is entertainment. The boy watches eleven
minutes, stops smiling because it is the first thing he has ever seen that was
not made to hold him, says "Oh", and turns the television off from the inside.
The three Drebins are one man for exactly one frame.

Also: the win-path harness lived in a scratch dir and got wiped mid-session,
which made every case look like it had broken. The games were fine; the harness
was not reproducible. It now lives in the repo — tests/scripts/*.jsonl plus
tools/verify.sh — so regression testing survives the machine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 13:39:20 +10:00

118 lines
6.5 KiB
Markdown

# Police Squad Quest
A Sierra-style adventure game set in the *Police Squad!* / *Naked Gun* universe,
built on the [MRPGI](https://github.com/) engine (`~/Documents/MRPGI`) — which is
itself a reimplementation of AGI, the engine Sierra shipped *Police Quest* on.
> The game grades you on correct police procedure with a completely straight
> face. The reward for perfect procedure is catastrophe anyway.
- **[RESEARCH.md](RESEARCH.md)** — the source material: all six *Police Squad!*
episodes, all four films, the recurring cast, and the ZAZ comedy grammar.
- **[DESIGN.md](DESIGN.md)** — the game bible: the joke engine, the two Drebins,
the eleven-case campaign, and how it all maps onto MRPGI data.
**Sixteen cases, all playable, all verified end-to-end at 100/100** (Case One is
95 + 5 optional). `python3 tools/lint.py` checks all thirteen clean.
## Play
```bash
./play.sh
```
That opens the engine's **title screen** — the whole campaign on one shelf,
arrow keys to choose, Enter to play, Esc backs out of a case to the shelf.
`./play.sh 07` still jumps straight to one case. The shelf's big title comes
from [cases/collection.json](cases/collection.json).
Or directly:
```bash
cargo run -p mrpgi --manifest-path ~/Documents/MRPGI/Cargo.toml -- --game cases/case-01-substantial-gift
```
`Tab` switches between play and the room editor. Type `help` in play.
## What's here
| | |
|---|---|
| `cases/case-00-1958/` | **Act Zero — playable, 100 points.** Frank Drebin **Sr**, 1958, hard noir mono. Five rooms. Played completely straight; the score is the cover-up. |
| `cases/case-00b-the-quartet/` | **Act Zero crossover — playable, 100 points.** Drebin **Sr** vs. five Ealing-comedy incompetents. Five rooms. |
| `cases/case-00c-the-liaison/` | **Act Zero crossover — playable, 100 points.** 1965: the spy-spoof era arrives hunting a pattern that is Drebin **Sr**. Five rooms. |
| `cases/case-01-substantial-gift/` | **Case One — playable, 100 points.** Drebin (Nielsen), 1982, monochrome. Five rooms. |
| `cases/case-03-big-gulch/` | **Case Three — playable, 100 points.** Four rooms, the locksmith front. |
| `cases/case-04-revenge-remorse/` | **Case Four — playable, 100 points.** Four rooms, the wrong manual. |
| `cases/case-05-butler-did-it/` | **Case Five — playable, 100 points.** Four rooms, chain of custody on a cake. |
| `cases/case-06-testimony-of-evil/` | **Case Six — playable, 100 points.** Drebin (Nielsen), 1982, monochrome. Five rooms, the whiskey exploit, four deaths. |
| `cases/case-07-from-the-files/` | **Case Seven — playable, 100 points.** Drebin (Nielsen), 1988, full colour. Six rooms, the Anaheim Stadium finale. |
| `cases/case-02-ring-of-fear/` | **Case Two — playable, 100 points.** Drebin (Nielsen), 1982, monochrome. Five rooms, undercover, three deaths. |
| `cases/case-08b-the-heron/` | **Case 8½ — playable, 100 points.** Interpol team-up: Drebin and a Sûreté legend chase a gentleman jewel thief to London. Five rooms. |
| `cases/case-09-final-insult/` | **Case Nine — playable, 100 points.** Four rooms, prison undercover and the envelope. |
| `cases/case-10-plot-device/` | **Case Ten — playable, 100 points.** Drebin Jr (Neeson), 2025, cold palette. Six rooms, the arena finale and the owl. |
| `cases/case-08-smell-of-fear/` | **Case Eight — playable, 100 points.** Drebin (Nielsen), 1991, full colour. Five rooms, the memory test. |
| `cases/case-11-what-he-wrote/` | **Case Eleven — playable, 100 points.** Drebin **Jr** reads his grandfather's files. Five rooms; the palette drifts from 2025 back to 1958. |
| `cases/case-12-the-late-movie/` | **Case Twelve — playable, 100 points.** The finale: all three Drebins pulled into a demonic cable multiverse. Seven channels. |
| `tools/sprites.py` | Generates every sprite on the MODELBEAST farm (free, local). |
| `tools/lint.py` | Checks every case for the authoring traps that have bitten us. Run it before playtesting. |
| `tools/verify.sh` | Replays every case's win path headlessly and checks it reaches max_score. Scripts in `tests/scripts/`. |
| `RESEARCH.md` / `DESIGN.md` | Source research and the campaign bible. |
## Case One — A Substantial Gift
*Police Squad!* episode 1. A credit union manager is dead, the wrong man is in a
cell, and the teller has new braces.
Sign out your badge and sidearm (the door will not let you leave without them),
get briefed, tip Johnny, dust the counter, match the print, find the bill, and
Mirandize the suspect **in the correct order**. Get the order wrong and the
statement is suppressed, which is a Sierra death card, which is the joke.
## Case Seven — From the Files
*The Naked Gun* (1988). Nordberg is shot on Ludwig's freighter, you tackle a head
of state at a state reception, and you get fired — which is the only way forward,
because a private citizen can't walk onto a baseball field but **an umpire can
walk anywhere**.
The climax: you are the home plate umpire at Anaheim Stadium with no power to
search anyone, so every frisk needs an umpire-legitimate pretext — brush the
plate, inspect the mitt, check the bat for pine tar — until you reach Number 44.
Announce yourself as police instead and sixty thousand people come over the
railings.
## Case Ten — The P.L.O.T. Device
*The Naked Gun* (2025). Liam Neeson's Frank Drebin Jr. — played **sincere** where
his father was oblivious. He means everything he says, all the time, and that is
both the joke and, eventually, the thing that saves the city.
Bank cold open (you are the distraction and don't know it) → a suicide that
isn't → Richard Cane → a New Year's ball drop, a pair of lost trousers, and a
barn owl in a 1950s hat who is lit by a different decade than everything around
him.
## Regenerating art
Sprites are generated locally on MODELBEAST (`flux_local` → `bg_remove_local`
downscale). Prompts live in each case's `sprites.json`.
```bash
python3 tools/sprites.py cases/case-01-substantial-gift # fill gaps
python3 tools/sprites.py cases/case-01-substantial-gift --force # redo all
MB_POOL=1 python3 tools/sprites.py cases/... # if the farm 401s
```
Seeds derive from the sprite name, so reruns reproduce the same art.
## Engine changes
Two small, general-purpose additions were made upstream in MRPGI for this
project — both benefit any game:
- `sprites/ego.png` in a game folder replaces the default party robot as the
player avatar (`ego1.png` optional second walk cel).
- `death_text` in `game.json` overrides the death banner, which was previously
hardcoded to another game's flavour text.