GPC Script Basics: Syntax, Structure & Patterns

GPC Programming12 min read

Technical introduction to GPC — variables, combos, main loops, conditionals, menu systems, and how to read commercial scripts safely.

# GPC Script Basics: Syntax, Combos, and Program Structure

GPC (GamePack Compiler language) is the domain-specific language Collective Minds developed for Cronus Zen and related devices. It is not general-purpose programming — every construct exists to read controller state, modify HID reports, and schedule timed button sequences within strict memory and timing budgets. This guide introduces GPC syntax, program structure, and the patterns commercial scripts use so you can read, customize, and debug .gpc files confidently. For advanced combo timing behavior, continue to GPC Combo, wait(), and Timing Deep Dive. For how compiled bytecode interacts with console input, see How Cronus Zen Scripts Work.

Language overview

GPC scripts compile to bytecode executed by the Cronus Zen ARM processor. At runtime the Zen sits between your physical controller and the console, intercepting USB or Bluetooth HID reports, applying script logic, and forwarding modified reports downstream.

The compilation pipeline:

.gpc source → Zen Studio compiler → bytecode → device memory slot → runtime interpreter

Each main iteration receives fresh controller state. The script decides whether to pass values through unchanged, scale them, zero them, or trigger combos that override values for timed durations.

Core program sections

GPC organizes code into named sections. Commercial scripts may span thousands of lines, but the skeleton repeats consistently.

SectionExecution modelTypical contents
`init`Runs once at script loadDefault variable values, slot detection
`main`Runs every input pollInput reads, conditionals, combo triggers
`combo`Runs when invokedTimed `set_val`, `wait`, button holds
`function`Called from main or combosReusable logic (firmware-gated)
`const` / definesCompile-time constantsButton masks, feature flags

A minimal structural example:

init {
    green_delay = 240;
    mod_enabled = TRUE;
}

main {
    if (mod_enabled && event_press(PS4_R2)) {
        combo_run(AutoGreen);
    }
}

combo AutoGreen {
    set_val(PS4_RY, -100);
    wait(green_delay);
    set_val(PS4_RY, 0);
}

The init block sets starting values before the first main tick. The main block watches for trigger press edges. The combo applies stick movement, waits, then releases.

Variables and types

GPC supports a small type system optimized for embedded controller logic.

TypeUse caseExample
`int`Milliseconds, percentages, toggles`int delay = 80;`
`fix32`Fixed-point stick mathAdvanced aim curves
`bool` / `TRUE` / `FALSE`Feature gates`int mod_on = TRUE;`

Example declarations at script top:

int green_delay = 240;
int aim_strength = 35;
int mod_enabled = TRUE;
int deadzone = 6;

Commercial scripts expose hundreds of int variables mapped to OLED menus, LED feedback, or hold-to-adjust patterns. Do not rename menu variables without provider documentation — menu systems reference variables by name and index conventions.

Variable scope and persistence

Variables retain values across main iterations until changed by logic or user menu adjustment. They do not persist across power cycles unless the script implements save patterns via provider-specific APIs. Toggles reset to init defaults on script reload.

Input API essentials

GPC provides controller-centric functions. These appear in virtually every script.

FunctionBehavior
`get_val(BUTTON)`Current axis or button value
`set_val(BUTTON, value)`Override report value sent to console
`event_press(BUTTON)`True for one poll on physical press edge
`event_release(BUTTON)`True for one poll on physical release edge
`get_ival(BUTTON)`Instantaneous raw value (advanced)

Button identifiers follow PlayStation naming (PS4_R2, PS4_LX) even when targeting Xbox; Zen maps outputs per active protocol.

Press vs hold detection matters for competitive scripts:

if (event_press(PS4_R2)) {
    combo_run(FireMod);
}
if (event_release(PS4_R2)) {
    combo_stop(FireMod);
}

event_press fires once per physical press. Holding R2 does not retrigger unless the script implements repeat logic.

Combos explained

Combos are named timed instruction lists. They are the primary mechanism for sequences longer than one poll — recoil patterns, dribble moves, rapid fire bursts.

combo AntiRecoil {
    set_val(PS4_RY, recoil_pull);
    wait(fire_duration);
    set_val(PS4_RY, 0);
}

Invocation from main:

if (get_val(PS4_R2)) {
    combo_run(AntiRecoil);
}

Combos run asynchronously relative to main in the sense that main continues executing while combo steps progress — but wait() inside a combo blocks that combo's own timeline. Misunderstanding this behavior causes most timing bugs. Full treatment in GPC Combo, wait(), and Timing Deep Dive.

combo_run vs combo_stop

CallEffect
`combo_run(Name)`Start combo from first step (or resume if designed)
`combo_stop(Name)`Halt combo immediately; releases stuck overrides
`combo_running(Name)`Returns TRUE if combo active

Always pair combo_stop on button release for hold-to-activate mods. Missing stops produce stuck stick values players describe as "drift."

Conditional logic and flow control

GPC supports if, else if, else, and while with C-like syntax.

Slot-based profile switching:

if (get_slot() == 1) {
    // Profile A — aggressive timing
    green_delay = 220;
} else if (get_slot() == 2) {
    // Profile B — conservative timing
    green_delay = 280;
}

Feature toggles with early exit pattern:

if (!shoot_mod) return;
// shoot mod logic below

The return in main skips remaining logic for that poll only — it does not terminate the script.

Avoid deeply nested conditionals without comments. Maintenance cost rises quickly in 3,000-line commercial files.

Functions and includes

Providers modularize scripts with #include directives:

#include <provider_core.gph>
#include <nba2k_timing.gph>

Included files contribute variables, combos, and functions to the compilation unit. Missing includes produce undefined identifier errors at compile time.

User-defined functions (when firmware supports):

function apply_deadzone(int axis) {
    if (abs(axis) < deadzone) return 0;
    return axis;
}

Check your firmware GPC reference for function support limits — older firmware restricts function features.

Main loop architecture patterns

Commercial scripts typically structure main as ordered phases:

  1. Menu handling — read adjustment inputs, update OLED
  2. Platform guards — skip PlayStation-specific blocks on Xbox
  3. Toggle checks — respect user-disabled mods
  4. Input edge detection — fire combos on press/release
  5. Passthrough defaults — ensure unstuck values each poll

Pseudo-pattern:

main {
    handle_menu();
    if (platform_ps5) ps5_auth_guard();
    if (!master_toggle) return;

    if (event_press(PS4_L2)) combo_run(AdsMod);
    if (event_release(PS4_L2)) combo_stop(AdsMod);
}

Order matters when multiple mods touch the same stick axis. Later set_val calls win unless combo overrides interleave.

Reading a commercial script safely

Follow this sequence before editing any downloaded .gpc:

  1. Identify the menu variable block at the top — document which integers map to which features.
  2. Locate toggle guards (if (!feature) return; patterns).
  3. Map combo names to marketing labels in provider documentation.
  4. Note platform conditionals — editing PlayStation delays may not affect Xbox builds.
  5. Change only values inside documented safe ranges (typically timing ±20 ms, strength ±5%).

Do not redistribute modified commercial scripts unless the license explicitly permits modification and redistribution.

Common compile errors

Error classTypical causeFix
Undefined identifierTypo, missing `#include`Restore spelling or add include
Combo already runningMissing `combo_stop` on releaseAdd release handler
Out of memoryScript too large for slotRemove unused combos or request slim build
Syntax errorMissing semicolon or braceJump to reported line
Unknown functionFirmware too oldUpdate firmware or downgrade script API usage

Zen Studio's output panel shows line numbers. Fix errors from top to bottom — later errors are sometimes cascading artifacts of the first mistake.

Debugging runtime behavior without recompiling constantly

Use incremental testing when self-tuning:

  1. Change one int at a time.
  2. Recompile and write to a test slot, not your production slot.
  3. Verify in private match for five minutes before merging to primary slot.
  4. Keep notes: green_delay 240→260: better offline, worse online.

For systematic in-game failures, use Troubleshooting Cronus Zen Scripts.

Relationship to aim and recoil tuning

Variables like aim_strength and recoil_pull feed into set_val calls inside combos. Tuning those values is documented practically in Cronus Zen Aim Assist and Anti-Recoil Settings. Syntax knowledge tells you where values live; tuning guides tell you what ranges work online.

GPC vs other automation approaches

ApproachWhat it seesTypical use
GPC on ZenController HID reportsInput timing, stick patterns
PC macrosOS-level inputPC games without Zen
Game trainersGame memoryNot applicable to Zen GPC

Zen GPC is controller-side only. Scripts cannot implement computer vision aim or packet inspection.

Installation and Studio prerequisites

You need a working compile-and-write workflow before editing matters. If you have not flashed a script yet, complete How to Install a Cronus Zen Script and Cronus Zen Studio Setup.

Frequently asked questions

Is GPC the same as Python or JavaScript?

No. GPC borrows C-like syntax but provides only Cronus controller APIs. General loops, file I/O, and networking are unavailable.

Can I write scripts without programming experience?

Simple toggle scripts with one combo are approachable. Large multi-game commercial packs require disciplined structure, commenting, and testing habits equivalent to junior embedded programming.

Where is official GPC documentation?

Collective Minds publishes language references in Zen Studio help files and community forums. Match documentation version to your firmware — APIs expand over time.

Can GPC access game memory?

No. GPC only sees controller state, Zen timers, and slot metadata. Any marketing claiming direct game reads is inaccurate for standard Zen scripting.

Why do scripts use PS4_ button names on Xbox?

Cronus normalizes internal identifiers. Output protocol mapping handles Xbox report formats. Authors document platform toggles where behavior diverges.

What is the difference between `wait` and polling in main?

wait inside combos pauses that combo's timeline in milliseconds. main polls every input cycle independently. See GPC Combo, wait(), and Timing Deep Dive.

How large can a GPC script be?

Bytecode size limits depend on firmware and slot layout. Compile output shows size. Exceeding limits fails compile with out-of-memory errors.

Can I comment GPC code?

Yes. Use // for line comments and /* */ for blocks. Comments do not affect bytecode size meaningfully but improve maintainability.

Constants, defines, and compile-time values

GPC supports define directives and const blocks for values that never change at runtime. Commercial scripts use them for button masks, feature flags, and protocol-specific thresholds.

define FIRE_BTN = PS4_R2;
define ADS_BTN   = PS4_L2;
define MENU_HOLD_MS = 2000;

const int MAX_STRENGTH = 100;
const int MIN_DELAY    = 40;
ConstructWhen to useRuntime changeable?
`define`Button aliases, magic numbersNo — compile-time substitution
`const`Shared limits across combosNo
`int` variablesMenu-tunable parametersYes

Prefer define for button identifiers you reference dozens of times. A single rename propagates through the compilation unit. Reserve int variables for values users adjust through OLED menus or hold-to-edit patterns.

OLED and in-script menu patterns

Many commercial scripts expose tuning without Zen Studio by mapping stick directions or button holds to variable increments. The pattern repeats across providers:

main {
    if (get_val(PS4_OPTIONS)) {
        if (event_press(PS4_UP)) {
            green_delay += 5;
            if (green_delay > 400) green_delay = 400;
        }
        if (event_press(PS4_DOWN)) {
            green_delay -= 5;
            if (green_delay < 100) green_delay = 100;
        }
    }
}
Menu patternUser actionScript response
Hold Options + D-padNavigate menuIncrement/decrement `int`
LED color flashToggle confirmVisual feedback on change
Combo activationEnable mod categorySets boolean gate variable

When reading unfamiliar scripts, locate the menu block first — it reveals which int variables are safe to edit in Studio versus which are internal counters. Editing internal loop counters (combo_step, menu_page) breaks navigation silently.

Bitwise and advanced input masks

Some scripts combine button states with bitwise operators for compact conditionals:

if (get_val(PS4_L2) && get_val(PS4_R2)) {
    combo_run(AdsFireMod);
}

Firmware-gated APIs may expose get_controller() or protocol detection helpers. Check your firmware GPC reference before using advanced identifiers — copying snippets from forum posts targeting newer firmware causes unknown function at compile time on older devices.

Multi-file compilation units

Large scripts split across .gph include files. The compiler merges them into one bytecode image:

main.gpc          → entry point, main loop
provider_core.gph → shared combos, menu system
game_fps.gph      → shooter-specific mods
game_sports.gph   → sports timing blocks
File roleTypical contents
Entry `.gpc``#include` list, `init`, `main`
`.gph` headersCombos, functions, variable declarations
Provider license blockActivation keys (some commercial packs)

Missing a single include produces dozens of cascading undefined identifier errors. Always compile from the provider-specified entry file — not an arbitrary included fragment.

Self-authored script starter template

For learning GPC beyond reading commercial files, start with a minimal passthrough-plus-one-mod template:

init {
    mod_enabled = TRUE;
    pulse_ms = 80;
}

main {
    if (!mod_enabled) return;

    if (event_press(PS4_CROSS)) {
        combo_run(TapPulse);
    }
}

combo TapPulse {
    set_val(PS4_CROSS, 100);
    wait(pulse_ms);
    set_val(PS4_CROSS, 0);
}

Test workflow:

  1. Compile and write to a test slot per Cronus Zen Slots, Profiles, and Backup.
  2. Verify passthrough when mod_enabled = FALSE.
  3. Enable mod and confirm single pulse per press.
  4. Add complexity only after baseline passes Tier 1–3 from Troubleshooting Cronus Zen Scripts.

GPC version and firmware alignment

API surface expands with firmware. Functions like advanced fix32 math, extended combo controls, or platform-specific guards appear in changelog order.

CheckHow
Firmware versionZen Studio device footer
Script requirementProvider readme or header comment
API referenceStudio Help → GPC Language Reference

When a script compiles on a friend's machine but fails on yours with unknown function, compare firmware numbers before editing source. Updating firmware via Cronus Zen Studio Setup often resolves API mismatch faster than deleting script features.

Commercial scripts expose dozens or hundreds of integers through OLED menus, LED color feedback, or hold-to-adjust patterns. Architecture pattern:

int menu_page = 0;
int aim_strength = 35;
int recoil_vert = 28;

init {
    aim_strength = 35;
    recoil_vert = 28;
}

main {
    if (event_press(PS4_OPTIONS)) {
        menu_page = cycle_menu(menu_page);
    }
    // menu adjust handlers read D-pad, write to aim_strength, etc.
}

Rule: Never rename menu-linked variables without provider documentation. Menu index tables map OLED lines to variable names; renames break adjustability silently while compile still succeeds.

Anti-patterns when editing commercial GPC

Anti-patternRisk
Copy-paste combo without matching stop handlersStuck stick drift
Duplicate combo names across merged filesCompile failure
Global search-replace on `PS4_` identifiersBreaks platform guards
Removing `#include` to shrink sizeUndefined references
Editing bytecode on PC directlyCorrupt slot; always edit `.gpc`

When learning syntax, duplicate provider file to my-tuning-v2.4.gpc before any edit — preserves clean rollback source.

Building a minimal custom script from scratch

For education, a two-feature script demonstrates full structure:

init {
    rapid_on = FALSE;
    delay_ms = 80;
}

main {
    if (event_press(PS4_SHARE)) {
        rapid_on = !rapid_on;
    }
    if (rapid_on && get_val(PS4_R2)) {
        combo_run(RapidTap);
    }
    if (event_release(PS4_R2)) {
        combo_stop(RapidTap);
    }
}

combo RapidTap {
    set_val(PS4_R2, 100);
    wait(delay_ms);
    set_val(PS4_R2, 0);
    wait(delay_ms);
}

Compile, write to test slot per How to Install a Cronus Zen Script, validate passthrough toggle, then expand. Combo timing details in GPC Combo, wait(), and Timing Deep Dive.

Cross-reference map for deeper reading

TopicArticle
Combo timing[GPC Combo, wait(), and Timing Deep Dive](/blog/gpc-combo-wait-timing-deep-dive)
Input path theory[How Cronus Zen Scripts Work](/blog/how-cronus-zen-scripts-work)
Tuning variables[Cronus Zen Aim Assist and Anti-Recoil Settings](/blog/best-cronus-zen-settings-aim-assist)
Slot management[Cronus Zen Slots, Profiles, and Backup](/blog/cronus-zen-slots-profiles-backup)
Diagnostics[Troubleshooting Cronus Zen Scripts](/blog/troubleshooting-cronus-zen-scripts)

Related reading