Wanted

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.

Rob it. Wear the stars. Vanish.

Move with WASD or the arrow keys. Stand on a target and hold E to rob it. Three cops patrol the block — once you are wanted they hunt you, and your stars only tick down while none of them has line of sight.

Best haul: $0 3 cops · 5 targets · no combat Runs entirely in this tab

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.

1

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.

2

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.

3

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 rule that carries all of it: being spotted resets the cool-off timer to zero rather than pausing it. Pausing lets a player inch out of sight and bank their progress. Resetting means a chase you nearly lost costs you everything, which is what makes breaking line of sight feel like an escape instead of an errand.

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.

TargetTimePayoutStarsCooldown
ATM6s$15040s
Liquor store12s$500★★90s
Bank30s$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
Honest limit: those tests prove the game logic. The mock has no rendering, physics, or replication, and the Roblox client HUD is untested. Nothing has been opened in Roblox Studio yet — that verification step is still outstanding.

What this actually cost

Both builds, honestly scoped. The expensive parts are the ones nobody sees.

PieceSolo effortWhere the time goes
Move, camera, one map1–2 weeksFastest part. Feels like progress, isn’t.
Multiplayer sync, 8 players4–8 weeksFree on Roblox. Months in the browser.
Server-authoritative hits4–8 weeksLag compensation. Get it wrong and every player feels cheated.
NPC police at scale3–6 weeksSkipped on purpose in both builds.
Art volumemonthsThe real killer. Code is tractable; a city is not.
Anti-cheat, persistence, mod tools2–3 monthsInvisible when right, fatal when wrong.