Skip to content

Installation

Initial installation steps for 0r-tattoo_designer

Initial installation steps for 0r-tattoo_designer

This guide covers the current resource installation.

Follow these steps in order. Incorrect resource order can prevent the Studio, database, or runtime tattoos from starting.

1. Prepare requirements#

The server must have ox_lib, oxmysql, OneSync, and Node.js 22+ for the worker. If Node is not found automatically, set the full executable path in 0r-tattoo_designer/config/init.lua:

lua
Config.Worker.NodePath = 'C:/Program Files/nodejs/node.exe' -- Windows
-- Config.Worker.NodePath = '/usr/bin/node'                 -- Linux

Keep FXServer on a current stable artifact. If a DLL or compatibility error occurs before the resource starts, update the artifact first.

The customer delivery contains generated resources and does not include a source workspace or build toolchain. No build toolchain is required for installation. fxmanifest.lua node_version '22' selects FiveM's embedded bridge runtime; Config.Worker.NodePath selects the separate host worker executable.

2. Copy the resources#

Copy the delivered [tattoo_designer] folder into your resources directory. All three resources must be present:

text
resources/
  [standalone]/
    ox_lib/
    oxmysql/
    [custom]/
    [tattoo_designer]/
      0r-tattoo_runtime_assets/  # Stable overlays, runtime slots, and studio map
      0r-tattoo_designer/
      0r-tattoo_exports/

3. Install the database#

The recommended method is to import this generated SQL fallback once with your MySQL tool:

0r-tattoo_designer/[installation]/database.sql

At startup, the resource applies missing ordered migrations and verifies the schema read-only. Version 2 creates the apply-job queue and upgrades the published version 1 schema. If the database user cannot create or alter tables, import the generated SQL fallback for a clean database. Do not rerun that fallback against an already migrated customer database, reset the schema, or alter migration records manually.

See Database for table ownership and migration behavior.

4. Create the private configuration#

Copy:

config/private.example.lua

to:

config/private.lua

Discord webhook URLs, FiveManage keys, and custom Template Catalog URLs belong only in this file. Keep private.lua out of public repositories, support uploads, and shared resource archives. Do not put secrets in config/init.lua or expose them to the NUI.

Remote image and preview URLs must be readable by the NUI through public HTTPS GET requests with the expected MIME type and CORS for the cfx-nui-0r-tattoo_designer origin.

5. Add server.cfg permissions and startup order#

Place the permissions before the ensure lines, then start the resources in this order. If you keep permissions in a separate file such as permissions.cfg, load it from server.cfg with exec permissions.cfg before the resource ensure lines:

cfg
add_ace resource.0r-tattoo_designer command.refresh allow
add_ace resource.0r-tattoo_designer command.ensure allow
add_ace resource.0r-tattoo_designer command.start allow
add_ace resource.0r-tattoo_designer command.stop allow
add_ace resource.0r-tattoo_designer command.restart allow

add_unsafe_child_process_permission 0r-tattoo_designer

ensure ox_lib
ensure oxmysql
ensure 0r-tattoo_runtime_assets
ensure 0r-tattoo_designer
ensure 0r-tattoo_exports

Export Reload requires command.refresh, command.stop, command.ensure, and command.start for resource.0r-tattoo_designer. FiveM's ensure command calls start internally, so grant both permissions. Grant command.restart only when you also restart an appearance provider. Use add_unsafe_child_process_permission to allow the export and processing worker to start.

Fully restart FXServer after adding these permissions.

6. Illenium-appearance integration#

If you use illenium-appearance, add filesystem permission so Export Reload can update its companion file:

cfg
add_filesystem_permission 0r-tattoo_designer write illenium-appearance

When Illenium is active, apply the local lifecycle hook below to the illenium-appearance resource before testing custom Tattoo Designer overlays. This is required because Illenium clears and rebuilds its native decoration list when customization ends; its catalog tattoos are restored by Illenium itself, while Tattoo Designer runtime overlays are owned by 0r-tattoo_designer.

In illenium-appearance/game/customization.lua, replace the existing client.exitPlayerCustomization function with the version below. The only integration addition is the appearanceApplied event after Illenium finishes its final native appearance/tattoo application:

lua
function client.exitPlayerCustomization(appearance)
    RenderScriptCams(false, false, 0, true, true)
    DestroyCam(cameraHandle, false)
    SetNuiFocus(false, false)

    if Config.HideRadar then DisplayRadar(true) end

    ClearPedTasksImmediately(cache.ped)
    SetEntityInvincible(cache.ped, false)

    SendNuiMessage(json.encode({
        type = "appearance_hide",
        payload = {}
    }))

    if not appearance then
        client.setPlayerAppearance(getAppearance())
    else
        client.setPedTattoos(cache.ped, appearance.tattoos)
    end

    -- Notify appearance integrations after Illenium has finished its
    -- final decoration reset and native tattoo re-application.
    TriggerEvent("illenium-appearance:client:appearanceApplied", "customization_exit")

    RestorePlayerStats()

    if callback then
        callback(appearance)
    end

    callback = nil
    config = nil
    playerAppearance = nil
    playerCoords = nil
    cameraHandle = nil
    currentCamera = nil
    reverseCamera = nil
    isCameraInterpolating = nil
end

Both the Illenium save and cancel paths call exitPlayerCustomization, so one hook covers both. Tattoo Designer listens for this local client event and runs its existing refreshOwnTattoos() flow. Do not add Tattoo Designer runtime entries to Illenium's appearance.tattoos snapshot. Reapply this small hook after replacing or updating the Illenium resource.

7. Grant designer access#

By default, group.admin receives tattoo_designer.use. This ACE grants access to the authoring Studio and artist self-service flow. To grant studio access to a specific player:

cfg
add_ace identifier.license:your-license-here tattoo_designer.use allow

8. Verify the first session#

  1. Restart the server.
  2. Open /tdesigner with an authorized player.
  3. Create and save a project as an authorized artist.
  4. Build the project.
  5. Run Export Reload.
  6. Open the Tattoo Shop and confirm that the published project is available.

Unsaved drafts exist only in process memory and are cleared by a resource or server restart. Save the project before the first build when the work must persist.

If the Studio does not open, start with Troubleshooting. Next: Configuration.

External integration#

See External Integration for the separate download and installation steps. You are responsible for its configuration, use, external service charges, and compliance with applicable platform and provider terms.