### Particle System Configuration in G.js Source: https://github.com/g-js-api/g.js/blob/main/README.md Example of configuring and adding a particle system in G.js. It showcases various properties that can be set for particle emission, appearance, and behavior, and how to position the system. ```javascript $.add(particle_system({ MAX_PARTICLES: 30, DURATION: -1, LIFETIME: 1, LIFETIME_VAR: 0.3, EMISSION: -1, ANGLE: 90, ANGLE_VAR: 90, SPEED: 29, POSVAR_X: 11, START_SIZE: 2, START_SIZE_VAR: 1, END_SIZE: 1, END_SIZE_VAR: 1, START_R: 1, START_G: 1, START_B: 1, START_A: 1, END_R: 1, END_G: 1, END_B: 1, END_A: 1, ADDITIVE: true }).with(X, 200).with(Y, 100)); ``` -------------------------------- ### Install G.js via npm Source: https://github.com/g-js-api/g.js/blob/main/README.md Install the G.js package into your Node.js project using npm. ```bash npm install @g-js-api/g.js ``` -------------------------------- ### `keyframe_system(group)` Source: https://context7.com/g-js-api/g.js/llms.txt Builds an animation path using GD's keyframe trigger system. Allows defining keyframes and starting playback. ```APIDOC ## `keyframe_system(group)` — Keyframe animation Builds an animation path using GD's keyframe trigger system. Each `keyframe()` call places a keyframe object; `start()` fires the animate keyframe trigger to begin playback. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let player = unknown_g(); 'P'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30).with(obj_props.GROUPS, player).add(); let anim = keyframe_system(player); // Place keyframes defining the movement path anim.keyframe(30, 30, 0.5, false, false, EASE_IN_OUT); // start anim.keyframe(120, 90, 0.5, true, false, EASE_IN_OUT); // curve midpoint anim.keyframe(200, 30, 0.5, false, true, EASE_IN_OUT); // end + close loop // Start the animation anim.start(); ``` ``` -------------------------------- ### Keyframe animation system Source: https://context7.com/g-js-api/g.js/llms.txt Build animations using GD's keyframe trigger system with `keyframe_system`. Use `keyframe()` to place keyframes and `start()` to begin playback. Ensure `@g-js-api/g.js` is imported. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let player = unknown_g(); 'P'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30).with(obj_props.GROUPS, player).add(); let anim = keyframe_system(player); // Place keyframes defining the movement path anim.keyframe(30, 30, 0.5, false, false, EASE_IN_OUT); // start anim.keyframe(120, 90, 0.5, true, false, EASE_IN_OUT); // curve midpoint anim.keyframe(200, 30, 0.5, false, true, EASE_IN_OUT); // end + close loop // Start the animation anim.start(); ``` -------------------------------- ### G.js Functional Example: Moving Text Source: https://github.com/g-js-api/g.js/blob/main/README.md This example demonstrates configuring G.js for level export, creating moving text, and implementing a looping trigger function. Ensure $.exportConfig is called before any GD-related operations. The 'unknown_g()' function is used to get a group ID, and 'to_obj().with().add()' is used to create objects. ```javascript import '@g-js-api/g.js' // configures G.js, so it knows how to export to Geometry Dash // this NEEDS to be ran before anything else GD-related! await $.exportConfig({ type: 'savefile', // you can change this to 'live_editor' if you want to use it using the WSLiveEditor mod, or 'levelstring' if you only want to export the levelstring (make sure to store the result in a variable!) options: { info: true } // displays level info when the program finishes running, check https://g-js-api.github.io/G.js/module-index.html#~save_config for a list of options }); // for a simple example, let's create some moving text // first, store a group in a variable (this is akin to doing 'Next Free' in GD) let my_text = unknown_g(); // now, add some text at X 45 Y 45 with the group ID we defined // GD uses small-step units internally (3x big step), meaning the block is 15 steps from the origin in-game 'Hello, World!' .to_obj() .with(obj_props.X, 45) .with(obj_props.Y, 45) .with(obj_props.GROUPS, my_text) .add(); // let's make a loop that moves this text left and right forever // a 'trigger function' is a system of Geometry Dash triggers let moveloop = trigger_function(() => { let my_context = $.trigger_fn_context(); // stores the ORIGINAL group of the trigger function (it will change later! this is called "context") my_text.move(30, 0, 0.5); // moves the text forwards 30 big step units with a 0.5 move time my_text.move(-30, 0, 0.5); // afterwards, it moves the text BACK 30 big step units to its original place // flashes the background white WITHOUT changing the context of triggers ignore_context_change(() => log.runtime.flash()); // after the two moves, the "context" changes (meaning spawn delays were applied in-between, therefore newer triggers have different group IDs than in the past) // so to loop it, you can just call the group of the original context after all operations are finished my_context.call(); }) // now finally, we can spawn this loop! moveloop.call(); ``` -------------------------------- ### timer(start, end, targetId?, backwards?, ...) Source: https://context7.com/g-js-api/g.js/llms.txt Creates a GD timer that counts between two time values and optionally calls a group when it reaches the end. Returns a counter-like object with `.start()`, `.stop()`, and `.display()` methods. ```APIDOC ## `timer(start, end, targetId?, backwards?, ...)` — Timer trigger Creates a GD timer that counts between two time values and optionally calls a group when it reaches the end. Returns a counter-like object with `.start()`, `.stop()`, and `.display()`. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let timeoutFn = trigger_function(() => { end(true); // instant end when timer expires }); // Count from 0 to 30 seconds, then call timeoutFn let countdown = timer(0, 30, timeoutFn, false, false, true); // Display the running time on screen countdown.display(200, 150); // Start counting countdown.start(); // Can be stopped early // countdown.stop(); ``` ``` -------------------------------- ### Control Music Playback with Song Trigger Source: https://context7.com/g-js-api/g.js/llms.txt The `song` function manages GD music channels. It allows preloading, starting, editing playback properties like volume and fade duration, and stopping songs. The returned object has `.start()`, `.edit()`, and `.stop()` methods. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // Preload song ID 481 on channel 0, looping let bgm = song(481, true, true, 0, 1.0); // Start playback bgm.start(); // Fade volume to 0.3 over 2 seconds bgm.edit(0.3, 1.0, 2.0); // Stop the song bgm.stop(); ``` -------------------------------- ### range(start, end, step?) / extract(dict) Source: https://context7.com/g-js-api/g.js/llms.txt Provides utility functions for generating numeric arrays and extracting dictionary key-value pairs. `range()` creates a sequence of numbers, and `extract()` makes dictionary contents globally available. ```APIDOC ## `range(start, end, step?)` / `extract(dict)` — Utilities `range()` generates a numeric array (like Python's `range`). `extract()` dumps a dictionary's keys and values into global scope. ### Parameters - **start** (number) - The starting number of the range. - **end** (number) - The ending number of the range (exclusive). - **step** (number, optional) - The step between numbers in the range. - **dict** (object) - A dictionary whose key-value pairs will be extracted. ### Example ```js // range(0, 5) → [0, 1, 2, 3, 4] for_loop(range(0, 10), () => { // fires 10 times at runtime }); // Make custom constants globally available extract({ MY_SPEED: 5, MY_COLOR: color(7), }); // Now MY_SPEED and MY_COLOR are global ``` ``` -------------------------------- ### gamescene() Source: https://context7.com/g-js-api/g.js/llms.txt Sets up a dual-mode wave player to expose button_a (left tap) and button_b (right tap) as collision-based events for input handling. ```APIDOC ## `gamescene()` — Input abstraction Sets up a dual-mode wave player hidden off-screen to expose `button_a` (left tap) and `button_b` (right tap) as collision-based events, enabling arbitrary input handling in levels. ### Returns An object with `button_a()` and `button_b()` methods representing input events. ### Example ```js let gs = gamescene(); let jumpCount = counter(0); // Left side tap on(gs.button_a(), trigger_function(() => { jumpCount.add(1); BG.pulse(rgb(0, 200, 255), 0, 0.05, 0.2); })); // Right side tap on(gs.button_b(), trigger_function(() => { jumpCount.subtract(1); BG.pulse(rgb(255, 100, 0), 0, 0.05, 0.2); })); ``` ``` -------------------------------- ### Handle Input with gamescene() Source: https://context7.com/g-js-api/g.js/llms.txt Set up a dual-mode wave player for input handling using gamescene(). Exposes button_a (left tap) and button_b (right tap) as collision events. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let gs = gamescene(); let jumpCount = counter(0); // Left side tap on(gs.button_a(), trigger_function(() => { jumpCount.add(1); BG.pulse(rgb(0, 200, 255), 0, 0.05, 0.2); })); // Right side tap on(gs.button_b(), trigger_function(() => { jumpCount.subtract(1); BG.pulse(rgb(255, 100, 0), 0, 0.05, 0.2); })); ``` -------------------------------- ### options() Source: https://context7.com/g-js-api/g.js/llms.txt Builds an Options trigger in a fluent style, allowing toggling of various level-wide settings. ```APIDOC ## `options()` — Level options trigger Builds an Options trigger in a fluent style, allowing toggling of various level-wide settings. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let o = options(); o.HIDE_GROUND(true); o.HIDE_P1(true); o.DISABLE_CONTROLS_P1(true); o.RESPAWN_TIME(2); // 2 second respawn delay o.add(); ``` ``` -------------------------------- ### Create and Control Timer Trigger Source: https://context7.com/g-js-api/g.js/llms.txt The `timer` function creates a GD timer that counts between specified start and end times. It can optionally call a function when the timer expires. Use `.start()`, `.stop()`, and `.display()` to manage the timer. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let timeoutFn = trigger_function(() => { end(true); // instant end when timer expires }); // Count from 0 to 30 seconds, then call timeoutFn let countdown = timer(0, 30, timeoutFn, false, false, true); // Display the running time on screen countdown.display(200, 150); // Start counting countdown.start(); // Can be stopped early // countdown.stop(); ``` -------------------------------- ### song(id, loop?, ...) Source: https://context7.com/g-js-api/g.js/llms.txt Controls GD music channels and returns an object with `.start()`, `.edit()`, and `.stop()` methods. ```APIDOC ## `song(id, loop?, ...)` — Song trigger Controls GD music channels. Returns an object with `.start()`, `.edit()`, and `.stop()` methods. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // Preload song ID 481 on channel 0, looping let bgm = song(481, true, true, 0, 1.0); // Start playback bgm.start(); // Fade volume to 0.3 over 2 seconds bgm.edit(0.3, 1.0, 2.0); // Stop the song bgm.stop(); ``` ``` -------------------------------- ### Create Gradient Trigger Source: https://context7.com/g-js-api/g.js/llms.txt Use the `gradient` function to create a GD gradient trigger. Define the gradient area using four vertex groups for the corners and specify the start and end colors. Blending and layer can also be configured. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let bl = unknown_g(), br = unknown_g(); let tl = unknown_g(), tr = unknown_g(); // Place vertex objects $.add(object({ OBJ_ID: 1, X: 0, Y: 0, GROUPS: bl })); $.add(object({ OBJ_ID: 1, X: 300, Y: 0, GROUPS: br })); $.add(object({ OBJ_ID: 1, X: 0, Y: 200, GROUPS: tl })); $.add(object({ OBJ_ID: 1, X: 300, Y: 200, GROUPS: tr })); // Create gradient from color(1) to color(2), blending enabled, layer 0 $.add(gradient(color(1), color(2), bl, br, tl, tr, true, true, 0)); ``` -------------------------------- ### Manage Color Channels with color() and unknown_c() Source: https://context7.com/g-js-api/g.js/llms.txt Reference or allocate color channels for level objects. `color(n)` creates a typed reference to a specific channel, while `unknown_c()` allocates the next free channel. Functions are available to set colors instantly, transition them over time, copy colors, and pulse them using RGB or HSV values. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let myColor = color(1); // color channel 1 let freeColor = unknown_c(); // next free channel // Set channel to red instantly myColor.set(rgb(255, 0, 0)); // Transition background to blue over 1 second with blending BG.set(rgb(0, 100, 255), 1, true); // Copy color channel 2 into freeColor freeColor.copy(color(2), 0.5); // Pulse color with RGB myColor.pulse(rgb(255, 255, 0), 0, 0.1, 0.5); // Pulse with HSV (hue shift by 180 degrees) myColor.pulse_hsv(180, 1, 1, false, false, 0, 0.1, 0.5); ``` -------------------------------- ### Create and Configure Particle System Source: https://context7.com/g-js-api/g.js/llms.txt Use `particle_system` to create a GD particle system object. Configure properties like particle count, duration, lifetime, emission, angle, speed, size, and color. The system can be positioned using `.with()` and added to the scene with `.add()`. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // Fire-like upward particle burst particle_system({ MAX_PARTICLES: 50, DURATION: -1, // -1 = infinite LIFETIME: 1.5, LIFETIME_VAR: 0.3, EMISSION: -1, ANGLE: 90, ANGLE_VAR: 30, SPEED: 40, POSVAR_X: 15, START_SIZE: 3, END_SIZE: 0, START_R: 1, START_G: 0.5, START_B: 0, START_A: 1, END_R: 1, END_G: 0, END_B: 0, END_A: 0, ADDITIVE: true }).with(obj_props.X, 200).with(obj_props.Y, 100).add(); // Spawn particles at a group's position at runtime let emitter = unknown_g(); spawn_particle(emitter, group(0), 0, 0, 1.5, 0.5, 0, 45); ``` -------------------------------- ### Configure Level Options with Options Trigger Source: https://context7.com/g-js-api/g.js/llms.txt The `options()` function builds an Options trigger in a fluent style, allowing toggling of various level-wide settings. Use methods like `HIDE_GROUND()`, `HIDE_P1()`, `DISABLE_CONTROLS_P1()`, and `RESPAWN_TIME()` to configure options before adding the trigger. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let o = options(); o.HIDE_GROUND(true); o.HIDE_P1(true); o.DISABLE_CONTROLS_P1(true); o.RESPAWN_TIME(2); // 2 second respawn delay o.add(); ``` -------------------------------- ### particle_system(props, ...) Source: https://context7.com/g-js-api/g.js/llms.txt Creates a GD particle system object. It accepts a properties dictionary and returns an object that can be positioned and added to the scene. ```APIDOC ## `particle_system(props, ...)` — Particle systems Creates a GD particle system object using a named property dictionary (see `properties/particles.js` for all keys). Returns an `object` that can be positioned with `.with()` and added with `.add()`. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // Fire-like upward particle burst particle_system({ MAX_PARTICLES: 50, DURATION: -1, // -1 = infinite LIFETIME: 1.5, LIFETIME_VAR: 0.3, EMISSION: -1, ANGLE: 90, ANGLE_VAR: 30, SPEED: 40, POSVAR_X: 15, START_SIZE: 3, END_SIZE: 0, START_R: 1, START_G: 0.5, START_B: 0, START_A: 1, END_R: 1, END_G: 0, END_B: 0, END_A: 0, ADDITIVE: true }).with(obj_props.X, 200).with(obj_props.Y, 100).add(); // Spawn particles at a group's position at runtime let emitter = unknown_g(); spawn_particle(emitter, group(0), 0, 0, 1.5, 0.5, 0, 45); ``` ``` -------------------------------- ### end(instant?, no_effects?, no_sfx?) Source: https://context7.com/g-js-api/g.js/llms.txt Ends the current level with configurable effect options. Allows for instant ending and disabling visual/sound effects. ```APIDOC ## `end(instant?, no_effects?, no_sfx?)` — End level trigger Ends the current level with configurable effect options. ### Parameters - **instant** (boolean, optional) - If true, ends the level instantly. - **no_effects** (boolean, optional) - If true, disables level end effects. - **no_sfx** (boolean, optional) - If true, disables level end sound effects. ### Example ```js // Standard end with effects end(); // Instant end with no effects or sound end(true, true, true); ``` ``` -------------------------------- ### Create HSV Colors with hsv() Source: https://context7.com/g-js-api/g.js/llms.txt Generate HSV color strings for GD's HVS and COLOR_2_HVS properties using hsv(). ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // Create an object with HSV color shift object({ OBJ_ID: 1, X: 100, Y: 100, HVS: hsv(90, 1, 0.8, false, true), // hue+90, sat=1, bright=0.8 }).add(); ``` -------------------------------- ### Define and Call Trigger Functions Source: https://context7.com/g-js-api/g.js/llms.txt Use `trigger_function(callback)` to group triggers into a spawnable context, similar to SPWN's `!{}`. Capture the context using `$.trigger_fn_context()` before modifications. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let obj = unknown_g(); 'Hello!'.to_obj().with(obj_props.X, 45).with(obj_props.Y, 45) .with(obj_props.GROUPS, obj).add(); // Define a looping animation as a trigger function let bounce = trigger_function(() => { let ctx = $.trigger_fn_context(); // capture this context's group before it changes obj.move(0, 5, 0.25, EASE_IN_OUT); obj.move(0, -5, 0.25, EASE_IN_OUT); ctx.call(); // loop forever }); // Start the loop bounce.call(); ``` -------------------------------- ### Create Tick-Rate Loops with frame_loop() and frames() Source: https://context7.com/g-js-api/g.js/llms.txt Utilize frame_loop() for per-tick execution and frames() for tick-based delays. Render-frame variants are also available. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let tickCount = counter(0); let obj = unknown_g(); 'T'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30).with(obj_props.GROUPS, obj).add(); // Count ticks let loop = frame_loop(trigger_function(() => { tickCount.add(1); })); // After 60 ticks (0.25 seconds at 240Hz), stop the loop let checker = trigger_function(() => { frames(60); // wait 60 ticks loop.stop(); obj.alpha(0, 0.5); // fade out }); checker.call(); ``` -------------------------------- ### while_loop(condition, fn, delay?) Source: https://context7.com/g-js-api/g.js/llms.txt Builds a GD trigger system that repeatedly evaluates a condition and calls a function while true. ```APIDOC ## `while_loop(condition, fn, delay?)` — Runtime while loop Builds a GD trigger system that repeatedly evaluates a counter condition and calls a function while true. Uses `less_than()`, `equal_to()`, or `greater_than()` to build conditions. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let i = counter(0); let target = unknown_g(); // Spawn 5 objects sequentially at runtime while_loop(less_than(i, 5), () => { target.move(10, 0, 0); // move right 10 units each iteration i.add(1); }, 0.1); // 0.1 second delay between iterations ``` ``` -------------------------------- ### Create Runtime While Loops Source: https://context7.com/g-js-api/g.js/llms.txt Employ `while_loop(condition, fn, delay?)` to build a trigger system that repeatedly evaluates a counter condition and executes a function while true. Conditions are built using `less_than()`, `equal_to()`, or `greater_than()`. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let i = counter(0); let target = unknown_g(); // Spawn 5 objects sequentially at runtime while_loop(less_than(i, 5), () => { target.move(10, 0, 0); // move right 10 units each iteration i.add(1); }, 0.1); // 0.1 second delay between iterations ``` -------------------------------- ### Place Objects with object() and $.add() Source: https://context7.com/g-js-api/g.js/llms.txt Use object() to create G.js objects from property dictionaries and $.add() to place them. Supports chainable .with() and .add() methods. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let g1 = unknown_g(); // Build and place a custom object object({ OBJ_ID: obj_ids.special.TEXT, TEXT: btoa('G.js'), X: 100, Y: 100, }) .with(obj_props.GROUPS, g1) .with(obj_props.SCALING, 1.5) .add(); // Place a color trigger manually $.add(color_trigger(color(1), 255, 128, 0, 0.5)); // Place a move trigger manually $.add(move_trigger(g1, 20, 0)); // String shortcut: convert to text object 'Hello World' .to_obj() .with(obj_props.X, 45) .with(obj_props.Y, 45) .add(); ``` -------------------------------- ### Utilities: range() and extract() Source: https://context7.com/g-js-api/g.js/llms.txt Generate numeric arrays with range() and expose dictionary keys/values globally with extract(). ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); // range(0, 5) → [0, 1, 2, 3, 4] for_loop(range(0, 10), () => { // fires 10 times at runtime }); // Make custom constants globally available extract({ MY_SPEED: 5, MY_COLOR: color(7), }); // Now MY_SPEED and MY_COLOR are global ``` -------------------------------- ### `for_loop(range, fn, delay?)` Source: https://context7.com/g-js-api/g.js/llms.txt A convenience wrapper around `while_loop` that iterates over a numeric range, executing a provided function for each step with an optional delay. ```APIDOC ## `for_loop(range, fn, delay?)` — Runtime for loop Convenience wrapper around `while_loop` that loops over a numeric range. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let obj = unknown_g(); 'X'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30) .with(obj_props.GROUPS, obj).add(); // Move object right 5 times, once per 0.3 seconds for_loop(range(0, 5), () => { obj.move(5, 0, 0.2); }, 0.3); ``` ``` -------------------------------- ### `compare(c1, op, c2, trueGroup, falseGroup?)` Source: https://context7.com/g-js-api/g.js/llms.txt Adds an Item Compare trigger that branches execution based on comparing two counters or a counter and a literal number at runtime. ```APIDOC ## `compare(c1, op, c2, trueGroup, falseGroup?)` — Counter comparison Adds an Item Compare trigger. Branches execution based on comparing two counters or a counter and a literal number at runtime. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let health = counter(5); let maxHealth = counter(10); let criticalFn = trigger_function(() => { BG.pulse(rgb(255, 0, 0), 0, 0.1, 0.5); // flash red }); let fullFn = trigger_function(() => { BG.pulse(rgb(0, 255, 0), 0, 0.1, 0.5); // flash green }); // Compare health < 3 → criticalFn, otherwise → fullFn compare(health, LESS, 3, criticalFn, fullFn); // Compare counter to another counter compare(health, EQUAL_TO, maxHealth, fullFn); ``` ``` -------------------------------- ### trigger_function(callback) Source: https://context7.com/g-js-api/g.js/llms.txt Groups triggers into a single spawnable group, equivalent to SPWN's `!{}` syntax. ```APIDOC ## `trigger_function(callback)` — Trigger functions (contexts) Groups a set of triggers into a single spawnable group. This is G.js's equivalent of SPWN's `!{}` syntax. Triggers inside the callback are assigned to the new context's group and can be spawned via `.call()`. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let obj = unknown_g(); 'Hello!'.to_obj().with(obj_props.X, 45).with(obj_props.Y, 45) .with(obj_props.GROUPS, obj).add(); // Define a looping animation as a trigger function let bounce = trigger_function(() => { let ctx = $.trigger_fn_context(); // capture this context's group before it changes obj.move(0, 5, 0.25, EASE_IN_OUT); obj.move(0, -5, 0.25, EASE_IN_OUT); ctx.call(); // loop forever }); // Start the loop bounce.call(); ``` ``` -------------------------------- ### Manage Game State with Counters Source: https://context7.com/g-js-api/g.js/llms.txt Utilize `counter(num?, use_id?, persistent?, timer?)` for item-based counters supporting arithmetic and comparisons. Persistent counters (`persistent: true`) survive between game attempts. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let score = counter(0); // starts at 0 let lives = counter(3); // starts at 3 let highscore = counter(0, false, true); // persistent across attempts // Display on screen at position (100, 100) score.display(100, 100); // Arithmetic score.add(10); score.subtract(5); score.multiply(2); score.divide(2); score.set(100); score.reset(); // sets to 0 // Copy counter value into another counter score.copy_to(highscore); // Conditional: if lives == 0, call a game-over trigger function let gameOver = trigger_function(() => { end(true); // instant end }); lives.if_is(EQUAL_TO, 0, gameOver); // Convert counter to a compile-time constant for branching score.to_const(range(0, 5), (val) => { // 'val' is a plain JS number here (0..4) // triggers added inside run only when score equals val at runtime $.print(`Score branch: ${val}`); }); // Modulo let remainder = score.mod(counter(3)); ``` -------------------------------- ### color(id) / unknown_c() Source: https://context7.com/g-js-api/g.js/llms.txt Manages color channels in Geometry Dash. `color(n)` creates a typed reference to a color channel, while `unknown_c()` allocates the next free color channel. ```APIDOC ## color(id) / unknown_c() — Color channels `color(n)` creates a typed color-channel reference. `unknown_c()` allocates the next free color. Named channels like `BG`, `GROUND`, `OBJECT` are pre-exported as constants. ### Parameters - **id** (number) - Required - The numeric ID of the color channel. ### Methods available on color objects - **set(rgb_color, duration, blending)**: Sets the color of the channel. - **copy(source_color, duration)**: Copies the color from another channel. - **pulse(rgb_color, delay, duration, easing)**: Pulses the color with RGB values. - **pulse_hsv(hue_shift, saturation, value, red_shift, green_shift, blue_shift, delay, duration, easing)**: Pulses the color with HSV values. ### Request Example ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let myColor = color(1); // color channel 1 let freeColor = unknown_c(); // next free channel // Set channel to red instantly myColor.set(rgb(255, 0, 0)); // Transition background to blue over 1 second with blending BG.set(rgb(0, 100, 255), 1, true); // Copy color channel 2 into freeColor freeColor.copy(color(2), 0.5); // Pulse color with RGB myColor.pulse(rgb(255, 255, 0), 0, 0.1, 0.5); // Pulse with HSV (hue shift by 180 degrees) myColor.pulse_hsv(180, 1, 1, false, false, 0, 0.1, 0.5); ``` ``` -------------------------------- ### object(dict) / $.add(object) Source: https://context7.com/g-js-api/g.js/llms.txt Allows for the creation and placement of game objects. `object()` converts a property dictionary into a chainable object, and `$.add()` places it into the current context. ```APIDOC ## `object(dict)` / `$.add(object)` — Raw object placement `object()` converts a property dictionary into a typed G.js object with `.with()` and `.add()` chainable methods. `$.add()` places it into the current context. ### Parameters - **dict** (object) - A dictionary of properties for the object. - **object** (object) - The object to add to the context. ### Example ```js let g1 = unknown_g(); // Build and place a custom object object({ OBJ_ID: obj_ids.special.TEXT, TEXT: btoa('G.js'), X: 100, Y: 100, }) .with(obj_props.GROUPS, g1) .with(obj_props.SCALING, 1.5) .add(); // Place a color trigger manually $.add(color_trigger(color(1), 255, 128, 0, 0.5)); // Place a move trigger manually $.add(move_trigger(g1, 20, 0)); // String shortcut: convert to text object 'Hello World' .to_obj() .with(obj_props.X, 45) .with(obj_props.Y, 45) .add(); ``` ``` -------------------------------- ### hsv(hue, sat, bright, ...) Source: https://context7.com/g-js-api/g.js/llms.txt Generates an HSV color string in the format used by GD for `HVS` and `COLOR_2_HVS` object properties. ```APIDOC ## `hsv(hue, sat, bright, ...)` — HSV color helper Generates an HSV string in the format GD uses for the `HVS` and `COLOR_2_HVS` object properties. ### Parameters - **hue** (number) - The hue value. - **sat** (number) - The saturation value. - **bright** (number) - The brightness value. - **...** (any) - Additional parameters may be accepted for specific color properties. ### Example ```js // Create an object with HSV color shift object({ OBJ_ID: 1, X: 100, Y: 100, HVS: hsv(90, 1, 0.8, false, true), // hue+90, sat=1, bright=0.8 }).add(); ``` ``` -------------------------------- ### Compare counters or literals with branching Source: https://context7.com/g-js-api/g.js/llms.txt Use `compare` to create an Item Compare trigger that branches execution based on comparing two counters or a counter and a literal number. Ensure `@g-js-api/g.js` is imported. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let health = counter(5); let maxHealth = counter(10); let criticalFn = trigger_function(() => { BG.pulse(rgb(255, 0, 0), 0, 0.1, 0.5); // flash red }); let fullFn = trigger_function(() => { BG.pulse(rgb(0, 255, 0), 0, 0.1, 0.5); // flash green }); // Compare health < 3 → criticalFn, otherwise → fullFn compare(health, LESS, 3, criticalFn, fullFn); // Compare counter to another counter compare(health, EQUAL_TO, maxHealth, fullFn); ``` -------------------------------- ### Runtime for loop with delay Source: https://context7.com/g-js-api/g.js/llms.txt Use `for_loop` for iterating over a numeric range with an optional delay between iterations. Ensure `@g-js-api/g.js` is imported. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let obj = unknown_g(); 'X'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30) .with(obj_props.GROUPS, obj).add(); // Move object right 5 times, once per 0.3 seconds for_loop(range(0, 5), () => { obj.move(5, 0, 0.2); }, 0.3); ``` -------------------------------- ### `on(event, triggerFn)` Source: https://context7.com/g-js-api/g.js/llms.txt Attaches a trigger function to a GD event. Supports various events like touch, collision, death, and custom events. ```APIDOC ## `on(event, triggerFn)` — Event listeners Attaches a trigger function to a GD event. Events include `touch()`, `touch_end()`, `collision()`, `collision_exit()`, `death()`, `count()`, `x_position()`, and `event()` (2.2 event trigger). ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let scoreCounter = counter(0); let blockA = unknown_b(); let blockB = unknown_b(); // On screen touch: add 1 to score on(touch(), trigger_function(() => { scoreCounter.add(1); })); // On touch release: flash background white on(touch_end(), trigger_function(() => { BG.pulse(rgb(255, 255, 255), 0, 0, 0.3); })); // On collision between two blocks: toggle object off let obj = unknown_g(); on(collision(blockA, blockB), trigger_function(() => { obj.toggle_off(); })); // On collision exit: toggle object back on on(collision_exit(blockA, blockB), trigger_function(() => { obj.toggle_on(); })); // On player death: restart sequence on(death(), trigger_function(() => { scoreCounter.reset(); })); // When score counter hits 10: trigger a win sequence let winFn = trigger_function(() => { end(false); }); on(count(scoreCounter.item, 10), winFn); // When player reaches X position 300 in the level on(x_position(300), trigger_function(() => { camera_zoom(2, 1, EASE_IN_OUT); })); // 2.2 event trigger: respond to the player jumping on(event(events.NORMAL_JUMP), trigger_function(() => { GROUND.pulse(rgb(255, 200, 0), 0, 0.05, 0.2); })); ``` ``` -------------------------------- ### Teleport Player with teleport() Source: https://context7.com/g-js-api/g.js/llms.txt Teleport players to a group's location or specific coordinates using teleport(). Requires a destination group or [x, y] pair. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let dest = unknown_g(); $.add(object({ OBJ_ID: 1, X: 500, Y: 100, GROUPS: dest })); // Teleport to the object's position teleport(dest); // Teleport to explicit coordinates teleport([500, 100]); ``` -------------------------------- ### Control GD Camera with Various Functions Source: https://context7.com/g-js-api/g.js/llms.txt This suite of functions allows for comprehensive camera control in GD. It includes locking the camera to an object, offsetting, zooming, rotating, enabling free mode, and anchoring edges. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let camTarget = unknown_g(); $.add(object({ OBJ_ID: 1, X: 200, Y: 100, GROUPS: camTarget })); // Lock camera to an object camera_static(camTarget, 1.0, EASE_IN_OUT); // Offset camera by 50 units left over 0.5s camera_offset(-50, 0, 0.5, EASE_OUT); // Zoom to 2x over 1 second camera_zoom(2, 1, EASE_IN_OUT); // Rotate camera 45 degrees camera_rotate(45, 0.5, EASE_IN_OUT); // Enable free camera mode camera_mode(true); // Set left edge to a specific object camera_edge(camTarget, LEFT_EDGE); ``` -------------------------------- ### frame_loop(triggerFn) / frames(n) Source: https://context7.com/g-js-api/g.js/llms.txt Provides mechanisms for creating tick-rate loops. `frame_loop` calls a function every game tick, while `frames(n)` delays execution by `n` ticks. Render-frame variants are also available. ```APIDOC ## `frame_loop(triggerFn)` / `frames(n)` — Tick-rate loops `frame_loop` calls a trigger function every game tick (1/240s). `frames(n)` is a `wait()`-like function that delays execution by exactly `n` ticks. The render-frame variants (`render_frame_loop`, `render_frames`) operate on variable render frames instead. ### Parameters - **triggerFn** (function) - The function to execute on each game tick. - **n** (number) - The number of ticks to delay execution. ### Example ```js let tickCount = counter(0); let obj = unknown_g(); 'T'.to_obj().with(obj_props.X, 30).with(obj_props.Y, 30).with(obj_props.GROUPS, obj).add(); // Count ticks let loop = frame_loop(trigger_function(() => { tickCount.add(1); })); // After 60 ticks (0.25 seconds at 240Hz), stop the loop let checker = trigger_function(() => { frames(60); // wait 60 ticks loop.stop(); obj.alpha(0, 0.5); // fade out }); checker.call(); ``` ``` -------------------------------- ### wait(time) Source: https://context7.com/g-js-api/g.js/llms.txt Inserts a spawn delay, causing subsequent triggers to fire after the specified time. ```APIDOC ## `wait(time)` — Sequential delay Inserts a spawn delay so that all triggers added after `wait()` fire that many seconds later. Works by creating a new child context linked to the current one. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let g = unknown_g(); 'Start'.to_obj().with(obj_props.X, 45).with(obj_props.Y, 45) .with(obj_props.GROUPS, g).add(); let sequence = trigger_function(() => { g.alpha(0); // immediately hide wait(1); g.alpha(1); // show after 1 second wait(0.5); g.move(10, 0, 0.3); // slide right 0.5 seconds after showing wait(0.3); g.move(-10, 0, 0.3); // slide back }); sequence.call(); ``` ``` -------------------------------- ### counter(num?, use_id?, persistent?, timer?) Source: https://context7.com/g-js-api/g.js/llms.txt Creates a wrapper around a GD item ID for arithmetic operations, comparisons, and display. Supports persistent counters. ```APIDOC ## `counter(num?, use_id?, persistent?, timer?)` — Item-based counters Creates a wrapper around a GD item ID that supports arithmetic operations, comparisons, and display. Arithmetic is implemented through Pickup and Item Edit triggers at runtime. Persistent counters survive between attempts. ```js import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let score = counter(0); // starts at 0 let lives = counter(3); // starts at 3 let highscore = counter(0, false, true); // persistent across attempts // Display on screen at position (100, 100) score.display(100, 100); // Arithmetic score.add(10); score.subtract(5); score.multiply(2); score.divide(2); score.set(100); score.reset(); // sets to 0 // Copy counter value into another counter score.copy_to(highscore); // Conditional: if lives == 0, call a game-over trigger function let gameOver = trigger_function(() => { end(true); // instant end }); lives.if_is(EQUAL_TO, 0, gameOver); // Convert counter to a compile-time constant for branching score.to_const(range(0, 5), (val) => { // 'val' is a plain JS number here (0..4) // triggers added inside run only when score equals val at runtime $.print(`Score branch: ${val}`); }); // Modulo let remainder = score.mod(counter(3)); ``` ``` -------------------------------- ### Create and Manage Collision Blocks Source: https://context7.com/g-js-api/g.js/llms.txt Use `block(id)` to create typed block references and `unknown_b()` to allocate new block IDs. Collision blocks can be placed statically or dynamically and checked for collisions. ```javascript import '@g-js-api/g.js'; await $.exportConfig({ type: 'savefile', options: {} }); let blockA = unknown_b(); let blockB = unknown_b(); // Place a static collision block at (50, 50) blockA.collision_block(50, 50).add(); // Place a dynamic collision block at (50, 80) $.add(object({ OBJ_ID: obj_ids.special.COLLISION_BLOCK, BLOCK_A: blockB, X: 50, Y: 80, DYNAMIC_BLOCK: true })); // Instant collision check: call group(10) if colliding, group(11) if not blockA.if_colliding(blockB, group(10), group(11)); ```