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

# Using Conditionals, Loops, and Math in erlc.dev Studio

> Control automation flow with if/else conditions, while and for-each loops, math operations, and timing blocks like wait and throttle.

Conditionals, loops, and math blocks form the backbone of every automation you build in erlc.dev Studio. Use them to branch execution based on player data, repeat actions over a list, perform arithmetic on numeric values, and carefully time or rate-limit sensitive operations — all without writing a single line of code.

***

## Conditional Blocks

Conditionals let your automation make decisions. Connect a boolean-producing block to the `CONDITION` input and the Studio engine evaluates it at run time.

<CardGroup cols={2}>
  <Card title="erlc_if_then" icon="code-branch">
    Runs the `DO` statement block only when `CONDITION` is truthy. No else branch — execution continues with the next block either way.
  </Card>

  <Card title="erlc_if_else" icon="shuffle">
    Evaluates `CONDITION` and runs `THEN` if true, or `ELSE` if false. Both branches reconnect to the block after the if/else.
  </Card>

  <Card title="erlc_compare_values" icon="equals">
    Compares `LEFT` and `RIGHT` using the `OPERATOR` field (`=`, `!=`, `>`, `>=`, `<`, `<=`, `contains`). Returns a boolean.
  </Card>

  <Card title="logic_compare" icon="greater-than-equal">
    Blockly native compare block. Compares inputs `A` and `B` using `OP` field values: `EQ`, `NEQ`, `LT`, `LTE`, `GT`, `GTE`. Returns a boolean.
  </Card>

  <Card title="logic_operation" icon="circle-half-stroke">
    Combines two booleans (`A` and `B`) with `AND` or `OR` logic via the `OP` field.
  </Card>

  <Card title="logic_negate" icon="ban">
    Inverts the boolean value provided in the `BOOL` input (logical NOT).
  </Card>

  <Card title="logic_boolean" icon="toggle-on">
    A literal boolean value block. Set the `BOOL` field to `TRUE` or `FALSE`.
  </Card>

  <Card title="erlc_event_field" icon="tag">
    Reads a field from the current event and tests it. Set `FIELD` to the event property name and `OPERATOR` to `equals`, `contains`, or `not_equals`. Plug in a comparison value via the `VALUE` input. Returns a boolean.
  </Card>
</CardGroup>

### JSON Example — `erlc_if_else` with `erlc_compare_values`

The example below checks whether a player's team name equals `"Police"`. If true, it runs the `THEN` branch; otherwise it runs the `ELSE` branch.

```json theme={null}
{
  "type": "erlc_if_else",
  "id": "block_if_1",
  "inputs": {
    "CONDITION": {
      "block": {
        "type": "erlc_compare_values",
        "id": "block_cmp_1",
        "fields": {
          "OPERATOR": "="
        },
        "inputs": {
          "LEFT": {
            "block": {
              "type": "erlc_event_field",
              "id": "block_field_1",
              "fields": {
                "FIELD": "team",
                "OPERATOR": "equals"
              },
              "inputs": {
                "VALUE": {
                  "block": {
                    "type": "erlc_text_value",
                    "id": "block_text_1",
                    "fields": { "VALUE": "Police" }
                  }
                }
              }
            }
          },
          "RIGHT": {
            "block": {
              "type": "logic_boolean",
              "id": "block_bool_1",
              "fields": { "BOOL": "TRUE" }
            }
          }
        }
      }
    },
    "THEN": {
      "block": {
        "type": "erlc_bot_send_message",
        "id": "block_then_1"
      }
    },
    "ELSE": {
      "block": {
        "type": "erlc_bot_send_message",
        "id": "block_else_1"
      }
    }
  }
}
```

<Note>
  `erlc_compare_values` is purpose-built for ERLC data and supports `contains` for partial string matching. Use `logic_compare` when you need the standard Blockly comparison operators (`EQ`, `NEQ`, etc.) on generic values.
</Note>

***

## Loop Blocks

Loop blocks repeat a set of statement blocks. Connect your repeating logic to the `DO` input of any loop block.

<CardGroup cols={2}>
  <Card title="erlc_repeat" icon="rotate">
    Repeats the `DO` body a fixed number of times. Connect a number block to the `TIMES` input.
  </Card>

  <Card title="erlc_while" icon="arrows-spin">
    Repeats the `DO` body **while** the `CONDITION` input remains truthy. Condition is checked before each iteration.
  </Card>

  <Card title="erlc_repeat_until" icon="arrow-rotate-right">
    Repeats the `DO` body **until** the `CONDITION` input becomes truthy. Condition is checked after each iteration.
  </Card>

  <Card title="erlc_repeat_for_seconds" icon="stopwatch">
    Repeats the `DO` body continuously for the duration provided in the `SECONDS` input.
  </Card>

  <Card title="erlc_forever" icon="infinity">
    Loops the `DO` body indefinitely. This block has no `next` connection — nothing placed below it will ever execute.
  </Card>

  <Card title="erlc_for_each" icon="list-ol">
    Iterates over every item in the `LIST` input. Each item is stored in the variable named by the `VARIABLE` field and the `DO` body runs once per item.
  </Card>

  <Card title="erlc_break_loop" icon="circle-stop">
    Immediately exits the innermost running loop. This block has no `next` connection.
  </Card>

  <Card title="erlc_continue_loop" icon="forward-step">
    Skips the rest of the current iteration and jumps to the next. This block has no `next` connection.
  </Card>
</CardGroup>

<Warning>
  `erlc_forever` and `erlc_break_loop` / `erlc_continue_loop` have no `next` connection — any blocks you stack below them will never run. Place them as the final block in their respective contexts.
</Warning>

***

## Flow Control Blocks

Flow control blocks manage timing, error handling, and execution lifetime. Use them to pace your automations and guard against unexpected failures.

<Accordion title="erlc_wait">
  Pauses execution for the number of seconds provided in the `SECONDS` input. All subsequent blocks in the stack wait until the timer expires.
</Accordion>

<Accordion title="erlc_wait_until">
  Polls the `CONDITION` input repeatedly and resumes execution only when it becomes truthy. Use this instead of a busy `erlc_while` loop when you need to wait for an external state change.
</Accordion>

<Accordion title="erlc_stop_run">
  Stops the entire automation run immediately. No `next` connection — nothing below it executes.
</Accordion>

<Accordion title="erlc_stop_stack">
  Stops only the current block stack, leaving other parallel stacks running.
</Accordion>

<Accordion title="erlc_stop_message_stack">
  Stops the current message-handling stack specifically. Useful inside Discord message event handlers.
</Accordion>

<Accordion title="erlc_throttle">
  Rate-limits a block section. The `DO` body runs at most once per `SECONDS` window for a given `KEY` field value. Subsequent calls within the window are silently skipped.
</Accordion>

<Accordion title="erlc_run_once">
  Runs the `DO` body only once for the lifetime of the automation, identified by the `KEY` field. Subsequent executions reaching this block skip the body entirely.
</Accordion>

<Accordion title="erlc_try_catch">
  Wraps the `TRY` statement body in an error boundary. If any block inside `TRY` throws an error, execution resumes from the `CATCH` statement body instead of stopping the run.
</Accordion>

<Tip>
  Use `erlc_throttle` with a meaningful `KEY` value (such as `"announce_cooldown"`) to prevent the same announcement from firing multiple times per minute, even if the triggering event fires rapidly.
</Tip>

***

## Math Blocks

Math blocks produce numeric values or perform arithmetic. Connect them to any input that expects a number.

### Arithmetic

| Block | Inputs | Field | Output |
| - | - | - | - |
| `math_arithmetic` | `A`, `B` | `OP`: `ADD`, `MINUS`, `MULTIPLY`, `DIVIDE`, `POWER` | Number |
| `math_modulo` | `DIVIDEND`, `DIVISOR` | — | Remainder |
| `math_number` | — | `NUM` | Number literal |
| `erlc_number_value` | — | `VALUE` | Number literal |

### Random & Rounding

| Block | Inputs | Output |
| - | - | - |
| `erlc_random_number` | `FROM`, `TO` | Random integer in range |
| `erlc_math_abs` | `VALUE` | Absolute value |
| `erlc_math_floor` | `VALUE` | Rounded down |
| `erlc_math_ceil` | `VALUE` | Rounded up |
| `erlc_math_round` | `VALUE` | Nearest integer |

### Min, Max, and Clamping

| Block | Inputs | Output |
| - | - | - |
| `erlc_math_min` | `A`, `B` | Smaller of the two |
| `erlc_math_max` | `A`, `B` | Larger of the two |
| `erlc_math_clamp` | `VALUE`, `MIN`, `MAX` | Value constrained to range |
| `erlc_math_between` | `VALUE`, `MIN`, `MAX` | Boolean — true if MIN ≤ VALUE ≤ MAX |
| `erlc_math_percent` | `PERCENT`, `VALUE` | Percentage of value |

### Advanced Math

| Block | Inputs | Output |
| - | - | - |
| `erlc_math_sqrt` | `VALUE` | Square root |
| `erlc_math_sin` | `VALUE` | Sine |
| `erlc_math_cos` | `VALUE` | Cosine |
| `erlc_math_tan` | `VALUE` | Tangent |
| `erlc_math_log10` | `VALUE` | Base-10 logarithm |
| `erlc_math_sign` | `VALUE` | Sign: `-1`, `0`, or `1` |

<Info>
  `math_arithmetic` is the standard Blockly block for arithmetic. Connect number value blocks (such as `math_number` or `erlc_number_value`) to its `A` and `B` inputs, and choose the operation with the `OP` field: `ADD`, `MINUS`, `MULTIPLY`, `DIVIDE`, or `POWER`.
</Info>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.