> For the complete documentation index, see [llms.txt](https://devmosaic.gitbook.io/devmosaic/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://devmosaic.gitbook.io/devmosaic/resources/devmosaic-dm-hud/extending.md).

# Adding Your Own

Add your own status bars and info chips, from the config or from another resource.

Two things you can add: a **status bar** next to health and armour, or a **chip** in the row next to job and cash.

{% hint style="success" %}
**A radiation bar, in four lines**

`shared/config.lua`

```lua
DashCfg.extras = {
    vitals = {
        {
            id = 'radiation',
            label = 'Radiation',
            colour = '#7cff5a',
            icon = 'fa:radiation',
            get = function() return LocalPlayer.state.radiation or 0 end,
        },
    },
}
```

Restart. It appears with the others, and players can restyle and move it like any built-in bar.
{% endhint %}

## Two ways to add one

<table><thead><tr><th width="200">Way</th><th>Use it when</th></tr></thead><tbody><tr><td><strong>From the config</strong><br><code>DashCfg.extras</code></td><td>The value can be read with a function. Simplest</td></tr><tr><td><strong>From your own script</strong><br><code>registerVital</code> + <code>setVital</code></td><td>Your resource already knows the value and wants to push it</td></tr></tbody></table>

## From the config

### A status bar

```lua
DashCfg.extras = {
    vitals = {
        {
            id = 'radiation',
            label = 'Radiation',
            colour = '#7cff5a',
            icon = 'fa:vials',
            get = function() return LocalPlayer.state.radiation or 100 end,
        },
    },
}
```

| Field         | Required | What it is                                         |
| ------------- | -------- | -------------------------------------------------- |
| `id`          | Yes      | A unique name. Used everywhere else to refer to it |
| `label`       | Yes      | What the player sees                               |
| `colour`      | Yes      | A hex colour                                       |
| `icon`        | Yes      | See [Icons](#icons) below                          |
| `get`         | Yes      | A function returning `0` to `100`                  |
| `min` / `max` | No       | A different scale than 0–100                       |

### A chip

```lua
DashCfg.extras = {
    chips = {
        {
            id = 'crew',
            label = 'Crew',
            colour = '#ffb02e',
            icon = 'gang',
            get = function() return LocalPlayer.state.crew end,
        },
    },
}
```

Same fields, except `get` returns **text** instead of a number. Return `nil` and the chip hides itself.

## From your own script

Register it once, then push values whenever they change. **This is cheaper** — nothing polls.

```lua
CreateThread(function()
    exports['dm-hud']:registerVital({
        id = 'radiation',
        label = 'Radiation',
        colour = '#7cff5a',
        icon = 'fa:radiation',
        value = 0,
    })
end)

RegisterNetEvent('my-script:radiationChanged', function(level)
    exports['dm-hud']:setVital('radiation', level)
end)
```

Chips work the same way:

```lua
exports['dm-hud']:registerChip({
    id = 'crew',
    label = 'Crew',
    colour = '#ffb02e',
    icon = 'users',
    text = 'Alpha',
})

exports['dm-hud']:setChip('crew', { text = 'Bravo' })
```

{% hint style="warning" %}
Register inside a `CreateThread`, or wait for the HUD to start. Registering before it is ready is silently dropped.
{% endhint %}

### Players get a toggle for free

Every chip you register appears in the settings menu under **Player info** with its own on/off switch, labelled with the `label` you gave it. You do not have to build anything — it is there as soon as the chip is registered.

Their answer is saved in `identity.extras`. To have a chip start switched **off**, name it in [`shared/defaults.lua`](/devmosaic/resources/devmosaic-dm-hud/defaults.md):

```lua
identity = {
    extras = { crew = false },
},
```

### Taking one away

```lua
exports['dm-hud']:removeVital('radiation')
exports['dm-hud']:removeChip('crew')
```

## Icons

Three sources, and you do not need to download anything.

{% tabs %}
{% tab title="Lucide" %}
Name any icon from [lucide.dev](https://lucide.dev).

```lua
icon = 'graduation-cap'
icon = 'heart-pulse'
icon = 'users'
```

{% endtab %}

{% tab title="Font Awesome" %}
Any free Font Awesome icon, with a prefix.

```lua
icon = 'fa:radiation'     -- solid
icon = 'far:clock'        -- regular
icon = 'fab:discord'      -- brands
```

{% endtab %}

{% tab title="Your own SVG" %}
Paste the path data and its viewBox.

```lua
path = 'M12 2 L22 20 H2 Z',
viewBox = '0 0 24 24',
fill = true,
```

Set `fill = true` for a solid shape, or leave it off for an outline.
{% endtab %}
{% endtabs %}

## A different scale

A bar assumes `0` to `100`. Give it `min` and `max` for anything else.

```lua
{
    id = 'temperature',
    label = 'Body temp',
    colour = '#ff6b4a',
    icon = 'thermometer',
    min = 30,
    max = 45,
    get = function() return LocalPlayer.state.bodyTemp or 37 end,
}
```

`37` on a 30–45 scale fills the bar just under half way.

## Hiding and locking what you added

Your additions use the id you registered them with, and behave like anything else in [`shared/policy.lua`](/devmosaic/resources/devmosaic-dm-hud/policy-and-locks.md):

```lua
DashPolicy.hidden = {
    'vitals.radiation',
    'info.crew',
}
```

## Worked example: a full resource

```lua
local registered = false

CreateThread(function()
    while GetResourceState('dm-hud') ~= 'started' do Wait(500) end

    exports['dm-hud']:registerVital({
        id = 'radiation',
        label = 'Radiation',
        colour = '#7cff5a',
        icon = 'fa:radiation',
        value = 0,
    })

    exports['dm-hud']:registerChip({
        id = 'crew',
        label = 'Crew',
        colour = '#ffb02e',
        icon = 'users',
    })

    registered = true
end)

RegisterNetEvent('my-script:update', function(rads, crew)
    if not registered then return end

    exports['dm-hud']:setVital('radiation', rads)
    exports['dm-hud']:setChip('crew', { text = crew })
end)

AddEventHandler('onResourceStop', function(name)
    if name ~= GetCurrentResourceName() then return end

    exports['dm-hud']:removeVital('radiation')
    exports['dm-hud']:removeChip('crew')
end)
```

{% hint style="info" %}
The `onResourceStop` cleanup matters during development. Without it, a restarted script leaves a dead bar on screen until the player relogs.
{% endhint %}

## Replacing a built-in feature instead

Adding a bar is not the only option. If you already run a seatbelt, stress or cruise script, hand the built-in one over rather than adding a second:

```lua
DashCfg.providers = {
    stress = {
        get = function() return exports['my-stress']:GetStress() end,
    },
}
```

Details on the [Configuration](/devmosaic/resources/devmosaic-dm-hud/configuration.md#handing-a-feature-to-your-own-script) page.
