cc_minigames that requires the server. Two players collaborate: a viewer sees a target waveform, and a tuner adjusts probe frequency and amplitude until both axes are within tolerance, then both hold for holdSeconds to win. The server holds the canonical state and ticks the hold-timer at 100 ms — neither client can spoof a “locked” frame to fake a win.
Server export
FrequencyStart returns a promise that resolves with the success boolean. From inside a server thread you can also Citizen.Await(p) to block on it.
Per-difficulty defaults
Server export reference
Cross-resource event
When a session ends, the server fires:AddEventHandler it and react when a frequency session resolves — useful when the server resource that started the session was in a different lifecycle than the one that needs to react to the result.
What happens on the wire
1
Server picks targets, seeds probes off-target
targetFreq and targetAmp are randomized within their bounds. probeFreq and probeAmp are re-rolled until they’re at least 25% off-target on each axis, so the game never spawns already-locked.2
Server fans out the join event
Both clients receive
cc_minigames:cl:frequency:join carrying the token and their assigned role. Each client runs the local Frequency minigame export.3
Tuner inputs go to the server
A/D/W/S on the tuner client fire
cc_minigames:sv:frequency:input with { axis, dir }. Server clamps and applies the step. Viewer inputs are silently ignored.4
Server ticks at 100 ms
On each tick: drift advances the target on harder tiers, the timer counts down, and the hold-meter accumulates while both axes are within tolerance and decays 1.5× faster when out. State is broadcast to both clients.
5
Hold target met → success
When
holdMs reaches holdSeconds × 1000, the server fires cc_minigames:cl:frequency:finish to both clients with success = true, resolves the promise, and emits cc_minigames:sv:frequency:finished for cross-resource listeners.6
Anything else → fail
Time limit hit, either player escapes the local minigame, or either player drops — the session resolves
false with the same fan-out.Variants
Embedding the viewer in a DUI
A common heist setup: the viewer’s waveform is on a wall-mounted CRT prop, the tuner is a player at a console nearby. Use the DUI session helper for the viewer side and passviewerEmbed = true so the server doesn’t try to push a fullscreen NUI to that player.
sessionToken.
Test it solo
For visual debugging without a partner the local/minigame command bypasses the server session entirely and renders both halves in one card: