> For the complete documentation index, see [llms.txt](https://airdevelopment.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://airdevelopment.gitbook.io/docs/aircore/configuration/modules/placeholders.md).

# Placeholders

## General

Every placeholder is registered under the `aircore` identifier:

```
%aircore_key_<name>[_arg1][_arg2]...%
```

Trailing underscore-separated segments after the name are passed in as arguments, in order. See Arguments.

### Creating your own file

Files can be split across `/placeholders/` subdirectories (e.g. `/placeholders/staff/tags.yml`). Everything defined in split files is merged into the same list at startup. Keys must be unique across **all** files.

```yaml
placeholders:
  rank_color:
    ...
```

## Configuration

### Entries

Every placeholder resolves through an `entries` list, checked **top to bottom**. The first entry whose `conditions` all pass wins. An entry with no `conditions` key always passes. Put one last as the fallback.

```yaml
rank_color:
  entries:
    - conditions:
        - "%luckperms_primary_group_name% == 'owner'"
      output: "<dark_red>"
    - conditions:
        - "%luckperms_primary_group_name% == 'admin'"
      output: "<dark_purple>"
    - output: "<gray>"
```

### Conditions

Every entry in the list must pass for the block to be considered satisfied.

```yaml
conditions:
  - "%player_health% >= 10"
  - "%player_gamemode% == SURVIVAL"
```

Conditions are evaluated as strings. See [Conditions](/docs/global-features/conditions.md) for more information.

### Arguments

Declared under `args`, with an optional `default`. Args are bound to names in the order they're passed, and referenced directly by that name in `conditions`/`output`.

```yaml
kit_cooldown:
  args:
    - name: kit
      default: "0"
  entries:
    - conditions:
        - "%aircore_kit_cooldown_remaining_%kit%% <= 0"
      output: "<green>Ready"
    - output: "<yellow>%aircore_kit_cooldown_remaining_%kit%%"
```

`%aircore_key_kit_cooldown_starter%` binds `kit` to `starter`. If the arg is omitted (`%aircore_key_kit_cooldown%`), `default` is used instead.

### **Cache**

```yaml
cache: 5    # seconds; 0 = always evaluate fresh
```

Caches the resolved output per player (and per arg combination, if the placeholder takes args) for the given number of seconds. Useful for anything polled frequently, like scoreboards or tab list. Omit to always evaluate fresh.

### Entry types

Each entry produces its result with exactly **one** of the following:

| Type     | Description                                    |
| -------- | ---------------------------------------------- |
| `output` | Static or placeholder-interpolated string.     |
| `math`   | Numeric expression (`+ - * /` ).               |
| `bar`    | Progress bar rendered from a current/max pair. |
| `random` | Weighted random pick between several outputs.  |

{% tabs %}
{% tab title="output" %}

```yaml
output: "<yellow>Hello, %player_name%!"
```

{% endtab %}

{% tab title="math" %}

```yaml
kd_ratio:
  entries:
    - conditions:
        - "%statistic_deaths% == 0"
      output: "0.00"
    - math: "%statistic_player_kills% / %statistic_deaths%"
      transform:
        - number-format: "0.00"
```

{% endtab %}

{% tab title="bar" %}

```yaml
health_bar:
  entries:
    - bar:
        current: "%player_health%"
        max: "%player_max_health%"
        segments: 10
        filled-char: "❤"
        empty-char: "♡"
        filled-color: "<red>"
        empty-color: "<dark_gray>"
```

{% endtab %}

{% tab title="random" %}

<pre class="language-yaml"><code class="lang-yaml"><strong>login_greeting:
</strong>  entries:
    - random:
        - weight: 1
          output: "&#x3C;green>Welcome back, &#x3C;white>%player_name%&#x3C;green>!"
        - weight: 1
          output: "&#x3C;aqua>Good to see you, &#x3C;white>%player_name%&#x3C;aqua>."
        - weight: 1
          output: "&#x3C;yellow>The server got better the moment you joined."
        - weight: 2
          conditions:
            - "%luckperms_primary_group_name% == 'vip'"
          output: "&#x3C;gold>Welcome back, VIP &#x3C;white>%player_name%&#x3C;gold>!"
        - weight: 1
          conditions:
            - "%aircore_player_login_streak% >= 7"
          output: "&#x3C;aqua>7-day streak! Welcome back, &#x3C;white>%player_name%&#x3C;aqua>."
</code></pre>

{% endtab %}
{% endtabs %}

#### Transform

Applied after `output`/`math`/`bar` resolves, in the order listed. Each step is its own list entry:

```yaml
transform:
  - trim
  - truncate: 40
```

| Step                                   | Description                                                   |
| -------------------------------------- | ------------------------------------------------------------- |
| `uppercase`                            | Converts the resolved value to uppercase.                     |
| `lowercase`                            | Converts the resolved value to lowercase.                     |
| `capitalize`                           | Capitalizes the first letter.                                 |
| `trim`                                 | Strips leading/trailing whitespace.                           |
| `truncate: <length>`                   | Hard-caps the value to `<length>` characters.                 |
| `truncate:` `length: 10` `suffix: "…"` | Same as above, with a suffix appended when truncated.         |
| `replace: ["<old>", "<new>"]`          | Replaces the first match of `<old>` with `<new>`.             |
| `number-format: "<pattern>"`           | Formats a numeric value using a Java `DecimalFormat` pattern. |

## Examples

{% tabs %}
{% tab title="First Tab" %}
**Rank color**

```yaml
rank_color:
  cache: 5
  entries:
    - conditions:
        - "%luckperms_primary_group_name% == 'owner'"
      output: "<dark_red>"
    - conditions:
        - "%luckperms_primary_group_name% == 'admin'"
      output: "<dark_purple>"
    - conditions:
        - "%vault_eco_balance% >= 100000"
      output: "<gold>"
    - output: "<gray>"
```

{% endtab %}

{% tab title="Example 2" %}
**Kit cooldown, with args**

```yaml
kit_cooldown:
  args:
    - name: kit
      default: "0"
  cache: 1
  entries:
    - conditions:
        - "%aircore_kit_cooldown_remaining_%kit%% <= 0"
      output: "<green>Ready"
    - output: "<yellow>%aircore_kit_cooldown_remaining_%kit%%"
```

{% endtab %}

{% tab title="Example 3" %}
**K/D ratio, using math**

```yaml
kd_ratio:
  cache: 5
  entries:
    - conditions:
        - "%statistic_deaths% == 0"
      output: "0.00"
    - math: "%statistic_player_kills% / %statistic_deaths%"
      transform:
        - number-format: "0.00"
```

{% endtab %}

{% tab title="Example 4" %}
**XP bar, hiding once full**

```yaml
xp_bar:
  cache: 2
  entries:
    - conditions:
        - "%aircore_var_xp% >= 1000"
      output: "<yellow>■■■■■■■■■■"
    - bar:
        current: "%aircore_var_xp%"
        max: "1000"
        segments: 10
        filled-char: "■"
        empty-char: "□"
        filled-color: "<yellow>"
        empty-color: "<dark_gray>"
```

{% endtab %}

{% tab title="Example 5" %}
**Weighted random login greeting**

```yaml
login_greeting:
  sequence: RANDOM
  entries:
    - weight: 1
      output: "<green>Welcome back, <white>%player_name%<green>!"
    - weight: 1
      output: "<aqua>Good to see you, <white>%player_name%<aqua>."
    - weight: 1
      output: "<yellow>The server got better the moment you joined."
    - weight: 2
      conditions:
        - "%luckperms_primary_group_name% == 'vip'"
      output: "<gold>Welcome back, VIP <white>%player_name%<gold>!"
```

{% endtab %}
{% endtabs %}


---

# 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, and the optional `goal` query parameter:

```
GET https://airdevelopment.gitbook.io/docs/aircore/configuration/modules/placeholders.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
