> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nmentities.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Flow Control

> delay, run, if, loop, while, random effects and the condition language.

Flow control turns effect lists into sequences and decisions: pause between lines, branch on conditions, loop, and pick random outcomes.

## delay

Pauses the **remaining lines** of the current effect list, then resumes. This is the backbone of telegraphed attacks.

**Alias:** `wait`

The duration is positional: `delay 0.5s`, `delay 20`.

```yaml theme={null}
  smash:
  - particlering{particle=flame;radius=5;points=48} @self  # warn
  - delay 0.5s                                             # wind up
  - damage{amount=10} @playersRadius[4]                    # hit
```

A `delay` inside a [named effect](named-effects) pauses that effect only, not whatever called it.

## run

Runs a [named effect](named-effects). Its lines inherit this line's targets unless they set their own `@`.

**Aliases:** `effect`, `skill`

The effect id is positional:

```yaml theme={null}
- run smash #onHurt @target
```

## if

Runs one body when a condition holds, optionally another when it doesn't.

**Alias:** `branch`

| Attribute | Description                |
| --------- | -------------------------- |
| `cond`    | The condition (see below). |
| `then`    | Body to run when true.     |
| `else`    | Optional body when false.  |

```yaml theme={null}
- if{cond=var.phase >= 2;then=enrage;else=calm} #onHurt @target
- if{cond=random < 0.3;then=rare_drop}          #onDeath @self
```

## loop

Runs a body a fixed number of times.

| Attribute | Description                                                         |
| --------- | ------------------------------------------------------------------- |
| `effect`  | The body to run.                                                    |
| `times`   | Required. Iterations, capped at 1000.                               |
| `every`   | Optional. One iteration per this many ticks. Omit for back-to-back. |

```yaml theme={null}
- loop{effect=ring_blast;times=3;every=10} @self
```

## while

Re-checks a condition on an interval and runs the body while it holds. It checks first, then runs.

| Attribute | Default  | Description                            |
| --------- | -------- | -------------------------------------- |
| `cond`    | required | The condition.                         |
| `effect`  | required | The body to run each round.            |
| `every`   | `1s`     | Time between checks. Minimum 1 tick.   |
| `max`     | `100`    | Safety cap on iterations, up to 10000. |

```yaml theme={null}
- while{cond=var.charging;effect=charge_tick;every=5;max=200} @self
```

## Bodies: named effects or inline blocks

A body (`then` / `else` / `effect`) is either a **named effect id**, resolved mob-local first exactly like `run`, or an **inline block** `{stmt;stmt;...}`:

* Statements are full effect lines, mechanic plus optional `@targeter`, separated by `;`.
* Blocks **nest**: a statement can itself be an `if`/`loop`/`while` with its own block.
* A block may span **multiple lines**, and continuation lines may start with `- ` for readability. The loader joins them before YAML parsing, so the raw multi-line form doesn't need to be valid YAML on its own.

```yaml theme={null}
- if{cond=random < 0.5;then={narrate "&dheads!";sound{sound=block.bell.use}};else={narrate "&dtails"}}
- if{cond=var.phase >= 2;then={
  - narrate "&cThe boss is enraged!" @playersRadius[20]
  - setspeed{amount=0.45} @self
  - glow{glowing=true} @self
  };else=calm_down}
```

Rules for blocks:

* No `#triggers` inside a block. The trigger belongs to the outer line.
* No comments inside a multi-line block.
* A malformed or empty block fails the whole line at load time, logged and skipped.
* Prefer a named effect over a block when the body should be reusable or `run`-able. Blocks are for short one-off branches.

## randomskill

Runs one randomly chosen named effect. Great for varied attack patterns.

**Alias:** `randomeffect`

| Attribute | Description                 |
| --------- | --------------------------- |
| `skills`  | Comma-separated effect ids. |

```yaml theme={null}
- randomskill{skills=slam,fire_breath,summon_wave} #onAttack @target
```

## randommessage

Sends one randomly chosen message.

**Alias:** `randommsg`

| Attribute  | Description              |     |
| ---------- | ------------------------ | --- |
| `messages` | Messages separated by \` | \`. |

```yaml theme={null}
- randommessage{messages=&7Hello!\|&7Greetings.\|&7Oh, you again.} #onInteract @target
```

## Conditions

`if` and `while` share a small condition language over [variables](variables). A condition is one or more comparisons joined by `&&` and `||`, where `&&` binds tighter:

* **Operators:** `>=` `<=` `>` `<` `==` `!=`.
* **Truthy check:** a lone operand with no comparison is true when the value is set and non-zero, non-empty and not `"false"`. Example: `if{cond=var.enraged;then=...}`.
* **Operands:** numbers; variable references without angle brackets (`var.x`, `target.var.x`, `global.var.x`, `world.var.x`, `skill.var.x`); the keywords `random` (alias `chance`, a fresh 0-1 roll per evaluation, so `random < 0.3` is a 30% chance), `health` and `maxhealth` (the casting mob's), and `time` (world ticks). Anything else is a string literal, bare word, no quotes needed.
* Both sides numeric means numeric comparison. Otherwise case-insensitive string equality, `==` and `!=` only; ordered operators on strings are always false.
* Unset variables count as `0` in numeric comparisons and `""` in string ones.
* `target.var.x` reads from the line's **first** target.
* A malformed condition fails the whole line at load time, logged and skipped, like any other parse error.

```yaml theme={null}
- if{cond=health <= 150 && var.phase == 1;then=enrage} #onHurt @self
```

## Behavior notes

* A branch or loop body runs with the caller's context: same targets (unless its lines set their own `@targeter`) and the same `skill.` variable scope, so loop counters via `var{...}` work across iterations.
* A `delay` inside a looped effect pauses **that iteration only**, not the loop schedule.
* Spaced `loop` and `while` stop early if the mob dies or despawns. `while`'s `max` is a hard safety cap against infinite loops.

## The counter pattern

```yaml theme={null}
  effects:
  - var{n=0}                                          #onInteract @target
  - while{cond=var.n < 5;effect=step;every=10} @self  #onInteract @target
  step:
  - var{n+=1}
  - actionbar{message=&6charge <var.n> of 5} @playersRadius[16]
```
