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

Adding Decals

The catalog is rm_decalv/decals.lua, an open file of category blocks. Fields set on a block (textureDict, jobs, gangs, identifiers, adminOnly, resolution, canUse, vehicleModels) are inherited by every entry inside it; any entry can override them.

{
    category = 'My Crew',
    gangs = { 'ballas' },              -- whole block gang-locked
    decals = {
        { label = 'Crew Tag', fileName = 'crew_tag.webp' },
        { label = 'Boss Tag', fileName = 'boss_tag.webp', adminOnly = true },
    },
},

Every decal needs its image in rm_decalv/assets/ (webp, png or jpg) even when a ytd texture is used, because the interface preview reads the image file. After editing, restart rm_decalv.

Streamed .ytd textures are how all bundled categories work: the game loads them through its normal texture streaming, the same way it loads vehicle and map textures. That means no image decoding at runtime, no small texture pool to fill up, and it scales to hundreds of decals. Prefer this for anything beyond a handful of custom decals.

{
    category = 'JDM',
    textureDict = 'rm_dcl_jdm',        -- ytd in rm_decalv_assets/stream/
    decals = {
        { label = 'Antisocial Kanji', fileName = 'antisocial_kanji.webp' },
        -- textureName defaults to the file name without extension
    },
},
1

Build the texture dictionary

Build a .ytd containing one DXT5 texture per decal (OpenIV: new texture dictionary, import images). Texture names must match each entry's fileName without the extension, or set textureName per entry.

2

Put the file in the stream folder

Put the ytd in rm_decalv_assets/stream/ and keep the preview images in rm_decalv/assets/.

3

Set the block field

Set textureDict on the block.

Flip support: the flip/true-mirror feature looks for a <dict>_f twin. Generate it from your ytd with the bundled tool, no OpenIV needed. The only requirement is Node.js (18 or newer) on the machine you run it on; the tool has no packages to install:

It writes my_dict_f.ytd next to the input. Without a twin the decal simply renders unflipped and the interface greys the flip switch out.

Method 2: plain image file (quick for a few decals)

1

Add the image

Drop your image into rm_decalv/assets/.

2

Add the entry

Add an entry to a category block without a textureDict (or with textureDict = false inside a dict-carrying block):

The texture is decoded at runtime into a small per-client pool (8× 256², 16× 512², 6× 1024² slots) and its resolution is read from the file automatically. Perfectly fine for a handful of decals, but the pool is finite, so packs belong in a dictionary.

Method 3: in-game import (admins)

The admin panel adds decals without touching files:

  • Add from URL: downloads any https image into assets/ for you.

  • Add GIF: same, for animated GIFs (needs cfg.enableGifDecals).

  • Decal editor: compose text + images on a canvas, exported as a webp.

Each flow ends with a ready-to-paste decals.lua entry, e.g.:

Paste it inside the category block you want and restart the resource. The textureDict = false is important: it keeps the entry an image file even inside a block that carries a block-level texture dictionary. Files that never get their entry pasted are reported at startup as unreferenced. Imports are image-source decals (Method 2 rules apply); once a batch grows, move it into its own dictionary.

Entry field reference

Field
Type
Meaning

label

string

Name shown in the catalog (must be set)

fileName

string

Image in assets/, unique, extension included

textureDict

string | false

Stream ytd to render from; false forces the image file

textureName

string

Texture inside the dict; defaults to fileName minus extension

resolution

number

Optional override for the runtime pool bucket (auto-read from the file otherwise)

jobs / gangs

string[]

Only these jobs/gangs see and use the decal

identifiers

table

['license:...'] = true style allow-list (citizenid works on qb/qbox)

adminOnly

boolean

Admins only

vehicleModels

string[]

Sticker can only be applied to these models (server-enforced)

canUse

function

Server-side final gate, see Events & Exports

Last updated