# Configuration > Every config option in ML Tattoos Category: TATTOOS · Source: https://miciomods.it/docs/ml-tattoos-configuration · Last updated: 2026-07-28 ## Overview - `shared/config.lua`: Currency, prices, custom tattoos, uses, item payment, restrictions, shops and commands - `server/config_server.lua`: Discord webhooks and the rate-limit fallback (server-only, never sent to clients) The shop runs item/admin-only out of the box: `Config.Shops` is empty, so there are no public NPCs or blips until you add them. ## General **shared/config.lua** ```lua Config.Locale = 'en' Config.Currency = 'bank' Config.UIPosition = 'right' Config.MetaResource = 'ml_tattoos_meta' Config.AdminCommand = 'tattooadmin' Config.AdminPermission = 'admin' Config.PremiumCommand = 'mytattoos' Config.StudioCommand = 'mystudio' ``` - `Locale`: Interface language. Loads the matching file in `locales/`, with English as the fallback for any missing key - `Currency`: Money account used for every charge: `'bank'`, `'cash'` or `'money'` - `UIPosition`: Panel side: `'left'` or `'right'` - `MetaResource`: Name of the companion resource that streams the custom-tattoo overlay slots. Leave as `ml_tattoos_meta` unless you renamed it - `AdminCommand`: Command that opens the shop straight on the admin tab (admin only) - `AdminPermission`: `ml_bridge` permission (ACE node or framework group) that grants admin access to the command and the admin panel - `PremiumCommand`: Command that opens a read-only view of the tattoos the player owns - `StudioCommand`: Command that opens the My Studio tab for players who hold uses or own custom tattoos ## Currency & Prices **shared/config.lua** ```lua Config.RemovePrice = 1000 Config.DefaultTattooPrice = 500 Config.CategoryPrices = { ['mpheist4_overlays'] = 400, ['mplowrider_overlays'] = 500, ['mpluxe_overlays'] = 500, ['mpbeach_overlays'] = 200, -- ...one entry per DLC overlay pack } ``` - `RemovePrice`: Cost charged per tattoo removed - `DefaultTattooPrice`: Fallback price when a tattoo has no specific price - `CategoryPrices`: Per-DLC price, keyed by the overlay pack slug. Price priority is per-tattoo override → `CategoryPrices[dlc]` → `DefaultTattooPrice` ## Custom Tattoos **shared/config.lua** ```lua Config.EnableCustomTattoos = true Config.CustomTattooPrice = 500 Config.CustomTattooPrefix = 'MLTattoo' Config.UserCustom = { enabled = true, imageInput = 'paste', -- 'paste' | 'upload' | 'both' uploadMaxBytes = 2097152, editWindow = { enabled = true, ttlMinutes = 1440 }, maxCredits = { solo = 20, faction = 10, ytd = 10 }, refundOnAdminDeleteHours = 24, maxCustomsPerPlayer = 30, } Config.SlotsPerPreset = 100 ``` - `EnableCustomTattoos`: Master switch for player custom-image tattoos - `CustomTattooPrice`: Money charged to apply a custom tattoo through the normal shop flow (admins are exempt) - `CustomTattooPrefix`: Naming prefix for custom overlays - `UserCustom.enabled`: Lets players who hold uses create their own custom without admin involvement - `UserCustom.imageInput`: How a player supplies the image: `'paste'` a link, `'upload'` a PNG in-game (needs FiveManage), or `'both'` - `UserCustom.uploadMaxBytes`: Maximum PNG size accepted by the in-game uploader - `UserCustom.editWindow`: Free rework window after creation. `ttlMinutes` = 1440 gives 24h; after that a rework consumes another use - `UserCustom.maxCredits`: Per-type cap on how many uses a single player can hold at once - `UserCustom.refundOnAdminDeleteHours`: If an admin deletes a user-created custom within this many hours, the creator is refunded one use - `UserCustom.maxCustomsPerPlayer`: Maximum custom tattoos a single player can own - `SlotsPerPreset`: How many unique customs can coexist per body position. Size it to your expected total number of customs; a higher value reserves more streamed pool space. Changes take effect after a server restart ## Uses & Optional Donations > **INFO:** Fully optional > > This whole layer is opt-in. With no Tebex packages configured it does nothing, and the normal money/item tattoo shop keeps working. Use it only if you want to let players optionally support the server in exchange for custom-tattoo uses. A **use** is a token that lets a player create one custom tattoo. Uses come in three types: `solo` (a personal custom), `faction` (a custom shared with the player's gang/faction), and `ytd` (unlocks one installed Full-Body pack permanently). **shared/config.lua** ```lua Config.TebexPackages = { ['ml_tattoos_solo_1'] = { type = 'solo', amount = 1, eur = 15, money = 15000, source = 'tebex' }, ['ml_tattoos_solo_3'] = { type = 'solo', amount = 3, eur = 30, money = 40000, source = 'tebex' }, ['ml_tattoos_faction_1'] = { type = 'faction', amount = 1, eur = 40, money = 30000, source = 'tebex' }, ['ml_tattoos_ytd_1'] = { type = 'ytd', amount = 1, eur = 30, money = 25000, source = 'tebex' }, } Config.AllowedConsumerResources = { -- 'ml_donator_coins', } ``` - `TebexPackages`: Maps a Tebex package id to a use grant. Match each key to the package identifier on your Tebex store - `type`: `'solo'`, `'faction'` or `'ytd'` - `amount`: How many uses the package grants - `eur`: Real-money price on your Tebex store; `money`: in-game price (charged from `Config.Currency`) - `source`: Which rail the player may use: `'tebex'` (real-money donation through your store, delivered by webhook), `'money'` (in-game cash at the `money` price), or `'both'`. Defaults to `'tebex'` - `AllowedConsumerResources`: Server resources permitted to grant/consume/refund uses through the exports (e.g. a coin-donator system). Read access is always open When any package uses `source = 'tebex'`, set these convars in `server.cfg` so `ml_tebex` can verify and deliver donations: **server.cfg** ```cfg set ml_tebex_webhook_secret "your-webhook-secret" set ml_tebex_plugin_secret "your-plugin-secret" ``` Uses can also be granted by staff from the admin panel, or by another resource through `exports.ml_tattoos:GrantTattooCredit` (see Developer). ## Full-Body (YTD) Packs **shared/config.lua** ```lua Config.YtdPacks = { -- ['oldschool'] = { -- label = 'Old School Full Body', -- collection = 'mlytd_oldschool', -- thumbnail = 'https://i.imgur.com/xxxxxxx.png', -- tattoos = { -- { hash = 'OS_SLEEVE_L', zone = 'ZONE_LEFT_ARM', label = 'Left sleeve' }, -- }, -- -- allowedFactions / allowedIdentifiers restrict who can unlock it -- }, } ``` - `YtdPacks`: Declares each separately-installed full-body pack (its `.ytd` dictionaries plus a decoration collection). One `ytd` use unlocks one whole pack permanently per player - `collection`: The decoration collection name shipped inside the pack - `tattoos`: Every overlay in the pack a player can apply, with its zone and label - `allowedFactions / allowedIdentifiers`: Optional. Omit both for an open pack; otherwise only matched factions or identifiers see and unlock it ## Item Payment **shared/config.lua** ```lua Config.EnableItemPayment = false Config.ItemPerTattoo = { item = 'tattoo_kit', count = 1 } Config.UnlockableHashes = { -- ['MP_MP_Heist4_Tat_000_M'] = { item = 'rare_tattoo_scroll', count = 1 }, } Config.ItemPresets = { tattoo_kit_basic = { label = 'Basic Tattoo Kit', limit = 1, pay = 'item', count = 1, categories = { 'mphipster_overlays', 'mpbeach_overlays' }, allowCustom = false, }, } ``` - `EnableItemPayment`: When `true`, tattoos cost an item instead of money. Off by default - `ItemPerTattoo`: The item and quantity consumed per tattoo while item payment is on - `UnlockableHashes`: Locks specific tattoo hashes behind owning an item (the item is checked, not consumed) - `ItemPresets`: Each usable item opens the shop pre-filtered to a single tattoo. `pay` = `'item'` consumes the item, `'free'` applies for free, `'shop'` charges money. Filter with `zones`, `categories`, `hashes`, `allowCustom` ## Shops, NPC & Clothing **shared/config.lua** ```lua Config.UseTarget = true Config.InteractDistance = 2.5 Config.Shops = {} Config.UseNPC = false Config.NPC = { model = 'mp_m_waremech_01', scenario = 'WORLD_HUMAN_CLIPBOARD', invincible = true, freeze = true } Config.EnableClothesHide = true Config.ArtistScene = { enabled = true, duration = 4000, animDict = 'mini@repair', animName = 'fixing_a_player', flag = 49 } ``` - `UseTarget`: `true` uses ox_target on shop locations, `false` uses proximity + TextUI - `InteractDistance`: Interaction distance (metres) for a shop - `Shops`: Public shop locations (coords, heading, label, blip). Empty by default for an item/admin-only flow - `UseNPC / NPC`: Spawn a tattoo-artist ped at each shop and its appearance/behaviour - `EnableClothesHide`: Strips clothes while inside the shop so tattoos are visible (configurable via `Config.InvisibleClothes`) - `ArtistScene`: Animation played on the player when a checkout succeeds ## Admin Grant **shared/config.lua** ```lua Config.AdminGrantCommand = 'opentattoo' Config.AdminGrantDefaults = { limit = 1, customOnly = false, allowCustom = true, duration = 120000 } ``` - `AdminGrantCommand`: Admin command that opens the shop on a target player in free mode: `/opentattoo [limit] [customOnly]` - `AdminGrantDefaults`: Default grant limit, whether to show only customs, whether to include the custom catalog, and the grant lifetime in ms ## Webhooks **server/config_server.lua** ```lua ServerConfig.DiscordWebhook = GetConvar('ml_tattoos_webhook', '') ServerConfig.AdminWebhook = GetConvar('ml_tattoos_admin_webhook', ServerConfig.DiscordWebhook) ServerConfig.RateLimitCooldown = 500 ``` - `DiscordWebhook`: Player-action log webhook, read from the `ml_tattoos_webhook` convar so no URL ships in the build - `AdminWebhook`: Admin-action log webhook (`ml_tattoos_admin_webhook`); falls back to the main webhook when unset - `RateLimitCooldown`: Fallback minimum ms between repeated actions from one player > **INFO:** Webhooks via convars > > Set the URLs in `server.cfg`: `setr ml_tattoos_webhook "https://discord.com/api/webhooks/..."` (and optionally `ml_tattoos_admin_webhook`).