> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dietrich-development.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup

> Install and configure DD Gamemaster - permissions, core settings, catalog data, and localization

## Quickstart

<Steps>
  <Step title="Grant permission to use Gamemaster">
    Add an ACE permission to your server config so your admins can use the tool.

    ```cfg server.cfg theme={null}
    add_ace group.admin dd_gamemaster.admin allow
    add_principal identifier.steam:110000112345678 group.admin
    ```

    <Check>
      Restart the resource and verify that an allowed user can toggle the tool.
    </Check>
  </Step>

  <Step title="Set the command, language, and debug mode">
    Open `config/config.lua` and adjust basic options:

    ```lua config/config.lua theme={null}
    Config.ToggleCommand = 'gm'       -- Type /gm in chat or run gm in console
    Config.Language = 'en'            -- 'en' or 'de' (see config/language.lua)
    Config.Debug = false              -- Set true to see development diagnostics
    ```

    <Tip>
      Check every config file carefully and set them up to your liking.
    </Tip>
  </Step>

  <Step title="Reload and test">
    Reload the resource and toggle the UI to confirm your configuration.

    ```bash Console theme={null}
    restart dd_gamemaster
    ```

    Use default `/gm` or your custom command in-game to open/close the UI.
  </Step>
</Steps>

## Tutorial pages

Control the built-in onboarding/tutorial carousel via `config/tutorial.lua`.

```lua config/tutorial.lua theme={null}
Config.Tutorial = {
  pages = {
    {
      id = 'welcome',
      title = 'Welcome to Gamemaster',
      text = 'Lets take our first steps... ',
      media = 'images/animations/tutorial_opener_short.webp',
      mediaAlt = 'Welcome'
    },
    -- add, remove, or reorder pages freely
  }
}
```

* `id`: stable identifier used internally.
* `title`/`text`: content shown in the UI.
* `media`: optional relative path under `ui/dist/` (WebP, GIF, PNG).
* `mediaAlt`: optional accessible description.

## Core settings

All core settings live in `config/config.lua`.

### General

* **Config.Debug**: Enables verbose logging via `Bridge.Debug(...)`.
* **Config.Language**: Sets UI language. Supported keys match `Language.*` tables in `config/language.lua` (default: `en`, also `de`).
* **Config.ToggleCommand**: Chat/console command to toggle the Gamemaster UI (default: `gm`).
* **Config.stayInvisibleAfterLeavingGm**: If true, you remain invisible after leaving GM mode.

### Camera and movement

* **Config.InitialAltitude**: Starting camera height above ground.
* **Config.MinAltitude / Config.MaxAltitude**: Altitude limits.
* **Config.MoveSpeed**: Base lateral movement speed; combine with sprint multiplier.
* **Config.MoveSpeedSprintMultiplier**: Hold Shift to move faster by this factor.
* **Config.ZoomSpeed**: Mouse wheel zoom speed (height delta).
* **Config.RotateSpeed**: Rotation speed when using arrow keys.
* **Config.MouseRotateSensitivity**: MMB rotation sensitivity.
* **Config.SelectionMaxDistance**: Maximum distance for selectable peds from the camera.

<AccordionGroup>
  <Accordion title="Example camera tuning">
    ```lua config/config.lua theme={null}
    Config.InitialAltitude = 25.0
    Config.MinAltitude = 2.0
    Config.MaxAltitude = 150.0
    Config.MoveSpeed = 12.0
    Config.MoveSpeedSprintMultiplier = 4.0
    Config.ZoomSpeed = 6.0
    Config.RotateSpeed = 120.0
    Config.MouseRotateSensitivity = 180.0
    Config.SelectionMaxDistance = 350.0
    ```
  </Accordion>
</AccordionGroup>

### Network indicator

Configure the on-screen indicator that shows networked entity usage.

```lua config/config.lua theme={null}
Config.NetworkIndicator = {
  enabled = true,
  maxCapacity = 110,
  Notify = {
    enabled = false, -- enable pop-up warning via your bridge
  },
  thresholds = {
    yellow = 76,
    orange = 91,
    red = 101,
  },
  minVisible = 1,
}
```

<Warning>
  Above \~90 entities you may see performance issues. The hard limit is around 110 on RedM.
</Warning>

#### Notifications

* Enable `Config.NetworkIndicator.Notify.enabled = true` to show a warning when the networked ped count nears or exceeds capacity. This uses `Bridge.notify(...)` and localized strings `NotifyHighNetworkPoolTitle` and `NotifyHighNetworkPoolText` from `config/language.lua`.

### Markers and overlays

Configure selection/destination marker colors, move order indicator style, and optional infrared vision overlay.

```lua config/config.lua theme={null}
Config.DrawMarkers = {
  -- Disable all drawing for clean screenshots
  screenShotMode = false,
  selection = {
    ped = { r = 0, g = 128, b = 255 },
    vehicle = { r = 255, g = 165, b = 0 },
  },
  destination = {
    line = { r = 0, g = 200, b = 0 },
    marker = { r = 0, g = 200, b = 0 },
  },
  moveOrder = {
    -- 'rotate' shows a rotating circle, 'arrow' shows a directional arrow
    type = 'rotate',
  },
  -- Toggle an infrared-style highlight overlay while in GM mode
  InfraredVision = true,
}
```

<Info>
  All colors are RGB integers 0-255. Switch `moveOrder.type` between `rotate` and `arrow` based on preference. Turn on `screenShotMode` to hide markers while capturing footage.
</Info>

### Health bar colors

Tune the gradient and alpha used by the on-entity health bars.

```lua config/config.lua theme={null}
Config.HealthBar = {
  -- Gradient colors
  colorLow = { r = 255, g = 60, b = 60 },
  colorMid = { r = 255, g = 165, b = 0 }, -- optional midpoint; remove to blend low to high
  colorHigh = { r = 51, g = 189, b = 51 },

  -- Background rectangle RGBA
  background = { r = 20, g = 20, b = 20, a = 180 },

  -- Foreground (fill) opacity 0-255
  foregroundAlpha = 230,
}
```

<Tip>
  Lower `foregroundAlpha` for subtler bars; raise `background.a` if the bar is hard to see against bright scenes.
</Tip>

### Permissions and access control

Control who can toggle Gamemaster with a single function.

```lua config/config.lua theme={null}
Config.Permissions = {
  useGameMaster = function(src)
    return IsPlayerAceAllowed(src, "dd_gamemaster.admin")
  end,
}
```

<Tabs>
  <Tab title="ACE-based (recommended)">
    Use server ACE policies so you can manage access without editing code.

    ```cfg server.cfg theme={null}
    add_ace group.admin dd_gamemaster.admin allow
    add_principal identifier.steam:110000112345678 group.admin
    ```
  </Tab>

  <Tab title="Job-based (framework bridge)">
    Gate access by player job using `frameworkBridge` helpers.

    ```lua config/config.lua theme={null}
    Config.Permissions = {
      useGameMaster = function(src)
        return Bridge.getJob(src) == 'police' -- or 'admin'
      end,
    }
    ```
  </Tab>

  <Tab title="Group-based (framework bridge)">
    Use your group system from the bridge.

    ```lua config/config.lua theme={null}
    Config.Permissions = {
      useGameMaster = function(src)
        local groups = Bridge.getGroups(src)
        return groups and groups['gamemaster'] == true
      end,
    }
    ```
  </Tab>
</Tabs>

<Tip>
  You can combine checks (ACE + job + groups) in the same function when needed.
</Tip>

## Data, categories, and items

Customize what appears in the grid UI using `config/data.lua`.

### Categories

Define your high-level categories (order and icon are supported):

```lua config/data.lua theme={null}
Data.categories = {
  { id = 'npcs', label = T('NPCs', 'NPCs'), order = 1, icon = '👥' },
  { id = 'animals', label = T('Animals', 'Animals'), order = 2, icon = '🐾' },
}
```

### Custom items

Add curated NPCs or animals you want to highlight. You only need `id`, `name`, `type`, and `model`. Optional fields include `image`, `tags`, `condition`, and `variants` (for grouped horses).

```lua config/data.lua theme={null}
Data.items = {
  -- NPC example
  { id = 'sheriff_johnson', name = 'Sheriff Johnson', type = 'npc', model = 'CS_LawCarl',
    image = 'images/items/sheriff.webp', tags = { 'lawman', 'authority' }, condition = 'isAdmin' },

  -- Animal example
  { id = 'outlaw_wolf', name = 'Wolf', type = 'animal', model = 'A_C_Wolf',
    tags = { 'animal', 'dangerous' }, condition = 'anyone' },
}
```

<Tip>
  `label = T('SomeKey', 'Fallback')` uses the active language from `config/language.lua` with a safe fallback.
</Tip>

### Conditions

Gating logic lives in `Data.conditions`. Reference by string from an item's `condition` field.

```lua config/data.lua theme={null}
Data.conditions = {
  anyone = function()
    return true
  end,
  isAdmin = function()
    local player = Bridge.getPlayerData(source)
    return player.job == 'admin'
  end,
}
```

Define as many as you need and reuse them across items.

### Default favorites

Seed the 1-9 favorites bar for first-time users with `Data.defaultFavorites`. Values are item ids or `nil`.

```lua config/data.lua theme={null}
Data.defaultFavorites = {
  'sheriff_johnson', -- 1
  nil,               -- 2
  'outlaw_wolf',     -- 3
  nil, nil, nil, nil, nil, nil
}
```

If server-side favorites are present, they override these defaults after character selection.

### Horse mount models

The list `Data.horseMountModels` powers the "Spawn on Horse" option with valid horse models. You can add or remove entries safely.

```lua config/data.lua theme={null}
Data.horseMountModels = {
  'A_C_Horse_Arabian_Black',
  'A_C_Horse_Turkoman_Gold',
}
```

### Generated items

`config/data_items_generated.lua` contains a large, generated list of NPCs and animals. The UI automatically merges it with your `Data.items` while avoiding duplicates and grouping horse variants by breed.

<Warning>
  Avoid manual edits to `config/data_items_generated.lua` as it is intended to be machine-generated and may be replaced by updates.
</Warning>

## Item images and file paths

Items display an image in the grid. You can either point to a custom image on disk or rely on the script's default naming rules.

### Where images live

Images are served from the resource UI:

```text theme={null}
ui/dist/images/items/
```

Place WebP images in that folder. The `fxmanifest.lua` already exposes this path to the game UI.

### How the path is chosen

* If you set `image` on an item, that path is used as-is.
* If you do not set `image`, the script builds a filename from the item id or model:
  * For custom items in `config/data.lua`: `images/items/<id>.webp`
  * For generated items in `config/data_items_generated.lua`: `images/items/<sanitized_model>.webp`

<Info>
  Sanitized model means lowercase, spaces to `_`, and only letters, numbers, and `_`. For example `A_C_Horse_Turkoman_Gold` becomes `a_c_horse_turkoman_gold.webp`.
</Info>

### Adding custom images

<Steps>
  <Step title="Pick a filename that matches the item">
    For a custom item with `id = 'sheriff_johnson'`, create `ui/dist/images/items/sheriff_johnson.webp`.
  </Step>

  <Step title="Override the image path if needed">
    You can point to a different file by setting `image` on the item.

    ```lua config/data.lua theme={null}
    { id = 'sheriff_johnson', name = 'Sheriff Johnson', type = 'npc', model = 'CS_LawCarl',
      image = 'images/items/special_sheriff.webp', tags = { 'lawman' }, condition = 'anyone' }
    ```
  </Step>

  <Step title="Provide images for generated models you care about">
    For generated items, drop files named after the sanitized model:

    ```text theme={null}
    ui/dist/images/items/a_c_wolf.webp
    ui/dist/images/items/a_c_bear_black.webp
    ui/dist/images/items/cs_lawcarl.webp
    ```

    You don't need to cover every model. The UI can still show items without custom images.
  </Step>
</Steps>

<Tip>
  Use WebP format to keep file sizes small and loading fast. Recommended resolution is around 256-512 px on the short edge.
</Tip>

## Language and localization

Localize all UI strings in `config/language.lua`. Two languages ship by default: English (`Language.en`) and German (`Language.de`).

* **Change active language** by setting `Config.Language = 'en'` or `Config.Language = 'de'` in `config/config.lua`.
* **Edit text** by changing values inside the language tables. Keep keys stable across languages.

```lua config/language.lua theme={null}
Language.en["SearchItemsPlaceholder"] = "Search items... (Ctrl+F)"
Language.de["SearchItemsPlaceholder"] = "Elemente suchen... (Strg+F)"
```

<Tip>
  Respect placeholders like `{name}`, `{slot}`, `{count}` when translating. They are replaced at runtime.
</Tip>

## Testing and troubleshooting

* **Toggle command not working**: Confirm your permission function returns `true` for your account. In ACE mode, verify your identifiers and group mapping.
* **UI shows no items**: Ensure `config/data_items_generated.lua` is loaded in `fxmanifest.lua` (it is by default) and that `Data.items` merges correctly. Use `Config.Debug = true` and `Bridge.Debug(...)` to inspect.
* **Network indicator missing**: Check `Config.NetworkIndicator.enabled = true` and that your entity counts exceed `minVisible`.
* **Animations not playing**: Verify the `dict` and `name` pair exists in RedM; test with a simpler known animation first.

<Check>
  When everything is configured, `/gm` should open the UI, items should load, and context menu actions should work according to your permissions.
</Check>

## Reference snippets

### Minimal working configuration

```lua config/config.lua theme={null}
Config.Debug = false
Config.Language = 'en'
Config.ToggleCommand = 'gm'

Config.NetworkIndicator = {
  enabled = true,
  maxCapacity = 110,
  thresholds = { yellow = 76, orange = 91, red = 101 },
  minVisible = 1,
}

Config.Permissions = {
  useGameMaster = function(src)
    return IsPlayerAceAllowed(src, 'dd_gamemaster.admin')
  end,
}
```

### Example custom items with a guard

```lua config/data.lua theme={null}
Data.conditions.isGM = function()
  return Bridge.hasGroup and Bridge.hasGroup(source, 'gamemaster')
end

Data.items = {
  { id = 'gm_only_deer', name = 'Deer', type = 'animal', model = 'A_C_Deer_01', condition = 'isGM' },
}
```

<Info>
  If your bridge exposes different helpers, adapt the examples accordingly (e.g., `Bridge.getGroups`, `Bridge.getJob`, `Bridge.getPlayerData`).
</Info>
