Skip to content

Tattoo Shop and Appearance

Player Tattoo Shop, professional sessions, and appearance integration

This guide covers the current Tattoo Shop behavior.

Tattoo Shop applies published Tattoo Designer projects to player characters. It is separate from the authoring studio: the studio creates and saves projects; the shop sells or applies published projects.

The supported authoring and shop scope is limited to the text and image modes, six standard body zones (torso, zone_head, left_arm, right_arm, left_leg, and right_leg), and male/female freemode peds. A project can contain at most 64 layers; the default image-layer limit is MaxImageLayers = 12.

1. Open the shop and configure locations#

Keep Config.TattooShop.Enabled enabled and configure locations in config/init.lua:

lua
Config.TattooShop = {
  Enabled = true,
  Locations = {
    vector4(-1361.5669, -351.1030, 36.7585, 161.1648),
  },
}

The final vector4 value is the preview camera heading. The marker and TextUI appear when the player is within the configured shop distance. The default interaction key is E (Interaction.Key = 38). Blip, distance, and visibility settings live under Config.TattooShop.Interaction.

The delivered 0r-tattoo_runtime_assets resource also owns the integrated tattoo-studio map assets. Keep it running; no separate map resource is required.

2. How presets become available#

Only projects that were built and published by Tattoo Designer appear in the shop. A Template Image or saved draft does not become a shop preset by itself.

To publish a preset:

  1. An authorized artist opens the studio with /tdesigner.
  2. The designer selects body zones and builds the project.
  3. The designer publishes the project and runs Export Reload when required.
  4. The project becomes available in the Tattoo Shop preset list.
  5. An authorized artist can apply the preset through self-service. A normal player receives it through a professional artist session when that flow is enabled.

Disable the preset list with Config.TattooShop.Presets.Enabled = false.

3. Applied tattoo limits and pricing#

lua
Config.TattooShop.Pricing.PricePerZone = 500
Config.TattooShop.AppliedTattoos = {
  Enabled = true,
  MaxPerPlayer = 8,
  MaxPerZone = 3,
}

Self-service is available to authorized artists. The price is PricePerZone multiplied by the selected zones that contain rendered tattoo layers. The limits are character-bound. The built-in payment adapters use the QBX/QB-Core/ESX cash account; use a custom payment provider for another economy.

Professional quotes are separate from PricePerZone. The artist supplies a positive whole-currency quote, subject to the server's safe amount limit, and the customer must accept it before the quote expires. Quotes expire after 30 seconds.

4. Professional Tattoo sessions#

In a professional session, an artist offers a tattoo service to another player. The server validates the offer, distance, customer identity, selected zones, project revision, quote, and payment sequence.

lua
Config.TattooShop.Professional = {
  Enabled = true,
  Access = {
    Match = 'any',
    Identifiers = {},
    Jobs = {
      tattoo = { MinGrade = 0, RequireOnDuty = true },
    },
  },
}
  • The artist sends the offer through the configured target provider.
  • The customer accepts or declines the offer.
  • Payment is charged to the customer; a successful committed purchase can pay the artist.
  • Rendering and upload preparation happen before the customer is charged.
  • The apply job calls the payment adapter after preparation and before the canonical ownership write.
  • If preparation, payment, or the canonical ownership write fails, the resource creates no canonical ownership.
  • After the ownership write, runtime synchronization or artist-payout failure keeps the committed ownership and is logged with no automatic refund workflow.

ox_target and qb-target are optional. Without a target provider, target-based professional offers are unavailable. Use the Modules and Custom Providers page for a custom target integration.

5. Select an appearance provider#

Standalone#

Standalone does not require an external appearance resource. Tattoo Designer applies the ped decorations directly, while Tattoo Designer's database remains the canonical owner of the saved-project ownership and applied records. An external appearance system can still reapply its own state later and visually overwrite a tattoo.

illenium-appearance#

When illenium-appearance is active, the resource merges Tattoo Designer tattoos with the provider's existing tattoos and persists the appearance:

lua
Config.AppearanceIntegration.ActiveProvider = 'illenium-appearance'
Config.AppearanceIntegration.Providers['illenium-appearance'].Resource = 'illenium-appearance'

The Resource value must exactly match the resource name on the server. If Export Reload updates the companion file, add:

cfg
add_filesystem_permission 0r-tattoo_designer write illenium-appearance

Illenium lifecycle compatibility#

Illenium's native tattoos are stored in its appearance.tattoos snapshot. It can therefore clear the ped decorations and reapply its own catalog tattoos after an editor session. Tattoo Designer custom images use separate runtime overlay slots and are not part of that snapshot.

The patched Illenium resource must emit this local event after its final appearance/tattoo application in client.exitPlayerCustomization:

lua
TriggerEvent("illenium-appearance:client:appearanceApplied", "customization_exit")

Tattoo Designer listens for the event and re-runs its canonical owned-tattoo sync. The event is deliberately generic: Illenium does not call a 0r-tattoo_designer export, and Tattoo Designer remains the canonical owner of custom tattoo ownership and runtime manifests. Save and cancel both use this same Illenium function, so the one hook covers both editor exit paths.

6. Preview controls#

The live preview runs on a FiveM clone ped:

  • With CAPS LOCK off, left drag moves the active tattoo within the current zone.
  • With CAPS LOCK on, left drag orbits the camera and right drag rotates the preview ped.
  • The mouse wheel changes zoom and framing.

The preview clone's clothing is simplified only to keep visible zones clear; the real player's clothing is not changed. Preview data URLs default to 512 KiB per zone and 2 MiB total. An over-budget preview is rejected and the last accepted preview remains visible.

Checklist#

  1. Visit a configured shop location and verify the marker/blip.
  2. Confirm a published project appears only after the required build and Export Reload.
  3. Test persistence by reconnecting after a successful purchase.
  4. With Illenium enabled, verify that other appearance tattoos remain and removed Tattoo Designer tattoos do not return.
  5. With Illenium enabled, apply a custom image tattoo, open and close the appearance editor, and change an outfit; confirm the custom overlay returns while native Illenium tattoos remain.
  6. Test a preparation/payment failure and a post-commit synchronization failure separately; confirm the latter preserves ownership and writes the expected server log.