> For the complete documentation index, see [llms.txt](https://guide.cronuszen.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide.cronuszen.com/gpcscripting/gpc-script-guide/reference/combo-reference.md).

# Combo reference

Combos are compiler-scheduled top-level blocks. They produce timed output without an inner delay loop in `main`. A combo keeps running across VM cycles until it finishes, is stopped, or is suspended.

***

### <i class="fa-code">:code:</i> Declaration <a href="#declaration" id="declaration"></a>

{% code title="combo-declaration.gpc" %}

```gpc
combo TapSquare {
    set_val(PS5_SQUARE, 100);
    wait(80);
    set_val(PS5_SQUARE, 0);
    wait(80);
}
```

{% endcode %}

`combo` and `fcombo` use the same source structure. Combo names are resolved separately from variables, definitions, enum members, and const-data names. Keywords and built-in names remain reserved.

***

### <i class="fa-play">:play:</i> Control <a href="#control" id="control"></a>

#### `combo_run`

Starts a combo only when it is not already running.

**Syntax**

```gpc
combo_run(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="combo-run.gpc" %}

```gpc
main {
    if(event_press(PS5_CROSS)) combo_run(TapSquare);
}
```

{% endcode %}

Repeated calls do not reset an active combo.

***

#### `combo_running`

Reports whether a combo is currently active.

**Syntax**

```gpc
result = combo_running(combo_name);
```

**Returns**

`TRUE` while the combo is running; otherwise `FALSE`.

**Example**

{% code title="combo-running.gpc" %}

```gpc
main {
    set_val(TRACE_1, combo_running(TapSquare));
}
```

{% endcode %}

***

#### `combo_stop`

Stops one combo. It has no effect when that combo is not running.

**Syntax**

```gpc
combo_stop(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="combo-stop.gpc" %}

```gpc
main {
    if(event_release(PS5_L2)) combo_stop(TapSquare);
}
```

{% endcode %}

***

#### `combo_restart`

Starts a stopped combo or restarts an active combo from its first step.

**Syntax**

```gpc
combo_restart(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="combo-restart.gpc" %}

```gpc
main {
    if(event_press(PS5_CROSS)) combo_restart(TapSquare);
}
```

{% endcode %}

Use this only when every new trigger should deliberately reset the timing sequence.

***

#### `combo_suspend`

Pauses one running combo without discarding its position.

**Syntax**

```gpc
combo_suspend(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="combo-suspend.gpc" %}

```gpc
main {
    if(event_press(PS5_OPTIONS)) combo_suspend(TapSquare);
}
```

{% endcode %}

***

#### `combo_suspended`

Reports whether a combo is paused.

**Syntax**

```gpc
result = combo_suspended(combo_name);
```

**Returns**

`TRUE` when suspended; otherwise `FALSE`.

**Example**

{% code title="combo-suspended.gpc" %}

```gpc
main {
    if(combo_suspended(TapSquare) && event_press(PS5_CROSS)) {
        combo_resume(TapSquare);
    }
}
```

{% endcode %}

***

#### `combo_resume`

Resumes one suspended combo.

**Syntax**

```gpc
combo_resume(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="combo-resume.gpc" %}

```gpc
main {
    if(event_press(PS5_CROSS)) combo_resume(TapSquare);
}
```

{% endcode %}

***

### <i class="fa-magnifying-glass">:magnifying-glass:</i> Inspection <a href="#inspection" id="inspection"></a>

#### `combo_current_step`

Returns the index of the step currently being executed.

**Syntax**

```gpc
step = combo_current_step(combo_name);
```

**Returns**

The current combo step value.

**Example**

{% code title="combo-current-step.gpc" %}

```gpc
int active_step;

main {
    if(combo_running(TapSquare)) {
        active_step = combo_current_step(TapSquare);
        set_val(TRACE_1, active_step);
    }
}
```

{% endcode %}

Use this for diagnostics and progress displays. Do not build fragile behavior that depends on an undocumented compiler step layout.

***

#### `combo_step_time_left`

Returns the milliseconds remaining in the active combo step.

**Syntax**

```gpc
time_left = combo_step_time_left(combo_name);
```

**Returns**

Remaining milliseconds.

**Example**

{% code title="combo-step-time-left.gpc" %}

```gpc
int time_left;

main {
    if(combo_running(TapSquare)) {
        time_left = combo_step_time_left(TapSquare);
        set_val(TRACE_1, time_left);
    }
}
```

{% endcode %}

***

### <i class="fa-layer-group">:layer-group:</i> All-combo control <a href="#all-combo" id="all-combo"></a>

{% hint style="warning" %}
Only use all-combo control when the state transition truly owns every scheduled behavior. Unrelated combos are affected as well.
{% endhint %}

#### `combo_stop_all`

Stops every running combo.

**Syntax**

```gpc
combo_stop_all();
```

**Returns**

Nothing.

**Example**

{% code title="combo-stop-all.gpc" %}

```gpc
main {
    if(event_press(PS5_OPTIONS)) combo_stop_all();
}
```

{% endcode %}

This is useful on an emergency cancel or exclusive menu transition. Document the ownership change.

***

#### `combo_suspend_all`

Pauses every active combo.

**Syntax**

```gpc
combo_suspend_all();
```

**Returns**

Nothing.

**Example**

{% code title="combo-suspend-all.gpc" %}

```gpc
main {
    if(event_press(PS5_OPTIONS)) combo_suspend_all();
}
```

{% endcode %}

***

#### `combo_resume_all`

Resumes every suspended combo.

**Syntax**

```gpc
combo_resume_all();
```

**Returns**

Nothing.

**Example**

{% code title="combo-resume-all.gpc" %}

```gpc
main {
    if(event_release(PS5_OPTIONS)) combo_resume_all();
}
```

{% endcode %}

***

### <i class="fa-clock">:clock:</i> Inside a combo <a href="#inside" id="inside"></a>

#### `wait`

Holds the output assignments from the current combo step for a duration. `wait` is valid only at the root level of a combo.

**Syntax**

```gpc
wait(milliseconds);
```

**Parameters**

* `milliseconds`: the current 32-bit target accepts an integer duration. Use practical bounded values and verify compiled timing on the device.

**Returns**

Nothing.

**Example**

{% code title="wait.gpc" %}

```gpc
combo HoldCross {
    set_val(PS5_CROSS, 100);
    wait(250);
    set_val(PS5_CROSS, 0);
    wait(50);
}
```

{% endcode %}

{% hint style="warning" %}
Do not place `wait` inside `if`, `while`, or another nested block within the combo.
{% endhint %}

***

#### `call`

Runs another combo as a subroutine. The parent combo pauses until the called combo finishes, then resumes at its next step.

**Syntax**

```gpc
call(combo_name);
```

**Returns**

Nothing.

**Example**

{% code title="call.gpc" %}

```gpc
combo ParentSequence {
    set_val(PS5_CROSS, 100);
    wait(80);
    call(SharedPause);
    set_val(PS5_CIRCLE, 100);
    wait(80);
}

combo SharedPause {
    set_val(PS5_CROSS, 0);
    set_val(PS5_CIRCLE, 0);
    wait(120);
}
```

{% endcode %}

{% hint style="warning" %}
`call` must be at the combo root. Avoid recursion and cycles such as A calling B while B calls A.
{% endhint %}

***

### <i class="fa-list-check">:list-check:</i> Complete control example <a href="#complete-example" id="complete-example"></a>

{% code title="combo-control.gpc" lineNumbers="true" %}

```gpc
int paused;

main {
    if(event_press(PS5_CROSS)) combo_run(TapSquare);
    if(event_press(PS5_SQUARE)) combo_restart(TapSquare);
    if(event_press(PS5_CIRCLE)) combo_stop(TapSquare);

    if(event_press(PS5_OPTIONS)) {
        paused = !paused;
        if(paused) combo_suspend(TapSquare);
        else combo_resume(TapSquare);
    }

    set_val(TRACE_1, combo_running(TapSquare));
    set_val(TRACE_2, combo_suspended(TapSquare));
}

combo TapSquare {
    set_val(PS5_SQUARE, 100);
    wait(80);
    set_val(PS5_SQUARE, 0);
    wait(80);
}
```

{% endcode %}

The combo output and `main` output share the final report. Device-test output ownership when both write the same identifier.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://guide.cronuszen.com/gpcscripting/gpc-script-guide/reference/combo-reference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
