GPC scripting 101: your first Cronus Zen script
Learn GPC from zero: how main runs, get_val and set_val, int variables, event_press, combos and wait(), then build and program a working rapid-fire script with a toggle in Zen Studio Live.
- Updated

Quick answer
GPC is the C-like language the Cronus Zen runs. Every script needs a main block, which the Zen executes top to bottom once per input cycle. Read inputs with get_val, write outputs with set_val, react to a single press with event_press, and build timed sequences with a combo that uses wait(). Compile in Zen Studio Live.
What is GPC and how does a script run?
GPC is a small C-like language. You write it in Zen Studio, the compiler turns it into bytecode, and the Zen's virtual machine runs that bytecode on the device. No computer is involved once the slot is programmed.
The mental model that matters most: the Zen reads the controller, runs your main block from top to bottom, and sends the resulting report to the console. Then it does it again, many times per second. Anything you set_val inside one run applies to that one outgoing report; the next cycle starts fresh from the real controller input. This is why "state" needs variables, which we get to shortly.
The smallest useful script
Straight from the official guide:
main {
if(get_val(PS5_L2)) {
set_val(PS5_R1, 100);
}
}Every cycle this reads L2. If it is non-zero (pressed at all), it writes a fully pressed R1 into the outgoing report. Release L2 and R1 goes back to whatever the controller says. Four lines, and it already demonstrates read, evaluate, write, send.
What values do inputs have?
| Control | Range | Meaning |
|---|---|---|
| Digital button | 0 or 100 | Released or pressed |
| Analog trigger | 0..100 | How far pressed |
| Stick axis | -100..100 | Centre is 0 |
So get_val(PS5_R2) might return 37 for a half-pulled trigger, and get_val(PS5_RX) returns a negative number when the right stick is pushed left. Any non-zero value counts as true in an if.
How do I remember something between cycles?
Declare an int at the top level. Globals keep their value across cycles.
int shots;
main {
if(event_press(PS5_R2)) {
shots = shots + 1;
}
}event_press is the important detail. get_val(PS5_R2) is true for every cycle the trigger is held, which could be dozens per second. event_press(PS5_R2) is true only on the single cycle where the trigger goes from released to pressed. Use get_val for "while held" behaviour and event_press for "when pressed" behaviour.
What is init for?
init runs once when the slot loads, before the first main. Use it to load saved settings or set starting values. Both blocks see the same global variables.
int enabled;
init {
enabled = 1;
}
main {
if(event_press(PS5_TRIANGLE)) {
enabled = !enabled;
}
}How do I make a timed sequence?
Use a combo. A combo is a block of set_val and wait calls that runs on its own schedule without blocking main. Start it with combo_run, and it steps through its lines over successive cycles, holding each set_val for the duration of the following wait in milliseconds.
main {
if(event_press(PS5_CROSS)) combo_run(TapSquare);
if(event_press(PS5_CIRCLE)) combo_stop(TapSquare);
}
combo TapSquare {
set_val(PS5_SQUARE, 100);
wait(80);
set_val(PS5_SQUARE, 0);
wait(80);
}wait is combo-only and must sit at the root of the combo. combo_run will not restart a combo that is already running; use combo_restart if that is what you want.
Putting it together: rapid fire with a toggle
This script taps R2 repeatedly while you hold it, and lets you switch the feature on and off with Triangle. It uses everything above.
// Rapid fire on R2 with an enable toggle on TRIANGLE.
int enabled = 1; // 1 = on, 0 = off
main {
// Toggle once per press, not once per cycle.
if(event_press(PS5_TRIANGLE)) {
enabled = !enabled;
set_val(PS5_TRIANGLE, 0); // swallow the press so the game does not see it
}
// While enabled and R2 is held, run the tapping combo.
if(enabled && get_val(PS5_R2)) {
combo_run(RapidFire);
}
// Show state in Device Monitor's trace window.
set_val(TRACE_1, enabled);
}
combo RapidFire {
set_val(PS5_R2, 100);
wait(40);
set_val(PS5_R2, 0);
wait(30);
}A few notes on why it is written this way:
set_val(PS5_TRIANGLE, 0)after the toggle stops the game from also receiving the Triangle press. This "current-cycle suppression" pattern appears throughout the official examples.- The combo re-runs as long as
get_val(PS5_R2)stays true becausecombo_runis called every cycle; once the combo finishes it is started again. TRACE_1is a debug output visible in Zen Studio Legacy's Device Monitor. It has no effect on the game.- The 40 ms / 30 ms timings are a starting point. Games cap fire rates differently; tune with the device in hand. Our rapid fire guide goes deeper.
How do I compile and program it?
- Open Zen Studio Live in Chrome or Edge and connect the Zen via the PROG port.
- Open the Editor tab, paste the script, and click Compile. Fix any line the output pane flags.
- Drag the compiled script to a slot and click Program Slots.
- Unplug PROG, connect to your console or PC, and select the slot on the OLED.
- Test in a controller tester or a game's settings screen before trusting it in play.
What are the first mistakes to expect?
- Toggling with
get_val. Covered above; useevent_press. - Forgetting
main. Every script needs one. Zen Studio Live will merge multiplemainblocks, but one is easier to read. waitoutside a combo. The compiler rejects it.- Values out of range. The compiler checks constants; if you compute a value, clamp it before
set_val. - Compiling for the wrong platform. Use the identifiers that match your output protocol, or the cross-platform identifiers from the official guide.
Where next?
- Reading stick values with get_val for analog input.
- Combos and wait() timing for sequences and
call. - Persistent variables with SPVAR to save settings across power cycles.
- The official GPC Script Guide for the full reference, including the 32-bit compiler's limits: 1,020 runtime variables, 1,024 stack slots and 65,519 bytes of bytecode per slot.
A reminder before you take any of this online: automating inputs is exactly what Epic and Activision prohibit and detect. Read Is the Cronus Zen allowed? first.
Frequently asked questions
Do I need programming experience?
Which button names do I use?
Why does my toggle flip randomly?
Where can I read more scripts?
Sources
Every link was live when this guide was last updated.
- 01The smallest useful script (official GPC guide)guide.cronuszen.com
- 02init and main (official GPC guide)guide.cronuszen.com
- 03Combos and fcombo (official GPC guide)guide.cronuszen.com
- 04Toggle state without repeat firing (official GPC guide)guide.cronuszen.com
- 05Control value ranges (official GPC guide)guide.cronuszen.com
This guide is independent and unofficial; product names belong to their owners. Found an error? Use the contact page and we will correct it and note the change.


