RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
Level JSON Schema

a

Shipped shared level files live under data/levels/. Editor-authored custom levels live beside the owning game data at data/games/<game_id>/custom_levels/, for example data/games/platformer_demo/custom_levels/ or data/games/project_alchemy/custom_levels/.

The current schema is backward-compatible with the older tiles and spawns fields, but new files should prefer layers and objects.

Core Fields

  • schema_version: current value is 1.
  • id: stable level id.
  • name: display name.
  • tile_size: [width, height] in pixels.
  • metadata: game/editor metadata such as game_type, theme, background, music, camera settings, biome, weather, or palette.
  • legend: map from tile character to metadata, such as type, sprite, walkable, damage, one_way, or tags.
  • layers: ordered tile layers.
  • objects: placed gameplay objects.
  • triggers: optional data-driven trigger definitions.

Layers

Each layer is a dictionary:

{
"id": "terrain",
"type": "tiles",
"collision": true,
"visible": true,
"tiles": [
"........................",
"########################"
]
}

Layer rows should be rectangular. Multiple layers can represent background, terrain, collision, decoration, hazards, foreground, or editor-only annotation layers. The editor supports selecting the active paint layer and adding non-colliding decoration layers, which is important for metroidvania-style rooms where collision, foreground art, secrets, and door markers often need separate authoring passes.

Non-square or irregular rooms should still use a rectangular backing grid. Mark cells outside the playable room shape as void/null terrain instead of shrinking the map around each room. A void tile is a normal legend entry with type: "void" and walkable: false; games should render it as black/outside space, block movement through it, and avoid drawing normal grid details over it. This lets one dungeon level contain several differently shaped rooms and halls inside one map file:

{
"legend": {
" ": { "type": "void", "terrain": "void", "walkable": false, "render": "black", "draw_grid": false },
".": { "type": "empty", "terrain": "stone_floor", "walkable": true },
"#": { "type": "solid", "terrain": "wall", "walkable": false }
},
"layers": [{
"id": "terrain",
"type": "tiles",
"collision": true,
"visible": true,
"tiles": [
" ####### ",
" #.....# ",
"#######.....##### ",
"#...............# ",
"#######.....##### ",
" #.....# ",
" ####### "
]
}]
}

Objects

Objects are placed by tile coordinate:

{
"id": "player_start",
"kind": "player",
"tile": [2, 7],
"facing": "right"
}

Common kind values:

  • player
  • enemy
  • pickup
  • upgrade
  • checkpoint
  • exit
  • door
  • hazard
  • npc
  • resource
  • obstacle
  • trigger_volume
  • secret

Objects can include arbitrary game-specific metadata such as archetype, sprite_id, target, reward, patrol, or script.

Triggers

Triggers are reserved for data-driven interactions:

{
"id": "exit_opened",
"type": "objective_complete",
"conditions": { "collected_at_least": { "coin": 3 } },
"actions": [{ "type": "unlock_exit", "id": "exit_01" }]
}

The trigger condition language should converge with conditionEvaluator as the editor and scene builder mature.

Tooling

  • levelManager.load_level(path) loads either the new schema or legacy tiles/spawns files.
  • levelManager.validate_level(data) returns issue dictionaries suitable for smoke tests and editor display.
  • levelManager.make_template_level(id, width, height) generates starter level JSON.
  • levelEditorManager owns reusable editor mutations for schema v1 data: history, resize, paint, erase, flood fill, eyedropper pick, active-tool cycling, palette visibility, object removal, and compact input badge descriptors.
  • customLevelLibrary resolves, saves, and discovers custom levels from data/games/<game_id>/custom_levels/ so games can load editor-authored levels without editing shipped indexes.
  • data/games/<game_id>/editor_palette.json defines the game-specific visual tile and object palette used by the editor. Tile entries provide tile characters, sprites, and legend metadata; object entries provide kind, sprite, and default placement fields such as enemy archetype, resource id, or exit target. A metroidvania palette can define one-way platforms, breakable blocks, doors, save points, upgrades, boss rooms, and ability gates without changing editor code.
  • scenes/level_editor.tscn opens the Godot level editor for loading, creating, painting, validating, and saving schema v1 JSON levels. It includes a visual tile canvas, legend-backed tile palette, object placement for common gameplay kinds, a game selector that chooses the target custom-level folder, controller-friendly cursor movement, palette cycling, layer cycling, and a raw JSON editor for advanced/manual changes. The visible palette is now scoped to the active tool: tile mode shows only tiles, object mode shows only objects, and erase mode hides the palette entirely. Non-visual operations are routed through levelEditorManager so future platformer, tactical, metroidvania, and room editors can share the same editing behavior.
  • addons/rgf_level_tools/ provides an optional Godot editor plugin. Enable RGF Level Tools in Project Settings -> Plugins to add an RGF Levels dock inside the Godot IDE. The dock browses data/games/<game_id>/custom_levels/, creates starter template levels, validates selected JSON with levelManager, previews raw JSON, reveals files on disk, opens the existing runtime level editor scene, builds editable Godot 2D scenes from selected JSON, and exports the active Godot scene back to JSON. This makes the Godot editor a first-class authoring surface without replacing the portable JSON level format.

Godot IDE Workflow

Use this workflow when developing levels inside the Godot editor:

  1. Enable Project -> Project Settings -> Plugins -> RGF Level Tools.
  2. Open the RGF Levels dock.
  3. Select the target game, such as Platformer Demo or Project Alchemy.
  4. Select an existing level or click New to create a schema v1 JSON template under the selected game's custom_levels folder. Built-in levels are shown in the list and can be edited in place.
  5. Use Validate after hand-editing or external-tool edits.
  6. Use Build 2D Scene to generate an editable .tscn bridge from the selected JSON level. The generated scene contains normal Node2D children for layers, tile sprites, and placed objects, so you can use Godot's native 2D viewport, node tree, transform tools, duplication, and inspector.
  7. Use the dock's Library tab to browse the selected game's editor_palette.json. Tiles and objects appear in one shared list, so level authors can select an entry without switching modes. Enable Paint in 2D View to place the selected entry by clicking directly in Godot's 2D viewport. The X/Y fields and Add Selected button remain available for exact grid-cell placement. Move, duplicate, or inspect the created node normally in the 2D editor.
  8. Save or edit the scene normally in Godot.
  9. Use Export Active Scene to write the currently open RGF scene back to the selected level JSON.

The plugin is intentionally a bridge, not a competing level format. JSON remains the portable runtime/source format. Generated .tscn files are editable Godot authoring views over that data, with RGFLevelRoot, RGFLevelTile, and RGFLevelObject marker scripts preserving the metadata needed to round-trip back to JSON. Game runtime code, the in-game editor, the Godot editor plugin, and future external tools should all load and save the same schema v1 JSON files.

When editing through the native 2D viewport, each non-empty tile becomes a sprite-backed RGFLevelTile node and each placed object becomes an RGFLevelObject node. Moving a node changes its tile coordinate on export. Deleting a node removes it from the exported JSON. Adding new marker-scripted nodes manually is supported, but the fastest workflow is usually to duplicate an existing tile or object and then change its exported properties in the Inspector.

The Library tab is powered by data/games/<game_id>/editor_palette.json. Adding a tile, enemy, pickup, exit, door, NPC, resource, or future metroidvania ability gate to that file makes it available to the Godot plugin without changing plugin code. A future plugin pass should add direct click-to-paint drag painting, eraser mode, and rectangle brushes; the current pass provides a resizable palette tab with data-driven click placement, exact-cell add/place, and normal Godot 2D editing.

Games consume the exported JSON from the same source path the plugin writes. Custom levels are written to data/games/<game_id>/custom_levels/. Platformer built-in levels are standalone schema v1 files under data/levels/, so exporting overwrites those files directly. Project Alchemy adventure stages are embedded inside adventure JSON; the plugin converts a stage into editable schema v1 scene data, then folds the exported layout, objects, enemies, exits, player spawn, and scripts back into the original adventure JSON level entry.

Editor Controls

The editor is intended to work like a lightweight maker tool rather than a text form. The on-screen control strip uses compact button/icon badges so controller, keyboard, and mouse users can understand the current mappings without a long instruction panel.

  • D-pad / arrow keys: move the editor cursor by one tile.
  • A / Enter: place the selected tile or object at the cursor.
  • X / 2: erase at the cursor.
  • Y / 3: cycle Tile, Object, and Erase tools.
  • LB/RB / PageUp/PageDown: cycle the active tile/object palette item.
  • Left Stick button / 5: cycle the active layer.
  • B / 4: open save confirmation.
  • F: flood fill matching connected tiles on the active layer.
  • Q: pick the tile under the cursor and select it in the palette.
  • Ctrl+Z / Ctrl+Y: undo and redo editor changes.

The controller cursor auto-scrolls the canvas so large platformer and metroidvania rooms can be authored without relying on the mouse.

Editor Capability Roadmap

The editor is intentionally moving toward proven tile-map authoring patterns:

  • Layer controls: add lock, hide/show, opacity, tint, and drag reorder for tile, collision, foreground, annotation, and object layers.
  • Object templates: define reusable enemy, pickup, trigger, door, checkpoint, and NPC presets with custom properties.
  • Selection tools: add rectangle selection, copy/paste, stamps, brush sizes, pattern brushes, and object multi-select.
  • Trigger editing: draw rectangular or polygon trigger volumes and bind them to schema triggers.
  • Validation overlays: highlight missing player starts, unreachable exits, invalid object metadata, and unsupported tiles for the selected game.
  • Playtest loop: launch the selected level in its target game directly from the editor.
  • Future sprite support: use game sprite mappings to preview animated tiles, enemies, pickups, portals, and hazards in-editor.