Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/g-js-api/G.js/llms.txt

Use this file to discover all available pages before exploring further.

G.js provides a rich set of control-flow primitives that let you schedule trigger execution, loop over sequences, and build parameterized trigger systems. Under the hood each function emits the appropriate GD triggers — spawn triggers, sequence triggers, and item-backed timing — so everything runs inside the game itself with no external runtime required.

Spawn Triggers

spawn_trigger(group, time?)

Creates a raw GD spawn trigger and returns it as a GJsObject. You must call .add() on the result to place it in the level.
spawn_trigger(group(5), 1.0).add(); // spawns group 5 after 1 second
spawn_trigger(group(3)).add();       // spawns group 3 immediately
group
$group | any
The group to spawn.
time
number
default:"0"
Delay in seconds before the group is spawned.
Most of the time you won’t need spawn_trigger directly. Use wait(), call_with_delay(), or trigger_function() instead — they manage spawn triggers for you.

Delays

wait(time)

Inserts a pause inside the current trigger-function context. All triggers defined after wait() are placed in a new spawn context that fires after the delay.
trigger_function(() => {
  group(1).call();
  wait(2);            // pause 2 seconds
  group(2).call();    // fires 2 seconds after group 1
});
time
number
Duration to wait, in seconds.

call_with_delay(time, func)

Schedules a group or trigger function to be called after time seconds. Unlike wait(), this does not block the current context — it fires func asynchronously.
call_with_delay(3, trigger_function(() => {
  // runs 3 seconds after this line
}));
time
number
Delay in seconds.
func
TriggerFunctionGroup | $group
The group or trigger function to call after the delay.

For Loops

for_loop(range, fn, delay?)

Iterates fn once for each value in range, inserting a small delay between each iteration.
for_loop(range(0, 4), (i) => {
  // called 5 times: i = 0, 1, 2, 3, 4
  group(i + 10).call();
}, 0.1); // 0.1s between each call
range
any[]
An array of values to iterate over. Use the range(start, end) helper to generate numeric sequences.
fn
Function
Callback called once per iteration with the current value.
delay
number
default:"0.05"
Seconds to wait between each iteration.
for_loop runs at script (build) time, not at play-time. Each iteration generates a separate set of GD triggers with a spawn delay, so the iteration count must be known before the level is exported.

Frame Loops

Frame loops repeat a trigger function continuously. G.js offers two variants matching GD’s two timing modes.

frame_loop(tfn)

Calls tfn every game tick (1/240 second), regardless of frame rate. Returns a TriggerFunctionGroup that you can call .stop() on to halt the loop.
const tick_counter = counter(0);

const loop = frame_loop(trigger_function(() => {
  tick_counter.add(1);
}));

// Stop after 240 ticks (1 second)
call_with_delay(1, trigger_function(() => {
  loop.stop();
}));
tfn
TriggerFunctionGroup | $group
The group to call on every tick.
Returns: TriggerFunctionGroup — call .stop() to end the loop.

frames(frames_count)

Waits exactly frames_count ticks (each tick = 1/240 s) inside a trigger-function context.
trigger_function(() => {
  group(1).call();
  frames(48);       // wait 48/240 = 0.2 seconds
  group(2).call();
});
frames_count
number
Number of ticks to wait.

render_frame_loop(fn)

Like frame_loop, but fires on every rendered frame instead of every tick. The interval is variable and depends on the player’s FPS setting. Returns a TriggerFunctionGroup.
const render_loop = render_frame_loop(trigger_function(() => {
  // visual-only update
}));

render_frames(frames_count)

Waits frames_count rendered frames inside a trigger-function context.
trigger_function(() => {
  group(1).call();
  render_frames(10); // wait 10 render frames
  group(2).call();
});
Use frames() / frame_loop() for deterministic gameplay logic. Use render_frames() / render_frame_loop() only for cosmetic effects where exact timing doesn’t matter, since the interval varies with the player’s device.

Sequence Triggers

sequence(sequence_arr, mode?, min_int?, reset?)

Wraps GD’s Sequence trigger. Each call to the returned step function advances through the list, calling the next group in the array.
const step = sequence(
  [
    [group(1), 1],   // call group 1, weight 1
    [group(2), 1],   // call group 2, weight 1
    [group(3), 1],   // call group 3, weight 1
  ],
  MODE_STOP          // stop at the end
);

// Advance one step each time the player touches the screen
on(touch(), trigger_function(() => {
  step();
}));
sequence_arr
any[][]
Array of [group, weight] pairs. Each pair calls group when that step is reached. The weight field matches GD’s internal sequence weight property.
mode
number
default:"MODE_STOP"
What to do when the sequence reaches the end:
  • MODE_STOP (0) — stop at the last item.
  • MODE_LOOP (1) — wrap back to the first item.
  • MODE_LAST (2) — keep repeating the last item.
min_int
number
default:"0"
Minimum interval between steps (maps to GD’s MinInt field).
reset
number
default:"0"
Reset behaviour: 0 = full reset, 1 = step reset.
Returns: A step function () => void. Call it to advance to the next item in the sequence.

Sequence Mode Constants

ConstantValueBehaviour
MODE_STOP0Halts at the last step.
MODE_LOOP1Wraps around to the beginning.
MODE_LAST2Repeats the final step indefinitely.

Remappable Trigger Functions

remappable(fn)

Creates a trigger-function-like system whose internal item IDs can be remapped at call-time. This is the G.js equivalent of parameterized trigger functions — you describe a template once and call it with different arguments.
const move_target = remappable((target_id) => {
  group(target_id).move(30, 0, 0.5);
});

// Call with different groups at runtime
move_target(group(10).value);
move_target(group(20).value);
fn
Function
A function whose parameters become remappable item IDs. Inside fn, use the parameter values as group/item IDs.
Returns: A callable function that accepts the concrete item IDs to remap onto.
remappable is ideal when you want to reuse the same trigger sequence for different objects — for example, a generic “flash and shake” routine that can target any group. See the README example for the canonical pattern.

When to Use Which Abstraction

ToolRuns atBest for
trigger_functionPlay-timeStandard trigger groups; most use-cases.
remappablePlay-timeReusing trigger sequences with different IDs.
sequencePlay-timeStep-by-step progressions (cutscenes, puzzles).
for_loopBuild-timeGenerating repeated trigger patterns.
frame_loopPlay-timePer-tick gameplay logic.
render_frame_loopPlay-timePer-frame cosmetic effects.

Full Examples

for_loop — Staggered Group Calls

import '@g-js-api/g.js';

await $.exportConfig({ type: 'savefile', options: { info: true } });

// Call groups 10, 11, 12, 13, 14 with 0.1s between each
for_loop(range(0, 4), (i) => {
  group(10 + i).call();
}, 0.1);

frame_loop — Counter Incrementer

import '@g-js-api/g.js';

await $.exportConfig({ type: 'savefile' });

const ticks = counter(0);

const loop = frame_loop(trigger_function(() => {
  ticks.add(1);
}));

// Display running tick count
ticks.display(15, 45);

// Stop after 5 seconds (5 * 240 = 1200 ticks)
call_with_delay(5, trigger_function(() => {
  loop.stop();
}));

sequence with MODE_STOP

import '@g-js-api/g.js';

await $.exportConfig({ type: 'savefile' });

// Three-phase boss fight: intro → fight → outro
const advance = sequence(
  [
    [group(1), 1],   // intro cutscene
    [group(2), 1],   // main boss fight
    [group(3), 1],   // outro
  ],
  MODE_STOP
);

// Each player touch advances to the next phase
on(touch(), trigger_function(() => {
  advance();
}));

remappable — Generic Move Routine

import '@g-js-api/g.js';

await $.exportConfig({ type: 'savefile' });

// Generic "move right then left" routine for any group
const bounce = remappable((target_id) => {
  group(target_id).move(60, 0, 0.3);
  wait(0.3);
  group(target_id).move(-60, 0, 0.3);
});

// Apply the same routine to two different groups
bounce(group(5).value);
bounce(group(10).value);

Events

Combine control-flow with event listeners for reactive logic.

Counters

Use counters inside loops and sequences.

Control Flow API

Full API reference for all control-flow functions.

Trigger Functions

How trigger functions and contexts work under the hood.

Build docs developers (and LLMs) love