` block and its styles out of the generated `index.html` into your own NUI page.
## PNG and SVG
- **PNG** exports at 128, 256 or 512 px with transparency. By default the crosshair is drawn at its real pixel size and centred, which is what you want when you are dropping it into an overlay or a HUD. Turn on the scale option when you want it to fill the image, for example for a release post.
- **SVG** is the same drawing as vectors. Use it in your own HTML, or open it in Figma or Inkscape.
- **Copy PNG** puts the image straight on the clipboard where the browser allows it.
## Console settings
GTA V has no crosshair commands. It has two options in Settings, Display, which FiveM exposes as convars:
| Setting | What it is |
| --- | --- |
| `profile_reticule` | Weapon Target. `0` is the simple dot, `1` is the complex crosshair that changes per weapon. |
| `profile_reticuleSize` | Simple Reticule Size. Values below zero shrink the simple dot until it is gone, and `-10` is what most people use to get rid of it. |
On top of that, the FiveM client draws a crosshair of its own behind `cl_customCrosshair`. It copies the Counter-Strike crosshair, so it can do four bars, a square centre dot, a black outline, one colour and one opacity. It has no circles, no brackets, no chevrons, no rounded ends and no second colour.
The **Console settings** tab maps your design onto those convars as closely as they go, lists everything that is lost on the way, and draws what the client will really produce next to your design so you can compare them.
Three things to know about them:
- They are a client setting, saved with the player's own FiveM settings. You cannot ship them to your players, and they stay set on every other server until the player changes them.
- The bar length and thickness are scaled by the player's vertical resolution, so pick your resolution in the tab before you copy the lines.
- The only one a server can control is `setr cl_customCrosshair false` in your server.cfg, which switches the built in crosshair off for everyone while they are on your server. Use it together with the overlay so players do not end up with two crosshairs.
> [!NOTE]
> Styles 0, 1 and 3 draw the same crosshair today, because the spread the dynamic styles react to is fixed in the client. Style 2 splits every bar into two pieces and pulls the inner pair into the centre. Style 4 is the one whose gap does not change with resolution, so it is the safest choice.
## Tips
- Keep a 1 px black outline. It is the difference between a crosshair you can see on a white car and one you cannot.
- Below 2 px thick, a line mostly disappears at 1080p.
- A large gap reads better for roleplay, where you are not shooting most of the time, and it keeps the middle of the screen clear.
- Green and cyan hold up almost everywhere on the map. Red disappears on brick and on brake lights.
- If you build a crosshair for a weapon shop or a minigame, export the PNG and use it as an image in your own NUI instead of shipping a second overlay resource.
_Last updated: 2026-09-23_
---
## server.cfg Generator
URL: https://fivemad.com/docs/tools/server-cfg-generator
Build a working FiveM server.cfg from a form: endpoints, OneSync, game build, keys, oxmysql, pma-voice, resource load order and ACE permissions.
The server.cfg Generator turns a form into a clean, commented `server.cfg` for FXServer. It covers networking, server list identity, OneSync, the enforced game build, security convars, keys, the oxmysql connection string, pma-voice convars, the `ensure` order for Standalone, QBCore, Qbox or ESX, and ACE permissions for your admins.
## What it is for
Most broken servers fail on something small in `server.cfg`: a resource started before its library, a missing license key, an admin line with the wrong identifier prefix, or a database password with an `@` in it. The generator writes the file in a fixed, readable order and shows warnings next to the output while you fill in the form, so you catch those before you start FXServer.
Use it when you set up a new server, when you move a server to a new framework, or when you want a clean reference file to compare your old one against.
## Quick start
1. Pick a **Framework** at the top: **Standalone**, **QBCore**, **Qbox** or **ESX Legacy**. This fills the **Resources** list and the tags, and adds the permission lines that framework needs. Any framework other than Standalone also turns on the **Database** and **Voice (pma-voice)** panels.
2. In **Server identity**, set `sv_hostname`, **Project name**, **Project description**, **Locale** and **Tags**.
3. In **Slots, network & game**, set `sv_maxclients`, **OneSync**, **Bind IP**, **Port** and `sv_enforceGameBuild`.
4. In **Keys & branding**, paste your `sv_licenseKey` from [portal.cfx.re](https://portal.cfx.re).
5. Under **Permissions (ACE)**, add yourself in **Admins** with your license, Discord or other identifier.
6. Read the amber warnings above the output, fix what applies, then use the download button on the `server.cfg` code block and save the file in your server-data folder, next to the `resources` folder.
> [!NOTE]
> Everything runs in your browser. The license key, Tebex secret and database password never leave your machine. The form is saved in this browser's local storage so you can come back to it. **Reset** puts every field back to the defaults.
## Options
### Framework presets
| Preset | Resources it fills | Tags | Admin group |
| --- | --- | --- | --- |
| Standalone | `mapmanager`, `chat`, `spawnmanager`, `sessionmanager`, `basic-gamemode`, `hardcap`, `baseevents` | `default` | `group.admin` |
| QBCore | the cfx defaults, then `oxmysql`, `ox_lib`, `qb-core`, `[qb]`, `[standalone]`, `[voice]`, `[defaultmaps]` | `roleplay, qbcore, qb-core` | `qbcore.god` |
| Qbox | `chat`, `hardcap`, `oxmysql`, `ox_lib`, `qbx_core`, `[ox]`, `[qbx]`, `[standalone]`, `[voice]` | `roleplay, qbox, ox` | `group.admin` |
| ESX Legacy | `chat`, `spawnmanager`, `sessionmanager`, `hardcap`, `oxmysql`, `ox_lib`, `es_extended`, `[core]`, `[standalone]`, `pma-voice` | `roleplay, esx` | `group.admin` |
Switching the framework replaces the **Resources** text and the tags. Admin rows that use a preset admin group are moved to the new framework's group; rows with a custom group are left alone.
### Server identity
| Field | Output | Notes |
| --- | --- | --- |
| `sv_hostname` | `sv_hostname "..."` | Shown in the server list. `^1` to `^9` are colour codes. Over 100 characters gets a warning. |
| Project name | `sets sv_projectName "..."` | Skipped when empty. |
| Project description | `sets sv_projectDesc "..."` | Skipped when empty. |
| Locale | `sets locale "en-US"` | 25 locales, including `root-AQ`. |
| Tags | `sets tags "..."` | Comma separated, trimmed and re-joined. |
### Slots, network and game
| Field | Output | Default |
| --- | --- | --- |
| `sv_maxclients` | `sv_maxclients 48` | 48 (slider and box, 1 to 2048) |
| OneSync | `set onesync on` | `on`. Also `legacy` or `off`. |
| Bind IP / Port | `endpoint_add_tcp` and `endpoint_add_udp` with `"0.0.0.0:30120"` | `0.0.0.0` and `30120` |
| `sv_enforceGameBuild` | `set sv_enforceGameBuild 3258` plus the DLC name as a comment | 3258 (Bottom Dollar Bounties). "Default (not enforced)" leaves the line out. |
The build list runs from 1604 (Arena War) to 3570 (Money Fronts). Setting a build unlocks the DLC vehicles, maps and clothing up to that update.
### Keys and branding
| Field | Output |
| --- | --- |
| `sv_licenseKey` | `sv_licenseKey "..."`, always written. Defaults to `changeme` with a comment pointing at portal.cfx.re. |
| `steam_webApiKey` | `set steam_webApiKey "none"` when empty. Only needed if you use Steam identifiers. |
| Server icon file | `load_server_icon logo.png`. A 96x96 PNG in the server-data folder. |
| Discord | `sets Discord "..."` |
| `banner_detail` URL | `sets banner_detail "..."` (1920x200 image on the server detail page) |
| `banner_connecting` URL | `sets banner_connecting "..."` (shown while connecting) |
| `sv_tebexSecret` | `sv_tebexSecret "..."`, only when filled in. |
| Extra sets variables | **Add variable** adds a key and value pair, written as `sets Key "value"`. Spaces in the key become underscores. |
### Security
| Option | Output | Default |
| --- | --- | --- |
| Running under txAdmin | Adds a txAdmin note at the top and leaves `rcon_password` out | On |
| `sv_endpointprivacy` | `sv_endpointprivacy true` (hides player IPs from other players) | On |
| `sv_scriptHookAllowed` | `sv_scriptHookAllowed 0` or `1` | Off |
| Private server | `sv_master1 ""` so the server is not listed in the server browser | Off |
| `sv_pureLevel` | Not set, `1` (blocks modified game files, allows audio and graphics mods) or `2` (blocks all modified files) | `1` |
| `sv_entityLockdown` | Not set, `relaxed` (blocks client created entities, allows script ones) or `strict` (only the server creates entities) | Not set |
| `rcon_password` | Only shown with txAdmin off. Empty writes a commented out line. | Empty |
### Database
The **Database** panel has an **Enabled** / **Off** switch. When on, it writes one line for oxmysql built from **Host**, **Port**, **User**, **Password** and **Database**. The user, password and database name are URL-encoded for you, and `charset=utf8mb4` is appended.
### Voice (pma-voice)
When enabled, it writes `setr` convars for pma-voice:
| Field | Convar |
| --- | --- |
| Audio mode | `voice_useNativeAudio true`, `voice_use2dAudio true`, or nothing for "pma-voice default" |
| Sending range only | `voice_useSendingRangeOnly` (default true) |
| Built-in UI | `voice_enableUi` (default 0) |
| Radio animation | `voice_enableRadioAnim` (default 1) |
| Range key / Radio key | `voice_defaultCycle "F11"` and `voice_defaultRadio "LMENU"` |
If voice is on but your resource list has neither `pma-voice` nor `[voice]`, the generator adds `ensure pma-voice` at the end of the resources.
### Resources
One entry per line. Plain names become `ensure name`. A `[folder]` name starts every resource in that folder. Lines starting with `#` stay as comments, and lines that already start with `ensure`, `start`, `stop`, `restart`, `exec`, `set`, `setr` or `sets` are kept as written. When `ox_lib` or `[ox]` is in the list, the generator adds `setr ox:locale "en"` above the resources and the ACE lines ox_lib needs.
### Permissions (ACE)
**Admins** rows take an identifier type (`license`, `license2`, `fivem`, `discord`, `steam`, `xbl`, `live`, `ip`), the identifier value, a group and an optional note. The `license:` style prefix in the value is optional; the tool strips it and writes the full `identifier.license:...` principal. **Custom rules** (toggle with **Show custom rules**) adds free `add_ace` rows with an allow/deny switch and `add_principal` rows.
## Output
The file is written in this order: header, Networking, Server identity, Slots and game, Security, Keys, Database, Voice, ox_lib, Resources, Permissions. With the default Standalone settings it looks like this:
```cfg title="server.cfg"
## Networking
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"
## Server identity
sv_hostname "^5My Server ^7| Serious RP | Discord: example"
sets sv_projectName "My Server"
sets sv_projectDesc "Serious roleplay with custom jobs and an active staff team"
sets locale "en-US"
sets tags "default"
## Slots and game
sv_maxclients 48
set onesync on
set sv_enforceGameBuild 3258 # Bottom Dollar Bounties
## Security
sv_scriptHookAllowed 0
sv_pureLevel 1 # blocks modified game files, allows audio and graphics mods
sv_endpointprivacy true
## Keys
set steam_webApiKey "none" # https://steamcommunity.com/dev/apikey
sv_licenseKey "changeme" # https://portal.cfx.re
## Resources (load order matters)
# Default cfx resources
ensure mapmanager
ensure chat
ensure spawnmanager
ensure sessionmanager
ensure basic-gamemode
ensure hardcap
ensure baseevents
## Permissions
add_ace group.admin command allow # all commands
add_ace group.admin command.quit deny # but not quit
# add_principal identifier.license:xxxxxxxx group.admin # add yourself here
```
With QBCore picked and an admin added, the extra sections look like this:
```cfg
## Database (oxmysql)
set mysql_connection_string "mysql://root:p%40ss@localhost:3306/fivem?charset=utf8mb4"
## Voice (pma-voice)
setr voice_useNativeAudio true
setr voice_useSendingRangeOnly true
setr voice_enableUi 0
setr voice_enableRadioAnim 1
setr voice_defaultCycle "F11"
setr voice_defaultRadio "LMENU"
## ox_lib
setr ox:locale "en"
## Permissions
add_ace group.admin command allow # all commands
add_ace group.admin command.quit deny # but not quit
add_ace resource.qb-core command allow
add_ace qbcore.god command allow
add_principal qbcore.god group.admin
add_principal qbcore.god qbcore.admin
add_principal qbcore.admin qbcore.mod
add_ace resource.ox_lib command.add_ace allow
add_ace resource.ox_lib command.remove_ace allow
add_ace resource.ox_lib command.add_principal allow
add_ace resource.ox_lib command.remove_principal allow
add_principal identifier.license:1a2b3c4d5e6f qbcore.god # owner
```
### Starting the server
With txAdmin, point the deployer (or Settings, then FXServer) at this file. Without txAdmin, start FXServer from the server-data folder:
```bash
# Windows
C:\FXServer\server\FXServer.exe +exec server.cfg
# Linux
bash ~/FXServer/server/run.sh +exec server.cfg
```
## Warnings the tool shows
- `sv_licenseKey` is empty or still `changeme`.
- More than 32 slots with OneSync `off`.
- More than 48 slots: that needs an Element Club subscription linked to the license key.
- OneSync `legacy` is deprecated.
- A framework is picked but the database section is off.
- `sv_scriptHookAllowed 1` lets players run ScriptHook mod menus.
- The hostname is longer than 100 characters.
- The database has no password (fine for local testing only).
- No admin identifier is set.
## Tips
- Load order matters. Libraries such as `oxmysql` and `ox_lib` go before the framework core, and the core (`qb-core`, `qbx_core`, `es_extended`) goes before any script that uses it. `ensure [folder]` starts everything inside a bracketed folder in an order you do not control, so ensure dependencies by name before the folder.
- Check a permission in Lua with `IsPlayerAceAllowed(source, 'command.kick')`. After you change ACE lines you can paste them into the server console to apply them without a restart.
- Find identifiers in txAdmin (Players, then a player) or with `GetPlayerIdentifiers(source)`.
- `setr` convars are replicated to clients, `sets` convars are shown publicly in the server list, plain `set` stays on the server.
> [!WARNING] Keep secrets out of git
> `server.cfg` holds your license key and database password. Do not commit it to a public repo. Move secrets to a separate file and load it with `exec secrets.cfg`.
## Common mistakes
- **Starting FXServer with `+exec` while using txAdmin.** txAdmin starts the server itself. It still reads the port from the `endpoint_add_*` lines, so keep them.
- **Only opening TCP or only UDP.** The port needs both.
- **Changing `sv_enforceGameBuild` while players are on.** Clients download the matching game build on their next connect, so set it before launch.
- **Special characters in the database password.** They must be URL-encoded in `mysql_connection_string`. The generator does that, so do not encode them a second time.
## Limitations
The generator does not check that the resources you list exist in your `resources` folder, and it does not validate identifiers or keys. The framework presets are a starting point: rename folders to match your own server. The game build list stops at 3570.
## Related tools
- [fxmanifest.lua Generator](/docs/tools/fxmanifest-generator)
- [Server Status Checker](/docs/tools/server-status-checker)
- [Cfx Blacklist Checker](/docs/tools/cfx-blacklist-checker)
- [Artifacts](/docs/tools/artifacts)
_Last updated: 2026-09-22_
---
## fxmanifest.lua Generator
URL: https://fivemad.com/docs/tools/fxmanifest-generator
Generate a valid fxmanifest.lua: fx_version, game, lua54, shared, client and server scripts, NUI page, files, data_file lines, dependencies and exports.
The fxmanifest.lua Generator builds the manifest every FiveM or RedM resource needs. You fill in scripts, NUI page, files, `data_file` entries, dependencies and exports, and it writes a clean `fxmanifest.lua` with warnings for the mistakes that stop a resource from loading.
## What it is for
A manifest is short, but one wrong line costs you an hour: an NUI page that is not in `files`, a vehicle meta with a `data_file` line but no `files` entry. Use the generator when you start a new resource, when you turn a loose folder of add-on cars into a pack, or when you want to check an old `__resource.lua` style resource against a clean modern manifest.
## Quick start
1. Under **Start from**, pick **Basic script**, **NUI resource** or **Vehicle pack**. The preset keeps your **Name** and **Author** and fills the rest.
2. In **Resource**, set `fx_version`, the **Game** chips, **Name**, **Author**, **Version**, **Repository** and **Description**.
3. Add scripts in the **Scripts** panel. Type a path and press
Enter or the plus button, or click one of the small `+ ...` shortcut buttons under each list.
4. For NUI, fill in `ui_page` and your web files under **NUI & files**.
5. Add `data_file` lines for meta files, and list **dependencies** and exports if you need them.
6. Fix anything in the amber warnings box, then download `fxmanifest.lua` from the code block and put it in the root of your resource folder.
Your manifest is saved in this browser, so you can come back and tweak it. **Clear** empties every field (it keeps `game 'gta5'`, `lua54 'yes'` and version `1.0.0`).
## Presets
| Preset | What it sets |
| --- | --- |
| Basic script | `shared_scripts` `config.lua`, `client_scripts` `client/*.lua`, `server_scripts` `server/*.lua` |
| NUI resource | `@ox_lib/init.lua` and `config.lua` in shared, client and server globs, `ui_page` `web/build/index.html`, files `web/build/index.html` and `web/build/**/*`, dependency `ox_lib` |
| Vehicle pack | `lua54` off, client script `vehicle_names.lua`, and six `data_file` lines for handling, vehicles, carcols, carvariations, vehiclelayouts and dlctext metas under `data/**/` |
## Options
### Resource
| Option | Output | Default |
| --- | --- | --- |
| `fx_version` | `fx_version 'cerulean'` | `cerulean (current)`. `bodacious` and `adamant` are there for old resources and trigger a warning. |
| Game | `game 'gta5'` for one game, `games { 'gta5', 'rdr3' }` for several | `gta5`. Picking `rdr3` also adds the required `rdr3_warning` line. `common` is for resources that run on any game. |
| Name, Author, Description, Version, Repository | `name '...'`, `author '...'` and so on | Version `1.0.0`. Empty fields are left out. |
| `lua54 'yes'` | `lua54 'yes'` | On. Lua 5.4 has been the default since mid 2025, so the line is optional on current servers, but keeping it does no harm and helps older artifacts. |
| `use_experimental_fxv2_oal` | `use_experimental_fxv2_oal 'yes'` | Off. Experimental faster native calls for Lua 5.4. Test before you ship. |
### Scripts
Three lists: `shared_scripts`, `client_scripts` and `server_scripts`. Each row can be edited in place, moved up with the arrow button or removed. Globs like `client/*.lua` work. The shortcut buttons add common entries:
| List | Shortcuts |
| --- | --- |
| shared_scripts | `@ox_lib/init.lua`, `@qbx_core/modules/lib.lua`, `@es_extended/imports.lua`, `@es_extended/locale.lua`, `config.lua`, `shared/*.lua`, `locales/*.lua` |
| client_scripts | `client/*.lua`, `@qbx_core/modules/playerdata.lua`, `client/main.lua` |
| server_scripts | `@oxmysql/lib/MySQL.lua`, `server/*.lua`, `server/main.lua` |
Order matters: scripts load in the order listed, and on each side `shared_scripts` load before the client or server scripts. Put `@ox_lib/init.lua` or `@qbx_core/modules/lib.lua` at the top of shared, and `config.lua` before any file that reads `Config`. Paths starting with `@` point into another resource.
### NUI and files
| Option | What it does |
| --- | --- |
| `ui_page` | Path inside the resource, or an `http(s)` URL for a dev server. |
| `files` | Files sent to clients. Globs like `**` work. Shortcuts: `html/**/*`, `web/build/**/*`, `stream/**/*.ytyp`, `locales/*.json`. |
| Add ui_page and data_file paths to files automatically | On by default. Copies the `ui_page` path (unless it is a URL) and every `data_file` path into `files { }`, because clients never download anything that is not listed there. |
### data_file
**Add data_file** adds a row with a type and a path. The type box suggests `HANDLING_FILE`, `VEHICLE_METADATA_FILE`, `CARCOLS_FILE`, `VEHICLE_VARIATION_FILE`, `VEHICLE_LAYOUTS_FILE`, `DLCTEXT_FILE`, `CONTENT_UNLOCKING_META_FILE`, `PED_METADATA_FILE`, `WEAPONINFO_FILE`, `WEAPON_ANIMATIONS_FILE`, `WEAPONCOMPONENTSINFO_FILE`, `LOADOUTS_FILE`, `AUDIO_GAMEDATA`, `AUDIO_SOUNDDATA`, `AUDIO_SYNTHDATA`, `AUDIO_WAVEPACK`, `DLC_ITYP_REQUEST` and `TIMECYCLEMOD_FILE`, but you can type any type. **+ Vehicle metas** adds the six vehicle meta lines that are not already there.
### Dependencies and exports
| Option | What it does |
| --- | --- |
| dependencies | Resources that must start first. Shortcuts: `oxmysql`, `ox_lib`, `ox_target`, `ox_inventory`, `qbx_core`, `qb-core`, `es_extended`, `/onesync`, `/gameBuild:3095`. Entries like `/onesync`, `/server:
` and `/gameBuild:` set server requirements. |
| provide | Lets this resource stand in for another one, for example a `mysql-async` replacement. |
| exports (client) / server_exports | Old style export lists. `exports('name', fn)` in Lua works without them. |
| escrow_ignore | Files left readable when the resource goes through the Cfx.re asset escrow. Shortcuts: `config.lua`, `locales/*.lua`, `client/open.lua`, `server/open.lua`. |
## Output
The file comes out in this order: version and game lines, metadata, script blocks, `ui_page`, `files`, `data_file` lines, dependencies, `provide`, exports, `escrow_ignore`. The **Basic script** preset produces:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'my_script'
description 'Basic client/server script'
version '1.0.0'
shared_scripts {
'config.lua',
}
client_scripts {
'client/*.lua',
}
server_scripts {
'server/*.lua',
}
```
A typical Qbox / ox_lib job resource:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'my_job'
version '1.0.0'
shared_scripts {
'@ox_lib/init.lua',
'@qbx_core/modules/lib.lua',
'config.lua',
}
client_scripts {
'@qbx_core/modules/playerdata.lua',
'client/*.lua',
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/*.lua',
}
dependencies {
'ox_lib',
'qbx_core',
'oxmysql',
}
```
The **Vehicle pack** preset, with automatic files on:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
name 'my_vehicles'
description 'Add-on vehicle pack'
version '1.0.0'
client_scripts {
'vehicle_names.lua',
}
files {
'data/**/handling.meta',
'data/**/vehicles.meta',
'data/**/carcols.meta',
'data/**/carvariations.meta',
'data/**/vehiclelayouts.meta',
'data/**/dlctext.meta',
}
data_file 'HANDLING_FILE' 'data/**/handling.meta'
data_file 'VEHICLE_METADATA_FILE' 'data/**/vehicles.meta'
data_file 'CARCOLS_FILE' 'data/**/carcols.meta'
data_file 'VEHICLE_VARIATION_FILE' 'data/**/carvariations.meta'
data_file 'VEHICLE_LAYOUTS_FILE' 'data/**/vehiclelayouts.meta'
data_file 'DLCTEXT_FILE' 'data/**/dlctext.meta'
```
For a vehicle pack, put models (`.yft`, `.ytd`) in a `stream` folder, they are streamed automatically. The `data/**/` globs let you keep one folder per car. Then add the resource to `server.cfg`:
```cfg
ensure my_vehicles
```
## Warnings the tool shows
- `@ox_lib/init.lua` is loaded but `lua54` is off.
- You load `@ox_lib/...` files but `ox_lib` is not in dependencies.
- You load `@oxmysql/lib/MySQL.lua` but `oxmysql` is not in dependencies.
- You load `@qbx_core/...` files in shared scripts but `qbx_core` is not in dependencies.
- `common` is combined with `gta5` or `rdr3`.
- `ui_page` is not in `files` (only when automatic files is off).
- `data_file` lines exist while automatic files is off: every path must also be in `files { }`.
- `fx_version` is not `cerulean`.
- The name contains spaces. The folder name is what counts for `ensure`.
## Common mistakes
- **Blank NUI frame.** `ui_page` must also be in `files`. Leave the automatic option on.
- **Shipping both manifests.** `fxmanifest.lua` replaced `__resource.lua`. Do not ship both in one resource.
- **RedM without the warning line.** `game 'rdr3'` needs the exact `rdr3_warning` text. The generator adds it for you.
- **Editing the manifest on a running server.** Run `refresh` and then `ensure your_resource` in the server console, or the old manifest stays in use.
- **Relying on `[folder]` order.** If your resource needs another one to start first, list it in dependencies instead of hoping the folder order is right.
> [!TIP]
> Keep the resource name and folder name the same, lowercase, with no spaces. `ensure` uses the folder name, and `name` in the manifest is only metadata.
## Limitations
The generator does not look at your resource folder, so it cannot tell whether the files and globs you list exist. It writes one manifest at a time. Everything happens in your browser.
## Related tools
- [server.cfg Generator](/docs/tools/server-cfg-generator)
- [Vehicle Handling Editor](/docs/tools/vehicle-handling-editor)
- [Vehicle Pack Validator](/docs/tools/vehicle-pack-validator)
- [Weapons Meta Editor](/docs/tools/weapons-meta-editor)
- [Vehicle Sirens Editor](/docs/tools/vehicle-sirens)
_Last updated: 2026-09-22_
---
## Vehicle Handling Editor
URL: https://fivemad.com/docs/tools/vehicle-handling-editor
Tune CHandlingData with sliders, import an existing handling.meta, toggle flag bits, and export handling.meta, runtime Lua or a carcols.meta mod kit.
The Vehicle Handling Editor lets you tune a vehicle's `CHandlingData` block with sliders and a one line explanation per field. You can start from a template or import your own `handling.meta`, flip handling, model and damage flag bits, and export a clean `handling.meta`, a runtime Lua script for live testing, or a `carcols.meta` mod kit for add-on cars.
## What it is for
Handling work is a loop: change a value, restart the resource, respawn the car, drive, repeat. The editor shortens that loop. You see every field with its unit and meaning, you see what you changed against the loaded values, and you can copy a Lua snippet that applies the new values to the car you are sitting in without a restart. When the car feels right, you download the final `handling.meta`.
It is also the quickest way to give an add-on car a mod kit, so it can take engine, brake, gearbox, suspension and armour upgrades.
## Quick start
1. Pick a template under **Start from template**, or click **Import handling.meta** and paste the file (or use **Open file**), then **Parse**.
2. Set **handlingName** so it matches `` in the car's `vehicles.meta`.
3. On the **Physics** tab, tune the values. A field you changed gets an amber dot and a **Reset** link that puts that one field back.
4. Switch to **Flags** for handling, model and damage flags, and to **Mod kit** if the car needs a `carcols.meta` kit.
5. Watch the **Driving profile** tiles on the right to see what the change does to top speed, drivetrain and grip.
6. Pick an output tab (**handling.meta**, **Lua** or **carcols.meta**), then copy or download it.
**Undo N changes** in the top bar puts every field back to the loaded template or import. Your work is saved in this browser.
## Templates
The templates are generic, hand-tuned starting points, not copies of base game cars.
| Template | Drive | Notes |
| --- | --- | --- |
| Sports car (RWD) | RWD | 1400 kg, 6 gears, drive force 0.30, flat vel 150 |
| Supercar (AWD) | AWD 30/70 | 1500 kg, 7 gears, drive force 0.36, flat vel 160, more grip |
| Compact (FWD) | FWD | 1100 kg, 5 gears, drive force 0.20, softer brakes and grip, AI `AVERAGE` |
| Sedan (RWD) | RWD | 1600 kg, 5 gears, soft suspension, AI `AVERAGE` |
| Muscle (RWD) | RWD | 1600 kg, drive force 0.32, extra wheelspin at launch, weak brakes |
| Off-road SUV (AWD) | AWD 50/50 | 2200 kg, long suspension travel, low off-road grip loss, off-road handling flag |
| Drift setup (RWD) | RWD | Sports car base with 55 degree steering lock, lower grip, stronger handbrake |
Loading a template keeps your current **handlingName**.
## Importing a handling.meta
Paste a whole `handling.meta` or a single `- ` block. If the file holds several vehicles, the editor lists them as chips ("N vehicles found, pick one") and you choose which one to load. Fields the editor does not have sliders for (for example `fDownforceModifier`) and the `SubHandlingData` block are kept and written back on export, so bikes, boats and planes keep their `CBikeHandlingData`, `CBoatHandlingData` or `CFlyingHandlingData` item untouched.
If you want to start from a real game vehicle, copy its `
- ` block from the game's handling.meta and import that.
## Fields
The **Physics** tab has section chips (**All**, **Body & mass**, **Engine & gearbox**, **Brakes & steering**, **Traction**, **Suspension**, **Damage & fluids**, **Seat, value & AI**). Each field has a slider and a number box. The number box accepts values outside the slider range, which matters for imports that go past it.
### Body and mass
| Field | What it does | Slider range |
| --- | --- | --- |
| `fMass` | Weight in kg. Affects collisions and how much force is needed to move the car. | 50 to 30000 |
| `fInitialDragCoeff` | Air drag. Higher lowers the real top speed and slows the car when coasting. | 0 to 50 |
| `fPercentSubmerged` | How far it sinks in water before it floats, percent of height. | 0 to 100 |
| `vecCentreOfMassOffset` | x = right, y = forward, z = up, in metres. Negative z makes it harder to roll. | -2 to 2 per axis |
| `vecInertiaMultiplier` | Rotational inertia per axis. Higher is slower to pitch, roll or yaw. | 0 to 5 per axis |
### Engine and gearbox
| Field | What it does | Slider range |
| --- | --- | --- |
| `fDriveBiasFront` | 0.0 is RWD, 1.0 is FWD, anything between is AWD with that share at the front. | 0 to 1 |
| `nInitialDriveGears` | Number of forward gears. | 1 to 10 |
| `fInitialDriveForce` | Engine power at the wheels. The main acceleration value. | 0.01 to 2 |
| `fDriveInertia` | How fast the engine revs up. | 0.01 to 2 |
| `fClutchChangeRateScaleUpShift` | Up-shift speed. Higher shifts faster. | 0.1 to 15 |
| `fClutchChangeRateScaleDownShift` | Down-shift speed. | 0.1 to 15 |
| `fInitialDriveMaxFlatVel` | Gearing top speed on flat ground, roughly km/h. Drag decides the real top speed. | 0 to 500 |
### Brakes and steering
| Field | What it does | Slider range |
| --- | --- | --- |
| `fBrakeForce` | Brake strength. Around 1.0 is a strong sports car brake. | 0.01 to 5 |
| `fBrakeBiasFront` | Share of brake force on the front axle. 0.5 is even. | 0 to 1 |
| `fHandBrakeForce` | Handbrake strength. Higher locks the rear quicker. | 0 to 5 |
| `fSteeringLock` | Maximum steering angle in degrees. | 1 to 90 |
### Traction
| Field | What it does | Slider range |
| --- | --- | --- |
| `fTractionCurveMax` | Peak cornering grip. The main grip value. | 0 to 5 |
| `fTractionCurveMin` | Grip when sliding. Lower than max makes the car easier to break loose. | 0 to 5 |
| `fTractionCurveLateral` | Slip angle in degrees where peak grip is reached. | 0 to 45 |
| `fTractionSpringDeltaMax` | How far the tyre can flex before it loses grip, in metres. | 0 to 1 |
| `fLowSpeedTractionLossMult` | Wheelspin at launch. 0 is none. | 0 to 3 |
| `fCamberStiffnesss` | Grip from body roll when cornering, usually 0. | -1 to 1 |
| `fTractionBiasFront` | Grip distribution. Below 0.5 gives the rear more grip. | 0 to 1 |
| `fTractionLossMult` | Grip loss on dirt and grass. Lower keeps road grip off-road. | 0 to 3 |
### Suspension
| Field | What it does | Slider range |
| --- | --- | --- |
| `fSuspensionForce` | Spring stiffness. | 0 to 10 |
| `fSuspensionCompDamp` | Damping when the spring compresses. | 0 to 5 |
| `fSuspensionReboundDamp` | Damping when the spring extends. | 0 to 5 |
| `fSuspensionUpperLimit` | How far the wheel moves up from rest, metres. | -0.5 to 0.5 |
| `fSuspensionLowerLimit` | How far the wheel drops from rest, negative values. | -0.5 to 0.5 |
| `fSuspensionRaise` | Ride height offset. Negative lowers the car. | -0.3 to 0.3 |
| `fSuspensionBiasFront` | Spring force distribution. Above 0.5 is stiffer at the front. | 0 to 1 |
| `fAntiRollBarForce` | Anti-roll bar strength. Higher reduces body roll. | 0 to 3 |
| `fAntiRollBarBiasFront` | Anti-roll bar distribution. | 0 to 1 |
| `fRollCentreHeightFront` / `fRollCentreHeightRear` | Roll centre heights. Higher reduces roll but can tip the car. | -0.5 to 1 |
### Damage and fluids
| Field | What it does | Slider range |
| --- | --- | --- |
| `fCollisionDamageMult` | Damage from collisions. | 0 to 5 |
| `fWeaponDamageMult` | Damage from weapons. | 0 to 5 |
| `fDeformationDamageMult` | Visual body deformation. 0 keeps the body straight. | 0 to 5 |
| `fEngineDamageMult` | Engine damage from hits. | 0 to 5 |
| `fPetrolTankVolume` | Tank size in litres. Fuel scripts often read it. | 0 to 200 |
| `fOilVolume` | Oil volume. Affects how long the engine smokes before it dies. | 0 to 20 |
### Seat, value and AI
`fSeatOffsetDistX`, `fSeatOffsetDistY` and `fSeatOffsetDistZ` move the driver seat position (-1 to 1 m). `nMonetaryValue` is the base value used for things like insurance and sell price. **AIHandling** picks how AI drivers handle the car: `AVERAGE`, `SPORTS_CAR`, `TRUCK` or `CRAP` (an imported value that is not in this list is kept as an extra option).
## Flags
The **Flags** tab has three panels: **Handling flags** (`strHandlingFlags`), **Model flags** (`strModelFlags`) and **Damage flags** (`strDamageFlags`). Click a bit to toggle it, or type the hex value in the box at the top right of the panel. Each bit shows its name, a short description and its hex mask.
Some common ones:
| Flag | Mask | What it does |
| --- | --- | --- |
| `HF_HAS_RALLY_TYRES` | `0x8` | Better grip on loose surfaces |
| `HF_NO_HANDBRAKE` | `0x10` | Handbrake disabled |
| `HF_CVT` | `0x1000` | No gear shifts |
| `HF_OFFROAD_ABILITIES` | `0x100000` | Better off-road grip |
| `HF_FORCE_NO_TC_OR_SC` | `0x2000000` | Disables traction and stability control |
| `MF_ABS_STD` | `0x10` | ABS fitted as standard |
| `MF_NO_WHEEL_BURST` | `0x2000000` | Bulletproof tyres |
| `DF_BONNET` | `0x10` | Bonnet cannot break off |
Model flag changes usually need the vehicle to be respawned.
## Mod kit
The **Mod kit** tab builds a `carcols.meta` with one kit. An add-on vehicle needs a kit before it can take performance upgrades or show up properly in tuning menus.
| Option | What it does | Default |
| --- | --- | --- |
| Kit id | Must be unique across every vehicle on the server. | 1450 |
| Kit type | `MKT_STANDARD`, `MKT_SPECIAL`, `MKT_SPORT` or `MKT_SUV` | `MKT_STANDARD` |
| Kit name | Empty uses `
__modkit`, for example `1450_mycar_modkit`. | Empty |
| Stat mods | A toggle per upgrade with comma separated modifier values, one per level. | Engine `25, 50, 75, 100`, Brakes `25, 50, 100`, Transmission `25, 50, 100`, Suspension `25, 50, 75, 100`, Armour `20, 40, 60, 80, 100` |
Picking the **Mod kit** tab switches the output to **carcols.meta**.
## Driving profile
The tiles on the right are estimates from the current values:
| Tile | What it shows |
| --- | --- |
| Top speed (est.) | Gearing limit from `fInitialDriveMaxFlatVel`, in km/h and mph. Drag and power decide where the car really tops out. |
| Drivetrain | RWD, FWD or AWD with the front/rear split, plus the gear count. |
| Force per tonne | Drive force relative to mass, for comparing cars. |
| Weight | Mass and drag. |
| Brake bias | Front brake share and brake force. |
| Grip | Max and min traction, plus the front grip bias. |
## Output
### handling.meta
The **handling.meta** tab gives a complete file with one item. Floats are written with six decimals and flags as hex without `0x`. If the loaded handling had no `SubHandlingData`, three `NULL` items are added.
```xml title="handling.meta"
-
MYCAR
440010
20000
0
SPORTS_CAR
```
Load it in a resource like this:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'data/handling.meta',
}
data_file 'HANDLING_FILE' 'data/handling.meta'
```
Restart the resource and respawn the vehicle. Handling is read when the vehicle is created, so a car that was already out keeps the old values.
### Lua
The **Lua** tab writes a client script that applies the values with `SetVehicleHandlingFloat`, `SetVehicleHandlingInt` and `SetVehicleHandlingVector` on the `'CHandlingData'` class, then calls `ModifyVehicleTopSpeed(vehicle, 1.0)` so drive force and top speed changes apply right away.
| Option | What it does |
| --- | --- |
| Command / Function | **Command** adds a `RegisterCommand` that applies the handling to the vehicle you sit in. The box next to it sets the command name (default `handling`). **Function** returns just the `ApplyHandling(vehicle)` function. |
| Only changed fields | Emit natives only for values that differ from the loaded template or import. |
With **Only changed fields** on and two values changed:
```lua title="handling.lua"
-- Runtime handling for MYCAR (client side).
-- Values use handling.meta units: FiveM converts km/h, degrees and bias values itself.
-- Changes apply to this vehicle only and are lost when it is deleted or respawned.
local function ApplyHandling(vehicle)
SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce', 0.35)
SetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel', 165.0)
-- Commonly needed so drive force and top speed changes take effect right away.
ModifyVehicleTopSpeed(vehicle, 1.0)
end
RegisterCommand('handling', function()
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if vehicle == 0 then
print('You need to be in a vehicle')
return
end
ApplyHandling(vehicle)
print('Applied MYCAR handling')
end, false)
```
Run it on the client that owns the vehicle. You pass the same numbers you would write in handling.meta, FiveM converts them to the game's internal units. Floats always carry a decimal point (`165.0`, not `165`). The Lua output does not include `AIHandling`.
### carcols.meta
```xml title="carcols.meta"
-
1450_mycar_modkit
MKT_STANDARD
-
VMT_ENGINE
```
Then reference the kit in the car's `vehicles.meta` item and register the file:
```xml title="vehicles.meta"
- 1450_mycar_modkit
```
```lua title="fxmanifest.lua"
data_file 'CARCOLS_FILE' 'data/carcols.meta'
```
## Common mistakes
- **handlingName does not match.** The value must equal `` in `vehicles.meta`, or the car keeps its old handling.
- **Fixing the spelling of `fCamberStiffnesss`.** It really has three s's. Spelling it "correctly" means the game ignores it.
- **Testing on a car that was already spawned.** Respawn after restarting the resource.
- **Flags with `0x`.** In handling.meta flags are hex without a prefix, for example `440010 `.
- **Duplicate mod kit ids.** Two cars with the same kit id make tuning menus show the wrong parts.
- **Shipping only the Lua.** Runtime changes only affect that one vehicle and are gone when it is deleted. Ship the final values in handling.meta.
> [!TIP]
> Tune with the Lua command first: sit in the car, change a slider, copy the Lua, run it, drive. When it feels right, download handling.meta once.
## Limitations
The editor has sliders for 45 common `CHandlingData` fields plus the three flag sets and `AIHandling`. Other fields from an import are kept as they are but cannot be edited here. The driving profile numbers are estimates, not a physics simulation. Everything runs in your browser and nothing is uploaded.
## Related tools
- [fxmanifest.lua Generator](/docs/tools/fxmanifest-generator)
- [Vehicle Pack Validator](/docs/tools/vehicle-pack-validator)
- [Vehicle Sirens Editor](/docs/tools/vehicle-sirens)
- [Model Hash Browser](/docs/tools/model-hash-browser)
_Last updated: 2026-09-22_
---
## Clothing Designer
URL: https://fivemad.com/docs/tools/clothing-designer
How to open a clothing .ydd or .ydr with its .ytd files, paint on the 3D model or the UV layout with layers, and export ready to stream .ytd textures.
The Clothing Designer is a texture editor for FiveM clothing that shows your work on the real model. You open a drawable (`.ydd` or `.ydr`) with its `.ytd` texture files, or start from a game template, paint on the model or on the flat texture with layers, and export new `.ytd` files named the way the game expects. It is meant for server owners and clothing makers who want a new colourway, a logo on a top or a whole set of variations without a Photoshop and OpenIV round trip.
## What it is for
A typical job: you have a hoodie in your clothing pack and want a police, EMS and gang version of it. Normally you export the diffuse from the `.ytd`, paint it blind in an image editor while guessing where the UV islands land, convert it back to DDS and import it again. Here you paint straight on the 3D model (strokes go through the UVs into the texture), see the result live, add one texture slot per variation, and export every `.ytd` in one zip.
Everything runs in your browser. The files you drop are read locally and nothing is uploaded.
> [!NOTE]
> The editor needs a screen at least 1024 px wide. On a phone or small tablet the page only shows a 3D viewer for the game templates, with a note to open it on a PC to edit and export.
## Quick start
1. Open the [tool](/tools/clothing-designer). The start screen has **Choose files**, **Choose folder** and a row of game templates.
2. Drop the drawable and its textures, for example `jbib_004_u.ydd` with `jbib_diff_004_a_uni.ytd`, `jbib_diff_004_b_uni.ytd` and so on. A whole stream folder works too. If the folder holds several drawables you get a list (**Pick the drawable to edit**) showing vertex and texture counts; the textures are matched to the one you pick by name.
3. No files at hand? Click a template on the start screen or in the **Templates** tab.
4. Pick the **Brush** (B ), choose a colour in the tool rail on the left and paint on the model or on the texture panel.
5. Press **Save** (Ctrl + S ) to keep the project in this browser.
6. Press **Export**, set the drawable number and gender, and click **Export all (.zip)**.
7. Copy the `stream/` files from the zip into your clothing resource.
## Supported files
| Input | Notes |
| --- | --- |
| `.ydd` | Drawable dictionary, how the game and most packs ship clothing. A `.ydd` can hold several drawables, each shows up in the picker. |
| `.ydr` | Single drawable. |
| `.ydd.xml`, `.ydr.xml` | CodeWalker XML export, with its DDS folder. |
| `.ytd` | Texture dictionaries. Readable formats: DXT1, DXT3, DXT5, BC4 (ATI1), BC5 (ATI2), BC7 and A8R8G8B8. |
| PNG, JPG, WebP, GIF, DDS | Images for image layers. |
| TTF, OTF, WOFF, WOFF2 | Custom fonts for text layers. |
| `.fmcloth` | A project file saved by this tool. |
Binary files must be the legacy RSC7 resources FiveM uses. The highest LOD of the drawable is shown. Textures embedded in the drawable itself (common for props) are found too; if the diffuse is embedded, the export writes it as a separate `.ytd` and a warning under **Drawable details** says so.
Addon names with a collection prefix, like `mp_m_freemode_01_mypack^jbib_004_u.ydd`, work the same as plain names. Files that do not follow the freemode naming at all open as **Other drawable** and keep their own file and texture names on export.
> [!WARNING]
> Dropping only `.ytd` files does not work: the tool needs the model for the UV layout and the 3D preview. Drop the `.ydd` or `.ydr` together with its textures. If no diffuse texture is found, you paint on a blank grey texture and a warning tells you so.
## The workspace
The header shows the project name (click it to rename), the gender, and the item code like `jbib_004`. **Unsaved** appears when you have changes that are not saved. On the right: undo, redo, the keyboard shortcut list, full screen (Esc leaves it), **Save** and **Export**.
Below the header is the options bar for the active tool, the tool rail on the left, the two view panels in the middle and the sidebar on the right. The status bar at the bottom shows the cursor position in texture pixels, the UV island under the pointer, and vertex, triangle, geometry and UV island counts.
### 3D preview
The model with your texture as it is right now. Drag on the model to paint (with a painting tool active), drag the background to orbit, right drag to pan.
| Control | What it does |
| --- | --- |
| **Lit** / **Flat** | Lit uses preview shading. Flat is unlit and shows the texture colours as they are. |
| Wireframe | Draws the mesh edges on top. |
| Background | Cycles dark, mid and light. |
| **View** | Jumps to front, back, left or right. |
| Reset view | Back to the start camera. |
Ped clothing is shown in its bind pose without the body. Hats and glasses are turned upright for the preview only. The shading is a preview, not the game's ped shader.
### Texture panel
The texture at full size with the model's UV layout on top, so you see which part of the image lands where. Hover the model or the texture to highlight a UV island.
| Control | What it does | Default |
| --- | --- | --- |
| UV overlay | Shows or hides the UV wireframe. | On |
| **UV style** | Colour and opacity of the UV lines. | White, 35% |
| Pixel grid | Grid when zoomed in far. | On |
| Zoom out, zoom in, percentage | The percentage button fits the texture (F ). | Fit |
Pan with Space + drag, Alt + drag (move tool) or the middle or right mouse button. The wheel zooms. Drag the divider between the panels to give one more room (25% to 75%), or hide a panel with its minimize button and bring it back from the thin bar at the side.
## Tools
The tool rail holds the tools and the primary and secondary colour (defaults `#d9463b` and white). X swaps them. Each tool has its settings in the options bar.
| Tool | Key | Options |
| --- | --- | --- |
| Move and transform | V | For image, text and shape layers: X, Y, W, H, Angle, flip horizontally, flip vertically, centre on the texture. Drag a paint layer to shift its pixels. |
| Brush | B | Colour, Size (1 to 600 px, default 32), Hardness (default 70%), Opacity, Pen pressure, Stay inside the UV island. |
| Eraser | E | Size (default 48), Hardness (default 80%), Opacity, Pen pressure, Stay inside the UV island. |
| Fill | G | Colour, mode (**Similar colour**, **UV island**, **Whole layer**), Tolerance (0 to 255, default 32) and sample **All layers** or **This layer** for similar colour, Opacity. |
| Gradient | D | Start and end colour, **Linear** or **Radial**, **Fade to transparent**. Each drag makes a new gradient layer. |
| Colour picker | I | Click to pick the primary colour, Shift + click for the secondary. Alt + click works with the brush too. |
| Text | T | Text colour. Click the texture or the model to place text; font, outline and curve are in the layer panel. |
| Shapes | U | Rectangle, ellipse, line, polygon, star. Fill and outline with their colours, outline width (1 to 200 px). Shift keeps the shape square (or snaps a line to 15 degrees), Alt draws from the centre. |
| Image | P | Opens a file picker. You can also paste an image with Ctrl + V or drop it on the texture. |
[ and ] change the brush or eraser size. **Stay inside the UV island** keeps a stroke on the island where it started, which is handy along seams.
Painting on the model stops at UV seams: a stroke that crosses a seam continues on the other island without joining up, so touch up seams in the texture view.
## Sidebar
The sidebar has three tabs: **Layers**, **Templates** and **Saved**.
### Slots
A slot is one texture variation of the drawable: `a`, `b`, `c`... Every slot has its own layer stack and becomes its own `.ytd`. **Add slot** offers **Copy of slot a** (the current one), **Base texture only** and **Solid primary colour**. Below the thumbnails you can change the letter of the active slot and see the texture name it will get on export, for example `jbib_diff_004_b_uni`. The trash button deletes the slot (the last one can not be deleted).
> [!IMPORTANT]
> The game reads texture variations in order from `a`. A gap (a, b, d) means missing textures in game. The export dialog warns about this and has a **Make a, b, c** button that renumbers the slots.
### Layers
The original texture is the bottom layer (**Base texture**), with an empty **Paint** layer above it. Paint on the layer above the base so the eraser always brings the original back.
Each row has visibility and lock toggles; double click a name to rename it, drag rows to reorder. The buttons below the list: move up, move down, **Duplicate** (Ctrl + J ), **Merge down** (Ctrl + E ), flip horizontally, flip vertically and **Delete layer**. The plus button adds a paint layer, the image button adds an image layer. Ctrl + C and Ctrl + V copy and paste a layer.
### Layer properties
Every layer has **Opacity** and **Blend**: Normal, Multiply, Screen, Overlay, Soft light, Hard light, Darken, Lighten, Color dodge, Color burn, Difference, Exclusion, Hue, Saturation, Color, Luminosity.
- **Text layers**: the text itself (multi line), font, **Size**, **Weight** (300 to 900), colour, alignment (Left, Centre, Right), **Italic**, outline colour and width, **Spacing**, **Curve** (minus 360 to 360 degrees, bends the text over an arc) and **Line height** for multi line text without curve. Built in fonts are Arial, Arial Black, Impact, Verdana, Tahoma, Trebuchet MS, Georgia, Times New Roman, Courier New, Comic Sans MS, Geist and Geist Mono. The upload button next to the font list adds your own `.ttf`, `.otf` or `.woff`; it is stored with the project. Double click a text layer on the texture to jump to its text box.
- **Shape layers**: **Width**, **Height**, **Radius** for rectangles, **Points** (3 to 48) for polygons and stars, fill and outline on or off with colours and outline width.
- **Gradient layers**: Linear or Radial, start and end colour, each with its own alpha. Drag the two dots on the texture to move the gradient.
- **Image layers**: show the source size. Drag the corner handles to scale (Shift frees the ratio), the round handle to rotate (Shift snaps to 15 degrees).
**Limit to UV islands** switches to island picking: click islands on the texture or the model to add or remove them, then press **Done**. The layer then only shows inside those islands, for example only the sleeves. **Clear** removes the limit. **Rasterize** turns a text, shape, gradient or image layer into plain pixels so you can paint on it.
**Drawable details** at the bottom lists the file, type, LOD shown, shaders, embedded textures, textures from the original `.ytd` that are kept as they are (normal and spec maps), and any load warnings.
### Templates
Freemode clothing from the base game, with the real UV layout and textures. Filter by **Male** or **Female**, by category (JBIB, LOWR, FEET, ACCS, TEEF, BERD, TASK, HAND, HATS) or search by name. A template opens with one slot per texture variation. Templates do not include the drawable file itself, see the Output section below.
### Saved
**Save** keeps the whole project (layers, fonts and your original files) in this browser's storage, with a 3D thumbnail. The Saved tab lists every project with **Continue**, rename, **Download project file** and delete, plus **Import file** to open a `.fmcloth` and **Delete all saved projects**. Saved projects stay in this browser only; download a `.fmcloth` to back one up or move it to another PC.
The page warns before you close it with unsaved changes. Undo keeps the last 80 steps.
## Export
**Export** opens a dialog with two columns.
### Drawable
| Field | What it does |
| --- | --- |
| **Number** | The drawable number, 0 to 999. Change it to place the item after your existing ones. |
| **Male** / **Female** | Picks `mp_m_freemode_01` or `mp_f_freemode_01` for the prefix and the zip name. |
| Drawable **_u** / **_r** | Universal or race specific drawable suffix (components only, not props). |
| **Texture race** | The race suffix on texture names: `uni`, `whi`, `bla`, `chi`, `lat`, `ara`, `bal`, `jam`, `kor`, `ita`, `pak`. |
| **Addon names with a collection prefix** | Adds `mp_m_freemode_01_^` (props: `mp_m_freemode_01_p_^`). On by default when your files had a prefix or you started from a template. |
| **Collection** | The collection name, default `my_clothes`. Lower case letters, digits and underscores only. |
For an **Other drawable** these fields are hidden and every file keeps its original name.
### Texture format
| Choice | Result |
| --- | --- |
| **Auto** (default) | DXT1 when the texture has no transparency, DXT5 otherwise. |
| **DXT1** | Always DXT1. |
| **DXT5** | Always DXT5. |
| **Uncompressed** | A8R8G8B8, 4x bigger. |
Every texture gets a full mip chain. Normal and spec maps that were inside your original `.ytd` files are copied as they were. Big textures (2048 px) take a few seconds to encode.
### Buttons
- **Export all (.zip)**: every slot as its own `.ytd`, the drawable renamed to your number and prefix, and a `README.txt`.
- **.ytd**, **PNG**, **DDS**: only the active slot, as a single file.
- **Project file (.fmcloth) with all layers**: the editable project.
## Output
The zip is named `__.zip`, for example `jbib_004_male.zip`. With a collection prefix it contains:
```bash
stream/mp_m_freemode_01_my_clothes^jbib_004_u.ydd
stream/mp_m_freemode_01_my_clothes^jbib_diff_004_a_uni.ytd
stream/mp_m_freemode_01_my_clothes^jbib_diff_004_b_uni.ytd
README.txt
```
Props follow the prop naming: `p_head_000.ydd` and `p_head_diff_000_a.ytd`, without race suffix. The drawable is your original file, byte for byte, only renamed. Each `.ytd` holds the edited diffuse under the slot's texture name plus any other textures that were in the original `.ytd` for that variation.
When you started from a template the drawable is not in the zip. The README names the game file to copy (for base game items from `x64v.rpf/models/cdimages/streamedpeds_mp.rpf/mp_m_freemode_01/`, or `streamedpedprops.rpf` for props) and what to rename it to. Extract it with CodeWalker or OpenIV.
## Getting it into FiveM
1. Create a resource folder, for example `resources/[clothes]/my_clothes/`, with a `stream/` folder inside.
2. Copy everything from the zip's `stream/` folder into it. The drawable and its `.ytd` files must keep matching names: same component, same number, texture letters in order.
3. Addon clothing (with the collection prefix) also needs the ped variation file (`.ymt`) and usually a shop meta so the item shows up in clothing menus. Build them with the [YMT Creator](/docs/tools/ymt-creator), which reads the file names this tool writes.
4. Add the resource to `server.cfg` and restart.
A minimal manifest for an addon pack with a shop meta:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'mp_m_freemode_01_my_clothes.meta',
}
data_file 'SHOP_PED_APPAREL_META_FILE' 'mp_m_freemode_01_my_clothes.meta'
```
```cfg title="server.cfg"
ensure my_clothes
```
FiveM streams everything in `stream/` on its own, so the `.ydd` and `.ytd` files need no `files` entry.
> [!TIP]
> Only changed the textures of an item that is already in your pack? Keep the prefix and number the pack uses, export, and overwrite just the `.ytd` files. The `.ymt` does not change as long as the number of texture variations stays the same.
## Keyboard shortcuts
| Keys | Action |
| --- | --- |
| V , B , E , G , D , I , T , U , P | Move, brush, eraser, fill, gradient, picker, text, shapes, image |
| [ and ] | Brush size |
| X | Swap colours |
| Ctrl + Z | Undo |
| Ctrl + Shift + Z , Ctrl + Y | Redo |
| Ctrl + C / Ctrl + V | Copy / paste layer (paste also takes images) |
| Ctrl + J / Ctrl + E | Duplicate layer / merge down |
| Delete | Delete layer (move tool) |
| Arrows | Nudge 1 px, with Shift 10 px (move tool) |
| F | Fit the texture |
| Ctrl + S | Save in this browser |
Shortcuts only work while the pointer is over the editor or it has focus, so the rest of the page keeps normal keys.
## Common mistakes
- **Gaps in texture letters.** Deleting slot `b` leaves `a, c`. Use **Make a, b, c** in the export dialog.
- **Mismatched numbers.** If you change **Number**, all files get the new number. Do not mix old and new files in `stream/`.
- **Soft alpha in DXT1.** With **Auto**, any pixel below full opacity makes the slot DXT5. If you forced DXT1, soft edges become hard cutouts.
- **Forgetting the drawable for templates.** A template export only has `.ytd` files. Copy the drawable from the game as the README says.
## Limitations
- Only the highest LOD is shown and painted. The drawable file is exported unchanged, so you can not edit geometry here.
- The 3D view is a preview, not the game's ped shader. Check the final look in game.
- Only the diffuse texture of each slot is edited. Normal and spec maps are passed through.
- Gen9 (Enhanced) resources are not read, only the legacy format FiveM uses.
## Related tools
- [YMT Creator](/docs/tools/ymt-creator) builds the `.ymt` and shop meta for addon clothing.
- [Texture Editor](/docs/tools/texture-editor) for any `.ytd`, with format and mip control.
- [YTD Optimizer](/docs/tools/ytd-optimizer) to shrink big clothing packs.
- [3D Tattoo Editor](/docs/tools/tattoo-editor) for tattoo overlays on the freemode ped.
- [Drawable Studio](/docs/tools/drawable-studio) for materials, lights and painting on CodeWalker XML exports.
_Last updated: 2026-09-22_
---
## 3D Tattoo Editor
URL: https://fivemad.com/docs/tools/tattoo-editor
How to place a tattoo on the freemode ped in 3D by zone, tune its uvPos, scale and rotation, and get the overlay XML or a Durty Cloth Tool project out of it.
The 3D Tattoo Editor lets you upload a tattoo image, pick a body zone and position it on `mp_m_freemode_01` or `mp_f_freemode_01` in 3D. You click the body to place it, fine tune the numbers, then copy the overlay XML or hand everything to Durty Cloth Tool. It is for anyone making addon tattoos who is tired of guessing `uvPos` values and restarting the game to check them.
## What it is for
GTA V tattoos are overlays: each one sits in a body zone (head, torso, each arm, each leg) and is placed by three values in the overlay XML:
| Value | Meaning |
| --- | --- |
| `uvPos` | Centre of the tattoo inside the zone, `x` and `y` from 0 to 1. |
| `scale` | Size, `x` and `y` from 0 to 1. |
| `rotation` | Angle in degrees. |
These numbers are hard to guess by hand. The editor shows the tattoo on the real freemode body while you move it, and what you see is where the game puts it.
## Quick start
1. Open the [tool](/tools/tattoo-editor). The male ped loads in the viewer.
2. Under **Tattoo image**, click **Upload tattoo image** or drop a PNG, JPG or WebP on it. No image yet? Click **No image at hand? Try a sample** for a test design with an arrow that shows which way is up.
3. Pick **Male** or **Female** and the **Zone**.
4. Click the body where the tattoo should go. The zone switches to the part you clicked and the position jumps there.
5. Fine tune with the **UV X**, **UV Y**, **Scale** and **Rotation (deg)** sliders, or type the numbers.
6. Set the **Overlay name** and **Collection**, then **Copy overlay XML** or press **Create in Durty Cloth Tool**.
## The viewer
Drag to orbit, scroll to zoom, click the body to place the tattoo there (a click only counts when you did not drag). The label in the top left shows the ped model and the current zone. The buttons in the top right:
| Button | What it does |
| --- | --- |
| Background colour | Colour picker for the viewer background (default near black). |
| Focus zone | Moves the camera to the current zone. The camera also moves there when you change zone. |
| Save screenshot | Downloads the current view as a PNG named `_.png`, for example `my_tattoo_zone_torso.png`. |
## Panels
### Tattoo image
Accepts PNG, JPG and WebP. A PNG with a transparent background works best, because everything that is not transparent shows on the skin.
Tattoo textures are square in GTA. When your image is not square, a dialog asks what to do:
- **Crop centre** cuts the largest centred square out of the image.
- **Fit with padding** keeps the whole image and pads the short side with transparency.
After loading you see a thumbnail with the file name and size, **Change** to pick another file, and the X to remove it. Uploading a file also fills the **Overlay name** from the file name (lower case, anything but letters, digits and underscores turned into `_`).
### Placement
| Control | What it does | Default |
| --- | --- | --- |
| **Male** / **Female** | Switches between `mp_m_freemode_01` and `mp_f_freemode_01`. | Male |
| **Skin tone** | Pale, Light, Medium, Tan, Brown, Dark. Preview only, it does not change the export. | Light |
| **Zone** | Head, Torso, Left arm, Right arm, Left leg, Right leg. | Torso |
| **Quick spots** | Preset positions for the current zone (see below). | |
| **UV X**, **UV Y** | The `uvPos` centre, 0 to 1 in steps of 0.001. | 0.5, 0.5 |
| **Scale** | One slider for both axes while **X + Y linked** is on. Click the lock to switch to **X and Y separate** and get **Scale X** and **Scale Y**. | 0.2, linked |
| **Rotation (deg)** | Minus 360 to 360. | 0 |
| **Show tattoo** | Hides the tattoo to compare with bare skin. | On |
| **Wrap around** | Continues the tattoo past the edge of the zone, the way the game does around limbs. | On |
| **Reset placement** | Back to the defaults above. | |
Each slider has a number box, so you can paste exact values from an existing overlay file.
### Quick spots
| Zone | Spots |
| --- | --- |
| Torso | Chest, Stomach, Upper back, Lower back, Right ribs, Left ribs |
| Head | Forehead, Left cheek, Right cheek, Left temple, Right temple |
| Left arm, Right arm | Shoulder, Upper arm, Forearm, Wrist, Hand |
| Left leg, Right leg | Thigh front, Thigh back, Shin, Calf, Ankle |
A quick spot only sets **UV X** and **UV Y**, scale and rotation stay as they are.
### How the zone coordinates run
Knowing this saves a lot of trial and error when you type values:
- `y` runs from bottom (0) to top (1): waist to neck on the torso, hand to shoulder on arms, ankle to hip on legs.
- On the torso, `x` wraps around the body: about 0.25 is the back, 0.5 the right side, 0.75 the chest, and both 0 and 1 are the left side.
- Arms and legs are mirrored on `x`, so the same values on the left and the right limb land on matching spots.
### Export
| Field | What it does | Default |
| --- | --- | --- |
| **Overlay name** | Written to `nameHash`, `txdHash` and `txtHash` in the XML, and used in the Lua snippet. | `my_tattoo` |
| **Collection** | Only used in the Lua snippet, as the collection argument. | `mpfivemad_overlays` |
Buttons:
- **Copy overlay XML** copies the `- ` block shown below the editor.
- **Create in Durty Cloth Tool** opens Durty Cloth Tool (v3.1 or newer must be installed) with the zone, gender and placement filled in. The tattoo image is passed through your clipboard, so allow clipboard access when the browser asks.
- **Copy share link** copies the page URL with the current gender, zone, skin tone and placement.
## Output
Below the panels you get two code blocks: the overlay item and a Lua snippet. With the defaults and an image named `dragon.png` on the torso:
```xml title="dragon_overlay.xml"
-
dragon
dragon
dragon
ZONE_TORSO
TYPE_TATTOO
FM
All
GENDER_MALE
```
```lua title="client.lua"
-- Apply the tattoo to the local player (collection = your overlay .ymt / dlc name)
local ped = PlayerPedId()
AddPedDecorationFromHashes(ped, `mpfivemad_overlays`, `dragon`)
-- Remove all tattoos
-- ClearPedDecorations(ped)
```
The tool does not make the `.ytd` itself. Durty Cloth Tool builds the `.ytd`, the overlay file and the stream folder for you; by hand you need to do those steps yourself.
## Getting it into FiveM
### With Durty Cloth Tool
Press **Create in Durty Cloth Tool** and follow its steps. Its [tattoo guide](https://docs.gta.clothing/getting-started/first-addon-tattoo) covers the resource it creates.
### By hand
1. Put your tattoo texture in a `.ytd` whose name matches `txdHash` (here `dragon.ytd`), with a texture inside named like `txtHash`. The [Texture Editor](/docs/tools/texture-editor) can build that dictionary from a PNG.
2. Add the copied `- ` to the `
` list of your collection's overlay XML (the file name, without extension, is the collection name you pass to the natives).
3. Stream the `.ytd` and register the overlay file in your manifest.
4. Apply the tattoo in a script with `AddPedDecorationFromHashes` (or `AddPedDecorationFromHashesInCorona` in character creators).
A sketch of the resource:
```bash
my_tattoos/
fxmanifest.lua
overlays/mpfivemad_overlays.xml
stream/dragon.ytd
```
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'overlays/mpfivemad_overlays.xml',
}
data_file 'PED_OVERLAY_FILE' 'overlays/mpfivemad_overlays.xml'
```
> [!TIP]
> Tattoo shops read a separate shop list (`shop_tattoo.meta`) for prices and names. If you only apply tattoos from your own scripts, the overlay file and the `.ytd` are enough.
## Tips
- The URL always holds the current gender, zone, skin tone and placement (`?gender=MALE&zone=ZONE_TORSO&uvx=...`). Bookmark it or send it to a teammate to pick up where you left off. The image and the **Wrap around** setting are not part of the link.
- Keep **Wrap around** on for bands around arms and legs. Turn it off to see exactly where the tattoo gets cut at the zone edge.
- Make one version per gender. Female and male bodies differ, so place the tattoo on each and copy both items; the XML says `GENDER_MALE` or `GENDER_FEMALE`.
- Use **Save screenshot** for your store page or changelog.
## Common mistakes
- **Tattoo upside down or mirrored.** Use the sample image first: its arrow shows which way is up for each zone. Then flip or rotate your artwork, or use **Rotation (deg)**.
- **Scale too big.** A scale of 1 fills the whole zone. Most tattoos sit between 0.1 and 0.4.
- **Names that do not match.** `txdHash` must match the `.ytd` name and `txtHash` the texture inside it. Changing **Overlay name** changes all three.
- **Clipboard blocked.** If Durty Cloth Tool opens without the image, the browser did not allow clipboard access. Allow it and try again.
## Limitations
- Placement only. The tool does not write `.ytd` files or a complete overlay file.
- **Skin tone** tints the preview skin, it is not the game's skin shader.
- Everything runs in your browser. The image is not uploaded anywhere; for Durty Cloth Tool it goes through your own clipboard.
## Related tools
- [Clothing Designer](/docs/tools/clothing-designer) for painting clothing textures in 3D.
- [Texture Editor](/docs/tools/texture-editor) to build the tattoo `.ytd` from a PNG.
- [YMT Creator](/docs/tools/ymt-creator) for addon clothing files.
- [Hash Calculator](/docs/tools/hash-calculator) to get the joaat hash of an overlay or collection name.
_Last updated: 2026-09-22_
---
## Drawable Studio
URL: https://fivemad.com/docs/tools/drawable-studio
How to open a CodeWalker XML export (.ydr, .ydd, .yft) in 3D, check geometry and textures, edit shaders and lights, paint textures and export the result.
Drawable Studio opens a CodeWalker XML export of a model with its textures and shows it in 3D in your browser. You can check geometry, LODs and textures, change shader parameters and texture slots, add or move light effects, paint straight onto the model, and export the edited XML, the textures as DDS or PNG, or a GLB. It is for prop, vehicle and map makers who want to inspect or tweak a model without opening a 3D package.
## What it is for
- **Checking a model before you ship it.** Missing textures, empty LODs, wrong shader, a texture at 4096 that should be 1024: the Scene tab shows all of it at a glance.
- **Small material fixes.** Too shiny, normal map too strong, glow too weak: change `specularIntensityMult`, `bumpiness` or `emissiveMultiplier` and see it live.
- **Lamps on props.** Add a light to a streetlight or a sign, move it with a gizmo, set the hours it is on.
- **Quick texture touch ups.** Paint over a logo, fix a seam, recolour a part, then export the texture under its original name.
Everything is read in your browser. Nothing is uploaded.
## Export the model from CodeWalker
The tool reads CodeWalker's XML format, not the binary files.
1. Open CodeWalker's RPF Explorer (or the project window for your own files) and find the `.ydr`, `.ydd` or `.yft`.
2. Right click it and pick **Export XML**. CodeWalker writes `name.yft.xml` and a folder `name/` with the textures as DDS.
3. Vehicles and most props keep their textures in a separate `.ytd`. Export that one too; it gives you a `.ytd.xml` and the same kind of DDS folder.
4. Drop everything on the viewer together, or use **Choose folder**. Textures are matched to shaders by name, so the folder layout does not matter.
## Quick start
1. Open the [tool](/tools/drawable-studio).
2. Click **Choose folder** and pick the export folder, or drop it on the viewer. **Choose files** takes `.xml`, `.dds`, `.png`, `.jpg` and `.jpeg` files.
3. Wait for the progress bar (reading, parsing, decoding textures). A message tells you how many textures are missing, if any.
4. Look around, then switch between the **Scene**, **Materials**, **Lights** and **Paint** tabs on the right.
5. When you are done, press **Export XML**, **Package .zip** or **GLB** in the bar above the viewer.
> [!TIP]
> Forgot the texture folder? Drop the DDS files (or the folder) on the viewer while the model is open. They are added to the current model and the toast says how many missing textures they filled in.
## Inputs
| File | Used for |
| --- | --- |
| `.ydr.xml`, `.ydd.xml`, `.yft.xml` | The model. If a drop holds several model XML files, one model is opened. |
| `.ytd.xml` | Format info for textures that live in a separate dictionary. |
| `.dds` | Textures: DXT1, DXT3, DXT5, BC4, BC5, A8R8G8B8 and other uncompressed formats. |
| `.png`, `.jpg` | Textures too, matched by file name. |
BC7 textures are not supported yet; they show as unsupported in the texture list.
## The viewport
Drag to orbit, right drag to pan, the wheel zooms. Click a mesh to select it; its shader is selected in the Materials tab too.
Top left is the LOD switcher: **High**, **Med**, **Low**, **VLow**. LODs the file does not have are greyed out. Top right:
| Button | What it does |
| --- | --- |
| Background colour | Colour picker for the viewer background. |
| Wireframe | Draws the mesh edges. |
| Night preview | Dark sky, so lights and emissive shaders stand out. |
| Frame model | Moves the camera to fit the model. |
| Save screenshot (PNG) | Downloads the current view as `.png`. |
The bottom bar shows vertices, triangles, shaders and textures for the current LOD, plus how many textures are missing.
The model is shown the way the game places it: rigid parts on their bones, vehicle wheels on every wheel bone. Skinned meshes (peds, most vehicle bodies) are shown in their bind pose. Missing textures render as a pink checker.
The bar above the viewport shows the file name, a counter of your changes, the export buttons and an X to close the file. Opening another file or closing with unsaved changes asks first.
## Scene tab
### Model
File name, type (Drawable, Drawable dictionary or Fragment), number of drawables, bones, lights and shaders, and how long the file took to read. Warnings from reading the file show here too.
### Display
| Option | What it does |
| --- | --- |
| **Textured**, **Clay**, **Normals**, **UV checker**, **Vertex colour** | View modes. Clay hides textures to judge the shape, UV checker shows stretching, Vertex colour shows the painted vertex data. |
| **Wireframe overlay** | Same as the viewport button. |
| **Ground grid** | On by default. |
| **Night preview** | Same as the viewport button. |
| **Paint colour** | Only for models with `vehicle_paint` shaders. Preview only: in game the colour comes from the vehicle's paint. |
### Geometry
Every geometry of the current LOD, grouped by drawable, with shader name and index, vertex and triangle count and the bone it sits on. The eye hides or shows a geometry, **Show all** and **Hide all** do it for the whole list, and **Solo** (in `.ydd` files) shows only one drawable. Click a row to select it in the viewport.
### Textures
A grid of every texture the shaders use, with format and size. The dot is green when the texture is fine, amber when you edited it, red when it is missing or could not be read. Click a texture to open the texture window:
- **Color**, **RGB** and **Alpha** channel views.
- **Used by**: which shader slots point at it.
- **File**: where it was loaded from.
- **PNG** and **DDS for CodeWalker** downloads.
- **Replace with image** (PNG, JPG or WebP) and **Revert changes**.
## Materials tab
Click a shader (or a mesh in the viewport) to expand it. Each shader row shows its index, name, `.sps` file, render bucket (opaque, alpha, decal, cutout and so on) and how many meshes use it. Pills tell you the alpha mode, glass, emissive (or emissive at night) and vehicle paint.
Inside you get every parameter:
- **Texture slots**: the texture name in a text field with suggestions from the loaded textures. Type another name to point the slot at a different texture. The image button replaces the texture's pixels with a PNG, JPG or WebP (the name stays the same). A download button appears once the texture is edited. The line below says the format and size, or `file not dropped`, or `unknown texture, add it to a .ytd`.
- **Vectors**: a single number for scalar values, with an **xyzw** button to edit all four components.
- **Arrays**: listed and kept as they are.
Parameters marked **live** change the preview: the diffuse, normal and spec maps, `bumpiness`, `specularIntensityMult`, `specularFalloffMult` and `emissiveMultiplier`. Every other change is written to the exported XML only. Hover a parameter name for a short hint (for example `specularFalloffMult`: specular tightness, higher is glossier). Each changed value has a reset button, and **Reset shader** undoes all changes of one shader.
**Textures for your .ytd** lists every texture you painted or replaced, with **DDS** and **PNG** downloads and where it belongs: embedded in the model, replace in the `.ytd`, or add to a `.ytd`. New texture names you typed into a slot that have no file show up as `needs a texture`.
The preview is an approximation, not the game's shaders. Check the final look in game.
## Lights tab
Shows the `` block of the model as real lights in the scene. With several drawables that have lights, a **Drawable** selector picks which one you edit.
- **Add light** creates a point light above the model, sized to it.
- Each light row shows its colour, type, bone, intensity and range, with duplicate and delete buttons.
- **Night preview** dims the sky, **Light gizmos** shows or hides the light helpers.
Pick a light in the list or click it in the viewport. Move it with the gizmo (switch between move and rotate with the two buttons in the light's header) or type values.
| Section | Fields |
| --- | --- |
| Light | **Type** (Point, Spot, Capsule), **Colour**, **Intensity**, **Bone**, **Position**, **Direction**, **Tangent**. Spot lights add **Cone inner (deg)** and **Cone outer (deg)**, capsules add **Extent**. |
| On hours (TimeFlags) | 24 buttons, one per hour. **Always** and **Night 20 to 6** presets. |
| Falloff | **Range (m)**, **Falloff exponent**, **Flashiness** |
| Corona | **Size**, **Intensity**, **Z bias** |
| Volume | **Intensity**, **Size scale**, **Outer intensity**, **Outer exponent**, **Outer colour** |
| Shadows | **Blur**, **Near clip** |
| Fade distances | **Light**, **Shadow**, **Specular**, **Volumetric** |
| Advanced | **Flags**, **Light hash**, **Group id**, **Time flags**, **Projected texture**, plus any other fields the file has |
Positions and directions are relative to the bone in `BoneId`, the same as in the file. Light brightness in the viewer is an estimate.
## Paint tab
| Control | What it does | Default |
| --- | --- | --- |
| **Texture** | Which texture you paint on. Diffuse textures are listed first, others are marked `non-diffuse`. When you open the tab the largest diffuse is picked. | |
| **Pick on model** | Click a mesh in the viewport to paint its diffuse texture. | |
| Brush (B ) | Paints the colour. | |
| Eraser (E ) | Paints the original texture back. | |
| Fill (G ) | Flood fill with **Tolerance** (0 to 128). | 24 |
| Eyedropper (I ) | Picks a colour and switches back to the brush. | |
| Colour | Brush colour. | `#e23b3b` |
| **Size** | Brush size in texture pixels, up to half the texture size (max 512). | 48 |
| **Hardness** | Edge softness. | 0.6 |
| **Opacity** | Stroke opacity. | 1 |
| **Mirror X** | Paints the other side of a symmetric model too (3D view only). | Off |
Left drag on the model paints, right drag orbits, middle drag pans, the wheel zooms. **Texture view** shows the flat texture with an optional **UV wireframe**; you can paint there too. Below it: download `.png`, **DDS**, and **Revert to the original texture**.
Keys in the Paint tab: Ctrl + Z undo, Ctrl + Y or Ctrl + Shift + Z redo, [ and ] brush size.
## Output
| Button | File | What is inside |
| --- | --- | --- |
| **Export XML** | Same name as the XML you opened, for example `prop_streetlight_01.ydr.xml` | The original file with only the values you changed rewritten. Everything else stays byte for byte, so diffs stay small. |
| **Package .zip** | `_edited.zip` | The edited XML plus `/.dds` for every texture you painted or replaced. |
| **GLB** | `_.glb`, for example `adder_high.glb` | The current LOD with textures, for Blender or other tools. One way only. |
Exported DDS files keep the texture name and the format family of the original (DXT1, DXT5 or A8R8G8B8) and get a full mip chain. A DXT1 texture you painted with transparency becomes DXT5. When you replace a texture with an image of a different size, the XML export updates the size of embedded textures.
## Getting your edits back into the game
1. Extract **Package .zip** over your CodeWalker export folder, so the XML and the `/` texture folder get replaced.
2. In CodeWalker, use **Import XML** and pick the `.ydr.xml`, `.ydd.xml` or `.yft.xml`. It builds the binary file again.
3. Textures that live in a separate `.ytd` are not part of the model. Open that `.ytd` in CodeWalker or OpenIV and replace the texture with the PNG or DDS of the same name, or use the [Texture Editor](/docs/tools/texture-editor). The Materials tab lists which textures need this.
4. Copy the rebuilt files into your resource's `stream/` folder and restart the resource.
```bash
my_props/
fxmanifest.lua
stream/
prop_my_lamp.ydr
prop_my_lamp.ytd
my_props.ytyp
```
FiveM streams everything in `stream/` automatically. A new prop (not a replacement of a game model) also needs an archetype in a `.ytyp`, loaded from the manifest:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
data_file 'DLC_ITYP_REQUEST' 'stream/my_props.ytyp'
```
The [YTYP Creator](/docs/tools/ytyp-creator) builds that file.
## Tips
- Drop the whole export folder, not single files. That way every texture, including the separate `.ytd` ones, is found in one go.
- Use **Clay** and **UV checker** to spot bad normals and stretched UVs before you blame the texture.
- For lights, turn on **Night preview** and set the hours with **Night 20 to 6** so street lamps do not burn at noon.
- **Solo** in a `.ydd` is the fastest way to check one drawable of a clothing or ped dictionary.
## Common mistakes
- **Only the XML dropped.** Every texture shows as a pink checker. Drop the texture folder on the open model.
- **Edited `.ytd` textures forgotten.** Painting a texture that lives in a separate `.ytd` does not change the model file. Export the DDS or PNG and put it into the `.ytd`.
- **Renamed texture that does not exist.** Typing a new name into a slot only changes the reference. Add a texture with that name to a `.ytd`, or the game draws nothing.
## Limitations
- Reads CodeWalker XML exports only, not binary `.ydr`, `.ydd` or `.yft` files.
- BC7 textures are not supported yet.
- Geometry can not be edited. Skinned meshes are shown in their bind pose.
- The 3D preview and the light brightness are estimates of the in game look.
- Everything runs in your browser and nothing is uploaded.
## Related tools
- [Texture Editor](/docs/tools/texture-editor) for editing the `.ytd` dictionaries that go with the model.
- [YTYP Creator](/docs/tools/ytyp-creator) for the archetype of a new prop.
- [Clothing Designer](/docs/tools/clothing-designer) for painting clothing with layers from binary `.ydd` files.
- [YTD Optimizer](/docs/tools/ytd-optimizer) to shrink texture memory.
- [Objects List](/docs/tools/objects-list) to find game props with pictures and 3D previews.
_Last updated: 2026-09-22_
---
## Weapons Meta Editor
URL: https://fivemad.com/docs/tools/weapons-meta-editor
Edit weapons.meta from the game's default values: damage, fire rate, range, falloff, clip size, recoil and flags, then export the meta files and fxmanifest.
The Weapons Meta Editor starts from the real default `weapons.meta` block of every base game and DLC weapon, lets you change damage, fire rate, range, reload, clip size, accuracy, recoil and flags with an explanation per field, compares everything against the game default, and exports a `weapons.meta`, a `weaponcomponents.meta`, an `fxmanifest.lua` and an optional runtime Lua script.
## What it is for
Weapon balancing on a FiveM server usually means copying a 200 line `- ` block, changing three numbers and hoping nothing else broke. This editor keeps the whole game block for you and only rewrites the fields you touch, so an edited weapon exports as the complete block with your changes in it. You see the default next to every value, derived stats like shots to down a player, and a list of every change you made across all weapons.
Typical jobs: lowering PvP damage on rifles, giving pistols less range, making a sniper semi auto, raising a magazine size, removing recoil shake, or checking what an old weapons.meta from a pack actually changes.
## Quick start
1. Pick a weapon in the list on the left. Use the search box or the **Weapons**, **Vehicle**, **Other** and **Edited** chips.
2. Change values with the slider or type a number. Changed fields turn amber, show a **changed** badge and a **Reset** link, and the game default is always shown next to the field name.
3. For magazine size, go to **Ammo & reload** and edit the clip under **Magazines (weaponcomponents.meta)**.
4. Edit as many weapons as you like. They all end up in one export.
5. On the right, open the **weapons.meta** tab (and **components** if you changed a clip), then download the files and copy the **fxmanifest** tab into your resource.
6. `ensure` the resource in `server.cfg`. Players need to reconnect to pick up the changes.
Your edits are saved in this browser. **Reset everything** in the top bar puts every weapon and clip back to the game defaults after a confirmation.
> [!TIP]
> You can link straight to a weapon with `?w=WEAPON_NAME`, for example `/tools/weapons-meta-editor?w=WEAPON_CARBINERIFLE`.
## The weapon list
The top bar shows the game build the defaults come from (build 3889) and how many weapons and clips you have edited.
| Chip | What it lists |
| --- | --- |
| Weapons | Hand weapons, grouped by weapon group (pistols, SMGs, rifles, MGs, shotguns, snipers, heavy, thrown, melee, stun gun). Custom weapons from an import show up here under **Imported**. |
| Vehicle | Vehicle weapons, grouped by the DLC they came with. |
| Other | Everything else in the game files that is not a hand or vehicle weapon. |
| Edited | Only the weapons that will be exported. The count is on the chip. |
Search matches the weapon name, label, group and DLC. Edited weapons carry an **edited** badge in the list.
## The editor
The header shows the weapon picture, label, internal name and which DLC and file the default comes from. **Reset weapon (N)** puts that one weapon back to default. For a custom imported weapon the button is **Remove** instead.
### Sections
The section chips filter the fields: **All**, **Damage**, **Fire**, **Range**, **Ammo & reload**, **Accuracy & recoil**, **Movement & misc**, and **Changed N**, which shows only the fields you changed on this weapon.
Melee and special weapons hide gun only fields like recoil and falloff. **Show every field** turns them on, and also adds an **Other fields** panel with every other single value field in the weapon's block (no descriptions there, change with care). Fields that identify the weapon (`Name`, `Model`, `Audio`, `Slot`, `Group`, `WheelSlot`, `StatName`, `HumanNameHash`, `PickupHash`, `MPPickupHash`) are never editable.
Numbers keep the game's style: a field that is a float in the game file stays a float with six decimals, an integer stays an integer. Sliders widen automatically when the default or your value is past the usual range.
### Damage
| Field | What it does |
| --- | --- |
| `Damage` | Base damage per bullet, or per hit for melee. A player goes down at 100 points of damage without armour. |
| `DamageType` | `BULLET`, `EXPLOSIVE`, `ELECTRIC`, `MELEE` and so on. |
| `NetworkPlayerDamageModifier` | Multiplier on Damage when the target is another player. The main PvP damage knob on a FiveM server. |
| `NetworkHeadShotPlayerDamageModifier` | Headshot multiplier against players. |
| `NetworkHitLimbsDamageModifier` | Arm and leg hit multiplier against players. |
| `NetworkPedDamageModifier` | Multiplier when a player hits an NPC in a network session. |
| `HeadShotDamageModifierPlayer`, `MaxHeadShotDistancePlayer` | Headshot multiplier against peds and the distance past which headshots count as body shots. |
| `HeadShotDamageModifierAI` | NPC headshot multiplier. The game default of 1000 makes NPC headshots near instant kills. |
| `HitLimbsDamageModifier`, `LightlyArmouredDamageModifier`, `VehicleDamageModifier` | Limb, light armour and vehicle damage multipliers. |
| `ArmouredVehicleGlassDamageOverride` | Damage to bulletproof glass per hit. -1 uses the per group value. |
| `MeleeDamageMultiplier` | Pistol whip or rifle butt damage. -1 keeps the default. |
| `Penetration` | How well bullets go through thin materials. |
| `Force`, `ForceHitPed`, `ForceHitVehicle`, `ForceHitFlyingHeli`, `FragImpulse`, `KillshotImpulseScale` | Physics push on objects, peds, vehicles, helicopters and breakables. |
| `KnockdownCount` | Hits needed to knock a ped over. -1 disables it. |
| `DamageTime` | Duration of damage over time effects, like the stun gun. |
### Fire
| Field | What it does |
| --- | --- |
| `FireType` | `INSTANT_HIT` for hitscan bullets, `PROJECTILE` for rockets and grenades, plus `MELEE`, `DELAYED_HIT`, `VOLUMETRIC_PARTICLE`, `NONE`. |
| `TimeBetweenShots` | Minimum time between shots in seconds. Lower fires faster. |
| `AlternateWaitTime` | Wait before the alternate fire (for example the double barrel's second shell). -1 is not used. |
| `BulletsInBatch`, `BatchSpread` | Pellets per shot and their spread. Each pellet deals the full Damage. |
| `Speed` | Bullet speed. Mostly affects tracers for hitscan weapons. |
| `SpinUpTime`, `SpinTime`, `SpinDownTime` | Minigun barrel timing. |
### Range
| Field | What it does |
| --- | --- |
| `WeaponRange` | Maximum distance a bullet can hit anything. |
| `LockOnRange` | Lock on distance (aim assist, homing launchers). |
| `DamageFallOffRangeMin` | Full damage up to this distance. |
| `DamageFallOffRangeMax` | Distance where damage reaches its lowest value. |
| `DamageFallOffModifier` | Damage multiplier at and past the max falloff range. 1.0 means no falloff. |
| `AiSoundRange` | How far NPCs hear the shot. -1 uses the group default. |
### Ammo and reload
| Field | What it does |
| --- | --- |
| `ClipSize` | Rounds per magazine, but only for weapons without a default clip component. |
| `AmmoInfo` | Ammo type the weapon uses and shares, picked from every ammo type in the game. |
| `ReloadTimeMP`, `ReloadTimeSP` | Reload time online and in single player. -1 lets the reload animation decide. |
| `AnimReloadRate` | Reload animation speed. Above 1.0 reloads faster. |
| `VehicleReloadTime` | Reload time when shooting from a vehicle. |
| `AmmoDiminishingRate` | Ammo drain for things like the jerry can and fire extinguisher. |
Under the fields, **Magazines (weaponcomponents.meta)** lists every clip component the weapon can attach, marks the default clip and shows each default size. Change a number there to change the real magazine size.
### Accuracy and recoil
`AccuracySpread`, `AccurateModeAccuracyModifier`, `RunAndGunAccuracyModifier`, `RunAndGunAccuracyMinOverride`, `RecoilAccuracyMax`, `RecoilErrorTime`, `RecoilRecoveryRate`, `RecoilShakeAmplitude` (camera shake strength), `RecoilShakeHash` and `RecoilShakeHashFirstPerson` (picked from the shakes the game uses), `MinTimeBetweenRecoilShakes` in ms, and `BulletDirectionOffsetInDegrees`.
### Movement and misc
`CameraFov`, `ZoomFactorForAccurateMode`, `FirstPersonScopeFov`, `ExpandPedCapsuleRadius`, and the weapon wheel bars `HudDamage`, `HudSpeed`, `HudCapacity`, `HudAccuracy` and `HudRange` (display only).
**WeaponFlags** also lives here. Current flags show as chips: click one to remove it. Flags you removed from the default stay visible crossed out, click to add them back. **Add a flag...** lists every flag the game uses, with a short description for the common ones:
| Flag | What it does |
| --- | --- |
| `Automatic` | Keeps firing while the trigger is held. |
| `OnlyFireOneShotPerTriggerPress` | Semi auto: one shot per press. |
| `Silenced` | Silent weapon, no gunshot events for AI. |
| `ArmourPenetrating` | Ignores body armour. |
| `IgnoreHelmets` | Headshots ignore helmets. |
| `NonLethal` | Does not kill (stun gun style). |
| `FirstPersonScope` | Scope overlay in first person. |
| `HiddenFromWeaponWheel` | Not shown in the weapon wheel. |
## Derived stats
The **Derived stats** panel shows estimates worked out from the meta values, with the old value under a tile when you changed it.
| Tile | Meaning |
| --- | --- |
| Damage per shot | Damage, times the pellet count for shotguns. |
| Fire rate | Rounds per minute. For semi auto weapons it is a cap, you cannot click faster. |
| Burst DPS | Every bullet hitting, no falloff, no armour. |
| Empty a clip | Time to fire the whole default magazine. |
| Reload | `ReloadTimeMP`, or "animation" when it is -1. With a real reload time you also get DPS including reloads. |
| Shots to down a player | Body shots with no armour, using `NetworkPlayerDamageModifier`, plus the headshot count. |
| Full damage to / Max range | Falloff start, the damage left at the falloff max, and `WeaponRange`. |
For guns a falloff chart shows damage over distance for the current values against the default. Melee weapons get **Damage per hit**, **Hits to down a player** and **Range** instead.
These numbers ignore scripts that change damage modifiers, armour, limb hits and animation timing, so treat them as a comparison tool, not the final truth.
## Importing an existing weapons.meta
Click **Import weapons.meta**, paste the file or use **Open file**, then **Parse**. You can paste a whole file or a single `
- ` block, and a `weaponcomponents.meta` works too (clip sizes are picked up).
- Base game weapons are compared against their defaults, so you see exactly what the file changes. Their block becomes the new base for that weapon.
- Weapons that are not in the base game (add-on guns) are added as custom weapons under **Imported** and exported as they are.
- The result line tells you how many weapons were loaded, how many differ from the game default, how many are not in the base game, and how many clip components were read.
## Output
The right column has five tabs.
| Tab | What you get |
| --- | --- |
| weapons.meta | One file with only the weapons you changed, each as its complete block. |
| components | `weaponcomponents.meta` with the clip components you changed. |
| fxmanifest | A ready `fxmanifest.lua` for the files you have. |
| Lua | A client script for the runtime alternative (damage and recoil shake only). |
| Changes | Every edited weapon and clip, field by field, default next to the new value, with a reset per field or per weapon. |
### weapons.meta
Weapons are placed in the same slot of the `
` list they sit in inside the game file:
```xml title="weapons.meta"
-
-
-
WEAPON_PISTOL
W_PI_PISTOL
-
-
fivemad weapons
```
### weaponcomponents.meta
```xml title="weaponcomponents.meta"
-
COMPONENT_PISTOL_CLIP_01
w_pi_pistol_mag1
fivemad weapon components
```
### fxmanifest.lua
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'weapons.meta',
'weaponcomponents.meta'
}
data_file 'WEAPONINFO_FILE_PATCH' 'weapons.meta'
data_file 'WEAPONCOMPONENTSINFO_FILE' 'weaponcomponents.meta'
```
Put the meta files next to this `fxmanifest.lua` in one resource folder. `WEAPONINFO_FILE_PATCH` is the type commonly used to override base game weapons. Items replace the game's weapon by ``, which is why the export always ships the whole block.
### Lua (runtime alternative)
Damage and recoil shake can also be changed from a client script, without a meta file. The **Lua** tab writes that script for your `Damage` and `RecoilShakeAmplitude` changes, and lists the weapons whose other changes still need the meta file:
```lua title="client.lua"
-- client.lua (client side, runs for every player)
-- Damage is worked out on the shooter's client, so every client needs this, not just the server.
-- SetWeaponDamageModifier (game native 0x4757F00BC6323CFE) multiplies the weapon's base damage.
-- It is not reset when the resource stops, the value stays until something sets it again.
local damageModifiers = {
[`WEAPON_PISTOL`] = 1.1538, -- Damage 26 -> 30
}
-- SetWeaponRecoilShakeAmplitude is a FiveM native, it writes RecoilShakeAmplitude directly.
local recoilAmplitude = {
-- no RecoilShakeAmplitude changes
}
CreateThread(function()
for weapon, modifier in pairs(damageModifiers) do
SetWeaponDamageModifier(weapon, modifier)
end
for weapon, amplitude in pairs(recoilAmplitude) do
SetWeaponRecoilShakeAmplitude(weapon, amplitude)
end
end)
```
- `SetWeaponDamageModifier(weaponHash, multiplier)` multiplies the weapon's base damage on the client that runs it. It does not need to run every frame and it is not reset when the resource stops.
- `SetWeaponRecoilShakeAmplitude(weaponHash, amplitude)` is a FiveM native that sets RecoilShakeAmplitude directly. `GetWeaponDamageModifier` and `GetWeaponRecoilShakeAmplitude` read them back.
- `SetPlayerWeaponDamageModifier(player, modifier)` and `SetPlayerWeaponDefenseModifier(player, modifier)` scale damage per player for every weapon, useful for buffs, safe zones or jobs.
Damage is worked out on the shooter's client, so a runtime modifier has to run on every client. Use natives when you want to tune damage live or per situation. Use weapons.meta for everything else (fire rate, range, falloff, reload, accuracy, flags) and for values that should be the same for everyone from the moment they join.
## Common mistakes
- **Changing `ClipSize` in weapons.meta for a normal gun.** Most guns have a default clip component, and the game uses its `ClipSize` instead. Edit the magazine under **Ammo & reload** and ship the `weaponcomponents.meta`.
- **Shipping only the changed lines.** A partial `- ` breaks the weapon. Ship the whole block, which the export does for you.
- **Two resources editing the same weapon.** The one loaded last wins. Keep all weapon edits in one resource.
- **Expecting a resource restart to be enough.** Players have to reconnect to pick up meta changes.
- **Running the runtime Lua on the server.** It is client side and has to run on every client.
> [!NOTE]
> Nobody outside Rockstar has an official description of every CWeaponInfo field. The one line explanations are the community's best understanding plus what the values in the game files show. Test big changes in game.
## Limitations
Only single value fields can be edited. Nested blocks such as `OverrideForces`, attach points and the explosion table are kept as they are (an import that changes them still exports them). The derived stats are estimates. Everything runs in your browser and nothing is uploaded.
## Related tools
- [Weapon Stats](/docs/tools/weapon-stats)
- [fxmanifest.lua Generator](/docs/tools/fxmanifest-generator)
- [Damage Events](/docs/tools/damage-events)
- [Hash Calculator](/docs/tools/hash-calculator)
_Last updated: 2026-09-22_
---
## YTYP Creator
URL: https://fivemad.com/docs/tools/ytyp-creator
Build a .ytyp archetype file for custom props: drop CodeWalker model XML, get measured bounds, pick flags and lodDist, then convert and stream it.
The YTYP Creator writes the `CMapTypes` XML that declares your custom props to the game (one `CBaseArchetypeDef` or `CTimeArchetypeDef` per model). Drop the CodeWalker XML exports of your `.ydr`, `.yft` or `.ydd` models and it measures the bounds, fills in the texture dictionary and checks everything against the 33,071 game prop archetypes. It is for map makers and anyone who streams their own props.
## What it is for
A model in `stream/` is not a spawnable prop on its own. The game needs an archetype for it: a name, a draw distance, a bounding box and sphere for culling, the texture and physics dictionaries and a set of flags. That archetype lives in a `.ytyp`. Without one you get the classic problems: `CreateObject` does nothing, `IsModelValid` returns false, the prop is invisible in your ymap, or it vanishes at the edges of the screen because the bounds are wrong.
Typical uses:
- You exported a prop from Blender (Sollumz) or ZModeler and need a ytyp for it.
- You have a pack of 200 props and do not want to type 200 bounding boxes by hand.
- You want to copy the settings of a game prop (a door, a bin, a bench) onto your own model.
- You got a ytyp from someone else and want to check it, rename things or fix flags.
## Quick start
1. In CodeWalker's RPF Explorer, right click your model (`.ydr`, `.yft` or `.ydd`) and choose **Export XML**. Do the same for its `.ytd`.
2. Set **Name** in the **Ytyp** panel. This is also the file name: `stream/
.ytyp`.
3. In **Add archetypes**, stay on the **Files** tab, pick **Flags for new archetypes** and **lodDist for new archetypes (m)**, then drop the `.ydr.xml` files together with the `.ytd.xml` files.
4. Each model becomes one row in **Archetypes**. Open a row with the arrow button (**Edit all fields**) to see the notes and every field.
5. Fix whatever the issue list in the right column points out. Click an issue to jump to the archetype it is about.
6. In **Export**, download `.ytyp.xml` from the **XML** tab.
7. Convert it to a binary `.ytyp` in CodeWalker (steps in the **Convert** tab), put it in `stream/` and add the `data_file` line from the **Resource** tab.
8. `ensure` the resource and reconnect.
## Adding archetypes
The **Add archetypes** panel has three tabs.
### Files
Drop zone for CodeWalker model exports. Accepted files:
| File | What happens |
|---|---|
| `.ydr.xml` | One archetype, `assetType` `ASSET_TYPE_DRAWABLE`. |
| `.yft.xml` | One archetype, `assetType` `ASSET_TYPE_FRAGMENT`. |
| `.ydd.xml` | One archetype per drawable in the dictionary, `assetType` `ASSET_TYPE_DRAWABLEDICTIONARY`, `drawableDictionary` set to the `.ydd` name. |
| `.ytd.xml` | Not an archetype. The texture names are read so `textureDictionary` can be matched and checked. |
| `.ytyp.xml` | Opened for editing. It replaces the current list (Undo brings the old one back). |
Binary files (`.ydr`, `.yft`, `.ydd`, `.ytd`, `.ytyp` without `.xml`) are refused with a message telling you to export them to XML first. Everything is read in the browser, nothing is uploaded.
The archetype name is the file name, lowercased, without the extension. `my_bench.ydr.xml` becomes `my_bench`. For a `.ydd`, each entry uses its own drawable name.
**Bounds.** The bounding box is filled in from the model, in model space with GTA axes (Z up), the same way game archetypes store them. The bounding sphere follows the rule every game prop follows: centre of the box, radius half the box diagonal. Open the row to read a note on where the bounds came from. If the model export has no geometry and no stored bounds, the box stays at zero and you type it yourself.
**textureDictionary.** Drop the model's `.ytd.xml` together with the model and the field is set to that dictionary. HD companions (`name+hi.ytd`, `name+hidr.ytd`) count as the base `name.ytd`. If you drop exactly one `.ytd`, every model without a better match uses it. If no dropped `.ytd` fits and the model needs outside textures, the field is set to the model name and a note tells you to rename it if your textures live elsewhere. Models with only embedded textures get an empty field. Textures the model needs that are missing from the chosen `.ytd` are listed in the notes, because those would render white.
**physicsDictionary.** Models with embedded collision get the archetype name here (what Sollumz writes too). Models without collision, and `.ydd` entries, leave it empty.
The two fields under the drop zone set the defaults for dropped models and for **Add empty**:
| Field | What it does | Default |
|---|---|---|
| Flags for new archetypes | Flag preset given to new rows. | `32` (Static) |
| lodDist for new archetypes (m) | Draw distance given to new rows. | `100` |
Both are remembered in your browser. When `.ytd` files have been dropped, a line lists the texture dictionaries seen with a **forget** link to clear them.
### Game prop
Search the 33,071 game prop archetypes by name (type at least 2 characters, underscores and spaces are the same). Each result shows a picture, the source ytyp, lod, flags and the size in metres. **Add** copies all the values.
By default the copy is named `_custom` with a note telling you to rename it to your model and point `textureDictionary` at your `.ytd`. Tick **Keep the game name** only when you really want to re-declare the game prop itself, for example to make it spawnable everywhere.
### Import
Open a `.ytyp.xml` (button **Open .ytyp.xml**) or paste the XML and press **Load pasted XML**. It replaces the list. What is kept:
- `CBaseArchetypeDef` and `CTimeArchetypeDef` items become editable rows.
- Interior (`CMloArchetypeDef`) archetypes and items of unknown types are kept as raw XML and written back unchanged. The Ytyp panel shows how many.
- Archetype `extensions` (particles, audio, spawn points, doors) are kept as raw XML on their row.
- Non empty root blocks (`extensions`, `dependencies`, `compositeEntityTypes`) are kept as they are.
- A bounding sphere that does not follow the box rule is kept exactly, and "Sphere from box" is turned off for that row.
- Unknown fields inside an archetype are dropped, with a warning naming them.
## Archetype fields
Each row shows the name, the asset type (`ydr`, `yft`, `ydd`), the size in metres, and quick inputs for **lodDist**, **txd** and **flags**. The buttons on the right are **Edit all fields**, **Duplicate** (adds `_copy` right below) and **Delete**. The Ytyp panel has **Undo** (last add, delete or import, up to 40 steps) and **Clear** (removes every archetype, undo works). The whole document is saved in your browser, so a reload keeps your work.
The expanded row has these fields:
| Field | Meaning | Default |
|---|---|---|
| Type | `CBaseArchetypeDef` or `CTimeArchetypeDef`. Time archetypes only show during the hours you tick. | `CBaseArchetypeDef` |
| `assetType` | `ASSET_TYPE_DRAWABLE` (.ydr), `ASSET_TYPE_FRAGMENT` (.yft), `ASSET_TYPE_DRAWABLEDICTIONARY` (.ydd), `ASSET_TYPE_ASSETLESS` (no model, MLOs), `ASSET_TYPE_UNINITIALIZED`. | from the file |
| `assetName` | Leave empty and the name is written again, like every game prop. | empty |
| `drawableDictionary` | Only for `.ydd` models: the `.ydd` name without extension. | empty |
| `textureDictionary` | The `.ytd` with the textures, without extension. | see above |
| `physicsDictionary` | Game props point at a shared physics dictionary. For a custom model with its collision inside, use the archetype name or leave it empty. | see above |
| `clipDictionary` | The `.ycd` with the animation or UV animation. Needs flag 512 or 1024. | empty |
| `specialAttribute` | Marks doors, bushes, traffic lights and a few others. | `0` |
| lodDist (m) | How far away the model is drawn. A ymap entity can override it (`-1` there means use this value). | `100` |
| hdTextureDist (m) | Where `+hi.ytd` / `+hidr.ytd` HD textures load. Keep it at or below lodDist. | `5` |
| bbMin / bbMax | The box used for culling and returned by `GetModelDimensions`. 6 decimals. | measured |
| Sphere from box | On: `bsCentre` and `bsRadius` are calculated from the box. Off: type them yourself. | on |
| flags | Number input, preset dropdown and one checkbox per bit. | `32` |
| timeFlags | Only for time archetypes. | `32505919` |
### specialAttribute values
`0` None, `3` Traffic light, `4` Unknown 4, `5` Garage door, `6` MLO water level, `7` Normal door, `8` Sliding door, `9` Barrier door, `10` Sliding door vertical, `11` Noisy bush, `12` Rail crossing barrier, `13` Noisy deformable bush, `14` Single axis rotation, `15` Dynamic cover bound, `16` Rumble on vehicle collision, `17` Rail crossing light, `30` Clock, `32` Street light. `1`, `2` (ladder) and `31` (tree) are listed as deprecated.
### Flag presets
| Preset | Value | Used for |
|---|---|---|
| Static | `32` | Fixed prop that never moves. Simple and safe for custom props. |
| Vanilla static prop | `549584928` | Static, dynamic, no AI or player cover, ambient scale (`prop_wait_bench_01`). |
| Vanilla physics prop | `549584896` | Dynamic, no cover, ambient scale. Bins, cones, crates. |
| Dynamic + ambient scale | `537001984` | The most common non zero value in game ytyps. |
| Ambient scale only | `536870912` | Interior furniture and fixed decoration. |
| No flags | `0` | The most common value, mostly map furniture. |
| No shadows | `8192` | LOD models, emissive and light props. |
| Door | `604110848` | Door physics, dynamic, ambient scale. Pair with specialAttribute `7`. |
| UV animated | `1024` | Animated UVs from the clipDictionary (screens, water, scrolling signs). |
The bit checkboxes cover all 32 bits with CodeWalker's names, for example `2` Don't fade, `4` Draw last, `32` Static, `512` Has anim (YCD), `1024` UV anims (YCD), `2048` Shadow only, `8192` Don't cast shadows, `16384` Cast texture shadows, `65536` Double-sided rendering, `131072` Dynamic, `524288` Auto start anim, `4194304` No AI cover, `8388608` No player cover, `67108864` Enable door physics, `536870912` Use ambient scale.
### Time archetypes
Switch **Type** to `CTimeArchetypeDef` and a 24 hour grid appears. Bit 0 is 00:00 to 01:00, bit 23 is 23:00 to 24:00 (game time). Presets: **Night 19:00 to 06:00** (`33030207`), **Night 20:00 to 06:00** (`32505919`), **Day 06:00 to 20:00** (`1048512`), **Always** (`16777215`). The checkbox **16777216 Allow vanish whilst viewed** lets the model switch while it is on screen.
## Checks
The right column lists problems as you edit. Errors and warnings mark the row number in amber.
| Severity | Check |
|---|---|
| Error | Ytyp has no name; archetype without a name; duplicate archetype names; empty or invalid numbers; lodDist of 0 or less; negative hdTextureDist; bbMin larger than bbMax; zero size box (gets culled, invisible); file extension in a name or dictionary (`my_prop.ytd`); time archetype with no hours ticked. |
| Warning | Ytyp name with capitals or symbols (shows the sanitised name); ytyp name equal to a game ytyp; archetype name with characters other than lowercase a-z, 0-9, `_` and `-`; names over 63 characters; same name as a game prop; lodDist under 15 m; hdTextureDist larger than lodDist; manual sphere smaller than the box; no textureDictionary while the model needs outside textures; drawableDictionary and assetType disagree; assetName differs from name on a `.ydr`; animation flag without clipDictionary. |
| Info | textureDictionary not among the dropped `.ytd` files (and not a game txd); clipDictionary without an animation flag; door specialAttribute without flag `67108864`; embedded textures; lodDist above 1500 m; more than 3000 archetypes in one ytyp. |
Name clash checks run once the game archetype list has loaded.
## Output
### The XML
The **XML** tab shows `.ytyp.xml` in the same layout CodeWalker exports. For a bench prop it looks like this:
```xml title="my_props.ytyp.xml"
-
my_bench
my_bench
my_bench
ASSET_TYPE_DRAWABLE
my_bench
my_props
```
If you type a hash instead of a name (`0x1234ABCD` or a plain number), it is written as `hash_1234ABCD`, the way CodeWalker writes unknown names. Time archetypes get a ` ` line after ` `.
### Converting to binary
Browsers cannot write the binary ytyp format, so CodeWalker does the last step (also shown in the **Convert** tab):
1. Download `.ytyp.xml` next to your models. Keep the double extension, CodeWalker reads the file type from it.
2. Open CodeWalker's **RPF Explorer**, then **File, Open Folder** on that folder.
3. Turn on **Edit mode**, then **Edit, Import XML** (or drag the file into the window).
4. CodeWalker writes `.ytyp`. Put it in `stream/` and keep the `.xml` out of it.
5. Add the `data_file` line, `ensure` the resource and reconnect.
### Resource layout
The **Resource** tab builds a folder layout from your archetypes (model files by asset type, each `.ytd`, each `.ycd`) and this manifest:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
name 'my_props'
description 'Custom props declared in my_props.ytyp'
-- Everything in stream/ (.ydr, .yft, .ydd, .ytd, .ytyp) is streamed on its own.
-- This line registers the archetypes when the resource starts, so the models
-- are valid everywhere (CreateObject, ymaps, map editors), not only near a ymap
-- that happens to depend on the ytyp.
data_file 'DLC_ITYP_REQUEST' 'stream/my_props.ytyp'
```
```text
my_props/
├── fxmanifest.lua
└── stream/
├── my_props.ytyp
├── my_bench.ydr
└── my_bench.ytd
```
```cfg title="server.cfg"
ensure my_props
```
`DLC_ITYP_REQUEST` is the resource version of the game's `PERMANENT_ITYP_FILE`: the archetypes stay registered while the resource runs. Without it a ytyp only loads when a ymap that depends on it is loaded nearby.
## Examples
Check the archetype is registered and spawn the prop:
```lua title="client.lua"
local model = `my_bench`
RegisterCommand('bench', function()
if not IsModelValid(model) then
print('my_bench is not registered, check the data_file line and the ytyp name')
return
end
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local ped = PlayerPedId()
local pos = GetOffsetFromEntityInWorldCoords(ped, 0.0, 2.0, 0.0)
local obj = CreateObject(model, pos.x, pos.y, pos.z, true, false, false)
PlaceObjectOnGroundProperly(obj)
FreezeEntityPosition(obj, true)
SetModelAsNoLongerNeeded(model)
end)
```
`GetModelDimensions(model)` returns the `bbMin` and `bbMax` you set here, which is a quick way to confirm the right ytyp is loaded.
## Common mistakes
- **Prop is invisible.** The ytyp is still XML, the `data_file` line is missing, or the archetype name does not match the model file name. For a `.ydr` the game finds the model by the archetype name, not by assetName.
- **White or purple textures.** `textureDictionary` does not match the `.ytd` name, or the `.ytd` is not streamed.
- **Prop disappears at screen edges.** Bounds are too small. Drop the model XML again to measure them.
- **Same name as a game prop.** Your archetype replaces or duplicates the game one. Give custom props their own prefix.
- **Ytyp named like a game ytyp.** Two files with one name fight each other. Pick a unique name for the ytyp too.
- **Changes do not show.** Reconnect. Archetypes are registered when the resource starts.
- **Animated prop does not animate.** Set `clipDictionary` and flag `512` (skeletal) or `1024` (UV). Add `524288` Auto start anim to start the clip on spawn.
> [!TIP]
> Keep the model file, the archetype name and the name you spawn identical and lowercase. Almost every "prop does not load" report comes down to one of the three being different.
## Limitations
- It writes XML only. The binary `.ytyp` comes from CodeWalker.
- Interiors (MLO archetypes) are passed through untouched, not edited. Use CodeWalker for those.
- Archetype extensions are kept from imports but cannot be created or edited here.
- Bounds come from the high detail mesh. If your lower LODs are bigger than the high LOD, widen the box by hand.
- Everything runs in your browser. Model files are read locally, nothing is uploaded. Your list is saved in browser storage.
## Related tools
- [YMAP Builder](/docs/tools/ymap-builder) to place your new props in the world
- [Objects List](/docs/tools/objects-list) to look up game props and their sizes
- [Texture Editor](/docs/tools/texture-editor) for the `.ytd`
- [YTD Optimizer](/docs/tools/ytd-optimizer) to shrink oversized texture dictionaries
- [fxmanifest Generator](/docs/tools/fxmanifest-generator)
- [joaat Hash Calculator](/docs/tools/hash-calculator)
_Last updated: 2026-09-22_
---
## Texture Editor
URL: https://fivemad.com/docs/tools/texture-editor
How to open a .ytd or a CodeWalker .ytd.xml export, preview and replace textures, pick the compression and mips, and export a new .ytd for your stream folder.
The Texture Editor opens a texture dictionary (`.ytd`) and lets you preview, replace, rename, add and delete its textures. PNG, JPG and WebP images are resized to a power of two and compressed right in the page, with the format and mip chain you pick, and you export a new `.ytd` or a CodeWalker XML + DDS zip. It is for anyone who needs to swap a logo, fix a broken texture or cut the memory of a dictionary without OpenIV.
## What it is for
- **Replacing a texture.** New livery, new sign, new shop logo: drop a PNG on the texture and export.
- **Fixing problem textures.** Odd sizes, missing mips, uncompressed 4 MB normal maps, DXT5 with no alpha. Each texture gets a list of issues and the fix is one click.
- **Building a dictionary from scratch.** Drop loose PNG or DDS files and export them as a new `.ytd`.
- **Checking memory.** The toolbar shows the memory of the whole dictionary, each tile its own.
Everything is read and written in your browser. Nothing is uploaded.
## Quick start
1. Open the [tool](/tools/texture-editor).
2. Drop the `.ytd` from your resource's `stream` folder on the page, or use **Choose files** or **Choose folder**.
3. Click a texture tile. The big preview and the inspector below it show it.
4. Drop a PNG, JPG, WebP or DDS on the tile or on the preview, or press **Replace image**.
5. Check the result in the preview (it shows the compressed version, so what you see is what the game gets).
6. Press **Export .ytd** and put the file back into `stream/` with the exact same name.
## Opening files
| What you drop | What happens |
| --- | --- |
| One or more `.ytd` files | The first one opens. With several, a selector (**N dictionaries in this drop**) switches between them. |
| A folder | Searched for `.ytd` files and CodeWalker exports. |
| `name.ytd.xml` with its DDS folder | Opens the CodeWalker export. Drop the XML and the folder together, or pick the parent folder. |
| Loose DDS, PNG, JPG or WebP files | Start a new dictionary named after the folder (or `my_textures`). |
| Images or DDS while a dictionary is open | Added as new textures. A file with the same name as an existing texture replaces it. |
**Start empty** on the first screen opens an empty dictionary called `my_textures`.
Game files inside an `.rpf` have to be extracted first with CodeWalker or OpenIV. A `.ytd` that is encrypted, damaged or from GTA V Enhanced (gen9) is rejected with a message; FiveM uses the legacy format.
> [!TIP]
> Vehicles usually have two dictionaries: `name.ytd` and `name+hi.ytd` (the close up versions). Drop both and switch between them with the selector. Clothing has one `.ytd` per variation, like `jbib_diff_000_a_uni.ytd`.
## Toolbar
| Control | What it does |
| --- | --- |
| **Dictionary** | The dictionary name, used for the exported file names. |
| **Used for** | **Prop**, **Vehicle**, **Clothing / ped** or **Map / MLO**. Guessed from the name. Changes the size warnings: 2048 px is the soft limit, 4096 for maps and MLOs. |
| **Memory** | Total texture memory of the dictionary and the texture count. |
| **Open** | Open another dictionary folder. |
| **Add texture** | Add DDS, PNG, JPG or WebP files. |
| **XML + DDS zip** | Export for CodeWalker's Import XML. |
| **Export .ytd** | Export a new `.ytd`. |
Under the toolbar a line shows the facts of the opened `.ytd` (resource version, size on disk, memory pages) and after an export the same facts for the new file.
Messages appear below that: dictionary level issues (duplicate names, total size), how many textures have errors, files in the drop that are not part of the dictionary (with an **Add them** button), and **Undo** after a delete. Deleting can be undone until the next delete.
## Texture grid
**Filter textures** searches names and usages. Sort by **File order**, **Name**, **Memory** or **Pixels**.
Each tile shows a thumbnail, the name, size and format, the usage and the memory. A red or amber badge counts the errors and warnings (hover it to read them). Edited tiles show their state in green: **Replaced**, **Added**, **Re-encoded** or **Mips rebuilt**. A tile without a DDS says **No DDS**. Drop an image on any tile to replace that texture.
## Preview
| Control | What it does |
| --- | --- |
| **RGB** | Colour, alpha ignored. |
| **RGBA** | Colour over the backdrop using alpha. |
| **R**, **G**, **B**, **A** | Single channels. **A** is the fastest way to check a cutout or decal mask. |
| Backdrop | Checker, black, grey or white, used by the RGBA view. |
| Zoom | Mouse wheel, the zoom buttons, the percentage (click for 1:1) and fit to view. |
| Mip level | Shows each mip, for example `Mip 2: 256x256`, when the texture has more than one. |
You can drop an image on the preview to replace the selected texture.
## Inspector
The top row has the **Name** (rename it, two textures can not share a name), the **Usage** (DIFFUSE, NORMAL, SPECULAR, DETAIL, EMISSIVE, TINTPALETTE, DEFAULT, UNKNOWN), **Revert** (back to the file you opened) and **Delete**.
The facts: size, format, mips (for example `9 of 9`), memory, alpha (opaque, cutout, soft), flags, source file and encode time. Below them the issue list for this texture.
### Issues it checks
- Name has spaces.
- Size is not a power of two.
- Bigger than 4096 (error) or bigger than the limit for the **Used for** type (warning).
- Fewer mip levels than the game wants.
- Large uncompressed textures.
- Normal maps in DXT1 or ATI2 (notes), colour maps in ATI1 or ATI2 (warning).
- DXT5 with fully opaque alpha (DXT1 would halve the memory).
- Soft alpha stored as DXT1 (it becomes on or off).
- A DDS missing, truncated or in an unknown format.
- For XML exports: when the XML and the DDS file disagree on size, mips or format (the DDS wins).
Dictionary wide it warns about duplicate names and the total size: a note above 8 MB, a warning above 16 MiB (FXServer prints a memory warning) and an error above 48 MiB (FXServer calls the file oversized).
### Actions
- **Replace image** picks a new file for the selected texture.
- **Re-encode as ...** encodes the texture again with the settings below (for example to turn DXT5 into DXT1 or downsize it).
- **Build missing mips** appears when the texture has fewer mips than the game wants. The full size level stays exactly as it was.
- **DDS** and **PNG** download the selected texture.
### Encode settings
These apply when you replace, add or re-encode a texture.
| Setting | Options | Default |
| --- | --- | --- |
| **Format** | **Keep**, DXT1 (BC1), DXT5 (BC3), ATI2 (BC5), ATI1 (BC4), A8R8G8B8 | Keep |
| **Size** | **Same**, **Nearest power of two**, 4096, 2048, 1024, 512, 256, 128, 64 | Same |
| **Fit** | **Stretch**, **Fit (pad)** (pads with transparency), **Crop (fill)** | Stretch |
| **Max size** | 4096, 2048, 1024, 512, 256 | 2048 |
| **Mips** | **Game (to 4 px)**, **Full (to 1 px)**, **None** | Game |
| **Mip filter** | Kaiser, Box | Kaiser |
| **Quality** | High, Fast | High |
**Will cost** shows the memory and the size the texture will have with these settings.
How the settings play together:
- **Keep** reuses the format of the texture you replace. When that format can not be written (for example DXT3 or BC7), it picks DXT5 for normal maps and textures with soft alpha, DXT1 for the rest.
- **Same** keeps the size of the texture you replace, so UVs and the rest of the dictionary stay as they were. For brand new textures it falls back to the nearest power of two.
- The result is always a power of two and never bigger than **Max size**.
- A DDS you drop is used as it is, without re-encoding.
- Re-encoding a texture that is already compressed loses a little detail. Use the original artwork when you have it.
## Which format to pick
| Format | Memory | Use it for |
| --- | --- | --- |
| `DXT1` | 0.5 byte per pixel | Most diffuse, spec and normal maps without alpha. Cutout alpha (fences, leaves) works too, it is on or off. |
| `DXT5` | 1 byte per pixel | Soft alpha: glass, decals, hair, fades. Cleaner normal maps at twice the cost. |
| `ATI2` (BC5) | 1 byte per pixel | Two channel data. Stores only X and Y of a normal, test in game before you ship it. |
| `ATI1` (BC4) | 0.5 byte per pixel | One channel masks. |
| `A8R8G8B8` | 4 bytes per pixel | Only when compression artifacts are not acceptable, like small UI or script render targets. |
BC7 textures are shown and written back untouched. The editor does not encode BC7; re-encoding one turns it into one of the formats above.
## Output
| Button | File | Contents |
| --- | --- | --- |
| **Export .ytd** | `.ytd` | Every texture that has a DDS. Name, usage and flags you did not touch stay as they were. |
| **XML + DDS zip** | `.zip` | `.ytd.xml` and a folder `/` with one DDS per texture, the layout CodeWalker's **Import XML** wants. |
| **DDS**, **PNG** | `.dds`, `.png` | The selected texture only. |
Textures without a DDS are left out of both exports; the message lists them. Wait until every texture has finished encoding before you export, the tool tells you if some are still busy.
## Put it back into the game
1. **Export .ytd** and copy the file into your resource's `stream` folder with the exact same name as the one you replace.
2. Restart the resource (or the server). Players download the new file when they join.
3. Going through CodeWalker instead: extract the **XML + DDS zip**, then **Import XML** in the RPF Explorer and pick the `.ytd.xml`.
```bash
my_car/
fxmanifest.lua
stream/
mycar.yft
mycar.ytd # the rebuilt dictionary
mycar+hi.ytd
```
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
```
FiveM streams everything in `stream/` automatically, so a `.ytd` needs no `files` or `data_file` entry. For clothing, keep the file names your addon pack uses.
> [!IMPORTANT]
> Texture names inside the dictionary are what shaders look up. If you rename a texture, the model will not find it any more unless its shader points at the new name too.
## Texture memory and server warnings
The memory numbers are the GPU size of the texture with its mips, the same number the game streams. A `.ytd` file on disk is smaller because resources are compressed, but in memory it is the full size. FXServer prints a memory warning for every streamed file above 16 MiB of physical memory and calls it oversized above 48 MiB, and players on weaker PCs get textures that pop in late or stay blurry. The usual fixes, biggest win first:
- Drop 4096 textures to 2048 and 2048 ones to 1024 where nobody looks closely. Each step cuts the memory by 4.
- Use DXT1 instead of DXT5 when the alpha is fully opaque (the inspector tells you when that is the case). Half the memory.
- Never ship A8R8G8B8 for normal textures, it is 8x DXT1.
- Keep full mip chains. Without mips the game always keeps the biggest level loaded and the texture shimmers at distance.
- Split a huge dictionary: shared textures in one `.ytd`, or move close up detail into the `+hi` dictionary for vehicles.
For many files at once, use the [YTD Optimizer](/docs/tools/ytd-optimizer).
## Common mistakes
- **Wrong file name.** The exported `.ytd` is named after the **Dictionary** field. Make sure it matches the file you replace, including `+hi`.
- **Soft alpha in DXT1.** Glass or decals turn hard edged. Pick DXT5, or leave **Format** on **Keep** when the original was DXT5.
- **Stretching a wide logo.** Set **Fit** to **Fit (pad)** or **Crop (fill)** when your image has a different aspect ratio than the texture.
- **Exporting while encoding.** Wait for the busy labels on the tiles to finish.
## Limitations
- Does not encode BC7 or DXT3. Those stay untouched unless you re-encode them into another format.
- Reads the legacy `.ytd` format FiveM uses, not GTA V Enhanced files.
- Encrypted files (for example escrow protected assets) can not be opened.
- Everything runs in your browser and nothing is uploaded.
## Related tools
- [YTD Optimizer](/docs/tools/ytd-optimizer) shrinks many `.ytd` files at once.
- [Clothing Designer](/docs/tools/clothing-designer) paints clothing textures on the 3D model.
- [Drawable Studio](/docs/tools/drawable-studio) edits materials and paints textures on CodeWalker model exports.
- [Script Thumbnail Creator](/docs/tools/script-thumbnail-creator) for store images.
_Last updated: 2026-09-22_
---
## Vehicle Sirens Editor
URL: https://fivemad.com/docs/tools/vehicle-sirens
Edit carcols.meta siren settings with a live preview and a 32 step pattern grid, export carcols.meta, and find free or clashing siren ids on your server.
The Vehicle Sirens Editor builds and tunes emergency lighting for GTA V vehicles. You edit every siren light's colour, direction, rotation, flash and 32 step pattern with a live preview on the real vehicle layout, set the timing, and export a `carcols.meta`. The **Siren ID check** tab reads all your carcols and carvariations files and shows which siren ids are taken, free or clashing.
## What it is for
Siren settings are hard to write by hand: each one has 20 lights, each light has two 32 bit patterns stored as big decimal numbers, and you cannot see the result without restarting and driving into the dark. The editor shows the pattern as a grid you paint with the mouse and plays it on the vehicle, so you can build a wig wag or a rotator bar in minutes.
The id checker solves the other common problem on emergency vehicle servers: two packs that use the same siren id, so one set of cars shows the wrong lights.
## How siren settings work
A siren setting is one `- ` in the `
` block of a `carcols.meta`. It has an `id`, timing for the whole set (`sequencerBpm`, `timeMultiplier`), how the cast light behaves (falloff and cone angles), head and tail light patterns, and a list of exactly 20 lights. Light 1 is drawn at the model's `siren1` bone, light 20 at `siren20`. A light with no matching bone on the model is skipped, so the same setting looks different on different cars.
The vehicle picks its setting in `carvariations.meta` with ` `. That number must match the `id` in carcols.meta. 0 means no sirens.
Every light has a 32 bit `sequencer`: one bit per beat at `sequencerBpm`, 1 is on and 0 is off. The file stores it as an unsigned decimal. Step 1 in the grid is the leftmost (highest) bit. `4294967295` is always on, `2863311530` is 1010..., `1431655765` is 0101.... At 300 BPM a full 32 step pattern takes 6.4 seconds. Flashing lights use the `flashiness` sequencer, rotators (`rotate` true) the `rotation` one.
## Quick start
1. Pick a game setting on the left (search by id, name or vehicle model), or click **New setting**, or **Import carcols.meta**.
2. To build your own lights from a game setting, click **Copy to new id**. It copies the setting to the next free id from 100 up.
3. Press **Play** in the **Preview** panel and paint steps in the **Patterns** grid.
4. Click a lamp in the preview (or a light name in the grid) and edit it in the **Light** panel.
5. Set the timing and cone values in the **Setting** panel.
6. Open the **carcols.meta** tab under the editor and copy or download it. Use the **carvariations** tab to see where the id goes, and the **fxmanifest** tab for the resource manifest.
Your work is saved in this browser. Links like `?id=16` open a game setting, `?tab=ids` opens the id checker, and `?view=rear` starts the preview in the rear view.
## The setting list
The list has two groups:
- **Yours**: settings you edited, copied, created or imported, with a badge (**edited**, **new**, **import**) and where they came from ("copy of 1", "from carcols.meta").
- **Game**: the 21 game settings (ids 0 to 20, build 3889) from the base game and DLCs, with the vehicles that use each one. Id 0 is a placeholder that nothing uses.
Each row shows a strip of the first eight light colours.
### Editing a game setting vs copying it
You can edit a game setting in place. It then shows as **edited** and exports with its game id, which replaces that id for every vehicle that uses it (for example id 1 is `police/sheriff`). The id box is locked for game settings. For your own car, use **Copy to new id** instead.
**Reset (N)** puts the setting back to what it was loaded as (the game values, the import, or the state when you copied it). **Remove** drops your own settings from the list.
## Header and warnings
The **id** and **name** fields sit at the top. Ids above 255 or below 1 turn the box red. Amber warnings appear when:
- `lightInnerConeAngle` is not smaller than `lightOuterConeAngle`.
- The setting has more or fewer than 20 lights.
- `sequencerBpm` is 0 or below.
- The id is 0, or above 255.
## Preview
The preview draws the lights on a vehicle layout, seen from the **Top** or the **Rear**.
| Control | What it does |
| --- | --- |
| Model select | **Auto** uses a vehicle that uses this setting (or `police`), **Generic layout** uses a neutral layout, or pick any of the listed models. |
| Play / Pause | Plays the pattern at the setting's BPM. Starts paused if your system asks for reduced motion. |
| Step | Advances one sequencer step. |
| Restart | Back to step 1. |
| 0.25x, 0.5x, 1x | Playback speed. |
Click a lamp in the preview to select that light. If the model has no bone for some of the lights, a note under the preview tells you how many are not drawn (the game skips them too).
The timing, which lights are lit on which step, multiples, colours and lamp positions follow the setting. Glow size, beam length, brightness and rotator speed are approximations, so always check the result in game.
## Patterns
The **Patterns** panel shows one row of 32 steps per light. Click a cell to toggle it, or click and drag to paint. The current playback step is highlighted.
| Mode | What the grid edits |
| --- | --- |
| In use | The rotation pattern for rotators, the flash pattern for the rest. |
| Flash | Every light's `flashiness` sequencer. |
| Rotation | Every light's `rotation` sequencer. |
Below it, **Head and tail lights** has four rows (left and right head, left and right tail) for flashing the car's real lights, with a **useRealLights** switch. Guides advise at most 4 flashes in a row.
## Light
Pick a light with the numbered buttons or the `siren1` to `siren20` dropdown. The header says whether it is a rotator, flasher or not lit, and whether it casts a spot light, a round light or only a corona.
**Colour to all** gives every light this colour. **Settings to all** copies every field except the colour and the patterns to the other lights.
### Switches
| Switch | What it does |
| --- | --- |
| `rotate` | Spins the light (rotator). Uses the rotation pattern. |
| `flash` | Flashes the light. Uses the flash pattern. |
| `light` | Casts real light on the world, not only a corona. |
| `spotLight` | Cone shaped light instead of a round glow. Rotators need it to look like they spin. |
| `scale` | Corona grows with `scaleFactor` while lit. |
| `castShadows` | The cast light makes shadows. Costs performance; game files keep it off. |
### Colour
Use the colour picker, type `0xAARRGGBB` in the text box, or click a preset: Red `FFFF0300`, Blue `FF0019FF`, Amber `FFFFAA00`, White `FFFFFFFF`, Green `FF00FF0D`, Magenta `FFFF00FB`. Game lights use alpha `FF`; the tool tells you when yours is lower.
### Numbers
| Field | What it does | Range |
| --- | --- | --- |
| `intensity` | Brightness of the light cast on the world. | 0 to 10 |
| `scaleFactor` | Corona size while flashing when `scale` is on. | 0 to 255 |
| `lightGroup` | Lamp group. Game files use 0 to 3. | 0 to 255 |
### flashiness and rotation
Each has its own block, and the one in use is highlighted:
| Field | What it does |
| --- | --- |
| `sequencer` | The 32 step pattern. Pick from **Presets...** (Always on, Off, Alternate A/B, Pairs A/B, Quads A/B, Half A/B, Triple flash A/B), shift it one step left or right, invert it, or type it as decimal, `0x` hex, `-1` or a 32 character bit string. |
| Direction dial | Click a dot to point the light front, back, left, right or diagonal. The top of the dial is the front of the car. |
| `delta` | Facing in radians: 0 front, 1.5708 left, 3.1416 back, -1.5708 right. |
| `start` | Start angle, added to delta. |
| `speed` | Spin speed for rotators. |
| `multiples` | Flashes inside one lit beat. |
| `direction` | Flips the spin direction. |
| `syncToBpm` | Ties the timing to `sequencerBpm`. |
The light also shows its own warnings, for example rotate and flash both on, neither on, an empty pattern, or a rotator without `spotLight`.
### corona
`intensity` (0 hides the corona), `size` (0 hides it too), `pull` (pulls the corona towards the camera so it shows through the lamp glass) and `faceCamera`.
## Setting
| Field | What it does | Default for a new setting |
| --- | --- | --- |
| `sequencerBpm` | Beats per minute. Game lightbars use 150 to 300. | 300 |
| `timeMultiplier` | Scales the BPM. 2 plays the pattern twice as fast. | 1 |
| `lightFalloffMax` | How far the cast light reaches, metres. | 10 |
| `lightFalloffExponent` | How hard the light fades towards the max distance. | 10 |
| `lightInnerConeAngle` | Full brightness part of each spot cone, degrees. | 2.29061 |
| `lightOuterConeAngle` | Edge of each spot cone, degrees. | 70 |
| `lightOffset` | Offset of the cast light from the lamp. Game lightbars use 0. | 0 |
| `textureName` | Corona texture. Leave it at `VehicleLight_sirenlight`. | `VehicleLight_sirenlight` |
The four head and tail light sequencers also have their pattern tools here, each with a `...Multiples` value. If a setting has fewer than 20 lights, **Fill up to 20 lights** adds blank, unlit ones.
A **New setting** starts with 20 lights: red on odd lights, blue on even ones, flashing in turns.
## Importing
Click **Import carcols.meta**, paste a whole carcols.meta, its `` block or one siren `- `, and press **Parse**, or use **Open files** to load several files at once. Kits and lights in the file are ignored. Signed sequencers like `-1` are read too. Missing or odd fields are filled with defaults and listed under **field warnings**. The message also tells you when an imported id is also a game id. Importing the same file again replaces its settings instead of adding copies.
## Output
The tabs under the editor:
| Tab | What you get |
| --- | --- |
| carcols.meta | A carcols.meta with every setting in your export: edited game settings, copies, new and imported ones. |
| carvariations | Where to put each id in your vehicle's carvariations.meta. |
| fxmanifest | A ready `fxmanifest.lua`. |
| Settings | Every exported setting with its changed fields, a **Copy Item** button (one setting to paste into an existing Sirens block) and a button to drop it from the export. |
### carcols.meta
```xml title="carcols.meta"
-
my_sirens
VehicleLight_sirenlight
-
```
A carcols.meta that only has a `` block is fine. If your vehicle resource already ships a carcols.meta, paste the setting's `- ` (use **Copy Item** on the **Settings** tab) into its Sirens block instead of adding a second file with the same id.
### carvariations.meta
```xml title="carvariations.meta"
-
yourcar
```
For a copy of a game setting, the tab fills in a vehicle that used the original id. Edited game settings need no carvariations change, their vehicles already point at that id.
### fxmanifest.lua
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'data/carcols.meta',
'data/carvariations.meta',
}
data_file 'CARCOLS_FILE' 'data/carcols.meta'
data_file 'VEHICLE_VARIATION_FILE' 'data/carvariations.meta'
```
Save the files in a `data` folder next to this manifest and `ensure` the resource. Leave out the carvariations lines if the vehicle resource already loads its own.
## Siren ID check
The **Siren ID check** tab reads files and tells you which ids are in use.
1. Drop `carcols.meta` and `carvariations.meta` files on the **Files** box (several at once, from every siren resource on your server), or paste the text of a file and click **Add**.
2. Leave **Include the game's ids** on to see clashes with game settings. Turn on **Include my editor settings** to check what you built in the editor.
3. Read the results.
| Result | What it shows |
| --- | --- |
| Id map 0 to 255 | A 16 by 16 grid: game ids, yours, warnings and clashes. Hover a cell for details. |
| Problems / Ids in your files / Free ids (1 to 254) | Counts. |
| Next free ids | Ids you can copy, from 100 up, then the gap above the game's ids. Plus the list of free ranges. |
| Vehicles with more than one id | A model pointed at different ids by different carvariations files. The last one loaded wins. |
| Ids table | Each id, where it is defined, which models use it, and its status. |
| Status | Meaning |
| --- | --- |
| Clash | Defined more than once. Only one definition wins. |
| Replaces game | Same id as a game setting. Every game vehicle on that id gets your lights. |
| Not defined | A carvariations entry points at an id no loaded carcols (or the game) defines. |
| Unused | Defined, but no loaded carvariations points at it. |
| Over 255 | Only works with the SirenSetting Limit Adjuster on every client. |
| OK | Defined once, no clash. |
Files over 20 MB are skipped. Nothing is uploaded.
## The 255 id limit
- The id is a single byte in both carcols and carvariations, so ids go up to 255. 0 means no sirens and the Limit Adjuster reserves 255, so 1 to 254 is the safe range.
- The game uses ids 1 to 20 at build 3889, and Rockstar adds more with DLCs, so start your own ids higher. The tool suggests ids from 100 up.
- FiveM does not raise the limit ([citizenfx/fivem#2612](https://github.com/citizenfx/fivem/issues/2612) is still open). The client side SirenSetting Limit Adjuster allows higher ids, but every player has to install it.
> [!WARNING]
> Two resources with the same siren id do not crash anything, which is why the problem goes unnoticed. Run every carcols.meta on your server through the Siren ID check before adding a new pack.
## Common mistakes
- **Id in carcols does not match carvariations.** Put the same number in `id` and `sirenSettings`.
- **Editing a game setting when you meant to make your own.** That changes every vehicle on that id. Use **Copy to new id**.
- **Rotate and flash both on.** The game handles one mode per light. Pick one.
- **Rotator without `spotLight`.** It becomes a round glow and the spin cannot be seen.
- **Fewer than 20 lights.** Use **Fill up to 20 lights** so the `` list is complete.
- **A second carcols.meta with the same id** inside a pack that already has one. Merge the Item into the existing Sirens block.
## Limitations
The preview is a guide, not the game renderer: glow, beam length, brightness and rotator speed are approximate. The tool only reads and writes the `` part of carcols.meta; kits and lights are ignored on import and not written. Everything runs in your browser.
## Related tools
- [Vehicle Handling Editor](/docs/tools/vehicle-handling-editor)
- [Vehicle Pack Validator](/docs/tools/vehicle-pack-validator)
- [fxmanifest.lua Generator](/docs/tools/fxmanifest-generator)
- [Model Hash Browser](/docs/tools/model-hash-browser)
_Last updated: 2026-09-22_
---
## Vehicle Pack Validator
URL: https://fivemad.com/docs/tools/vehicle-pack-validator
Check a FiveM vehicle resource for broken links between metas, stream files and fxmanifest. Every check it runs, what it means and how to fix it.
The Vehicle Pack Validator reads an addon car resource (or a whole `[cars]` folder) and reports every broken link between `fxmanifest.lua`, the vehicle metas and the files in `stream/`. Each finding names the file and line and says what to change. It is for server owners installing car packs and for devs who build them.
## What it is for
A car that does not spawn, spawns without textures, has no tuning parts or flashes another car's light pattern is almost always a wiring problem, not a model problem: a `data_file` line with the wrong type, a meta missing from `files { }`, a `handlingId` with a typo, a kit id that another pack already uses. Finding those by hand across five metas and a manifest takes a long time, and it gets worse when you merge twenty car resources.
Drop the pack here before you put it on the server, or when a car misbehaves and you want to rule out the metas.
## Quick start
1. Open the tool and use **Choose a folder** (pick the resource folder, or the parent `[cars]` folder), **Open a .zip**, or drag the folder or zip onto the card.
2. Wait for the progress bar to finish reading the files.
3. Read the verdict at the top: **Ready to ship**, **Works, with problems** or **Broken**, with counts of errors, warnings, notes, vehicles, broken cars and resources.
4. Work through the **Findings** tab, errors first. Click a model name under a finding to jump to that car in the **Vehicles** tab.
5. Open the **fxmanifest** tab to compare your manifest with the one built from the files that are really in the folder.
6. Press **Report .md** to download the whole report as Markdown for a ticket or a Discord post.
No pack at hand? **Try a sample** loads a made up pack with invented names and placeholder model files, broken on purpose.
> [!NOTE]
> Everything is read in your browser, nothing is uploaded. Big model files are not opened in full, so even a large car folder checks quickly.
## Input
What you can drop:
- One resource folder (the one with `fxmanifest.lua` or `__resource.lua`).
- A folder holding many resources. Each folder with a manifest becomes its own resource, and conflicts between them are checked.
- A `.zip`. Normal and zip64 archives with store or deflate compression work. Password protected zips and 7z or rar archives must be extracted first. Files the zip reader skips are listed under the verdict.
Vehicle files that sit in no resource with a manifest are grouped by their top folder (the folder above `stream/`, `data/`, `meta/`, `metas/`, `audioconfig/` or `sfx/`), so a pack without a manifest is still checked and gets a "no fxmanifest" error.
Ignored: `__MACOSX/`, `.git/`, `.DS_Store`, `Thumbs.db`, `desktop.ini`.
What it looks at:
| Files | Used for |
|---|---|
| `*.meta` | The vehicle metas. You can name them anything: a meta is recognised by its root element (`CVehicleModelInfo__InitDataList` is vehicles.meta, `CHandlingDataMgr` handling, `CVehicleModelInfoVarGlobal` carcols, `CVehicleModelInfoVariation` carvariations, `CVehicleMetadataMgr` vehiclelayouts, plus dlctext, content unlocks and shop metas). |
| `.yft .ytd .ydr .ydd` | Presence, location, file type and memory size. |
| Other stream files (`.ybn .ycd .ymap .ytyp` ...) | Name and location. |
| `*.dat151.rel`, `*.dat54.rel`, `.awc` and other audio data | Engine sound checks and the audio `data_file` lines. |
| Client and shared `*.lua` | `AddTextEntry` calls for car display names. |
| `*.fxap` | Marks the resource as escrowed. |
## The report
### Verdict
- **Broken**: at least one error. The title says how many cars will not work as shipped.
- **Works, with problems**: no errors, some warnings.
- **Ready to ship**: no errors or warnings. Notes may remain, they are optional.
### Findings tab
Findings are grouped: fxmanifest and data_file, Stream files, vehicles.meta, handling.meta, Mod kits (carcols and carvariations), Sirens, Engine sound, Asset size, Conflicts between resources, File and folder names. The filter row switches between **All**, **Errors**, **Warnings** and **Notes**. Each finding has a title, evidence lines (`file:line` and what was found) and a fix. Model buttons under a finding open that car in the Vehicles tab.
### Vehicles tab
One row per `modelName`, worst status first. The chips show what the car links to:
| Chip | Meaning |
|---|---|
| `.yft` | The model file, with its path and memory size. Red when missing, amber when over 16 MiB. |
| `_hi` | The high detail model. Amber when missing. |
| `.ytd` | The texture dictionary from `txdName`. |
| `handling` | The matching `handlingName`, or "base game". |
| `variations` | The carvariations entry. |
| `kit` | Kits and their ids. |
| `siren` | `sirenSettings` id, only for cars that have one. |
| `sound` | `audioNameHash` and whether it is a base game sound, in this pack or not found. |
Open a row to see the meta file and line plus all findings for that car. With more than 6 vehicles a filter box appears (by model or resource).
### fxmanifest tab
A suggested manifest per resource, built from what is really in the folder. It says whether it **differs from the current manifest** or **matches** it. The rules:
- `fx_version 'cerulean'` and `game 'gta5'`, plus `lua54`, `name`, `author`, `description`, `version` if you had them.
- Your `shared_scripts`, `client_scripts` and `server_scripts` are kept.
- One `data_file` line per vehicle meta with the type that matches its root element, and one per sound file, in Rockstar's DLC order: `HANDLING_FILE`, `VEHICLE_LAYOUTS_FILE`, `VEHICLE_METADATA_FILE`, `CARCOLS_FILE`, `VEHICLE_VARIATION_FILE`, `CONTENT_UNLOCKING_META_FILE`, `VEHICLE_SHOP_DLC_FILE`, `TEXTFILE_METAFILE`, `AUDIO_SYNTHDATA`, `AUDIO_GAMEDATA`, `AUDIO_SOUNDDATA`, `AUDIO_WAVEPACK`.
- Other valid `data_file` lines you had (types this tool does not manage) are kept. `DLCTEXT_FILE` is dropped.
- `files { }` lists every data file target, the `.nametable` files, `/*.awc` for wave packs, and your own entries for other files (images, json).
- `escrow_ignore` is kept.
Compare it with yours before you replace anything.
## Every check
Severity: **Error** blocks loading (car does not spawn, meta not loaded, crash). **Warning** means it loads but looks, sounds or behaves wrong, or clashes with something. **Note** is information.
### fxmanifest and data_file
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| No fxmanifest.lua | Error | A folder with metas or stream files has no manifest, so FiveM never starts it. | Add an `fxmanifest.lua` (the suggested one is a start) and `ensure` the folder. |
| Both manifests | Warning | `fxmanifest.lua` and `__resource.lua` exist. FiveM ignores `__resource.lua`. | Move what you need into fxmanifest.lua, delete `__resource.lua`. |
| Legacy manifest | Note | The resource still uses `__resource.lua`. | Rename to fxmanifest.lua, replace `resource_manifest_version` with `fx_version 'cerulean'` and `game 'gta5'`. |
| Lua syntax problem | Error | Unclosed string, unclosed `--[[` comment, unclosed `{`, a missing comma between table entries, or `data_file` without both a type and a path. Everything after the break is silently missing. | Fix the line shown. The server console shows the same error on start. |
| `fx_version` missing | Error | The resource does not start. | Add `fx_version 'cerulean'` at the top. |
| `game` missing | Warning | The server warns about manifests without a game. | Add `game 'gta5'`. |
| `this_is_a_map` in a vehicle resource | Note | Makes the client reload the map store on start. Cars do not need it. | Remove it unless the resource also streams map files. |
| files entry matches no file | Warning | A `files { }` path points at nothing. | Fix the path (relative to the resource folder) or remove it. |
| files entry only matches with different case | Warning | Works on Windows, finds nothing on Linux. | Make the path match the real file name exactly. |
| data_file loaded twice | Warning | The same type and path appear twice, so every entry is added twice. | Remove the duplicate line. |
| `DLCTEXT_FILE` | Note | Not a type FiveM has a loader for. It does nothing. | Delete the line. Car names come from `AddTextEntry`. |
| Unknown data_file type | Error | A misspelled type is ignored, so the file never loads. Close matches are suggested. | Use the exact type name, it is case sensitive. |
| Audio data_file uses a wildcard | Error | Audio data files cannot be globbed. | One line per sound pack with the exact path. |
| data_file points at a missing file | Error | Nothing matches the path. For audio types the path must be the file without the version suffix, for `AUDIO_WAVEPACK` the folder. | Fix the path. `audioconfig/mycar_game.dat151.rel` is written `audioconfig/mycar_game.dat`. |
| data_file not in files { } | Error | Clients only download what `files { }` lists, so the game never sees it. | Add the path to `files { }`. |
| Wrong data_file type for a meta | Error | A vehicles.meta loaded as `HANDLING_FILE` and so on. The type is checked against the root element. | Change the type to the one the finding names. |
| Meta never loaded | Error (core metas), Note (content unlocks, shop meta) | A vehicles, handling, carcols, carvariations or vehiclelayouts meta has no `data_file` line. | Add the `data_file` line and list the file in `files { }`. |
| CARCOLS or VARIATION before VEHICLE_METADATA | Note | Rockstar loads vehicles.meta, then carcols.meta, then carvariations.meta. FiveM only moves handling and layouts to the front. | Reorder the lines to rule it out. |
| Not a vehicle meta | Note | A meta with an unknown root element. Not checked. | Make sure it has the right `data_file` type if it belongs to the car. |
| Not valid XML | Error | The game skips or crashes on a meta it cannot parse. | Fix the tag at the line shown (VS Code highlights the break). |
Globs follow FiveM's rules: `*` and `?` stay inside one folder, `**` matches any number of folders.
### Stream files
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| Files outside stream/ | Error | `.yft`, `.ytd`, `.ydr` or `.ydd` not under `stream/`. Listing them in `files { }` does not stream them. | Move them into `stream/` (subfolders are fine). |
| Stream folder spelled differently | Warning | `Stream/` or `STREAM/`. Linux hosts do not find it. | Rename to lowercase `stream`. |
| Exported XML or openFormats file | Error | `.yft.xml`, `.ytd.xml`, `.oft`, `.otd` and so on. The game only loads compiled files. | Import in CodeWalker (or OpenIV) and save the binary, delete the export. |
| Not a GTA V resource file | Error | Empty, damaged or renamed from another format (not checked for escrowed resources). | Re-export the file or get a fresh copy from the author. |
| Enhanced edition (RSC8) asset | Error | FiveM runs the Legacy game and cannot load RSC8. | Use the Legacy version or convert it with CodeWalker. |
| Wrong resource version | Warning | Expected `yft` 162, `ytd` 13, `ydr` 165, `ydd` 165. Usually a file renamed to the wrong extension. | Check the file really is what its extension says. |
| Same file twice in one resource | Warning | Streaming uses the file name only, so one silently replaces the other. | Keep one copy. |
| Meta or script inside stream/ | Warning | Files in `stream/` are streamed as assets, not loaded as data. | Move metas to `data/` and load them with `data_file`. Scripts go in `client_scripts`. |
### vehicles.meta
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| Defines no vehicles | Warning | `` is missing or empty. | Check the file was not saved half way. |
| No modelName | Error | An entry without ``. | Set it to the `.yft` name without extension. |
| No .yft for modelName | Error | The car cannot spawn ("model does not exist"). If the name is a base game car, it is a Note instead: the entry edits that car. | Stream `.yft` or fix ``. |
| `_hi.yft` missing | Warning | No high detail model, the car can look low poly or flicker up close. | Stream `_hi.yft` (a copy of the `.yft` works). |
| No txdName | Error | Entry without ``. | Set it to the model name and stream `.ytd`. |
| txdName has no .ytd | Error | Not in the pack, not a model name, not a shared game txd. Car renders white, checkered or not at all. | Stream the `.ytd` or point `txdName` at the right one. If `.ytd` exists, the fix says to use it. |
| `.ytd` exists but txdName differs | Warning | The model's own `.ytd` is streamed for nothing. | Set `` to the model name if that is where the textures are. |
| Layout does not exist | Error | Not a base game layout and not in a loaded vehiclelayouts.meta. Breaks entering the car or crashes. | Use `LAYOUT_STANDARD`, `LAYOUT_LOW` or ship the layouts file. |
| Unknown vehicle type | Warning | `` is not a game type. | Usually `VEHICLE_TYPE_CAR`. |
| Unknown vehicle class | Warning | `` is not a game class. | Use one the finding lists. |
| No display name | Note | No `AddTextEntry` for `` in the resource's Lua, so menus show NULL. | Add `AddTextEntry('', 'Your Car Name')` in a client script. |
| txd parent does not exist | Warning | `` parent is not in the pack or the game. | Point it at a `.ytd` in the pack or a shared game txd like `vehshare`. |
| txd child is not in the pack | Note | The relationship does nothing. | The child is usually the car's `txdName`. |
| modelName has special characters | Warning | Spaces and symbols break spawn commands and garages. | Use a-z, 0-9 and `_`, rename files to match. |
| No carvariations entry | Warning | No default colours and no mod kit, tuning menus stay empty. | Add an entry with colours and `` (`0_default_modkit` if no custom parts). |
| Also a base game car | Warning | A streamed `.yft` with a base game model name replaces that car for everyone, traffic too. | Rename the model if it is meant as a new car. |
### handling.meta
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| No handlingId | Error | Entry without ``. | Set it to a `` from handling.meta. |
| handlingId not in any handling.meta | Error | Keeps the car from spawning or crashes the client. | Add the handling entry or fix the id. |
| Uses base game handling | Note | The id is a base game handling name. | Fine if on purpose. |
| handling without handlingName | Error | Empty ``. | Use the name vehicles.meta refers to. |
| handling not used | Note | No vehicle in the pack uses it. | Check for a typo or remove it. |
| handling changes a base game car | Warning | The name is a base game handling, so every car of that model on the server drives differently. | Rename it and point `handlingId` at the new name. |
| handlingName defined more than once | Warning | Only the last one loaded is used, start order decides. | Keep one, or give each car its own name. |
### Mod kits (carcols and carvariations)
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| carvariations for an unknown model | Warning | No vehicles.meta defines that `modelName`. | Fix the typo or add the missing vehicles.meta. |
| No mod kit | Note | `` is empty, tuning menus show nothing. | Add `- 0_default_modkit
` or the car's own kit. |
| Kit not in any carcols.meta | Warning | The car gets no tuning parts. | Match the `` exactly or load the carcols.meta that has it. |
| Kit has no numeric id | Error | ` ` missing or not a number. | Give every kit a unique id. |
| Kit id above 65535 | Error | Kit ids are 16 bit, it wraps and collides. | Pick an unused id between 1000 and 65535. |
| Kit id used by the base game | Warning | Tuning parts get mixed with a game car's kit. Game ids run 0 to 640 and 999. | Move yours above 1000 and keep a list across your packs. |
| Kit not used by any car | Note | No carvariations entry lists it. | Add it to the car's ``. |
| Tuning parts with no .yft | Warning | `visibleMods` or `linkMods` model missing, the part shows in the menu but is invisible. | Stream the `.yft` or remove the entry. |
| Kit id used by several kits | Error | Two kits with different names share an id, across resources too. | Give all but one a new id. |
| Kit name with different ids | Warning | carvariations picks kits by name, so only one is used. | Rename one kit and update its carvariations. |
### Sirens
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| sirenSettings not defined | Warning | The id in carvariations exists in no carcols.meta or the game. Lights stay dark. | Load the carcols.meta with that siren id or use one that exists. |
| Siren id above 255 | Warning | FiveM keeps 8 bits, so 300 acts as 44 ([citizenfx/fivem issue 2612](https://github.com/citizenfx/fivem/issues/2612)). | Use a free id between 21 and 254. |
| Siren id taken by the base game | Warning | Game ids are 0 to 20. The patterns overwrite each other. | Pick a free id above that. |
| Siren settings share an id | Error | Also after the 255 wrap. Only one wins, other cars flash the wrong pattern. | Give each its own id and update `sirenSettings`. |
### Engine sound
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| No audioNameHash | Note | Empty on a new model, so the car falls back to a generic engine. | Set it to a base car (`ADDER`, `SULTAN`) or your sound pack name. |
| Sound not in this pack's game.dat | Warning | The pack has sound files but none of its `.dat151.rel` files defines a sound with that name. | Check the spelling against the sound pack. |
| Sound is not a base game sound | Warning | No sound pack in the drop. Silent or default sound unless another resource streams it and starts first. | Ship the sound pack or use a base car name. |
| Audio file never loaded | Error | A `.dat151.rel`, `.dat54.rel` or `.dat10.rel` has no matching `AUDIO_GAMEDATA`, `AUDIO_SOUNDDATA` or `AUDIO_SYNTHDATA` line (or the wrong type). | Add `data_file '' ''` and list the `.rel` in `files { }`. |
| Sound folder has no AUDIO_WAVEPACK | Error | A folder of `.awc` files is never mounted. The car is silent. | Add `data_file 'AUDIO_WAVEPACK' ''` and list the `.awc` files. |
### Asset size
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| Oversized asset | Warning over 16 MiB, Error over 48 MiB | The file's physical or virtual memory size, the number the server prints in its "Asset uses X MiB of physical memory" warning. FiveM says assets over 48 MiB "can and WILL lead to streaming issues". | `.ytd`: 2048 px is plenty for a body, 512 to 1024 for details, DXT1/BC1 without alpha. Models: fewer polygons, textures out to the `.ytd`. |
| Large file (header unreadable) | Warning | Escrowed or unreadable header and the file is over 16 MiB on disk. Only a hint. | Check it in CodeWalker. |
### File and folder names
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| Resource folder name | Error with spaces, Warning with other symbols | `ensure` cannot start a name with spaces. | Rename to lowercase letters, numbers, `_` or `-`. |
| Paths with spaces | Warning | Break globs and some hosting panels. | Use underscores and update metas and manifest. |
| Stream files with special characters | Warning | The asset name no longer matches what the metas ask for. | Rename to plain lowercase names. |
| Stream files with uppercase | Note | Works, the game ignores case. | Lowercase avoids typos. |
| Escrowed resource | Note | `.fxap` found. Only runs with the owning license key, sizes are estimated. | Do not rename or move escrowed files. |
### Conflicts between resources
| Check | Severity | What it means | How to fix |
|---|---|---|---|
| modelName defined more than once | Error | Only one definition wins, start order decides. | Keep one, or rename a car. |
| Stream files in several resources | Warning | One finding per group of resources that share file names. The last started wins. | Often the same car installed twice: remove one. |
Handling, kit, kit name and siren duplicates across resources are also listed under Conflicts.
## Example
A typical manifest from the fxmanifest tab for a car with its own engine sound:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
client_scripts {
'client.lua',
}
files {
'data/handling.meta',
'data/vehicles.meta',
'data/carcols.meta',
'data/carvariations.meta',
'audioconfig/mycar_game.dat151.rel',
'audioconfig/mycar_sounds.dat54.rel',
'sfx/dlc_mycar/*.awc',
}
data_file 'HANDLING_FILE' 'data/handling.meta'
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'
data_file 'CARCOLS_FILE' 'data/carcols.meta'
data_file 'VEHICLE_VARIATION_FILE' 'data/carvariations.meta'
data_file 'AUDIO_GAMEDATA' 'audioconfig/mycar_game.dat'
data_file 'AUDIO_SOUNDDATA' 'audioconfig/mycar_sounds.dat'
data_file 'AUDIO_WAVEPACK' 'sfx/dlc_mycar'
```
And the display name the "No display name" note asks for:
```lua title="client.lua"
CreateThread(function()
AddTextEntry('MYCAR', 'My Car GT')
end)
```
## Tips
- Drop all your car resources at once. Kit id, siren id, handling and stream file clashes only show up when the tool sees both sides.
- Keep one list of the kit and siren ids you use across packs. Base game kits run up to 640 (and 999), sirens up to 20.
- Links with `?sample` open the tool with the sample pack loaded, and `?tab=vehicles` or `?tab=manifest` picks the tab that opens after a check.
> [!WARNING]
> If a check is clean and a car still misbehaves, open the F8 console while you spawn it and look for streaming errors. This tool does not open the models.
## Limitations
- It reads metas and file headers. It does not open the models, so it cannot see a broken mesh, missing bones or a wrong embedded texture.
- Escrowed (`.fxap`) stream files are encrypted, so their memory size is estimated from the file size.
- A sound that another resource provides cannot be seen from here. The finding says so instead of calling it broken.
- Handling values themselves are not judged. Use the handling editor for that.
- Everything runs in your browser. Nothing is uploaded.
## Related tools
- [Vehicle Handling Editor](/docs/tools/vehicle-handling-editor)
- [Vehicle Sirens](/docs/tools/vehicle-sirens) to build siren settings with free ids
- [YTD Optimizer](/docs/tools/ytd-optimizer) for oversized texture dictionaries
- [Native Audio Builder](/docs/tools/native-audio-builder) for custom sound banks
- [fxmanifest Generator](/docs/tools/fxmanifest-generator)
_Last updated: 2026-09-22_
---
## YMT Creator
URL: https://fivemad.com/docs/tools/ymt-creator
Turn a folder of addon clothing .ydd and .ytd files into a streamable pack: ped variation .ymt, shop meta, fxmanifest and correctly renamed stream files.
The YMT Creator builds the ped variation `.ymt` for an addon clothing pack from the names of its `.ydd` and `.ytd` files. Drop the pack, and you get the `CPedVariationInfo` XML, the shop `.meta` that registers the collection, the `fxmanifest.lua`, and every stream file renamed to the name the game expects. It is for server owners who stream clothing for `mp_m_freemode_01` and `mp_f_freemode_01`.
## What it is for
Addon clothing needs three things to show up in game: files named in a strict pattern with the collection prefix, a `.ymt` that lists every drawable and texture per component, and a shop meta loaded with `SHOP_PED_APPAREL_META_FILE`. Get one number wrong and a top is invisible, a texture is purple or the whole pack does not load.
Use this tool when you:
- bought or made a clothing pack that ships loose files (`jbib_000_u.ydd`, `jbib_diff_000_a_uni.ytd`) and no ymt,
- want to add, remove or reorder drawables in an existing pack without renaming 300 files by hand,
- have a `.ymt.xml` from someone else and want to check or edit it.
## Quick start
1. Open **Add files**, **Files** tab, and drop the pack folder (or use **Pick a folder**). Put male files in a `male` folder and female files in a `female` folder, or use files that already carry the `mp_m_freemode_01_^` prefix.
2. Set **Collection name** in the **Pack** panel. It must be unique on your server, lowercase.
3. Fix what the issue list in the right column points out. Click an issue to jump to the drawable.
4. Reorder drawables with the arrow buttons if you want another order in game. The number on each card is the number the drawable gets.
5. In **Export**, **Files** tab, press **Download my_clothes.zip** (named after your collection). It contains `stream/` with every file renamed, `fxmanifest.lua`, the `.meta` files and a `convert_in_codewalker/` folder with the ymt XML.
6. Convert the XML in CodeWalker (steps in the **Convert** tab) and put the `.ymt` files in `stream/`.
7. `ensure` the resource, restart the server and reconnect.
Want to see it with data first? The **Names** tab has **Fill an example**, and opening the tool with `?example` in the URL loads the same made up pack.
## Input file names
The tool reads everything from file names, so they must follow the game's pattern. Folders are allowed, and the `^` prefix is optional on input.
| File | Pattern | Example |
|---|---|---|
| Component model | `_<000>_.ydd` | `jbib_000_u.ydd` |
| Component texture | `_diff_<000>__.ytd` | `jbib_diff_000_a_uni.ytd` |
| Alternate model | `_<000>__<1-9>.ydd` | `hair_000_u_1.ydd` |
| Cloth physics | `_<000>_.yld` | `jbib_000_u.yld` |
| Prop model | `p__<000>.ydd` | `p_head_000.ydd` |
| Prop texture | `p__diff_<000>_.ytd` | `p_head_diff_000_a.ytd` |
- `_u` drawables use `_uni` textures. `_r` drawables draw skin and use a race suffix, usually `_whi`.
- Texture letters run `a` to `z`, so at most 26 textures per drawable.
- Prop textures have no race suffix.
- Only diffuse textures (`_diff_`) belong in the ymt. Normal and specular maps are skipped with a message.
- Names that almost match (1 or 2 digit numbers, a missing `_u`, a missing race suffix) are still read and get a note on the card. The export renames them to the standard form.
- `.ymt.xml` files dropped here are imported (see Import below).
**Gender** comes from, in this order: a `mp_m_freemode_01...` or `mp_f_freemode_01...` prefix, then the nearest folder called `male`, `female`, `men`, `women`, `m`, `f` and similar (also inside names like `[female]` or `my_pack_female`). Files with neither go to **Gender for files without one**, and the log tells you how many did.
**Collection name**: if all dropped files share one prefix (`mp_m_freemode_01_mybrand^...`) and the pack is still empty with the default name, the name is taken from that prefix.
### Names tab
When the files are on your server and not on this PC, paste the names, one per line, with or without folders and the `^` prefix. The output of `dir /b /s` or `ls -R` works too. Press **Add names**. Everything works the same except the zip, which needs the real files.
### Import tab
Open a ped variation `.ymt.xml` exported from CodeWalker (**Open .ymt.xml**) or paste it and press **Load pasted XML**. It replaces the drawables of that gender (undo brings them back). The gender comes from the file name (`mp_f_freemode_01...`), otherwise from the Male / Female switch next to the button. The collection name is read from the file.
Kept from an import: propMask, alternates, cloth flag, texture races, audio, flags, heel and hat values, inclusions and exclusions, prop render flags, and `aSelectionSets` as raw XML. The log lists anything odd in the file (unused component blocks, prop ids with gaps, wrong texture counts) and ends with a **Re-export check** line that says whether the generated XML has the same content as the file.
## Pack settings
| Field | What it does | Default |
|---|---|---|
| Collection name | The collection (DLC) name. Files become `mp_m_freemode_01_^jbib_000_u.ydd`. Lowercase letters, digits and `_`; other characters are replaced when you leave the field. | `my_clothes` |
| Gender for files without one | Where files go when neither prefix nor folder says the gender. | Male |
| Male ped / Female ped | Under **Ped names and header flags**. Change only for an addon ped with its own ymt. | `mp_m_freemode_01`, `mp_f_freemode_01` |
| bHasTexVariations and bHasDrawblVariations true | Writes `true` in both header fields. The game's DLC clothing ymts write false, grzyClothTool writes true, both load. | off |
The **Pack** panel also has **Undo** (last add, move, delete or import, 40 steps) and **Clear** (removes every drawable, keeps name and peds). Your pack is saved in the browser. Dropped files themselves are not kept after a reload, so drop them again before you download the zip.
## Drawables
The **Drawables** panel has a **Male** and **Female** tab with counts. Drawables are grouped by slot, each group shows its drawable and texture count and an **Add** button for an empty drawable. **Start another slot...** plus **Add drawable** at the bottom starts a slot that has nothing yet.
Each card shows the number it will get (`000`, `001`...), the race suffix, one chip per texture letter (amber when the race does not fit the drawable), and the source file with its memory size. The buttons move it one number up or down, or remove it. Click the card to open it.
### Card fields
| Field | What it does |
|---|---|
| Slot | Moves the drawable to another component or prop anchor. It is appended at the end of that slot. |
| Race suffix | `_u` or `_r`. Switching updates the textures (`_uni` or `_whi`) and the skin bit of propMask. Components only. |
| propMask | `1` plain (`_u` clothing), `17` with skin (`_r` clothing), `19` with skin variant. Presets also list 3, 5, 9 (game hair), 11 (game hair, masks) and 65. |
| numAlternatives | Extra models named `_u_1.ydd`, `_u_2.ydd` (hair under hats). 0 to 9. |
| Cloth physics | **Has .yld cloth** when a `.yld` ships with the model (ownsCloth). Set automatically when you drop one. |
| Audio | `pedXml_audioID` for components, `audioId` for props. Suggestions per slot, like `shoe_trainers`, `shoe_heels`, `cloth_upper_jacket_leather`, `cloth_lower_pants_denim`. `none` is fine. New shoes default to `shoe_trainers`. |
| High heels | Shoes (feet) only. Heel height, the game's heels use `1`. `0` is off. |
| Hair scale under the hat | Hats (`p_head`) only. Squashes hair so it does not poke through. Game hats use `0.5`. `0` is off. |
| renderFlags | Props only: none, `PRF_ALPHA`, `PRF_DECAL`, `PRF_CUTOUT`. |
| compInfo flags / propFlags | Bulky, Job, Sunny, Wet, Cold, Not in car, Bike only, Not indoors, Fire retardant, Armoured, Lightly armoured, High detail, Default helmet, Random helmet, Script helmet, Flight helmet, Hide in first person, Use physics hat 2, Pilot helmet, Wet: more wet, Wet: less wet. |
| Textures | One row per letter with its race (`uni`, `whi`, `bla`, `chi`, `lat`, `ara`, `bal`, `jam`, `kor`, `ita`, `pak`) and file. **Add texture** adds the next letter, up to 26. |
The right side of an open card shows **Streams as** (the final file names) and the Lua line to put it on a ped.
### Components and props
| Id | Component | Holds | Prop anchor | Holds |
|---|---|---|---|---|
| 0 | `head` | Heads | `p_head` | Hats |
| 1 | `berd` | Masks | `p_eyes` | Glasses |
| 2 | `hair` | Hair | `p_ears` | Earrings |
| 3 | `uppr` | Arms (torso) | `p_mouth` | Mouth |
| 4 | `lowr` | Legs | `p_lhand` | Left hand |
| 5 | `hand` | Bags and parachutes | `p_rhand` | Right hand |
| 6 | `feet` | Shoes | `p_lwrist` | Watches |
| 7 | `teef` | Chains, ties | `p_rwrist` | Bracelets |
| 8 | `accs` | Undershirts | `p_hip` | Hip |
| 9 | `task` | Body armor | `p_lfoot` | Left foot |
| 10 | `decl` | Decals | `p_rfoot` | Right foot |
| 11 | `jbib` | Tops | `p_ph_l_hand` | Left hand (ph) |
| 12 | | | `p_ph_r_hand` | Right hand (ph) |
> [!IMPORTANT]
> Drawable numbers are positions. The game reads the Nth model of a slot as drawable N, so numbers must run 000, 001, 002 without gaps. The tool numbers drawables in list order and renames the files to match, so a gap in your source files closes up and later files get new numbers.
## Checks
| Severity | Check |
|---|---|
| Error | No collection name; a game collection name (`male_heist`, `female_freemode_beach` and the like); empty ped name; drawable with no texture; more than 26 textures; more than 256 drawables in one slot; two models with the same number; texture in a folder of the other gender than its drawable; file without a valid game header (broken, encrypted or renamed); a file over 48 MiB of memory; a gender whose drawables have no textures at all. |
| Warning | Collection name with capitals or symbols; name over 40 characters; textures without a matching `.ydd`; files not used (with the reason); the same texture letter twice (`_a_uni` and `_a_whi`); race suffix mismatch; skin bit on a `_u` drawable; `_r` drawable without the skin bit; `.ydd.xml` models instead of binary; files over 16 MiB of memory; files over 16 MB on disk; ownsCloth without a `.yld`; numAlternatives higher than the alternates dropped; heel height on something that is not a shoe; hair scale above 1. |
| Note | Gaps in drawable numbers (files get renamed); texture letters with gaps or not starting at `a`; names that do not follow the pattern; heel height above 1.5; addon heads (freemode characters use head blends, masks go in `berd`). |
## Output
### Export tabs
- **YMT**: the `mp_m_freemode_01_.ymt.xml` for the selected gender (switch appears when the pack has both).
- **Files**: a table of every stream file, source name on the left and final name on the right; **Download .zip**; and a copy script.
- **Resource**: the folder layout, `fxmanifest.lua`, the shop `.meta`, and the creature metadata XML when needed.
- **Convert**: the CodeWalker steps.
### Stream file names
| File | Name |
|---|---|
| Component model | `mp_m_freemode_01_^jbib_000_u.ydd` |
| Component texture | `mp_m_freemode_01_^jbib_diff_000_a_uni.ytd` |
| Alternate model | `mp_m_freemode_01_^hair_000_u_1.ydd` |
| Cloth physics | `mp_m_freemode_01_^jbib_000_u.yld` |
| Prop model | `mp_m_freemode_01_p_^p_head_000.ydd` (note the `_p_`) |
| Prop texture | `mp_m_freemode_01_p_^p_head_diff_000_a.ytd` |
| Variation data | `stream/mp_m_freemode_01_.ymt` |
| Shop meta | `mp_m_freemode_01_.meta` in the resource root |
| Creature metadata | `stream/mp_creaturemetadata_m_.ymt` (only with heels or hat hair scale) |
Female files use `mp_f_freemode_01` the same way. The `^` stands for a folder: FiveM streams `a^b.ydd` as `b.ydd` inside `a`, the same layout as the game's DLC archives.
### Zip and copy script
**Download .zip** renames the dropped files into `/stream/`, adds `fxmanifest.lua`, the `.meta` per gender, and `convert_in_codewalker/` with the `.ymt.xml` (and `.ymt.rbf.xml` for creature metadata). Files added by typed name or import have no source and are left out; the message after the download says how many. Packs over 1.5 GB are too big for a browser zip, use the script instead.
The copy script comes as **PowerShell** or **bash**. Set **Output folder** (defaults to the collection name) and run it inside the folder you dropped. It copies every file to `/stream/` and never moves or deletes anything.
```powershell title="rename_my_clothes.ps1"
# Copies the clothing files of "my_clothes" into my_clothes/stream with the names the ymt expects.
# Run it in the "my_clothes" folder. Your files are copied, not moved.
$ErrorActionPreference = 'Stop'
New-Item -ItemType Directory -Force -Path 'my_clothes/stream' | Out-Null
Copy-Item -LiteralPath 'male/jbib_000_u.ydd' -Destination 'my_clothes/stream/mp_m_freemode_01_my_clothes^jbib_000_u.ydd'
Copy-Item -LiteralPath 'male/jbib_diff_000_a_uni.ytd' -Destination 'my_clothes/stream/mp_m_freemode_01_my_clothes^jbib_diff_000_a_uni.ytd'
Copy-Item -LiteralPath 'male/jbib_diff_000_b_uni.ytd' -Destination 'my_clothes/stream/mp_m_freemode_01_my_clothes^jbib_diff_000_b_uni.ytd'
Write-Host "Copied 3 files to my_clothes/stream"
```
### The ymt XML
For a male pack with one top and two textures:
```xml title="mp_m_freemode_01_my_clothes.ymt.xml"
255 255 255 255 255 255 255 255 255 255 255 0
-
-
-
-
-
none
none
0 0 0 0 0
0
0
PV_COMP_HEAD
hash_8AB05D7E
```
What the main fields mean:
| Field | Meaning |
|---|---|
| `availComp` | 12 numbers, one per component: the index of its block in `aComponentData3`, `255` when the pack has none. |
| `numAvailTex` | Total textures of all drawables in the component. |
| `propMask` | `1` plain clothing, `17` for `_r` drawables that draw skin. |
| `texId` | Texture race for components: 0 uni, 1 whi, 2 bla, 3 chi, 4 lat, 5 ara, 10 pak. For props, the texture position. |
| `distribution` | Random pick weight, 255 on every game texture. |
| `compInfos` | One entry per drawable: audio, expressionMods (heel height in the 5th value), flags. |
| `aAnchors` | Per prop anchor, the texture count of each prop drawable. |
| `dlcName` | Hash of the collection name. Must match `dlcName` in the shop meta. |
### Resource files
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
files {
'mp_m_freemode_01_my_clothes.meta',
'mp_f_freemode_01_my_clothes.meta'
}
data_file 'SHOP_PED_APPAREL_META_FILE' 'mp_m_freemode_01_my_clothes.meta'
data_file 'SHOP_PED_APPAREL_META_FILE' 'mp_f_freemode_01_my_clothes.meta'
```
```xml title="mp_m_freemode_01_my_clothes.meta"
mp_m_freemode_01
my_clothes
mp_m_freemode_01_my_clothes
SCR_CHAR_MULTIPLAYER
mp_creaturemetadata_m_my_clothes
```
The `.meta` registers the collection. Without it the game never loads the `.ymt` and the addon drawables do not exist. It goes next to `fxmanifest.lua`, not in `stream/`. A pack with only one gender gets one meta and one line.
```text
my_clothes/
fxmanifest.lua
mp_m_freemode_01_my_clothes.meta
stream/
mp_m_freemode_01_my_clothes.ymt
mp_m_freemode_01_my_clothes^jbib_000_u.ydd
mp_m_freemode_01_my_clothes^jbib_diff_000_a_uni.ytd
mp_m_freemode_01_my_clothes^jbib_diff_000_b_uni.ytd
```
### Heels and hats
Set **High heels** on a shoe or **Hair scale under the hat** on a hat and the **Resource** tab adds `mp_creaturemetadata__.ymt.rbf.xml`. Keep the `.ymt.rbf.xml` name so CodeWalker converts it in the right format, then stream the resulting `mp_creaturemetadata_m_.ymt`. The shop meta always names it in `creatureMetaData`; when you use neither heels nor hat hair scale, that file simply does not exist, which is harmless.
### Converting to binary
1. Download `mp_m_freemode_01_.ymt.xml` (YMT tab) into an empty folder. Keep the double extension.
2. In CodeWalker open **RPF Explorer**, then **File, Open Folder** on that folder.
3. Turn on **Edit mode** and use **Edit, Import XML** (or drag the file in). CodeWalker writes the `.ymt`.
4. Do the same for the other gender and for any creature metadata file.
5. Put the `.ymt` files in `stream/` with the renamed `.ydd` and `.ytd`, keep the `.xml` files out of it.
6. `ensure` the resource, restart the server and reconnect.
## Using the clothes in scripts
Addon drawables come after the game's own, so their global number shifts whenever the game adds clothes. Use the collection natives with your collection name and the local number shown on each card:
```lua title="client.lua"
local ped = PlayerPedId()
-- top 000 of my_clothes, texture a
SetPedCollectionComponentVariation(ped, 11, 'my_clothes', 0, 0, 0)
-- hat 000 of my_clothes, texture a
SetPedCollectionPropIndex(ped, 0, 'my_clothes', 0, 0, true)
-- how many tops the pack added
print(GetNumberOfPedCollectionDrawableVariations(ped, 11, 'my_clothes'))
```
More on these natives: [collection based natives](https://docs.fivem.net/docs/scripting-manual/using-new-game-features/collection-based-natives/).
## Common mistakes
- **Nothing shows up.** The `.meta` is missing from `files` or `data_file`, the ymt is still XML, or its name does not match the `^` prefix of the files.
- **Invisible or wrong drawable.** A gap in the numbers, or the ymt lists more drawables than there are files. Stream the renamed files from the zip or script, not your originals.
- **Purple or missing texture.** Texture letter or race suffix does not match: `_u` needs `_uni`, `_r` needs `_whi`.
- **Skin looks broken.** `_r` drawable with propMask 1. Use 17.
- **Two packs clash.** Every pack on the server needs its own collection name.
- **Server console size warnings.** FiveM warns above 16 MiB of memory per asset and calls anything over 48 MiB oversized. Downsize the textures (2048 px is usually enough for clothing).
> [!TIP]
> Adding clothes to a pack later? Import the pack's `.ymt.xml`, then drop the pack's files plus the new ones. Files with a number the ymt already has are attached to that drawable, new numbers are added at the end of their slot, so existing drawables keep their numbers.
## Limitations
- It writes XML. The binary `.ymt` comes from CodeWalker.
- It does not open or edit the models or textures. Use the other clothing tools for that.
- Only `mp_m_freemode_01` and `mp_f_freemode_01` style packs are the target. Custom ped names work for the file names, but the shop meta still says multiplayer.
- Dropped files stay in your browser and are not uploaded. Only names, sizes and headers are read until you build the zip.
## Related tools
- [Clothing Designer](/docs/tools/clothing-designer)
- [Drawable Studio](/docs/tools/drawable-studio)
- [Texture Editor](/docs/tools/texture-editor)
- [YTD Optimizer](/docs/tools/ytd-optimizer) for oversized textures
- [joaat Hash Calculator](/docs/tools/hash-calculator)
_Last updated: 2026-09-22_
---
## YTD Optimizer
URL: https://fivemad.com/docs/tools/ytd-optimizer
How to shrink many .ytd files at once: pick a preset or your own size caps, review the plan per texture, run it and put the smaller files back in stream.
The YTD Optimizer takes a whole stream folder (or any pile of `.ytd` files) and makes the texture dictionaries smaller in one go. It caps texture sizes per type, turns opaque DXT5 into DXT1, compresses uncompressed textures and fixes missing mip chains, and shows you the memory saved per file before anything changes. It is for server owners fighting texture loss and FXServer memory warnings on vehicle packs, clothing packs and MLOs.
## What it is for
When a resource starts, FXServer checks every file in `stream/` and prints a warning for files that need a lot of physical memory. GTA has a fixed texture budget: when a player is near many heavy assets, the game runs out of room and drops things. Textures stay blurry, cars and clothes turn invisible, parts of the map do not render. That is "texture loss". Smaller dictionaries fix it for everyone, not only for players with weak PCs.
The **Physical** column in this tool is the number FXServer looks at.
| Size | What FXServer does |
| --- | --- |
| up to 16 MiB | Nothing, this is where you want every file. |
| over 16 MiB | Prints "Asset ... uses X MiB of physical memory". |
| over 32 MiB | Same warning, in yellow. |
| over 48 MiB | Adds "Oversized assets can and WILL lead to streaming issues (such as models not loading/rendering)". |
| over 64 MiB | Same, in red. |
The warning is not a hard limit, the file still streams. But it is a good sign of which files to fix first.
## Quick start
1. Make a copy of the resource you want to optimize.
2. Open the [tool](/tools/ytd-optimizer) and drop the resource folder, its `stream` folder or single `.ytd` files. **Choose folder** and **Choose .ytd files** do the same. Sub folders are searched; everything that is not a `.ytd` is ignored.
3. Pick a preset: **Safe**, **Balanced** (default) or **Strict**.
4. Look at the file table. **After** and **Saved** show the plan. Expand a file to see what happens to each texture and untick the ones you want to keep as they are.
5. Press **Optimize**.
6. Click a texture name to compare before and after.
7. Press **All as zip**, extract it over your copy of the resource and restart it.
## Rules
### Presets
| Preset | Colour maps | Normal maps | Spec maps | Skip up to | For |
| --- | --- | --- | --- | --- | --- |
| **Safe** | 2048 | 2048 | 2048 | 128 px | Anything players look at up close. Only textures above 2048 shrink, formats and mips get fixed. |
| **Balanced** | 2048 | 1024 | 1024 | 128 px | Most servers. Normal and spec detail is hard to see at 1024, big win on vehicles and MLOs. |
| **Strict** | 1024 | 512 | 512 | 64 px | Crowded servers and big packs (EUP, clothing, vehicle packs with dozens of cars). Check a few close up shots after. |
All three turn on **Opaque DXT5 to DXT1**, **Compress uncompressed** and **Rebuild missing mips**, leave **BC5 for normal maps** off, exclude `script_rt_*` and use **High** quality. Changing any setting switches the preset to **Custom**.
### Settings
| Setting | What it does |
| --- | --- |
| **Max size** | Longest side cap for colour maps and everything that is not a normal or spec map (4096 to 128). |
| **Normal maps** | Cap for normal maps. |
| **Spec maps** | Cap for specular maps. |
| **Skip up to** | Textures whose longest side is at or below this are left alone (Nothing, 32, 64, 128, 256 px). |
| **Opaque DXT5 to DXT1** | When the alpha of a DXT5 texture is fully opaque, store it as DXT1. Half the memory, pixels stay identical. Not applied to normal maps. |
| **Compress uncompressed** | A8R8G8B8 and similar to DXT1, or to DXT5 when the alpha is soft. |
| **Rebuild missing mips** | Adds the missing mip levels, down to 4 px as the game expects. The full size level is not touched. |
| **BC5 for normal maps** | Stores normal maps as ATI2 (BC5). Cleaner normals at DXT5 size, but many GTA shaders expect RGB normals, so test in game first. |
| **Exclude textures** | Name patterns, one per line or comma separated. `*` matches anything, `?` one character. |
| **Re-encode quality** | High or Fast. Only used when pixels really have to change. |
Normal and spec maps are recognised by their usage and their name (for example `_n`, `_nrm`, `_normal`, `_s`, `_spec`).
Always left as they are: BC7 textures, script render targets and A8 / L8 masks. Nothing is ever upscaled, and a texture is only halved until it fits the cap.
## How textures get smaller
Most changes do not touch the pixels at all:
- **Dropping mip levels.** A 2048 texture with a mip chain already holds 1024, 512 and so on. Capping it at 1024 removes the top level, nothing is compressed again. Each step saves three quarters of the memory.
- **Opaque DXT5 to DXT1.** Looks identical, half the size.
- **Missing mips** are added below the full size level, which stays the same.
**Re-encoding** only happens when the pixels have to change: uncompressed textures, BC5 normals, DXT3, or a downscale of a texture without mips. The plan marks those with `(re-encoded)`.
Name, usage and flags of every texture stay as they were, and the texture count never changes. Files where no texture changes are not rewritten.
## Summary panel
- **Physical memory**: total before, and the planned (or, after a run, the real) total after, with the amount and percentage saved.
- **Files**: files read so far.
- **Textures to change**: how many textures the plan touches, out of all textures.
- **Over 16 MiB now** and **After**: how many files FXServer would warn about.
- **Optimize** starts the run (turns into **Cancel** while it runs; finished files keep their result). **All as zip** downloads the result. **Add** adds more files.
## File table
Sort by **Most saved**, **Biggest** or **Name**. **Clear** empties the list.
| Column | Meaning |
| --- | --- |
| **File** | File name and folder. Click to expand the texture plan. |
| **Textures** | Textures to change / total. |
| **Physical** | Physical memory now. |
| **After** | Planned size, the real size after a run, or the progress while it runs. |
| **Saved** | Memory saved. |
| **Largest** | Size and format of the biggest texture. |
| **Notes** | The FXServer warning level, plus counts of textures over the cap, with missing mips, uncompressed or not a power of two, and read warnings. |
After a run, a **.ytd** button downloads that single file.
### Texture plan
Expanding a file shows every texture with **Now** and **After** (size, format, mip count, memory), **Saved** and **What happens**, for example `2048x2048 to 1024x1024 (drops 1 mip), opaque DXT5 to DXT1, lossless`. Textures that stay the same say why: `Already within the rules`, `Excluded by name`, `Script render target`, `BC7 is kept as is`, `Not above 128 px` and so on. **Sort by savings** puts the biggest wins on top.
Untick a texture to leave it exactly as it is. Unticked textures are copied over untouched.
### Compare
After a run, click a texture name to open the compare view: the original on the left and the result on the right, drawn at the same size with pixelated scaling so lost detail is easy to see. Drag across the image or use the **Split** slider to move the divider, and tick **Show alpha** to compare the alpha too.
## Report
A Markdown report under the table sums it up: preset and rules, textures changed (and how many without re-encoding), physical memory before and after, how many files FXServer warns about before and after, and the 20 files with the biggest savings. **Copy for Discord** copies it, **.md** downloads `ytd-optimizer-report.md`. Before a run it shows the plan, marked `(planned)`.
```bash
**YTD optimizer report**
Preset: Balanced (max 2048, normal maps 1024, spec maps 1024, skip up to 128 px, opaque DXT5 to DXT1, compress uncompressed, rebuild mips, exclude script_rt_*)
Files: 42, textures changed: 318 of 1204 (291 without re-encoding)
Physical memory: 812.40 MiB -> 401.77 MiB, saved **410.63 MiB** (50.5%)
Files FXServer warns about (over 16 MiB): 17 -> 3
```
The numbers above are an example layout; yours come from your files.
## Output
**All as zip** is named after the top folder of your drop, for example `stream_optimized.zip` or `my_cars_optimized.zip`. It keeps your folder layout and includes every file that was read, changed or not, so you can extract it straight over a copy of the resource.
## Put the files back
1. Extract **All as zip** over a copy of the resource (or copy the single `.ytd` downloads into `stream/`, same names).
2. Restart the resource and look at the server console: the memory warnings for these files should be gone.
3. Drive around, look at a few cars, clothes or interiors up close.
4. Keep the originals until you checked the result in game.
```cfg title="server.cfg"
ensure my_cars
```
No manifest change is needed: the files keep their names and stay in `stream/`.
## Tips
- Start with **Balanced**. Go **Strict** only on packs where memory is the real problem, like 50 EUP uniforms.
- Emissive and livery textures with text or logos suffer first. Add them to **Exclude textures** (for example `*_livery*` or `*_sign_*`) if they get too soft.
- Sort by **Most saved**: often a handful of files hold most of the memory.
- Rerun on the same files after changing the rules; press **Optimize** again and the new rules apply to the originals.
## Common mistakes
- **Optimizing the only copy.** Always work on a copy and keep the originals until you checked the result in game.
- **BC5 normals without testing.** Many GTA shaders expect RGB normal maps. Leave **BC5 for normal maps** off unless you tested it.
- **Mixing old and new files.** Extract the zip over the whole folder so no old `.ytd` is left next to a new one with a different path.
## Limitations
- Only `.ytd` files. Textures embedded in `.ydr`, `.ydd` or `.yft` files are not changed.
- Files protected by the Cfx asset escrow are encrypted and can not be read.
- BC7 textures, script render targets and A8 / L8 masks are left as they are.
- Everything runs in your browser. No files are uploaded.
## Related tools
- [Texture Editor](/docs/tools/texture-editor) to fix or replace single textures by hand.
- [Vehicle Pack Validator](/docs/tools/vehicle-pack-validator) to check a vehicle pack before you ship it.
- [Profiler Analyzer](/docs/tools/profiler-analyzer) to find what really costs frame time on your server.
- [Clothing Designer](/docs/tools/clothing-designer) for clothing textures.
_Last updated: 2026-09-22_
---
## Native Audio Builder
URL: https://fivemad.com/docs/tools/native-audio-builder
Turn WAV, MP3 or OGG files into a FiveM native audio resource and play them from Lua on the UI, on an entity or at a position, synced if you want.
The Native Audio Builder turns your sound files into a complete FiveM resource that plays them as real game audio: the `.awc` wave bank, the `.dat54.rel` sound data, `fxmanifest.lua` with the right `data_file` lines, and Lua to load the bank and play sounds. No CodeWalker step is needed. It is for script devs who want custom sounds without a NUI page.
## What it is for
Most servers play custom sounds through NUI, a hidden browser page with an audio tag. That works, but the game does not know the sound exists: no 3D position, no distance falloff, no game volume slider, and every client runs a browser page for it. Native audio puts your files into the game's own audio system, so `PlaySoundFrontend`, `PlaySoundFromEntity` and `PlaySoundFromCoord` play them like any Rockstar sound.
Typical uses: phone ringtones and notification sounds, a siren or horn attached to a vehicle, an alarm at a bank that everyone nearby hears, UI clicks for a custom menu, door buzzers and radio chatter.
Looking for a base game sound instead? Use the [Sound Browser](/docs/tools/sound-browser).
## Quick start
1. Open the tool and use **Choose audio files** or **Choose folder**, or drag files or a folder onto the page.
2. Check each sound's **Name** and **Sound set**. These are the two strings you pass to the play functions.
3. Set **Resource name** in the **Bank** panel (for example `my_sounds`). The wave pack, data file and default sound set follow it.
4. Press play on a row to hear what the game will get.
5. Tick **Loop** for sounds that should repeat until you stop them.
6. Fix anything shown in red, then press **Download resource**.
7. Unzip, put the `my_sounds` folder in your resources, add `ensure my_sounds` and run `/my_sounds_test` in game.
## Input
- Formats: WAV, MP3 and OGG work everywhere. FLAC, M4A, AAC, Opus and WebM work when your browser can decode them. Other files are skipped with a count.
- Up to 200 sounds per bank.
- Stereo and multichannel files are mixed down to mono, and every file is converted to the bank's sample rate. The row shows the length, the channel change and the rate change (for WAVs), for example `2.40 s, 2 ch to mono, 44100 to 32000 Hz`.
- Each file becomes one sound named after the file: lowercase, anything other than letters and digits becomes `_`, cut at 48 characters. `Door Buzzer (2).wav` becomes `door_buzzer_2`. A second file with the same name in the same set gets `_2`, `_3` and so on.
- The sound set comes from the folder the file is in. Drop `in/phone/ring.mp3` and `in/alerts/beep.wav` and you get the sets `phone` and `alerts`. Files dropped without a folder go into the **Default sound set**.
- Sounds whose name contains `loop` or `alarm`, or that sit in a set called `ringtone` or `ringtones`, start with **Loop** on.
Drop more files anywhere on the page at any time to add them. **Clear** removes every sound.
> [!NOTE]
> Everything runs in your browser. Your audio is decoded and converted locally and the zip is built on your PC. Nothing is uploaded.
## The sound list
Each row has:
| Control | What it does |
|---|---|
| Play / Pause | Preview after conversion: sample rate, mono downmix, trimming, normalizing, the codec, the row's volume and loop. What you hear is close to what the game plays. |
| Name | The sound name, first argument of the play natives. Lowercase letters, digits, `_` and `-`. |
| Sound set | The sound set name. Lowercase letters, digits and `_`. Existing sets are suggested as you type. |
| Volume dB | Volume stored in the sound, from `-60` to `+6`. Default `0`. |
| Loop | The sound repeats until you call `StopNative` (or `StopSound`). |
| Remove | Removes the sound from the bank. |
Under each row you see a small waveform, the source file name, length and conversion info, and **Copy call**, which copies a ready line like `exports['my_sounds']:PlayNative('beep', 'my_sounds_set')`. Problems for that sound are listed right under it.
## Bank settings
| Setting | What it does | Default |
|---|---|---|
| Resource name | Folder name of the resource and the name you `ensure`. Lowercase letters, digits, `_` or `-`. Changing it also updates the three names below while you have not edited them yourself. | `my_sounds` |
| Wave pack | Folder that holds the bank inside `audio/`, and the first half of the bank path in Lua. | `dlc_my_sounds` |
| Bank | File name of the `.awc`, second half of the bank path. | `sounds` |
| Data file | File name of the `.dat54.rel`. | `my_sounds_sounds` |
| Default sound set | Set for files dropped without a folder. **Apply to all** puts every sound in this set. | `my_sounds_set` |
| Codec | **ADPCM** is 4x smaller and lossy. **PCM** is lossless and 4x bigger. | ADPCM |
| Sample rate | 48000, 44100, 32000, 24000 or 22050 Hz. Every sound in the bank uses the same rate. | 32000 Hz |
| Category | The mix group the game puts the sounds in: `scripted_louder` or `scripted`. | `scripted_louder` |
| Trim silence | Cuts silence at the start and end, so sounds fire on time. | on |
| Normalize | Raises or lowers each sound so its peak sits at -1 dBFS. | off |
| Synced playback | Adds `server.lua` to play a sound for every player nearby. | on |
| CodeWalker source | Adds the `.awc.xml`, `.rel.xml` and WAVs next to the resource, for editing later. | on |
Wave pack, Bank and Data file allow lowercase letters, digits and `_` only.
The summary card shows the number of sounds, the total length and an estimated `.awc` size. Changing the sample rate, trim or normalize reconverts every sound; the download button waits until that is done ("Converting audio...").
### Choosing codec and rate
- **ADPCM** is fine for effects, voice and most music. Very hard edged synth sounds (square waves) lose detail, use PCM for those.
- **32 kHz** keeps banks small and is plenty for effects and UI sounds. Use 44.1 or 48 kHz for music.
- The whole bank is loaded into memory when a script requests it. Keep long music or big packs in a bank of their own (a second resource) and load it only when you need it.
## Checks
Errors block the download, warnings do not.
| Level | Check |
|---|---|
| Error | Resource name, Wave pack, Bank or Data file with characters that are not allowed; sound name with characters other than lowercase a-z, 0-9, `_`, `-`; name over 64 characters; sound set with characters other than lowercase a-z, 0-9, `_`; the same name twice in one sound set; two names that clash inside the bank or with each other (rename one); a sound that is empty after conversion (for example pure silence with Trim on); volume outside -60 to +6 dB; a sound set that already exists in the base game; a file the browser could not decode. |
| Warning | A sound longer than 30 seconds (the whole bank sits in memory once loaded). |
## Output
### What is in the zip
**Download resource** saves `.zip`:
```text
my_sounds/
fxmanifest.lua
client.lua load the bank, play, stop, free
server.lua only with Synced playback
audio/dlc_my_sounds/sounds.awc the wave bank
audio/data/my_sounds_sounds.dat54.rel the sound data
codewalker_source/ only with CodeWalker source
sounds.awc.xml
sounds/*.wav
my_sounds_sounds.dat54.rel.xml
```
Put only the `my_sounds` folder in your server's resources. `codewalker_source` is for you, not for the server. The message under the button shows the exact size of the `.awc` and `.dat54.rel` after the download.
The code tabs under the list show `client.lua`, `server.lua` (with Synced playback), `fxmanifest.lua`, the `.rel.xml` and the `.awc.xml` before you download.
### fxmanifest.lua
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
description 'Native audio bank built with fivemad.com/tools/native-audio-builder'
client_script 'client.lua'
server_script 'server.lua'
files {
'audio/data/my_sounds_sounds.dat54.rel',
'audio/dlc_my_sounds/sounds.awc',
}
-- sound data: the path of the .dat54.rel without "54.rel"
data_file 'AUDIO_SOUNDDATA' 'audio/data/my_sounds_sounds.dat'
-- wave pack: the folder that holds the .awc bank
data_file 'AUDIO_WAVEPACK' 'audio/dlc_my_sounds'
```
```cfg title="server.cfg"
ensure my_sounds
```
> [!IMPORTANT]
> The `AUDIO_SOUNDDATA` path ends in `.dat`, not `.dat54.rel`, and `AUDIO_WAVEPACK` points at the folder, not the `.awc`. Both files must also be in `files { }`, or clients never download them. The generated manifest already does this, keep it that way if you merge it into another resource.
### client.lua
The generated `client.lua` loads the bank when the resource starts (it waits up to 10 seconds and prints an error if the bank does not load) and releases it when the resource stops. It defines these functions, all also available as exports:
| Function | What it does | Returns |
|---|---|---|
| `PlayNative(name, soundSet, loop)` | 2D sound (UI, phone, notifications) via `PlaySoundFrontend`. | sound id |
| `PlayNativeOnEntity(name, soundSet, entity, loop)` | 3D sound that follows a ped, vehicle or prop via `PlaySoundFromEntity`. | sound id |
| `PlayNativeAtCoords(name, soundSet, coords, range, loop)` | 3D sound at a position via `PlaySoundFromCoord`. `range` defaults to `20.0`. | sound id |
| `SetNativeVolume(id, volume)` | Changes the volume of a playing sound, `0.0` to `1.0`. | |
| `StopNative(id)` | Stops the sound and frees its id. | |
One shot sounds free their sound id by themselves when they finish. Looped sounds keep their id until you call `StopNative`, so store it. The `loop` argument only controls that cleanup; whether a sound actually repeats is set by the **Loop** toggle when you build the bank.
It also registers a test command named after the resource: `/my_sounds_test` plays every sound one after the other (looped ones for 5 seconds), `/my_sounds_test beep` plays just one.
## Examples
Inside the same resource (add your code to `client.lua` or another client script of the resource):
```lua title="client.lua"
-- UI sound
PlayNative('beep', 'my_sounds_set')
-- follows the vehicle
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
PlayNativeOnEntity('horn', 'my_sounds_set', veh)
-- heard up to 30 m from the bank door
PlayNativeAtCoords('alarm', 'my_sounds_set', vector3(150.2, -1040.5, 29.4), 30.0)
-- looped ringtone at half volume, stopped later
local id = PlayNative('ringtone', 'my_sounds_set', true)
SetNativeVolume(id, 0.5)
Wait(8000)
StopNative(id)
```
From another resource, use the exports:
```lua title="phone/client.lua"
local ring = exports['my_sounds']:PlayNative('ringtone', 'phone', true)
RegisterNetEvent('phone:answered', function()
exports['my_sounds']:StopNative(ring)
end)
```
### Synced playback
For everyone nearby to hear a sound, the server has to tell them. With **Synced playback** on, `server.lua` exports two functions that check each player's distance (needs OneSync) and send the sound only to players in range:
```lua title="bank_robbery/server.lua"
-- everyone within 30 m of the vault hears the alarm
exports['my_sounds']:PlayAtCoords('alarm', 'my_sounds_set', vector3(255.0, 225.0, 101.9), 30.0)
-- everyone within 30 m (the default) hears the horn on that networked vehicle
exports['my_sounds']:PlayOnEntity('horn', 'my_sounds_set', vehicle)
```
`PlayAtCoords` defaults to a 20 m range, `PlayOnEntity` to 30 m. The play natives also have an `isNetwork` argument, but it does not load your bank on the other clients, so the server event approach is the reliable one.
## Editing the bank later
With **CodeWalker source** on, the zip has everything to rebuild the bank in CodeWalker: open RPF Explorer, turn on edit mode, and drag `sounds.awc.xml` (with the `sounds` folder of WAVs next to it) and the `.dat54.rel.xml` into a folder. CodeWalker builds the binary files, drag them back into the resource. Or drop the WAVs into this tool again and download a new bank.
## Common mistakes
- **No sound at all.** The bank did not load: check the F8 console for "could not load audio bank", then check the `data_file` lines and that both files are in `files { }`. Restart the resource after changing the manifest and reconnect.
- **Wrong sound set or name.** Both strings are case sensitive in your scripts. Copy them with **Copy call**.
- **Sound plays only for you.** `PlayNative` is local. Use the server exports with Synced playback for sounds others must hear.
- **Looping sound never stops.** Keep the id returned by the play function and call `StopNative(id)`.
- **Name clash with the game.** Sound sets share one namespace with every game sound, so give them your own prefix. The tool refuses sets that already exist in the base game.
- **Huge bank.** A bank with ten minutes of music at 48 kHz is loaded into memory as a whole. Split music into its own resource.
## Limitations
- The page cannot play the finished `.awc` and `.rel` in the game itself, so test the resource on your own server before you ship it.
- Output is mono. Multichannel banks (the stereo format radio stations use) are not built here.
- One sample rate, codec and category per bank.
- Up to 200 sounds per bank.
- Files you drop are kept only for this page visit. After a reload, drop them again.
Based on [lb-nativeaudio](https://github.com/lbphone/lb-nativeaudio) by LB Scripts.
## Related tools
- [Sound Browser](/docs/tools/sound-browser) for base game sounds and sound sets
- [fxmanifest Generator](/docs/tools/fxmanifest-generator)
- [Vehicle Pack Validator](/docs/tools/vehicle-pack-validator) checks engine sound `data_file` lines in car packs
_Last updated: 2026-09-22_
---
## YMAP Builder
URL: https://fivemad.com/docs/tools/ymap-builder
Place props by coordinates or in a 3D world, get CodeWalker ready .ymap XML with correct rotations and extents, and stream it from a FiveM resource.
The YMAP Builder turns a list of props and positions into a `.ymap` placement file without opening a map editor. You paste coordinates from the game (or place props in the 3D world), set heading or full rotation, and the tool writes CodeWalker XML with the quaternions, entity extents, streaming extents and map flags already calculated. It is for server owners and devs who want a few benches, barriers or decorations streamed with the map instead of spawned by a script.
## What it is for
Props spawned with `CreateObject` live in a script: they need a thread, they need cleanup, and every client creates them again. A ymap is part of the map itself. The game streams it in when you get close and drops it when you leave, with no script at all. The catch is the file format: rotations are stored as an inverted quaternion, extents have to cover every entity plus its draw distance, and the map flags depend on the LOD levels you use. Get one of those wrong and props face the wrong way, pop out early or never load. This tool handles those parts so you only think about model, position and heading.
Typical jobs:
- Decorating a spot (benches, bins, barriers, plants) around an MLO or a job location.
- Turning a list of `vector4` spawn points from your config into static props.
- Editing an existing ymap XML: fix a rotation, move a group of props, change `lodDist` on everything.
## Quick start
1. Add the helper from **Grab positions in game** (bottom of the page) to a client script on your dev server. Stand where a prop should go and run `/ymappos`, or look at an existing prop and run `/ymapprop`. Finish with `/ymapdump`.
2. In **Import**, keep the **Coordinates** tab, paste the lines, pick a **Default model** and press **Add**.
3. Fine tune rows in **Entities**, or select several and use the bulk edit bar. Open **3D world** (desktop) to move them with a gizmo inside the GTA V map.
4. Set **Name** in the **Ymap** panel. It becomes the file name.
5. Check the warnings under the preview, then press **Download** on the **XML** tab of **Export**. You get `.ymap.xml`.
6. Convert it to a binary `.ymap` with CodeWalker (see the **Convert** tab), put it in `stream/` of a resource and `ensure` it.
The page starts with three sample props at Vespucci Beach so you can see the output before adding your own. Your work is saved in the browser (local storage) and comes back when you reopen the page.
## Panels
### Ymap
| Field | What it does | Default |
| --- | --- | --- |
| **Name** | Ymap name and file name (`stream/.ymap`). Lowercase letters, digits, `_` and `-` only; anything else is replaced on export. Must be unique across all your resources. | `my_props` |
| **Parent** | Parent ymap name, written to ``. Leave empty for standalone props. | empty |
| **Assumed entity radius (m)** | The tool does not know model sizes, so this radius (times the entity scale) stands in for each prop when the extents are filled in. Raise it for big props. | `10` |
| **lodDist when set to -1 (m)** | Entities with `lodDist -1` use the model's own draw distance. The extents still need a number, so this one is used. | `150` |
| **Scripted (flags 1)** | Sets map flag 1. The game then only loads the ymap after `RequestIpl('name')`. Leave it off for props that should always be there. | off |
**Undo** reverts the last structural change (add, delete, duplicate, reorder, import, bulk edit, 3D edits), up to 40 steps. Typing in a field is not recorded, to keep the history useful. **Clear** removes every entity, and Undo brings them back.
### Entities
Each row has a model field (with autocomplete from the vanilla objects list), `x`, `y`, `z` and `heading`. A model name that is not in the objects list is marked, and the row number turns amber when the row has a warning.
- **Add** appends a row 2 m east of the last one, with the same z and heading, using the model, flags and lodDist from the import defaults.
- Paste a whole `vector3(...)`, `vector4(...)` or a `/ymapprop` line into the **x** field and it fills x, y, z, heading (and pitch, roll and model when the line has them).
- The row buttons duplicate (the copy sits 1 m east) or delete that row. The chevron opens **More fields**.
- The checkbox bar on top selects rows. With a selection you get move up, move down, duplicate and delete for all of them, plus the bulk edit bar.
- Long lists show 60 rows at a time with a **Show more** button.
**More fields** per entity:
| Field | Written to | Notes |
| --- | --- | --- |
| **Rotation**: Heading only / Pitch / roll / yaw | `rotation` | Pitch/roll/yaw adds `pitch` and `roll` inputs and renames heading to `yaw`. The stored quaternion is shown next to it. |
| **lodDist** | `lodDist` | Draw distance in metres. `-1` uses the model's own value. Default `100`. |
| **childLodDist** | `childLodDist` | Only matters for LOD parents. Default `0`. |
| **priority** | `priorityLevel` | `REQUIRED`, `OPTIONAL_HIGH`, `OPTIONAL_MEDIUM`, `OPTIONAL_LOW`. |
| **lodLevel** | `lodLevel` | `ORPHANHD` for standalone props. HD, LOD and SLOD levels are for LOD chains. |
| **AO multiplier** | `ambientOcclusionMultiplier` | 0-255, default 255. |
| **artificial AO** | `artificialAmbientOcclusion` | 0-255, default 255. |
| **tint** | `tintValue` | Texture variation, same as `SetObjectTextureVariation`. |
| **scale xy / z** | `scaleXY`, `scaleZ` | Default 1. |
| **flags** | `flags` | Number field plus a preset menu and a **Flag bits** list with every known bit. |
Flag presets:
| Preset | Value | Use |
| --- | --- | --- |
| Static + shadows | `1572896` | Frozen prop that casts shadows. The default for new rows. |
| Static | `32` | Frozen prop, CodeWalker's default. |
| Dynamic + shadows | `1572864` | Physics on (if the model has physics), like most vanilla props. |
| Dynamic | `0` | Physics on, no extra bits. |
If an entity is tilted (pitch or roll not zero), flag `1` (allow full rotation) is added on export, and the flags editor says so. Without it the game ignores pitch and roll.
For entities loaded from an XML, `guid`, `parentIndex`, `numChildren` and any `extensions` block are kept and written back unchanged.
### Bulk edit
With rows selected, the bar under the toolbar edits all of them at once. Empty fields stay unchanged, offsets are added.
- **model**, **flags** (presets), **lodDist**, **priority**, **lodLevel**: replace the value.
- **offset x**, **offset y**, **offset z**: add to the position (move a whole group).
- **rotate heading by**: adds degrees to each heading. **set heading**: sets one heading for all (wins over rotate).
- **Apply to N** runs it, **Reset** empties the bar.
### Import: Coordinates
Paste one entity per line. It accepts `vector3`, `vector4`, `vec3`/`vec4`, `{x = , y = , z = , w = }`, JSON objects or arrays and plain numbers. A model name, `model=` or `rot=vector3(pitch, roll, yaw)` on the same line is picked up too. Model hashes are turned back into names when they are vanilla props, otherwise into `hash_XXXXXXXX`.
```lua
vector4(-1386.72, -1004.23, 3.86, 125.0)
{x = -1383.35, y = -1008.94, z = 3.86, w = 125.0}
prop_bin_07a vector3(-1385.1, -1006.62, 3.86)
model=prop_bench_01a pos=vector3(-1374.0, -1018.5, 3.86) rot=vector3(0.0, 0.0, 125.0)
```
| Option | What it does | Default |
| --- | --- | --- |
| **Default model** | Used for lines without a model. | `prop_bench_01a` |
| **Heading if missing** | Used for lines without a heading (vector3). | `0` |
| **Z offset (m)** | Added to every z. The **-1** link sets it for player coords. | `0` |
| **Flags for new rows** | Flag preset for the imported rows. | Static + shadows |
| **lodDist for new rows** | lodDist for the imported rows. | `100` |
**Add N** appends, **Replace all** replaces the list. Lines it cannot read are counted and the first five are listed.
### Import: Ymap XML
**Open .ymap.xml** or paste XML and press **Load pasted XML**. It replaces the current entities (Undo brings them back). Get the XML from CodeWalker: RPF Explorer, right click the ymap, Export XML. Rotations are read the way CodeWalker stores them and shown as in-game heading or pitch/roll/yaw. Sections the builder does not edit (car generators, occluders, LOD lights, time cycle modifiers and so on) are kept and written back as they were.
### Top-down preview
An SVG plan of every entity. The line on each dot shows its heading. Click a dot to jump to its row, Shift or Ctrl click to add it to the selection. The solid box is the entity extents; tick **Streaming extents** to also draw the dashed streaming box (the area in which the ymap is loaded).
### Warnings
The list under the preview checks your ymap as you edit. Click a warning to select the rows it is about.
- Missing or invalid name, empty model, invalid numbers.
- Models not in the vanilla objects list (fine for custom props, otherwise a typo).
- Two entities within 1 cm of each other, entities outside the playable map, entities at 0, 0.
- A ymap spanning a very large area, or more than 1000 entities (split it by area).
- `lodDist` under 20 m.
- HD levels without a LOD parent (use `ORPHANHD` for standalone props).
- Tilted entities that get flag 1 on export (info).
### 3D world
The **3D world** button in the preview panel (desktop only) opens the ymap inside the GTA V world at the top of the page, starting next to the active entity. Props that have a model in the Objects List show as the real mesh, others as a box of their real size (or a 1 m box). Everything you do there updates the entity list and the export right away, and Undo works for moves, rotations and placed props.
| Control | What it does |
| --- | --- |
| Click a prop | Select it (it becomes the active row). Shift , Ctrl or Cmd click adds it to the selection. |
| **Move** or G | Move gizmo (world axes). Drag an arrow or plane. |
| **Rotate** or T | Rotate gizmo (local axes). Heading-only entities only get the vertical ring; switch the row to Pitch / roll / yaw to tilt it. |
| **Place** | Pick a model, then click the ground to drop it. A ghost follows the mouse and the coordinates under it are shown. R turns it 15 degrees (Shift R the other way), Esc stops placing. |
| **Snap to ground** | Drops the selected entities (or the active one) so the model's lowest point rests on the ground or roof under it. Entities with no loaded ground under them are skipped and counted. |
| **Focus** | Moves the camera to the active entity. |
| Right mouse drag, W A S D | Look and move the freecam. Clicking does not capture the mouse here, so you can click props. |
The camera, quality setting and full screen work the same as in the [3D world](/docs/tools/world-3d) docs. **Close 3D** hides the panel again.
## Output
### Export tabs
- **XML**: a stats line (`entities`, map `flags`, `contentFlags`, entity extent size) and the full CMapData XML. **Download** saves it as `.ymap.xml`.
- **Resource**: the folder layout, a ready `fxmanifest.lua`, and a `client.lua` with `RequestIpl` when **Scripted** is on.
- **Convert**: the CodeWalker steps below.
Each entity is written like this (a `prop_bench_01a` at heading 125):
```xml title="my_props.ymap.xml"
-
prop_bench_01a
LODTYPES_DEPTH_ORPHANHD
PRI_REQUIRED
```
### Converting with CodeWalker
Browsers cannot write the binary ymap format, so CodeWalker does the last step:
1. Put `.ymap.xml` in your resource's `stream` folder. Keep the double extension, CodeWalker uses it to know the file type.
2. Open CodeWalker's **RPF Explorer**, then **File, Open Folder** and pick that stream folder.
3. Turn on **Edit mode**, then **Edit, Import XML** (or drag the file into the window) and choose the XML.
4. CodeWalker writes `.ymap` next to it. Delete the `.xml` from stream.
5. `ensure` the resource and reconnect.
To check it first, open CodeWalker's world view, use the Project window, **File, Open Files** to load the ymap and fly to it.
### The resource
```text
my_props/
├── fxmanifest.lua
└── stream/
└── my_props.ymap <- binary, converted with CodeWalker
```
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
name 'my_props'
description 'Props streamed with my_props.ymap'
-- A .ymap inside stream/ is picked up on its own, nothing else is required.
-- this_is_a_map 'yes' reloads the map store when the resource starts. Only add it
-- if you replace vanilla map files or ship map data files.
-- this_is_a_map 'yes'
```
```cfg title="server.cfg"
ensure my_props
```
With **Scripted** on, the manifest adds `client_script 'client.lua'` and the tool gives you:
```lua title="client.lua"
-- The ymap has the "scripted" flag, so the game only loads it on request.
CreateThread(function()
RequestIpl('my_props')
end)
-- Later, to remove the props again:
-- RemoveIpl('my_props')
```
## Grabbing positions in game
The **Grab positions in game** panel gives you `ymap_helper.lua`, a client script for your dev server:
| Command | Output |
| --- | --- |
| `/ymappos` | Your position snapped to the ground (`GetGroundZFor_3dCoord`) plus heading, as `vector4(...)`. |
| `/ymapprop` | Model hash, position and rotation (`GetEntityRotation(ent, 2)`) of the object in front of the camera, found with a shape test ray of 30 m. |
| `/ymapdump` | Prints every collected line so you can paste them all at once. |
| `/ymapclear` | Forgets the collected lines. |
Each line is printed to the F8 console and chat. Tick **Copy to clipboard (ox_lib)** to also copy it with `lib.setClipboard` (needs ox_lib). Every line it prints is a format the importer reads. Remove the helper before going live.
> [!NOTE]
> `/ymapprop` only finds props the game spawned as objects. Static map geometry is not an object and will not be hit by the ray.
## Rotation
Enter rotations the way you read them in game: heading from `GetEntityHeading`, or pitch, roll and yaw from `GetEntityRotation(entity, 2)`. Heading 0 faces north and 90 faces west. The tool writes the quaternion a ymap expects, so you never type one yourself. The expanded row shows the value that will be written, if you want to compare it with another file.
When you open the result in CodeWalker, its entity panel shows the stored rotation as is, so its Euler Z reads minus your in-game heading. That is normal, the prop still faces the heading you entered.
## Common mistakes
- **Props float 1 m in the air.** `GetEntityCoords(PlayerPedId())` is at the pelvis. Use `/ymappos` (ground snapped) or set **Z offset** to -1 when importing.
- **Props face the wrong way.** Someone wrote the heading straight into the quaternion without inverting it. Import the XML here and headings are read correctly.
- **Props vanish when you walk away.** lodDist too low, or the streaming extents were not recalculated after moving things. The builder recalculates them on every change.
- **Nothing shows up.** The file in `stream/` is still the `.xml`, the name clashes with another ymap, or **Scripted** is on and nothing calls `RequestIpl`.
- **Custom props are invisible.** The ymap only places them. Their `.ydr`, `.ytd` and `.ytyp` must be streamed too.
- **One huge ymap.** The whole file streams in as soon as you enter its extents. Keep one ymap per area.
- **Changes do not show.** Reconnect. Map files load when you join, a resource restart is not always enough.
> [!TIP]
> You do not need `this_is_a_map 'yes'` to add props. It only matters when you replace vanilla map files.
## Limitations
- Output is CodeWalker XML. You still need CodeWalker to make the binary `.ymap`.
- The tool does not know model sizes, so extents use the **Assumed entity radius**. Raise it for big props.
- No LOD chain authoring (parents, LOD models), occluders, car generators or MLO interiors. Those sections are only passed through from an imported XML.
- The 3D world needs a desktop browser with WebGL 2, and it does not include Cayo Perico or North Yankton.
- Everything runs in your browser and is saved locally. Nothing is uploaded.
## Related tools
- [Objects / Props List](/docs/tools/objects-list): find model names, sizes and 3D previews.
- [3D world](/docs/tools/world-3d): camera modes, keys and performance tips for the 3D view.
- [Interactive Map](/docs/tools/interactive-map): grab coordinates without starting the game.
- [YTYP Creator](/docs/tools/ytyp-creator): archetypes for custom props you place with a ymap.
- [fxmanifest Generator](/docs/tools/fxmanifest-generator)
_Last updated: 2026-09-23_
---
## Minimap Editor
URL: https://fivemad.com/docs/tools/minimap-editor
Shape, place and style the FiveM minimap in the browser, see it over the real Los Santos map, and download a ready resource with the mask textures and Lua.
The Minimap Editor builds a complete minimap resource for your server. You pick the shape, place it on a real screen, style the border and the rings, and download a folder you can drop straight into `resources`. The preview draws over our own render of the Los Santos map, so what you judge is what players get.
## Quick start
1. Pick one of the presets at the top: **Classic round**, **Square modern**, **Minimal**, **Big square for RP** or **Hex tactical**.
2. Open the **Shape** tab and choose a silhouette, or upload your own mask image.
3. Open **Layout** and drag the minimap in the preview until the spacing looks right.
4. Switch the screen size above the preview between 1080p, 1440p and 21:9 to check all three.
5. Style the border and the rings, then press **Download resource**.
6. Unzip, put the folder in `resources`, add `ensure ` to your `server.cfg` and restart.
## The tabs
### Shape
Thirteen shapes, all drawn by the tool: circle, square, rounded square, squircle, octagon, two hexagons, diamond, pill, notched, blade, shield, and your own image.
- **Corner radius**, **Squareness** and **Cut size** appear only for the shapes that use them.
- **Edge softness** feathers the edge of the mask, so the map fades out instead of stopping on a hard line. A value of 0 gives a razor edge, 8 to 15 gives a soft one.
- **Mask texture size** is how sharp the exported mask is. 512 is enough for almost everything, 1024 helps a very soft edge on a large map.
- **Your own image**: a PNG with alpha, or a black and white picture. Only the silhouette is used, the colours in it never show up in game. The file is read in your browser and is never uploaded.
- **Blip clipping** is a separate setting from the mask. The mask cuts the map, this cuts the blips. Pick the option closest to your shape or blips will hang over the edge.
### Layout
- **Anchor** picks the screen corner or edge to measure from. Bottom left is where the game puts it.
- **Offset X, Offset Y, Width, Height** are fractions of the screen, the same units the game uses. X is measured over a 16:9 width, Y over screen height, which is why an ultrawide monitor gets the same minimap further from the centre.
- **Mask inset** shrinks the visible map inside its frame, useful when you want a thick border that eats into the edge.
- **Backing plate** is the dark panel behind the map. Size, spread and softness are separate so you can go from a tight drop shadow to a wide fade.
- **Expanded map** sets the size of the bigger map players toggle with the map key.
- **Raw component rows** shows the six rectangles the resource writes. Turn the link off and type exact numbers if you are matching an existing design.
Dragging inside the preview moves the minimap. It only works while the link is on.
### Style
- **Border** and **inner line**. The inner line is a darker stroke just inside the border, it stops the map bleeding into the border colour. Thickness is in pixels at 1080p and scales up on bigger screens.
- **Glow** puts a soft colour halo behind the border. Keep it under 15 px unless you want it obvious.
- **Plate colour** and opacity control the panel behind the map.
- **Map tint** lays a colour over the map. It also tints the blips, so keep the strength low. The blend modes behave the way they do in an image editor: multiply darkens, screen lifts, colour recolours while keeping the brightness.
- **Night colours** is a second full set of colours. Set the hours and the resource switches over by the game clock.
### Rings
First decide what happens to the game's own health and armour arcs:
| Setting | What happens |
| --- | --- |
| Keep | The arcs stay exactly as the game draws them |
| Recolour | The arcs stay, with the colours you set on the Game tab |
| Hide | The arcs are hidden, your own rings replace them |
Then add up to six rings. Each one has:
- **Value key**: `health`, `armour`, `stamina` and `oxygen` fill themselves. Any other key is filled by your own script.
- **Style**: *Follow shape* runs along the outline of your mask, *Arc* runs along a circle whatever the shape is, *Bar* sits under the map as a straight line.
- **Colour**, **track colour** and track opacity.
- **Thickness** and **gap from the border**, both in pixels at 1080p.
- **Start** and **Length**, measured as a percent of the outline starting at the top, plus the direction. Two rings at 50 percent and 0 percent going opposite ways give you the classic left and right arcs.
- **Rounded ends** and **glow**.
- **Preview value** is only for the preview.
To drive a ring of your own from Lua:
```lua title="somewhere in your script"
exports['fivemad_minimap']:SetMinimapRing('hunger', 0.62)
```
### Game
- **When the radar shows**: always, only in a vehicle, or off so your own script decides.
- **Zoom** is `SetRadarZoom`. 0 keeps the game default, higher values show less ground. The **Range** slider above the preview is separate and only changes how much map the preview draws.
- **Lock north up** stops the map turning with the player.
- **Reveal the whole map** clears the fog of war on join.
- **HUD colours**: tick an entry to override it. These are `hudcolor.dat` entries set by index, and the resource puts the originals back when it stops.
- **Hide HUD elements**: the cash, stars, street names and the rest. The preview shows a struck out box for each one you hide.
## What is in the zip
```
fivemad_minimap/
fxmanifest.lua
config.lua every value, with a comment on each one
client.lua applies the config in game
README.md
textures/
radarmasksm.png mask for the small map
radarmasklg.png mask for the expanded map
ui/
index.html the overlay page
style.css
app.js draws the border and the rings
shape.json the outline of your shape
mask.png
border.png your border art
minimap-project.json open this back in the editor later
```
The mask is not streamed as a `.ytd`. The client builds a runtime texture from the PNG and swaps it in over the game's own mask, so nothing in the game is replaced and the originals come back when the resource stops. If you would rather have a real `.ytd`, take the PNG into the [Texture Editor](/docs/tools/texture-editor).
The border, the glow and the rings are drawn by the small overlay page in `ui/`. The game has no native for any of them. The page never asks for NUI focus, so it cannot eat a click.
## Saving and sharing
- Your work autosaves in this browser as you edit.
- **Save** writes a `.minimap.json` project file, **Open** loads one back.
- **Share** copies a link with the whole setup in it. Send it to someone and they open your exact minimap.
- The project JSON is also inside the zip, so you can always get back to the editor from the resource folder.
## Limits worth knowing
- **Land and sea colour** come from the game's own map textures, not from a HUD colour. The tint layer is an approximation over the top, a real recolour means replacing those textures.
- **The health and armour arcs cannot be restyled**, only hidden or recoloured. They live inside `minimap.gfx`, and rebuilding that movie breaks with every game update. Hide them and use your own rings instead.
- **Only one resource can own the minimap.** If another HUD resource also calls `SetMinimapComponentPosition`, load this one after it, or call `exports['fivemad_minimap']:ApplyMinimap()` once the other one is done.
- **The preview is a layout preview**, not a screenshot. The map inside the minimap is real, the space around it is deliberately empty.
- Cayo Perico and North Yankton are not in the preview map.
## Related
- [Texture Editor](/docs/tools/texture-editor) to put the mask into a `.ytd`
- [Blip, Marker and Checkpoint Browser](/docs/tools/blip-marker-browser) for the blips that sit on the map
- [Scaleform Functions](/docs/tools/scaleform-reference) for the other `minimap` movie calls
_Last updated: 2026-09-23_
---
## Zone Creator
URL: https://fivemad.com/docs/tools/zone-creator
Draw a zone on the real GTA V map in 2D or 3D and copy ready code for ox_lib zones, PolyZone, ox_target and qb-target, or the points as Lua or JSON.
The Zone Creator draws a zone on the actual Los Santos map, in 2D or in the 3D world, and hands you the code for whichever zone library your server uses. Nothing is uploaded and nothing needs a game client: you click where the zone belongs, set the two heights against the real ground, and copy the block.
## Quick start
1. Pick a shape: **Polygon**, **Box**, **Circle** or **Sphere**.
2. Click the map to drop corners (polygon) or to place the centre (the other three).
3. Switch to **Edit** and drag things into place. Set **minZ** and **maxZ** on the right, or press **Sit on the ground here** to put the band on the floor under the zone.
4. Open the output for your library at the bottom and copy it.
Switch to **3D world** on a desktop to see the zone as the solid it really is and check it clears the counter or the fence.
## Drawing and editing
| Action | How |
| --- | --- |
| Add a corner | **Add points** mode, click the map or the ground in 3D |
| Move a corner | **Edit** mode, drag it |
| Add a corner on an edge | **Edit** mode, drag the edge where you want the new corner |
| Delete a corner | Right click it, or use the bin in the Points list |
| Move the whole zone | **Edit** mode, drag from inside the shape |
| Set the heights in 3D | Drag the two flat discs in the middle of the zone |
| Undo / redo | Ctrl + Z and Ctrl + Y |
Changing shape keeps the zone where it is, so a polygon you drew turns into a box on the same spot.
## Heights
`minZ` and `maxZ` are world z, the same numbers `GetEntityCoords` returns. The panel shows the ground height under the zone, read from the same height data the map uses, so the numbers mean something instead of being a guess.
> [!TIP]
> A band from about a metre below the floor to two metres above it covers a player standing there. Go wider if people arrive by car, or if the floor slopes.
A **sphere** has no band. It is a ball around its centre, so it uses the centre z and the radius, and the two height fields are hidden.
## The outputs
Every tab says which library and version it was written against, and the comments at the top of each snippet list the `fxmanifest.lua` lines that library needs.
### ox_lib
`lib.zones.poly`, `lib.zones.box` and `lib.zones.sphere`, with `onEnter`, `onExit` and `inside` stubbed out.
Two things about ox_lib worth knowing, because the tool handles them for you:
- A poly zone is **flat**. Every point is put on one z and the height comes from `thickness`, which is the **total** height centred on that plane. So a band from 28 to 34 becomes points at z 31 with `thickness = 6.0`.
- `size` on a box is the **full** size, and `rotation` is the heading in degrees.
```lua title="client.lua"
local my_zone = lib.zones.box({
name = 'my_zone',
coords = vec3(213.94, -935.61, 31.0),
size = vec3(10.0, 14.0, 6.0),
rotation = 340.0,
debug = true,
onEnter = function(self)
print('entered ' .. self.name)
end,
onExit = function(self)
print('left ' .. self.name)
end,
inside = function(self)
-- runs every frame while the player is inside
end,
})
```
### PolyZone
`PolyZone:Create`, `BoxZone:Create` or `CircleZone:Create`, with an `onPlayerInOut` handler. `BoxZone` takes `(center, length, width, options)`: **length runs along the heading, width across it**, which the tool works out from the box you drew.
```lua title="client.lua"
local my_zone = PolyZone:Create({
vector2(207.74, -943.21),
vector2(230.1, -943.21),
vector2(230.1, -925.4),
}, {
name = 'my_zone',
minZ = 28.0,
maxZ = 34.0,
debugPoly = true,
})
my_zone:onPlayerInOut(function(isPointInside, point)
if isPointInside then
print('entered my_zone')
end
end, 500)
```
### ox_target and qb-target
The same zone as an interaction, with one option ready to edit: a label, a Font Awesome icon, a distance and a client event. Set those four in the tool and they land in the snippet.
ox_target uses ox_lib underneath, so its zone keys are ox_lib's. qb-target uses PolyZone, so its zone options are PolyZone's, and the interaction lives in a separate `targetoptions` table.
### Lua table and JSON
Just the numbers, for your own inside test or a library that is not listed here.
## Shapes a library does not have
- **ox_lib has no cylinder.** A circle is written as a sixteen sided polygon with a thickness, which is a real bounded cylinder.
- **PolyZone's `CircleZone` takes no `minZ` or `maxZ`.** With `useZ = false` it only tests x and y, so it has no top and no bottom; with `useZ = true` it is a ball. If the height matters, use a polygon there.
## Point order
Neither library needs a particular winding. ox_lib reverses a clockwise ring itself before it splits the polygon into triangles, and PolyZone's inside test does not care either way. The panel shows which way round your points run and there is a **Reverse order** button, which is useful when you are matching a list you already have.
What does matter is that the ring is **simple**: no edge may cross another. The tool flags a crossing and tells you which two edges do it.
## Bringing a zone back in
Paste any of these into the box at the bottom and press **Load it onto the map**:
- An ox_lib, ox_target, PolyZone or qb-target snippet
- The JSON this tool produces
- A plain list of `vector2` or `vector3` lines, or rows of `x, y` numbers
Only the shape and the heights are read back. Callbacks, target options and job checks are not.
## Share links
**Share link** puts the whole zone in the URL, so you can send it to whoever is writing the script and they open it exactly as you drew it. The link only carries what differs from the defaults, so it stays short.
## Limits
- One zone at a time. Putting several into a `ComboZone` is something you do in your own code.
- A self intersecting polygon is drawn and flagged, but no library can test it correctly. Fix the crossing first.
- Over roughly 400 metres across, or past about 40 points, the per frame inside test starts to cost real time. Split the area into a few zones, or use a box.
- The 3D view needs a desktop browser with WebGL 2. The 2D map works everywhere.
_Last updated: 2026-09-23_
---
## Server Status Checker
URL: https://fivemad.com/docs/tools/server-status-checker
Check whether a FiveM server is online by IP:port or cfx.re join code, and read its players, game build, OneSync, resources and server variables.
The Server Status Checker looks up any FiveM server by IP:port, host name or cfx.re join code and tells you whether it is online, who is playing, which game build and OneSync mode it runs, its resource list and its public server variables. Server owners use it to check their own server from outside; players and devs use it to peek at any public server.
## What it is for
- Checking from the outside that your server is reachable after a restart, a host move or a firewall change.
- Finding the game build, OneSync setting or resource list of a server you want to compare against.
- Getting the join code and F8 `connect` line of a server to share.
- Checking a player count before you hop on.
## Quick start
1. Type an address or join code in the **Server** box.
2. Press **Check status** (or Enter ).
3. Read the summary card, then use the tabs below it for players, resources, variables or the raw data.
## What you can enter
| Input | Example |
| --- | --- |
| IP and port | `51.75.12.34:30120` |
| IP only (uses port 30120) | `51.75.12.34` |
| Host name and port | `play.myserver.com:30120` |
| Join link | `https://cfx.re/join/abc123` or `cfx.re/join/abc123` |
| Bare join code | `abc123` |
An IP or host name is asked directly. A join code goes through the Cfx.re server list, which also works for servers behind a proxy or a firewall that blocks direct HTTP. The summary shows which one was used: **via direct** or **via cfx.re list**.
Every lookup gets its own link with `?q=`, for example `/tools/server-status-checker?q=cfx.re/join/abc123`, so you can share a link that opens straight on the result. **Copy share link** copies it for you.
## The summary card
When the server is online you get:
- **Online** plus how it was reached, the response time in ms and how long ago it was fetched (with **(cached)** when the result came from the short cache).
- The hostname with its FiveM colour codes rendered, the project description, the server icon and the `banner_detail` image if the server sets one.
- **Players**: current and max slots with a fill bar (amber at 95 % and up).
- A row with **Game** (GTA V, RedM (RDR2) or LibertyM (GTA IV)), **Game build** (`default` when none is enforced), **OneSync** (On or Off), **Gametype**, **Map** and **Locale**.
- **Server** (the FXServer version string), **Endpoint** and **F8 connect**, all click to copy.
Buttons under it:
| Button | What it does |
| --- | --- |
| Connect | Opens `fivem://connect/...` so the FiveM client joins the server |
| Server list | Opens the server's page on servers.fivem.net (only with a join code) |
| Refresh | Checks again |
| Copy share link | Copies the `?q=` link |
| Make a badge | Opens the [Server Status Badge](/docs/tools/server-uptime-badge) tool with this server filled in |
**Auto-refresh every 30 seconds** keeps the result updated while the tab is open.
## Tabs
| Tab | What it shows |
| --- | --- |
| Players | ID, name (colour codes rendered) and ping, coloured green under 80 ms, amber under 150 ms, red above. Search by name or exact ID. |
| Resources | Every started resource the server publishes, sorted A-Z, click to copy, with search. |
| Variables | The `banner_detail` and `banner_connecting` images, the server tags, and every public `sets` variable with search. |
| Raw JSON | The whole result as JSON (the icon is shortened) for copying. |
Many servers hide player names and pings. In that case the tab says **Players (hidden)** and the tool shows only the count. Player identifiers (license, steam, discord, ip) and `sv_licenseKeyToken` are always removed from results.
## When it says offline
The result card tells you what went wrong: **Offline**, **Timed out**, **Not listed**, **Invalid input**, **Not allowed** or **Slow down**, with a **Retry** button.
- **Wrong port.** The game port is usually `30120`. `40120` is txAdmin, not the game.
- **Firewall.** FiveM needs both TCP and UDP open on the game port.- **Proxy.** Servers using `sv_forceIndirectListing`, a reverse proxy or a DDoS shield often do not answer plain HTTP. Check the join code instead.
- **Not listed.** A join code only resolves while the server is online and listed. A private server (`sv_master1 ""`) can only be checked by IP.
- **Not allowed.** Private and local addresses (`192.168.x.x`, `10.x.x.x`, `127.0.0.1` and so on) cannot be checked from the internet.
```cfg title="server.cfg"
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"
```
These are the usual endpoint lines. Make sure both are in your config and that your host's firewall allows TCP and UDP on that port.
## Limitations
- Results are cached for about 30 seconds, so a fresh restart can take a moment to show.
- Each visitor gets 30 lookups per minute. Auto-refresh keeps the last result on screen if you hit the limit.
- The tool only sees what the server makes public. Hidden player lists stay hidden.
## Related tools
- [Server Status Badge](/docs/tools/server-uptime-badge) to show your live player count on a website or README.
- [Cfx Blacklist Checker](/docs/tools/cfx-blacklist-checker) when a server will not show up in the list at all.
- [FXServer artifacts](/docs/tools/artifacts) to see whether the server version in the summary is a recommended build.
- [server.cfg Generator](/docs/tools/server-cfg-generator) for endpoints, OneSync and game build settings.
_Last updated: 2026-09-22_
---
## Profiler Analyzer
URL: https://fivemad.com/docs/tools/profiler-analyzer
Record a FiveM profile with profiler record and saveJSON, then read time per resource, worst frames, hitches, a flame graph and findings with fixes.
The Profiler Analyzer reads the JSON file the built-in FiveM profiler saves and turns it into a report you can act on: which resources eat your frame or tick time, which frames were the worst and what ran in them, which events and threads are heavy, when hitches happened, and plain advice on what to fix. It works for both server and client recordings and runs entirely in your browser.
## What it is for
`resmon` tells you a resource averages 0.8 ms, but not why, not when, and not what it looked like in the frame where the game stuttered. The profiler records all of that, but its raw output is hard to read. Use this tool when:
- Players report lag or rubber banding and you need to know which resource is responsible.
- The server console prints hitch warnings and you want to know whether a script caused them.
- You changed a resource and want proof that it got faster (the Compare tab).
- You want to share a short, readable summary with a script's developer.
## How to record a profile
FiveM has a profiler built in on both sides. It records every resource tick and event handler with microsecond timing, including escrowed resources. The **How to record** card next to the drop zone has the same commands with copy buttons for **Server console** and **Client F8**.
### Server (txAdmin Live Console or the FXServer window)
```bash
profiler record 1200
profiler status
profiler saveJSON lag.json
```
1. `profiler record 1200` records 1200 ticks. The server runs 20 ticks per second, so that is one minute. Use `600` for a quick look.
2. `profiler status` shows whether it is still recording. It stops by itself.
3. `profiler saveJSON lag.json` writes the file next to your `server.cfg` with txAdmin, or wherever FXServer was started.
Record while the server is busy. Problems that only show with players online will not show on an empty server.
### Client (F8 console)
```bash
profiler record 1000
profiler status
profiler saveJSON lag.json
```
Stand where the game feels bad and do the laggy thing while it records. 1000 frames is 8-16 seconds depending on your FPS. The file ends up in `%localappdata%\FiveM\FiveM.app\citizen\lag.json`.
Client recordings store a small screenshot per frame, so they get big fast. Files of a few hundred MB are fine here.
### Other profiler commands
| Command | What it does |
| --- | --- |
| `profiler record start` / `profiler record stop` | Record until you stop it |
| `profiler resource myresource 300` | Records Lua function calls of one resource (`*` for all). Slower, but shows which function is heavy |
| `profiler view` | Opens the raw trace in Chrome DevTools for a manual look |
| `profiler save name` | Writes a binary file this tool cannot read. Use `saveJSON` |
## Quick start
1. Record a profile as above.
2. Drop the `.json` on the page, or press **Choose a file**. A gzipped `.json.gz` works too.
3. Read the verdict at the top, then the **Findings** tab.
4. Click the worst bars on the timeline to see exactly what ran in those frames.
No file handy? **Try a sample** loads a made-up server recording so you can look around. Its resource names are invented.
## The report
### File bar
Shows the file name, size, number of events and how long it took to read. Buttons:
| Button | What you get |
| --- | --- |
| Copy for Discord | A short summary that fits in one Discord message (2000 characters) |
| Report .md | `-report.md`, the full report as Markdown |
| Timeline .png | `-timeline.png`, a picture of the current timeline |
| Open another | Load a different file. You can also drop a new file anywhere on the page |
### Verdict
A one-line status (**Healthy**, **Some pressure**, **Struggling** or **Overloaded**), a title and a sentence explaining it. **Read as** shows whether the file was detected as a **Server** or **Client** recording and why; switch it if the guess is wrong.
The card on the right shows:
- **Scripts per tick (or frame), average**: the big number.
- **p95 / p99**: how bad the slow ticks or frames get.
- **Worst tick / frame**: click it to open that frame.
- **FPS, avg / 1% low** on the client, or **Tick interval, p99** on the server.
- **Hitches**, and how many of them came from scripts.
- **Recorded** (ticks or frames) and **Length**.
### Timeline
One bar per tick or frame. Two views:
- **Script time**: what resources spent in each frame or tick.
- **Tick interval** (server) or **Frame time** (client): the time between two ticks or frames for the whole server or game.
Amber and red mark the budgets below, and guide lines show 50 ms (a whole tick) or 60 and 30 FPS. Hover a bar for the numbers and the top three resources in it. Click a bar to open that frame. Drag to zoom, Ctrl + scroll to zoom, Shift + scroll to pan. Under the chart, **Worst ticks / frames** lists the eight worst with their time in the recording.
When you select a resource in the Resources tab, its own time is drawn in white on top of the timeline.
### Frame detail
Opens under the timeline when you click a bar or a worst-frame button. It shows:
- **Scripts**, **Resource Manager Tick**, and **Until next tick** (server) or **Frame time** with the FPS pace (client), marked heavy, over budget or hitch when they are.
- A flame chart of exactly what ran in that frame, in order, left to right. Colours mark the type: frame, resource tick, event handler, thread or function. Hover a block for its duration, start and file lines. Click a block to zoom in, **Whole tick / frame** to zoom out.
- On client recordings, the screenshot the game took at the end of that frame.
- **Heaviest resources in this frame**: click one to open it in Resources.
Use the arrows to step to the previous or next frame.
## Tabs
### Findings
Rules that read the numbers and point at problems, grouped as **Fix first**, **Worth fixing** and **Good to know** (filter with the buttons at the top). Each finding lists the evidence and a concrete fix, with **Open resource** and buttons that jump to the frames involved. They cover:
- Scripts taking a big part of every tick or frame.
- A resource running code every frame (the `Wait(0)` loop pattern).
- Heavy event handlers and heavy NUI callbacks.
- Events that fire constantly or very often.
- Spikes that repeat on a timer, and one-off big spikes.
- Resources that run many small threads.
- Hitches caused by scripts, and hitches not caused by scripts (streaming, the host, garbage collection).
- Resources with no detail (JS and C#), Lua memory that keeps growing, short recordings and unclosed scopes.
If nothing stands out you get **Nothing stands out**, with the tip to record during the laggy moment or on the other side (client vs server).
### Resources
A sortable table of every resource:
| Column | Meaning |
| --- | --- |
| Share | Share of all script time in the recording |
| Avg | Average ms per frame or tick over the whole recording, the same thing `resmon` shows |
| Worst | Most time spent in a single frame or tick |
| Events | Time spent in event handlers |
| Calls | Number of calls |
| Active | Share of frames or ticks where it ran |
Times are exclusive: when resource A triggers an event in resource B, B's handler counts for B, not twice. Filter by name; the table shows 60 rows until you press **Show all**.
Click a resource to open its detail: average, p95, worst and total time, **Its worst ticks / frames**, **What triggered it** (every tick, or which events, with calls, average, worst and total), **Threads, handlers and functions** with file and line numbers, and the Lua heap at the start and end when the file has it.
### Flame graph
The whole recording merged by call path. The wider a block, the more total time it took. Hover for total, per tick or frame, share of all, self time and calls. Click a block to zoom in and use the path at the top to go back. **Highlight a name** marks every block that matches a resource or file and shows how much time the matches take in total.
### Compare
Did your fix work? The loaded file is **before**. Drop a second recording taken after your change, ideally the same length and in the same spot, on **Drop the "after" profile**. You get:
- A summary: scripts per tick or frame (average and 99th percentile), worst tick or frame, average FPS on the client and hitches per minute, each marked better, worse or about the same.
- **Per resource, average ms per tick / frame** with before, after and the change. Green means less time after the change.
Numbers are per tick or frame, so two recordings of different length still line up. A warning shows if you compare a client recording with a server one. **Remove after** clears the second file.
## Budgets
| | Client | Server |
| --- | --- | --- |
| Frame or tick | 16.7 ms at 60 FPS | 50 ms (20 ticks per second) |
| Scripts get heavy at | 4 ms per frame | 25 ms per tick |
| Hitch | a frame over 50 ms | ticks over 150 ms apart (the console's hitch warning) |
| One resource worth a look | 0.1 ms per frame, heavy from 0.5 ms | 0.5 ms per tick, heavy from 2 ms |
**Script time** is what resources spent in a frame or tick. **Frame time** and **tick interval** cover everything. When the gap is big but script time is small, the stall came from somewhere else, and the findings say so instead of blaming a script.
## Examples
The most common finding is a loop that runs every frame even when it has nothing to do:
```lua title="client.lua"
-- runs every frame, all the time
CreateThread(function()
while true do
Wait(0)
local coords = GetEntityCoords(PlayerPedId())
if #(coords - shopCoords) < 2.0 then
DrawMarker(2, shopCoords.x, shopCoords.y, shopCoords.z, 0, 0, 0, 0, 0, 0, 0.3, 0.3, 0.3, 255, 255, 255, 150, false, true, 2, false, nil, nil, false)
end
end
end)
```
```lua title="client.lua"
-- only runs every frame while the player is close
CreateThread(function()
while true do
local sleep = 1000
local coords = GetEntityCoords(PlayerPedId())
if #(coords - shopCoords) < 10.0 then
sleep = 0
DrawMarker(2, shopCoords.x, shopCoords.y, shopCoords.z, 0, 0, 0, 0, 0, 0, 0.3, 0.3, 0.3, 255, 255, 255, 150, false, true, 2, false, nil, nil, false)
end
Wait(sleep)
end
end)
```
Record again after a change like this and drop both files into **Compare**.
## Tips
- Record on the side where the problem is. Client FPS drops need a client recording; server hitch warnings need a server one.
- Record for long enough to catch the problem. A short recording gets a **Short recording** note.
- For a resource that shows as heavy but has no named threads, run `profiler resource 300` for function-level detail.
- The profiler adds a little overhead itself, so absolute numbers run slightly high. Compare recordings made the same way.
## Limitations
- The file never leaves your browser. There is no upload and no shared leaderboard.
- Only Lua threads and handlers get names. JS and C# resources show up as a total per resource.
- Files from `profiler save` (binary) cannot be read; use `profiler saveJSON`.
- The sample file is synthetic, not a real server.
## Related tools
- [Server Status Checker](/docs/tools/server-status-checker) to check the server from outside while you debug.
- [FXServer artifacts](/docs/tools/artifacts) in case the hitches come from a known broken server build.
- [fxmanifest Generator](/docs/tools/fxmanifest-generator) when a finding points at how a resource is set up.
_Last updated: 2026-09-22_
---
## Cfx Blacklist Checker
URL: https://fivemad.com/docs/tools/cfx-blacklist-checker
Check whether an IP, host name or cfx.re join code is on the Cfx.re platform blacklist, up to 20 at once, before you rent a VPS or when a server vanishes.
The Cfx Blacklist Checker tells you whether an IP address is on the Cfx.re platform blacklist. Paste IPs, host names or cfx.re join codes, up to 20 at once, and each address comes back as blacklisted or not. It is for server owners picking a host, moving to a new IP, or wondering why their server is missing from the list.
## What the Cfx.re blacklist is
Cfx.re keeps a list of IP addresses that may not run public FiveM or RedM servers, usually addresses tied to abuse, ban evasion or hosting ranges that were used for it. A server on a blacklisted IP does not show up in the server list, and players get an error when joining. The blacklist is about the machine the server runs on, not about the players on it.
## When to check
- **Before renting a VPS or dedicated server.** Ask the host for the IP first and check it here. Cheap reseller plans and recycled IPs are the usual suspects.
- **When your server vanishes from the list** after moving hosts or getting a new IP.
- **Before buying a used IP block.**
## Quick start
1. Paste one or more addresses in **IPs, host names or join codes**, one per line (spaces and commas work too).
2. Press **Check**, or Ctrl + Enter .
3. Read the result list: every address gets **Blacklisted**, **Not blacklisted** or **Could not check**.
## What you can paste
| Input | What happens |
| --- | --- |
| `51.75.12.34` | Checked directly. IPv4 and IPv6 both work. |
| `play.myserver.com` | Every public A and AAAA record of the host is checked, so one host can give several rows. |
| `cfx.re/join/abc123` or `abc123` | Looked up to the server's address, then checked. |
Up to 20 inputs per check.
## Reading the results
The header says how many addresses were checked and how many are blacklisted or could not be checked. Each row shows:
- The IP (click to copy).
- Under it: the host name it came from, the reverse DNS name when there is one, and a note when something went wrong: a private or reserved address, a host name that did not resolve or has no public IP, a join code that was not found, or a server that hides its address behind a proxy.
- The state on the right.
| State | Meaning |
| --- | --- |
| Blacklisted | This IP may not host a public server. |
| Not blacklisted | The IP is not on the list right now. |
| Could not check | The input could not be turned into a public IP, or the check failed. See the note. |
The footer shows when the check ran. Every check gets its own link with `?q=`, so you can send the result to your host's support: `/tools/cfx-blacklist-checker?q=51.75.12.34`.
> [!TIP]
> The reverse DNS name often tells you which hosting company owns an IP. Handy when a join code resolves to an address you do not recognise.
## If your IP is blacklisted
- Ask your host for a different IP. Most hosts can swap it, and it is their range that is flagged.
- If you think the listing is a mistake, contact Cfx.re support through the forum with your server details.
- Changing ports does not help: the check is by IP.
## Limitations
- Servers behind a proxy hide their address, so a join code check for them comes back as **Could not check** with a note saying so. Check the real IP directly if you know it.
- Private and reserved addresses (LAN, `127.0.0.1`, `192.168.x.x` and so on) are not checked.
- Results are cached for 10 minutes, so a fresh change on Cfx.re's side can take a moment to show.
- A clean result only means the IP is not blacklisted now. It says nothing about the host's network quality.
## Related tools
- [Server Status Checker](/docs/tools/server-status-checker) to see whether a server answers at all.
- [FXServer artifacts](/docs/tools/artifacts) to pick a good server build for the new machine.
- [server.cfg Generator](/docs/tools/server-cfg-generator) to set up the config on a fresh host.
_Last updated: 2026-09-22_
---
## Server Status Badge
URL: https://fivemad.com/docs/tools/server-uptime-badge
Build a live SVG badge, card or signature square with your FiveM server's logo, player count and a Join button, and embed it with Markdown, HTML or BBCode.
The Server Status Badge tool makes a live image of your FiveM server: `402/700 players` while it answers, `offline` when it does not. You pick the shape, the artwork and the colours, and copy a ready snippet for a GitHub README, a website or a forum thread.
## What it is for
- A status card with your logo and a Join button at the top of your server's website or Tebex store.
- A small badge in a GitHub README for a server or a public config repo.
- A compact square for a forum.cfx.re signature, with BBCode.
The badge is not a historical uptime percentage. It shows the state at the moment it was loaded, and it updates about once a minute wherever it is embedded.
## Quick start
1. Enter your server in **Address or join code**: `ip:port`, `host:port`, `cfx.re/join/abc123` or just the join code.
2. Pick a starting point under **Start from**. **Dark card** is the one most people want.
3. Adjust **Shape**, **What it shows**, **Artwork** and **Colours**.
4. Check the **Live preview**. It shows the real image on a dark and a white plate, with its true pixel size.
5. Copy one of the snippets under **Embed**.
If you came from the [Server Status Checker](/docs/tools/server-status-checker), **Make a badge** opens this tool with your server already filled in.
## The three shapes
| Shape | What it looks like | Good for |
| --- | --- | --- |
| **Badge** | The small shields style strip with the count on the right | A README line, next to build badges |
| **Card** | Logo, server name, player bar, Join button | A website header, a README title block |
| **Square** | A tile with a player ring and your logo | Forum signatures, a sidebar |
## Your server logo
With a **cfx.re join code**, the badge uses the icon your server already shows in the FiveM server list. Nothing to upload, nothing to configure. Animated icons are drawn as one still frame so the badge stays small.
If your server has no icon, or you are badging it by `ip:port`, pick **Own picture** under **Artwork**. Your file is shrunk in the browser and travels inside the badge link, so keep it simple: the tool tells you how long the link has become and warns you when it gets too long for some forums.
**Backdrop** puts artwork behind a card or a square:
- **Icon, faded** blows up the same logo. It costs nothing extra.
- **Server banner** uses the banner your server advertises in `banner_detail`. We fetch it and put it in the image. If it is missing, slow, not an image or bigger than 96 KB, the badge drops it and still looks right.
> [!TIP]
> A badge with a banner is a much heavier image than a plain one. On a page where the badge loads on every visit, the icon backdrop is the cheaper choice.
## Options
| Group | Option | What it does |
| --- | --- | --- |
| Shape | Shape | Badge, card or square |
| | Style | Badge only: Flat, Square, Big |
| | Theme | Card and square: Dark or Light |
| | Size | Renders the badge bigger or smaller, from 0.5x to 3x |
| | Corner radius | Rounds the corners, 0 for sharp |
| | Text size / Width | Text size on a badge, fixed width on a card or square |
| What it shows | Player count | `402/700`, a bar, a ring, a percentage, or hidden |
| | Use the server name | Your server name as the label or title, colour codes stripped |
| | Game type, Map name, Last updated | Extra lines on a card or square |
| | Join button | Card only, needs a join code |
| | Extra line | Your own text, for example your Discord invite |
| Artwork | Logo | Server icon, none, or your own picture |
| | Backdrop | None, the icon faded, or your server banner |
| Colours | Online, Offline, Join button, Background, Text, Border | Every part separately |
Offline keeps its own colour whatever you pick for online, so a server that is down never shows up green.
## Embed snippets
The **Embed** panel gives you four versions, each with a copy button. With a join code the link goes to `https://cfx.re/join/` so a click opens FiveM. With an IP it links to the Server Status Checker page for your server.
### Markdown (GitHub README)
```markdown
[](https://cfx.re/join/abc123)
```
### HTML (website)
```html
```
### BBCode (forums)
```text
[url=https://cfx.re/join/abc123][img]https://fivemad.com/api/badge/abc123.svg?shape=square[/img][/url]
```
### Image URL
Just the image link, for places that only take an image URL.
## Editing the link by hand
Everything you set ends up in the image link, so you can tweak an existing badge without coming back to the tool:
```text
https://fivemad.com/api/badge/.svg?shape=card&players=bar&logo=server&art=banner
```
| Part | Values |
| --- | --- |
| `` | Join code (`abc123`), `ip:port` or `host:port` |
| `shape` | `badge` (default), `card`, `square` |
| `style` | Badge only: `flat` (default), `flat-square`, `for-the-badge` |
| `theme` | Card and square: `dark` (default) or `light` |
| `players` | `count`, `bar`, `ring`, `percent`, `none` |
| `logo` | `server`, `none`, or a `data:image/...` picture |
| `art` | `none`, `icon`, `banner` |
| `label` | Left text or card title. `hostname=1` uses your server name. |
| `sub` | Your own extra line |
| `map`, `mode`, `updated`, `join`, `border` | `1` or `0` |
| `scale`, `radius`, `font`, `width` | Size, corner radius, text size, fixed width |
| `color`, `offline`, `bg`, `bg2`, `fg`, `muted`, `accent`, `bcolor`, `labelColor` | Hex without `#`, or a colour name like `blue` |
The tool page takes the same options, so `/tools/server-uptime-badge?q=abc123&shape=card&art=banner` opens the editor on that design. Old badge links keep working: `label`, `style`, `color`, `labelColor` and `hostname` still mean what they did.
For example, a big blue badge with your server name:
```text
https://fivemad.com/api/badge/abc123.svg?style=for-the-badge&color=blue&hostname=1
```
## Tips
- Check the preview on both plates. A card set to the light theme disappears on a white page unless you keep the border on.
- Shorter titles read better. On a badge, `status` or your server tag often looks cleaner than the full hostname.
- **Size** is the cheapest way to make a card look sharp on a high resolution screen: 2x renders the same design at twice the pixels.
- GitHub shows README images through its own image cache, so a badge there can lag a few minutes behind.
## Limitations
- **Discord does not show SVG images**, neither in chat previews nor in embeds, and there is no PNG version yet. For Discord, link your [Server Status Checker](/tools/server-status-checker) page or use a bot that posts the player count.
- The badge updates about once a minute, not in real time. There is a limit of 120 badge requests a minute per address.
- The logo, the banner and the Join button need a **join code**. An `ip:port` badge shows the player count and the name only.
- It only knows what your server makes public. If the server does not answer from outside, the badge shows offline even when players on your LAN can join.
## Related tools
- [Server Status Checker](/docs/tools/server-status-checker) for the full picture: players, resources, variables.
- [Cfx Blacklist Checker](/docs/tools/cfx-blacklist-checker) if your server is up but missing from the list.
- [Generators](/docs/tools/generators) for a server name and a coloured `sv_hostname`.
_Last updated: 2026-09-23_
---
## FXServer artifacts
URL: https://fivemad.com/docs/tools/artifacts
Find the recommended FXServer artifact, see which builds have known issues, download for Windows or Linux and update your server step by step.
The FXServer artifacts page answers one question every server owner asks: which server build should I run? It shows the recommended artifact with direct Windows and Linux downloads, lists every build with known issues, and lets you look up any artifact number to see whether it is safe.
## What it is for
FXServer (the FiveM and RedM server) ships as numbered builds called artifacts. New ones come out often, and now and then one has a bug: crashes, voice not working, clients failing to connect. Use this page:
- Before you update, to pick a build without reported issues.
- When your server started acting up right after an update, to see if your build is on the issues list.
- When a resource says it needs "artifact 12345 or newer", to find and download a matching build.
## Quick start
1. Open [/artifacts](/artifacts). The **Recommended artifact** card shows the build number.
2. Press **Windows** or **Linux** under **Download** to get that build.
3. Follow the update steps below for your OS.
## The recommended artifact
The big number is the build most server owners should run. A new artifact is not recommended straight away: it waits a short period so server owners have time to report problems, and the recommended one is the newest build that cleared that window with no reported issues. The question mark button next to the number explains the same thing.
When a newer build exists, the card also shows **latest build** with its number. Newer is not always better; the latest one may simply not have been tested long enough yet.
## The build table
Every build is listed newest first, 10 per page, with a tag:
| Tag | Meaning |
| --- | --- |
| RECOMMENDED | The recommended build (highlighted) |
| OK | No reported issues |
| ISSUE | A build or range of builds with a known problem; the description says what |
| BUILD | A build that failed to build upstream. Hidden unless **Failed builds** is on |
| N/A | Not a valid artifact number (search results only) |
Controls above the table:
- **All** shows every build. **Issues only** shows just the builds with known problems, with a count.
- **Failed builds** shows or hides builds that never finished building.
- **Artifact number** looks up one build. Type a number and you get its tag, the reason if it has an issue, and download links if it is fine.
Rows with no issues have Windows and Linux download buttons on the right, and the five newest also show their release date. Click a build number to copy it.
> [!NOTE]
> The build list is loaded from GitHub, which allows 60 requests an hour per visitor. If you page through a lot of builds you may see **GitHub rate limit reached** with a time to try again. The **Issues only** view keeps working in the meantime.
## How to update FXServer
The rule for both systems: replace the contents of your **artifacts folder** (the server binaries), never your **server-data** folder (resources, `server.cfg`, database). Keep a copy of the old artifacts folder until the new build has run for a while.
### Windows
1. Download **Windows** from the page. You get `server.zip`.
2. Stop the server (in txAdmin, stop it and close the FXServer window).
3. Rename your current artifacts folder as a backup, for example `server` to `server_old`.
4. Make a new empty folder with the old name and extract `server.zip` into it.
5. Start `FXServer.exe` again (or your usual start script / txAdmin shortcut).
6. Check the console for the new build number.
### Linux
1. Download **Linux** from the page. You get `fx.tar.xz`. On a server without a browser, right click the button to copy the link and fetch it with `wget`.
2. Stop the server.
3. Move the old artifacts folder aside and extract the new one in its place:
```bash
cd /home/fivem
mv server server_old
mkdir server && cd server
wget -O fx.tar.xz " "
tar xf fx.tar.xz
rm fx.tar.xz
```
4. Start it again with `./run.sh` from the artifacts folder (or your txAdmin service).
The folder names are examples; use whatever your setup calls them. If the new build misbehaves, stop the server and swap the old folder back.
> [!TIP]
> Found a bad build? The page links a **Report an issue** form, and the **Update guide** button opens a longer walkthrough. Reports end up in the shared issues list, so every server owner gets warned.
## Let your server check itself
Further down the page there is a Lua snippet with a **Copy** button. Drop it into any server script. On start it reads the running build from the `version` convar, asks the public artifacts database about it and prints a warning in the server console if the build has known issues:
```lua title="server/artifact_check.lua"
CreateThread(function()
local build = GetConvar('version', ''):match('v1%.0%.0%.(%d+)')
if not build then return end
PerformHttpRequest('https://artifacts.jgscripts.com/check?artifact=' .. build, function(code, body)
if code ~= 200 or not body then return end
local data = json.decode(body)
if data and data.status == 'BROKEN' then
print(('^1[artifacts] Build %s has known issues: %s^0'):format(build, data.reason or 'unknown'))
print('^3[artifacts] Recommended build: https://fivemad.com/artifacts^0')
else
print(('^2[artifacts] Build %s has no reported issues.^0'):format(build))
end
end, 'GET')
end)
```
The same database has a free JSON API (no key, no signup), described on the page, if you want the recommended build or the broken list in your own tools.
## Limitations
- The issues list only knows what server owners reported. A build marked OK can still have a problem nobody has hit yet.
- If the artifacts database cannot be reached, the card says **Could not load** and the downloads stay disabled. Try again later.
- Download links point straight at the official Cfx.re artifact server; nothing is re-hosted.
Artifact data comes from the open source FiveM Artifacts DB by JG Scripts.
## Related tools
- [Server Status Checker](/docs/tools/server-status-checker) to see which server version a running server reports.
- [Profiler Analyzer](/docs/tools/profiler-analyzer) to find out whether lag after an update comes from scripts or not.
- [server.cfg Generator](/docs/tools/server-cfg-generator) for game build and OneSync settings that go with a new artifact.
_Last updated: 2026-09-22_
---
## joaat Hash Calculator
URL: https://fivemad.com/docs/tools/hash-calculator
Turn any model, weapon or asset name into its GTA V joaat hash in unsigned, signed and hex form, one at a time or as a bulk Lua table.
The joaat Hash Calculator turns any string into the 32-bit hash GTA V uses for it, the same value `GetHashKey`, `joaat` and the Lua backtick give you in game. It is for anyone who needs a hash outside the game: comparing a value from a log, filling a config, or building a lookup table for a script.
## What it is for
GTA V (and RDR2) identify models, weapons, animations, components and most other assets by a Jenkins one-at-a-time hash of their lower-cased name. You meet those numbers everywhere: `GetEntityModel` returns one, weapon events carry one, and dumps print them in different formats. When a script prints `-1216765807` and you want to know if that is `adder`, or when you need a hash table for a whitelist, this tool gives you the number without starting the game.
## Quick start
1. Open the tool. The **Single** tab is selected, with `adder` already typed in.
2. Type your string in the **String** field. The **Result** panel updates on every key press.
3. Click any value in the result to copy it.
4. For many names at once, switch to **Bulk**, paste one name per line, pick an **Export format** and copy the generated `hashes.lua`.
## Single mode
The **Result** panel shows four rows for the current string:
| Row | Example for `adder` | Notes |
| --- | --- | --- |
| **Unsigned** | `3078201489` | The raw 32-bit value, 0 to 4294967295. |
| **Signed (int32)** | `-1216765807` | Same bits read as a signed int32. What most natives return and many dumps print. |
| **Hex** | `0xB779A091` | Always `0x` plus 8 upper-case digits. |
| **Lua backtick** | `` `adder` `` | Your string lower-cased inside backticks, ready to paste into Lua. |
The input is lower-cased before hashing, exactly like the game does, so `ADDER`, `Adder` and `adder` all give the same result. `WEAPON_PISTOL` and `weapon_pistol` are the same hash too.
## Bulk mode
Paste one string per line in **One string per line**. Empty lines are skipped and spaces around each line are trimmed. The panel title shows how many hashes were computed, and the table lists each name with its **Signed** and **Hex** value (click to copy).
Below the table, **Export format** (**Hex**, **Signed** or **Unsigned**, default Hex) controls the value used in the generated `hashes.lua` block:
```lua title="hashes.lua"
local Hashes = {
adder = 0xB779A091,
zentorno = 0xAC5DF515,
WEAPON_PISTOL = 0x1B06D571,
mp_m_freemode_01 = 0x705E61F2,
prop_bench_01a = 0x6BA514AC,
}
```
Names that are valid Lua identifiers become plain keys. Anything else (a name with a dash or starting with a digit) is written as `["name"]`, so the table always parses.
## Examples
Reverse lookup of a model you got from the game, using a table built in bulk mode:
```lua title="client.lua"
local Names = {
[`adder`] = "adder",
[`zentorno`] = "zentorno",
}
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
local model = GetEntityModel(veh)
print(Names[model] or ("unknown model %d"):format(model))
```
The backtick is resolved when the script is compiled, so it costs nothing at runtime:
```lua
local model = `adder`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false)
SetModelAsNoLongerNeeded(model)
```
## Signed vs unsigned
The hash itself is unsigned, but natives hand it to Lua as a signed int32, so `GetEntityModel` on an Adder returns `-1216765807`, not `3078201489`. Both are the same model. In Lua, compare against the backtick or `GetHashKey` result instead of a hard-coded unsigned number, and the sign never gets in the way. Hex literals like `0xB779A091` are positive in Lua 5.4, so a table keyed by hex will not match a signed value from a native. Pick **Signed** as the export format when you compare against values returned by natives.
> [!TIP]
> Use **Signed** when the table is compared with `GetEntityModel`, `GetSelectedPedWeapon` or event payloads. Use **Hex** when you want readable values in a config that is only passed back into natives.
## Common mistakes
- Hashing a display name. `Adder` is fine because case does not matter, but "Truffade Adder" is not the model name. Use the spawn name.
- Adding spaces or a file extension. `adder.yft` hashes to something else entirely.
- Comparing a signed value from a native with an unsigned or hex constant.
## Limitations
- The tool only hashes. It does not look a hash up to find the name. For vehicles, peds and weapons, the [Model & Hash Browser](/tools/model-hash-browser) lists spawn names next to their signed, unsigned and hex hashes.
- Everything runs in your browser. Nothing you type is sent anywhere.
## Related tools
- [Model & Hash Browser](/docs/tools/model-hash-browser)
- [Weapon Stats & Components](/docs/tools/weapon-stats)
- [Objects / Props List](/docs/tools/objects-list)
- [Player Stats List](/docs/tools/player-stats)
_Last updated: 2026-09-22_
---
## Driving Style Calculator
URL: https://fivemad.com/docs/tools/driving-style-calculator
Build and decode the driving style integer for TaskVehicleDriveToCoord, TaskVehicleDriveWander and SetDriveTaskDrivingStyle, with every flag bit listed.
The Driving Style Calculator combines vehicle AI flags into the single integer the driving tasks expect, and decodes any value you find in someone else's script. It also writes a ready Lua snippet for the task you pick, for the player's own car or an NPC driver.
## What it is for
A driving style is a 32-bit number where each bit switches one AI behaviour: stop for cars, obey lights, use shortcuts, drive in reverse. You pass it to `TaskVehicleDriveToCoord`, `TaskVehicleDriveToCoordLongrange`, `TaskVehicleDriveWander`, or change a running task with `SetDriveTaskDrivingStyle`. Guessing numbers like `786603` by hand is slow, and reading one back is worse. This tool does both directions.
## Quick start
1. Pick a **Preset** (the page opens on **Normal**, `786603`) or tick the flags you want.
2. Read the result in the **Driving style** panel: **Decimal**, **Hex**, **Binary**, plus **Signed int32** when bit 31 is set.
3. In **Snippet options**, choose the **Task**, the **Driver** (**Player** or **NPC**) and the **Destination** (**Waypoint** or **Coords**).
4. Copy `driving_style.lua` from the code block under the calculator.
To decode, paste a value into **Decode a value**. It accepts decimal, negative int32, `0x` hex, `0b` binary and expressions like `1 | 2 | 128` (a `+` works as well). Underscores are ignored. The value is kept in the URL as `?v=`, so you can share a link to it.
## Flags
| Bit | Value | Name | What it does |
| --- | --- | --- | --- |
| 0 | 1 | StopForVehicles | Brakes and waits behind vehicles in its way. |
| 1 | 2 | StopForPeds | Stops for pedestrians on the road. |
| 2 | 4 | SwerveAroundAllVehicles | Swerves around moving and stopped vehicles instead of waiting. |
| 3 | 8 | SteerAroundStationaryVehicles | Steers around parked and empty vehicles. |
| 4 | 16 | SteerAroundPeds | Steers around pedestrians instead of stopping. |
| 5 | 32 | SteerAroundObjects | Steers around props on the road. |
| 6 | 64 | DontSteerAroundPlayerPed | Does not steer around the player: stops or hits it. |
| 7 | 128 | StopAtTrafficLights | Obeys red lights and stop lines. |
| 8 | 256 | GoOffRoadWhenAvoiding | May leave the road to get around something. |
| 9 | 512 | AllowGoingWrongWay | Uses oncoming lanes when its own lane is blocked. |
| 10 | 1024 | Reverse | Drives the whole route in reverse. |
| 11 | 2048 | UseWanderFallbackInsteadOfStraightLine | Wanders if no route is found, instead of a straight line. |
| 12 | 4096 | AvoidRestrictedAreas | Keeps out of restricted zones. |
| 13 | 8192 | PreventBackgroundPathfinding | Cruise tasks: no background re-planning. |
| 14 | 16384 | AdjustCruiseSpeedBasedOnRoadSpeed | Cruise tasks: matches each road's speed. |
| 15 | 32768 | Unknown15 | No known effect. |
| 16 | 65536 | Unknown16 | No known effect. |
| 17 | 131072 | Unknown17 | No known effect. |
| 18 | 262144 | UseShortCutLinks | Allows dirt tracks, alleys and other shortcut links. |
| 19 | 524288 | ChangeLanesAroundObstructions | Changes lanes to pass slower traffic. |
| 20 | 1048576 | Unknown20 | No known effect. |
| 21 | 2097152 | UseSwitchedOffNodes | Routes over nodes switched off for traffic (goto tasks only). |
| 22 | 4194304 | PreferNavmeshRoute | Navmesh pathing for off-road, roughly 200 m around the player. |
| 23 | 8388608 | PlaneTaxiMode | Planes on a goto task taxi on the ground. |
| 24 | 16777216 | ForceStraightLine | Ignores pathing, heads straight for the target. |
| 25 | 33554432 | UseStringPullingAtJunctions | Cuts corners through junctions. |
| 26 | 67108864 | Unknown26 | No known effect. |
| 27 | 134217728 | Unknown27 | No known effect. |
| 28 | 268435456 | Unknown28 | No known effect. |
| 29 | 536870912 | TryToAvoidHighways | Avoids highways when there is another way. |
| 30 | 1073741824 | ForceJoinInRoadDirection | Always joins a road in the direction of traffic. |
| 31 | 2147483648 | StopAtDestination | Brakes to a stop at the destination. |
Each flag row in the tool also shows older community names under "Also known as" (for example `DF_StopForCars`, or "Use blinkers" for bit 8). Unknown bits can be hidden with **Show unknown bits**. **All on**, **All off** and **Invert** work on the defined bits.
## Presets
| Preset | Value |
| --- | --- |
| Normal | 786603 |
| Strict | 262275 |
| Ignore lights | 786475 |
| Avoid vehicles | 786469 |
| Reckless | 786468 |
| Avoid, obey lights | 786597 |
| Avoid, stop for peds, lights | 786599 |
| Rushed | 1074528293 |
| Off-road allowed | 2883621 |
| Avoid highways | 537657515 |
| Plough through | 262144 |
| Straight line | 17039360 |
Under the flag list, **Values used in Rockstar's scripts** holds 39 raw values from the decompiled scripts. Click one to load and decode it.
## Snippet options
| Option | What it does | Default |
| --- | --- | --- |
| **Task** | `TaskVehicleDriveToCoord`, `TaskVehicleDriveToCoordLongrange`, `TaskVehicleDriveWander` or **SetDriveTaskDrivingStyle only** | TaskVehicleDriveToCoord |
| **Driver** | **Player** uses your current vehicle (you must be the driver). **NPC** adds a `SpawnDriver()` function that spawns an `adder` with `a_m_y_business_01` in front of you. | Player |
| **Destination** | **Waypoint** reads blip sprite 8, **Coords** uses the x, y, z fields. Only for the two goto tasks. | Waypoint |
| **Speed (m/s)** | Cruise speed, with km/h and mph shown under it. | 20 |
| **Stop range (m)** | How close to the target the task ends. Goto tasks only. | 8 |
| **Ability** / **Aggressiveness** | `SetDriverAbility` and `SetDriverAggressiveness`, 0.0 to 1.0. | 1.0 / 0.0 |
## Example
A trimmed version of what the tool writes for the Normal preset and a waypoint:
```lua title="driving_style.lua"
local drivingStyle = 786603
local speed = 20.0
local stopRange = 8.0
CreateThread(function()
local ped = PlayerPedId()
local vehicle = GetVehiclePedIsIn(ped, false)
if vehicle == 0 or GetPedInVehicleSeat(vehicle, -1) ~= ped then return end
local blip = GetFirstBlipInfoId(8) -- 8 = waypoint
if not DoesBlipExist(blip) then return end
local target = GetBlipInfoIdCoord(blip)
SetDriverAbility(ped, 1.0)
SetDriverAggressiveness(ped, 0.0)
TaskVehicleDriveToCoord(ped, vehicle, target.x, target.y, target.z, speed, 0, GetEntityModel(vehicle), drivingStyle, stopRange, 1.0)
end)
```
> [!NOTE]
> When bit 31 is set the snippet writes the negative signed value, for example `local drivingStyle = -1073741824`, with the unsigned number in a comment. Natives take the style as an int32, so this is correct.
## Tips
- Speed is metres per second. 20.0 is about 72 km/h.
- NPC drivers react to gunfire and give up unless you call `SetBlockingOfNonTemporaryEvents(ped, true)`. The NPC snippet does this and adds `SetPedKeepTask`.
- Take control back from your own AI driving with `ClearPedTasks(ped)`.
- The yellow warning in the value panel means the value has bits with no known effect.
## Limitations
The descriptions reflect what is known about each bit from the FiveM native docs and community testing. The calculator runs entirely in your browser.
## Related tools
- [Animation Flags Calculator](/docs/tools/animation-flags-calculator)
- [Warning Screen Buttons](/docs/tools/warning-buttons)
- [Vehicle Handling Editor](/docs/tools/vehicle-handling-editor)
- [Interactive Map](/docs/tools/interactive-map)
_Last updated: 2026-09-22_
---
## Animation Flags Calculator
URL: https://fivemad.com/docs/tools/animation-flags-calculator
Build and decode the flag value for TaskPlayAnim: every eScriptedAnimFlags bit, common presets and a ready Lua snippet with dict loading and a toggle command.
The Animation Flags Calculator builds the `flag` argument of `TaskPlayAnim` from named bits, decodes values you find in other scripts, and writes a Lua snippet that loads the dictionary and plays the clip. It is for anyone writing emotes, interactions or cutscene-like moments.
## What it is for
The flag decides how an animation behaves: whether it loops, plays on the upper body only, lets the player walk, freezes on the last frame, ignores collision. Most scripts copy `49` around without knowing why. This tool shows every bit with its name from the `eScriptedAnimFlags` enum, so you can pick exactly what you need or see what a value in an old emote menu does.
## Quick start
1. Pick a **Preset** (the page opens on `49`, the classic emote flag) or toggle flags by hand.
2. In the **TaskPlayAnim** panel, click an **Example animation** or type your own **Anim dictionary** and **Anim name**.
3. Adjust **Blend in**, **Blend out**, **Duration (ms)** and **Playback rate** if needed.
4. Copy `play_anim.lua` from the code block under the calculator.
**Decode a value** in the **Animation flag** panel accepts `49`, `0x31`, `0b110001` or `1 | 16 | 32`. The value is stored in the URL (`?v=`) so a link shares it.
## Flags
| Bit | Value | Name | What it does |
| --- | --- | --- | --- |
| 0 | 1 | AF_LOOPING | Repeats until stopped. |
| 1 | 2 | AF_HOLD_LAST_FRAME | Freezes on the last frame instead of blending out. |
| 2 | 4 | AF_REPOSITION_WHEN_FINISHED | Moves the ped to where the clip ended. |
| 3 | 8 | AF_NOT_INTERRUPTABLE | AI events and other tasks cannot interrupt it. |
| 4 | 16 | AF_UPPERBODY | Only the upper body plays the clip. |
| 5 | 32 | AF_SECONDARY | Runs as a secondary task: the player keeps control. |
| 6 | 64 | AF_REORIENT_WHEN_FINISHED | Applies the clip's final heading to the ped. |
| 7 | 128 | AF_ABORT_ON_PED_MOVEMENT | Stops as soon as the ped moves. |
| 8 | 256 | AF_ADDITIVE | Plays as an additive layer on the current pose. |
| 9 | 512 | AF_TURN_OFF_COLLISION | No ped collision while playing. |
| 10 | 1024 | AF_OVERRIDE_PHYSICS | The clip fully drives position, physics ignored. |
| 11 | 2048 | AF_IGNORE_GRAVITY | No gravity while playing. |
| 12 | 4096 | AF_EXTRACT_INITIAL_OFFSET | Applies the clip's initial mover offset. |
| 13 | 8192 | AF_EXIT_AFTER_INTERRUPTED | Ends the task once interrupted. |
| 14 | 16384 | AF_TAG_SYNC_IN | Syncs the blend in with sync tags. |
| 15 | 32768 | AF_TAG_SYNC_OUT | Syncs the blend out with sync tags. |
| 16 | 65536 | AF_TAG_SYNC_CONTINUOUS | Keeps syncing to tags the whole time. |
| 17 | 131072 | AF_FORCE_START | Starts this frame even if the ped is busy. |
| 18 | 262144 | AF_USE_KINEMATIC_PHYSICS | Pushes objects but is not pushed back. |
| 19 | 524288 | AF_USE_MOVER_EXTRACTION | Moves the ped with the clip's mover track. |
| 20 | 1048576 | AF_HIDE_WEAPON | Hides the weapon while playing. |
| 21 | 2097152 | AF_ENDS_IN_DEAD_POSE | The clip ends in a dead pose. |
| 22 | 4194304 | AF_ACTIVATE_RAGDOLL_ON_COLLISION | Ragdolls on collision. |
| 23 | 8388608 | AF_DONT_EXIT_ON_DEATH | Keeps playing if the ped dies. |
| 24 | 16777216 | AF_ABORT_ON_WEAPON_DAMAGE | Stops on weapon damage. |
| 25 | 33554432 | AF_DISABLE_FORCED_PHYSICS_UPDATE | Skips the forced physics update at start. |
| 26 | 67108864 | AF_PROCESS_ATTACHMENTS_ON_START | Updates attached props on the first frame. |
| 27 | 134217728 | AF_EXPAND_PED_CAPSULE_FROM_SKELETON | Grows the capsule to fit the pose. |
| 28 | 268435456 | AF_USE_ALTERNATIVE_FP_ANIM | Uses the first-person variant if one exists. |
| 29 | 536870912 | AF_BLENDOUT_WRT_LAST_FRAME | Blend out finishes exactly at the last frame. |
| 30 | 1073741824 | AF_USE_FULL_BLENDING | Blends every bone fully. |
Older names from the first calculators (`ANIM_FLAG_REPEAT`, `ANIM_FLAG_STOP_LAST_FRAME`, `ANIM_FLAG_UPPERBODY`, `ANIM_FLAG_ENABLE_PLAYER_CONTROL`) are shown in the tool as "Also known as" on bits 0, 1, 4 and 5.
## Presets
| Preset | Value | Flags |
| --- | --- | --- |
| Play once | 0 | none |
| Loop | 1 | AF_LOOPING |
| Freeze at end | 2 | AF_HOLD_LAST_FRAME |
| Upper body once | 16 | AF_UPPERBODY |
| Upper body, can move | 48 | AF_UPPERBODY, AF_SECONDARY |
| Upper body loop, can move | 49 | AF_LOOPING, AF_UPPERBODY, AF_SECONDARY |
| Upper body hold, can move | 50 | AF_HOLD_LAST_FRAME, AF_UPPERBODY, AF_SECONDARY |
| Loop, can move | 51 | bits 0, 1, 4, 5 |
| Loop, stop when moving | 129 | AF_LOOPING, AF_ABORT_ON_PED_MOVEMENT |
| Cancelable | 120 | bits 3, 4, 5, 6 |
| Loop, no collision | 2561 | AF_LOOPING, AF_TURN_OFF_COLLISION, AF_IGNORE_GRAVITY |
## TaskPlayAnim panel
| Option | What it does | Default |
| --- | --- | --- |
| **Example animations** | Hands up, Arms crossed, Smoking, Cuffed, Wave, Triathlon idle. Sets dict, name and a fitting flag. | Hands up |
| **Anim dictionary** / **Anim name** | The clip to play. | `missminuteman_1ig_2` / `handsup_base` |
| **Blend in** / **Blend out** | 1.0 is a slow blend, 8.0 is nearly instant. | 8.0 / 8.0 |
| **Duration (ms)** | `-1` plays the whole clip, or forever when looping. | -1 |
| **Playback rate** | Really the start phase, 0.0 to 1.0. | 0.0 |
| **Lock X / Y / Z** | Passes `true` for lockX, lockY and lockZ. | off |
| **/anim toggle command** | Wraps it in a `/anim` command that starts or stops the clip. Off gives a plain `CreateThread`. | on |
## Example
The core of the generated snippet:
```lua title="play_anim.lua"
local function LoadAnimDict(dict)
if not DoesAnimDictExist(dict) then return false end
RequestAnimDict(dict)
local timeout = GetGameTimer() + 5000
while not HasAnimDictLoaded(dict) do
if GetGameTimer() > timeout then return false end
Wait(0)
end
return true
end
RegisterCommand("anim", function()
local ped = PlayerPedId()
local dict, name = "missminuteman_1ig_2", "handsup_base"
if IsEntityPlayingAnim(ped, dict, name, 3) then
StopAnimTask(ped, dict, name, 8.0)
elseif LoadAnimDict(dict) then
TaskPlayAnim(ped, dict, name, 8.0, 8.0, -1, 49, 0.0, false, false, false)
RemoveAnimDict(dict)
end
end, false)
```
## Tips
> [!TIP]
> Upper body alone (`16`) still blocks walking. Add `AF_SECONDARY` (`32`) to let the player move while the clip plays.
- Stop a clip with `StopAnimTask(ped, dict, name, blendOut)` or `ClearPedTasks(ped)`.
- `RemoveAnimDict` right after starting is fine: the running task keeps its own reference.
- For sitting or lying on props, try the **Loop, no collision** preset.
- Bit 31 is not part of this enum, so the bit strip only shows bits 0 to 30.
## Limitations
The tool does not check that a dictionary or clip name exists. The snippet does that at runtime with `DoesAnimDictExist` and a 5 second load timeout. Everything runs in the browser.
## Related tools
- [Driving Style Calculator](/docs/tools/driving-style-calculator)
- [Warning Screen Buttons](/docs/tools/warning-buttons)
- [Controls Reference](/docs/tools/controls-reference)
_Last updated: 2026-09-22_
---
## Warning Screen Buttons
URL: https://fivemad.com/docs/tools/warning-buttons
Pick the buttons for a GTA V alert screen, get the flag value for SetWarningMessageWithHeader, preview it and copy a Lua snippet that reads the input.
Warning Screen Buttons calculates the button flags for the full-screen GTA V alert (the black "Alert" screen with Yes / No at the bottom). You pick the buttons, see a preview with your own text, and copy a Lua snippet that draws the screen and waits for the player's choice.
## What it is for
`SetWarningMessage` and `SetWarningMessageWithHeader` take a bit field that decides which instructional buttons appear on the screen. Each bit adds one button: Yes is 4, No is 32, so Yes / No is `36`. Useful for "are you sure" prompts: leaving a job, deleting a character, confirming a purchase.
## Quick start
1. Pick a **Preset** (the page opens on **Yes / No**, `36`) or toggle buttons.
2. Fill **Header**, **Line 1** and **Line 2** in the **Text** panel and check the **Preview**.
3. Turn **Black background** on or off.
4. Copy `warning.lua`.
**Decode a value** in the **Button flags** panel reads `36`, `0x24` or `4 | 32` and shows which buttons it contains.
## Button flags
| Bit | Value | Name | Text | Key |
| --- | --- | --- | --- | --- |
| 0 | 1 | SELECT | Select | Enter |
| 1 | 2 | OK | OK | Enter |
| 2 | 4 | YES | Yes | Enter |
| 3 | 8 | BACK | Back | Esc |
| 4 | 16 | CANCEL | Cancel | Esc |
| 5 | 32 | NO | No | Esc |
| 6 | 64 | RETRY | Retry | Space |
| 7 | 128 | RESTART | Restart | Space |
| 8 | 256 | SKIP | Skip | Space |
| 9 | 512 | QUIT | Quit | Esc |
| 10 | 1024 | ADJUST | Adjust | Left / right arrows |
| 11 | 2048 | SPACE_NO_TEXT | (no text) | Space |
| 12 | 4096 | SHARE | Share | Space |
| 13 | 8192 | SIGN_IN | Sign In | Space |
| 14 | 16384 | CONTINUE | Continue | Enter |
| 15 | 32768 | ADJUST_ARROWS | Adjust | Left / right symbols |
| 16 | 65536 | SCROLL | Scroll | Up / down symbols |
| 17 | 131072 | OVERWRITE | Overwrite | Space |
| 18 | 262144 | SOCIAL_CLUB_SIGN_UP | Social Club Sign Up | Enter |
| 19 | 524288 | CONFIRM | Confirm | Enter |
| 20 | 1048576 | QUEUE | Queue | Enter |
| 21 | 2097152 | RETRY_ACCEPT | Retry | Enter |
| 22 | 4194304 | BACK_ESC | Back | Esc |
| 23 | 8388608 | SOCIAL_CLUB | Social Club | Enter |
| 24 | 16777216 | SPECTATE | Spectate | Space |
| 25 | 33554432 | OK_CANCEL_KEY | OK | Esc |
| 26 | 67108864 | CANCEL_TRANSFER | Cancel Transfer | Esc |
| 27 | 134217728 | LOADING_SPINNER | (spinner) | none |
| 28 | 268435456 | NO_RETURN_TO_GTA | No - Return to Grand Theft Auto V | Esc |
| 29 | 536870912 | CANCEL_ESC | Cancel | Esc |
The constant names are descriptive labels used by this tool. The game has no official names for most of these bits.
## Presets
| Preset | Value |
| --- | --- |
| OK | 2 |
| Yes / No | 36 |
| OK / Cancel | 18 |
| Confirm / Back | 524296 |
| Retry / Cancel | 80 |
| Continue | 16384 |
| Back / Continue | 16392 |
| Skip / OK | 258 |
| Loading spinner | 134217728 |
| Cancel + spinner | 134217744 |
## The generated snippet
The snippet registers your text with `AddTextEntry` (warning screens only take text entry keys, not raw strings), then draws the screen every frame until a key is pressed. Buttons are grouped by what they mean, and each group is checked with frontend controls in input group 2, which still work while the warning is up:
| Group | Controls checked |
| --- | --- |
| accept | 201, 217 (`INPUT_FRONTEND_ACCEPT`, `INPUT_FRONTEND_SELECT`) |
| cancel | 202 (`INPUT_FRONTEND_CANCEL`) |
| alt | 203 (`INPUT_FRONTEND_X`) |
| adjust | 189, 190 (`INPUT_FRONTEND_LEFT`, `INPUT_FRONTEND_RIGHT`) |
| scroll | 188, 187 (`INPUT_FRONTEND_UP`, `INPUT_FRONTEND_DOWN`) |
For Yes / No it looks like this:
```lua title="warning.lua"
local WARNING_FLAGS = 36 -- YES | NO
AddTextEntry("FM_WARN_HEADER", "Alert")
AddTextEntry("FM_WARN_LINE1", "Are you sure you want to leave the server?")
AddTextEntry("FM_WARN_LINE2", "Unsaved progress will be lost.")
local function ShowWarning()
while true do
SetWarningMessageWithHeader("FM_WARN_HEADER", "FM_WARN_LINE1", WARNING_FLAGS, "FM_WARN_LINE2", false, -1, true, 0, true)
if IsControlJustPressed(2, 201) or IsControlJustPressed(2, 217) then return "accept" end
if IsControlJustPressed(2, 202) then return "cancel" end
Wait(0)
end
end
CreateThread(function()
local choice = ShowWarning()
if choice == "accept" then
print("Accepted")
elseif choice == "cancel" then
print("Cancelled")
end
end)
```
If only the loading spinner (or nothing) is selected, there is nothing to press, so the snippet shows the screen for 5 seconds instead.
## Tips
> [!IMPORTANT]
> The buttons are only visual. The game does not report which one was pressed, you check the keys yourself, like the snippet does.
- The warning has to be drawn every frame, inside a loop with `Wait(0)`.
- Several bits share a key. Select, OK, Yes and Continue are all Enter, so combining two of them gives the player two labels for the same key.
- **Black background** is passed as the background argument of `SetWarningMessageWithHeader`.
## Limitations
The preview is an approximation of the game's layout, not a screenshot. Everything runs in the browser.
## Related tools
- [Controls Reference](/docs/tools/controls-reference)
- [Draw Text Colors](/docs/tools/text-colors)
- [Scaleform Functions](/docs/tools/scaleform-reference)
- [Driving Style Calculator](/docs/tools/driving-style-calculator)
_Last updated: 2026-09-22_
---
## Draw Text Colors
URL: https://fivemad.com/docs/tools/text-colors
Preview GTA V tilde colour and formatting codes live in DrawText, notifications and help text, and FiveM chat caret codes, with ready Lua snippets.
Draw Text Colors lets you type a string with GTA V formatting codes (`~r~`, `~h~`, `~n~`, `~INPUT_CONTEXT~` and friends) and see how it looks as on-screen text, a feed notification or a help text box. A second section does the same for the caret codes (`^1`, `^*`) of the FiveM chat. Every preview comes with a Lua snippet.
## What it is for
Testing text formatting in game means a restart or a resource reload for every tweak. Here you see the colours, bold parts, line breaks and key prompts as you type, then copy code that draws the same thing with the right natives.
## Quick start
1. Type in the **Text** box. The page starts with a sample that uses colours, a key prompt, a `~a~` name and a `~1~` number.
2. Click the colour buttons under the box (or any card in **Reference**) to insert a code at the cursor.
3. Pick the output style with the tabs above the preview: **DrawText**, **Notification** or **Help text**.
4. If your text has `~a~` or `~1~`, fill the value fields that appear under the text box.
5. Copy `drawtext.lua`, `notify.lua` or `helptext.lua`.
The preview uses system fonts in place of the game fonts, so it is close but not pixel exact.
## Tilde codes
| Code | Result | Colour |
| --- | --- | --- |
| `~r~` | Red | #E03232 |
| `~b~` | Blue | #5DB6E5 |
| `~g~` | Green | #72CC72 |
| `~y~` | Yellow | #F0C850 |
| `~p~` | Purple | #8466E2 |
| `~q~` | Pink | #CB3694 |
| `~o~` | Orange | #FF8555 |
| `~c~` | Grey | #8C8C8C |
| `~m~` | Dark grey | #646464 |
| `~u~` | Black | #000000 |
| `~l~` | Black | #000000 |
| `~d~` | Dark blue | #2F5C73 |
| `~f~` | Friendly blue | #5DB6E5 |
| `~w~` | White | #F0F0F0 |
| `~s~` | Back to the default colour | set by `SetTextColour` |
| `~h~` | Bold on / off | |
| `~bold~` | Bold on / off (newer builds) | |
| `~italic~` | Italic on / off (newer builds) | |
| `~n~` | New line | |
| `~a~` | String placeholder, filled by `AddTextComponentSubstringPlayerName` | |
| `~1~` | Integer placeholder, filled by `AddTextComponentInteger` | |
| `~ws~` | Wanted star icon | |
| `~EX_R*~` | Rockstar logo | |
A colour stays active until the next colour code. The **HUD colours** tab lists 32 `~HUD_COLOUR_NAME~` tokens (for example `~HUD_COLOUR_FREEMODE~`, `~HUD_COLOUR_REDLIGHT~`) with their RGB values, and they work inline the same way.
The **Buttons** tab lists `~INPUT_*~` tokens such as `~INPUT_CONTEXT~`, `~INPUT_ENTER~`, `~INPUT_DETONATE~` and `~INPUTGROUP_MOVE~`. In game they render the key the player has bound (or the pad button), so a prompt stays correct on custom bindings. The preview shows the default keyboard key.
## DrawText options
Shown only on the **DrawText** tab:
| Option | What it does | Default |
| --- | --- | --- |
| **Font** | 0 Chalet London, 1 House Script, 2 Monospace, 4 Chalet Comprime, 7 Pricedown | 4 |
| **Scale** | 0.2 to 1.2, written as `SetTextScale(0.0, scale)` | 0.5 |
| **Colour** / **Alpha** | Base colour for `SetTextColour`, and what `~s~` returns to | white, 255 |
| **X (0 to 1)** / **Y (0 to 1)** | Screen position for `EndTextCommandDisplayText` | 0.5 / 0.8 |
| **Outline** | Adds `SetTextOutline()` | on |
| **Drop shadow** | Adds `SetTextDropShadow()` | off |
| **Centre** | Adds `SetTextCentre(true)` | on |
## Snippets
DrawText is drawn every frame inside a thread:
```lua title="drawtext.lua"
CreateThread(function()
while true do
Wait(0)
SetTextFont(4)
SetTextScale(0.0, 0.5)
SetTextColour(255, 255, 255, 255)
SetTextOutline()
SetTextCentre(true)
BeginTextCommandDisplayText("STRING")
AddTextComponentSubstringPlayerName("~b~Mission~s~ started.")
EndTextCommandDisplayText(0.5, 0.8)
end
end)
```
A notification is a single call:
```lua title="notify.lua"
BeginTextCommandThefeedPost("STRING")
AddTextComponentSubstringPlayerName("~g~Saved~s~ your outfit.")
EndTextCommandThefeedPostTicker(false, true)
```
Help text has to be called every frame while it should stay up:
```lua title="helptext.lua"
BeginTextCommandDisplayHelp("STRING")
AddTextComponentSubstringPlayerName("Press ~INPUT_CONTEXT~ to open the shop")
EndTextCommandDisplayHelp(0, false, true, -1)
```
When the text contains `~a~` or `~1~`, the snippet registers it with `AddTextEntry("FIVEMAD_TEXT", ...)` and adds one component per placeholder, in order, with the values you typed.
> [!NOTE]
> One `AddTextComponentSubstringPlayerName` is cut at 99 characters. For longer text without placeholders, the snippet switches to the built-in `CELL_EMAIL_BCON` entry and splits your text into chunks of up to 99 characters without breaking a `~code~` in half.
## FiveM chat colours
The default chat resource does not read tilde codes. It uses caret codes:
| Code | Result |
| --- | --- |
| `^0` | White |
| `^1` | Red |
| `^2` | Green |
| `^3` | Yellow |
| `^4` | Blue |
| `^5` | Light blue |
| `^6` | Purple |
| `^7` | White |
| `^8` | Orange red |
| `^9` | Grey |
| `^*` | Bold |
| `^_` | Underline |
| `^~` | Strikethrough |
| `^=` | Underline and strikethrough |
| `^r` | Reset |
Type an **Author** and **Text**, click the colour swatches (which also copy the code) or format buttons, and copy `chat.lua`:
```lua title="chat.lua"
TriggerEvent("chat:addMessage", {
color = { 255, 255, 255 },
multiline = true,
args = { "Dispatch", "^1[Police]^0 Suspect spotted near ^3Legion Square^0." }
})
```
The colours shown are the stock chat stylesheet defaults. A custom chat theme can change them.
## Common mistakes
- Using `~r~` in chat messages or `^1` in DrawText. They do not mix.
- Forgetting `~s~` after a coloured word, so the rest of the line stays coloured.
- Showing help text once. It disappears the next frame unless you call it in a loop.
## Related tools
- [Controls Reference](/docs/tools/controls-reference)
- [Warning Screen Buttons](/docs/tools/warning-buttons)
- [Blip, Marker & Checkpoint Browser](/docs/tools/blip-marker-browser)
- [Scaleform Functions](/docs/tools/scaleform-reference)
_Last updated: 2026-09-22_
---
## Screen Effects Browser
URL: https://fivemad.com/docs/tools/screen-effects
Find the right GTA V timecycle modifier or animpostfx effect, see what it does before you try it, and copy the Lua that switches it on.
The Screen Effects Browser lists every named screen effect the game ships: 1,101 timecycle
modifiers and 252 animpostfx effects. Each one has a before and after preview you can drag, the
exact values it sets, and ready Lua.
## The two tabs
**Timecycle modifiers** are named sets of overrides on the lighting and the screen: light and
ambient colour, fog, exposure, the tone curve, colour correction, vignette, grain, blur and so on.
You switch one on and it stays on until you clear it. Most interiors, drunk and drugged states and
"this area feels different" effects on a server are a timecycle modifier.
**animpostfx** effects are stacks of those modifiers with timing on top. Each layer has a start
delay, a fade in, a hold and a fade out, and the stack can loop. The character switch flash, the
death fade and the race boost streaks are animpostfx.
## Finding one
- The search box matches the name, and for timecycle modifiers also the file it comes from. For
animpostfx it also matches the modifiers the effect plays, so searching `nightvision` finds the
effects that use it.
- The dropdown filters by source file for timecycle modifiers, or by a rough family (character
switch, drugs, racing, damage, vision modes) for animpostfx.
- The three buttons on the right switch the viewpoint every card is rendered from: a city street,
a shop interior and a view over the city. Interior lighting values show up best on the interior
view, fog and far clip on the landscape one.
## Reading a card
Each card is the same view drawn twice: the left half with the game's clear noon lighting, the
right half with the effect's values on top. Drag the divider, or focus it and use the arrow keys.
The badge in the corner says how many parameters the modifier sets, or how many layers the effect
stacks.
## The detail view
Click a name to open it. You get:
- the bigger comparison and the viewpoint switcher
- a **strength** slider, which blends the effect back towards the plain frame the same way
`SetTimecycleModifierStrength` blends a modifier towards the timecycle that is running
- the full parameter table, searchable and filterable by group, with both floats the game file
stores, the clear noon value for comparison, and a mark on every parameter the preview draws
- for an animpostfx effect, the layer table with every duration and the layer blend settings
- cross links: which animpostfx effects play a modifier, and which modifiers an effect plays
- copy buttons for the name and for ready Lua
- **Open it live in the 3D map**, which loads the Interactive Map in 3D with the effect applied to
the world and the same strength slider
## Using a timecycle modifier
```lua title="client.lua"
SetTimecycleModifier("CAMERA_BW")
SetTimecycleModifierStrength(0.6) -- 0.0 to 1.0
-- later
ClearTimecycleModifier()
```
- Only one modifier is active at a time. Setting a second one replaces the first.
- `SetExtraTimecycleModifier` and `ClearExtraTimecycleModifier` give you a second slot that stacks
on top.
- Modifiers are client side and per player.
> [!TIP]
> Strength is the cheapest way to make a strong effect usable. Most of the dramatic modifiers look
> right somewhere between 0.3 and 0.6.
## Playing an animpostfx effect
```lua title="client.lua"
AnimpostfxPlay("SwitchHUDIn", 0, true) -- 0 = the effect's own timings, true = loop
AnimpostfxStop("SwitchHUDIn")
AnimpostfxStopAll()
if AnimpostfxIsRunning("SwitchHUDIn") then
-- ...
end
```
> [!WARNING]
> A looping effect runs until something stops it. Always pair a loop with an `AnimpostfxStop`, and
> call `AnimpostfxStopAll()` when your resource stops, or players get stuck with it.
## What the previews can and cannot show
The pictures are ours, rendered from the effect's own values. They show light and ambient colour
and intensity, fog colour, density, start and far clip, exposure, the filmic tone curve, colour
correction and colour shift, saturation, the screen gradient, vignette, grain, scan lines,
chromatic aberration, lens distortion, bloom, blur, depth of field and the night vision curve.
They do not show shadows, ambient occlusion, reflections, water, streaming distances, heat haze,
god rays, light directions, lens flares or the weather and particle switches. Those parameters are
still in the table, just not in the picture.
Treat a preview as a hint about the direction an effect pulls the image in. The parameter tables,
the layer timings and the names are exact.
## Names shown as a hash
A few animpostfx effects are listed with a `hash_xxxxxxxx` name. The game only stores the hash for
those and the readable string is not in the files we can read, so there is nothing to type. They
are shown so the list is complete.
_Last updated: 2026-09-23_
---
## Model & Hash Browser
URL: https://fivemad.com/docs/tools/model-hash-browser
Search every GTA V vehicle, ped and weapon by spawn name, display name or hash, copy hashes in any format and get a ready Lua spawn snippet.
The Model & Hash Browser lists every GTA V vehicle (921), ped (1,109) and weapon (184) with a picture, spawn name, display name, class and hash. Search by any of them, paste a hash to find out which model it is, and copy a Lua snippet that spawns or gives the thing you picked.
## What it is for
- You need the spawn name of a car you only know by its in-game name (Zentorno, Pegassi Tempesta).
- A log or an event prints `-1216765807` and you want to know which model that is.
- You are filling a garage, shop or whitelist config and need exact names and hashes.
- You want the right ped model for an NPC, or the `WEAPON_` name for a loadout.
## Quick start
1. Pick a tab: **Vehicles**, **Peds** or **Weapons**.
2. Type in the search box: a spawn name (`adder`), a display name (`Zentorno`), a manufacturer (vehicles), or a hash.
3. Narrow it down with the filters next to the search box.
4. Click the spawn name or the hash on a card to copy it.
5. Click anywhere else on the card to open the details drawer with every hash format and a Lua snippet.
## Search and filters
The search matches spawn name, display name and (for vehicles) manufacturer. Several words narrow the search: `pegassi super` finds cars with both words. Quotes and backticks are ignored, so you can paste `` `adder` `` straight from a script.
A hash in any format finds its model:
| Format | Example (Adder) |
| --- | --- |
| Signed | `-1216765807` |
| Unsigned | `3078201489` |
| Hex with `0x` | `0xB779A091` |
| Hex without `0x` (8 digits) | `B779A091` |
| Filter | Tabs | What it filters |
| --- | --- | --- |
| **Any class** / **Any ped type** / **Any category** | all | Vehicle class (Super, Sport, Emergency...), ped type (Civ Male, Cop, Animal...) or weapon category (Pistol, Rifle, Thrown...). Each option shows how many entries it has. |
| **Any type** | Vehicles | Vehicle type: Car, Bike, Boat, Heli, Plane, Trailer, Submarine and so on. |
| **Any DLC** | all | The update that added it. |
The line under the filters shows how many entries match, with a **Reset filters** button. Results load 48 at a time; scroll to the button at the bottom for more.
Switching tabs resets the filters. Your search, filters, tab and the open drawer are kept in the page URL, so you can bookmark or share a link to an exact result.
### Card hash format
**Card hash** (top right) picks which hash the cards show: **Signed**, **Unsigned** or **Hex**. It only changes the cards; the drawer always shows all formats.
## The details drawer
Opens from the right on desktop and from the bottom on phones. Esc , the close button or a click outside closes it.
**Hashes** (every tab), each one click to copy:
| Row | Example |
| --- | --- |
| Spawn name | `adder` |
| Signed | `-1216765807` |
| Unsigned | `3078201489` |
| Hex | `0xB779A091` |
| Lua backtick | `` `adder` `` |
### Vehicles
- **Details**: manufacturer, class, type, seats, wheels, DLC, value, sirens and armored glass.
- **Performance**: top speed (km/h and mph), acceleration, braking and traction as bars, scaled against land vehicles.
- **Mod kits**, **Vehicle weapons** and **Flags** (the model's `FLAG_` list without the prefix).
- **Spawn it** snippet:
```lua
local model = `adder`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, GetEntityHeading(ped), true, false)
SetPedIntoVehicle(ped, veh, -1)
SetVehicleNumberPlateText(veh, "FIVEMAD")
SetModelAsNoLongerNeeded(model)
```
Top speed is the game's estimated max speed for the model (what `GetVehicleModelEstimatedMaxSpeed` returns), not a measured run. Jets and some boats sit at the top of the bar. Handling edits and upgrades change the real numbers.
### Peds
- **Details**: display name, ped type, DLC.
- **Use it** snippet, to change the player model or spawn the ped as an NPC:
```lua
local model = `a_m_y_hipster_01`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
-- Change the player model
SetPlayerModel(PlayerId(), model)
SetPedDefaultComponentVariation(PlayerPedId())
-- Or spawn it as an NPC
-- local c = GetEntityCoords(PlayerPedId())
-- local npc = CreatePed(4, model, c.x + 2.0, c.y, c.z, 0.0, true, false)
SetModelAsNoLongerNeeded(model)
```
### Weapons
- The in-game description, when there is one.
- **Details**: category, ammo type, damage type, max ammo (MP), number of components and tints, weapon model, DLC, and whether it is a vehicle weapon.
- **Components, tints and flags** opens the [Weapon Stats & Components](/tools/weapon-stats) tool on this weapon.
- **Give it** snippet, with the weapon's max MP ammo:
```lua
local ped = PlayerPedId()
GiveWeaponToPed(ped, `WEAPON_PISTOL`, 250, false, true)
```
## Signed, unsigned or hex?
They are the same 32-bit hash of the spawn name, written three ways. Natives such as `GetEntityModel` and `GetHashKey` return the signed form, dumps and native docs often use hex, and most natives accept any of them. In Lua you can skip the lookup and write the name in backticks: `` `adder` `` is turned into the hash when the script loads.
```lua
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
if GetEntityModel(veh) == `adder` then
print("You are in an Adder")
end
```
## Tips
- Paste an unknown hash from an error or a log first. It is the fastest way to find out which model a script is talking about.
- Compare models with backticks or `GetHashKey`, not with a hard-coded unsigned number: natives hand you the signed value.
- Weapon names are upper case by convention (`WEAPON_PISTOL`), but hashes ignore case, so `weapon_pistol` gives the same hash.
- Some peds and newer DLC models have no picture yet. They show an icon instead; the names and hashes are still right.
## Limitations
- Base game content only. Addon vehicles, peds and weapons from your server are not listed. For those, hash the name with the [joaat Hash Calculator](/tools/hash-calculator).
- Stats are the game's reference values, not the handling on your server.
- Pictures are loaded from the FiveM docs site.
## Related tools
- [joaat Hash Calculator](/docs/tools/hash-calculator)
- [Weapon Stats & Components](/docs/tools/weapon-stats)
- [Objects / Props List](/docs/tools/objects-list)
- [Vehicle Handling Editor](/docs/tools/vehicle-handling-editor)
_Last updated: 2026-09-22_
---
## Interactive Map
URL: https://fivemad.com/docs/tools/interactive-map
Find any spot on the GTA V map, copy exact vector3 and vector4 coordinates, drop pins, measure distances and share links to a location.
The Interactive Map is the whole GTA V map in your browser, with coordinates under the cursor. Click to drop a pin and copy it as `vector3` or `vector4`, measure a route, or share a link that opens the map on an exact spot. On a desktop you can switch to a 3D world and move to the place you are about to script with a freecam or on foot. It is for anyone who needs coordinates without starting the game: spawn points, blips, job locations, teleports, zones.
## What it is for
Most FiveM configs are full of coordinates. Getting them usually means joining your server, walking to the spot and printing `GetEntityCoords`. With the map you can pick rough positions for a whole job route in a minute, check the distance between two shops, or look up where a coordinate from a config actually is. For spots where height matters (a roof, under a bridge), use the 3D view or fine tune the z in game.
## Quick start
1. Open the tool. On a desktop it starts in the **3D world** at Legion Square; press **2D map** to see the flat map. On phones and tablets it opens the 2D map.
2. Drag to pan, scroll (or pinch) to zoom. The box in the bottom right corner shows `x, y` under the cursor, plus `z` when the ground height there is known.
3. With **Drop pins** active, click the map. A pin appears and is added to **Pins** on the right.
4. In the pin card, set **heading** if you need one, then press **vector3** or **vector4** to copy the line.
5. Paste it into your script or config.
## The 2D map
| Control | What it does |
| --- | --- |
| Drag | Pan the map. |
| Mouse wheel / pinch | Zoom, centred on the cursor. |
| **+** / **-** buttons (top right) | Zoom in and out one step. |
| Click | Drop a pin (**Drop pins** tool) or add a measure point (**Measure** tool). |
| Cursor box (bottom right) | `x, y` and `z` of the spot under the mouse. |
| Scale bar (bottom left) | Shows metres or kilometres at the current zoom. |
When you have been in the 3D view, a small white arrow on the 2D map shows where the 3D camera is and which way it looks.
### Drop pins
The default tool. Each click drops a pin at that spot with the ground height filled in. If the height is still loading when you click, the z is filled in about a second later. Pins draw a short line in the direction of their heading.
### Measure
Switch to **Measure** and click two or more points. The **Measure** card shows:
- **flat distance**: the length of the line on the map, point to point.
- **with height**: the same route including height differences.
- **points**: how many points you clicked.
Distances over 1000 m are shown in km. **Clear** starts over. The measure line stays on the map when you switch back to pins, until you clear it.
## Go to a place or coordinates
The search box at the top of the side panel does two things:
- **Places**: with an empty box you get a list of well known spots (Legion Square, Pillbox Hill Medical, Mission Row Police, Maze Bank Tower roof, Vespucci Beach, Del Perro Pier, Vinewood Sign, LS International Airport, Sandy Shores, Paleto Bay, Mount Chiliad, Fort Zancudo). Type to filter, click one (or press Enter for the first match) to jump there.
- **Coordinates**: paste a coordinate in any common format, for example `vector3(195.2, -933.8, 30.7)`, `vector4(...)`, `{x = ..., y = ..., z = ...}` or plain `195.2, -933.8, 30.7`. A **Go to x, y and pin it** button appears. Click it or press Enter to centre the map there and drop a pin, with the heading from a `vector4`.
This is the quickest way to answer "where is this coordinate from the config?".
## Pins
The **Pins** card lists every pin with its x, y, z. Pins are saved in your browser, so they are still there next time you open the map.
- Click a pin's coordinates to centre the map (or the 3D camera) on it.
- Click a pin card to make it active. The active pin is drawn larger on the map.
- The trash icon removes one pin, **Clear** removes all of them.
The active pin opens its editor:
| Field / button | What it does |
| --- | --- |
| **z** | Height. Filled in from the map, edit it if you know better (roofs, bridges, interiors). |
| **heading** | 0 faces north, 90 west, 180 south, 270 east, the same as `GetEntityHeading`. Values are wrapped into 0-360. |
| **vector3** | Copies `vector3(x, y, z)`, rounded to 2 decimals. |
| **vector4** | Copies `vector4(x, y, z, heading)`, heading rounded to 1 decimal. |
| **Link** | Copies a link that opens the map on this pin with the same heading. |
| **See in 3D** | Desktop only. Opens the 3D world standing at the pin, looking along its heading. |
### Share links
A link looks like `https://fivemad.com/tools/interactive-map#at=195.2,-933.8,29.7,90&zoom=6`. Opening it shows the 2D map centred on that spot and adds a pin labelled **Shared** (only once, even if you open the link again). Good for pointing a teammate at the exact spot you mean.
## The 3D world
Press **3D world** (desktop browser with mouse and keyboard) to leave the flat map and move through the world itself. It opens standing at the active pin, or, with no pin selected, above the area you were looking at on the 2D map. In 3D:
- Click the view to look around with the mouse, Esc releases it. Holding the right mouse button also works.
- W A S D move, Shift goes faster, Space up, C down, the mouse wheel sets the camera speed.
- **Freecam** and **Walk** switch the movement mode.
- **Pin here** (bottom left) drops a pin on the ground under the camera, with the camera's heading. Switch back to **2D map** to copy it.
- Picking a place or pasting coordinates in the search box teleports the camera above that spot.
Every key and the quality settings are in the [3D world](/docs/tools/world-3d) docs.
## Examples
A pin copied as `vector4` works straight away as a spawn point:
```lua title="client.lua"
local spawn = vector4(195.2, -933.8, 29.7, 144.0)
RegisterCommand('legion', function()
local ped = PlayerPedId()
SetEntityCoords(ped, spawn.x, spawn.y, spawn.z, false, false, false, false)
SetEntityHeading(ped, spawn.w)
end, false)
```
A `vector3` for a map blip:
```lua title="client.lua"
local shop = vector3(25.7, -1347.3, 29.5)
CreateThread(function()
local blip = AddBlipForCoord(shop.x, shop.y, shop.z)
SetBlipSprite(blip, 52)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName("24/7")
EndTextCommandSetBlipName(blip)
end)
```
A list of pins pasted into a config for a job route:
```lua title="config.lua"
Config.Deliveries = {
vector3(-1300.0, -1600.0, 3.3),
vector3(1860.0, 3678.0, 32.5),
vector3(-287.0, 6220.0, 30.5),
}
```
## Tips
- The z under the cursor is the top surface: ground, road or roof. For a spot under a bridge or inside a building, fix the z by hand or check it in the 3D view.
- `GetEntityCoords(PlayerPedId())` returns a point about 1 m above the ground (the pelvis). Map pins sit on the ground. For `SetEntityCoords` either is fine; for props and markers, the ground value is what you want.
- Use the **Measure** tool to size `#(a - b) < radius` checks, zones and delivery payouts before you write them.
- Pins are only stored in this browser. Copy what you need, or use **Link** to move a pin to another device.
> [!TIP]
> The [YMAP Builder](/tools/ymap-builder) imports `vector3` and `vector4` lines directly, so a set of pins can become a set of placed props.
## Limitations
- Heights are accurate to a few metres. Always check spawn heights on roofs, bridges and stairs in game.
- Cayo Perico and North Yankton are not on the map.
- The 3D view needs a desktop browser with WebGL 2, a mouse and a keyboard. On phones the 2D map works fully.
- Pins, measure points and links stay in your browser. Nothing is uploaded.
## Related tools
- [3D world](/docs/tools/world-3d)
- [YMAP Builder](/docs/tools/ymap-builder)
- [Blip, Marker & Checkpoint Browser](/docs/tools/blip-marker-browser)
- [Objects / Props List](/docs/tools/objects-list)
_Last updated: 2026-09-23_
---
## 3D world
URL: https://fivemad.com/docs/tools/world-3d
Move through GTA V in your browser with a freecam or on foot: every key and mouse control, the quality settings, what is shown, and tips for a smooth frame rate.
The 3D world is GTA V's map, rendered in your browser so you can move through it like a free camera. It is the **3D world** tab of the [Interactive Map](/tools/interactive-map) and the **3D world** panel of the [YMAP Builder](/tools/ymap-builder). Use it to scout a location before you script it, check what a spot looks like from the street, grab a pin at an exact place, or place ymap props where they belong.
## Where you find it
| Where | How to open it | What is different |
| --- | --- | --- |
| [Interactive Map](/tools/interactive-map) | On a desktop it opens in 3D straight away. Otherwise press the **3D world** tab, or **See in 3D** on a pin. | Clicking the view captures the mouse for looking around. Has **Pin here**. |
| [YMAP Builder](/tools/ymap-builder) | **3D world** button in the **Top-down preview** panel. | Clicking selects and places props, so you look around with the right mouse button. Adds the prop editing toolbar (see the [YMAP Builder docs](/docs/tools/ymap-builder)). |
Both need a desktop browser with WebGL 2, a mouse and a keyboard. On phones the Interactive Map stays on the 2D map and the YMAP Builder hides the button.
## Quick start
1. Open the [Interactive Map](/tools/interactive-map) on a desktop. You start above Legion Square.
2. Click the view. The mouse now turns the camera. Press Esc to get the pointer back.
3. Hold W to move forward. Scroll the mouse wheel to change speed.
4. Press **Walk** in the top left toolbar to drop to street level and walk.
5. Press **Pin here** to save the spot, then switch to **2D map** to copy it as `vector3` or `vector4`.
## Toolbar
The toolbar sits in the top left corner of the view.
| Control | What it does |
| --- | --- |
| **Freecam** | Free camera. The default. |
| **Walk** | Walk on the ground with gravity, at eye height. |
| Quality (gauge icon) | **Low**, **Medium** or **High**. Remembered for next time. See Quality below. |
| **Full screen** | Puts the view in full screen (in the YMAP Builder the whole panel, toolbar included). Esc or **Exit full screen** leaves it. |
The box in the top right corner shows live numbers: **fps** (amber below 30), **draws** (draw calls), **tris** (triangles in millions), **nodes** (world pieces loaded, plus how many are still loading), **props** (trees, lamps, benches and other props drawn right now), **data** (MB of world data loaded), **heap** (browser memory, only in Chromium browsers) and, in freecam, **speed** in m/s.
## Controls
### Looking around
| Input | What it does |
| --- | --- |
| Click the view | Interactive Map: captures the mouse, so moving it turns the camera. Esc releases it. |
| Hold right mouse button and drag | Turns the camera without capturing the mouse. Works in both tools, and is the only way in the YMAP Builder. |
The keyboard only works while the view has focus. If keys do nothing, click the view once.
### Freecam
| Key | Action |
| --- | --- |
| W / Up | Forward, in the direction you look (up and down too) |
| S / Down | Back |
| A / Left , D / Right | Strafe left, right |
| Space or E | Straight up |
| C , Q or Ctrl | Straight down |
| Shift (hold) | 4x speed |
| Mouse wheel | Camera speed, from 2 to 800 m/s. Starts at 40 m/s. |
The camera eases in and out of movement, so short taps give small, precise moves.
### Walk
| Key | Action |
| --- | --- |
| W A S D / arrows | Walk along the ground, relative to where you look |
| Shift (hold) | Run (twice the walking speed) |
| Space | Jump |
In walk mode you follow the ground and roofs, you step up curbs and stairs, and you cannot climb anything higher than about 0.8 m in one step. Walls stop you and you slide along them. Doorways stay open. Props such as trees, lamp posts and benches do not block you. The mouse wheel does nothing while walking.
Switch to **Walk** while you are high up and you fall to the ground under you. If the ground there has not loaded yet, you hover until it has.
## Quality
The quality menu trades detail for frame rate. The choice is saved in your browser.
| Setting | Draw distance | Textures | Interiors | Props on screen | Resolution |
| --- | --- | --- | --- | --- | --- |
| **Low** | Shorter than the game | Less filtering | Off | Up to 25,000 | Normal |
| **Medium** (default) | Same as the game | Sharper at angles | On | Up to 50,000 | Slightly sharper on high DPI screens |
| **High** | Longer than the game | Sharpest | On | Up to 90,000 | Full sharpness on high DPI screens |
The setting applies right away, no reload needed.
## What you see
- The whole main island: Los Santos, Blaine County and Paleto Bay, with terrain, roads, buildings, bridges and the sea, lakes and rivers.
- Detail changes with distance like in the game: far away you see the low detail versions of districts and mountains, and full detail buildings, trees and street props appear as you get closer.
- Street props and vegetation: trees, lamp posts, benches, bins, fences and so on.
- Interiors of many buildings that are open in the base game (police stations, banks, shops, the car showroom and others) on **Medium** and **High**. They load when you are close to them.
- Fixed calm daylight.
Not shown:
- Cayo Perico and North Yankton.
- Peds, traffic, parked vehicles and animals.
- Time of day, weather, street lights at night and shadows.
- Interiors that a server has to load with a script, and interiors on **Low**.
Textures are lighter than the game's, so close up surfaces look flatter than in GTA V. Distances, heights and positions match the game.
## Performance tips
- Watch **fps** in the corner. If it drops below 30 (it turns amber), switch to **Low**.
- Move slower when you arrive somewhere new. At full speed the world has to catch up, so you see low detail for a moment. At the same spot a second later everything is there.
- **Full screen** renders more pixels. On a weak GPU a normal size view is smoother.
- Use a browser with hardware acceleration on. If `chrome://gpu` or `about:support` says WebGL is software only, the view will be slow or will not start.
- Laptops: plug in and pick the high performance GPU for your browser if you have two.
- Close other heavy tabs (other 3D pages, video). Only one 3D view runs well at a time.
- If **data** keeps climbing after a long session and things get choppy, reload the page.
## Messages you may see
| Message | Meaning |
| --- | --- |
| **Loading the world...** | The view is starting. Takes a few seconds the first time. |
| **WebGL 2 is not available in this browser, so the 3D view can't run.** | Your browser or GPU does not support WebGL 2, or hardware acceleration is off. The 2D map still works. |
| **The 3D world data is not available right now.** | The world could not be loaded. Try again later. |
| **The 3D view failed to start.** | Something went wrong while starting. A reload usually fixes it. |
## Common mistakes
- **Keys do nothing.** The view does not have focus. Click it once.
- **The mouse is stuck.** You clicked the view in the Interactive Map, which captures the pointer. Press Esc .
- **Walking through a tree or bench.** Props do not block you in walk mode. Walls and buildings do.
- **Low detail everywhere.** You are moving faster than the world loads, or **Low** is selected. Stop for a second, or pick **Medium**.
## Limitations
- Desktop only: WebGL 2, a mouse and a keyboard are needed.
- It is a viewer. Positions you pick here are exact enough for scripts, but check spawn heights on roofs and stairs in game.
- Everything runs in your browser. Nothing you do in the view is uploaded.
## Related tools
- [Interactive Map](/docs/tools/interactive-map)
- [YMAP Builder](/docs/tools/ymap-builder)
- [Objects / Props List](/docs/tools/objects-list)
_Last updated: 2026-09-23_
---
## Blip, Marker & Checkpoint Browser
URL: https://fivemad.com/docs/tools/blip-marker-browser
Pick a GTA V blip sprite and colour, a DrawMarker type or a race checkpoint by picture, tune it, and copy a ready FiveM Lua snippet.
The Blip, Marker & Checkpoint Browser shows every map blip sprite (966), blip colour (100), marker type (44) and checkpoint type (50) with a preview and its id. Click one to copy the id, tune the options in the side panel, and copy a Lua snippet that creates it.
## What it is for
Blip sprite 52, colour 2, marker 1: scripts are full of these numbers and nobody remembers them. Instead of guessing and reconnecting, you pick the icon or shape by picture here, check how the colour looks on it, and paste a working snippet into your client script.
## Quick start
1. Pick a tab: **Sprites**, **Colours**, **Markers** or **Checkpoints**. The tab is kept in the URL (`?tab=markers`), so you can link straight to it.
2. Search by id or name in the box on the right. A number matches ids that start with it.
3. Click a tile. It becomes the selected one and its id is copied (the tile briefly says **Copied**).
4. Adjust the options in the panel (**Blip**, **Marker** or **Checkpoint**).
5. Copy the code block under the panel (`blip.lua`, `marker.lua` or `checkpoint.lua`).
## Sprites and colours
The **Sprites** and **Colours** tabs share the **Blip** panel.
| Option | What it does | Default |
| --- | --- | --- |
| **Colour** swatches | Pick the blip colour. Picking one also turns the tint preview on. | 0 (White) |
| **Tint preview** | Multiplies the sprite previews by the selected colour, the way the game tints white icons. | off |
| **Label** | The name shown in the map legend. | `My Blip` |
| **Scale** | Blip size, 0.3 to 2. | 0.8 |
| **Coords (x, y, z)** | Where the blip goes. Any `x, y, z` text works. | `215.76, -810.12, 30.73` |
| **Short range** | Only show it on the minimap when the player is nearby. | on |
The **Colours** tab lists every `SetBlipColour` value with its name and hex code. Some colours have **enemy** and **friendly** variants: picking one adds `SetBlipAsFriendly` to the snippet.
Most sprites are white and take the colour. A few (police, gang and mission icons) are already coloured and ignore it, which the tint preview shows too.
```lua title="blip.lua"
local blip = AddBlipForCoord(215.76, -810.12, 30.73)
SetBlipSprite(blip, 1) -- radar_level
SetBlipDisplay(blip, 4)
SetBlipScale(blip, 0.8)
SetBlipColour(blip, 0) -- White
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName("My Blip")
EndTextCommandSetBlipName(blip)
```
`SetBlipDisplay(blip, 4)` shows the blip on both the pause map and the minimap.
## Markers
The **Markers** tab lists every `DrawMarker` type with a picture. The **Marker** panel:
| Option | What it does | Default |
| --- | --- | --- |
| **Scale X / Y / Z** | Size on each axis. | 1.0, 1.0, 1.0 |
| **Colour** | Any colour from the picker. | `#5db6e5` |
| **Alpha** | Opacity, 0 to 255. | 150 |
| **Blip colour presets** | The first 30 blip colours as quick picks, so a marker can match its blip. | |
| **Bob up and down** | Marker floats up and down. | off |
| **Rotate** | Marker spins. | off |
| **Face camera** | Marker always turns towards the camera. | off |
| **Draw distance** | Only draw it when the player is within this many metres. | 20 |
| **Coords** | Marker position (shared with the blip coords). | |
Markers only last one frame, so the snippet draws it every tick while you are close and sleeps 500 ms when you are not. The z is lowered by 0.98 so the marker sits on the ground when you paste player coordinates.
```lua title="marker.lua"
local pos = vector3(215.76, -810.12, 30.73)
CreateThread(function()
while true do
local sleep = 500
local dist = #(GetEntityCoords(PlayerPedId()) - pos)
if dist < 20.0 then
sleep = 0
DrawMarker(
1, -- MarkerTypeVerticalCylinder
pos.x, pos.y, pos.z - 0.98,
0.0, 0.0, 0.0, -- direction
0.0, 0.0, 0.0, -- rotation
1.0, 1.0, 1.0, -- scale
93, 182, 229, 150, -- rgba
false, false, 2, false,
nil, nil, false
)
end
Wait(sleep)
end
end)
```
## Checkpoints
The **Checkpoints** tab lists the `CreateCheckpoint` types (race cylinders, rings, arrows, flags). Ids match game build 2189 and newer. Types that are not used in game are dimmed. A checkpoint is created once and the game keeps drawing it until you delete it, so there is no per-frame loop.
| Option | What it does | Default |
| --- | --- | --- |
| **Number or icon (reserved)** | Only for types 44 to 46. Pick a group (numbers 0 to 99, or chevrons, circles, arrows and spheres with a digit, 100 to 189) and a value. The preview tile updates. | 1 |
| **Position (x, y, z)** | Where the checkpoint is. Shared with the blip and marker coords. | |
| **Next point (x, y, z)** | Only sets where the arrow faces. Pass the next checkpoint of the route. | `225.40, -798.90, 30.73` |
| **Diameter** | 0.5 to 20. | 4 |
| **Colour** / **Alpha** | Main colour. | `#5db6e5`, 120 |
| **Blip colour presets** | Quick picks for the main colour. | |
| **Icon colour** / **Alpha** | Colour of the arrow, flag or number inside. | white, 200 |
| **Cylinder height**: **Near**, **Far**, **Radius** | Height while the player is within the radius (near) and outside it (far). | 2.0, 2.0, 4.0 |
| **Delete when reached** | Adds a loop that deletes the checkpoint once the player is inside it. | on |
```lua title="checkpoint.lua"
local pos = vector3(215.76, -810.12, 30.73)
local nextPos = vector3(225.40, -798.90, 30.73) -- arrows point here
-- Created once. The game draws it every frame until you delete it.
local cp = CreateCheckpoint(
12, -- Ring, 1 arrow
pos.x, pos.y, pos.z,
nextPos.x, nextPos.y, nextPos.z,
4.0, -- diameter
93, 182, 229, 120, -- rgba
0 -- reserved
)
SetCheckpointCylinderHeight(cp, 2.0, 2.0, 4.0) -- near, far, radius
SetCheckpointRgba2(cp, 255, 255, 255, 200) -- icon colour, old name SetCheckpointIconRgba
CreateThread(function()
while true do
if #(GetEntityCoords(PlayerPedId()) - pos) < 2.0 then
DeleteCheckpoint(cp)
break
end
Wait(100)
end
end)
AddEventHandler("onResourceStop", function(resource)
if resource == GetCurrentResourceName() then DeleteCheckpoint(cp) end
end)
```
## Tips
- Use **Short range** for shops, garages and other static points so the minimap edge stays clean.
- `SetBlipScale` between 0.8 and 1.0 matches most vanilla blips.
- Set the same coordinates once: the blip, marker and checkpoint panels share one position, so a shop's blip and its marker line up.
- For a race, chain checkpoints by passing the following checkpoint as **Next point**, and use a chequered flag type for the last one.
- Grab coordinates on the [Interactive Map](/tools/interactive-map) and paste them into **Coords**.
## Common mistakes
- **Marker flickers or costs CPU.** `DrawMarker` must run every frame while visible, but the thread should sleep when the player is far away. Keep the distance check.
- **Checkpoints pile up.** `CreateCheckpoint` inside a loop creates a new one every tick. Create once, delete with `DeleteCheckpoint`.
- **Blip has no name.** The label needs the three text command natives (`BeginTextCommandSetBlipName`, `AddTextComponentSubstringPlayerName`, `EndTextCommandSetBlipName`).
- **Wrong checkpoint shape.** Type ids moved in build 2189. On an older game build, types can look different.
## Limitations
- Previews are pictures, not live renders. Colour and size in game can look a little different.
- Sprite, marker and checkpoint pictures load from the FiveM docs site. If one fails, an icon is shown instead.
- Everything else runs in your browser.
## Related tools
- [Interactive Map](/docs/tools/interactive-map)
- [Text Colors](/docs/tools/text-colors)
- [Controls Reference](/docs/tools/controls-reference)
- [Scaleform Reference](/docs/tools/scaleform-reference)
_Last updated: 2026-09-22_
---
## Weapon Stats & Components
URL: https://fivemad.com/docs/tools/weapon-stats
Look up any GTA V weapon: hashes, group, ammo type, max ammo, damage type, flags, every component, livery and tint, plus a Lua loadout snippet.
Weapon Stats & Components is a searchable list of every GTA V weapon (184 entries, 23 of them vehicle weapons) with its hashes, ammo type, max ammo, flags, attachments and tints. Tick attachments and pick a tint, and it writes the Lua to give that exact loadout.
## What it is for
Giving a weapon with the right attachments means knowing names like `COMPONENT_AT_AR_SUPP` and which tint indices exist for that gun. Shops, loadout menus, armoury scripts and admin tools all need these. This page puts every weapon's components and tints next to each other, with copyable hashes for when you have to decode a value from an event or a database.
## Quick start
1. Type in the search box, for example `carbine`, `suppressor` or `AMMO_SHOTGUN`.
2. Narrow by group with the chips (**All**, **Pistol**, **Smg**, **Rifle** and so on). Each chip shows a count.
3. Click a weapon row to open it.
4. Tick the components you want and click a tint. The **Lua** block updates as you go.
5. Copy the snippet into a client script.
## Searching
The search box matches the weapon name (`WEAPON_*`), its label, its ammo type, and the names and labels of its components. Several words must all match. It also takes a hash: signed, unsigned or `0x` hex, for both weapons and components. So pasting `-2084633992` (the Carbine Rifle) or a component hash from a log finds the weapon it belongs to.
Vehicle weapons (tank cannons, jet guns) are hidden unless you turn on **Vehicle weapons**. The search, group and vehicle toggle are kept in the URL (`?q=`, `?group=`, `?vehicle=1`), and a search that leaves exactly one weapon opens it automatically, so a link like `/tools/weapon-stats?q=WEAPON_PISTOL` lands on the pistol.
## What a weapon shows
Each row shows the picture, label, `WEAPON_*` name, ammo type, hex hash and component count. Opening it shows:
| Section | Contents |
| --- | --- |
| Description | The in-game description, when there is one. |
| **Hashes** | Spawn name, Signed, Unsigned, Hex and Lua backtick, all click to copy. |
| **Details** | Group, Ammo type, Damage type, Model, DLC, Vehicle weapon. |
| **Max ammo** | Story (Default, Skill > 50, Max skill) and Online (the same plus Bonus). |
| **Components** | Label, component name, hash (hex and signed), type and attach slot. The default component is marked **default**. |
| **Liveries / camos** | Mk II camo components, tick to add them. |
| **Tints** | Every tint index with its label. Click one to put it in the snippet, click again to remove it. |
| **Flags** | The weapon's flags, such as `Automatic`, `TwoHanded`, `CanFreeAim`. |
## Example
With the Carbine Rifle open, the flashlight and suppressor ticked and tint 2 picked:
```lua title="client.lua"
local ped = PlayerPedId()
local weapon = `WEAPON_CARBINERIFLE`
GiveWeaponToPed(ped, weapon, 250, false, true)
GiveWeaponComponentToPed(ped, weapon, `COMPONENT_AT_AR_FLSH`) -- Flashlight
GiveWeaponComponentToPed(ped, weapon, `COMPONENT_AT_AR_SUPP`) -- Suppressor
SetPedWeaponTintIndex(ped, weapon, 2) -- Gold tint
```
The ammo amount is the weapon's Online default max ammo (250 when unknown). Nothing ticked means the component and tint lines are shown commented out as a hint.
Checking what the player is holding, against a hash from this page:
```lua
local ped = PlayerPedId()
if GetSelectedPedWeapon(ped) == `WEAPON_CARBINERIFLE`
and HasPedGotWeaponComponent(ped, `WEAPON_CARBINERIFLE`, `COMPONENT_AT_AR_SUPP`) then
print("Suppressed carbine")
end
```
## Tints
Regular weapons have 8 tints, 0 to 7 (Black, Green, Gold, Pink, Army, LSPD, Orange, Platinum). Mk II weapons use their own longer list, for example 33 tints on the Pistol Mk II.
> [!WARNING]
> Tint indices are not shared between normal and Mk II weapons. An index that does not exist for that weapon does nothing, so always use the list shown for the weapon you give.
## Tips
- Only one component per slot applies: giving an extended clip replaces the default clip.
- Mk II camos are components too, give them with `GiveWeaponComponentToPed` like any attachment.
- Components with no label in the list exist in the game files but have no display name, such as rail covers.
## Limitations
The page does not show damage, fire rate, accuracy or range. Those bars on the weapon wheel are HUD values, not raw `weapons.meta` values, so they are left out rather than guessed. For real per-shot damage, read `Damage` in the weapon's `weapons.meta`, or change it at runtime with `SetWeaponDamageModifier`.
Data comes from [DurtyFree/gta-v-data-dumps](https://github.com/DurtyFree/gta-v-data-dumps), images from the FiveM docs.
## Related tools
- [Weapons Meta Editor](/docs/tools/weapons-meta-editor)
- [joaat Hash Calculator](/docs/tools/hash-calculator)
- [Model & Hash Browser](/docs/tools/model-hash-browser)
- [Game Damage Events](/docs/tools/damage-events)
_Last updated: 2026-09-22_
---
## Objects / Props List
URL: https://fivemad.com/docs/tools/objects-list
Find any GTA V prop by name, tag or hash, check it in 3D with its real size, and copy the model name, hashes and a CreateObject snippet.
The Objects / Props List is a searchable catalogue of more than 30,000 GTA V props. Most have a picture, a readable label, a category, tags and their real size in metres, and almost all of them open as a 3D model you can turn around. Pick one and copy its name, its hash or a ready `CreateObject` snippet.
## What it is for
- Finding the right prop for a script or a ymap without guessing names: "office chair", "traffic cone", "atm".
- Checking the size of a prop before you place it, so the table fits in the room.
- Turning a hash from `GetEntityModel` or a log back into a model name.
- Getting the hash of a custom or addon prop name that is not in the base game.
## Quick start
1. Type part of a name, label or tag in the search box (`bench`, `cone`, `chair office`).
2. Narrow it down with a category chip, or tick **Only props with a picture**.
3. Click a prop. It opens in the **Prop** panel on the right (below the list on phones).
4. Look at it in **3D** or as a **Picture**, check the **Size**.
5. Copy the name, a hash, or the Lua snippet under it.
## Search
- Several words narrow the search: `chair office` finds props that have both words in their name, label, category or tags.
- Quotes and backticks are ignored, so you can paste `` `prop_bench_01a` `` from a script.
- Paste a hash to find its model. Signed or unsigned decimal (`1805980844`) and hex (`0x6BA514AC`) both work. The line above the results says **Hash matches prop_bench_01a**, or that no prop in the list has that hash (then it is probably an MLO piece, a map model or an addon).
- Type a single name that is not in the list and a card shows its signed and hex hash anyway. Handy for addon props.
The counter shows how many props match. Very broad searches keep the first 5,000 matches; refine the search to see the rest.
## Filters and views
| Control | What it does |
| --- | --- |
| Category chips | The 7 biggest categories, with counts. **All** clears the filter. |
| **More categories...** | The rest of the categories in a menu. |
| **Only props with a picture** | Hides entries that only have a name. |
| Grid / list buttons | **Grid** shows picture cards (60 per page). **List** shows compact rows with the **Signed** and **Hex** hash in columns (100 per page), click any of them to copy. |
Search, category, view, the picture filter and the selected prop are kept in the page URL, so a link opens the same result.
## The Prop panel
| Part | What it shows |
| --- | --- |
| Preview | The prop in **3D** when a model is available (the default), or its **Picture**. The **3D** / **Picture** switch in the corner changes it. |
| Label and name | The readable label and the model name (click to copy). |
| Category chip and tags | Click the category chip to filter the list by it. |
| **Size** | Width × depth × height in metres. |
| **Signed** / **Hex** | The model hash, click to copy. |
| **Needs game build** | Shown when the prop only exists from a certain game build. Set `sv_enforceGameBuild` to at least that number. |
| Lua snippet | Spawns the prop in front of the player. |
### 3D preview controls
| Input | Action |
| --- | --- |
| Drag | Turn the model |
| Mouse wheel | Zoom |
| Arrow keys (with the preview focused) | Turn |
| + / - | Zoom |
| 0 or Home | Reset the view |
| Reset button (bottom right) | Reset the view |
The model turns slowly on its own until you touch it (not when your system asks for reduced motion). The size in metres is shown in the bottom left corner. The 3D models are lighter than the game's, so small details and textures are simpler. If a prop has no 3D model, or your browser has no WebGL, the picture is shown instead.
## Spawning a prop
The snippet in the panel follows the prop you picked:
```lua
local model = `prop_bench_01a`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local ped = PlayerPedId()
local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.5, 0.0)
local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, false)
PlaceObjectOnGroundProperly(obj)
FreezeEntityPosition(obj, true)
SetModelAsNoLongerNeeded(model)
```
To place many props permanently, use the [YMAP Builder](/tools/ymap-builder) instead: it streams them with the map, with no script running.
Comparing a prop you are looking at against a known model:
```lua
if GetEntityModel(entity) == `prop_atm_01` then
print("That is an ATM")
end
```
## Tips
- Search by what the prop is, not only by its name. Labels and tags cover things like "bench", "barrier" or "plant" even when the model name is cryptic.
- Check **Size** before placing props in an MLO or a tight garage.
- Names ending in `_lod` or `_slod` are distance models, and some map pieces are huge or invisible on their own. Pick the plain name when in doubt.
- `CreateObject` with `true` as the network argument creates a networked object. Use `false` for props only one client needs.
## Common mistakes
- **Prop does not appear.** The model did not load (typo in the name) or the game build is too old. Check **Needs game build**.
- **Prop floats or sinks.** Call `PlaceObjectOnGroundProperly` after creating it, or set the z yourself.
- **Hash search finds nothing.** The model is not a base game prop: MLO parts, map models and addon props are not in the list.
- **Prop falls over.** Freeze it with `FreezeEntityPosition(obj, true)`.
## Limitations
- Base game props only. Addon props are not listed, but typing their name still gives you the hash.
- Not every entry has a picture, a label or a size. Plain name entries still have hashes and the snippet.
- 3D models and pictures are simplified previews, not the in-game look.
- Search and hashing run in your browser.
## Related tools
- [YMAP Builder](/docs/tools/ymap-builder)
- [Model & Hash Browser](/docs/tools/model-hash-browser)
- [joaat Hash Calculator](/docs/tools/hash-calculator)
- [YTYP Creator](/docs/tools/ytyp-creator)
_Last updated: 2026-09-22_
---
## Particle Effects List
URL: https://fivemad.com/docs/tools/particles-list
Search all 2,900+ GTA V particle effects with their ptfx dictionaries and build a working Lua snippet: one-shot, networked or looped.
The Particle Effects List is the full text list of GTA V particle effects: 2,907 effect names in 360 dictionaries (ptfx assets). Search it, pick an effect, choose how you want to spawn it, and copy a Lua snippet that loads the dictionary and starts the effect.
## What it is for
Every particle effect lives inside a dictionary, and you need both names to spawn it. Getting one wrong gives you nothing on screen and no error. This list pairs every effect with its dictionary and writes the loading code for you, so you only decide what the effect should do: fire once, loop on the player, loop at a spot, or show for everyone.
If you want to see what an effect looks like first, many entries have a film icon that opens its video on [Particle videos](/particles).
## Quick start
1. Search for a word (`fire`, `smoke`, `spark`, `water`) or a dictionary name (`core`, `scr_rcbarry2`).
2. Optionally pick a dictionary in the menu next to the search box.
3. Press **Use** on a row. It turns into **Selected** and the snippet updates.
4. Pick a **Mode**, set **Scale** (and **Duration** for looped modes).
5. Copy `ptfx.lua` or press its **Download** button, and test it in game.
## The list
| Column | What it does |
| --- | --- |
| **Effect** | The effect name. Click to copy. A film icon means there is a video preview: click it to watch it on [Particle videos](/particles). |
| **Dictionary** | The ptfx asset it belongs to. Click to copy. |
| **Use** | Loads this effect into the snippet panel. |
The search matches effect names and dictionary names: typing a dictionary name lists all of its effects. The panel title shows how many effects match. Rows load 100 at a time with a button for more.
## Snippet options
| Option | What it does | Default |
| --- | --- | --- |
| **Mode**: **At coord** | One-shot effect at the player's position, only this client sees it. Uses `StartParticleFxNonLoopedAtCoord`. | selected |
| **Mode**: **Networked** | One-shot effect other players also see. Uses `StartNetworkedParticleFxNonLoopedAtCoord`. | |
| **Mode**: **Looped on entity** | Attached to the player ped until stopped. Uses `StartParticleFxLoopedOnEntity`. | |
| **Mode**: **Looped at coord** | Looped effect at a fixed position until stopped. Uses `StartParticleFxLoopedAtCoord`. | |
| **Scale** | Effect size. Any value above 0. | 1.0 |
| **Duration (ms)** | How long a looped effect runs before `StopParticleFxLooped`. Only for looped modes. | 5000 |
| **Networked** | Only in **Looped on entity**: switches to `StartNetworkedParticleFxLoopedOnEntity` so others see it. | off |
| **Wrap in /ptfx command** | Wraps the code in a `/ptfx` command for quick testing. | off |
The panel starts with `core` / `ent_sht_steam` selected.
## Examples
**At coord**, the default:
```lua title="ptfx.lua"
CreateThread(function()
local dict, name = "core", "ent_sht_steam"
RequestNamedPtfxAsset(dict)
while not HasNamedPtfxAssetLoaded(dict) do Wait(0) end
local coords = GetEntityCoords(PlayerPedId())
UseParticleFxAsset(dict)
StartParticleFxNonLoopedAtCoord(name, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 1.0, false, false, false)
RemoveNamedPtfxAsset(dict)
end)
```
**Looped at coord** with **Wrap in /ptfx command**:
```lua title="ptfx.lua"
RegisterCommand("ptfx", function()
CreateThread(function()
local dict, name = "core", "ent_sht_steam"
RequestNamedPtfxAsset(dict)
while not HasNamedPtfxAssetLoaded(dict) do Wait(0) end
local coords = GetEntityCoords(PlayerPedId())
UseParticleFxAsset(dict)
local fx = StartParticleFxLoopedAtCoord(name, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 1.0, false, false, false, false)
Wait(5000)
StopParticleFxLooped(fx, false)
RemoveNamedPtfxAsset(dict)
end)
end, false)
```
**Looped on entity** keeps a handle so you can stop it:
```lua
UseParticleFxAsset(dict)
-- offset xyz, rotation xyz, scale, axis flip x/y/z
local fx = StartParticleFxLoopedOnEntity(name, PlayerPedId(), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, false, false, false)
```
## How to load an effect
The order matters:
1. `RequestNamedPtfxAsset(dict)` and wait for `HasNamedPtfxAssetLoaded(dict)`.
2. `UseParticleFxAsset(dict)` right before the start call. It only applies to the next `Start*ParticleFx*` call, so call it again before each one.
3. Start the effect with the native that fits (see **Mode** above).
4. Looped effects return a handle: stop them with `StopParticleFxLooped(handle, false)`.
5. `RemoveNamedPtfxAsset(dict)` when you no longer need the dictionary.
For looped effects you can also change colour and alpha with `SetParticleFxLoopedColour` and `SetParticleFxLoopedAlpha`, but only effects made with tintable colours react.
## Common mistakes
- **Nothing shows up.** Looped and one-shot effects are not interchangeable. Most names with `_loop`, `ent_amb_` or `_trail` are looped: switch the mode and try again.
- **Forgot `UseParticleFxAsset`.** Without it right before the start call, the game looks in the wrong dictionary.
- **Effect never stops.** You dropped the handle of a looped effect. Keep it and call `StopParticleFxLooped`.
- **Other players cannot see it.** Use a networked mode.
- **Scale does nothing.** Some effects ignore scale or only change part of the effect.
> [!TIP]
> Test with **Wrap in /ptfx command** on, type `/ptfx` in game, and try both modes. Once it looks right, turn the wrapper off and paste the code where you need it.
## Limitations
- Names and dictionaries only. For previews, use [Particle videos](/particles), which has clips for most effects.
- The snippet always spawns at or on the player. Change the coordinates or entity for your use.
- Everything runs in your browser.
## Related tools
- [Particle videos](/docs/tools/particle-videos)
- [Sound Browser](/docs/tools/sound-browser)
- [Objects / Props List](/docs/tools/objects-list)
_Last updated: 2026-09-22_
---
## Particle videos
URL: https://fivemad.com/docs/tools/particle-videos
Watch video previews of 2,300+ GTA V particle effects, filter by dictionary, and copy a ready FiveM Lua snippet for the effect you like.
Particle videos lets you see what a GTA V particle effect looks like before you put it in a script. It has 2,317 effects from 278 dictionaries, and 2,312 of them have a video clip recorded in game. Hover a card to play it, click it for the names and a Lua snippet.
## What it is for
Effect names like `scr_xm_orbital_blast` or `ent_amb_fbi_door_smoke` tell you little. Testing each one in game means a restart per try. Here you scroll through a dictionary, watch the clips, and only take the one that fits into your script.
For the complete text list (2,907 effects, including those without a clip) use the [Particle Effects List](/tools/particles-list). Rows there that have a clip show a film icon linking back here.
## Quick start
1. Open [Particle videos](/particles).
2. Search for a word (`fire`, `explosion`, `water`, `smoke`) or pick a dictionary on the left.
3. Hover a card to play its clip. Turn on **Autoplay** to play every clip on screen as you scroll.
4. Click a card to open it.
5. In the window, pick a snippet mode, set the scale and copy the code.
## Browsing
| Control | What it does |
| --- | --- |
| Search box | Matches effect and dictionary names. Several words narrow the search. `#120` or `120` jumps to effect number 120. |
| Dictionary list (left, desktop) | Every dictionary with its effect count. Filter the list with the box on top. Click a dictionary again to clear it. **All dictionaries** shows everything. |
| Dictionary menu (phones and tablets) | Same as the list, as a menu next to the search box. |
| **Autoplay** | Off: a clip plays while you hover its card. On: every card on screen plays. Remembered in your browser. |
| **Clear filters** | Resets the search and the dictionary. |
| **Show more** | Cards load 48 at a time. |
Each card shows the effect number (`#id`), the effect name, its dictionary and a copy button for the name. Effects without a clip say **No preview**.
The search, dictionary and open effect are kept in the page URL (`/particles?q=fire&dict=core&fx=120`), so you can send someone a link to an exact effect.
## The effect window
| Part | What it does |
| --- | --- |
| Video | Plays the clip in a loop, with player controls. |
| **Effect**, **Dictionary**, **Both** | Copy the effect name, the dictionary, or both as `dict:effect`. |
| **Snippet** tabs | **At coords**, **On entity** or **Networked**. |
| **Scale** | Slider from 0.1 to 5. |
| Code block | The Lua snippet for the chosen mode and scale. |
| Arrows / counter | Previous and next effect in the current results (for example `3 / 48`). |
Keyboard: Left and Right go to the previous or next effect, Esc closes the window. Clicking outside also closes it.
## Snippet modes
| Mode | Native | Use it for |
| --- | --- | --- |
| **At coords** | `StartParticleFxNonLoopedAtCoord` | One-shot effect at the player's position, only this client sees it. |
| **On entity** | `StartParticleFxLoopedOnEntity` | Looped effect attached to the player, stopped after 5 seconds. |
| **Networked** | `StartNetworkedParticleFxNonLoopedAtCoord` | One-shot effect every nearby player sees. |
**At coords** for `core` / `ent_sht_steam` at scale 1:
```lua
local dict, name = 'core', 'ent_sht_steam'
RequestNamedPtfxAsset(dict)
while not HasNamedPtfxAssetLoaded(dict) do Wait(0) end
UseParticleFxAsset(dict)
-- One-shot effect at the player's position (only this client sees it).
local coords = GetEntityCoords(PlayerPedId())
StartParticleFxNonLoopedAtCoord(name, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 1.00, false, false, false)
RemoveNamedPtfxAsset(dict)
```
**On entity**:
```lua
local dict, name = 'core', 'ent_sht_steam'
RequestNamedPtfxAsset(dict)
while not HasNamedPtfxAssetLoaded(dict) do Wait(0) end
UseParticleFxAsset(dict)
-- Looped effect attached to the player. Keep the handle to stop it later.
local ped = PlayerPedId()
local handle = StartParticleFxLoopedOnEntity(name, ped, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.00, false, false, false)
Wait(5000)
StopParticleFxLooped(handle, false)
RemoveNamedPtfxAsset(dict)
```
The snippet runs its `Wait` directly, so put it inside a `CreateThread` or a command handler. For a looped effect at a fixed spot (`StartParticleFxLoopedAtCoord`) or a custom duration, build the snippet in the [Particle Effects List](/tools/particles-list), which has those options.
## Tips
- Turn on **Autoplay** and pick a dictionary to skim through it quickly. With a slow connection, leave it off and hover instead.
- If the effect looks right in the clip but nothing shows in game, you probably used the wrong mode. Clips do not tell you whether an effect is looped: most names with `_loop`, `ent_amb_` or `_trail` are.
- Effect and dictionary names are the same in FiveM, alt:V and RageMP, so names you find here work in any of them.
## Limitations
- 5 effects in the list have no clip.
- Clips show the effect at its default scale and colour. Your scale and any colour changes will look different.
- The video previews were originally recorded for the alt:V ParticleDB.
## Related tools
- [Particle Effects List](/docs/tools/particles-list)
- [Sound Browser](/docs/tools/sound-browser)
_Last updated: 2026-09-22_
---
## Sound Browser
URL: https://fivemad.com/docs/tools/sound-browser
Search GTA V sound names and sound sets, listen to them in the browser, and copy a working PlaySoundFrontend, PlaySoundFromCoord or PlaySoundFromEntity call.
The Sound Browser lists 2,179 known GTA V script sounds across 498 sound sets. 1,353 of them have a preview you can play right in the page. Pick one, hear it, and copy a Lua call that plays it in FiveM.
## What it is for
Finding the right beep for a menu, a checkpoint or a hacking minigame usually means guessing names in game and restarting. Here you can listen through dozens of candidates in a minute, then copy the exact name and set, already wrapped in the native you need.
## Quick start
1. Type part of a name or set in the search box (`beep`, `checkpoint`, `HUD_FRONTEND`).
2. Click a row to select it and hear it. The round button on each row plays or stops without moving the selection.
3. Use ↑ and ↓ to step through the list and Space to play or stop. While something is playing, stepping with the arrows plays the next sound too.
4. In the detail panel, choose a snippet tab and copy the code.
## Filters and list
| Control | What it does |
| --- | --- |
| Search box | Matches sound name and set name. Several words must all match. |
| Sound set list (left side on wide screens, a dropdown on smaller ones) | Limits the list to one set. Each set shows its count. **No set (AudioRef 0)** holds names that play without a set. The side list has its own filter box. |
| **Only with preview** | Hides sounds that have no clip. |
| Volume slider and mute button | Preview volume. |
| **Loop** | Repeats the preview. |
| **Clear filters** | Resets search, set and the preview toggle. |
The list shows 120 rows at first, **Show more** adds more. Each row has **Name** and **Set** copy buttons, and icons for sounds that are one of several random variations (shuffle) or that loop in game (repeat). Sounds with no clip show a crossed speaker, and generated ones show "synth" in place of a duration.
The search, set and selected sound are kept in the URL (`?q=`, `?set=`, `?s=`), so you can send someone a link to the exact sound you mean. On phones and tablets, the info button on a row opens the details in a drawer.
## Detail panel
The panel shows the name and set (click to copy), the clip length, and notes about the preview when they apply:
- One of several variations: the game picks one at random each time.
- Partly synthesized: the preview has only the recorded layers.
- Looping: in game it keeps playing until your script stops it.
- Streamed from disk: it can start a moment late the first time.
- Several recorded layers mixed together, as the game plays them.
**Same name elsewhere** lists up to 6 other sets that have a sound with the same name, so you can compare them.
### Snippet tabs
| Tab | Native used | Notes |
| --- | --- | --- |
| **Frontend** | `PlaySoundFrontend(-1, ...)` | 2D, fire and forget. For looping sounds it tells you to use the Sound ID tab, since id -1 cannot be stopped. |
| **Sound ID** | `GetSoundId` + `PlaySoundFrontend` | Stops and releases the id in a thread. |
| **Coords** | `PlaySoundFromCoord` | Plays at the player's position. |
| **Entity** | `PlaySoundFromEntity` | Plays on the player ped, or swap in a vehicle or object. |
When the sound's waves are in a bank that is not always loaded, the panel shows the **Wave bank** and every snippet loads it first with `RequestScriptAudioBank` and releases it at the end.
## Examples
A one-shot menu sound:
```lua
PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", true)
```
A sound you need to stop, in the style of the **Entity** tab:
```lua title="client.lua"
local soundId = GetSoundId()
PlaySoundFromEntity(soundId, "Beep_Red", PlayerPedId(), "DLC_HEIST_HACKING_SNAKE_SOUNDS", false, 0)
CreateThread(function()
local stopAt = GetGameTimer() + 10000
while not HasSoundFinished(soundId) and GetGameTimer() < stopAt do
Wait(100)
end
StopSound(soundId)
ReleaseSoundId(soundId)
end)
```
> [!IMPORTANT]
> Always call `ReleaseSoundId` when you are done with an id from `GetSoundId`. The game has a small pool of sound ids, and leaking them breaks audio for every script on the client.
## When a sound is silent in game
- DLC sound sets only exist when the server runs that game build. Set `sv_enforceGameBuild` in `server.cfg`.
- If the panel shows a wave bank, keep the `RequestScriptAudioBank` part of the snippet.
- Streamed sounds can start late the first time they play.
- Names under **No set (AudioRef 0)** are passed with `0` as the set, as the snippets do.
## Limitations
- Some sounds have no preview. Many HUD beeps are generated live by the game's synthesizer and have no recording, and some names could not be matched to game data (newer DLC, renamed sets, or sets built at run time).
- For random-variation sounds you hear one of the variations.
- Preview levels are evened out so you can compare clips. In game, volume also depends on the sound's category, distance and the player's audio settings.
Sound names and sets come from [mikigoalie/gta_sound_tester](https://github.com/mikigoalie/gta_sound_tester), originally collected by PlebMasters.
## Related tools
- [Native Audio Builder](/docs/tools/native-audio-builder)
- [Controls Reference](/docs/tools/controls-reference)
- [Scaleform Functions](/docs/tools/scaleform-reference)
- [Particle Effects List](/docs/tools/particles-list)
_Last updated: 2026-09-22_
---
## Controls Reference
URL: https://fivemad.com/docs/tools/controls-reference
Find any GTA V control index by number, INPUT_ name or key, press a real key to see every control on it, and copy detect, disable or RegisterKeyMapping code.
The Controls Reference lists all 361 GTA V controls (index 0 to 360) with their `INPUT_` name, default keyboard key and default gamepad button. Press a key on your keyboard or controller to see every control bound to it, then copy a snippet to detect it, disable it, or replace it with your own key mapping.
## What it is for
`IsControlJustPressed(0, 51)` means nothing until you know 51 is `INPUT_CONTEXT` on E . And E is also `INPUT_PICKUP`, `INPUT_TALK`, `INPUT_VEH_HORN` and more, depending on what the player is doing. This page answers "what index is that key" and "what else uses this key" before you pick one for your script.
## Quick start
1. Search by index (`51`), name (`CONTEXT`, `veh exit`) or key (`E`, `LEFT SHIFT`). Searching for a single letter or two looks up the key, not names.
2. Or click **Press a key to find it** and press the real key. Click **Stop listening** when done.
3. Click a row. The detail panel (right side on desktop, inline on phones) shows the bindings and snippets. Before you click anything it shows control 51.
4. Pick the **Input group**, a snippet tab, and copy the code.
## Filters
| Control | What it does |
| --- | --- |
| Search box | Index, `INPUT_` name, name words or key. Exact index and key matches rank first. |
| Group dropdown | On foot, Camera, Weapons, Melee, Vehicle, Aircraft, Submarine, Bicycle, Parachute, Phone, Frontend, Cursor & map, Script, Multiplayer, Replay editor, Creator. Each shows a count. |
| Device chips | **All**, **Keyboard / mouse** (has a keyboard default), **Gamepad only**, **No default**. |
| **Copy link** | Copies a link to the exact view. |
The list shows 80 rows at a time with a button to show more. Click the index or name to copy it, click a key chip to filter the list by that key.
## Key finder
The **Key finder** panel has a **Keyboard** and a **Gamepad** tab. Each key on the map shows how many controls use it (within the current group). Click a key to filter the list, and **Clear key** removes the filter.
With listening on:
- Any key press on the keyboard selects that key.
- A box appears where you can left click, right click, middle click or scroll to pick mouse buttons and the wheel.
- On the **Gamepad** tab, pressing a controller button or pushing a stick picks it. Browsers only see a controller after you press something on it, and controllers without the standard mapping may pick the wrong button.
## Detail panel
Shows the name, index, group, whether it is an axis, the keyboard and gamepad bindings, and the raw text from the FiveM docs.
**Input group (first argument)** switches the snippets between:
| Value | Name | Use it for |
| --- | --- | --- |
| `0` | PLAYER_CONTROL | Almost everything: on foot, driving, weapons. |
| `1` | CAMERA_CONTROL | Camera inputs, rarely needed. |
| `2` | FRONTEND_CONTROL | Menus and the pause screen. Still works while a frontend menu is open. |
### Snippet tabs
| Tab | What you get | File name |
| --- | --- | --- |
| **Detect** | A `Wait(0)` loop with `IsControlJustPressed`, `IsControlPressed` or `IsControlJustReleased` (buttons to switch). For axis controls the tab is called **Read** and uses `GetControlNormal`. | `control.lua` |
| **Disable** | `DisableControlAction` every frame plus an `IsDisabledControlJustPressed` check. | `disable_control.lua` |
| **Key mapping** | `+` and `-` commands with `RegisterKeyMapping`, using the control's default key. Set a **Command prefix** (default `myres`) and a **Settings label**. | `keymapping.lua` |
## Examples
Detecting E near something:
```lua title="control.lua"
CreateThread(function()
while true do
Wait(0)
if IsControlJustPressed(0, 51) then -- INPUT_CONTEXT (E, pad DPAD RIGHT)
-- your code here
end
end
end)
```
Blocking attacks in a safe zone:
```lua title="disable_control.lua"
CreateThread(function()
while true do
Wait(0)
DisableControlAction(0, 24, true) -- INPUT_ATTACK
if IsDisabledControlJustPressed(0, 24) then
-- player tried to shoot
end
end
end)
```
A rebindable key for your own feature:
```lua title="keymapping.lua"
RegisterCommand("+myres_context", function()
-- key pressed
end, false)
RegisterCommand("-myres_context", function()
-- key released
end, false)
RegisterKeyMapping("+myres_context", "Open my menu", "keyboard", "E")
```
## Control index or RegisterKeyMapping?
- **Control indexes** are the game's own actions. Use them to react to or block vanilla input. If a player rebinds a GTA action, the index follows their key. They need a `Wait(0)` loop and you cannot give your feature its own key.
- **RegisterKeyMapping** adds an entry under Settings, Key Bindings, FiveM. Each player can change it, it is saved on their machine, and it needs no loop. Use it for anything your resource adds: menus, radios, emotes.
> [!WARNING]
> The default key of a mapping only applies the first time a player sees it. Changing it in your script later does not move existing players, so choose it carefully.
## Tips
- `DisableControlAction` lasts one frame. Call it every tick.
- While a control is disabled, `IsControlJustPressed` returns false. Use `IsDisabledControlJustPressed` or `IsDisabledControlPressed`.
- `DisableAllControlActions(0)` blocks the whole group; re-enable what you need with `EnableControlAction`.
- If a check does nothing while a pause menu or frontend is open, try input group `2`.
## Shareable links
The URL follows the page: `?q=` for the search, `?key=` for the selected key (`?key=E`, `?key=LSHIFT`, `?key=pad:DPAD RIGHT`) and `?id=` for the open control.
## Limitations
Keyboard keys are the QWERTY defaults and gamepad buttons use Xbox names, as the FiveM docs list them. A player's own bindings may differ. Everything runs in the browser, and key presses are only read while listening is on.
## Related tools
- [Draw Text Colors](/docs/tools/text-colors) (for `~INPUT_CONTEXT~` prompts)
- [Warning Screen Buttons](/docs/tools/warning-buttons)
- [Scaleform Functions](/docs/tools/scaleform-reference)
- [Sound Browser](/docs/tools/sound-browser)
_Last updated: 2026-09-22_
---
## Scaleform Functions
URL: https://fivemad.com/docs/tools/scaleform-reference
Search 471 GTA V scaleform movies and 4,847 functions, see their parameter names, and build a ready Lua call with BeginScaleformMovieMethod and a draw loop.
Scaleform Functions is a reference of GTA V scaleform movies and the functions you can call on them, with their parameter names. Pick a function, fill the parameters, and copy a Lua snippet that loads the movie, calls it and draws it.
## What it is for
Scaleform movies are the Flash UI files GTA V uses for big "mission passed" shards, instructional buttons, phones, computer screens, the minimap and more. Using one from a script means knowing the movie name, the function name and the order of its arguments. This page lists all of that and writes the boilerplate so you can try a message in seconds.
## Quick start
1. The page opens on `MIDSIZED_MESSAGE` with `SHOW_SHARD_MIDSIZED_MESSAGE` selected.
2. Search movie names in the **Movies** tab, or switch to **Functions** to search function names across every movie (type at least 2 characters, for example `SET_TITLE`).
3. Click a movie, then a function in its list.
4. In the **Snippet builder**, check the type of each parameter and type a value.
5. Copy `scaleform.lua`.
## Browsing
| Control | What it does |
| --- | --- |
| **Movies** / **Functions** tabs | Search by movie name, or by function name across all movies. The Functions search also matches a parameter name exactly. |
| Category chips | **All**, frontend, generic, generic_2, heist_mp, minigames, minimap, platform_pc, web. |
| **UPPERCASE functions only** | Hides lowercase functions, which are mostly internal. |
| **Filter functions** | Appears on a movie with more than 8 functions. |
Each movie shows its category, its name (click to copy) and the function count. Functions are listed with their parameter names, for example `SHOW_SHARD_MIDSIZED_MESSAGE(bigText, msgText, colID, useDarkerShard, useCondensedShard)`. The selected movie and function are kept in the URL (`?movie=` and `?fn=`), so you can link someone straight to a function.
## Snippet builder
For every parameter you get a type dropdown and a value field. The type is pre-filled from the parameter name (`useDarkerShard` becomes a bool, `colID` an int, `bigText` a string). Change it if the movie expects something else.
| Type | Native written |
| --- | --- |
| int | `ScaleformMovieMethodAddParamInt` |
| float | `ScaleformMovieMethodAddParamFloat` |
| bool | `ScaleformMovieMethodAddParamBool` |
| string (TextureNameString) | `ScaleformMovieMethodAddParamTextureNameString` |
| string (PlayerNameString) | `ScaleformMovieMethodAddParamPlayerNameString` |
| text (BeginTextCommand...) | `BeginTextCommandScaleformString("STRING")`, `AddTextComponentSubstringPlayerName`, `EndTextCommandScaleformString` |
| Option | What it does | Default |
| --- | --- | --- |
| **Draw fullscreen** | Adds a `DrawScaleformMovieFullscreen` loop after the call. | on |
| **Duration (seconds)** | How long to draw before `SetScaleformMovieAsNoLongerNeeded`. `0` draws forever. | 5 |
Use the text type when you want `~r~` style colour codes or long strings, since the plain string natives do not format.
## Example
What the builder writes for a green midsized shard:
```lua title="scaleform.lua"
local function LoadScaleform(name)
local handle = RequestScaleformMovie(name)
local timeout = GetGameTimer() + 5000
while not HasScaleformMovieLoaded(handle) do
if GetGameTimer() > timeout then return nil end
Wait(0)
end
return handle
end
CreateThread(function()
local scaleform = LoadScaleform("MIDSIZED_MESSAGE")
if not scaleform then return print("Could not load MIDSIZED_MESSAGE") end
BeginScaleformMovieMethod(scaleform, "SHOW_SHARD_MIDSIZED_MESSAGE")
ScaleformMovieMethodAddParamTextureNameString("MISSION PASSED") -- bigText
ScaleformMovieMethodAddParamTextureNameString("You delivered the car") -- msgText
ScaleformMovieMethodAddParamInt(2) -- colID
ScaleformMovieMethodAddParamBool(false) -- useDarkerShard
ScaleformMovieMethodAddParamBool(false) -- useCondensedShard
EndScaleformMovieMethod()
local untilTime = GetGameTimer() + 5000
while GetGameTimer() < untilTime do
DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0)
Wait(0)
end
SetScaleformMovieAsNoLongerNeeded(scaleform)
end)
```
## Tips
- A scaleform only shows while you draw it every frame.
- Call functions after the movie has loaded, or they are dropped.
- Release a movie you no longer need with `SetScaleformMovieAsNoLongerNeeded`.
- `colID` style parameters take HUD colour ids. The [Draw Text Colors](/tools/text-colors) page lists the common HUD colours by name.
> [!WARNING]
> Movies in the **frontend** category (pause menu and similar) usually cannot be drawn with `DrawScaleformMovie`. They are driven through `BeginScaleformMovieMethodOnFrontend` and friends, and are mostly undocumented. The tool shows a warning on those movies.
## Limitations
- Not every listed function does something in game. UPPERCASE functions are the movie's public API and usually work; lowercase ones are internal but sometimes work too.
- Only parameter names are known, not their types or allowed values. Test in game.
Data: Vespura ([tomgrobbe.com](https://tomgrobbe.com/fivem/scaleform/)).
## Related tools
- [Draw Text Colors](/docs/tools/text-colors)
- [Warning Screen Buttons](/docs/tools/warning-buttons)
- [Controls Reference](/docs/tools/controls-reference)
- [Sound Browser](/docs/tools/sound-browser)
_Last updated: 2026-09-22_
---
## Player Stats List
URL: https://fivemad.com/docs/tools/player-stats
Search 3,025 GTA V stat names by name or description, see their type, scope and hash, and copy the right StatGetInt, StatSetInt or StatSetFloat call.
The Player Stats List is a searchable list of 3,025 known GTA V stat names with their data type, whether they are per character or global, and their hash. Pick one and it writes the Lua to read and set it with the native that matches its type.
## What it is for
The most common use on a FiveM server is the skill bars: stamina, strength, lung capacity, shooting, driving and flying. They affect how the player ped actually behaves, and you set them through stats. Beyond those, the list helps when you find a stat name in a script and need its type or hash, or when you want to know whether a stat needs the `MP0_` prefix.
## Quick start
1. Click one of the **Common ones** chips (`STAMINA`, `STRENGTH`, `LUNG_CAPACITY`, `SHOOTING_ABILITY`, `WHEELIE_ABILITY`, `FLYING_ABILITY`, `STEALTH_ABILITY`), or search the list.
2. Pick the **Prefix**: **MP0_** (first character, the default), **MP1_** or **None**.
3. Type the **Value to set**.
4. Copy `stats.lua`.
## Filters
| Control | What it does |
| --- | --- |
| Search box | Matches stat names and descriptions. A leading `MP0_` or `MP1_` in your search is ignored, so pasting a full name works. |
| **Prefix** | The prefix shown and used for per character stats: **MP0_**, **MP1_** or **None**. |
| Type chips | **All types** or one of int, u64, bool, u32, userid, string, s64, float, date, pos, label, packed, each with a count. |
| Scope chips | **All stats**, **Per character (prefixed)**, **Global (no prefix)**. |
The list shows 60 stats at a time. Each row shows the full name (with the prefix greyed out), the description, the type and the hex hash of the full name (click to copy).
## Selected stat
The **Selected stat** panel shows the full name, description, **Type**, **Hash (hex)**, **Hash (signed)**, **Hash (unsigned)** and **Scope**. The hash always matches the prefix you picked, since `MP0_STAMINA` and `MP1_STAMINA` are different stats. If you pick **None** on a per character stat, a warning reminds you that it normally needs a prefix.
**Value to set** is a true / false dropdown for bool stats and a text field for the rest. It is hidden for date, packed and pos stats, which use their own snippet.
## Which native for which type
| Type | Read | Write |
| --- | --- | --- |
| int, u32 | `StatGetInt` | `StatSetInt` |
| s64, u64 | `StatGetInt` (32-bit range) | `StatSetInt`, or `StatSetCurrentPosixTime` for timestamp stats |
| float | `StatGetFloat` | `StatSetFloat` |
| bool | `StatGetBool` | `StatSetBool` |
| string | `StatGetString` | `StatSetString` |
| label | n/a | `StatSetGxtLabel` (a text label key, not free text) |
| userid | `StatGetUserId` | `StatSetUserId` |
| pos | `StatGetPos` | `StatSetPos` (the snippet uses the player's position) |
| date | `StatGetDate` | `StatSetDate` (a 7 int struct, awkward from Lua) |
| packed | `GetPackedStatBoolCode` / `GetPackedStatIntCode` | `SetPackedStatBoolCode` / `SetPackedStatIntCode`, by index not name |
## Examples
What the tool writes for `MP0_STAMINA` with value 100:
```lua title="stats.lua"
local stat = `MP0_STAMINA` -- joaat("MP0_STAMINA")
local ok, value = StatGetInt(stat, -1)
if ok then print("MP0_STAMINA", value) end
-- Last argument = save. On FiveM there is no cloud save, so set it again on every spawn.
StatSetInt(stat, 100, true)
```
Max out every skill bar each time the player spawns:
```lua title="client.lua"
local SKILLS = { "STAMINA", "STRENGTH", "LUNG_CAPACITY", "SHOOTING_ABILITY",
"WHEELIE_ABILITY", "FLYING_ABILITY", "STEALTH_ABILITY" }
AddEventHandler("playerSpawned", function()
for _, name in ipairs(SKILLS) do
StatSetInt(GetHashKey("MP0_" .. name), 100, true)
end
end)
```
## Tips
> [!IMPORTANT]
> FiveM has no Rockstar cloud save. Stats live on the client and reset when the game restarts. Store the real values in your own database and set them again on every spawn.
- Most stats only matter to GTA Online's own scripts and do nothing on a FiveM server. The skill stats do work.
- The `save` argument of the setters can stay `true`. It does nothing harmful on FiveM.
- `MPPLY_` stats and other global stats are used without a prefix. Use the **Global (no prefix)** chip to see them.
## Limitations
The list is generated from the game's MP stat definitions and may contain mistakes or stats that no longer exist. Everything runs in your browser.
Data: Vespura ([tomgrobbe.com](https://tomgrobbe.com/fivem/gta-stats/)).
## Related tools
- [joaat Hash Calculator](/docs/tools/hash-calculator)
- [Parachutes & Smoke Trails](/docs/tools/parachutes)
- [Weapon Stats & Components](/docs/tools/weapon-stats)
_Last updated: 2026-09-22_
---
## Parachutes & Smoke Trails
URL: https://fivemad.com/docs/tools/parachutes
Every GTA V parachute canopy tint and smoke trail colour with indices, text labels and RGB values, plus a snippet builder for the parachute natives.
Parachutes & Smoke Trails lists all 14 canopy tints and 8 smoke trail options with their indices, text labels and RGB values. Click a canopy, pick a smoke colour, and copy a snippet that gives the parachute and applies everything to the player.
## What it is for
Skydiving events, BASE jumping jobs, or a store that sells parachute styles all need the tint indices and the natives to apply them. Six of the canopies also need a model swap that is easy to miss. The snippet handles that for you.
## Quick start
1. Click a card under **Canopy tints**. With **Same tint everywhere** on (the default), the main canopy, reserve and pack all follow it.
2. Turn **Smoke trail** on or off and click a colour swatch, or use **Custom** to pick any colour.
3. Copy `parachute.lua` from under the **Snippet builder**.
## Canopy tints
| Index | Name | Label | Model override |
| --- | --- | --- | --- |
| 0 | Rainbow Chute | `PM_TINT0` | |
| 1 | Red Chute | `PM_TINT1` | |
| 2 | Seaside Stripes Chute | `PM_TINT2` | |
| 3 | Widowmaker Chute | `PM_TINT3` | |
| 4 | Patriot Chute | `PM_TINT4` | |
| 5 | Blue Chute | `PM_TINT5` | |
| 6 | Black Chute | `PM_TINT6` | |
| 7 | Hornet Chute | `PM_TINT7` | |
| 8 | Air Force Chute | `PS_CAN_0` | yes |
| 9 | Desert Chute | `PS_CAN_1` | yes |
| 10 | Shadow Chute | `PS_CAN_2` | yes |
| 11 | High Altitude Chute | `PS_CAN_3` | yes |
| 12 | Airborne Chute | `PS_CAN_4` | yes |
| 13 | Sunrise Chute | `PS_CAN_5` | yes |
Each card also shows the description label (`PD_TINT*` or `PSD_CAN_*`), click to copy. Tints 8 to 13 are the San Andreas Flight School canopies and are marked **model override**: they only appear after you swap the canopy model to `pil_p_para_pilot_sp_s`.
## Smoke trail colours
| Name | RGB | Label |
| --- | --- | --- |
| No Smoke Trail | none | `PM_TINT8` |
| Red Smoke Trail | 255, 0, 0 | `PM_TINT9` |
| Orange Smoke Trail | 255, 165, 0 | `PM_TINT10` |
| Yellow Smoke Trail | 255, 255, 0 | `PM_TINT11` |
| Blue Smoke Trail | 0, 0, 255 | `PM_TINT12` |
| Black Smoke Trail | 20, 20, 20 | `PM_TINT13` |
| Crew Smoke Trail | crew colour, pick any RGB | `PM_TINT14` |
| Patriot Smoke Trail | 255, 0, 0 / 255, 255, 255 / 0, 0, 255 | `PM_TINT15` |
Click a swatch in the table to use it in the snippet (it also turns the smoke trail on). Smoke trails are not a tint index: you turn them on and pass any RGB you like. The Patriot trail is three colours, but the native takes one RGB per call, so pick one or cycle them yourself.
## Snippet builder
| Option | What it does | Default |
| --- | --- | --- |
| **Same tint everywhere** | Main, reserve and pack follow the card you click. Changing one of the dropdowns turns it off. | on |
| **Main** / **Reserve** / **Pack** | Tint for each part. | 6 (Black Chute) |
| **Give parachute** | Adds `GiveWeaponToPed` with `gadget_parachute` and `SetPlayerHasReserveParachute`. | on |
| **Smoke trail** | Adds `SetPlayerCanLeaveParachuteSmokeTrail` and the colour. | on, red |
## Example
A Desert Chute (needs the model override) with an orange trail:
```lua title="parachute.lua"
CreateThread(function()
local player = PlayerId()
local ped = PlayerPedId()
GiveWeaponToPed(ped, `gadget_parachute`, 1, false, false)
SetPlayerHasReserveParachute(player)
-- tints 8 to 13 only exist on the flight school canopy
local model = `pil_p_para_pilot_sp_s`
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
SetPlayerParachuteModelOverride(player, model)
SetPlayerReserveParachuteModelOverride(player, model)
SetPlayerParachuteTintIndex(player, 9) -- Desert Chute
SetPlayerReserveParachuteTintIndex(player, 9) -- Desert Chute
SetPlayerParachutePackTintIndex(player, 9) -- Desert Chute
SetPlayerCanLeaveParachuteSmokeTrail(player, true)
SetPlayerParachuteSmokeTrailColor(player, 255, 165, 0)
end)
```
## Natives
| Native | What it does |
| --- | --- |
| `SetPlayerParachuteTintIndex(player, tintIndex)` | Canopy tint of the main parachute. |
| `SetPlayerReserveParachuteTintIndex(player, index)` | Canopy tint of the reserve. |
| `SetPlayerParachutePackTintIndex(player, tintIndex)` | Tint of the backpack. |
| `SetPlayerParachuteModelOverride(player, model)` | Swaps the canopy model (needed for 8 to 13). |
| `SetPlayerReserveParachuteModelOverride(player, model)` | Same, for the reserve. |
| `SetPlayerCanLeaveParachuteSmokeTrail(player, enabled)` | Turns the smoke trail on or off. |
| `SetPlayerParachuteSmokeTrailColor(player, r, g, b)` | Smoke colour, 0 to 255 each. |
| `SetPlayerHasReserveParachute(player)` | Gives a reserve chute. |
Click a native name in the tool to copy it.
## Tips
- These natives take the player id (`PlayerId()`), not the ped.
- The labels are text entries. Use `GetLabelText("PM_TINT7")` to show the localised name in a menu.
- Setting an index from 8 to 13 without the model override shows the wrong canopy.
## Limitations
The canopy previews are approximate drawings from the in-game descriptions, not renders. Everything runs in the browser.
Data: Vespura ([vespura.com](https://vespura.com/fivem/parachutes/)).
## Related tools
- [Weapon Stats & Components](/docs/tools/weapon-stats)
- [Player Stats List](/docs/tools/player-stats)
- [Particle Effects List](/docs/tools/particles-list)
_Last updated: 2026-09-22_
---
## Game Damage Events
URL: https://fivemad.com/docs/tools/damage-events
The CEventNetworkEntityDamage payload from gameEventTriggered explained index by index, plus generated clean kill, death and vehicle events for your resource.
Game Damage Events documents the raw `CEventNetworkEntityDamage` payload FiveM hands to scripts, and generates a small resource that turns it into named events like `damage:onPlayerDied` and `damage:onPlayerKilled`. It is for anyone building a kill feed, death screen, bounty system or vehicle damage logic.
## What it is for
FiveM forwards low-level game events to client scripts through `gameEventTriggered`. When a networked entity takes damage, you get `CEventNetworkEntityDamage` with an array of integers and no names. The layout also changed between game builds, which is why many old snippets read the wrong index and silently break. This page tells you which index is which today, and writes the parsing once so every other script can listen to clean events.
## Quick start
1. Open **Raw args** to see the payload layout, or **Event explorer** to see the events the generated code emits.
2. Tick **Include** on the events you want (five are selected by default).
3. Open **Code builder**, set the **Event prefix** and options.
4. Copy each file tab (`client.lua`, `server.lua`, `fxmanifest.lua`) into a new resource, and use `examples.lua` as a starting point for your listeners.
## The raw payload
On game build 2189 and newer, the args are:
| Index | Lua | Name | Type | Status |
| --- | --- | --- | --- | --- |
| 0 | `args[1]` | victim | entity | Reliable |
| 1 | `args[2]` | attacker | entity (-1 or 0 when none) | Reliable |
| 2 | `args[3]` | unknown, likely the damage amount as a raw float | int | Reported |
| 3 | `args[4]` | unknown, added in b2060 | int | Reported |
| 4 | `args[5]` | unknown, added in b2189 | int | Reported |
| 5 | `args[6]` | fatal (1 when it killed or destroyed the victim) | int 0/1 | Reliable |
| 6 | `args[7]` | weaponHash (weapon or cause, such as `WEAPON_RUN_OVER_BY_CAR`, `WEAPON_FALL`) | hash | Reliable |
| 7 | `args[8]` | unknown, non-zero on vehicle collisions | int | Reported |
| 8 | `args[9]` | unknown, non-zero on vehicle collisions | int | Reported |
| 9 | `args[10]` | unknown, 1 on some headshots or collisions | int 0/1 | Varies by build |
| 10 | `args[11]` | read as isMelee or isHeadshot depending on build | int 0/1 | Varies by build |
| 11 | `args[12]` | isMelee or vehicle damage flags (93 tyres, 116 body, 120 windows) | int | Varies by build |
| 12 | `args[13]` | vehicle damage type or hit material | int | Varies by build |
Only victim, attacker, fatal and weapon are safe to rely on. The attacker can be a vehicle when someone was run over.
Before b2060 the layout was two slots shorter: fatal at index 3 and weaponHash at index 4. Older resources still read those and get wrong values on current builds. The **Old layout (before b2060)** panel lists it.
The minimal handler:
```lua
AddEventHandler("gameEventTriggered", function(name, args)
if name ~= "CEventNetworkEntityDamage" then return end
local victim, attacker = args[1], args[2]
local fatal = args[6] == 1
local weaponHash = args[7]
print(json.encode(args)) -- dump the rest on your build
end)
```
> [!WARNING]
> The event fires on every client that knows the victim, not only on the victim and the attacker. If ten players are near a fight, all ten get it. Filter on `PlayerPedId()` before you reward a kill.
## Events the generated code emits
All are client events named `:`, for example `damage:onPlayerDied`.
| Event | When | Arguments |
| --- | --- | --- |
| `onPlayerDied` | Local player died, any cause. Once per death. | cause, killerServerId, weaponHash, killerEntity |
| `onPlayerKilledByPlayer` | Local player killed by another player (also run over by a player's car). | killerServerId, weaponHash, isMelee, isHeadshot, distance |
| `onPlayerKilledByPed` | Local player killed by an NPC. | killerPed, weaponHash, isMelee |
| `onPlayerKilledByVehicle` | Run over by a vehicle with no player driver. | vehicle, weaponHash |
| `onPlayerKilled` | Local player killed another player (killer side). | victimServerId, weaponHash, isMelee, isHeadshot, distance |
| `onPlayerDamaged` | Local player took damage and survived. Frequent. | attacker, weaponHash, isMelee, attackerServerId |
| `onPedKilledByPlayer` | Local player killed an NPC. | ped, weaponHash, isMelee, isHeadshot |
| `onPedDied` | An NPC died and the local player was not the killer. Every client. | ped, attacker, weaponHash |
| `onVehicleDestroyed` | A vehicle blew up or was wrecked. Every client. | vehicle, attacker, weaponHash, byLocalPlayer |
| `onVehicleDamaged` | A vehicle took damage but survived. Every client, frequent. | vehicle, attacker, weaponHash |
| `onEntityDamaged` | Every raw damage event, untouched, for debugging. | victim, attacker, weaponHash, fatal, args |
`cause` is one of `"player"`, `"ped"`, `"vehicle"`, `"suicide"` or `"environment"`. Selected by default: onPlayerDied, onPlayerKilledByPlayer, onPlayerKilled, onPedKilledByPlayer, onVehicleDestroyed. The **Event explorer** search matches event names, descriptions, groups and argument names, and each card has a ready listener.
In the generated code, melee comes from the weapon group and headshots from `GetPedLastDamageBone` (bone `31086`, the head), not from the unstable slots. Deaths are reported once: shooting a body again does not fire a second death, and deaths that never raised a damage event (fall damage on some builds, `SetEntityHealth(ped, 0)`) are still caught.
## Code builder options
| Option | What it does | Default |
| --- | --- | --- |
| **Events** | Which events to generate. **All** and **None** buttons at the top. | 5 selected |
| **Event prefix** | Prefix for every event name. | `damage` |
| **Debug prints** | Prints every emitted event to the F8 console. | off |
| **Server relay** | Adds `server.lua`: the victim reports its own death, the server checks it and fires `:server:playerDied` and `:server:playerKilled`. | on |
| **Max kill distance (m)** | Server relay drops kill reports where the killer is further away than this (OneSync). | 1000 |
The server relay checks the payload type and cause, allows one report per player every 3 seconds, makes sure the killer is another connected player, and checks the distance between the two peds.
## Examples
Client side, a kill feed line:
```lua title="killfeed.lua"
AddEventHandler("damage:onPlayerKilled", function(victimServerId, weaponHash, isMelee, isHeadshot, distance)
local msg = ("You killed %s (%.0fm)%s"):format(GetPlayerName(GetPlayerFromServerId(victimServerId)), distance, isHeadshot and ", headshot" or "")
print(msg)
end)
```
Server side, with the relay on:
```lua title="server.lua"
AddEventHandler("damage:server:playerDied", function(victim, killer, info)
print(GetPlayerName(victim), "died", info.cause, killer and GetPlayerName(killer))
end)
```
The manifest the tool writes:
```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
client_script 'client.lua'
server_script 'server.lua'
```
## Limitations
- The server never receives `CEventNetworkEntityDamage` itself. The relay trusts the victim's own report, which is the least abusable direction (a cheater can only lie about their own death), but treat it as a kill feed source, not as proof for bans.
- The unknown slots differ between builds. If you need one, turn on `onEntityDamaged` with **Debug prints** and log the raw table on your server's build.
The idea of named damage events comes from Vespura's [DamageEvents](https://github.com/TomGrobbe/DamageEvents) resource. The Lua here is a separate implementation for current game builds.
## Related tools
- [Weapon Stats & Components](/docs/tools/weapon-stats)
- [joaat Hash Calculator](/docs/tools/hash-calculator)
- [fxmanifest.lua Generator](/docs/tools/fxmanifest-generator)
_Last updated: 2026-09-22_
---
## Animation Browser
URL: https://fivemad.com/docs/tools/animations
Browse every GTA V animation dictionary and clip, search the whole set, watch any of them on a freemode ped and copy ready TaskPlayAnim Lua.
The Animation Browser lists every animation dictionary the game ships and plays them on a freemode ped in your browser, so you can see what a clip does before you put it in a script. It also has a section for synchronised scenes: the pairs of animations that were authored to be played by two peds at the same time.
## The two tabs
| Tab | What it holds |
| --- | --- |
| All animations | Every in-game dictionary and clip in the game, browsable and searchable |
| Synced scenes | Two ped scenes with their props, both peds on one timeline |
## All animations
The first tab is the whole in-game set: 11,273 dictionaries and 97,204 clips, the real names and the real numbers straight out of the game files. You browse it in three steps.
1. Pick a family (heists, ambient and scenarios, movement, vehicles, weapons and combat, nightclub, casino, animals, story mode and the rest). Each one says how many dictionaries and clips it holds.
2. Pick a dictionary. The row shows its clip count and how many of its clips play on a ped.
3. Pick a clip. It starts playing, and you get its length, frames, rate and bone track count plus the Lua.
Search covers all of it. Type two or more letters and every dictionary and clip name is matched at once; words that hit the dictionary name count for every clip in it, so `ornate_bank` gives you the whole Pacific Standard set and `reload pistol` narrows to pistol reloads. Clips that play are listed first.
> [!NOTE]
> Not every clip can run on a ped, and the rows say which and why: `facial or camera` (no body bone moves), `not a ped rig` (it drives a vehicle, a weapon or a prop) and `nothing to watch` (a single pose). Those are still listed with their real facts and their Lua, and the viewer says so instead of showing you the previous animation. Dictionaries for animals are marked too: they only share part of their skeleton with a ped.
The ped follows the dictionary name: a dictionary with `female` in it opens on the female ped, everything else on the male. The **Ped** switch still overrides it.
### Where the heist animations are
The heist dictionaries sit in the catalogue like every other dictionary, under **Heists and robberies**: drilling, cutting, thermal charges, keypads and card swipes, safes, money and gold grabs, carrying, hold ups and crew prep. Typing `drill` finds every drilling clip and `ornate_bank` the whole Pacific Standard set.
## Watching a clip
1. Pick a clip in the list on the left. It downloads on the spot, usually under 10 KB, and starts playing.
2. Drag to orbit the camera, scroll to zoom, and press **Reset view** to go back to the default framing.
3. Use the bar to scrub through the motion, **Speed** to slow it down, and **Loop** to watch it once instead of over and over.
4. **Ped** switches between the male and the female freemode ped.
> [!NOTE]
> Clips that travel (walking in, stepping away) are held on the spot here so you can see them. In the game they move the ped.
The facts under the viewer are the ones you usually need: how long the clip runs, how many frames it has, its rate and how many bones it actually moves. A clip with very few bone tracks only moves part of the body.
## Getting it into your script
Click the dictionary name or the clip name to copy it. Under that, the Lua panel gives you a working block:
```lua title="client.lua"
local dict = "anim@heists@ornate_bank@grab_cash"
local anim = "grab"
RequestAnimDict(dict)
while not HasAnimDictLoaded(dict) do
Wait(0)
end
TaskPlayAnim(PlayerPedId(), dict, anim, 8.0, -8.0, -1, 1, 0.0, false, false, false)
RemoveAnimDict(dict)
```
The flag and the duration are filled in from the clip: a clip that reads as a loop (`idle`, `loop`, `base`) gets flag `1` and no time limit, anything else gets flag `0` and its own length in milliseconds. There is a one line upper body version below it, for when the ped should keep walking.
For other flag combinations, the [Animation Flags Calculator](/docs/tools/animation-flags-calculator) builds the number.
## Synced scenes
A synchronised scene plays two animations that were made to fit together, so both peds line up exactly: a handshake, a hug, a mugging, a fistfight, a drug deal. The other tab lists them with their category.
- Both peds play on one timeline, so play, pause and scrub move them together.
- **Ped 1** and **Ped 2** pick the model for each side, and **Swap peds** flips them.
- When a scene animates a prop and we have a model for it, the prop is drawn and animated too. When we cannot draw it, the model name is listed as "needs prop" so you still know what to spawn.
- If the two clips are not the same length, the shorter one holds on its last frame. That is what the game does inside a scene, not a bug in the preview.
The Lua panel writes the whole block for a scene: loading the dictionaries, creating any prop, `NetworkCreateSynchronisedScene` at your ped's position and heading, both peds added to it, and the start call.
```lua title="scene.lua"
local scene = NetworkCreateSynchronisedScene(coords.x, coords.y, coords.z, 0.0, 0.0, heading, 2, false, false, 1065353216, 0, 1.0)
NetworkAddPedToSynchronisedScene(ped1, scene, dict, anim1, 1000.0, -1000.0, 16, 16, 1148846080, 0)
NetworkAddPedToSynchronisedScene(ped2, scene, dict, anim2, 1000.0, -1000.0, 16, 16, 1148846080, 0)
NetworkStartSynchronisedScene(scene)
```
> [!TIP]
> The scene is created at a position and a heading, not at a ped. Put it where you want the pair to stand, then attach both peds; the offsets are baked into the animations.
## Sharing a link
The page keeps your selection in the URL, so you can send someone the exact clip or scene:
- `/tools/animations?d=anim@heists@fleeca_bank@drilling&c=drill_straight_idle`
- `/tools/animations?d=amb@world_human_smoking@male@male_a@base&c=base`
- `/tools/animations?tab=scenes&s=`
A `?d=&c=` link opens the browser on that dictionary and that clip.
## Limits
- The viewer needs WebGL. On a browser without it the page says so instead of showing an empty box.
- The list covers the in-game dictionaries (`anim/ingame`). Cutscene animations live in the [Cutscene Browser](/tools/cutscenes).
- A clip that does not move enough of the ped's own bones is not played on one; it is listed with its facts and its Lua and says why.
- Facial clips only move face bones, so there is nothing to watch on a preview ped; they are listed and marked.
- Clips that drive a prop, a vehicle or a weapon instead of a body are listed and marked too. You see prop clips running on the prop in a synced scene.
_Last updated: 2026-09-23_
---
## Cutscene Browser
URL: https://fivemad.com/docs/tools/cutscenes
Look up any GTA V cutscene: the real name for RequestCutscene, its actors, length, camera cuts, subtitles and world position, plus a 3D preview of the exported ones.
The Cutscene Browser lists every cutscene this build of GTA V ships and, for a large part of the list, plays a 3D preview of it. It is the quick way to find the cutscene name a script needs, see who is in it and how long it runs, and check what it actually shows before you wire it up.
## What is in the list
Every cutscene is read out of the game's own cutscene files, so each row carries the real data:
- The cutscene name, exactly the string `RequestCutscene` wants.
- How long it runs and how many camera cuts it makes.
- The ped models that act in it, with the character name where it is obvious.
- The props and vehicles the cutscene places.
- How many subtitle lines it has, and the lines themselves for the exported ones.
- The world position and heading the cutscene plays at.
The list is grouped into story missions, story heists, Strangers and Freaks, GTA Online heists, the GTA Online updates and test files. That grouping is read from the cutscene names, because the files themselves do not record which mission they belong to.
## What the preview shows
A cutscene in GTA V is not one animation. It is a set of actors with their own character models and faces, a camera track, props, lighting, audio, subtitles and a piece of the world around it. The preview covers the parts that can honestly be rebuilt in a browser:
- Each actor's real body animation, played on our own freemode ped.
- Every actor standing where the cutscene puts them, relative to each other.
- The props we already have a 3D model for, animated by the cutscene.
- The cutscene's own camera: position, rotation and field of view, with its real cuts.
- The subtitle line that belongs to the current moment.
It does not show the cutscene character models, facial animation or lip sync, lighting or effects, audio, vehicles, or the world the scene plays in. Treat it as a blocking pass, not as the cutscene.
Cutscenes without a preview still show all of their metadata and the Lua. They were left out because they run longer than the export limit, have no ped actor, or are test files.
## Watching one
- **Scene camera** looks through the cutscene's own camera. **Orbit** gives you a free camera you can drag and zoom.
- Scrub the bar to find a moment, change the speed, or turn the loop off to watch it once.
- Each actor has its own male or female ped switch. The animation data is identical on both.
- **Floor** hides the ground plane, **Reset view** puts the orbit camera back.
- The page URL keeps the selected cutscene, so you can link straight to one.
## Playing the real cutscene in game
Click the cutscene name to copy it. The Lua panel gives you the working sequence:
```lua
local scene = "ah_1_int"
RequestCutscene(scene, 8)
while not HasCutsceneLoaded() do
Wait(0)
end
StartCutscene(0)
while IsCutsceneActive() do
Wait(0)
end
RemoveCutscene()
```
A few things worth knowing:
- Register an entity **before** `StartCutscene`, never after. The handle string is the model the cutscene expects for that actor, which the actor rows show you next to the character name.
- `SetCutsceneEntityStreamingFlags` and the flags on `RegisterEntityForCutscene` decide how much of the ped the cutscene owns. Flag 64 is the usual "let the cutscene drive it".
- A cutscene streams the world around it. Played somewhere else it will look wrong or hang on a black screen, so warp the player to the coordinates in the panel first.
- Always call `RemoveCutscene` when you are done, or the next request will fail.
## Credits
Every cutscene here is our own extraction from the game files. The public [gta-v-data-dumps](https://github.com/DurtyFree/gta-v-data-dumps) name list was used once, as a cross check on the names we found.
_Last updated: 2026-09-23_
---
## Interiors, IPLs and ymaps
URL: https://fivemad.com/docs/tools/interiors
Find any GTA V MLO interior with a cutaway render, its rooms, portals and entity sets, plus every IPL and ymap name with ready RequestIpl and teleport Lua.
The interiors browser answers the questions you hit when you build anything indoors: which interior is this, where is it, does it load on its own, what is the IPL called, and which entity sets turn the furniture on. It lives under [Assets](/assets) at `/assets/interiors` and has three tabs.
## MLOs
An MLO is a real interior: rooms you can walk through, with portals between them. Every one has a cutaway render so you can recognise it without loading the game.
Each entry shows:
- **Name and hash**, both copyable.
- **Rooms** with their flags and timecycle modifier, so you know which room name to pass to `GetRoomKeyFromEntity` checks.
- **Portals** between rooms.
- **Entity sets**: the optional furniture and clutter an interior can turn on. Copy the name for `EnableInteriorProp`.
- **Where it is placed**: every instance in the world with its coordinates, and a link to the same spot on the [Interactive Map](/docs/tools/interactive-map).
- A badge saying **Loaded by default** or **Needs RequestIpl**.
Under the detail you get ready Lua: a teleport to the interior, the `RequestIpl` call when it needs one, and an entity set block.
## IPLs
The IPL tab is the flat list of map names you can pass to `RequestIpl` and `RemoveIpl`, the ones people usually hunt for on forum threads. Filter to **Needs RequestIpl** to see only the ones a script has to load, and copy the name or the Lua.
```lua title="client.lua"
RequestIpl("v_michael")
-- later
RemoveIpl("v_michael")
```
> [!NOTE]
> Most IPLs are part of the world the game loads on its own. You only need `RequestIpl` for a scripted one, or after something removed it.
## YMAPs
Ymaps are the placement files behind the map. The tab lists every name with what is in it, which is what you want when you are hunting the file that places a prop, or checking that a name you found in an old script still exists.
## Tips
- Search matches names and labels, so `bank`, `mrpd` or `casino` gets you close in one go.
- The tab and the selected item are in the URL (`?t=mlos&id=…`), so a link shares the exact entry.
- An interior that says **Needs RequestIpl** will look empty in game until you load it, which is the usual reason a teleport lands you in a black room.
_Last updated: 2026-09-23_
---
## Ped Decorations
URL: https://fivemad.com/docs/tools/decorations
Find any GTA V tattoo, badge or decal, see it on a ped, and copy the collection and overlay hashes for AddPedDecorationFromHashes.
Ped Decorations lists all 3,373 tattoos, badges and t-shirt decals the game defines, from the base game and every DLC pack. Each one shows its artwork, a picture of it on a freemode ped, and the two hashes you need to apply it.
## What it is for
`AddPedDecorationFromHashes` wants two hashes: a collection and an overlay. Nothing in game tells you what either of them is called, and the names are not guessable (`mpbiker_overlays` plus `MP_MP_Biker_Tat_001_F`). This page is the list, with a picture so you know what you are about to apply.
## Finding a decoration
Type anything into the search box: the overlay name, the shop name the game gives it ("Demon Rider", "Ship Arms"), the collection, or the texture dictionary. Then narrow it down:
| Filter | What it does |
| --- | --- |
| Collection | One DLC pack's overlay file, for example Bikers or Beach Bum |
| Zone | Torso, head and neck, left or right arm, left or right leg |
| Ped | Male, female, or entries that work on either |
| Kind | Tattoo, or badge and decal (t-shirt prints and crew badges) |
Your filters and the decoration you picked live in the address bar, so you can paste a link and the other person lands on the same one.
## The panel
Clicking a picture opens the detail panel. It has:
- **The artwork** on its own, trimmed to the part of the texture sheet that is actually used.
- **The ped picture**: the same decoration drawn on a freemode ped, framed on its zone, so you can see where it lands before you load the game.
- **Overlay, collection, pack, zone, ped and kind**, plus the texture dictionary and texture name.
- **Both hashes** as unsigned, signed and hex, all one click to copy.
- **The shop price**, when the game sells that one in a tattoo shop.
- **Ready Lua**, on four tabs.
## Applying one
```lua title="client.lua"
local ped = PlayerPedId()
-- collection first, then the overlay name
AddPedDecorationFromHashes(ped, `mpbeach_overlays`, `MP_Bea_M_Back_000`)
```
The backticks are FiveM's hash literals. The native wants the joaat of each name, not the string. If backticks are not an option, the panel also gives the plain numbers:
```lua title="client.lua"
AddPedDecorationFromHashes(ped, -1719270477, 1056297333)
-- same thing, hashed at runtime
AddPedDecorationFromHashes(ped, GetHashKey("mpbeach_overlays"), GetHashKey("MP_Bea_M_Back_000"))
```
> [!TIP]
> Store the two strings, not the hashes, in your character data. They are readable in a database dump and you can hash them again any time.
## Taking them off
```lua title="client.lua"
local ped = PlayerPedId()
ClearPedDecorations(ped) -- everything, scars included
ClearPedDecorationsLeaveScars(ped) -- keep scars, drop tattoos and decals
```
There is no native for removing a single decoration. Clear them all and reapply the ones you want to keep, which is why most scripts hold the player's tattoo list server side.
## Applying a set
```lua title="client.lua"
local tattoos = {
{ collection = "mpbeach_overlays", overlay = "MP_Bea_M_Back_000" },
{ collection = "mpbiker_overlays", overlay = "MP_MP_Biker_Tat_000_M" },
}
local function applyTattoos(list)
local ped = PlayerPedId()
ClearPedDecorations(ped)
for _, t in ipairs(list) do
AddPedDecorationFromHashes(ped, GetHashKey(t.collection), GetHashKey(t.overlay))
end
end
applyTattoos(tattoos)
```
Call that again after every model change, respawn and clothing menu that rebuilds the ped. Decorations do not survive `SetPlayerModel`.
## Things to watch out for
> [!WARNING]
> The order of the two hashes matters. Collection first, overlay second. Swapping them does nothing at all and reports no error.
- **Male and female entries are separate.** Most tattoos ship twice, ending in `_M` and `_F`, with slightly different placement. Applying the male one to a female ped puts it in the wrong place.
- **DLC collections need the game build.** A collection from a newer pack only exists on a server running a build that includes it. Set `sv_enforceGameBuild` accordingly.
- **Crew emblem overlays have no picture.** They point at a texture the game builds at runtime from the player's crew, so there is nothing to show and nothing to extract.
- **A few entries have no ped picture.** They sit outside the parts of the ped we draw, so only the artwork is shown.
## Placing your own artwork
Every panel has a link into the [3D Tattoo Editor](/tools/tattoo-editor) opened at that decoration's zone, position, scale and rotation. Drop your own image on top and you get an overlay that sits exactly where the game tattoo sits.
## Where the data comes from
The collections, placements and hashes are read out of the game's own `PedDecorationCollection` files. The artwork is each decoration's texture, and the ped pictures are rendered by us on our own conversion of the freemode ped. Nothing on this page is taken from another site.
_Last updated: 2026-09-23_
---
## Giveaways
URL: https://fivemad.com/docs/tools/giveaways
How fivemad giveaways work for players: log in with Discord, finish the tasks, enter, and how winners are picked and contacted.
fivemad giveaways are free draws run by FiveM creators: scripts, vehicle packs, MLOs, clothing, server slots, Tebex gift cards and more. You log in with Discord, finish the tasks the host set, enter, and when the timer runs out the winners are picked at random. This page explains everything from the entrant's side.
## Quick start
1. Open [Giveaways](/giveaways) and pick one.
2. Press **Log in with Discord to enter** and approve the login on Discord.
3. Work through the **Tasks** list. Each task shows a tick when it is done.
4. Press **Enter giveaway** once every task is done. The panel changes to **You are in**.
5. Come back after the timer runs out to see the winners.
## Finding a giveaway
The giveaways page has three tabs: **Active**, **Ending soon** and **Ended**. You can filter by prize type (Script, Vehicle pack, MLO, Clothing, Server slot, Tebex gift card, Discord Nitro, Other) and search by name. Each card shows the prize, the host, the time left, the number of entries, winners and tasks.
New giveaways are announced in the fivemad Discord first, so join it if you do not want to miss one.
## Logging in with Discord
Giveaways use your Discord account, so there is no separate fivemad account or password.
- When you log in, Discord asks you to allow fivemad to see your **name and avatar** and **which servers you are in**. That is all the site asks for.
- The server list is how the "join a server" tasks are checked.
- Nothing gets posted for you, and the site cannot read your messages or DMs.
- **Log out** in the header ends your session on fivemad. To remove the app's access completely, open Discord, User Settings, Authorized Apps, and remove it there.
## Task types
A giveaway can have any mix of these tasks, or none at all ("No tasks for this one. Log in and enter.").
| Task | What you see | What you need to do |
| --- | --- | --- |
| Join a Discord server | "Join *server* on Discord" with a **Join** button | Join that server with the same Discord account you logged in with. |
| Have a role | "Have the *role* role in *server*" | Be a member of that server and hold the role. How you get the role is up to the host's server (verification, reacting, levels and so on). |
| Account age | "Discord account at least *N* days old" | Nothing to do: your Discord account must be at least that old. This stops fresh alt accounts. |
| Visit a link | "Visit *name*" with an **Open** button | Open the link (a store page, a video, a forum post). |
**Visit a link** tasks cannot be checked, and the page says so: "We cannot check this one, so opening the link counts." The task is ticked as soon as you press **Open** while logged in.
### When a task is not done
Under an unfinished task you may see:
| Message | What to do |
| --- | --- |
| You are not in this server yet. | Press **Join**, join the server, then come back. |
| You do not have this role yet. | Get the role in that server first. |
| Your Discord account is too new for this giveaway. | Nothing you can do for this giveaway. |
| Log in again so we can check this. | Log out and log in again. |
| Discord did not answer. Try again in a moment. | Wait a little and press **Check again**. |
## Check again
After you join a server in another tab, press **Check again** above the task list. When you switch back to the giveaway tab with a Discord task still open, the page also checks again by itself. Discord can take a few seconds to report a new join, so if a task does not tick right away, wait a moment and press **Check again** once more.
## Entering
The button at the bottom of the panel tells you where you stand:
- **Finish every task to enter**: at least one task is not done yet.
- **Enter giveaway**: everything is done. Press it.
- **You are in**: you entered, with the date. Good luck.
- **Entries open when the giveaway starts.** / **Entries are closed.**: the giveaway has not started or has ended.
The tasks are checked again when you press **Enter giveaway**, so leaving a server right before entering does not work. You can enter each giveaway once. **Copy link** at the bottom of the panel copies the giveaway's link to share.
Your entries are listed on **My entries** (the link at the top of the giveaways page), with the ones you won marked.
## How winners are drawn
- When the timer runs out, winners are picked at random from every valid entry. The number of winners is shown on the giveaway.
- Hosts can have each picked winner checked again at draw time. Anyone who left a required server or lost a required role by then is skipped, and the next random entry is used instead. So stay in the servers until the draw is done.
- The results appear on the giveaway page with the draw date and how many entries were in the draw. If the timer just ran out, the page says the winners are being drawn; reload in a moment.
- If the host has to replace a winner later (for example one who never claimed the prize), the page shows that a winner was replaced and when.
- If nobody entered, there are no winners.
## If you win
The giveaway page shows **You won** when you are logged in, and the giveaway is marked as won on **My entries**. Contact the host to claim your prize; the **Contact** button opens the host's link when they set one. Have your Discord name ready. fivemad does not hand out prizes itself, the host does.
## Tips
- Log in with the Discord account you actually use in those servers. Tasks are checked against that account only.
- Do not leave the host's server right after entering. With the draw re-check on, you would be skipped.
- Times are shown in your own time zone.
## Limitations
- Giveaways are run by their hosts. fivemad checks the tasks and runs the draw, but the prize and its delivery are between you and the host.
- An account that is blocked from giveaways sees "This account cannot join giveaways." at login.
- Pages in other languages have the same giveaways; only the page text is translated.
## Related tools
- [Generators](/docs/tools/generators) and the rest of the [tools overview](/docs/tools) are free to use without logging in.
_Last updated: 2026-09-22_
---
# Tool list
Every tool runs in the browser and is free.
- Interactive Map (https://fivemad.com/tools/interactive-map): Find any spot on the GTA V map, copy exact coordinates as vector3 or vector4, measure distances and drop pins. Switch to 3D to roam the world rendered from the game's own models, with a freecam or on foot.
- Clothing Designer (https://fivemad.com/tools/clothing-designer): A 3D texture editor for FiveM clothing. Drop a .ydd or .ydr with its .ytd files or start from a game template, then paint on the model or on the texture with the UV layout on top. Layers, text, images, shapes, gradients and texture variations, all exported as ready to stream .ytd files.
- Animation Browser (https://fivemad.com/tools/animations): Watch a clip before you write the code. The browser lists every dictionary and clip the game ships, with the real frame count, length and rate, and plays them on our own freemode ped: scrubbing, speed, a male and a female ped and a ready RequestAnimDict plus TaskPlayAnim snippet. The synced scenes tab puts two peds and the scene's prop on one timeline.
- Cutscene Browser (https://fivemad.com/tools/cutscenes): Look up any cutscene before you call RequestCutscene: the real name, how long it runs, the ped models that act in it, the props, the camera cuts, the subtitle lines and where in the world it plays. A large part of the list also has a 3D preview that plays each actor's body animation on our freemode ped and follows the cutscene's own camera.
- YMAP Builder (https://fivemad.com/tools/ymap-builder): Build a map placement file without opening a map editor: paste coordinates from the game or add props one by one, set heading or full rotation, and get CodeWalker-ready .ymap XML with quaternions, entity and streaming extents calculated for you. Import an existing ymap XML to edit it.
- Zone Creator (https://fivemad.com/tools/zone-creator): Draw the zone where it actually is. Click points on the Los Santos map or in the 3D world, set the two heights against the real ground, then copy ready code for ox_lib zones, PolyZone, ox_target or qb-target, or just the points as a Lua table or JSON. Paste an existing zone back in to edit it, and share the whole thing as a link.
- 3D Tattoo Editor (https://fivemad.com/tools/tattoo-editor): Upload a tattoo, pick a zone and position it on mp_m_freemode_01 or mp_f_freemode_01 in 3D. Click the body to place it, fine tune UV position, scale and rotation, then copy the overlay XML or open it in Durty Cloth Tool.
- Objects / Props List (https://fivemad.com/tools/objects-list): Browse every GTA V prop with a rendered picture, readable name, category, tags and its real size in metres. Search by name or tag, paste a hash to find the model it belongs to, and copy a ready CreateObject snippet.
- Screen Effects Browser (https://fivemad.com/tools/screen-effects): Browse all 1,101 timecycle modifiers and 252 animpostfx effects with the exact values they set, our own before and after preview of each one, and ready SetTimecycleModifier and AnimpostfxPlay snippets.
- Ped Decorations (https://fivemad.com/tools/decorations): Browse all 3,373 ped decorations from the base game and every DLC pack: the overlay artwork, the same decoration drawn on a freemode ped so you see where it lands, its collection, zone and gender, and the collection and overlay hashes with ready AddPedDecorationFromHashes Lua.
- Interiors, IPLs and ymaps (https://fivemad.com/assets/interiors): Find the interior you need: 391 MLO archetypes with a rendered cutaway, their rooms, portals, entity sets and timecycle mods, every placed instance with its coordinates, and the full list of IPL and ymap names with ready Lua to load or unload them.
- Minimap Editor (https://fivemad.com/tools/minimap-editor): Give your server its own minimap. Pick a shape or upload your own mask, move and resize it on a real screen, set the border, glow, rings, blip clipping, zoom and HUD colours, and watch it draw over the actual Los Santos map as you edit. Download a complete resource: the mask textures, the Lua that applies every value and a README that explains each one.
- Vehicle Handling Editor (https://fivemad.com/tools/vehicle-handling-editor): Edit 45 common CHandlingData fields plus the flags with sliders and live explanations. Import an existing handling.meta, tweak it and export handling.meta XML or runtime Lua using SetVehicleHandlingFloat.
- Drawable Studio (https://fivemad.com/tools/drawable-studio): Drop a CodeWalker XML export with its textures and get a 3D view of the model in your browser. Check geometry and textures, edit shader parameters and lights, paint straight onto the model, then export the XML, PNG textures or a GLB.
- Particle Effects List (https://fivemad.com/tools/particles-list): Browse all GTA V particle effects with their asset dictionaries and copy a working UseParticleFxAsset + StartParticleFxLoopedOnEntity snippet.
- Sound Browser (https://fivemad.com/tools/sound-browser): Search every known GTA V sound name and sound set, play it right here, and copy a working PlaySoundFrontend or PlaySoundFromCoord snippet. No need to restart the game to find the right beep.
- Texture Editor (https://fivemad.com/tools/texture-editor): Open a CodeWalker .ytd XML export with its DDS files, preview every texture and channel, replace them with PNG or JPG, resize to power of two, pick the compression (DXT1, DXT5, BC7 where possible) and export the new DDS files plus the .ytd XML ready to import.
- Vehicle Sirens Editor (https://fivemad.com/tools/vehicle-sirens): Build and tune emergency lighting: every siren light's colour, rotation, flash and 32-step sequencer pattern with a live preview, BPM and timing, then export carcols.meta. Drop your carcols files to see which siren IDs are taken, free or clashing.
- Model & Hash Browser (https://fivemad.com/tools/model-hash-browser): Browse every GTA V vehicle, ped and weapon with images, spawn names, display names, classes and signed/unsigned/hex hashes. Filter, search and copy in one click.
- Generators (https://fivemad.com/tools/generators): Everything that makes something up for you: a full roleplay character, server names with ready hostname lines, a gang with ranks and turf in Los Santos, and script ideas based on what is being released on forum.cfx.re, each with a technical plan.
- server.cfg Generator (https://fivemad.com/tools/server-cfg-generator): Fill in a form and get a clean, commented server.cfg ready to drop into your FiveM server, including OneSync, endpoints, tags, locale, resources and ACE permissions.
- fxmanifest.lua Generator (https://fivemad.com/tools/fxmanifest-generator): Generate a valid fxmanifest.lua for any FiveM or RedM resource: shared/client/server scripts, NUI page, files, dependencies, exports and lua54.
- Weapons Meta Editor (https://fivemad.com/tools/weapons-meta-editor): Start from the real default weapons.meta of any base game or DLC weapon, tweak damage, range, fire rate, reload, clip size, accuracy and recoil with explanations, compare against the default, and export a clean weapons.meta and fxmanifest for your server.
- YTYP Creator (https://fivemad.com/tools/ytyp-creator): Build CBaseArchetypeDef entries for custom props: name, texture dictionary, LOD distance, flags, physics dictionary and asset type. Drop CodeWalker .ydr XML files and the bounding box, sphere centre and radius are measured from the mesh. Import any default game ytyp as a starting point.
- Vehicle Pack Validator (https://fivemad.com/tools/vehicle-pack-validator): Drop a FiveM vehicle resource folder and get a report: models without handling, handling ids that do not match, missing carcols or carvariations entries, missing .yft/.ytd files, missing _hi models, data_file lines that are wrong or missing, duplicate names and more, each with the fix.
- YMT Creator (https://fivemad.com/tools/ymt-creator): Drop the .ydd and .ytd files of a clothing pack and get the CPedVariationInfo .ymt XML with every component, drawable, texture variation and prop filled in, plus the creature metadata and fxmanifest lines to stream it.
- Inventory Icons (https://fivemad.com/tools/inventory-icons): Pick props from the game or drop your own PNGs, then trim, pad, resize and export a clean icon pack for ox_inventory, qb-inventory or any other inventory, with the matching items list ready to paste.
- Script Thumbnail Creator (https://fivemad.com/tools/script-thumbnail-creator): Drop your script's screenshots, type the name, frameworks and price, pick one of nine layouts and export clean preview images for your forum.cfx.re release, YouTube video, Discord post and Tebex package. Every size from one project, rendered in your browser.
- Snaily Creator (https://fivemad.com/tools/snaily-creator): Build your own version of Snaily, our mascot. Set the colours, pick a mood from happy to furious, add hats, sunglasses, chains, outfits, shell stickers, backdrops and something to hold, then export a transparent PNG or an SVG for your Discord, your server or your release images.
- Crosshair Generator (https://fivemad.com/tools/crosshair-generator): Build the crosshair you want, from a single dot to a cross with a ring, brackets or chevrons, and check it over a dark scene, a light scene and Los Santos. Export a ready to drop NUI overlay resource with fxmanifest and client Lua, a transparent PNG, an SVG, or the cl_crosshair console settings that come closest to your design.
- YTD Optimizer (https://fivemad.com/tools/ytd-optimizer): Drop a stream folder or a pile of .ytd files and optimize them in one go: cap the largest texture size, turn opaque DXT5 into DXT1, fix missing or broken mip chains and see the memory saved per file before you download. Everything runs in your browser.
- Native Audio Builder (https://fivemad.com/tools/native-audio-builder): Drop your sounds and get a complete FiveM resource that plays them as real game audio: the .awc wave bank and .dat54.rel sound data built right here (no CodeWalker step), the data_file lines, and Lua to load the bank and play sounds on the UI, on an entity or at a position, synced if you want. Based on lb-nativeaudio.
- Server Status Checker (https://fivemad.com/tools/server-status-checker): Look up any FiveM server by IP:port or cfx.re join code and see whether it is online, its player list, game build, OneSync, resources and server variables.
- Profiler Analyzer (https://fivemad.com/tools/profiler-analyzer): Record with the built-in FiveM profiler, drop the saved JSON here and get a readable report: time per resource, worst frames, hot threads and events, spikes over time and plain advice on what to fix. Everything is parsed in your browser, nothing is uploaded.
- Cfx Blacklist Checker (https://fivemad.com/tools/cfx-blacklist-checker): Cfx.re blocks some IPs and hosting ranges from running public servers. Paste IPs, host names or cfx.re join codes (up to 20 at once) and see which ones are blacklisted, straight from Cfx's own endpoint.
- Server Status Badge (https://fivemad.com/tools/server-uptime-badge): Generate an auto-updating SVG badge showing your FiveM server's online state and player count. Copy the Markdown, HTML or BBCode and paste it anywhere.
- joaat Hash Calculator (https://fivemad.com/tools/hash-calculator): Compute GTA V / RDR2 joaat hashes (GetHashKey) for any string, in bulk, entirely in your browser. Signed, unsigned and hex output, plus a ready Lua hash table for bulk lists.
- Driving Style Calculator (https://fivemad.com/tools/driving-style-calculator): Combine vehicle driving flags (stop for cars, avoid peds, use shortest path…) into the single integer used by TaskVehicleDriveToCoord, TaskVehicleDriveWander and SetDriveTaskDrivingStyle.
- Animation Flags Calculator (https://fivemad.com/tools/animation-flags-calculator): Pick animation behaviours and get the combined flag integer for TaskPlayAnim / TaskPlayAnimAdvanced, with a ready-to-paste Lua snippet.
- Warning Screen Buttons (https://fivemad.com/tools/warning-buttons): Choose which instructional buttons should appear on a GTA V warning/alert screen and get the exact flag value for SetWarningMessage / SetWarningMessageWithHeader.
- Draw Text Colors (https://fivemad.com/tools/text-colors): Type text with GTA V formatting codes (~r~, ~b~, ~h~, ~n~ …) and see a live preview of how it renders in DrawText, notifications and help text.
- Blip, Marker & Checkpoint Browser (https://fivemad.com/tools/blip-marker-browser): Find the right map blip sprite, blip colour, 3D marker or race checkpoint for your script. Every entry shows its ID and preview, with one-click copy and a ready Lua snippet.
- Weapon Stats & Components (https://fivemad.com/tools/weapon-stats): Look up any GTA V weapon: hashes, weapon group, ammo type, max ammo, damage type, every component/attachment hash and every tint index.
- Controls Reference (https://fivemad.com/tools/controls-reference): Look up any control for IsControlJustPressed and DisableControlAction: index, INPUT_ name, default keyboard key and gamepad button. Press a key on your keyboard to find every control bound to it, and copy a ready snippet or a RegisterKeyMapping alternative.
- Scaleform Functions (https://fivemad.com/tools/scaleform-reference): Search GTA V scaleform movies and the functions you can call on them with BeginScaleformMovieMethod, including known parameter lists.
- Player Stats List (https://fivemad.com/tools/player-stats): Search 3,000+ known GTA Online stat names (MP0_, MP1_ and global) with their data type and hash, ready for StatGetInt / StatSetInt and friends.
- Parachutes & Smoke Trails (https://fivemad.com/tools/parachutes): All parachute pack tints, canopy styles and smoke-trail colours with their indices and RGB values, plus the natives to apply them.
- Game Damage Events (https://fivemad.com/tools/damage-events): Understand the gameEventTriggered / CEventNetworkEntityDamage payload and hook clean onPlayerKilled, onPlayerDied and vehicle-destroyed events in your own resource.
# Dataset list
- Props with pictures (https://fivemad.com/data/props.json): Every GTA V prop model that has a picture, with a readable label, category, tags and its real size in metres. 30,033 rows, 2.6 MB. Shape: rows: [model, label, category, tags, [x,y,z] size in m, minBuild, hasThumb, has3d, hasShot]
- Object model names (https://fivemad.com/data/objects.json): Plain list of object model names, including the map pieces that have no picture. 21,631 rows, 505 KB. Shape: { count, names } where names is one lower case model name per line
- Archetype definitions (https://fivemad.com/data/archetypes.json): The .ytyp archetype of each model: LOD distance, flags, bounding box, texture and physics dictionaries. 33,071 rows, 3.0 MB. Shape: cols lists the column names, rows is an array of arrays in that order
- Vehicles (https://fivemad.com/data/vehicles.json): Every vehicle with its spawn name, display name, manufacturer, class, seats, performance figures and flags. 921 rows, 309 KB. Shape: items: [{ n spawn name, h hash when it differs from joaat(n), l label, m make, c class, t type, d dlc, s seats, sp/ac/br/ag performance, f flags }]
- Peds (https://fivemad.com/data/peds.json): Every ped model with its type and the DLC it came with. 1,109 rows, 68 KB. Shape: items: [{ n model name, h hash when it differs, l label, t ped type, d dlc }]
- Weapons and components (https://fivemad.com/data/weapons.json): Every weapon with its group, ammo type, max ammo, flags, components, tints and liveries. 184 rows, 180 KB. Shape: items: [{ n WEAPON_*, h, l, c group, a ammo, ma max ammo, cp components, ti tints, lv liveries }]
- weapons.meta defaults (https://fivemad.com/data/weapons-meta.json): The game's own weapons.meta values for every weapon, stored as line indices into a shared line table. 594 KB. Shape: { lines, items } where each item's blocks are base 36 indices into lines
- Vehicle siren settings (https://fivemad.com/data/sirens.json): Every carcols siren setting with its lights, sequences and the vehicles that use it. 21 rows, 617 KB. Shape: settings: [{ id, name, lightFalloff*, sirens: [...] }]
- Vehicle reference names (https://fivemad.com/data/vehicle-refs.json): Model, handling, layout, mod kit and audio names read out of the game files, for validating a vehicle resource. 935 rows, 83 KB. Shape: named string arrays (models, handling, layouts, modkits, ...)
- Particle effects (https://fivemad.com/data/particles.json): Every particle effect name grouped by its particle asset (ptfx dictionary). 2,907 rows, 82 KB. Shape: dicts: [{ name, effects: [effect name] }]
- Particle effects with video (https://fivemad.com/data/particle-videos.json): The subset of particle effects that has a recorded preview clip under /media/particles. 2,317 rows, 59 KB. Shape: dicts: [[dict name, [effect name]]]; media id = running index over the whole list
- Frontend sounds (https://fivemad.com/data/sounds.json): Sound names grouped by sound set, with the ones that have an audio preview marked. 2,179 rows, 130 KB. Shape: sets: [{ n set name, s: [[sound name, hash, ...]] }]
- Heist animation clips (https://fivemad.com/data/animations.json): The curated heist dictionaries with their clips, frame counts and lengths. 399 rows, 23 KB. Shape: dicts: [{ d dictionary, g group, c: [[clip, frames, seconds, tracks, bytes]] }]
- Full animation catalogue (https://fivemad.com/data/anim/index.json): Every animation dictionary and clip the game ships. index.json has the totals and families, fam-.json the dictionaries of a family, c-000..127.json the clip rows (shard = FNV-1a of the dictionary name mod 128) and search.txt one line per dictionary. 97,204 rows, 2 KB. Shape: clip row: [name, frames, seconds, tracks, bytes, skip]; bytes > 0 means the clip has a playable file
- Synced scenes (https://fivemad.com/data/synced-scenes.json): Two ped synchronised scenes: which clips play on which ped, and the prop when there is one. 458 rows, 185 KB. Shape: scenes: [{ i id, n name, g group, a: [{ d dict, c clip, p prop clip }] }]
- Cutscenes (https://fivemad.com/data/cutscenes.json): Every cutscene the game ships, with its actors, length, camera cuts, subtitle count and world position. 781 rows, 549 KB. Shape: scenes: [{ n name, t title, g group, d seconds, sc sections, cc camera cuts, o world offset, a actors }]
- Ped decorations (https://fivemad.com/data/decorations.json): Every tattoo, badge and decal the game defines, with its collection, zone, gender and placement. 3,373 rows, 366 KB. Shape: rows: [name, zone index, txd, txt, gender, ...]; collections: [{ n, dlc, l, h collection hash }]
- Timecycle modifiers (https://fivemad.com/data/timecycles.json): Every timecycle modifier with the parameters it sets and where it is defined. 1,101 rows, 453 KB. Shape: mods: [[name, sourceIndex, userFlags, [[paramIndex, valueA, valueB]], usedBy, alsoIn, img, key]]; params names the indices
- animpostfx effects (https://fivemad.com/data/animpostfx.json): Every animpostfx screen effect with its hash, layers and timings. 252 rows, 139 KB. Shape: fx: [{ n name, h hash, pr priority, l layers }]
- MLO interiors (https://fivemad.com/data/mlos.json): Every MLO archetype with its rooms, portals, entity sets, timecycle mods and bounding box. 391 rows, 348 KB. Shape: mlos: [{ n name, h hash, t ytyp, d dlc index, bb bounds, rm rooms, st entity sets, in instances }]
- Placed interiors (https://fivemad.com/data/interiors.json): Each MLO with the IPL that places it and its world position, in a flat shape. 391 rows, 58 KB. Shape: items: [{ name, kind, ipl, dlc, rooms, pos [x,y,z] }]
- IPL names (https://fivemad.com/data/ipls.json): Every IPL name with the DLC it belongs to and where it sits in the world. 10,613 rows, 632 KB. Shape: cols lists the column names, rows is an array of arrays in that order
- ymap files (https://fivemad.com/data/ymaps.json): Every .ymap in the game with its header flags, entity counts and extents. 10,613 rows, 909 KB. Shape: cols lists the column names, rows is an array of arrays in that order
- Blips, markers and blip colours (https://fivemad.com/data/blips.json): Blip sprite ids with their names and preview images, marker types and the blip colour table. 966 rows, 107 KB. Shape: sprites / markers / colors arrays of { id, name, img }
- Checkpoint types (https://fivemad.com/data/checkpoints.json): Every race checkpoint type with its id and a preview image. 50 rows, 24 KB. Shape: checkpoints: [{ id, name, img }]
- Control indices (https://fivemad.com/data/controls.json): Every control index with its INPUT_ name and the default keyboard and pad bindings. 361 rows, 39 KB. Shape: controls: [{ index, name, keyboard, pad, kb, gp }]
- Scaleform movies (https://fivemad.com/data/scaleforms.json): Scaleform movie names with the functions you can call on them and their known parameter names. 471 rows, 192 KB. Shape: movies: [[movie name, category index, [[function name, [param names]]]]]
- Player stats (https://fivemad.com/data/stats.json): Known GTA Online stat names with their data type. 3,025 rows, 213 KB. Shape: stats: [[name, typeIndex, description, ...]]; types names the indices
- forum.cfx.re release trends (https://fivemad.com/data/cfx-trends.json): What the latest batch of forum.cfx.re releases is made of: frameworks, categories, selling points and topics. 250 rows, 24 KB. Shape: { source, totals, frameworks, sellingPoints, categories, topics }