Skip to content

tattoos.json

The tattoos.json file (located in resources\vMenu\config\) is used to add your own custom (streamed) tattoos to the MP Character tattoos menu.

vMenu already ships with every known base game tattoo and badge up to 2026 built in, so you do not need to list those here. This file is only for overlays that you stream in yourself from your own resource.

The file ships empty:

[]

Once you add at least one entry, an extra Addon Tattoos list appears in MP Ped Customization > Tattoos, alongside the built in Hair, Head, Torso, Left/Right Arm, Left/Right Leg and Badge Overlays lists. If the file is empty, that menu item is hidden entirely.

Unlike the other config files, this one is a JSON array (square brackets), not an object. Each entry describes one tattoo:

[
{
"gender": 2,
"name": "mytattoos_05_A",
"collectionName": "mytattoos_overlays"
}
]
Field Type Required Description
gender number Yes 0 for male only, 1 for female only, 2 for both.
name string Yes The name of the overlay itself.
collectionName string Yes The name of the collection the overlay lives in.
zoneId number No Accepted, but ignored for addon tattoos. See the note below.
type string No Accepted, but ignored for addon tattoos. See the note below.

Here I’ve added five tattoos from two different collections, with a mix of male only, female only and unisex entries:

[
{
"gender": 0,
"name": "mytattoos_01_M",
"collectionName": "mytattoos_overlays"
},
{
"gender": 1,
"name": "mytattoos_01_F",
"collectionName": "mytattoos_overlays"
},
{
"gender": 2,
"name": "mytattoos_02_A",
"collectionName": "mytattoos_overlays"
},
{
"gender": 2,
"name": "sleeves_fullarm_left",
"collectionName": "custom_sleeves_overlays"
},
{
"gender": 2,
"name": "sleeves_fullarm_right",
"collectionName": "custom_sleeves_overlays"
}
]

This is the part people get stuck on, so it’s worth spelling out.

When you stream a custom tattoo, your resource contains an overlay definition file (usually named something like mytattoos_overlays.xml) with one <Item> per tattoo. That file is where both of the names you need come from:

<Item>
<uvPos x="0.720000" y="0.670000" />
<scale x="0.280000" y="0.350000" />
<rotation value="0.000000" />
<nameHash>mytattoos_05_A</nameHash>
<txdHash>mytattoos_05</txdHash>
<txtHash>mytattoos_05</txtHash>
<zone>ZONE_RIGHT_ARM</zone>
<type>TYPE_TATTOO</type>
<faction>FM</faction>
<garment>All</garment>
<gender>GENDER_DONTCARE</gender>
<award />
<awardLevel />
</Item>
  • name is the <nameHash> value, so mytattoos_05_A in the example above. Note that this is not the same as <txdHash>/<txtHash> (the texture dictionary), which is a common mix up.
  • collectionName is the collection that overlay file declares. By convention this matches the overlay file’s own name without the extension, so mytattoos_overlays.xml gives you a collection called mytattoos_overlays.
  • gender maps from the <gender> field: GENDER_MALE (or a _M suffixed name) becomes 0, GENDER_FEMALE (or _F) becomes 1, and GENDER_DONTCARE becomes 2.

Those two names are exactly the pair you’d pass to the AddPedDecorationFromHashes native, which is what vMenu does under the hood:

AddPedDecorationFromHashes(ped, GetHashKey("mytattoos_overlays"), GetHashKey("mytattoos_05_A"))

Everything above assumes you already have a working tattoo resource and just need to point vMenu at it. Making the assets themselves is a separate job that vMenu isn’t involved in at all, so it isn’t covered here.

vMenu sorts its built in overlays into the separate menu lists automatically:

  • Any overlay whose name contains hair_ goes into Hair Tattoos. This is why hair overlays no longer get mixed in with the head tattoos.
  • Any overlay of type TYPE_BADGE goes into Badge Overlays.
  • Everything else is sorted by zone into the Head, Torso, Arm and Leg lists.

That sorting only applies to the built in data. Your addon entries always land in the Addon Tattoos list, regardless of whether they’re hair overlays, badges or regular tattoos.

[]

Consider supporting me on Patreon!