NBZ Nathan Bonavia Zammit

08 · Robbery · Robbery system

LTD Safe Robbery

A robbery for the convenience stores that players own. A small safe sits in the store's back room: you crack its 6-digit combination on a dial while a 5-minute timer runs and the police have already been alerted. The money isn't created out of nothing. It comes out of that store company's real account, so the robber's gain is the owners' loss.

Role
Lua (client + server), NUI
Server
Skyland
Framework
ESX
Stack
Lua, ESX, esx_addonaccount, ox_lib, oxmysql / MariaDB, NUI, tk_dispatch
Target
Player-owned LTD stores
Status
Live on Skyland
The safe in the back room of the Mirror Park LTD, with the prompt to press E
The safe screen listening to the mechanism: two discs found, the dial on 7 and a stethoscope pulsing
Cracking the safe with two discs found and the hint narrowed to 6 to 9
The safe door open after six clicks, with the amount taken shown
The safe prompt showing a live five-hour countdown after a robbery
The safe in the back room of the Mirror Park LTD: walk up and press E to start cracking it 1 / 5

How it works

Start to finish

  1. The safe in the back room of the Mirror Park LTD, with the prompt to press E
    The safe screen listening to the mechanism: two discs found, the dial on 7 and a stethoscope pulsing
    Cracking the safe with two discs found and the hint narrowed to 6 to 9
    The safe door open after six clicks, with the amount taken shown
    The safe prompt showing a live five-hour countdown after a robbery
    Cracking the safe: two discs found, and the third is higher than 5, so only 6 to 9 are left on the dial 3 / 5

    01 — The dial

    Higher, lower or click

    • The combination never leaves the server. The client can only send three things: start, try this digit, cancel. It gets back higher, lower or click, and there's no "I finished" message to fake: the safe opens when the server has counted six correct digits.
    • The server does the waiting too: each try takes two seconds on its side before the answer comes back, so the delay can't be skipped or stacked, and the 5-minute limit is checked before and after every try.
    • The safe screen is a NUI built for it: a 10-notch dial, lock discs that turn green, a flip-clock timer, and a hint showing the range your tries have already narrowed down. It was picked from three prototypes.
  2. The safe in the back room of the Mirror Park LTD, with the prompt to press E
    The safe screen listening to the mechanism: two discs found, the dial on 7 and a stethoscope pulsing
    Cracking the safe with two discs found and the hint narrowed to 6 to 9
    The safe door open after six clicks, with the amount taken shown
    The safe prompt showing a live five-hour countdown after a robbery
    Six clicks and the door swings open: 243,158 $ taken straight from the store's company account 4 / 5

    02 — The money

    Paid from a real account

    • The amount is rolled at the start (100,000 to 300,000 $) and capped by what the company holds when the safe opens; under 100,000 $ the safe counts as empty. Nothing moves before success, so a crash or a restart can't lose or duplicate money.
    • Police get a dispatch alert the moment it starts, with the store and the street. Police and the store's own employees can't rob it, and a minimum number of officers online is checked server-side.
    • Every attempt is logged: an SQL row with the player, the store, the amount rolled and paid, the company balance before and after, timings and outcome, plus Discord embeds (retried when Discord rate-limits) and a line in the company's transaction history.
  3. The safe in the back room of the Mirror Park LTD, with the prompt to press E
    The safe screen listening to the mechanism: two discs found, the dial on 7 and a stethoscope pulsing
    Cracking the safe with two discs found and the hint narrowed to 6 to 9
    The safe door open after six clicks, with the amount taken shown
    The safe prompt showing a live five-hour countdown after a robbery
    After a robbery the safe stays locked for five hours, with a live countdown right on the prompt 5 / 5

    03 — Lockouts

    Cooldowns that survive restarts

    • A 5-hour cooldown after a success, stored in SQL so it survives restarts.
    • A failed attempt locks the safe and the robber for 10 minutes and changes the combination. If the server restarts mid-robbery, the attempt is closed at the next boot and the safe is locked.
    • One robber per safe and one robbery per player, start requests rate-limited, distance checked on the server at the start and on every try; disconnecting or walking away ends the attempt.

Under the hood

What keeps it solid

Admin tools
  • Place, turn and nudge a safe in game without a restart, reset it, and read the combination from the server console only.
  • Each store's safe is switched on in the config, so the rollout goes one store at a time.
Testing
  • The decision logic is plain Lua tested outside FiveM (78 checks).
  • The feature was run scenario by scenario on the dev server: success, timeout, wrong digits, key spam, disconnect, restart and every refusal.

Tech

Tech and package

  • Lua
  • ESX
  • NUI
  • MariaDB
  • Client script
  • Server script
  • Config
  • NUIthe safe screen
  • One SQL migration
  • Offline test suite

Need something like this on your server?

Email me