> For the complete documentation index, see [llms.txt](https://simple.superiormc.cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simple.superiormc.cn/arcmenu-wiki/menu-configuration/menus/conditions.md).

# Conditions

Conditions determine whether a player may perform a menu operation, such as checking permissions, location or a saved selection. This page covers configuration placement first, followed by expressions and execution order.

Paper, Folia, Leaf and Spigot support conditions, but available actions and placeholders still depend on the platform. Spigot supports permission checks and player name, UUID and coordinate placeholders. Player data, menu arguments and PlaceholderAPI placeholders are unsupported there.

## Configuration levels

| Location                                                      | Scope                             | When it fails              |
| ------------------------------------------------------------- | --------------------------------- | -------------------------- |
| Top-level menu `permission`                                   | Opening the entire menu.          | Menu opening is denied.    |
| `backend` → region name → `condition`                         | All click actions in that region. | Runs the region's `deny`.  |
| Conditional branch within a click type or event → `condition` | Actions within that branch.       | Runs that branch's `deny`. |
| `{condition=...}` inside one action                           | That individual action.           | Skips the action.          |

The top-level `permission` takes a permission node, not a condition expression. It is checked alongside the player's required `arcmenu.use` permission. See [Menu document structure](/arcmenu-wiki/menu-configuration/menus.md#permission). Top-level menu `condition` and `deny` fields are unsupported.

## Region conditions

A region's `condition`, `deny` and `actions` are at the same level. The condition controls every click type in that region.

```yaml
backend:
  vip-area:
    x: 0
    y: 0
    width: 80
    height: 24
    condition: 'perm myserver.menu.vip'
    deny:
      - 'tell: &cYou do not have permission.'
    actions:
      right:
        - 'tell: &aWelcome, VIP!'
      shift-right: close
```

A player without `myserver.menu.vip` receives only the denial message when clicking this region. Shift+right-click will not close the menu either. If `deny` is omitted, a failed condition runs no denial actions.

Region conditions are checked on clicking. They do not hide buttons or tooltips or pass the click to an overlapping region underneath. See [Backend regions and click events](/arcmenu-wiki/menu-configuration/menus/backend.md) for region selection rules.

## Conditional click branches

To restrict only one click type, place a branch beneath that click type. The hierarchy is **region name → `actions` → click type → branch properties**.

```yaml
backend:
  member-area:
    x: 0
    y: 0
    width: 80
    height: 24
    actions:
      right:
        condition: 'perm myserver.menu.member'
        actions:
          - 'tell: &aMember access granted.'
        deny:
          - 'tell: &cMembership is required.'
      shift-right: close
```

The outer `actions` organizes click types; the inner `actions` lists operations to run when the condition passes. This permission check restricts only normal right-clicks. Shift+right-click still closes the menu.

### Branch properties

| Property    | Purpose                                                       | Default behavior                                                          |
| ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `condition` | The branch's expression.                                      | Omission runs `actions` directly.                                         |
| `actions`   | Actions run when the condition passes.                        | None.                                                                     |
| `deny`      | Actions run when the condition fails.                         | None.                                                                     |
| `priority`  | Processing order, using an integer; smaller values run first. | `0` for a single branch; list entries default to `0`, `1`, `2` and so on. |

Each branch needs at least `actions` or `deny`. Do not write `condition` as a YAML list. Combine multiple checks into one expression.

### Multiple branches and execution order

Use a list for several branches within a click type:

```yaml
backend:
  greeting-area:
    x: 0
    y: 0
    width: 80
    height: 24
    actions:
      right:
        - priority: 0
          condition: 'perm myserver.menu.vip'
          actions:
            - 'tell: &aWelcome, VIP!'
            - return
        - priority: 10
          actions:
            - 'tell: &aWelcome!'
```

Branches do not automatically stop at the first passing condition. Each branch is checked in order, running its `actions` on success or its own `deny` on failure. Processing continues to subsequent branches unless an action ends the flow.

The VIP branch in this example uses `return`, so VIP players receive only the dedicated message. Other players continue to the general branch. Removing `return` makes VIP players receive both messages.

Equal priorities follow configuration order. This `priority` controls branches within a single click type. It differs from overlapping region priorities, where larger values win. Click groups such as `all` and `right` still follow their configuration order.

## Conditional event branches

`events.open` and `events.close` accept the same conditional branch structure:

```yaml
events:
  open:
    condition: 'perm myserver.menu.vip'
    actions:
      - 'tell: &aVIP menu greeting.'
    deny:
      - 'tell: &7Menu greeting.'
```

This condition selects the opening message. It does not prevent the menu from opening. Control opening access with the menu's top-level `permission`.

## Individual action conditions

Append `{condition=...}` inside an action string to restrict only that action:

```yaml
backend:
  notice-area:
    x: 0
    y: 0
    width: 80
    height: 24
    actions:
      right:
        - 'tell: &aVIP notice. {condition=perm myserver.menu.vip}'
        - 'sound: UI_BUTTON_CLICK-1-1'
```

Only VIP players receive the message, while every player clicking hears the sound. A failed individual action condition does not trigger the region's or branch's `deny`.

Use a conditional branch for requirements shared by a whole operation. A condition on a payment action does not protect a later unconditional reward action.

## Expression syntax

`condition` must be a string. Keep YAML quotation marks around expressions. Even fixed values use `condition: 'true'` or `condition: 'false'`, rather than YAML booleans.

### Permissions

`perm myserver.menu.vip` checks whether the player has the permission. `permission myserver.menu.vip` is also supported. Supply an actual permission node; the expression does not create groups or grant permissions.

### Numeric and text comparisons

| Expression                           | Meaning                                                          |
| ------------------------------------ | ---------------------------------------------------------------- |
| `%player_y% >= 64`                   | Player Y coordinate is at least `64`.                            |
| `%player_y% > 64`                    | Player Y coordinate exceeds `64`.                                |
| `%player_y% <= 64`                   | Player Y coordinate is at most `64`.                             |
| `%player_y% < 64`                    | Player Y coordinate is below `64`.                               |
| `%player_name% == Alex`              | Player name equals `Alex`.                                       |
| `%player_name% != Alex`              | Player name differs from `Alex`.                                 |
| `%player_name% contains Alex`        | Player name contains `Alex`.                                     |
| `{data:preferred-world} == survival` | Saved world preference is `survival`; Paper-family servers only. |

Placeholders on both sides are expanded first. If both values are numeric, they are compared numerically; otherwise, they are compared as text. Text comparisons ignore case. `is` and `is not` also mean equal and unequal respectively.

Use backticks around comparison values containing spaces, as in `` {data:display-name} == `Survival World` `` . Unset data reads as `null`; `{data:preferred-world} != null` can check whether a value is set.

Verify that numeric placeholders actually return numbers. Unresolved placeholders are not automatically replaced with `0`, and they do not automatically fail the condition. Check balance placeholder output before using it in purchase conditions.

### Combining checks

| Syntax                                                   | Meaning                                    |
| -------------------------------------------------------- | ------------------------------------------ |
| `perm myserver.menu.member && %player_y% >= 64`          | Both conditions must pass.                 |
| `perm myserver.menu.vip \|\| perm myserver.menu.staff`   | Either condition may pass.                 |
| `not (perm myserver.menu.vip)`                           | The player lacks this permission.          |
| `!(perm myserver.menu.vip)`                              | Same as the preceding expression.          |
| `all [perm myserver.menu.member; %player_y% >= 64]`      | Every enclosed condition must pass.        |
| `any [perm myserver.menu.vip; perm myserver.menu.staff]` | At least one enclosed condition must pass. |

`&&` groups more tightly than `||`. Use parentheses to clarify complex expressions. For example, `perm myserver.menu.member && (perm myserver.menu.vip || %player_y% >= 64)` requires membership plus either of the enclosed checks.

The brackets in `all` and `any` are part of the expression text. Quote the entire expression in YAML instead of converting it to a YAML list.

### Testing a placeholder directly

A placeholder returning a truth value can be used directly, for example `condition: '%arcmenu_meta_ready%'`. Values of `true`, `yes`, `on` or any nonzero number pass; other values fail. These words are case-insensitive.

This example uses temporary player data and requires a Paper-family server. Use `==`, `!=` or `contains` to test specific text. Arbitrary nonempty text does not count as a passing result.

## Checking and loading

After `/arcmenu validate` and `/arcmenu reload`, open the menu normally and test both passing and failing cases. Check that:

* Ordinary players get the expected permission results and denial messages.
* Branches use `return` where needed to prevent both dedicated and general operations from running.
* Placeholders return the expected text or numbers, and required plugins are installed.
* The selected platform supports the branch's actions and placeholders.

Preview mode does not execute click actions. Conditions do not automatically undo commands, payments or item operations already performed. See [Advanced actions](/arcmenu-wiki/menu-configuration/menus/advanced-actions.md) for those behaviors.
