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

# Installation

## **1. Add Safe Items to Core**

Add the following entries to:

**`core > shared.gta5.lua`**\
These define the usable safe items and their metadata.

```lua
["largesafe"] = {
    ["label"] = "Large Safe",
    ["weight"] = 30000,
    ["type"] = "item",
    ["image"] = "largesafe.webp",
    ["unique"] = true,
    ["stackable"] = true,
    ["useable"] = true,
    ["shouldClose"] = true,
    ["description"] = "What am I gonna store here..",
    ["metadata"] = {
        password = 0,
        stashId = 0,
        destroyed = 0
    }
},

["smallsafe"] = {
    ["label"] = "Small Safe",
    ["weight"] = 30000,
    ["type"] = "item",
    ["image"] = "smallsafe.webp",
    ["unique"] = true,
    ["stackable"] = true,
    ["useable"] = true,
    ["shouldClose"] = true,
    ["description"] = "What am I gonna store here..",
    ["metadata"] = {
        password = 0,
        stashId = 0,
        destroyed = 0
    }
},
```

Be sure to also add both included `.webp` images to your inventory image folder.

***

## **2. Add Interaction Types to Core Game**

Add the following to:

**`core_game > config.lua > Config.InteractionTypes`**\
These define how the safes behave when placed or interacted with.

```lua
['largesafe'] = {
    PromptName = 'Large Safe',
    PromptDescription = 'What can I store here?...',
    PromptIcon = 'fa-solid fa-vault',
    PromptComplete = function(objConf, obj)
        TaskTurnPedToFaceEntity(playerPedId, obj, 2000, 0.0, 0.0, 0.0)
        Citizen.Wait(250)
        TriggerEvent('client:playersafes:getSafe', source)
    end,
    Object = `m23_2_prop_m32_safe_01a`,
    UseItemMetadata = true,
    InteractDist = 1.3,
    ReturnItem = 'largesafe',
    StoreMetadataOnReturn = true,
    Offset = vector4(0.0, 0.0, -1.0, 0.0),
    LimitUse = false,
},

['smallsafe'] = {
    PromptName = 'Small Safe',
    PromptDescription = 'What can I store here?...',
    PromptIcon = 'fa-solid fa-vault',
    PromptComplete = function(objConf, obj)
        TaskTurnPedToFaceEntity(playerPedId, obj, 2000, 0.0, 0.0, 0.0)
        Citizen.Wait(250)
        TriggerEvent('client:playersafes:getSafe', source)
    end,
    Object = `prop_ld_int_safe_01`,
    UseItemMetadata = true,
    InteractDist = 1.3,
    ReturnItem = 'smallsafe',
    StoreMetadataOnReturn = true,
    Offset = vector4(0.0, 0.0, -1.0, 0.0),
    LimitUse = false,
},
```

This enables the pickup system and returns safes to the player with metadata preserved.

***

## **3. Add Radial Menu Option**

Add the following entry to:

**`radialmenu > config.lua > newSubMenus`**

```lua
['general:pickupPlayerSafe'] = {
    title = 'Pickup Safe',
    icon = 'vault',
    iconCategory = 'solid',
    functionName = 'playersafes:client:pickupClosestSafe',
    enableMenu = function()
        return not isDead and (
            exports['core_game']:CanPickupInteractionObject('smallsafe')
            or exports['core_game']:CanPickupInteractionObject('largesafe')
        )
    end,
},
```

Then **add `'general:pickupPlayerSafe'`** to your **general rootMenuConfig** to make it appear in the radial menu.

***

## **4. Ensure the Resource**

If needed by your server structure, add this line to your:

```
server.cfg / resources.cfg
```

```
ensure playersafes
```

***

## **5. Configure the Script**

Open the script’s `config.lua` and adjust to your liking.

All safes use metadata, allowing each placed safe to be fully persistent and unique.

***

## **🎉 Installation Complete**

Once installed:

* Players can place **Small** and **Large** Safes as world objects
* Safe metadata (password, stashId, destroyed state) persists
* Safes can be picked up using the **radial menu**
* Core interactions will handle storing and retrieving safes correctly


---

# 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.gunchi.dev/scripts/player-safes/installation.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.
