# Conditional Judgment

KaMenu provides a powerful general-purpose conditional system that can be used in the menu's**any text field**and**action list**to dynamically display different content or perform different actions based on player state.

***

## Supported locations

Conditional checks can be used in all of the following locations:

| Location                      | Description                                                                                    |
| ----------------------------- | ---------------------------------------------------------------------------------------------- |
| `Title`                       | Menu title                                                                                     |
| `Body.*.text`                 | Body component text                                                                            |
| `Body.*.name` / `Body.*.lore` | Item component name and lore                                                                   |
| `Body.*.type`                 | Component type (used to conditionally hide components)                                         |
| `Inputs.*.text`               | Input component label text                                                                     |
| `Bottom.*.text`               | All button text                                                                                |
| `Bottom.*.actions`            | Button action list (executes conditional branches)                                             |
| `Events.*`                    | Menu event action list ([see the event system for details](/plugins/kamenu-en/menu/events.md)) |

***

## Text field conditional checks

### Syntax

```yaml
Field name:
  - condition: "condition expression"
    allow: 'value when condition is met'
    deny: 'value when condition is not met'
```

### Example

**Menu title:**

```yaml
Title:
  - condition: "%player_is_op% == true"
    allow: '&8» &4&lAdmin Panel &8«'
    deny: '&8» &6&lPlayer Panel &8«'
```

**Input component label:**

```yaml
Inputs:
  amount:
    type: 'slider'
    text:
      - condition: "%player_level% >= 10"
        allow: '&6VIP purchase amount (max 64)'
        deny: '&7Purchase amount (max 16)'
    min: 1
    max:
      - condition: "%player_level% >= 10"
        allow: '64'
        deny: '16'
```

**Button text:**

```yaml
Bottom:
  type: 'confirmation'
  confirm:
    text:
      - condition: "%player_level% >= 10"
        allow: '&6[ VIP Confirm ]'
        deny: '&a[ Confirm ]'
```

***

## Action list conditional checks

In the `actions` list, you can nest conditions to enable branching execution:

### Syntax

```yaml
actions:
  - condition: "condition expression"
    allow:
      - 'action 1 to execute when condition is met'
      - 'action 2 to execute when condition is met'
    deny:
      - 'action 1 to execute when condition is not met'
      - 'action 2 to execute when condition is not met'
```

`deny` is optional; if not provided, nothing will be executed when the condition is not met.

### Mixed use

You can mix normal actions and conditional actions in the same `actions` list:

```yaml
actions:
  - 'sound: ui.button.click'           # Always execute
  - condition: "%player_balance% >= 100"
    allow:
      - 'console: eco take %player_name% 100'
      - 'tell: &aDeduction successful!'
    deny:
      - 'tell: &cInsufficient balance!'
  - 'close'                             # Always execute
```

***

## Condition expression syntax

### Comparison operators

| Operator | Description              | Example                        |
| -------- | ------------------------ | ------------------------------ |
| `==`     | Equal to                 | `%player_name% == Steve`       |
| `!=`     | Not equal to             | `%world_name% != world_nether` |
| `>`      | Greater than             | `%player_level% > 10`          |
| `>=`     | Greater than or equal to | `%player_health% >= 10`        |
| `<`      | Less than                | `%player_food_level% < 18`     |
| `<=`     | Less than or equal to    | `%player_exp% <= 100`          |

**Note:**

* String comparisons (`==` and `!=`) are default**case-insensitive**
* Strings that cannot be converted to numbers are treated as `0` in numerical comparisons

### Logical operators

| Operator | Description                   | Priority |
| -------- | ----------------------------- | -------- |
| `&&`     | Logical AND                   | High     |
| `\|\|`   | Logical OR                    | Low      |
| `()`     | Parentheses (change priority) | Highest  |

**Short-circuit evaluation is supported:**

* `||`: when the first condition is `true` , subsequent conditions are not evaluated
* `&&`: when the first condition is `false` , subsequent conditions are not evaluated

### Expression examples

```yaml
# Single condition
- condition: "%player_level% >= 10"

# AND condition
- condition: "%player_level% >= 10 && %player_level% < 20"

# OR condition
- condition: "%player_is_op% == true || %player_level% >= 20"

# Using parentheses
- condition: "(%player_level% >= 5 && %player_level% <= 10) || %player_is_op% == true"
```

***

## Built-in condition methods

KaMenu provides some built-in condition-check methods, invoked using `.` syntax.

### Syntax

```
method.value    # Positive check
!method.value   # Negative check
```

### Supported methods

| Method         | Description                                                                               | Positive example                   | Negative example                            |
| -------------- | ----------------------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------- |
| `isNum`        | Checks whether it is a number (integer or decimal)                                        | `isNum.$(amount)`                  | `!isNum.$(amount)`                          |
| `isPosNum`     | Checks whether it is a positive number (greater than 0)                                   | `isPosNum.{data:price}`            | `!isPosNum.{data:price}`                    |
| `isInt`        | Checks whether it is an integer                                                           | `isInt.$(count)`                   | `!isInt.$(count)`                           |
| `isPosInt`     | Checks whether it is a positive integer (greater than 0)                                  | `isPosInt.$(amount)`               | `!isPosInt.$(amount)`                       |
| `hasPerm`      | Checks whether the player has a permission                                                | `hasPerm.kamenu.admin`             | `!hasPerm.kamenu.admin`                     |
| `hasMoney`     | Checks whether the player has enough money                                                | `hasMoney.100`                     | `!hasMoney.100`                             |
| `hasItem`      | Checks whether the player's inventory contains items of the specified material and amount | `hasItem.[mats=DIAMOND;amount=10]` | `!hasItem.hasItem.[mats=DIAMOND;amount=10]` |
| `hasStockItem` | Checks whether the player's inventory has stock items                                     | `hasStockItem.Mysterious Fruit;16` | `!hasStockItem.Mysterious Fruit;16`         |

**For detailed usage of item checks, see** [**hasItem and hasStockItem condition methods**](/plugins/kamenu-en/menu/conditions/conditions_item.md) **.**

### Usage examples

**Check whether the input value is an integer:**

```yaml
actions:
  - condition: "isInt.$(amount)"
    allow:
      - 'tell: &aThe input value is an integer: $(amount)'
    deny:
      - 'tell: &cPlease enter a valid integer!'
```

**Check whether it is a positive integer:**

```yaml
actions:
  - condition: "isPosInt.$(amount)"
    allow:
      - 'tell: &aValid positive integer: $(amount)'
    deny:
      - 'tell: &cPlease enter an integer greater than 0!'
```

**Check whether the player has enough money:**

```yaml
actions:
  - condition: "hasMoney.100"
    allow:
      - 'console: eco take %player_name% 100'
      - 'tell: &aPurchase successful!'
    deny:
      - 'tell: &cInsufficient balance, need 100 coins'
```

**Permission check (positive):**

```yaml
Bottom:
  confirm:
    text: 'Admin operation'
    actions:
      - condition: "hasPerm.kamenu.admin"
        allow:
          - 'open: admin_panel'
        deny:
          - 'tell: &cYou do not have permission to perform this action!'
```

**Permission check (negative - execute when no permission):**

```yaml
Bottom:
  confirm:
    text: 'Admin operation'
    actions:
      - condition: "!hasPerm.kamenu.admin"
        allow:
          - 'tell: &cYou do not have permission!'
```

**Check whether the player has 10 diamonds:**

```yaml
actions:
  - condition: "hasItem.[mats=DIAMOND;amount=10]"
    allow:
      - 'tell: &aYou have enough diamonds!'
    deny:
      - 'tell: &cYou need 10 diamonds!'
```

**Check whether the player has 16 mysterious fruits:**

```yaml
actions:
  - condition: "hasStockItem.Mysterious Fruit;16"
    allow:
      - 'tell: &aYou have enough mysterious fruits!'
    deny:
      - 'tell: &cYou need 16 mysterious fruits!'
```

***

## Variable support

The following variable formats are supported in condition expressions:

| Variable format | Description                                                                                           | Example                 |
| --------------- | ----------------------------------------------------------------------------------------------------- | ----------------------- |
| `%papi_var%`    | PlaceholderAPI variable                                                                               | `%player_level%`        |
| `{data:key}`    | Player personal data (persistent)                                                                     | `{data:vip_level}`      |
| `{gdata:key}`   | Global shared data (persistent)                                                                       | `{gdata:server_status}` |
| `{meta:key}`    | Player metadata (in-memory cache)                                                                     | `{meta:last_visit}`     |
| `$(key)`        | Dialog input variable (supported only in actions and Inputs areas,**not supported in the Body area**) | `$(amount)`             |

**Special note for the Body area:**

* Text in the Body area is rendered before dialog and button input, so**input variables are not supported** `$(key)` Input variables
* The Body area supports `{data:key}`and`{gdata:key}` and `{meta:key}` built-in variables
* The Inputs and Actions areas support all variable formats

**Metadata notes:**

* Metadata is stored only in memory and is not persisted to the database
* When a player leaves, that player's metadata is automatically cleared
* All metadata is cleared when the plugin is reloaded or the server shuts down
* Suitable for scenarios that require temporary data storage for a short period

***

## Complete example

### Example 1: VIP level check

```yaml
Bottom:
  type: 'notice'
  confirm:
    text: '&aClaim daily reward'
    actions:
      - condition: "%player_level% >= 10"
        allow:
          - 'console: give %player_name% diamond 5'
          - 'tell: &a&lVIP Reward: &f5 diamonds'
          - 'title: title=&6Claimed successfully;subtitle=&fVIP exclusive reward;in=5;keep=40;out=10'
        deny:
          - 'console: give %player_name% dirt 1'
          - 'tell: &7Normal reward: 1 block of dirt'
          - 'tell: &eReach level 10 to claim the VIP reward!'
```

### Example 2: Admin operation

```yaml
Bottom:
  type: 'multi'
  columns: 2
  buttons:
    admin_panel:
      text:
        - condition: "%player_is_op% == true"
          allow: '&4[ Admin Panel ]'
          deny: '&8[ Locked ]'
      actions:
        - condition: "%player_is_op% == true"
          allow:
            - 'open: admin/tools'
          deny:
            - 'tell: &cYou do not have permission to access the admin panel!'
```

### Example 3: Balance check

```yaml
actions:
  - condition: "hasMoney.1000"
    allow:
      - 'console: eco take %player_name% 1000'
      - 'tell: &aPurchase successful! 1000 coins deducted'
      - 'sound: entity.player.levelup'
    deny:
      - 'tell: &cInsufficient balance! Need 1000 coins'
      - 'tell: &7Current balance: &f%player_balance%'
      - 'sound: block.note_block.bass'
```

### Example 4: Complex multiple conditions

```yaml
actions:
  - condition: "(%player_level% >= 5 && %player_level% <= 10) || %player_is_op% == true"
    allow:
      - 'tell: &aCondition passed: you are a level 5-10 player, or you are an admin'
    deny:
      - 'tell: &cConditions not met'
```

### Example 5: Metadata state check

```yaml
actions:
  - condition: "{meta:temp_status} != null"
    allow:
      - 'tell: &aTemporary status exists: {meta:temp_status}'
    deny:
      - 'tell: &7No temporary status set'
  - 'set-meta: last_action clicked'
```

### Example 6: Combining metadata and conditions

```yaml
actions:
  # Set temporary status
  - 'set-meta: temp_user true'

  - condition: "{meta:temp_user} == true"
    allow:
      - 'tell: &aMarked as temporary user'
      - 'open: temp_menu'
    deny:
      - 'tell: &cNot marked as temporary user'
```

### Example 7: Validate input using built-in methods

```yaml
Inputs:
  amount:
    type: 'input'
    text: 'Please enter a quantity (positive integer)'

actions:
  - condition: "isPosInt.$(amount)"
    allow:
      - 'tell: &aValid input: $(amount)'
      - 'set-meta: purchase_amount $(amount)'
    deny:
      - 'tell: &cPlease enter an integer greater than 0!'
      - 'close'
```

### Example 8: Reverse permission check (prompt when no permission)

```yaml
Bottom:
  confirm:
    text: 'Buy VIP'
    actions:
      # Prompt when no permission (reverse check)
      - condition: "!hasPerm.vip.purchase"
        allow:
          - 'tell: &cYou need the vip.purchase permission to perform this action!'
        deny: []

      # Execute purchase logic when permitted
      - condition: "hasPerm.vip.purchase"
        allow:
          - 'console: eco give %player_name% 1000'
          - 'tell: &a1000 coins have been granted as a VIP reward!'
```

***

## Notes

1. **PAPI dependency**: using `%papi_var%` variables in the format requires the PlaceholderAPI plugin to be installed
2. **Numeric conversion**: strings that cannot be converted to numbers are treated as`>`and`<` in numeric comparisons ( `0`
3. **Case-insensitive**:`==` and `!=` operators are case-insensitive when comparing strings
4. **deny can be omitted**: in action conditions, the `deny` field is optional; in text field conditions, `deny` it is recommended to fill it in to avoid blank display
5. **Nested parentheses**: supports multi-level nested parentheses to build complex logical expressions
6. **Data persistence**:
   * `{data:key}` and `{gdata:key}` Stored in the database and persisted
   * `{meta:key}` Stored only in memory, automatically cleared when the player leaves or the plugin reloads
   * Use `{meta:key} != null` to check whether metadata exists
7. **Built-in method format**:
   * Use `method.value` format, such as `isInt.$(amount)`
   * Supports reverse checks, using the `!` prefix, such as `!hasPerm.kamenu.admin`
   * Reverse checks are suitable for scenarios where actions need to be executed when conditions are not met

***

## Related documentation

* [🍉 hasItem and hasStockItem condition methods](/plugins/kamenu-en/menu/conditions/conditions_item.md) - Learn the detailed usage of item checks
* [⚙️ Events](/plugins/kamenu-en/menu/events.md) - Learn the detailed usage of the event system
* [🤖 Actions](/plugins/kamenu-en/menu/actions.md) - Learn all available action types
* [💾 Data storage](/plugins/kamenu-en/data/storage.md) - Learn about data storage and variable usage

***

## Demo menu

The plugin includes a demo menu for conditional checks, which can be opened with the following command:

```
/km open example/actions_demo
```


---

# Agent Instructions: 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:

```
GET https://katacr.gitbook.io/plugins/kamenu-en/menu/conditions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
