Event JSON Reference

Complete reference for GB Studio event JSON structure in .gbsres scene, actor, and trigger files. These files can be edited directly with any text editor — no compilation required.

Overview

Scene, actor, and trigger .gbsres files contain event scripts as JSON. Events are arrays of event objects, where each event has a unique id, a command, and an args object containing command-specific parameters.

  • Events are stored as ordered JSON arrays
  • Each event object must have a unique id string (typically a UUID)
  • The command field identifies the event type
  • The args object contains all parameters for the command
  • Branching events use a children object to hold nested event arrays

Event Object Structure

Every event follows this basic shape:

{
  "id": "unique-uuid-string",
  "command": "EVENT_COMMAND_NAME",
  "args": {
    "field1": "value1",
    "field2": {"type": "number", "value": 42}
  }
}
FieldTypeDescription
idstringUnique identifier for this event instance (UUID)
commandstringEvent command name (e.g. EVENT_SET_VALUE)
argsobjectCommand-specific parameters
childrenobjectNested event arrays for branching events (optional)

Value Types

Event arguments use typed value objects to distinguish between constants, variables, expressions, and properties.

TypeFormatExample
Number{"type":"number","value":42}Constant integer
Variable{"type":"variable","value":"VAR_ID"}Reference to variable
Expression{"type":"expression","value":"$07$ >= 6"}Math expression
Property{"type":"property","value":"$self$:xpos"}Actor property

Variable References in Expressions

Within expression strings, variables are referenced using the $VAR_ID$ syntax. The ID is typically the variable index number.

// Reference variable index 130
{"type": "expression", "value": "$130$ + 1"}

// Compare variable 07 against a constant
{"type": "expression", "value": "$07$ >= 6"}

// Arithmetic with multiple variables
{"type": "expression", "value": "$12$ + $13$ * 2"}

Actor References

Actor fields accept several reference formats:

ReferenceMeaning
"$self$"The current actor (in actor scripts)
"" or "player"The player actor
UUID stringA specific actor identified by its unique ID

Branching Events

Events that control program flow use a children object containing named arrays of nested events.

If / Else

Conditional branching with true and false branches:

{
  "id": "evt-uuid-1",
  "command": "EVENT_IF",
  "args": {
    "variable": "12",
    "operator": ".EQ",
    "value": {"type": "number", "value": 1}
  },
  "children": {
    "true": [/* events when condition is true */],
    "false": [/* events when condition is false */]
  }
}

Comparison Operators

OperatorMeaning
.EQEqual
.NENot equal
.LTLess than
.LTELess than or equal
.GTGreater than
.GTEGreater than or equal

Switch

Multi-way branching using numbered true0trueN branches, with a false default:

{
  "id": "evt-uuid-2",
  "command": "EVENT_SWITCH",
  "args": {
    "variable": "12",
    "choices": 4
  },
  "children": {
    "true0": [/* case 0 events */],
    "true1": [/* case 1 events */],
    "true2": [/* case 2 events */],
    "true3": [/* case 3 events */],
    "false": [/* default events */]
  }
}

Loop

Repeating loop with events in the true branch:

{
  "id": "evt-uuid-3",
  "command": "EVENT_LOOP_WHILE",
  "args": {},
  "children": {
    "true": [/* loop body events */]
  }
}
Infinite Loop Warning
Using EVENT_LOOP_WHILE in an On Init script prevents VM_UNLOCK from executing, which permanently blocks state_update(). Never use infinite loops in On Init if the scene type needs per-frame updates. Use actor updateScript instead — it runs via script_runner_update() which is not blocked by VM_LOCK.

Variable Operations

Set Value

{
  "command": "EVENT_SET_VALUE",
  "args": {
    "variable": "12",
    "value": {"type": "number", "value": 42}
  }
}

Increment / Decrement

{"command": "EVENT_INC_VALUE", "args": {"variable": "12"}}
{"command": "EVENT_DEC_VALUE", "args": {"variable": "12"}}

Math Operations

{
  "command": "EVENT_MATH",
  "args": {
    "variable": "12",
    "operator": "add",
    "value": {"type": "number", "value": 5}
  }
}

Variable-to-Variable Math

{
  "command": "EVENT_VARIABLE_MATH",
  "args": {
    "vectorX": "12",
    "operation": "add",
    "other": "13"
  }
}

Actor Operations

Position & Movement

// Set position instantly
{
  "command": "EVENT_ACTOR_SET_POSITION",
  "args": {
    "actorId": "$self$",
    "x": {"type": "number", "value": 10},
    "y": {"type": "number", "value": 5},
    "units": "tiles"
  }
}

// Move to position over time
{
  "command": "EVENT_ACTOR_MOVE_TO",
  "args": {
    "actorId": "$self$",
    "x": {"type": "number", "value": 10},
    "y": {"type": "number", "value": 5},
    "speed": 2
  }
}

Direction & Animation

// Set facing direction
{
  "command": "EVENT_ACTOR_SET_DIRECTION",
  "args": {
    "actorId": "$self$",
    "direction": {"type": "direction", "value": "right"}
  }
}

// Set animation state
{
  "command": "EVENT_ACTOR_SET_ANIMATION_STATE",
  "args": {
    "actorId": "$self$",
    "animState": "default"
  }
}

// Set specific frame
{
  "command": "EVENT_ACTOR_SET_FRAME",
  "args": {
    "actorId": "$self$",
    "frame": {"type": "number", "value": 0}
  }
}

Visibility & Activation

{"command": "EVENT_ACTOR_HIDE", "args": {"actorId": "$self$"}}
{"command": "EVENT_ACTOR_SHOW", "args": {"actorId": "$self$"}}
{"command": "EVENT_ACTOR_DEACTIVATE", "args": {"actorId": "$self$"}}
{"command": "EVENT_ACTOR_ACTIVATE", "args": {"actorId": "$self$"}}
Deactivate vs Hide
EVENT_ACTOR_HIDE sets the HIDDEN flag — the actor stays in the active list but is not rendered. EVENT_ACTOR_DEACTIVATE sets DISABLED and moves the actor to the inactive list, preventing re-activation by the streaming system. Use deactivate for permanent removal, hide for temporary invisibility.

Text & Dialogue

// Display dialogue text
{
  "command": "EVENT_TEXT",
  "args": {
    "text": ["Line 1", "Line 2"],
    "avatarId": ""
  }
}

// Set text animation speed
{
  "command": "EVENT_TEXT_SET_ANIM_SPEED",
  "args": {
    "speed": 1,
    "allowFastForward": true
  }
}

Camera

// Move camera to position
{
  "command": "EVENT_CAMERA_MOVE_TO",
  "args": {
    "x": {"type": "number", "value": 10},
    "y": {"type": "number", "value": 5},
    "speed": 2
  }
}

// Lock camera to player
{
  "command": "EVENT_CAMERA_LOCK",
  "args": {
    "axis": ["x", "y"]
  }
}

Sound & Music

// Play music track
{
  "command": "EVENT_MUSIC_PLAY",
  "args": {"musicId": "uuid-of-track"}
}

// Stop music
{"command": "EVENT_MUSIC_STOP", "args": {}}

// Play sound effect
{
  "command": "EVENT_SOUND_PLAY_EFFECT",
  "args": {
    "type": "beep",
    "pitch": 4,
    "duration": 0.5
  }
}

Screen & Scene Transitions

// Fade in
{"command": "EVENT_FADE_IN", "args": {"speed": 1}}

// Fade out
{"command": "EVENT_FADE_OUT", "args": {"speed": 1}}

// Switch to another scene
{
  "command": "EVENT_SCENE_SWITCH",
  "args": {
    "sceneId": "uuid",
    "x": {"type": "number", "value": 5},
    "y": {"type": "number", "value": 5},
    "direction": "right",
    "fadeSpeed": 1
  }
}

Engine Fields

Engine fields are global C variables exposed to the scripting system. They can be written to or read from game variables.

// Set an engine field to a value
{
  "command": "EVENT_ENGINE_FIELD_SET",
  "args": {
    "engineFieldKey": "c_variable_name",
    "value": {"type": "number", "value": 42}
  }
}

// Read an engine field into a game variable
{
  "command": "EVENT_ENGINE_FIELD_STORE",
  "args": {
    "engineFieldKey": "c_variable_name",
    "variable": "12"
  }
}
Engine Field Timing
Engine field defaults from engine.json are set during script_engine_init.s, before scene loading. Values overridden via EVENT_ENGINE_FIELD_SET in the On Init script only take effect when the script runs — after state_init() has already executed.

Tilemap & Overlay

// Show overlay
{
  "command": "EVENT_OVERLAY_SHOW",
  "args": {"x": 0, "y": 0, "color": "white"}
}

// Hide overlay
{"command": "EVENT_OVERLAY_HIDE", "args": {}}

// Move overlay
{
  "command": "EVENT_OVERLAY_MOVE_TO",
  "args": {"x": 0, "y": 14, "speed": 1}
}

Flow Control

// Wait for a duration
{
  "command": "EVENT_WAIT",
  "args": {"time": 1.0, "units": "time"}
}

// Call a custom event (reusable script)
{
  "command": "EVENT_CALL_CUSTOM_EVENT",
  "args": {"customEventId": "uuid"}
}

// Inline GBVM assembly
{
  "command": "EVENT_GBVM_SCRIPT",
  "args": {"script": "VM_SET_CONST VAR_MY_VAR, 42"}
}

File Structure (.gbsres)

The .gbsres format is used for scenes, actors, triggers, palettes, and other project resources. Each file is a JSON object with a _resourceType field identifying its type.

Scene File

{
  "_resourceType": "scene",
  "id": "uuid",
  "name": "Scene Name",
  "type": "TOPDOWN",
  "backgroundId": "uuid",
  "width": 20,
  "height": 18,
  "script": [/* On Init events */],
  "playerHit1Script": [/* collision events */],
  "actors": [/* actor definitions */],
  "triggers": [/* trigger definitions */]
}
FieldDescription
_resourceTypeAlways "scene"
idUnique scene identifier (UUID)
nameDisplay name in editor
typeScene type: TOPDOWN, ADVENTURE, POINTNCLICK, LOGO, etc.
backgroundIdUUID of the background image resource
width / heightScene dimensions in tiles
scriptOn Init event array (runs when scene loads)
playerHit1ScriptPlayer collision event array
actorsArray of actor definitions
triggersArray of trigger definitions

Actor Definition

{
  "id": "uuid",
  "name": "Actor Name",
  "spriteSheetId": "uuid",
  "x": 5,
  "y": 10,
  "direction": "down",
  "moveSpeed": 1,
  "animSpeed": 15,
  "isPinned": false,
  "persistent": false,
  "script": [/* interact events */],
  "startScript": [/* On Init events */],
  "updateScript": [/* per-frame update events */]
}
FieldDescription
idUnique actor identifier (UUID)
nameDisplay name in editor
spriteSheetIdUUID of the sprite sheet resource
x / yInitial position in tiles
directionInitial facing direction (up, down, left, right)
moveSpeedMovement speed (0–4)
animSpeedAnimation speed (lower = faster; 255 = paused)
isPinnedIf true, actor stays fixed on screen (HUD element)
persistentIf true, actor persists across scene changes
scriptInteract events (triggered by player interaction)
startScriptOn Init events (runs when scene loads)
updateScriptPer-frame update events (runs via script_runner_update)
isPinned and Off-Screen Actors
Pinned actors are auto-activated during load_scene and their positions are screen-relative rather than world-relative. Non-pinned actors are managed by the streaming system and may be deactivated when off-screen. If moving an unpinned actor off-screen from script, use VM_ACTOR_ACTIVATE afterward to prevent streaming deactivation.

Trigger Definition

{
  "id": "uuid",
  "name": "Trigger",
  "x": 5,
  "y": 10,
  "width": 2,
  "height": 2,
  "script": [/* enter events */],
  "leaveScript": [/* leave events */]
}
FieldDescription
idUnique trigger identifier (UUID)
nameDisplay name in editor
x / yPosition in tiles (top-left corner)
width / heightSize in tiles
scriptEvents triggered when player enters the trigger area
leaveScriptEvents triggered when player leaves the trigger area