> For the complete documentation index, see [llms.txt](https://docs.ak4y.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ak4y.com/scripts/ak4y-tattooeditor/configuration.md).

# Configuration

```lua
Config = {}

Config.locales = {}
Config.Locale = "en" -- Active language/locale for the script (e.g. tr, en)

Config.ClearStudioTattoosOnRestart = true -- If true, dynamically cleared tattoos generated by the script are removed from the resources directory on script restart.

Config.OnlyForAdmin = false -- If true, only admin commands or admin menu is enabled.
Config.OpenCommand = "admintatto" -- Command registered to open the administrator menu.

Config.NeedSessionForRemove = 1 -- Number of laser/removal sessions needed to completely remove a tattoo. 0 means deleted instantly.
Config.RemovalSessionPrice = 500 -- The price charged per single laser removal session.

Config.IHaveAnticheatProblem = false -- Set to true if you encounter active anticheat blocks/problems when generating or editing tattoos. (When you do this, tattoos will apply to your character after restart)

Config.EnableShareCodes = true -- Enables the share/import code system for tattoos.

--Only for illenium-appearance (Default frameworks doesn't have a tattoo system.)
Config.SaveTattoosFromAppearance = false -- If true, the script reads/saves tattoos directly from your appearance resource instead of the local script db.
Config.Appearance = "illenium-appearance" --Since qb-core and ESX do not have a default Tatto script, they are not compatible.
Config.AppearanceTable = "playerskins" -- Table name for illenium-appearance (usually playerskins)
Config.AppearanceColumn = "citizenid"  -- Column name for character identification (citizenid or identifier)

Config.Studio = {
    AllowSelfTattoo = true, -- Allow players to open the menu and tattoo themselves without an artist.

    InteractKey = 47, -- G (FiveM Control ID)
    InteractKeyLabel = "[G]", -- Screen label displaying the interaction key binding.

    Ownable = true, -- If true, tattoo studios can be purchased or rented by players.
    ShopMode = "rent", -- Business model of the studio purchase: "buy" (one-time purchase) or "rent" (periodic leasing).
    RentPrice = 10000, -- Cost to rent the studio per lease cycle.
    RentDuration = 7, -- Number of days one rent cycle lasts (Days).

    openWithCommand = {
        enable = false, -- Enable opening the tattoo menu via command.
        command = "tattoo" -- The command that triggers menu opening.
    },

    DefaultTattooPrice = 250, -- The fallback/default cost for applying any standard tattoo.

    Studios = {
        {
            Enabled = true, -- If true, this specific tattoo studio is active and interactable in the game.
            blip = {
                enabled = true, -- Toggle map radar blip display for this studio.
                sprite = 75, -- Blip icon/sprite ID (75 is standard tattoo shop blip).
                color = 24, -- Color ID of the radar blip (24 is standard).
                scale = 1.0, -- Scale size multiplier of the map blip.
                name = "Tattoo Shop" -- Visual hover label of the map blip.
            },
            Location = vec4(323.5, 181.0, 102.5, 116.37), -- Coordinates (x, y, z, heading) of the interaction/sitting chair.
            ManagementLocation = vec3(320.57, 183.41, 103.99), -- Vector3 coordinates of the business management laptop/marker.
            ManagementRange = 2.0, -- Interaction distance threshold for opening the business management panel.
            PurchasePrice = 50000, -- One-time cost to buy this studio outright if buy mode is active.
            DefaultTattooPrice = 250, -- Starting fallback fee charged to customers at this studio.
            Range = 3.0, -- Maximum interaction radius for an artist to seat themselves at the chair.
            CustomerRange = 3.0, -- Maximum distance allowed between the customer ped and the artist to begin a session.

            ArtistOffset = vec3(0.8, -0.5, 0.0), -- Positional offset relative to the chair where the artist stands.
            CustomerOffset = vec3(0.1, 0.0, 0.0), -- Positional offset relative to the chair where the customer is placed.
            ArtistTurnTime = 1000, -- Duration (milliseconds) for the artist ped to rotate towards the customer.

            Artist = {
                dict = "misstattoo_parlour@shop_ig_4", -- Animation dictionary used for the tattooing ped.
                clip = "tattooist_loop", -- Animation clip/name for the tattooing action loop.
                flag = 1, -- Playback loop flag behavior.
                blendIn = 8.0, -- Animation blend-in transition speed.
                blendOut = -8.0, -- Animation blend-out transition speed.
            },

            Customer = {
                dict = "timetable@maid@couch@", -- Animation dictionary used for the customer sitting on the chair.
                clip = "base", -- Animation clip/name representing the sitting posture.
                flag = 1, -- Playback loop flag behavior.
                blendIn = 8.0, -- Animation blend-in transition speed.
                blendOut = -8.0, -- Animation blend-out transition speed.
            },
        },
        {
            Enabled = true,
            blip = {
                enabled = true,
                sprite = 75,
                color = 24,
                scale = 1.0,
                name = "Tattoo Shop"
            },
            Location = vector4(1322.7, -1653.45, 51.28, 354.68),
            ManagementLocation = vector3(1326.29, -1652.55, 52.78),
            ManagementRange = 2.0,
            PurchasePrice = 50000,
            DefaultTattooPrice = 250,
            Range = 3.0,
            CustomerRange = 3.0,

            ArtistOffset = vec3(0.8, -0.5, 0.0),
            CustomerOffset = vec3(0.1, 0.0, 0.0),
            ArtistTurnTime = 1000,

            Artist = {
                dict = "misstattoo_parlour@shop_ig_4",
                clip = "tattooist_loop",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },

            Customer = {
                dict = "timetable@maid@couch@",
                clip = "base",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },
        },
        {
            Enabled = true,
            blip = {
                enabled = true,
                sprite = 75,
                color = 24,
                scale = 1.0,
                name = "Tattoo Shop"
            },
            Location = vector4(-1154.23, -1427.0, 3.95, 350.33),
            ManagementLocation = vector3(-1150.62, -1426.14, 5.4),
            ManagementRange = 2.0,
            PurchasePrice = 50000,
            DefaultTattooPrice = 250,
            Range = 3.0,
            CustomerRange = 3.0,

            ArtistOffset = vec3(0.8, -0.5, 0.0),
            CustomerOffset = vec3(0.1, 0.0, 0.0),
            ArtistTurnTime = 1000,

            Artist = {
                dict = "misstattoo_parlour@shop_ig_4",
                clip = "tattooist_loop",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },

            Customer = {
                dict = "timetable@maid@couch@",
                clip = "base",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },
        },
        {
            Enabled = true,
            blip = {
                enabled = true,
                sprite = 75,
                color = 24,
                scale = 1.0,
                name = "Tattoo Shop"
            },
            Location = vector4(-3170.4, 1076.8, 19.83, 194.54),
            ManagementLocation = vector3(-3172.99, 1074.24, 21.4),
            ManagementRange = 2.0,
            PurchasePrice = 50000,
            DefaultTattooPrice = 250,
            Range = 3.0,
            CustomerRange = 3.0,

            ArtistOffset = vec3(0.8, -0.5, 0.0),
            CustomerOffset = vec3(0.1, 0.0, 0.0),
            ArtistTurnTime = 1000,

            Artist = {
                dict = "misstattoo_parlour@shop_ig_4",
                clip = "tattooist_loop",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },

            Customer = {
                dict = "timetable@maid@couch@",
                clip = "base",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },
        },
        {
            Enabled = true,
            blip = {
                enabled = true,
                sprite = 75,
                color = 24,
                scale = 1.0,
                name = "Tattoo Shop"
            },
            Location = vector4(-293.87, 6200.89, 30.49, 193.7),
            ManagementLocation = vector3(-294.5, 6197.96, 32.2),
            ManagementRange = 2.0,
            PurchasePrice = 50000,
            DefaultTattooPrice = 250,
            Range = 3.0,
            CustomerRange = 3.0,

            ArtistOffset = vec3(0.8, -0.5, 0.0),
            CustomerOffset = vec3(0.1, 0.0, 0.0),
            ArtistTurnTime = 1000,

            Artist = {
                dict = "misstattoo_parlour@shop_ig_4",
                clip = "tattooist_loop",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },

            Customer = {
                dict = "timetable@maid@couch@",
                clip = "base",
                flag = 1,
                blendIn = 8.0,
                blendOut = -8.0,
            },
        },
    },
}

Config.Upgrades = {
    Enabled = true, -- Enable studio business/equipment upgrade options.
    Types = {
        image = {
            label = "Image Upload",
            price = 25000,
            icon = "image",
            description = "Unlocks the ability to upload images via external URL."
        },
        text = {
            label = "Text Writing",
            price = 15000,
            icon = "text",
            description = "Unlocks the ability to create text-based tattoos."
        },
        sets = {
            label = "Preset Sets",
            price = 40000,
            icon = "sets",
            description = "Unlocks the ability to save and apply preset tattoo sets."
        }
    }
}

Config.Tutorials = {
    Enabled = true, -- Show short animated GIF tutorials for first-time users inside NUI.
    Opening = "https://files.catbox.moe/l6mwf2.gif", -- Tutorial GIF URL for shop opening walkthrough.
    Removal = "https://files.catbox.moe/zq3si9.gif", -- Tutorial GIF URL for the laser removal minigame.
    Drawing = "https://files.catbox.moe/l1l7uz.gif", -- Tutorial GIF URL for the custom drawing editor.
    ImageUpload = "https://files.catbox.moe/83w4df.gif", -- Tutorial GIF URL for external image custom URL uploading.
    TextTattoo = "https://files.catbox.moe/13x9wk.gif", -- Tutorial GIF URL for creating text-based tattoos.
    StorageKeyPrefix = "ak4y_tattoo_tutorial_v10", -- Local storage key prefix used to track tutorial completed status on NUI.
}

function getLocale(index, key)
    return Config.locales[index][key]
end

function drawText3D(x, y, z, text)
    local onScreen, sx, sy = World3dToScreen2d(x, y, z)
    if not onScreen then return end
    local camCoords = GetGameplayCamCoords()
    local distance = #(vector3(x, y, z) - camCoords)
    local size = 0.35 * (8.0 / distance)
    if size > 0.55 then size = 0.55 end
    if size < 0.18 then size = 0.18 end

    SetTextScale(size, size)
    SetTextFont(4)
    SetTextProportional(true)
    SetTextColour(255, 255, 255, 220)
    SetTextOutline()
    SetTextDropshadow(2, 0, 0, 0, 200)
    SetTextDropShadow()
    SetTextEdge(2, 0, 0, 0, 200)
    SetTextCentre(true)
    SetTextEntry('STRING')
    AddTextComponentString(text)
    DrawText(sx, sy)
end

function notify(message, typ)
    pcall(function()
        exports["ak4y-core"]:NotifyViaFramework(message, typ or 'inform')
    end)
end
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ak4y.com/scripts/ak4y-tattooeditor/configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
