# Actions (Actions)

`actions` List of actions performed after a node definition button is clicked. Supports multiple action types, delayed execution, and conditional branches.

***

## Configuration structure

```yaml
Bottom:
  type: 'notice'
  confirm:
    text: '&aConfirm'
    actions:
      - 'tell: &aOperation successful!'
      - 'sound: entity.experience_orb.pickup'
      - 'close'
```

The action list is executed one by one in**order**(`wait` actions can be used to insert delays).

***

## Overview of action types

| Action        | Function description                                                  | Supports target selector |
| ------------- | --------------------------------------------------------------------- | ------------------------ |
| `tell`        | Send a chat message to the player                                     | ✅                        |
| `actionbar`   | Send an action bar message to the player (bottom of the screen)       | ✅                        |
| `title`       | Send a title and subtitle to the player's screen                      | ✅                        |
| `toast`       | Display a Toast notification on the screen                            | ✅                        |
| `hovertext`   | Send a chat message with hover tips and click functionality           | ✅                        |
| `command`     | Make the player execute a command                                     | ✅                        |
| `chat`        | Make the player send a message in the chat box                        | ✅                        |
| `console`     | Execute a command with console permissions                            | ✅                        |
| `server`      | Teleport to the specified server (BungeeCord/Velocity)                | ✅                        |
| `tppos`       | Teleport to the specified coordinates                                 | ✅                        |
| `sound`       | Play a sound at the player's location                                 | ✅                        |
| `money`       | Operate on the player's money (requires Vault)                        | ✅                        |
| `stock-item`  | Store item give/take                                                  | ✅                        |
| `item`        | Item give/take                                                        | ✅                        |
| `open`        | Open another menu for the player                                      | ❌                        |
| `close`       | Close the current menu                                                | ❌                        |
| `force-open`  | Force open the menu (skip Events.Open)                                | ❌                        |
| `force-close` | Force close the menu (skip Events.Close)                              | ❌                        |
| `reset`       | Reopen the current menu (skip Events.Open)                            | ❌                        |
| `url`         | Open the specified link (only works when there is a single action)    | ❌                        |
| `copy`        | Copy text to the clipboard (only works when there is a single action) | ❌                        |
| `data`        | Operate on player data (supports set/add/take/delete)                 | ✅                        |
| `gdata`       | Operate on global data (supports set/add/take/delete)                 | ✅                        |
| `meta`        | Operate on player metadata (supports set/add/take/delete)             | ✅                        |
| `set-data`    | Set player data (legacy format, recommended to use `data`)            | ✅                        |
| `set-gdata`   | Set global data (legacy format, recommended to use `gdata`)           | ✅                        |
| `set-meta`    | Set player metadata (legacy format, recommended to use `meta`)        | ✅                        |
| `js`          | Execute JavaScript code (supports predefined functions)               | ❌                        |
| `actions`     | Execute the action list defined under Events.Click                    | ❌                        |
| `wait`        | Insert a delay before execution                                       | ❌                        |
| `return`      | Interrupt the action execution list                                   | ❌                        |

***

## Target selector

All actions support target selectors, allowing you to specify the target players affected by the action.

**Syntax:** `{player: selector}`

**Usage examples:**

```yaml
# 1. No target specified, sent to the current player (default)
- 'tell: Hello!'

# 2. Send to all online players
- 'tell: Server announcement: the server will restart in 5 minutes!{player: *}'
- 'tell: Hello everyone!{player: *}'

# 3. Use conditional selection (PAPI variables)
- 'tell: Welcome, admin!{player: %player_is_op% == true}'
- 'tell: Players who reached level 10: rewards have been sent!{player: %player_level% >= 10}'

# 4. Complex conditions
- 'tell: VIP player exclusive message{player: hasPerm.user.vip}'
- 'tell: Players with a wallet over 10000{player: %vault_eco_balance% >= 10000}'
```

**Selector types:**

| Selector              | Description                            | Example                          |
| --------------------- | -------------------------------------- | -------------------------------- |
| `{player: *}`         | All online players                     | `{player: *}`                    |
| `{player: all}`       | All online players (same as \*)        | `{player: all}`                  |
| `{player: condition}` | Online players that meet the condition | `{player: %player_level% >= 10}` |

**Conditional expressions:**

The target selector supports all `Condition` supported conditional expressions, including:

* **PAPI variables**:`%player_level%`, `%vault_eco_balance%`
* **comparison operators**:`>`, `>=`, `<`, `<=`, `==`, `!=`, `contains`, `!contains`
* **logical operators**:`&&`(and), `||`(or)
* **parentheses grouping**: used for complex logical expressions

**Condition examples:**

```yaml
# Single condition
{player: %player_level% >= 10}

# Multiple conditions (and)
{player: %player_level% >= 10 && hasPerm.user.vip}

# Multiple conditions (or)
{player: %player_is_op% || hasPerm.user.vip}

# Complex condition
{player: (%player_level% >= 10 && %vault_eco_balance% >= 1000) || %player_is_op% == true}
```

**Performance optimization:**

* ✅ The target player list is dynamically calculated based on conditions
* ✅ Conditional expressions are cached to improve performance
* ✅ A warning log is recorded when no players match

**Notes:**

* ⚠️ `*` and `all` will match all online players, please use with caution
* ⚠️ Variables in conditional expressions are parsed separately for each target player
* ⚠️ Some actions (such as `open`,`close`,`server`) do not support target selectors and will ignore the target parameter

***

## Action types overview

### tell - chat message

Send a chat message to the player.**Full support for all Adventure MiniMessage features**, including colors, gradients, click events, hover events, etc.

**Format:** `tell: <message>`

**Example (Legacy color codes):**

```yaml
- 'tell: &aOperation successful!'
- 'tell: &cOperation failed, please contact an administrator'
- 'tell: &7Current balance: &f%player_balance%'
- 'tell: &eThe content you entered: $(input_key)'
```

**Example (MiniMessage format):**

```yaml
# Basic colors and formatting
- 'tell: <red>Red text</red>'
- 'tell: <bold>Bold</bold> <italic>Italic</italic> <underline>Underline</underline>'
- 'tell: <gradient:red:blue>Blue-red gradient text</gradient>'

# Click events
- 'tell: Click here to run a command: <click:run_command:/say You clicked here!><gold>Click me!</gold></click>'
- 'tell: <click:copy_to_clipboard:Hello KaMenu><gold>Copy this text</gold></click>'
- 'tell: <click:open_url:https://minecraft.wiki><gold>Open Minecraft Wiki</gold></click>'
- 'tell: <click:suggest_command:/gamemode creative><gold>Switch to Creative Mode</gold></click>'

# Hover events
- 'tell: <hover:show_text:"<red>This is hover text<reset>\n<blue>Supports multi-line display"><gold>Hover over me!</gold></hover>'
- 'tell: <hover:show_item:diamond_sword>Display a diamond sword</hover>'
- 'tell: <hover:show_item:diamond><gold>Display a diamond</gold></hover>'

# Combined use (click + hover)
- 'tell: <click:run_command:/say Combined event><hover:show_text:"<green>Click to run command\n<gray>Hover to show tips"><gold>Click and hover</gold></hover></click>'

# Item icons and player heads (1.21.9+)
- 'tell: Look at this <sprite:block/stone> stone'
- 'tell: This is <sprite:items:item/porkchop> pork chop'
- 'tell: This is <head:Notch> Notch's head'
- 'tell: <head:entity/player/wide/steve> Steve's head'

# Other MiniMessage tags
- 'tell: <blue>Key: </blue><key:key.keyboard.b><red>B key</red>'
- 'tell: <blue>Line break test: <newline><red>This is a new line</red></blue>'
- 'tell: <blue>NBT data: </blue><nbt:display.Name></blue>'
```

**Common MiniMessage tags:**

| Tag                    | Description    | Example                                    |
| ---------------------- | -------------- | ------------------------------------------ |
| `<color>`              | Color tag      | `<red>Red</red>`                           |
| `<gradient>`           | Gradient color | `<gradient:red:blue>Gradient</gradient>`   |
| `<bold>`               | Bold           | `<bold>Bold</bold>`                        |
| `<italic>`             | Italic         | `<italic>Italic</italic>`                  |
| `<underline>`          | Underline      | `<underline>Underline</underline>`         |
| `<click:action:value>` | Click event    | `<click:run_command:/say hi>Click</click>` |
| `<hover:action:value>` | Hover event    | `<hover:show_text:Tip>Hover</hover>`       |
| `<newline>`            | Line break     | `Line 1<newline>Line 2`                    |
| `<key:keyname>`        | Key display    | `<key:key.keyboard.b>B key</key>`          |

**Note:**

* Supports mixing Legacy color codes (`&a`,`&c` etc.) with MiniMessage tags
* When MiniMessage tags are detected, Legacy color codes are automatically converted to the corresponding MiniMessage tags
  * For example:`&a` → `<green>`,`&c` → `<red>`,`&l` → `<bold>`
  * Example:`'<gold>&aThis is &cred &lbold text</l>'` will automatically be converted to `'<gold><green>This is <red>red <bold>bold text</bold>'`
* Supports PAPI variables (`%var%`), built-in data variables (`{data:key}`) and input component references (`$(key)`)
* It is recommended to use pure MiniMessage format for the best results and full functionality

***

### actionbar - action bar message

Send an action bar message to the player (displayed above the crosshair at the bottom of the screen).**Full support for all Adventure MiniMessage features**.

**Format:** `actionbar: <message>`

**Example:**

```yaml
# Legacy color codes
- 'actionbar: &aOperation successful!'
- 'actionbar: &7Balance: &f%player_balance%'

# MiniMessage format
- 'actionbar: <green>Operation successful!</green>'
- 'actionbar: <gradient:gold:red>Balance: 1000</gradient>'
- 'actionbar: <hover:show_text:View details><gold>Click to view details</gold></hover>'
```

**Note:** The message stays visible for about 3 seconds before disappearing. Supports the same MiniMessage features as `tell` .

***

### title - title message

Send a title and subtitle to the player’s screen.

**Format:** `title: title=main title;subtitle=subtitle;in=fade in;keep=stay;out=fade out`

**Parameter description:**

| Parameter  | Description     | Unit | Default value |
| ---------- | --------------- | ---- | ------------- |
| `title`    | Main title text | —    | Empty         |
| `subtitle` | Subtitle text   | —    | Empty         |
| `in`       | Fade-in time    | tick | `0`           |
| `keep`     | Stay time       | tick | `60`          |
| `out`      | Fade-out time   | tick | `20`          |

**Example:**

```yaml
- 'title: title=&aOperation successful;subtitle=&7Completed'
- 'title: title=&6Welcome!;subtitle=&fHello, %player_name%;in=10;keep=80;out=20'
```

**Note:** Parameters are separated by semicolons `;` ; supports color codes and variables.

***

### hovertext - clickable chat text

Send a chat message with hover tooltip and click actions.

**Format:** `hovertext: normal text <text=display text;hover=hover text;command=command;url=link;actions=action list name;newline=false> continue text`

**Parameter description:**

| Parameter | Description                                                 | Required |
| --------- | ----------------------------------------------------------- | -------- |
| `text`    | Clickable display text                                      | ✅        |
| `hover`   | Tooltip text shown on mouse hover                           | ❌        |
| `command` | Command executed by the player when clicked                 | ❌        |
| `url`     | Link opened when clicked                                    | ❌        |
| `actions` | Action list executed on click (key name under Events.Click) | ❌        |
| `newline` | Whether to add a line break after the text (`true`/`false`) | ❌        |

**Example:**

```yaml
- 'hovertext: &7Click here <text=&a[Claim Reward];hover=&eClick to claim today’s reward;command=/daily> or come back later.'
- 'hovertext: Visit <text=&b[Website];hover=&7Open the website in your browser;url=https://example.com> to learn more.'
- 'hovertext: <text=&a[Greeting];actions=greet;hover=Click to send a greeting> greet the player'
```

**Using the actions parameter:**

```yaml
Events:
  Click:
    greet:
      - 'tell: &aHello! Welcome to the server.'
      - 'sound: ENTITY_PLAYER_LEVELUP'

Body:
  text:
    type: 'message'
    text: '<text="Click to greet";actions=greet;hover=Click to execute the greet action>'
```

**Click event priority:**

When multiple click parameters exist at the same time, the priority is as follows (from high to low):

1. `actions` - Execute action list
2. `url` - Open link
3. `command` - Execute command

**Note:**

* Parameter values are wrapped in backticks `` ` ``, single quotes `'` or double quotes `"` wrap
* Clickable area uses `< >` wrap
* `actions` The parameter is only valid in the Body.message text component
* When using the `actions` parameter, the text click event will register a ClickCallback, valid for 5 minutes

***

### command - player command

Let the player who clicks the button execute a command.

**Format:** `command: <command>`

**Example:**

```yaml
- 'command: spawn'
- 'command: msg %player_name% Hello'
- 'command: warp hub'
```

**Note:** No need to add `/`before the command; the player needs permission to execute the command.

***

### chat - chat message

Let the player send a message in the chat box.

**Format:** `chat: <message>`

**Example:**

```yaml
- 'chat: /spawn'           # Player sends the /spawn command
- 'chat: Hello everyone!'          # Player sends a chat message
- 'chat: /msg Admin Help me' # Player sends a private message to the admin
- 'chat: $(input_message)'  # Sends the content entered by the player
```

**Difference from command:**

| Action    | Execution method                           | Permission requirement         | Applicable scenario                                                 |
| --------- | ------------------------------------------ | ------------------------------ | ------------------------------------------------------------------- |
| `command` | Directly execute command                   | Requires player permission     | Execute plugin commands (such as `/spawn`)                          |
| `chat`    | Simulate the player typing in the chat box | No special permission required | Send chat messages, execute commands that require player permission |

**Use cases:**

* Need to display a message in the chat box for the player (such as broadcasts or shouts)
* Execute commands that require the player to type in the chat box
* Interact with other players or plugins

**Note:** The message will be broadcast for online players to see; supports color codes, PAPI variables, and input component references.

***

### console - console command

Execute a command as the console (OP privileges).

**Format:** `console: <command>`

**Example:**

```yaml
- 'console: give %player_name% diamond 64'
- 'console: eco give %player_name% 1000'
- 'console: lp user %player_name% group add vip'
```

**Note:** No player permission required; no need to add `/`before the command; supports PAPI variables.

***

### server - send to specified server

Teleport the player to the specified server (supports proxy plugins such as BungeeCord or Velocity).

**Format:** `server: <server name>`

**Example:**

```yaml
- 'server: lobby'
- 'server: survival'
- 'server: creative'
```

**How it works:**

This action will automatically choose the transfer method based on the `config.yml` in the `bungeecord` configuration:

| Configuration       | Transfer method                    | Advantages                                                                        |
| ------------------- | ---------------------------------- | --------------------------------------------------------------------------------- |
| `bungeecord: true`  | BungeeCord plugin messaging system | <p>✅ No player permission required<br>✅ More reliable<br>✅ Better performance</p> |
| `bungeecord: false` | Execute `/server` command          | ⚠️ Player needs `/server` command permission                                      |

**Use cases:**

* BungeeCord/Velocity network servers
* Teleporting between multiple servers
* Lobby/main menu selects different game modes

**Note:**

* BungeeCord mode requires use with a proxy plugin
* The server name must be defined in the proxy plugin configuration
* The player will immediately disconnect from the current server and connect to the target server
* Supports variables and condition checks
* Recommended to enable in a BungeeCord network `bungeecord: true`

**Use with variables:**

```yaml
# Teleport to different servers based on player selection
- 'server: $(server_name)'

# Use the server name from data storage
- 'server: {data:favorite_server}'
```

**Advanced example - conditional teleport:**

```yaml
Events:
  Click:
    # Player selects a server
    select_server:
      - condition: '{data:last_server} == survival'
        allow:
          - 'server: survival'
          - 'tell: &aConnecting to the survival server...'
        deny:
          - 'server: lobby'
          - 'tell: &aConnecting to the lobby...'
```

***

### tppos - teleport to specified coordinates

Teleport the player to the specified coordinates.

**Format:** `tppos: <world name>,<x>,<y>,<z>[,<yaw>,<pitch>]`

**Parameter description:**

| Parameter  | Description             | Required                                      |
| ---------- | ----------------------- | --------------------------------------------- |
| World name | Target world name       | ✅                                             |
| x          | X coordinate            | ✅                                             |
| y          | Y coordinate            | ✅                                             |
| z          | Z coordinate            | ✅                                             |
| yaw        | Horizontal facing angle | ❌ (default: keep the player's current facing) |
| pitch      | Vertical facing angle   | ❌ (default: keep the player's current facing) |

**Example:**

```yaml
# Coordinates only, keep current facing
- 'tppos: world,100,64,200'

# Full coordinates + facing
- 'tppos: world,100,64,200,90,0'

# Use with variables
- 'tppos: {data:target_world},{data:target_x},{data:target_y},{data:target_z}'
```

**Note:** The world name must exist; if it does not exist, teleportation will not be executed.

***

### sound - Play sound

Play a sound at the player's location, supporting volume, pitch, and sound category.

**Format:** `sound: <sound name>;volume=volume;pitch=pitch;category=category`

**Parameter description:**

| Parameter  | Description                                       | Default value |
| ---------- | ------------------------------------------------- | ------------- |
| Sound name | Minecraft sound ID (use `_` or `.` both are fine) | —             |
| `volume`   | Volume (float)                                    | `1.0`         |
| `pitch`    | Pitch (float)                                     | `1.0`         |
| `category` | Sound category                                    | `master`      |

**Optional sound categories:**

| Value     | Description      |
| --------- | ---------------- |
| `master`  | Master volume    |
| `music`   | Music            |
| `record`  | Jukebox          |
| `weather` | Weather          |
| `block`   | Blocks           |
| `hostile` | Hostile mobs     |
| `neutral` | Neutral mobs     |
| `player`  | Player           |
| `ambient` | Ambient sound    |
| `voice`   | Voice            |
| `ui`      | UI sound effects |

**Example:**

```yaml
- 'sound: entity.experience_orb.pickup'
- 'sound: entity.player.levelup;volume=1.5;pitch=1.2'
- 'sound: block.note_block.pling;volume=1.0;pitch=2.0;category=ui'
```

***

### open - Open menu

Open another menu for the player; the current menu will automatically close.

**Format:** `open: <menu ID>`

**Example:**

```yaml
- 'open: main_menu'
- 'open: shop/weapons'
- 'open: admin/tools'
```

**Note:** Menu ID rules are the same as `/km open` command; subfolders are separated by `/` and do not include the `.yml` extension.

***

### close - Close menu

Close the currently open menu (**the Events.Close event will be executed first**).

**Format:** `close`

**Example:**

```yaml
- 'tell: &cGoodbye!'
- 'close'
```

***

### force-open - Force open menu

Force open the specified menu for the player,**skipping the target menu's Events.Open action list**. The difference from `open` action is that it will not trigger the target menu's open event.

**Format:** `force-open: <menu ID>`

**Example:**

```yaml
# Normal open (executes the target menu's Open event)
- 'open: shop'

# Force open (skip Open event)
- 'force-open: shop'
```

**Use cases:**

* Use when you need to open a menu but do not want to trigger the initialization logic in the Open event
* Avoid executing the Open event repeatedly when opening a menu nested within Events.Click

***

### force-close - Force close menu

Force close the current menu,**without executing the Events.Close action list**.

**Format:** `force-close`

**Example:**

```yaml
- 'force-close'
```

**Use cases:**

* Use when you need to close the menu immediately without triggering cleanup/logging logic in the Close event

***

### reset - Reopen current menu

Reopen the current menu (equivalent to refresh),**without executing the Events.Open action list**.

**Format:** `reset`

**Example:**

```yaml
# Refresh current menu
- 'reset'
```

**Use cases:**

* Refresh the current menu content (for example, updated variable displays)
* Reset button state

***

### url - Open link

Open the specified URL (only works when this is the button's only action).

**Format:** `url: <link address>`

**Example:**

```yaml
actions:
  - 'url: https://github.com/Katacr/KaMenu'
```

{% hint style="info" %}
`url` and `copy` The action is a static action,**and will only take effect when it is the only action in the button's actions list**. If you need to open a link while executing other actions, use the `hovertext` action.
{% endhint %}

***

### copy - Copy to clipboard

Copy the specified text to the player's clipboard (only works when this is the button's only action).

**Format:** `copy: <text>`

**Example:**

```yaml
actions:
  - 'copy: play.example.com'
```

***

### set-data - Set player data (legacy format)

Save a key-value pair to the current player's persistent data.

**Format:** `set-data: <key> <value>`

**Example:**

```yaml
- 'set-data: language zh_CN'
- 'set-data: nickname $(player_nickname)'
- 'set-data: score %player_level%'
```

**Read method:** Use `{data:key}` or the PAPI variable `%kamenu_data_key%`.

{% hint style="warning" %}
This is the legacy format,**it is recommended to use the new `data` Action**which supports more operation types (add/take/delete).
{% endhint %}

***

### set-gdata - Set global data (legacy format)

Save a key-value pair to global data (shared by all players).

**Format:** `set-gdata: <key> <value>`

**Example:**

```yaml
- 'set-gdata: server_status open'
- 'set-gdata: event_winner %player_name%'
```

**Read method:** Use `{gdata:key}` or the PAPI variable `%kamenu_gdata_key%`.

{% hint style="warning" %}
This is the legacy format,**it is recommended to use the new `gdata` Action**which supports more operation types (add/take/delete).
{% endhint %}

***

### set-meta - Set player metadata (legacy format)

Save a key-value pair to the player's metadata (memory cache, no persistence required).

**Format:** `set-meta: <key> <value>`

**Example:**

```yaml
- 'set-meta: time 19:02'
- 'set-meta: nickname $(player_nickname)'
- 'set-meta: last_menu shop/weapons'
```

**Read method:** Use `{meta:key}` or the PAPI variable `%kamenu_meta_key%`.

{% hint style="warning" %}
This is the legacy format,**it is recommended to use the new `meta` Action**which supports more operation types (add/take/delete).
{% endhint %}

**Note:**

* Metadata is stored only in memory and is not persisted to the database
* Player metadata is automatically cleared when the player logs out
* All metadata is cleared when the plugin reloads or the server shuts down
* Suitable for scenarios that require short-term temporary data storage

***

### data - Player data operations

Operate on a player's persistent data, supporting setting, adding, subtracting, and deleting numeric values.

**Format:** `data: type=operation type;key=key name;var=value`

**Parameter description:**

| Parameter | Description                                  | Required |
| --------- | -------------------------------------------- | -------- |
| `type`    | Operation type                               | ✅        |
| `key`     | Data key name                                | ✅        |
| `var`     | Value (required only when type=set/add/take) | ❌        |

**Type optional values:**

* `set`: Set value
* `add`: Increase value (valid only when the value is a number)
* `take`: Decrease value (valid only when the value is a number)
* `delete`: Delete this key-value pair

**Example:**

```yaml
# Set text value
- 'data: type=set;key=test;var=`Hello, my world`'

# Set numeric value
- 'data: type=set;key=num;var=`100`'

# Increase numeric value
- 'data: type=add;key=num;var=`10`'

# Decrease numeric value
- 'data: type=take;key=num;var=`10`'

# Delete data
- 'data: type=delete;key=num'
```

**Read method:** Use `{data:key}` or the PAPI variable `%kamenu_data_key%`.

**Note:**

* `add` and `take` During operation, if the current value or the specified value is not a number, the operation will fail and a warning will be output in the console
* `delete` During operation, if the key does not exist, the operation will fail silently (no error)
* Legacy format `set-data: <key> <value>` Still available, but the new format is recommended

***

### gdata - Global data operations

Operate on global data (shared by all players), supporting setting, adding, subtracting, and deleting numeric values.

**Format:** `gdata: type=operation type;key=key name;var=value`

**Parameter description:**

| Parameter | Description                                  | Required |
| --------- | -------------------------------------------- | -------- |
| `type`    | Operation type                               | ✅        |
| `key`     | Data key name                                | ✅        |
| `var`     | Value (required only when type=set/add/take) | ❌        |

**Type optional values:**

* `set`: Set value
* `add`: Increase value (valid only when the value is a number)
* `take`: Decrease value (valid only when the value is a number)
* `delete`: Delete this key-value pair

**Example:**

```yaml
# Set global data
- 'gdata: type=set;key=total;var=`1000`'

# Increase value
- 'gdata: type=add;key=total;var=`50`'

# Decrease value
- 'gdata: type=take;key=total;var=`20`'

# Delete data
- 'gdata: type=delete;key=total'
```

**Read method:** Use `{gdata:key}` or the PAPI variable `%kamenu_gdata_key%`.

**Note:**

* Global data is shared among all players
* `add` and `take` During operation, if the current value or the specified value is not a number, the operation will fail and a warning will be output in the console
* `delete` During operation, if the key does not exist, the operation will fail silently (no error)
* Legacy format `set-gdata: <key> <value>` Still available, but the new format is recommended

***

### meta - Player metadata operations

Operate on player metadata (memory cache), supporting setting, adding, subtracting, and deleting numeric values.

**Format:** `meta: type=operation type;key=key name;var=value`

**Parameter description:**

| Parameter | Description                                  | Required |
| --------- | -------------------------------------------- | -------- |
| `type`    | Operation type                               | ✅        |
| `key`     | Data key name                                | ✅        |
| `var`     | Value (required only when type=set/add/take) | ❌        |

**Type optional values:**

* `set`: Set value
* `add`: Increase value (valid only when the value is a number)
* `take`: Decrease value (valid only when the value is a number)
* `delete`: Delete this key-value pair

**Example:**

```yaml
# Set metadata
- 'meta: type=set;key=level;var=`10`'

# Increase value
- 'meta: type=add;key=level;var=`1`'

# Decrease value
- 'meta: type=take;key=level;var=`1`'

# Delete data
- 'meta: type=delete;key=level'
```

**Read method:** Use `{meta:key}` or the PAPI variable `%kamenu_meta_key%`.

**Note:**

* Metadata is stored only in memory and is not persisted to the database
* Player metadata is automatically cleared when the player logs out
* All metadata is cleared when the plugin reloads or the server shuts down
* `add` and `take` During operation, if the current value or the specified value is not a number, the operation will fail and a warning will be output in the console
* `delete` During operation, if the key does not exist, the operation will fail silently (no error)
* Legacy format `set-meta: <key> <value>` Still available, but the new format is recommended

***

### toast - Toast notification

Display a Toast notification in the top-right corner of the screen.

**Format:** `toast: type=type;icon=item ID;msg=title`

**Parameter description:**

| Parameter | Description       | Default value |
| --------- | ----------------- | ------------- |
| `type`    | Notification type | `task`        |
| `icon`    | Displayed item ID | `paper`       |
| `msg`     | Content text      | Empty         |

**Type optional values:**

* `task`: Title text:`Progress achieved!`(default)
* `goal`: Title text:`Goal achieved!`
* `challenge`: Title text:`Challenge completed!`(sound effect will play)

**Example:**

```yaml
- 'toast: msg=&fYou got a diamond sword;icon=diamond_sword'
- 'toast: type=challenge;msg=&fCongratulations on completing the challenge!;icon=diamond'
- 'toast: type=goal;msg=&fGoal achieved;icon=gold_ingot'
```

**Note:** Toast notifications automatically disappear after about 3 seconds on the screen.

***

### money - Money operations

Operate on a player's money (requires the Vault economy plugin).

**Format:** `money: type=operation type;num=amount`

**Parameter description:**

| Parameter | Description    | Optional values                   |
| --------- | -------------- | --------------------------------- |
| `type`    | Operation type | The following are optional values |
| `num`     | Amount         | Numeric value (supports decimals) |

**Type optional values:**

* `add`: Give the specified amount to the player
* `take`: Deduct the specified amount from the player
* `reset`: Set the player's balance to the specified amount

**Example:**

```yaml
# Give the player 100 coins
- 'money: type=add;num=100'

# Deduct 50 coins from the player
- 'money: type=take;num=50'

# Set the player's balance to 1000 coins
- 'money: type=reset;num=1000'

# Use with conditional judgment
- condition: "%player_balance% >= 500"
  allow:
    - 'money: type=take;num=500'
    - 'tell: &aPurchase successful!'
  deny:
    - 'tell: &cInsufficient balance! Need 500 coins'
```

**Note:**

* Requires the Vault economy plugin to use
* **This action will not send any message to the player**, the player must judge and prompt on their own (for example, using `tell` or conditional judgment)
* `take` The operation will check the balance; if the balance is insufficient, the deduction will not be executed, and only a warning will be printed in the console
* Amounts support decimals, such as 1.5, 0.99, etc.
* Amounts can use variables, such as `%player_level%` or `{data:price}`

***

### stock-item - Give/take items

Give the player or remove a specified quantity of database items from the player's inventory.

**Format:** `stock-item: type=operation type;name=item name;amount=quantity`

**Parameter description:**

| Parameter | Description            | Required       |
| --------- | ---------------------- | -------------- |
| `type`    | Operation type         | ✅              |
| `name`    | Item name (saved item) | ✅              |
| `amount`  | Quantity               | ❌ (default: 1) |

**Type optional values:**

* `give`: Give items to the player
* `take`: Remove items from the player's inventory

**Example:**

```yaml
# Give the player 16 mysterious fruits
- 'stock-item: type=give;name=神秘果;amount=16'

# Remove 16 mysterious fruits from the player's inventory
- 'stock-item: type=take;name=神秘果;amount=16'

# Use with conditional judgment
- condition: "hasStockItem.神秘果;16"
  allow:
    - 'stock-item: type=take;name=神秘果;amount=16'
    - 'tell: &aPurchase successful!'
  deny:
    - 'tell: &cNot enough items! Need 16 mysterious fruits'
```

**Note:**

* Items must be saved through `/km item save` command before they can be used
* `give` If the player's inventory is full during the operation, any remaining items will automatically drop at the player's location and will not be lost
* `take` The operation will iterate through all inventory slots of the player (including main inventory, armor slots, off-hand slot, and main hand slot)
* Item comparison uses `ItemStack.isSimilar()` method, ignoring item quantity differences
* Supports variable replacement, such as `name=$(item_name)` or `amount={data:price}`

***

### item - Give/take normal items

Give the player or remove a specified type of normal item from the player's inventory.

**Format:**

* `item: type=give;mats=material;amount=quantity`
* `item: type=take;mats=material;amount=quantity;lore=description;model=model`

**Parameter description:**

| Parameter | Description                                           | Required       |
| --------- | ----------------------------------------------------- | -------------- |
| `type`    | Operation type (give/take)                            | ✅              |
| `mats`    | Item material (Material ID)                           | ✅              |
| `amount`  | Quantity                                              | ❌ (default: 1) |
| `lore`    | Description (only used for take operations, optional) | ❌              |
| `model`   | Item model (only used for take operations, optional)  | ❌              |

**Type optional values:**

* `give`: Give items to the player (ignores lore and model parameters)
* `take`: Remove items from the player's inventory (supports lore and model checks)

**Example:**

```yaml
# Give the player 10 diamonds
- 'item: type=give;mats=DIAMOND;amount=10'

# Remove 10 diamonds from the player's inventory
- 'item: type=take;mats=DIAMOND;amount=10'

# Remove items with the specified lore
- 'item: type=take;mats=DIAMOND;amount=10;lore=Forging material'

# Remove items with the specified model (such as Oraxen items)
- 'item: type=take;mats=DIAMOND;amount=10;model=oraxen:mana_crystal'

# Specify both lore and model
- 'item: type=take;mats=DIAMOND;amount=10;lore=Forging material;model=oraxen:mana_crystal'

# Use with conditional judgment
- condition: "hasItem.[mats=DIAMOND;amount=10]"
  allow:
    - 'item: type=take;mats=DIAMOND;amount=10'
    - 'tell: &aRemoved successfully!'
  deny:
    - 'tell: &cNot enough items! Need 10 diamonds'
```

**Note:**

* `mats` Use Minecraft's native material IDs for parameters (such as `DIAMOND`,`IRON_INGOT` etc.)
* `give` During operation,`lore` and `model` parameters will be ignored, because these two parameters are only used for checking
* `give` If the player's inventory is full during the operation, any remaining items will automatically drop at the player's location and will not be lost
* `take` During operation:
  * If `lore`is specified, only items whose lore contains the specified string will be deducted (case-insensitive)
  * If `model`will only deduct items matching the specified item model
  * If both `lore` and `model`and
  * `model` are specified, the item must satisfy both conditions to be deducted `The format is`namespace:key `(for example,`,`oraxen:mana_crystal`)
* `take` The operation will iterate through all inventory slots of the player (including main inventory, armor slots, off-hand slot, and main hand slot)
* Supports variable replacement, such as `minecraft:diamond`,`amount={data:price}`,`mats=$(material)`

***

### lore={data:item\_desc}

wait - Delay execution

**Format:** `Insert a delay into the action list; subsequent actions will be executed after waiting the specified time.`

**Unit:** Minecraft tick (1 tick = 0.05 seconds, 20 ticks = 1 second)

**Example:**

```yaml
- 'tell: &aStarting countdown...'
- 'wait: 20'            # wait 1 second
- 'tell: &e3...'
- 'wait: 20'
- 'tell: &e2...'
- 'wait: 20'
- 'tell: &e1...'
- 'wait: 20'
- 'title: title=&cGo!;in=5;keep=30;out=10'
```

**Note:** `wait` Only affects the actions**after**it; it will not block other tasks currently executing.

***

### return - Interrupt execution

Insert an interruption into the action list; subsequent actions will not be executed.

**Format:** `return`

**Example:**

```yaml
- 'tell: You clicked this button'
- 'return'            # execution interruption
- 'tell: You will never see this message.'  # subsequent actions will not execute
```

```yaml
- 'tell: &aStarting countdown...'
- 'wait: 20'            # wait 1 second
- 'tell: &e3...'
- 'wait: 20'
- 'tell: &e2...'
- 'wait: 20'
- 'tell: &e1...'
- 'wait: 20'
- condition: '%player_is_online% == false'
  allow:
    - 'tell: &cPlayer offline detected, operation interrupted!'
    - 'return'   # execution interruption
- 'tell: &aYou have completed the operation.' # if the condition is met, this action will not be executed
```

**Note:** `wait` Only affects the actions**after**it; it will not block other tasks currently executing.

***

### js - Execute JavaScript code

Execute JavaScript code, supporting direct execution of code or calling predefined functions.

**Format:** `js: <JavaScript code>`

**Usage:**

1. **Directly execute JavaScript code**

```yaml
actions:
  - 'js: player.sendMessage("Hello from JavaScript!");'
  - 'js: var random = Math.floor(Math.random() * 100);'
  - 'js: player.sendMessage("Random number: " + random);'
```

2. **Call predefined function (no parameters)**

```yaml
JavaScript:
  show_health: |
    var health = player.getHealth();
    var maxHealth = player.getMaxHealth();
    player.sendMessage("§eHealth: §f" + health + "/" + maxHealth);

Bottom:
  type: 'notice'
  confirm:
    text: '&aView health'
    actions:
      - 'js: [show_health]'
```

3. **Call predefined function (with parameters)**

```yaml
JavaScript:
  process_data: |
    var playerName = args[0];
    var playerLevel = args[1];
    var money = args[2];

    player.sendMessage("§aPlayer: §f" + playerName);
    player.sendMessage("§aLevel: §f" + playerLevel);
    player.sendMessage("§aMoney: §f" + money);

Bottom:
  type: 'notice'
  confirm:
    text: '&eProcess data'
    actions:
      - 'js: [process_data] %player_name% $(level) {data:money}'
```

**Supported variables:**

* `player` - Current player object
* `uuid` - Player UUID string
* `name` - Player name
* `location` - Player location
* `inventory` - Player inventory
* `world` - World where the player is located
* `server` - Server instance
* `args` - Argument array of the predefined function (available only when calling a predefined function)

**Supported parameter types (for predefined functions):**

* String: passed directly
* PAPI variable:`%player_name%`
* Player data:`{data:money}`
* Global data:`{gdata:config}`
* Input box variables:`$(input1)`
* Number:`50`, `3.14`

{% hint style="info" %}
JavaScript is very powerful and supports access to the Bukkit API, mathematical calculations, conditional judgments, and more. For more details about JavaScript features, please see [🔧 JavaScript Features](/plugins/kamenu-en/menu/javascript.md) documentation.
{% endhint %}

**Note:**

* JavaScript code is executed on the server side
* Predefined functions must be in the menu's `JavaScript` Defined in the node
* Parameters are separated by spaces; parameters cannot contain spaces
* The Nashorn engine is based on the ECMAScript 5.1 standard and does not support ES6+ syntax

***

### actions - list of actions to execute

Execute `Events.Click` The list of actions defined below. This allows you to reuse predefined action lists within actions, avoiding duplicate code.

**Format:** `actions: <action list name>`

**Parameter description:**

| Parameter        | Description                                      | Example                              |
| ---------------- | ------------------------------------------------ | ------------------------------------ |
| Action list name | `Events.Click` Key name of the action list under | `greet`, `vip_check`, `daily_reward` |

**Example:**

```yaml
Events:
  Click:
    greet:
      - 'tell: &aHello! Welcome to the server.'
      - 'sound: ENTITY_PLAYER_LEVELUP'

    vip_check:
      - condition: 'hasPerm.essentials.vip'
        allow:
          - 'tell: &aVIP-exclusive welcome!'
          - 'sound: ENTITY_EXPERIENCE_ORB_PICKUP'
        deny:
          - 'tell: &cYou need VIP permission'

Bottom:
  type: 'multi'
  buttons:
    btn_greet:
      text: 'Greeting'
      actions:
        - 'actions: greet'  # execute Events.Click.greet

    btn_vip:
      text: 'VIP Check'
      actions:
        - 'actions: vip_check'  # execute Events.Click.vip_check
```

**Example of a complex action chain:**

```yaml
Events:
  Click:
    daily_login:
      - 'tell: &6Daily check-in successful!'
      - 'sound: ENTITY_PLAYER_LEVELUP'
      - 'set-data: coins +100'
      - 'tell: &eReceived 100 coins'
      - 'sound: ENTITY_EXPERIENCE_ORB_PICKUP'

Bottom:
  type: 'multi'
  buttons:
    daily:
      text: 'Daily Check-in'
      actions:
        - 'actions: daily_login'
```

**Features:**

1. **Asynchronous execution**:`actions` Actions are executed in an asynchronous thread and will not block the main thread
2. **Conditional judgment supported**: referenced action lists can use `condition` for conditional branching
3. **Variable support**: action lists support all KaMenu variables (`{data:xxx}`, `{gdata:xxx}` etc.)
4. **Code reuse**: avoid repeatedly defining the same action sequence in multiple buttons

**Error handling:**

If the referenced action list does not exist, the player will receive an error message:

```
&cError: action list 'xxx' not found
```

**Compared with other methods:**

| Method                             | Usage location                | Trigger method                 | Example                        |
| ---------------------------------- | ----------------------------- | ------------------------------ | ------------------------------ |
| `actions` Action                   | Button actions, commands      | Click button / execute command | `actions: greet`               |
| `<text>` tag's `actions` Parameter | text component (Body.message) | Click text                     | `<text='Click';actions=greet>` |

**Use cases:**

* **Button reuse action list**: multiple buttons execute the same action sequence
* **Conditional branching**: execute different actions based on player status
* **Command shortcut**: trigger predefined action lists through commands
* **Action chain reuse**: avoid repeatedly defining complex action sequences

**Notes:**

1. The action list must be defined in `Events.Click` under
2. Avoid circular references (e.g., action list A references itself)
3. `actions` Actions themselves can also be used in conditional judgments

***

## Complete example

```yaml
Bottom:
  type: 'multi'
  columns: 2
  buttons:
    purchase:
      text: '&6[ Purchase ]'
      actions:
        - condition: "%player_balance% >= 500"
          allow:
            - 'console: eco take %player_name% 500'
            - 'console: give %player_name% diamond_sword 1'
            - 'tell: &aPurchase successful! Spent 500 coins'
            - 'sound: entity.player.levelup'
            - 'close'
          deny:
            - 'tell: &cInsufficient balance! Need 500 coins, current: %player_balance%'
            - 'sound: block.note_block.bass'

    info:
      text: '&7[ View instructions ]'
      actions:
        - 'tell: &6=== Divine Sword Instructions ==='
        - 'tell: &f- Attack Power +20'
        - 'tell: &f- Can be used in advanced dungeons'
        - 'hovertext: &7Learn more <text=&b[Click to view official website];hover=&7Open browser;url=https://example.com>'
```


---

# 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/actions.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.
