> For the complete documentation index, see [llms.txt](https://documentation.rcore.cz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.rcore.cz/paid-resources/rcore_tattoos/installation.md).

# Installation

Follow these steps to install `rcore_tattoos` for the first time. See the [Requirements](/paid-resources/rcore_tattoos.md#-requirements) on the landing page before you start.

## 🛠️ First Time Installation

{% stepper %}
{% step %}

### Download the resource

Download `rcore_tattoos` from [CFX Portal](https://portal.cfx.re/).
{% endstep %}

{% step %}

### Move the folder

Move the `rcore_tattoos` folder into your server 📁`resources` folder.

```
📁 server
└── 📁 resources
    ├── 📁 rcore_tattoos
    └── 📁 other resources
```

{% endstep %}

{% step %}

### Import the SQL

You can find `db.sql` file in the root folder, please insert that sql into your database. It will create 2 tables for player tattoos and businesses.
{% endstep %}

{% step %}

### Ensure the resource

Add the resource to `server.cfg` after your framework, database and society resources.

```cfg
ensure rcore_tattoos
```

{% endstep %}
{% endstepper %}

## Config setup

Open the `config.lua` file.

### Framework

This script can be standalone, if needed, and we implemented two basic frameworks. You can change to your preferred framework like this:

```lua
Config.Framework = Frameworks.ESX -- for ESX
Config.Framework = Frameworks.QBCORE -- for QB
Config.Framework = Frameworks.STANDALONE -- for Standalone ❗ check note below ❗
```

:exclamation:For `Frameworks.STANDALONE`, check [Frameworks](/paid-resources/rcore_tattoos/configs/config.md#framework) in config, please.

To implement your custom framework, take a look at the [Framework](https://documentation.rcore.cz/paid-resources/rcore_tattoos/framework) easy guide.

### License type

Change `LicenseType` to the type of license you use to save your player data. We use this information to get the player's identifier.

```lua
Config.LicenseType = 'license' --license, steam, discord
```

### Language

To change the language of this script, you can simply change `Config.Locale` to any available language in `locales` folder (except tattooNames, that is used to make custom tattoo names).

### Example Multicharacter Integration

**cd\_multichar**

1. in rcore\_tattoos/config.lua Config.LicenseWithoutPrefix = true
2. cd\_multicharacter/configs/config.lua add into additional tables

```lua
{table_name = 'rcore_tattoos', column_name = 'identifier'}
```

1. cd\_multicharacter/configs/client\_customise\_me.lua add this into existing character & new character

```lua
TriggerServerEvent('rcore_tattoos:reload')
```

Example

```lua

--███████╗██╗  ██╗██╗███████╗████████╗██╗███╗   ██╗ ██████╗      ██████╗██╗  ██╗ █████╗ ██████╗  █████╗  ██████╗████████╗███████╗██████╗ 
--██╔════╝╚██╗██╔╝██║██╔════╝╚══██╔══╝██║████╗  ██║██╔════╝     ██╔════╝██║  ██║██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔════╝██╔══██╗
--█████╗   ╚███╔╝ ██║███████╗   ██║   ██║██╔██╗ ██║██║  ███╗    ██║     ███████║███████║██████╔╝███████║██║        ██║   █████╗  ██████╔╝
--██╔══╝   ██╔██╗ ██║╚════██║   ██║   ██║██║╚██╗██║██║   ██║    ██║     ██╔══██║██╔══██║██╔══██╗██╔══██║██║        ██║   ██╔══╝  ██╔══██╗
--███████╗██╔╝ ██╗██║███████║   ██║   ██║██║ ╚████║╚██████╔╝    ╚██████╗██║  ██║██║  ██║██║  ██║██║  ██║╚██████╗   ██║   ███████╗██║  ██║
--╚══════╝╚═╝  ╚═╝╚═╝╚══════╝   ╚═╝   ╚═╝╚═╝  ╚═══╝ ╚═════╝      ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝


--This function is triggered after you choose an EXISTING character.
function CharacterHasLoaded_EXISTING(charid_1, charid_2, skin)
    InitializeESX(charid_1, charid_2)

    while not PlayerLoaded do Wait(0) end
    ResetPlayerState()

    if GetResourceState('cd_spawnselect') == 'started' then
        ------------------------------------------------------------------------------------------------------
        --Add any additional trigger events here.
        TriggerEvent('cd_spawnselect:OpenUI')

        ------------------------------------------------------------------------------------------------------
    end

    if Config.SkinScript == 'esx_skin' or Config.SkinScript == 'cui_character' then
        if skin ~= 'Empty' then
            if Config.SkinScript == 'esx_skin' then
                Wait(2000)
                TriggerEvent('skinchanger:loadSkin', skin)
            elseif Config.SkinScript == 'cui_character' then
                TriggerEvent('cui_character:SetPedClothes_multi', false, skin)
            end
        else
            print('skin nil')
        end

    elseif Config.SkinScript == 'betrayed_clothing_1' or Config.SkinScript == 'betrayed_clothing_2' then
        TriggerServerEvent('clothing:get_character_current')
        --TriggerServerEvent('clothing:checkIfNew') --You may need to try each of these. Not sure which will work for your skin script version.

    elseif Config.SkinScript == 'other' then
        --Add your own code here.

    end
    ------------------------------------------------------------------------------------------------------
    --Add any additional trigger events here.

    ------------------------------------------------------------------------------------------------------

    --HERE
    --RCORE_TATTOOOS
    --RELOAD AFTER NEW CHARACTER
	TriggerServerEvent('rcore_tattoos:reload')
end


--███╗   ██╗███████╗██╗    ██╗     ██████╗██╗  ██╗ █████╗ ██████╗  █████╗  ██████╗████████╗███████╗██████╗ 
--████╗  ██║██╔════╝██║    ██║    ██╔════╝██║  ██║██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔════╝██╔══██╗
--██╔██╗ ██║█████╗  ██║ █╗ ██║    ██║     ███████║███████║██████╔╝███████║██║        ██║   █████╗  ██████╔╝
--██║╚██╗██║██╔══╝  ██║███╗██║    ██║     ██╔══██║██╔══██║██╔══██╗██╔══██║██║        ██║   ██╔══╝  ██╔══██╗
--██║ ╚████║███████╗╚███╔███╔╝    ╚██████╗██║  ██║██║  ██║██║  ██║██║  ██║╚██████╗   ██║   ███████╗██║  ██║
--╚═╝  ╚═══╝╚══════╝ ╚══╝╚══╝      ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝


--This function is triggered after you create a NEW character.
function CharacterHasLoaded_NEW(charid_1, charid_2)
    InitializeESX(charid_1, charid_2)

    while not PlayerLoaded do Wait(0) end
    ResetPlayerState()
    SetCoords(Config.DefaultSpawn)

    if GetResourceState('cd_identity') == 'started' then
        TriggerEvent('cd_identity:OpenIdentityUI', charid_1)
    else
        if Config.SkinScript == 'esx_skin' then
            TriggerEvent('skinchanger:loadDefaultModel', true)
            TriggerEvent('skinchanger:ResetPlayerSkin')
            TriggerEvent('esx_skin:openSaveableMenu')

        elseif Config.SkinScript == 'cui_character' then
            TriggerEvent('cui_character:SetPedClothes_multi', true)

        elseif Config.SkinScript == 'betrayed_clothing_1' or Config.SkinScript == 'betrayed_clothing_2' then
            TriggerServerEvent('clothing:checkIfNew')
            --TriggerServerEvent('clothing:checkIfNew') --You may need to try each of these. Not sure which will work for your skin script version.

        elseif Config.SkinScript == 'other' then
            --Add your own code here.

        end
    end
    ------------------------------------------------------------------------------------------------------
    --Add any additional trigger events here.

    ------------------------------------------------------------------------------------------------------

    --HERE
    --RCORE_TATTOOOS
    --RELOAD AFTER NEW CHARACTER
	TriggerServerEvent('rcore_tattoos:reload')
end
```

### Migration

In case you want to migrate player tattoos from a previous script, check the migration page.

{% content-ref url="/pages/E92jWEec06mtl7o4hupe" %}
[Migration](/paid-resources/rcore_tattoos/installation/migration.md)
{% endcontent-ref %}
