One mechanic, built twice
The chase
is the game
Your wanted level only cools off while nobody can see you. Not while you stand still. Not while you wait it out in a corner a cop is staring at. That single rule turns a map with no scripted content into a pursuit game — and it needs no AI, no story, and no quest log.
Why this loop works with nothing else in it
Most crime games spend their budget on content: missions, vehicles, a city, a shop. This one spends it on a timer.
Stars are a visible reputation
A number every other player can act on. It turns a solo action — robbing a till in an empty corner — into a social one, without a single line of authored content.
Roles emerge from that number
Nobody picks a class. A robber at zero stars is indistinguishable from a bystander. You become prey by doing something, and stop being prey by getting away with it.
Escaping beats shooting
Chases have a slow, readable failure state, so a new player loses interestingly instead of instantly. Instant-kill combat would sort players by aim; a chase sorts them by nerve.
The numbers
Identical in the browser build above and the Roblox build below — both read the same table. These are the only values worth arguing about.
| Target | Time | Payout | Stars | Cooldown |
|---|---|---|---|---|
| ATM | 6s | $150 | ★ | 40s |
| Liquor store | 12s | $500 | ★★ | 90s |
| Bank | 30s | $2,500 | ★★★ | 180s |
Star decay — 25 seconds
One star per 25 seconds unseen. The single most important number in the game: it sets how long a clean getaway takes, and therefore how far you dare travel between jobs.
Sight radius — 90 studs
How hard it is to break contact. Lower makes escapes trivial and stars meaningless. Higher makes stars feel permanent and stops anyone robbing the bank twice.
The Roblox build
The same loop as a multiplayer server game, where the cops are other people rather than
three lines of steering code. Source is in roblox/ in this repo.
What it ships with
- Six-star wanted system with sight-gated decay
- Three crime tiers, server-timed, per-target cooldowns
- Player cops: crime alerts, wall-hack highlight on wanted players, 9-stud arrests
- Arrest takes 40% and jails; dying costs 25% and keeps your stars
- Cash persists to a DataStore, with a no-save guard after a failed load
- The whole arena is generated from code at server start
What it deliberately skips
- NPC police — pathfinding a dozen NPCs eats the entire schedule, and being chased by a person is better anyway
- Vehicles — Roblox car handling that feels good is a multi-week problem on its own
- A modelled city — months of art; generated blocks give a real chase arena today
- Combat and a shop — cash accumulates, but there is nothing to spend it on yet
The security rule that matters
Roblox clients are hostile. The client never sends an amount — only “I triggered this prompt”. Payouts are read server-side from config, keyed by the target’s own attribute. Cash and stars live in Player Attributes, which replicate down and cannot be written back, so there are exactly two remotes in the game and neither accepts a number.
-- the whole trust boundary, in one line
local balance = DataService.AddCash(player, crime.Payout)
-- ^ from Config, never from the client
Tested outside Studio
A mock Roblox API plus a virtual clock lets the real server bundle boot under a plain Lua VM, so a 30-second bank robbery is testable in under a millisecond. 55 assertions cover payouts, cooldowns, leash cancels, decay timing, arrest maths, jail, and malformed remote payloads.
npm install fengari
node tools/run_tests.js
# 55 passed, 0 failed
What this actually cost
Both builds, honestly scoped. The expensive parts are the ones nobody sees.
| Piece | Solo effort | Where the time goes |
|---|---|---|
| Move, camera, one map | 1–2 weeks | Fastest part. Feels like progress, isn’t. |
| Multiplayer sync, 8 players | 4–8 weeks | Free on Roblox. Months in the browser. |
| Server-authoritative hits | 4–8 weeks | Lag compensation. Get it wrong and every player feels cheated. |
| NPC police at scale | 3–6 weeks | Skipped on purpose in both builds. |
| Art volume | months | The real killer. Code is tractable; a city is not. |
| Anti-cheat, persistence, mod tools | 2–3 months | Invisible when right, fatal when wrong. |