# Configuration

This guide covers all configuration options available in InfinityUI.

### ⚠️ IMPORTANT THING TO KNOW:

Renaming the resource can cause some parts of the code to break, do not do it !

## 📄 Configuration File Structure

Your `config.lua` should look like this:

```lua
InfinityUIConfig = {}

-- Audio Settings
-- Enable/Disable all menu sounds
InfinityUIConfig.EnableSounds = false

-- Navigation & Search
-- Text shown in the quick jump dialog
InfinityUIConfig.JumpDialog = {
    Title = "Go to Button",
    Label = "Button number (1 - %d)", -- %d will be replaced by max buttons
    Placeholder = ""
}

-- Text shown in the search dialog
InfinityUIConfig.SearchDialog = {
    Title = "Filter",
    Label = "Search",
    Description = "Enter text to search (leave empty to reset)",
    Placeholder = ""
}

-- Key mapping to jump to button number
-- Default: "RSHIFT" (Right Shift)
InfinityUIConfig.JumpToKey = "RSHIFT"

-- Configure the command 
-- and the text shown in the player mapping settings
InfinityUIConfig.MappingSettings = {
    Command = "infinityui_jump_to",
    Description = "Menu: Jump to a button (Number)"
}

-- Controls
InfinityUIConfig.ControllerSupport = true

-- Performance
InfinityUIConfig.Debug = false

-- Framework Integration
InfinityUIConfig.CoreResource = "core"

-- Custom Functions
function InfinityUIConfig.GetPlayerMenuSide() ... end
function InfinityUIConfig.PlaySound(audioName, audioRef) ... end
```

***

## 🔊 Audio Settings

### EnableSounds

**Type:** `boolean`\
**Default:** `false`\
**Description:** Enable or disable all menu sounds.

```lua
InfinityUIConfig.EnableSounds = true  -- Sounds ON
InfinityUIConfig.EnableSounds = false -- Sounds OFF (silent)
```

{% hint style="info" %}
Players can toggle sounds in-game if you implement a settings menu!
{% endhint %}

***

## 🔍 Navigation & Search

### SearchKey

**Type:** `string`\
**Default:** `"RSHIFT"`\
**Description:** Keyboard key to open the search dialog.

```lua
InfinityUIConfig.SearchKey = "RSHIFT"  -- Right Shift
InfinityUIConfig.SearchKey = "F3"      -- F3 key
InfinityUIConfig.SearchKey = "LCONTROL" -- Left Control
```

**Common Key Codes:**

* `RSHIFT` - Right Shift
* `LSHIFT` - Left Shift
* `RCONTROL` / `LCONTROL` - Control keys
* `F1` through `F12` - Function keys
* `TAB` - Tab key

***

### JumpToKey

**Type:** `string`\
**Default:** `"RSHIFT"`\
**Description:** Key to trigger the jump-to-item dialog.

```lua
InfinityUIConfig.JumpToKey = "RSHIFT" -- Same as search
```

{% hint style="info" %}
Usually set to the same key as `SearchKey` for consistency.
{% endhint %}

***

## 💬 Dialog Text Configuration

### JumpDialog

**Type:** `table`\
**Description:** Text displayed in the jump-to-item dialog.

```lua
InfinityUIConfig.JumpDialog = {
    Title = "Go to Button",
    Label = "Button number (1 - %d)",  -- %d = max number
    Placeholder = ""
}
```

**Multi-language Example:**

```lua
-- French
InfinityUIConfig.JumpDialog = {
    Title = "Aller au bouton",
    Label = "Numéro du bouton (1 - %d)",
    Placeholder = ""
}

-- Spanish
InfinityUIConfig.JumpDialog = {
    Title = "Ir al botón",
    Label = "Número del botón (1 - %d)",
    Placeholder = ""
}
```

***

### SearchDialog

**Type:** `table`\
**Description:** Text displayed in the search dialog.

```lua
InfinityUIConfig.SearchDialog = {
    Title = "Filter",
    Label = "Search",
    Description = "Enter text to search (empty to reset)",
    Placeholder = ""
}
```

**Multi-language Example:**

```lua
-- French
InfinityUIConfig.SearchDialog = {
    Title = "Filtrer",
    Label = "Recherche",
    Description = "Entrez un texte à rechercher (vide pour réinitialiser)",
    Placeholder = ""
}
```

***

### MappingSettings

**Type:** `table`\
**Description:** Command name and description for key mapping.

```lua
InfinityUIConfig.MappingSettings = {
    Command = "infinityui_jump_to",
    Description = "Menu: Jump to a button (Number)"
}
```

{% hint style="warning" %}
**Important:** The `Command` must be unique! Don't conflict with other resources.
{% endhint %}

***

## 🎮 Control Settings

### ControllerSupport

**Type:** `boolean`\
**Default:** `true`\
**Description:** Enable gamepad/controller support.

```lua
InfinityUIConfig.ControllerSupport = true  -- Controller enabled
InfinityUIConfig.ControllerSupport = false -- Disabled
```

***

## ⚡ Performance Settings

### Debug

**Type:** `boolean`\
**Default:** `false`\
**Description:** Enable debug mode (shows console messages).

```lua
InfinityUIConfig.Debug = false -- Production (no debug)
InfinityUIConfig.Debug = true  -- Development (debug logs)
```

{% hint style="warning" %}
**Keep this `false` in production!** Debug mode creates a lot of console spam.
{% endhint %}

***

## 🔧 Framework Integration

### CoreResource

**Type:** `string`\
**Default:** `"core"`\
**Description:** Name of your core/framework resource.

```lua
InfinityUIConfig.CoreResource = "es_extended"  -- ESX
InfinityUIConfig.CoreResource = "qb-core"      -- QBCore
InfinityUIConfig.CoreResource = "core"         -- Custom
```

This is used by `GetPlayerMenuSide()` to access exports.

***

## 🎯 Custom Functions

### GetPlayerMenuSide()

**Description:** Returns the player's preferred menu side.

**Signature:**

```lua
function InfinityUIConfig.GetPlayerMenuSide() : string
```

**Return:** `"left"` or `"right"`

**Examples:**

#### ESX Implementation

```lua
function InfinityUIConfig.GetPlayerMenuSide()
    local success, side = pcall(function()
        local ESX = exports['es_extended']:getSharedObject()
        local playerData = ESX.GetPlayerData()
        return playerData.menuSide or "left"
    end)
    
    if success and (side == "left" or side == "right") then
        return side
    end
    
    return "left" -- Default fallback
end
```

#### QBCore Implementation

```lua
function InfinityUIConfig.GetPlayerMenuSide()
    local success, side = pcall(function()
        local QBCore = exports['qb-core']:GetCoreObject()
        local PlayerData = QBCore.Functions.GetPlayerData()
        return PlayerData.metadata?.menuSide or "left"
    end)
    
    if success and (side == "left" or side == "right") then
        return side
    end
    
    return "left"
end
```

#### Database Implementation

```lua
function InfinityUIConfig.GetPlayerMenuSide()
    -- Fetch from database or KVP
    local side = GetResourceKvpString("menu_side")
    
    if side == "left" or side == "right" then
        return side
    end
    
    return "left"
end
```

#### Simple Toggle

```lua
-- Let players toggle with a command
local playerMenuSide = "left"

RegisterCommand("togglemenuside", function()
    playerMenuSide = (playerMenuSide == "left") and "right" or "left"
    SetResourceKvp("menu_side", playerMenuSide)
    print("Menu side: " .. playerMenuSide)
end)

function InfinityUIConfig.GetPlayerMenuSide()
    return playerMenuSide
end
```

***

### PlaySound()

**Description:** Plays a menu sound.

**Signature:**

```lua
function InfinityUIConfig.PlaySound(audioName: string, audioRef: string)
```

**Default Implementation:**

```lua
function InfinityUIConfig.PlaySound(audioName, audioRef)
    if InfinityUIConfig.EnableSounds then
        PlaySoundFrontend(-1, audioName, audioRef, 1)
    end
end
```

**Custom Implementation (with Volume):**

```lua
function InfinityUIConfig.PlaySound(audioName, audioRef)
    if InfinityUIConfig.EnableSounds then
        local soundId = GetSoundId()
        PlaySoundFrontend(soundId, audioName, audioRef, 1)
        
        -- Custom volume (0.0 - 1.0)
        SetVariableOnSound(soundId, "Volume", 0.5)
        
        ReleaseSoundId(soundId)
    end
end
```

***

## 📋 Full Configuration Template

Here's a complete, production-ready configuration template:

```lua
--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                   InfinityUI - Configuration                 ║
    ║                       User Configuration                     ║
    ╚══════════════════════════════════════════════════════════════╝
]]

InfinityUIConfig = {}

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                      AUDIO SETTINGS                          ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Enable/Disable all menu sounds
InfinityUIConfig.EnableSounds = false

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                    NAVIGATION AND SEARCH                     ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Text shown in the quick jump dialog
InfinityUIConfig.JumpDialog = {
    Title = "Go to Button",
    Label = "Button number (1 - %d)", -- %d will be replaced by max buttons
    Placeholder = ""
}

-- Text shown in the search dialog
InfinityUIConfig.SearchDialog = {
    Title = "Filter",
    Label = "Search",
    Description = "Enter text to search (leave empty to reset)",
    Placeholder = ""
}

-- Key mapping to jump to button number
-- Default: "RSHIFT" (Right Shift)
InfinityUIConfig.JumpToKey = "RSHIFT"

-- Configure the command 
-- and the text shown in the player mapping settings
InfinityUIConfig.MappingSettings = {
    Command = "infinityui_jump_to",
    Description = "Menu: Jump to a button (Number)"
}

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                    CONTROL SETTINGS                          ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Enable/Disable controller support
InfinityUIConfig.ControllerSupport = true

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                  PERFORMANCE SETTINGS                        ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Enable debug mode (shows debug info)
InfinityUIConfig.Debug = false

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║              SECURITY SETTINGS (IMPORTANT)                   ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Name of your core/framework resource
-- This resource must export the GetMenuSide() function
-- Example: exports["core"]:GetMenuSide() returns "left" or "right"
InfinityUIConfig.CoreResource = "core"

--[[
    ╔══════════════════════════════════════════════════════════════╗
    ║                    CUSTOM FUNCTIONS                          ║
    ╚══════════════════════════════════════════════════════════════╝
]]

-- Function called to get the player's preferred menu side
-- Returns: "left" or "right"
-- This function can be modified to fit your framework
function InfinityUIConfig.GetPlayerMenuSide()
    local success, side = pcall(function()
        return exports[InfinityUIConfig.CoreResource]:GetMenuSide()
    end)
    
    if success and (side == "left" or side == "right") then
        return side
    end
    
    -- Default value if the export fails
    return "left"
end

-- Function called to play a sound
-- Can be modified to use your own sound system
function InfinityUIConfig.PlaySound(audioName, audioRef)
    if InfinityUIConfig.EnableSounds then
        PlaySoundFrontend(-1, audioName, audioRef, 1)
    end
end
```

***

## 🎯 Best Practices

{% stepper %}
{% step %}

### Use the config values (don't hardcode)

```lua
-- ✅ GOOD
if InfinityUIConfig.EnableSounds then
    -- Play sound
end

-- ❌ BAD
if true then -- Hardcoded
    -- Play sound
end
```

{% endstep %}

{% step %}

### Provide fallback values

```lua
-- ✅ GOOD
function InfinityUIConfig.GetPlayerMenuSide()
    local side = GetPlayerPreference()
    
    if side == "left" or side == "right" then
        return side
    end
    
    return "left" -- Always have a fallback!
end

-- ❌ BAD
function InfinityUIConfig.GetPlayerMenuSide()
    return GetPlayerPreference() -- What if this returns nil?
end
```

{% endstep %}

{% step %}

### Test in debug mode during development

```lua
-- During development
InfinityUIConfig.Debug = true

-- In production
InfinityUIConfig.Debug = false
```

{% endstep %}
{% endstepper %}

***

## 🔄 Updating Configuration

{% stepper %}
{% step %}
Restart the resource:

```
restart infinityUI
```

{% endstep %}

{% step %}
Or restart the entire server if using global config.
{% endstep %}

{% step %}
Test in-game to verify changes.
{% endstep %}
{% endstepper %}

***

## ❓ FAQ

<details>

<summary>Q: Can players customize their own settings?</summary>

A: Yes! Implement a settings menu that modifies `InfinityUIConfig` values and saves to database/KVP.

</details>

<details>

<summary>Q: Do I need to restart the server after config changes?</summary>

A: Only restart the resource infinityUI and all the resources using it.

</details>

***

{% hint style="success" %}
**Configuration complete!** Ready to explore the API? Check out the [API Reference](https://infinityui.docs.hibry.net/api-reference)!
{% endhint %}
