Skip to content

feat(extra-natives/five): add-on vehicle number plate styles - #4396

Open
RaeLightwen wants to merge 2 commits into
citizenfx:masterfrom
RaeLightwen:feat/addon-license-plates
Open

RaeLightwen wants to merge 2 commits into
citizenfx:masterfrom
RaeLightwen:feat/addon-license-plates

Conversation

@RaeLightwen

@RaeLightwen RaeLightwen commented Nov 12, 2026 •

Copy link
Copy Markdown

Goal of this PR

Let servers stream their own license plate styles, and let scripts use plate indices beyond the 13 vanilla ones.

How is this PR achieving the goal

The game's only limit on plate indices is index < VehiclePlates.Textures.count (carcols). The natives, the getter and network sync (32-bit) all pass larger values through, so this PR adds real entries to that array. It doesn't override any natives.

  • New VEHICLE_PLATES_FILE data file type. Same format as the VehiclePlates node in carcols.ymt, plus:

    • TextureDictionary (required): the streamed .ytd with the plate textures.
    • Index (optional): a fixed index.

    Font settings and NormalMapName are optional and default to the game's default plate.

  • Index assignment doesn't depend on load order. Indices are synced as plain numbers, so every client must agree on them. Plates without an Index get the free indices after the vanilla plates in order of their TextureSetName, so clients running the same resources get the same indices whatever order they loaded them in. This includes players who join after a plate resource was restarted. When starting or stopping a plate resource moves a plate to a new index, vehicles using it switch to the new index; the owner's change syncs to everyone else. Vehicles on a removed plate go back to the default plate.

  • The plate array is replaced, not patched in place.

    • On load and unload, a new array allocated with the rage allocator is published (after a release fence). The old buffer is freed a few frames later.
    • Gaps left by explicit indices are filled with copies of the default plate.
    • When no add-on plates remain, the game's original array is restored.
    • The renderer doesn't bounds-check the index, so the array never shrinks while a vehicle still uses an index past the new end. Those vehicles are reset to the default plate first, and the shrink happens on a later frame.
  • Textures come from the add-on .ytd. SetLicensePlateTexture only looks textures up in vehshare. A hook calls the original and then, for add-on indices, sets the diffuse and normal textures from the add-on .ytd. The dictionary is ref-counted while the plate is registered.

  • New native GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX_BY_NAME (client) returns a plate index by TextureSetName. It works for vanilla plates too.

  • streaming::RegisterDataFileHandler (gta-streaming-five) lets a component register load and unload handlers for a custom data file type.

  • Offsets come from byte patterns inside the hooked function. Every pattern is unique on b3889.

  • Invalid entries are logged and skipped. This covers duplicate names or indices, out-of-range indices, missing fields, a missing .ytd or texture, malformed XML and a missing file.

-- fxmanifest.lua
files { 'plates.meta' }
data_file 'VEHICLE_PLATES_FILE' 'plates.meta'
<VehiclePlates>
  <Textures>
    <Item>
      <TextureSetName>Texas Classic</TextureSetName>
      <TextureDictionary>plates</TextureDictionary>
      <DiffuseMapName>texas_plate</DiffuseMapName>
      <NormalMapName>texas_plate_n</NormalMapName>
      <Index value="100" />
    </Item>
  </Textures>
</VehiclePlates>

Known limitations:

  • Plates without an Index can move when other plate resources start or stop, so servers that store plate indices (for example in a database) should set an Index or look plates up by name.
  • One game path, which restores a stored vehicle, reads the plate index as a signed byte (b3889 0xff82c1). On that path, indices above 127 keep the previous plate or fall back to no plate style. It doesn't seem to be reached in FiveM multiplayer, but I haven't identified the feature it belongs to.

This PR applies to the following area(s)

FiveM Client, Natives

...

Successfully tested on

Game builds: 3407

Platforms: Windows

Checklist

  • Code compiles and has been tested successfully.
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

Fixes issues

Resolves #4383

@github-actions github-actions Bot added the triage Needs a preliminary assessment to determine the urgency and required action label Nov 12, 2026
@RaeLightwen
RaeLightwen force-pushed the feat/addon-license-plates branch from dda1de1 to c18d860 Compare November 12, 2026 03:50
Add a VEHICLE_PLATES_FILE data file type that appends plate styles to the
game's VehiclePlates texture array, with textures from a streamed .ytd, and
GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX_BY_NAME to look plate indices up by name.

gta-streaming-five gains streaming::RegisterDataFileHandler so other
components can add custom data file types.

Signed-off-by: RaeLightwen <nikashatv@gmail.com>
…d order

Plate indices are synced as plain numbers, so clients must agree on them.
Plates without an Index now get the free indices after the vanilla plates in
order of their TextureSetName, so every client running the same resources
assigns the same indices, including players who join after a plate resource
was restarted. Vehicles using a plate that moves to another index are
switched to its new index.

Signed-off-by: RaeLightwen <nikashatv@gmail.com>
@RaeLightwen
RaeLightwen force-pushed the feat/addon-license-plates branch from c18d860 to 41b73f0 Compare November 12, 2026 20:05
@RaeLightwen
RaeLightwen marked this pull request as ready for review November 12, 2026 20:08
@github-actions github-actions Bot added invalid Requires changes before it's considered valid and can be (re)triaged and removed triage Needs a preliminary assessment to determine the urgency and required action labels Nov 12, 2026
@RaeLightwen

Copy link
Copy Markdown
Author

Check fail looks to be an issue with the runners, not with my branch. Hope this can get resolved soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid Requires changes before it's considered valid and can be (re)triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature / Bug: Lack of native VEHICLE_PLATE_FILE streaming leads to Adhesive false-positive bans when unclamping plate limits via client plugins

1 participant