Inspiration
I wanted to make a prison game where the clock is the real enemy. Most escape games let you wander until you find the exit. I wanted every minute to cost something: a sentence day, a meal you missed, a guard turning around at the wrong moment.
So I built Prison Life — Blackwater. You arrive with seven sentence days, $0 and 10 HP. You can behave, earn conduct points and walk out clean, or you can pick up a shovel and try to dig out. I also wanted the world to feel alive, so I added voiced guards, announcements and phone calls using ElevenLabs.
What it does
- A seven-day sentence with meals, roll call, curfew at 22:00 and a persistent daily routine
- Jobs, library reading, ring bouts and conversations that earn money, conduct and reputation
- Three guards with facing-based, wall-aware vision cones, shown on screen as WATCHED or UNSEEN
- A risky escape route: take the shovel and you trigger prisoner ambushes in groups of one, two and three
- Voiced verdicts, meals, curfew, endings and a phone call, plus a live ElevenLabs "roll call" generated on demand
How I built it
The game is a native macOS app in C++20, written for Apple silicon.
Time. One full game day lasts 5 minutes of active play:
$$ \text{game speed} = \frac{24 \times 60 \text{ game min}}{5 \times 60 \text{ real s}} = 4.8 \ \tfrac{\text{game min}}{\text{real s}} $$
Ambush pressure. While you carry the shovel, replacements respawn 1.5 times faster:
$$ t_{\text{respawn}} = \frac{t_{\text{base}}}{1.5} \approx 6.7 \text{ s} $$
The dig. You need five completed holds of eight seconds each, so the commitment is:
$$ 5 \times 8\text{ s} = 40\text{ s of guarded, uninterrupted digging} $$
Releasing E or moving cancels only the current hold. Being watched resets the whole run, so you have to read guard patrols and wait for the right moment.
Audio. The ElevenLabs integration uses Text to Speech and Sound Effects. Offline recordings play with no network or credits. A "Generate live roll call" button makes one real API request using the current day and remaining sentence, then caches the WAV. The game stays responsive during the request.
Saving. Day-start checkpoints are versioned JSON written atomically. Retry restores money, items, stats, sentence, resident progress, seeded RNG and dropped items.
Challenges I faced
- Making the escape tense but fair. Early versions were either trivial or impossible. Five separate holds, a fresh restart when watched, and faster ambush respawns gave me the balance I wanted.
- Guard vision. Sight had to respect facing, distance and walls, and the player needed to see it. Drawing the shaded cones solved the readability problem.
- Safe checkpoints. Rolling back everything, including the seeded random state and the loose-tile hotspot, without leaving a corrupted file meant atomic writes and versioning.
- Live API calls without freezing the game. The request runs in the background, ignores repeated clicks while it is in flight and shows the HTTP result and credit cost.
- Keeping the API key safe. The key stays in
.env.localor an environment variable. It is never shown, passed in process arguments or stored in the binary. - Testing limits. I couldn't use computer control to play the game, and I haven't manually checked audio audibility or a full seven-day playthrough.
What I learned
- Small rules can drive the tension in a game. A single "you're watched, so start over" rule did more than any amount of added content.
- Deterministic, seeded systems make saves and testing much easier. The suite now has 53 tests and 1,347 assertions, covering all 12 guard patrol layouts, the safe digging windows, ambush sizes, respawn speed and the checkpoint restore.
- Voice changes how a game feels. Subtitled, spoken events made the prison feel much more alive than text did.
- How to integrate a real AI API responsibly, with offline fallbacks, cached output and no leaked credentials.
What's next
- Continuous autosave beyond day-start checkpoints
- More NPC schedules and more prison activities
- Manual audio and full-playthrough testing
- Dynamic music, if my plan gets Music API access
Log in or sign up for Devpost to join the conversation.