For the complete documentation index, see llms.txt. This page is also available as Markdown.

Minigames

Thirty-three minigames, one export each. Every one returns true on success and false on cancel or fail. Every one accepts an opts table where you can override the difficulty, the placement, or any React prop the component reads.

The list below groups them by feel. Names in the code map straight to cfg.<name> and exports['rm_3dminigames']:<name>().


Puzzle & logic

Name
Feel
Time-ish

untangle

Drag nodes so no edges cross

40-90s

slidingPuzzle

Slide tiles to rebuild an image

60s

wireMatching

Match coloured wires across a panel

30-60s

wireSnip

Cut the right wire before the timer runs out

20s

pathTracing

Trace a path through a grid without lifting

15-25s

dataConduit

Route packets across a board of switches

45s

circuitPulse

Fire pulses in time so they arrive together

20-45s

laserGrid

Reflect a laser through mirrors to a target

30-60s

sequenceBreaker

Decode a hidden sequence from partial hints

30s

chemicalBalance

Balance a chemical equation by drag-and-drop

60-120s


Timing & reflex

Name
Feel
Time-ish

rhythmArrows

Press arrow keys in sync with the incoming beat

30s

flashPad

Repeat the flashing pattern back at it, longer each round

30-60s

motionDetector

Move only when the guard looks away

30s

spinnerLock

Stop the spinner when it lines up with the target

20s

vaultDrill

Hold pressure in the sweet spot while the drill bites

30s

powerGrid

Balance current across breakers before one blows

30s


Terminal & hack flavour

Name
Feel
Time-ish

terminalHack

Fallout-style word guess against a countdown

30-60s

portScanner

Sweep ports for the one that opens the door

30s

dataStreamCapture

Snap the moving cursor when the target byte is in frame

30s

firewallBreach

Peel firewall layers by matching packet types

30s

ipTracer

Ping subnets to zero in on the target IP

25-50s

packetInterceptor

Grab packets off a moving stream before they leave

30s

signalDescrambler

Rotate carrier bands until the audio comes clean

30s


Vault, keycard & combination

Name
Feel
Time-ish

vaultCombination

Dial N wheels to the target number sequence

30-60s

cipherWheel

Line up cipher wheels to decode a phrase

30s

keycardReassembly

Match keycard-fragment pairs on a memory grid

55-100s


Investigation flavour

Name
Feel
Time-ish

fingerprintTrace

Repair a scanned print by fixing corrupt zones

35-70s

cctvSweep

Sweep cameras until the target appears in shot

30s

dnaSplicer

Splice DNA strands so the pattern reads clean

30s

frequencyMatch

Tune two dials until the waveforms align

30s

dataMatcher

Pick the matching record from a scrolling wall of data

30s

colorMatch

Reproduce the shown colour by mixing sliders

30s

mathChallenge

Solve N arithmetic problems back to back

30-45s


Per-minigame tuning

Every entry has a cfg.<name> key. Two shapes:

Full difficulty table

The values are handed straight to the React component as props. Adjust freely.

Difficulty-only

The React component owns its own numbers and reads only the difficulty label. If you want finer control, open the component in web/src/minigames/<name>.tsx, expose the tunables as props, and rebuild.

Overriding per-call

Any field of a difficulty preset can be overridden at the callsite:

Fields the component reads that are not in the preset also work, so this is the escape hatch for one-off tuning. Anything unrecognised is ignored.


Localisation

All player-facing text lives in locales/. en.json is the reference file. To add a language, copy en.json to a new locale code and translate the values while leaving the keys untouched. Locales load through ox_lib, so a player with lib.locale('de') will see the German file.

Keep any %d or {token} placeholders exactly where they were. They are filled in at runtime, so shuffling them shows wrong numbers or breaks the message.


Adding a new minigame

  1. Write web/src/minigames/MyGame.tsx. Accept locales plus whatever props you want.

  2. Register it in the Minigames map at the top of web/src/App.tsx.

  3. Add makeExport('myGame', cfg.myGame) in client/client.lua.

  4. Add cfg.myGame = { default = 'medium', difficulty = { ... } } in cfg.lua.

  5. Add myGame = true to KNOWN_MINIGAMES in server/sync.lua so /create_minigame will accept it.

  6. Add it to the MINIGAMES lists at the top of client/creator.lua and client/test_command.lua so the dropdowns list it.

  7. Rebuild the bundle: cd web && npm run build.

Call it once with /test_minigame screen myGame to sanity-check. If it opens and returns to the console, you are done.

Last updated