Client-side Javascript Functions
The client API mirrors RAGE:MP's Client-side functions page. It has three layers, and knowing which layer a call comes from tells you what to expect from it.
| Layer | What it is | Where it lives |
|---|---|---|
mp.game.* | Every GTA native, wrapped and typed | mp_natives.js, generated |
| Class methods | Player / Vehicle / Entity / Object / Blip / Camera methods | mp_classes.js, generated |
| Platform API | Pools, events, GUI, voice, storage, Vector3, labels, markers | the client itself |
Current coverage: 5424 of 5733 members — 1294 class/namespace members plus the 4439
mp.game.* functions. The live breakdown, including the exact list of what is still missing, is
regenerated by python tools/audit-class-api.py into docs/RAGEMP_CLIENT_API_STATUS.md, and the
gap list with reasons into docs/NOT_IMPLEMENTED.txt.
Both the documented name and the native's full name work, so either of these is fine:
mp.game.ped.addArmourTo(ped, 50); // the name the wiki documents
mp.game.ped.addArmourToPed(ped, 50); // the native's own name
mp.game.* — the natives
Every GTA native is available, camel-cased under its namespace, with a typed signature:
mp.game.ped.setPedArmour(mp.players.local.handle, 100);
mp.game.graphics.drawMarker(1, x, y, z, 0,0,0, 0,0,0, 1,1,1, 255,0,0,128, false, false, 2, false, '', '', false);
These take the entity handle, not the entity object — that is the native's own signature.
Class methods
RAGE:MP's class methods are the same natives with the handle supplied for you:
// identical calls
mp.game.ped.addArmourToPed(mp.players.local.handle, 50);
mp.players.local.addArmourTo(50);
They are generated by mapping each name the wiki lists onto the native that implements it
(ADD_ARMOUR_TO_PED → addArmourToPed → Player.addArmourTo). A method is only generated when that
lookup resolves and the native's first parameter can actually take a handle, so nothing is bound on
a coincidental name match.
Hand-written methods always win: where the client has a richer implementation (deferred spawns, server-id resolution, freeze-state tracking), the generated forward is skipped rather than clobbering it.
Method availability
If a method is missing, it is missing for one of three reasons:
- RAGE:MP uses different wording for the same native. Its API was named against an older native
list, so
Vehicle.setNeonLightEnabledisSET_VEHICLE_NEON_ENABLED(no "LIGHT"). Most of these are now resolved automatically through a name→hash lookup, with anything left over going one verified line at a time intotools/ragemp-name-aliases.json. - RAGE:MP implements it itself, not through a native. The
Player.setVoiceFx*family, P2P voice (p2pEnabled/p2pConnected) and the object glow styles are RAGE:MP engine features with no GTA native behind them. - The native genuinely isn't in our table.
mp_natives.jsis built from a named-natives-only dump (6673 natives, no unnamed_0x…entries), so anything the dump omits has nothing to forward to.
Vector3
mp.Vector3 is a value type with full maths. Binary operations return a new vector and never
mutate the receiver:
const dir = target.position.subtract(mp.players.local.position).unit();
const dist = target.position.dist(mp.players.local.position);
Available: add, subtract, multiply, divide, negative, clone, dot, cross, length,
unit, equals, max, min, toArray, toAngles, angleTo.
Every vector the client hands you is a real Vector3 — including entity.position, raycast results
and Vector3 event arguments — so you can chain straight off a position read.
Entity pools
mp.players, mp.vehicles, mp.peds, mp.objects, mp.pickups, mp.blips, mp.markers,
mp.checkpoints, mp.colshapes, mp.labels, mp.browsers, mp.cameras, mp.dummies.
Each supports at, atRemoteId, atHandle, exists, forEach, forEachInStreamRange, apply,
toArray and length. Streamed pools resolve by server id; toArray() unions the streamer's live
set with locally created entities, so a streamed remote vehicle is visible to forEach even though
nothing was pushed into the pool by hand.
Every entity also carries dist(position), distSquared(position), getVariable, setVariable,
hasVariable and resetVariable.
Labels and markers
Both are draw-every-frame primitives — the client draws them for you once created:
const label = mp.labels.new('Hardware Store', new mp.Vector3(x, y, z), {
los: false, font: 4, drawDistance: 20, color: [255, 255, 255, 255], dimension: 0
});
const marker = mp.markers.new(1, new mp.Vector3(x, y, z), 1.5, {
color: [255, 128, 0, 120], visible: true, dimension: 0
});
marker.setColor(0, 255, 0, 200);
Labels respect drawDistance (a squared compare before any native runs, so hundreds of labels only
cost you the near ones) and los, which does a real raycast — only for labels already in range.
Checkpoints and colshapes
const cp = mp.checkpoints.new(1, new mp.Vector3(x, y, z), 3.0, { color: [255,128,0,120] });
const zone = mp.colshapes.newSphere(x, y, z, 15.0);
Both raise real enter/exit events — see
Client-side events for playerEnterCheckpoint and playerEnterColshape.
All six colshape variants use real geometry, and a shape only collides with a player in the same
dimension.
Namespaces
| Namespace | Notes |
|---|---|
mp.console | logInfo / logWarning / logError / logFatal / clear / reset / verbosity |
mp.events | add, remove, call, callRemote, callRemoteProc, addProc, addDataHandler; callRemoteUnreliable is an alias — our transport is reliable-only |
mp.gui | chat.push / chat.activate / chat.show / chat.safeMode / chat.colors, cursor.show, execute |
mp.keys | bind, unbind, isDown, isUp |
mp.raycasting | testPointToPoint, testCapsule, testPointToPointAsync (resolves immediately — our shape test is synchronous) |
mp.storage | data (persists across reconnects), sessionData, flush() |
mp.voiceChat | muted, defaultVolume, lastVad, minVad, preprocessing params |
mp.system | isFocused, isFullscreen, notify() |
mp.user | preferences.language, preferences.lowQualityAssets |
mp.nametags | enabled, orderByDistance, useScreen2dCoords, set(), update() |
mp.discord | update(); requestOAuth2() rejects — there is no OAuth2 broker here |
How a RAGE:MP name finds its native
Most methods resolve by stripping the class token (ADD_ARMOUR_TO_PED → Player.addArmourTo). The
rest are names RAGE:MP inherited from an older community native list, where nothing in the string
connects the two. Those are resolved by hash:
RAGE:MP name → hash (community native DB) → our generated wrapper
This target is RAGE:MP, not FiveM. The native database is used as a name→hash dictionary and
nothing more — the API surface comes exclusively from the RAGE:MP wiki's own member list
(tools/ragemp-class-api.json), so a native that RAGE:MP does not document is never bound, and
argument shapes are verified against RAGE:MP's own per-member pages. The two projects happen to share
native naming; that overlap is the only thing used.
Three guards apply: the name must match exactly one native (ambiguous names are skipped), the hash must
already exist in our table, and for a class method the native's first parameter must be that class's own
entity type. That last one matters — without it DESTROY_CAM reduces to destroy and would bind
Entity.destroy.
Signature fidelity
Existence is not correctness. Each generated forward assumes the RAGE:MP signature is the native's
minus the handle, and that is checked against every member's own wiki page by
python tools/verify-class-signatures.py:
917 signatures checked, 859 match, 58 do not. The full list is in
docs/CLASS_SIGNATURE_MISMATCHES.md. Two kinds:
- Out-parameter getters (25) — the native returns values through pointers. Our wrapper unpacks
them into an array; RAGE:MP returns a named object. So
veh.getColours()[0]works butveh.getColours().colorPrimaryisundefined. - Trailing defaults (33) — the native takes extra trailing arguments that RAGE:MP defaults.
Calling with the documented argument count leaves them
undefined, which the bridge pushes as0/false— usually the right default, but not guaranteed per call.
Regenerating
After changing the client's class surface, or after refreshing mp_natives.js:
python tools/gen-class-api.py # rebuild mp_classes.js
python tools/audit-class-api.py # refresh docs/RAGEMP_CLIENT_API_STATUS.md
python tools/verify-class-signatures.py # re-check signatures against the wiki
mp.voice — the alt:V Voice API
A second facade over the same 3D voice engine, using alt:V's member names. RAGE:MP's own voice
surface (Player.setVoiceFx*, P2P voice) is deliberately not implemented — the voice stack here
is alt:V-derived, so this is the shape it exposes. mp.voiceChat (RAGE:MP shape) keeps working and
both drive the same engine, so they can be mixed.
mp.voice.toggleInput(true); // start transmitting
mp.voice.muteInput = false;
mp.voice.noiseSuppressionEnabled = true;
// voice activation instead of push-to-talk
mp.voice.activityInputEnabled = true;
mp.voice.activationLevel = 0.08; // 0..1, compared against the measured mic level
for (const d of mp.voice.getAvailableInputDevices())
mp.console.logInfo(`${d.uid}: ${d.name}`);
mp.voice.inputDevice = 'Microphone (USB Audio)';
| Member | Notes |
|---|---|
activationKey | read-only; the key a UI treats as push-to-talk |
activationLevel | 0..1 threshold for voice activation |
inputDevice | device name, or null when there is no capture device |
muteInput | inverse of "transmitting" |
noiseSuppressionEnabled | RNNoise on/off |
voiceControlsEnabled | read-only; true once the voice engine came up |
activityInputEnabled | voice activation on/off |
getAvailableInputDevices() | [{ uid, name }] |
toggleInput(enabled) |
activityInputEnabled is real voice activation, not a stored flag: enabling it holds the
capture device open (you cannot measure a level on a closed mic) and opens the transmit gate
whenever the mic level crosses activationLevel, with a 300 ms hangover so the gate does not slam
shut between syllables.
alt:V gates several of these behind an "Extended Voice API permission" prompt. There is no permission broker here, so they are simply available.