Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GODOT_PATHNoPath to the Godot 4 executable. If not set, it is auto-detected.
GODOT_PROJECTNoGodot project directory to use. If not set, it is found from the working directory.
MESHY_API_KEYNoOptional Meshy API key for AI 3D generation.
OPENAI_API_KEYNoOptional OpenAI API key for AI image generation.
ELEVENLABS_API_KEYNoOptional ElevenLabs API key for AI SFX generation.
GODOT_FORGE_LAUNCHNoStart the editor when it isn't running. Valid values: gui, headless, none.gui
POLY_PIZZA_API_KEYNoOptional Poly Pizza API key for CC0 asset search/download.
GODOT_FORGE_PROFILENoTool profile: core = 16 essential tools for clients with small tool budgets; full = all tools.full

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
projectA

Project-level info and settings of the connected Godot project: overview, project settings, autoloads (singletons), input map actions, physics/render layer names, plugins, UIDs. Also creates brand new projects.

Actions:

  • info: {} overview: name, Godot version, main scene, autoloads, input actions, file counts, open scenes, renderer.

  • get_setting: {name} read a project setting, e.g. 'display/window/size/viewport_width'.

  • list_settings: {prefix?, limit?} list settings under a prefix, e.g. 'physics/2d'.

  • set_setting: {name, value} or {settings: {name: value}} change project settings (saved to project.godot).

  • set_main_scene: {scene} set the scene that runs on Play.

  • autoloads: {} list autoload singletons.

  • add_autoload: {name, path} register a script/scene as a global singleton (e.g. an event bus or game state).

  • remove_autoload: {name} unregister an autoload singleton.

  • input_actions: {include_builtin?} list input actions and their bindings.

  • add_input_action: {name, events: ['key:W', 'key:Up', 'joy:a', 'joy_axis:left_x-', 'mouse:left'], deadzone?, append?} or {actions: {name: [events]}} create/replace input actions. Prefer actions over hardcoded keys in scripts.

  • remove_input_action: {name} delete an input action.

  • layers: {kind?} named layers (2d_physics, 3d_physics, 2d_render, ...).

  • set_layer_name: {kind, layer: 1-32, name} name a physics/render layer, returns its bit value for collision_layer/mask.

  • plugins: {} list add-ons in res://addons and whether they are enabled.

  • set_plugin_enabled: {name, enabled}

  • uid: {path} convert between res:// path and uid://.

  • create_project: {path, name, kind?: '2d'|'3d', renderer?: 'forward_plus'|'mobile'|'gl_compatibility', pixel_art?, width?, height?} create a new Godot project folder with Godot Forge installed, then connect to it (launches the editor).

filesA

Read, write, search and manage files inside the Godot project (res://). Writes keep the editor in sync: scripts are reloaded and their compile errors returned, scenes/resources are refreshed, assets reimported. Reading an image returns it as a picture.

Actions:

  • list: {path='res://', recursive=true, pattern?='*.gd', include_addons?, limit?} list files with their resource type.

  • search: {query, regex?, case_sensitive?, glob?, path?, limit?} grep text files (gd, tscn, tres, gdshader, cfg, json, md...).

  • read: {path, offset?, limit?} read a text file (line range optional) or view an image.

  • write: {path, content, overwrite?=true} create/replace a file. .gd files come back with 'diagnostics'.

  • edit: {path, edits: [{old, new, replace_all?}]} exact string replacements (old must match exactly once, tabs matter). Prefer this over rewriting whole files.

  • move: {from, to, update_references?=true} move/rename, updating res:// references in scenes/scripts.

  • copy: {from, to}

  • delete: {path} move a file/folder to the OS trash.

  • mkdir: {path} create a folder (and parents).

  • exists: {path} does a file/folder exist, and its resource type.

  • dependencies: {path} what a resource depends on and what uses it.

  • rescan: {reimport?: [paths]} rescan the filesystem / force reimport (after changing files outside the editor).

sceneA

Create, open, save and inspect scene files (.tscn). The edited scene is the target of the node/signal tools. Edits are auto-saved after every call.

Actions:

  • create: {path, root_type='Node2D', root_name?, inherits?: 'res://base.tscn', props?, script?, open?=true, set_main?} new scene file (becomes main scene if none is set).

  • open: {path} open in the editor and make it the edited scene.

  • current: {} the edited scene and all open scenes.

  • tree: {scene?, path?, depth?, props?, expand_instances?} node tree of the edited (or any) scene. props=true adds non-default property values.

  • list: {path?} every scene in the project with its root type.

  • instance: {scene_path, parent?='.', name?, props?} add an instance of another scene (e.g. enemy.tscn) as a child.

  • pack_branch: {path, save_path} save a node subtree as its own reusable scene and replace it with an instance.

  • save: {path?} save (or 'save as' with path).

  • save_all: {} save every open scene.

  • close: {path?, save?=true}

  • reload: {path?} reload from disk.

  • source: {path?} raw .tscn text.

nodeA

Add, edit and inspect nodes in the edited scene. Every change is undoable (Ctrl+Z) and saved. Build whole subtrees in one 'add' via children. Returned 'warnings' flag setup mistakes (missing collision shapes, textures...).

Actions:

  • add: {type, name?, parent?='.', props?, script?, groups?, index?, children?: [same spec...]} or {nodes: [specs], parent?}. type = class (CharacterBody2D), class_name, res://x.gd or res://x.tscn (instance).

  • set: {path | paths[], props: {name: value}} set properties (sub-properties like 'position:x' allowed).

  • get: {path, props?: [names], all?} type, inheritance, script, non-default props (or the requested ones), children, groups, signal connections, warnings.

  • delete: {path | paths[]}

  • duplicate: {path, name?, parent?, count?, offset?: [x,y]} copies (with offset per copy, great for rows of platforms/coins).

  • move: {path, new_parent?, index?, keep_global_transform?=true} reparent and/or reorder.

  • rename: {path, name}

  • find: {name?: glob, type?, group?, script?, under?} search nodes.

  • call: {path, method, args?, property?} call a method in the editor (e.g. curve.add_point via property='curve').

  • change_type: {path, type, keep_script?} swap a node's class keeping children/compatible props (works on the root too).

  • add_to_group: {path, group}

  • remove_from_group: {path, group}

  • select: {path | paths[]} select in the editor (shows it to the user).

  • selection: {} what the user has selected — use it to resolve 'this node'.

signalA

Inspect and wire signals in the edited scene. Connections made here are saved in the scene. 'connect' can generate the handler function in the target's script.

Actions:

  • list: {path, connected_only?} signals of a node with their arguments and connections.

  • connect: {from, signal, to, method?, create_method?=true, body?, binds?, deferred?, one_shot?} e.g. Area2D body_entered -> Player. Method defaults to on_.

  • disconnect: {from, signal, to, method}

  • graph: {scope?: 'scene'|'project'} connection graph (project scope parses all scenes and scripts incl. .connect()/.emit() calls).

scriptA

GDScript (and C#) files. Creating/writing/editing a .gd reloads it in the editor and returns compile diagnostics immediately — fix errors before running. Use templates for common controllers.

Actions:

  • create: {path, content? | template?: 'default'|'empty'|'platformer_2d'|'topdown_2d'|'fps_3d'|'state_machine'|'autoload_events', extends?, class_name?, actions?: {jump,left,right,up,down}, attach_to?: node path, scene?} new script, optionally attached.

  • read: {path, outline?} script source (and its outline).

  • write: {path, content} replace the whole script; returns diagnostics (errors + warnings).

  • edit: {path, edits: [{old, new, replace_all?}]} exact replacements; returns diagnostics.

  • lint: {path | paths} full language-server diagnostics (all errors and warnings such as unused variables, shadowing, unsafe casts) for scripts on disk.

  • validate: {path? | paths? | content?} compile check. No args = every script in the project.

  • outline: {path} extends, class_name, signals, exported vars, functions with line numbers.

  • attach: {path: node, script, scene?}

  • detach: {path: node}

  • references: {symbol} find usages across the project.

  • classes: {} project class_name classes.

  • templates: {} available templates.

  • open: {path, line?} show the script to the user in the script editor.

resourceA

Resource files (.tres): materials, shapes, themes, curves, custom Resource classes (e.g. item data). Inline resources can also be set directly through node props with {"type": "ClassName", ...}.

Actions:

  • create: {path, type, props?, script?} e.g. type=StandardMaterial3D props={albedo_color:'#ff0000'}; type=Resource script=res://item_data.gd for custom data.

  • read: {path, all?}

  • edit: {path, props}

  • duplicate: {path, to, props?}

  • assign: {path: node, property, resource: 'res://..' | {type,...}, scene?}

  • extract: {path: node, property, save_path} save an embedded resource to its own file.

  • types: {base='Resource', filter?} instantiable resource classes.

introspectA

Ask the running engine about its exact API (no guessing): class members with types/defaults/enums, where a member is declared, node types by domain. Unknown Godot 3 names come back with suggestions.

Actions:

  • class: {name, sections?: ['properties','methods','signals','constants'], filter?, inherited?} members of an engine or project class.

  • search: {query, base?} find class names.

  • member: {name, base?} which classes declare a method/property/signal.

  • node_types: {domain?: '2d'|'3d'|'ui', base?}

  • check_parent: {child, parent} warn about invalid parent/child type combos.

editorA

Editor state and connection management: status, logs, undo/redo, notifications to the user, editor settings, and which Godot project/editor this server talks to.

Actions:

  • status: {} edited scene, selection, playing?, connected clients, log counts.

  • logs: {since?, level?: 'error'|'warning', source?: 'editor'|'game', limit?} editor + game output.

  • clear_logs: {} clear the captured log buffer.

  • undo: {steps?=1} undo AI or user edits in the edited scene.

  • redo: {steps?=1}

  • notify: {message} show a toast to the user in the editor.

  • main_screen: {name: '2D'|'3D'|'Script'|'AssetLib'}

  • get_setting: {name} editor setting.

  • set_setting: {name, value}

  • forge_settings: {set?: {autosave?, auto_changeset?, screenshot_max_size?}} Godot Forge behaviour.

  • restart: {save?=true} restart the editor (after enabling plugins, changing rendering method...).

  • connection: {} which project/editor is connected, Godot version, running editors.

  • use_project: {path} switch to another Godot project folder (launches its editor if needed).

  • install_addon: {path?, force?} copy/update the Godot Forge add-on in a project and enable it.

batchA

Run many editor operations in one round trip as a single transaction. With atomic=true (default) the batch stops at the first error and undoes everything it did. Use it to build a whole level or UI in one go.

Actions:

  • run: {operations: [{method: 'node.add', params: {...}}, ...], atomic?=true} method = '.' for editor-side tools (project, files, scene, node, signal, script, resource, animation, tiles, ui, physics, ...).

execA

Escape hatch: run a GDScript snippet in the editor or in the running game when no dedicated action fits (bulk procedural generation, one-off fixes, complex queries). Prefer dedicated tools; file changes made here are still tracked by changesets.

Actions:

  • editor: {code} body of func run(editor: EditorInterface, scene: Node, forge) -> Variant; return a value. forge.find_node(path), forge.begin(name)/forge.commit() for undoable edits.

  • game: {code} body of func run(tree: SceneTree, scene: Node) in the running game; return a value.

  • eval: {expression, path?} evaluate one expression in the editor with a node as self.

runA

Play the game from the editor and read its output. 'play' saves open scenes, launches, waits until the Godot Forge runtime inside the game connects, and returns startup errors. Then use game/input/view to interact.

Actions:

  • play: {scene?: 'main'|'current'|'res://x.tscn', restart?=true, timeout?=20, settle?=0.5, mute?} start the game. mute silences game audio (default: the godot_forge/mute_game_audio editor setting; always on in headless/test editors).

  • stop: {} stop the running game.

  • status: {} playing? connected? paused on an error? live fps/scene.

  • errors: {since?, level?='error'|'warning', source?} runtime + editor errors with script file:line and stack.

  • output: {since?, limit?} everything the game printed.

  • continue: {} resume after the debugger stopped on an error.

gameA

Inspect and manipulate the RUNNING game (after run.play): live scene tree, node state, evaluate expressions, call methods, wait for conditions, record values over time, time control, performance. Paths are relative to the current scene root; use /root/Autoload for singletons.

Actions:

  • info: {} current scene, fps, frame, viewport size, paused, time_scale.

  • tree: {path?, depth?=6, props?, whole_tree?} live node tree (includes runtime-spawned nodes).

  • get: {path, props?: ['velocity', 'position:x']} node state; default = non-default props + global_position/velocity/is_on_floor + screen_position.

  • set: {path, props} change live values (for testing; not saved).

  • call: {path, method, args?}

  • eval: {expression, path?} Godot Expression with the node as self, e.g. "get_node('Player').health", "get_tree().get_nodes_in_group('enemies').size()". Or {expressions: [...]}

  • wait: {seconds} | {condition: expr, path?, timeout?} | {node: path, gone?, timeout?} | {signal, path, timeout?} wait inside the game.

  • sample: {path, props?=['global_position'], seconds?=1, interval?=0.1} time series of values (did it move/fall/animate?).

  • time: {time_scale?, paused?, step_frames?} slow-mo, pause, frame stepping.

  • perf: {sample_seconds?} fps, frame times, draw calls, node/object counts, memory.

  • raycast: {from, to, mask?, areas?} physics ray in the game world (2D or 3D by vector size).

  • change_scene: {scene} switch scenes in the running game.

  • quit: {code?} quit the game from inside (tests quit handling).

  • audio: {mute?, volume_db?} mute/unmute the running game's master bus; returns which players are currently playing (verify sounds without hearing them).

inputA

Play the running game: press input actions, keys, gamepad buttons, click/drag at viewport coordinates or directly on a node (UI buttons), type text. Steps run in order with real timing. Also record the user's play session and replay it.

Actions:

  • send: {steps: [...]} where each step is one of: {action:'jump', hold?:0.2} | {action, pressed:true/false} | {key:'Space'|'Ctrl+S', hold?} | {click:[x,y], button?, double?, space?:'viewport'|'screenshot'} | {click_node:'UI/StartButton'} | {mouse_move:[x,y]} | {drag:[[x1,y1],[x2,y2]], seconds?} | {joy:'a'} | {axis:'left_x', value:-1, hold?} | {text:'hello'} | {wait:0.5} | {release_all:true}

  • record: {mode: 'start'|'stop', include_mouse_motion?} capture real input; 'stop' returns events with timestamps.

  • replay: {events, speed?=1} replay recorded events.

viewA

Look at things. Screenshots of the running game (optionally annotated with node markers), offscreen renders of any scene from chosen angles with automatic framing (no editor camera fiddling), editor viewport screenshots, and previews of textures/meshes/materials/scenes. Requires a non-headless editor for rendering.

Actions:

  • game: {max_size?=1280, annotate?, annotate_groups?, format?} screenshot of the running game. Returns viewport_size + coord_scale (click coordinate = image px * coord_scale).

  • render: {scene?, focus?: node path, angles?: ['iso','front','top','left','right','back','low'] (3D), size?: [w,h], zoom? (2D), preview_light?=true} render a scene offscreen, auto-framed.

  • editor: {which?: 'auto'|'2d'|'3d'|'editor'} screenshot of the editor viewport or whole editor window (what the user sees).

  • preview: {path} picture of a texture, mesh, material or scene file.

testA

Verify the game works. Scenarios are scripted playtests (play → input → wait → assert → screenshot) that you can save under res://tests/scenarios and re-run as regression tests. Also project lint (broken references, missing shapes/textures, script errors), GUT/gdUnit4 unit tests, and screenshot baselines.

Actions:

  • scenario: {scenario: {name?, scene?, steps: [...], keep_running?, stop_on_failure?=true, mute?=true}, save_as?: 'name'} run a playtest (audio muted unless mute=false). Steps: {wait_for: expr} {wait_node: path} {wait_signal: {path, signal}} {wait: s} {input: [input steps]} {assert: expr, message?} {expect_node: path} {expect_no_node: path} {eval: expr} {call: {path, method, args}} {set: {path, props}} {sample: {...}} {screenshot: label} {compare_baseline: 'res://tests/baselines/x.png'} {assert_no_errors: true} {time_scale: n}. Expressions run with the scene root as self.

  • run_all: {} run every saved scenario in res://tests/scenarios.

  • list: {} saved scenarios and detected unit test frameworks.

  • lint: {path?} check all scenes (missing dependencies, broken refs, missing collision shapes/textures) and all scripts (compile errors). Run before playing.

  • unit: {framework?: 'gut'|'gdunit4', dir?='res://test', filter?} run unit tests headless.

  • compare_image: {image_path | image_b64, baseline, threshold?=0.01, update?} compare against a baseline PNG (records it if missing).

docsA

Official Godot class reference for the EXACT engine version installed (signatures from the engine, descriptions from the matching release), plus Godot 3→4 migration notes and built-in game-dev guides. Check here before using an API you are not 100% sure exists in Godot 4 — most broken AI-written GDScript comes from Godot 3 habits.

Actions:

  • search: {query} find classes/methods/properties/signals, e.g. 'move and slide', 'tween property', 'raycast'.

  • class: {name, filter?, full?} class reference: description, properties, methods, signals, enums. filter narrows to members containing text.

  • member: {name: 'Class.member'} full docs for one member.

  • migrate: {query?} Godot 3 → 4 renames and syntax changes (filtered by query), e.g. 'yield', 'KinematicBody2D', 'export', 'tween'.

  • guide: {topic?} built-in guides (no topic = list): editor_first (read before building scenes), gdscript, best_practices, 2d_platformer, top_down, 3d_basics, ui, animation, physics, tilemaps, shaders, audio, save_load, performance, game_feel, and more.

  • status: {} docs index status (version, description download progress).

changesA

Changesets make AI work reviewable and reversible (like a sandbox). A changeset opens automatically before the first edit and records a baseline of the whole project; the user sees pending files in the editor's Forge dock with Approve/Discard buttons. Use checkpoints before risky steps and restore if an approach fails. Backed by a private git history in .godot/forge (the user's own git is untouched; requires git).

Actions:

  • status: {} open changeset (label, baseline, checkpoints) and changed files.

  • diff: {path?, checkpoint?} unified diff of text files since the baseline (or a checkpoint) + stat.

  • begin: {label, accept_previous?=true} start a named changeset for a new task (closes the previous one as accepted).

  • checkpoint: {name?} save a restore point.

  • restore: {checkpoint} roll every file back to a checkpoint (changeset stays open).

  • revert_files: {paths} restore selected files to the baseline.

  • approve: {message?} accept all pending changes (only when the user asked you to, or at the end of a task they approved).

  • discard: {} restore everything to the baseline and close the changeset. Destructive: confirm with the user first.

  • history: {limit?} past changesets with outcomes and ids.

  • revert_changeset: {id} undo a previously approved changeset (opens a new changeset for the revert).

animationA

Animate anything: build AnimationPlayer animations with all tracks and keys in one call (property tweens, method calls, sounds, 3D transforms), SpriteFrames for AnimatedSprite2D/3D from image files or a sliced sprite sheet, and AnimationTree state machines / blend spaces / blend trees with transitions and conditions. All edits are undoable.

Actions:

  • create: {name ('walk' or 'lib/walk'), tracks: [{type?=value, path: 'Sprite2D:modulate', keys: [{time, value, easing?}]}], length? (default: last key time), loop?: none|linear|pingpong|true, path? (AnimationPlayer; created if it doesn't exist), parent?/player? (where/what to name a new player), library?='', autoplay?, reset?=true (key the current values of animated properties into the default library's RESET animation, like the editor does; the editor applies RESET before saving so previews/AnimationTrees don't leak into the scene), step?, validate?=true, overwrite?=true} build a complete animation; adds an AnimationPlayer when the scene has none. Values: '#ff0000', [x,y], numbers, 'res://tex.png'. 2D 'rotation' is radians (or animate 'rotation_degrees'). Call methods with a method track: {type: 'method', path: 'Player', keys: [{time, method, args}]}.

  • list: {path?} animations (length, loop, track summary) of one player, or of every AnimationPlayer in the scene.

  • get: {path?, name} full tracks and keys of an animation.

  • edit: {path?, name, length?, loop?, step?} change animation settings.

  • add_track: {path?, name, tracks: [{type, path, keys}]} (or track: {...}) add tracks to an existing animation; extends length to fit keys (extend?=true); reset?=true adds missing RESET tracks.

  • set_keys: {path?, name, track: index|'Sprite2D:modulate', keys: [...], replace?=true} replace a track's keys (replace=false merges, overwriting keys at the same time).

  • remove_track: {path?, name, track: index|path}

  • delete: {path?, name} delete an animation.

  • rename: {path?, name, new_name}

  • set_autoplay: {path?, name} play this animation when the scene starts (name='' clears).

  • sprite_frames: {path: AnimatedSprite2D/3D node or res://frames.tres, animations: {name: {frames: ['res://run_1.png', 'res://run_*.png', {texture, duration}] | sheet: {texture, hframes, vframes, row? | frames?: [indices] | start?/count?, frame_size?: [w,h], margin?, separation?}, fps?=10, loop?=true|false|pingpong}}, autoplay? (animation name, or true = the first one), play? (animation shown in the editor), replace? (default merges into existing frames), save_path?} create SpriteFrames and assign it (sheets are sliced into AtlasTextures). If the sprite already uses a SpriteFrames .tres file, that file is updated.

  • tree: {path? (AnimationTree; created if missing) | parent?+name?, anim_player? (default: the only AnimationPlayer), type?=state_machine|blend_space_1d|blend_space_2d|blend_tree, states: ['idle', {name, animation?} | {name, type: blend_space_2d, blend_points}], transitions: [{from (name, list or '*'), to, condition?, expression?, switch_mode?: immediate|sync|at_end, auto?, xfade?, priority?}], start?, blend_points?: [{animation, pos: number|[x,y]}], min_space?, max_space?, nodes?/connections? (blend_tree: [{name, type: animation|blend2|blend3|add2|sub2|one_shot|time_scale|time_seek|transition, animation?, inputs? (transition: ['idle', 'run']), props?}], [{from, to: name|'output', port?: index or input name}]), parameters?: {'conditions/moving': false, 'shot/request': 'fire'}, props? (AnimationTree node props), active?=true, reset?=true (add missing RESET tracks so the tree playing in the editor can't leak its pose into the saved scene)} build a complete AnimationTree in one call; replaces the tree_root of an existing tree.

  • tree_info: {path?} describe an AnimationTree: states, transitions, blend points, settable parameters, problems (missing animations).

  • set_parameter: {path?, name: 'conditions/moving' | 'blend_position' | 'shot/request' (fire|abort|fade_out) | 'state/transition_request', value} or {parameters: {name: value}} set AnimationTree parameters (in game code: $AnimationTree.set('parameters/conditions/moving', true)).

tilesA

2D tile maps with TileMapLayer nodes (the deprecated TileMap node is never used). Build a TileSet from an atlas image in one call (tiles auto-detected from non-transparent cells, collision, terrains for autotiling, custom data), add layers, then paint: cells/rects/lines, terrain autotiling, or whole levels from ASCII art. All painting is undoable. Coordinates are map cells, tiles are atlas coords [x, y].

Actions:

  • create_tileset: {path: res://tiles/world.tres, texture: res://art/tiles.png, tile_size=[16,16], separation?=0|[x,y], margin?=0|[x,y], all_tiles?=false (else only non-transparent cells get tiles), overwrite? (layers of open scenes using the old TileSet are relinked), tile_shape?, physics_layers?: [{collision_layer: [1|'world'], collision_mask: [...]}], full_collision?: bool (full-square polygon on every tile) | collision_tiles?: [[x,y] | {tile:[x,y], points?:[[x,y]...] (tile-centered), one_way?}], terrains?: [{name, color?, mode?: match_corners_and_sides|match_sides|match_corners, block?: [x,y] (origin of a 3x3 autotile block: corners/edges/center; or {origin, size}), tiles?: [[x,y]...] (fully this terrain) | {"x,y": 'all' | ['top','right','bottom_right',...] | '010/111/010' 3x3 mask | {center:'grass', top:'dirt', ...}}}], custom_data?: [{name, type: int|float|bool|string|vector2|color..., values?: {"x,y": value}}]} create a TileSet from an atlas image. No art yet? assets.placeholder {kind: 'tileset'} makes one.

  • info: {path: res://x.tres | TileMapLayer node, tiles?=true} sources, atlas grid, tile coords (with collision/terrain/custom data per tile), physics layers, terrain sets, custom data; for a layer also used cells/rect.

  • create_layer: {tileset: res://x.tres, name?='TileMapLayer', parent?='.', position?, index?, props?: {z_index, y_sort_enabled, collision_enabled, ...}} add a TileMapLayer node. Use several layers for background/ground/decoration.

  • paint: {path: layer, cells: [[x,y],...] | rect: [x,y,w,h] | line: [[x1,y1],[x2,y2],...], tile: [ax,ay] (or [[ax,ay],[bx,by]] to pick randomly for variety), source?=first, alternative?=0} set cells to a tile.

  • fill_rect: {path, rect: [x,y,w,h], tile: [ax,ay], border?: [ax,ay] (different tile on the edge), hollow?: bool (only the edge; interior erased)} fill a rectangle, e.g. rooms with walls.

  • erase: {path, cells | rect | line} remove tiles.

  • terrain: {path, cells | rect | line, terrain: name|index, terrain_set?=0, mode?: connect|path, ignore_empty_terrains?=true} paint with terrain autotiling (the TileSet needs terrains, see create_tileset). Use -1 as terrain to erase terrain-aware.

  • from_ascii: {path, rows: ['##########', '#........#', '#..gggg..#', '##########'], legend: {'#': [3,0], '.': null (erase), 'g': {terrain: 'grass'} | 'grass', 'w': {tile: [1,0], source?, alternative?}}, origin?=[0,0], clear?=false} paint a whole level from ASCII art; spaces leave cells untouched. Best way to lay out levels.

  • read: {path, rect?: [x,y,w,h] (default: used rect), legend?: same legend as from_ascii ({char: [ax,ay] | null (empty char) | 'grass' | {terrain: 'grass'}}), cells?: bool} used cells plus an ASCII picture (terrain cells map to their terrain's char; other unknown tiles get auto characters, returned in auto_legend). Use it to check what's painted.

  • clear: {path} erase every cell of the layer (undoable).

physicsA

Physics bodies and collision: create a body/area with its collision shape (and optionally its sprite/mesh, auto-fitted) in one call, fit shapes to visuals, set collision layers/masks by name, add joints, raycast the edited scene, and change project physics settings (gravity, tick rate, engine).

Actions:

  • body: {type: static_2d|character_2d|rigid_2d|area_2d|animatable_2d|static_3d|character_3d|rigid_3d|area_3d|animatable_3d (or a class name), name?, parent?='.', position?, rotation? (degrees), shape?: {type: rect|circle|capsule|segment|world_boundary|convex|concave|polygon (2D) | box|sphere|capsule|cylinder|world_boundary|convex|concave|polygon (3D), size?, radius?, height?, points?, position?, rotation?, one_way?, disabled?} (default rect 32x32 / box 1m), shapes?: [several], sprite?: res://img.png (adds Sprite2D/Sprite3D) | mesh?: {type: 'BoxMesh', size: [1,1,1]} (adds MeshInstance3D) — the first shape is fitted to the visual (its opaque pixels) when it has no size/radius/points, layer?: [names|numbers], mask?: [names|numbers], script?, groups?, props?, visual_props?, children?: [node specs]} create a physics body + CollisionShape (+ visual) in one undoable step.

  • fit_shape: {path: body, its CollisionShape, or its Sprite2D/MeshInstance3D child, from?: visual node path (default: first Sprite2D/AnimatedSprite2D/MeshInstance3D/Sprite3D child), kind?: rect|circle|capsule|convex (2D, convex traces sprite alpha) | box|sphere|capsule|cylinder|convex|trimesh (3D), grow?: px/units (negative shrinks), trim?=true (2D: fit the opaque pixels of the current frame, not the padded frame rect)} size the collision shape to the visual (sprite frame incl. hframes/vframes/region/scale/flip; mesh AABB or hull). Creates the CollisionShape if missing.

  • layers: {path | paths, layer?: ['player'] | [2], mask?: ['world', 'enemies'] | [1, 3], mode?: set|add|remove} set collision_layer/mask using layer names from project settings (name them with project.set_layer_name) or layer numbers 1-32 (not bitmasks). Without layer/mask: shows current layers by name.

  • joint: {type: pin_2d|groove_2d|damped_spring_2d|pin_3d|hinge_3d|slider_3d|cone_3d|generic_6dof_3d, node_a, node_b, parent?=node_a's parent, name?, position? (parent space) | at?: mid|a|b (default mid), props?} connect two physics bodies. Groove/spring length defaults to the distance between the bodies.

  • raycast: {from: [x,y] | [x,y,z], to, mask?: names|numbers, areas?: bool, type?: 2d|3d} cast a ray in the edited scene (editor world, global coordinates): hit collider, position, normal. For the running game use game.raycast.

  • settings: {gravity?, gravity_direction?, linear_damp?, angular_damp?, engine_3d?: DEFAULT|GodotPhysics3D|Jolt Physics, gravity_2d?, gravity_direction_2d?, linear_damp_2d?, angular_damp_2d?, engine_2d?, ticks_per_second?, max_steps_per_frame?, jitter_fix?, interpolation?, settings?: {'physics/...': value}} read/change project physics settings (no args = read). 2D gravity is px/s² (default 980), 3D m/s² (9.8).

navigationA

Pathfinding setup: navigation regions (2D polygons / 3D navmeshes) baked from their child geometry, NavigationAgents with sane defaults and usage code, navigation links (jumps/teleports), an overview of the scene's navigation, and editor-side path queries to verify a level is connected.

Actions:

  • region: {type?: 2d|3d (default from parent), name?, parent?='.', outline?: [[x,y],...] | outlines?: [...] (several walkable areas, merged) | rect?: [x,y,w,h] (2D walkable area, pixels), holes?: [[[x,y],...]] (2D: unwalkable areas, added as NavigationObstacle2D children that carve the bake), sources?: [node paths] (extra geometry to bake from, e.g. a TileMapLayer whose tiles have collision, or level nodes that aren't children of the region; switches the region to group source mode), nav?: {agent_radius, cell_size, parsed_geometry_type: meshes|static_colliders|both, source_geometry_mode: root_node_children|groups_with_children|groups_explicit, collision_mask: names|numbers, agent_height, agent_max_climb, ...} (NavigationPolygon/NavigationMesh props; 2D and 3D names both accepted), bake?=true when an outline is given (2D) / always (3D), position?, props?} create a NavigationRegion2D/3D. Obstacles are the region's children (plus sources): 2D bakes carve child collision shapes/meshes out of the outline (agent_radius default 10px); 3D bakes walkable surfaces from child meshes/static bodies. Add children later (physics.body parent: region) then navigation.bake.

  • bake: {path: region, sources?: [node paths], nav?: {...bake settings, as in region}} (re)bake the region's navigation polygon/mesh from its source geometry (synchronous, undoable). Returns polygon/vertex counts and bounds.

  • agent: {parent: body node, type?: 2d|3d, name?, radius?, max_speed?, avoidance?: bool, path_desired_distance?, target_desired_distance?, props?} add a NavigationAgent2D/3D (defaults tuned: 4px / 0.5m path & target distances). Returns the movement code to use in the body's script.

  • link: {from: [x,y] | [x,y,z], to, parent?='.', name?, bidirectional?=true, props?: {enter_cost, travel_cost, navigation_layers}} add a NavigationLink2D/3D connecting two points (jump down a ledge, ladder, teleporter). Positions are in the parent's space.

  • path: {from: [x,y] | [x,y,z], to, type?: 2d|3d, navigation_layers?=1, tolerance?=8px/0.5m} query a path on the edited scene's navigation map: points, length, reachable. Use it to verify level connectivity before running the game.

  • info: {path?} one navigation node, or (no path) a scene overview: regions (polygons, bounds, agent radius, obstacle count), agents, links, obstacles, map cell sizes.

world3dA

Build 3D levels in few calls: primitive meshes with material + collision, CSG blockouts (nested boolean trees), materials (files or on nodes), lights, WorldEnvironment/sky presets with a sun, cameras aimed at targets, model import options + instancing, GridMap painting and MeshLibrary creation, and scattering props/vegetation over terrain. Every scene change is undoable. Positions are [x, y, z] in meters (Y up; a Node3D looks down its -Z axis). Colors are hex strings like '#aa8844' or names like 'orange'. Numbers and vectors are validated: a malformed value returns an error instead of a zero/NaN result.

Actions:

  • mesh: {shape: box|sphere|capsule|cylinder|cone|plane|prism|torus|quad|text (default box), parent?='.', name?, size? (box/prism [x,y,z] or one number; plane [w,d]; quad [w,h]; sphere/cylinder: diameter from size), radius?, height?, top_radius?, bottom_radius?, inner_radius?, outer_radius?, text?, font_size?, depth?, pixel_size?, font?, mesh_props?: {raw PrimitiveMesh props}, mesh?: 'res://x.tres' (a Mesh resource instead of shape), material?, position?, rotation_degrees?, scale?, look_at?: [x,y,z] | node path, cast_shadow?, props?: {raw MeshInstance3D props}, collision?: none|static|convex|trimesh} MeshInstance3D in one call. collision='static' adds StaticBody3D > CollisionShape3D with a best-fit shape (box/sphere/capsule/cylinder; plane/torus/text -> trimesh, cone/prism -> convex). Defaults: box 1m, sphere r=0.5, plane 2x2.

  • csg: {type: box|sphere|cylinder|cone|torus|polygon|mesh|combiner, parent?, name?, operation?: union|intersection|subtraction, size? (box [x,y,z]; sphere/cylinder diameter), radius?, height?, inner_radius?, outer_radius?, sides?, polygon?: [[x,y],...], depth?, mode?, mesh?: {shape, size...} | 'res://x.tres', material?, use_collision? (root only), position?, rotation_degrees?, scale?, props?, children?: [same spec...]} CSG blockout. Build a whole shape in one call, e.g. {type: 'combiner', name: 'House', use_collision: true, children: [{type: 'box', name: 'Walls', size: [4,3,4]}, {type: 'box', operation: 'subtraction', size: [1,2,1], position: [0,1,2]}]}. A material on a combiner becomes its material_override. Parent can be an existing CSG node.

  • material: {path: 'res://mat.tres' | node path, type?: standard|orm|shader (default: edit the existing material, else standard), props?: {albedo_color, albedo_texture, metallic, roughness, emission: '#hex', emission_energy, emission_texture, normal_texture, normal_scale, ao_texture, height_texture, unshaded, transparent, double_sided, uv_scale, triplanar, billboard, rim, clearcoat, filter: 'nearest', ...any BaseMaterial3D property; for shader: shader, params}, albedo_color?/color?/albedo_texture?/metallic?/roughness?/emission?/shader?/params? (shortcuts for props), material?: 'res://existing.tres' | '#hex' | {props} (node mode: what to assign), surface? (surface override index), save_as? (node mode: also save the material to this .tres and assign the file), assign_to? (file mode: also assign to this node), overwrite?} With a .tres path: create, or edit in place (every user of the file changes; a bad key changes nothing). With a node path: assign to material_override (meshes), material (CSG, CanvasItem, FogVolume) or a surface override; editing a node whose material is a shared file edits an embedded copy (reported in 'note').

  • light: {type: directional|omni|spot (default omni), parent?, name?, color?, energy?, range? (omni/spot), angle? (spot cone degrees 0-180), attenuation?, indirect_energy?, specular?, shadows?, position?, rotation_degrees?, look_at?: [x,y,z] | node path, props?: {raw Light3D props}} add a light. Directional defaults to rotation [-50,-30,0] with shadows.

  • environment: {preset?: default|sunny|night|foggy|studio|space, sky?: {type: procedural|panorama|physical|shader, top_color, horizon_color, ground_color, ground_horizon_color, energy, sun_size, panorama: 'res://sky.hdr', shader, params} | 'res://sky.hdr' | 'res://sky.gdshader' | false, ambient?: '#hex' | energy | {color, energy, source, sky_contribution}, fog?: bool | density | {density, color, height, height_density, sky_affect, ...fog_* without prefix}, volumetric_fog?, glow?: bool | intensity | {intensity, bloom, threshold, ...}, ssao?, ssil?, ssr?, sdfgi?, tonemap?: 'filmic'|'aces'|'agx'|'linear' | {mode, exposure, white}, adjustment?: {brightness, contrast, saturation}, background?: 'sky' | '#hex', props?: {raw Environment props}, sun?: bool | {color, energy, rotation_degrees, shadows, name, props}, update_sun?=true, save_path?, reset?, keep?, parent?, name?} Creates or updates the scene's single WorldEnvironment (+ Sky, + a DirectionalLight3D sun unless one exists, which is updated instead). A preset replaces the current look (keep=true layers it on top); other keys tweak the current one.

  • camera: {parent?, name?='Camera3D', position?=[0,2,5], look_at?: [x,y,z] | node path, rotation_degrees?, fov? (1-179), projection?: perspective|orthographic, size? (orthographic), near?, far?, current?=true, props?} add a Camera3D aimed at a point/node; becomes the current camera (others are un-set, undoably).

  • look_at: {path, target: [x,y,z] | node path, model_front?} rotate a Node3D so its -Z (or +Z with model_front=true, for imported models facing +Z) points at the target.

  • import: {path: 'res://model.glb', props?: {root_type: 'StaticBody3D', root_name, root_scale, root_script, generate_collisions: true, collision_shape: trimesh|convex|decompose_convex|box|sphere|cylinder|capsule|auto, body_type: static|rigid|area, fps, import_animation, generate_lods, light_baking: disabled|static|static_lightmaps|dynamic, or raw keys like 'meshes/ensure_tangents'} (the friendly keys also work at top level)} edit the asset's .import options and reimport. Without props: lists current options. Works for any importer (textures too, with raw keys like 'compress/mode').

  • instance: {model: 'res://x.glb' | 'res://x.tscn', parent?, name?, position?, positions?: [[x,y,z], ...] (several copies, max 500), rotation_degrees?, scale?, props?} instance an imported model or scene.

  • gridmap: {path? (existing GridMap) | parent?+name? (new), mesh_library: 'res://tiles.tres' (required for a new map), cell_size?=[2,2,2], cells?: [{pos: [x,y,z], item: 'Floor' | id, orientation?} or [x,y,z,item,orientation?]], fill?: [{from, to, item, orientation?}] (inclusive boxes, e.g. floors), erase?: [[x,y,z], ...], clear? (wipe first), position?, props?} create or paint a GridMap (undoable). Cells are integer grid coordinates. orientation: 0/90/180/270 (Y degrees), 'x90'/'z-90'/'y180', [rx,ry,rz] multiples of 90, or a raw index 0-23. item -1 erases.

  • mesh_library: {path: 'res://tiles.tres', from_scene?: 'res://tiles.tscn' (each MeshInstance3D becomes an item named after the node; StaticBody3D>CollisionShape3D children become its collision, NavigationRegion3D its navmesh; like Scene > Export As > MeshLibrary; CSG nodes are skipped), items?: [{name, shape|mesh, size?, radius?, height?, material?, collision?: true|false|convex|trimesh (default true), offset?}], replace?} create/merge a MeshLibrary for GridMap. Existing libraries are merged by item name unless replace=true; nothing changes if any item is invalid.

  • scatter: {source: 'res://tree.tscn' | 'res://rock.glb' | 'res://m.tres' (Mesh) | {shape, radius?, size?, material?}, parent?, name?='Scatter', count?=50, area?: {center: [x,y,z], size: [w,d] | [w,h,d] | w, radius?}, seed?, align_to_ground? (raycast down: lands on the LOWEST collider/visible mesh under each point, so props don't stack on roofs, trees or earlier props), ground?: node path | [paths] (only land on these; implies align_to_ground), align_to_normal?, y_offset?, random_rotation_y?=true, scale_range?=[1,1], min_distance?, mode?: multimesh (default for meshes; fast, visual only) | instances (default for scenes; real nodes with collision/scripts, max 2000), material?, item_name?, cast_shadow?} scatter props/vegetation.

shaderA

Godot shaders (.gdshader): create from ready-made templates (dissolve, outline, hit flash, water, toon, hologram, pixelate, wave, scroll, vignette...) and assign them in one call, compile-check code with the engine's shader compiler (with line numbers and Godot 3 -> 4 migration hints), read/edit, list uniforms, set shader parameters on nodes, and save ShaderMaterials. Godot 4 syntax: 'source_color' (not hint_color), 'uniform sampler2D screen_texture : hint_screen_texture' (not SCREEN_TEXTURE).

Actions:

  • templates: {} templates per shader type.

  • create: {path: 'res://shaders/x.gdshader', type?: canvas_item|spatial|particles|sky|fog (inferred from assign_to / template / scene), template?='blank' (canvas_item: blank|dissolve|outline|flash|water|toon|hologram|pixelate|wave|scroll|vignette; spatial: blank|dissolve|outline|flash|water|toon|hologram|wave|scroll; particles|sky|fog: blank), code? (instead of a template; its shader_type wins, 'shader_type ;' is added if missing), assign_to?: node path (creates a ShaderMaterial on material / material_override / process_material / environment sky; the spatial 'outline' template goes into material_overlay so the object's own materials stay), overlay? (spatial: use material_overlay), next_pass? (spatial: chain after the current material instead), surface?, params?: {uniform: value}, material_path?: also save the ShaderMaterial as .tres, overwrite?} write + compile-check. Returns ok, diagnostics and uniforms.

  • validate: {path | code, type?} compile with Godot's shader compiler (first error with line) + lint (missing shader_type, unbalanced braces, Godot 3 names like hint_color/SCREEN_TEXTURE/WORLD_MATRIX). type is prepended when code lacks shader_type.

  • read: {path: .gdshader | ShaderMaterial .tres | node path} code, shader type and parsed uniforms.

  • edit: {path, edits: [{old, new, replace_all?}] | code} exact replacements (or full replacement) then re-validate; returns diagnostics.

  • uniforms: {path: .gdshader | material .tres | node path} uniforms with type, hint, default, range, group and current value (for materials).

  • set_param: {path: node path | ShaderMaterial .tres, param + value | params: {name: value}, material_index?} set shader parameters (coerced: '#hex' colors, [x,y,z] vectors, 'res://tex.png', {type: 'NoiseTexture2D', noise: {type: 'FastNoiseLite'}}). Undoable on nodes with embedded materials; a node whose ShaderMaterial is a shared .tres file edits and saves that file.

  • material: {path: 'res://materials/x.tres', shader: 'res://x.gdshader', params?: {uniform: value}, props?: {render_priority, next_pass}, assign_to?: node path, surface?, overwrite?} create a ShaderMaterial file, or update an existing one in place (keeps its other params; overwrite=true starts fresh). Optionally assign it to a node.

uiA

Build game UIs (HUDs, menus, dialogs, inventories) from Control nodes. 'build' creates a whole UI tree in one undoable call with anchor presets, size flags, text and theme overrides; 'menu_template' makes a ready main menu; 'theme' creates project-wide Theme resources with StyleBoxFlat styles; 'inspect' explains why a layout looks wrong. Put in-game HUDs under a CanvasLayer so they don't move with the camera.

Actions:

  • build: {spec: {type, name?, layout?, props?, text?, theme_overrides?, children: [...]} | [specs], parent?='.', scene?} build a UI subtree. layout = anchor preset: full_rect|center|top_left|top_right|bottom_left|bottom_right|top_wide|bottom_wide|left_wide|right_wide|center_top|center_bottom|center_left|center_right|hcenter_wide|vcenter_wide (+ layout_margin, resize: minsize|keep_size); only for nodes NOT inside a Container. Shortcuts per node: text, min_size [w,h], size_flags 'expand_fill'|'shrink_center' (one value = both axes)|{h,v}|[h,v], align/valign (left|center|right, begin|end for boxes), font_size, font_color, color (ColorRect color, Panel background, else text color), separation, margin (MarginContainer: n or [l,t,r,b]), panel/stylebox (StyleBox spec), texture, icon, placeholder, tooltip, unique (%Name access), groups, script, theme (res://theme.tres). Any other key is set as a property (value, max_value, columns, autowrap_mode: 'word_smart'... enum names are matched loosely) or a theme item. theme_overrides: {font_size, font_color, outline_size, separation, colors:{}, constants:{}, font_sizes:{}, fonts:{}, styles:{panel|normal|hover|pressed|fill|background: {bg_color, corner_radius, border_width, border_color, content_margin, shadow_size...}}}. Children given as plain strings become Labels. Returns every created node path (buttons flagged with their 'pressed' signal) and layout warnings. A zero-size Control scene root is stretched to full_rect automatically.

  • menu_template: {title?, subtitle?, buttons?=['Play','Options','Quit'], parent?='.', name?='MainMenu', background?: color | res://image, button_size?=[260,56], font_size?=24, title_size?=56, title_color?, spacing?=16, button_style?: {bg_color, corner_radius, ...} (hover/pressed derived) or {normal, hover, pressed}, theme?} centered main menu: full-rect Control > Background > CenterContainer > VBox(Title, Subtitle, Buttons); in an empty scene whose root is a plain Control (no name/theme given) it is built directly into the root. Buttons get unique names (%PlayButton), shared StyleBoxes and wrap-around focus neighbors. Returns {buttons: {label: path}} to connect 'pressed' signals.

  • layout: {path | paths, preset?, margin?=0, resize?: minsize|keep_width|keep_height|keep_size, size_flags?: 'expand_fill' (both axes) | {h, v} | [h, v], min_size?: [w,h]} apply an anchor preset like the editor's layout toolbar (undoable). Presets don't apply inside Containers: use size_flags/min_size there.

  • theme_override: {path | paths, overrides: {font_size: 32, font_color: '#ffd166', outline_size: 4, font_outline_color: 'black', separation: 8, styles: {panel: {bg_color: '#1d2330', corner_radius: 12}}, fonts: {font: 'res://f.ttf'}}} set per-node theme overrides; a null value removes one. Flat keys are matched to the node's theme items; unknown item names are rejected with the valid list.

  • theme: {path: res://ui/theme.tres, props: {default_font_size?, default_font?: res://font.ttf, colors?: {Button: {font_color: '#fff', font_hover_color: ...}}, constants?: {VBoxContainer: {separation: 12}}, font_sizes?: {Label: {font_size: 20}}, fonts?, icons?, styles?: {Button: {normal: {bg_color, corner_radius, content_margin: [16,8]}, hover: {bg_color}, pressed: {...}, focus: 'empty'}, Panel: {panel: {...}}}, type_variations?: {TitleLabel: 'Label'}}, replace?, assign_to?: node path | 'project'} create or extend a Theme. Type names must be Control classes or declared in type_variations first; item names are checked against what the class uses. Style states other than 'normal' inherit the normal dict, so hover only needs what changes. assign_to 'project' makes it the game-wide default (gui/theme/custom); a node path assigns it to that Control and its children. Use theme_type_variation on nodes to use a variation.

  • font: {path: res://fonts/x.ttf|.otf|.woff2, size?, assign_to?: node path | res://theme.tres | 'project', variation?: {embolden, slant, spacing, spacing_top, baseline_offset, opentype}, save_as?: res://fonts/bold.tres} load a font (imported as FontFile; a file just copied into the project is imported first), optionally as a FontVariation (saved with save_as), and assign it as a node override (+font_size), a theme's default_font or the project default font.

  • focus: {chain: [paths], axis?='vertical'|'horizontal', wrap?=true, mode?: all|click|none} link controls for keyboard/gamepad navigation in order; or {path, neighbors: {left, right, top, bottom, next, previous: path}, mode?} set individual neighbors. Call grab_focus() on the first one in _ready().

  • inspect: {path} layout debugging: rect, global rect, anchors/offsets, detected preset, size flags, min size, what positions it (container vs anchors), parent size, overrides, children rects and warnings (zero-size parents, overlays blocking clicks, collapsed wrapped labels...).

audioA

Sound and music: audio buses with effects (saved to the project's default_bus_layout.tres, undoable), AudioStreamPlayer nodes, stream/import info, looping via import settings, and instant procedural placeholder sound effects (jump, coin, laser, explosion...) generated as .wav files so prototypes have sound without any assets.

Actions:

  • buses: {} list buses: volume, send target, mute/solo, effects with their changed properties.

  • add_bus: {name, send?='Master', volume_db? | volume? (linear 0..1), mute?, solo?, bypass_effects?, index?, effects?: ['reverb', {type: 'lowpass', cutoff_hz: 2000}, {type: 'compressor', props: {threshold: -12}}]} add a bus. Effect types: reverb, delay, compressor, limiter, eq/eq6/eq21, chorus, distortion, phaser, lowpass, highpass, bandpass, notch, lowshelf, highshelf, amplify, panner, pitch_shift, stereo_enhance, spectrum_analyzer, record, capture.

  • set_bus: {name, rename?, send?, volume_db?|volume?, mute?, solo?, bypass_effects?, effects? (replace all), add_effects?, remove_effects?: [index | type], effect_props?: {index|type: {prop: value}}} edit a bus (Master included, except send). Effect props accept aliases: cutoff -> cutoff_hz, mix -> wet (reverb), gain -> volume_db (amplify). Undoable.

  • remove_bus: {name} remove a bus; buses that sent to it are rerouted to Master.

  • player: {stream: res://x.wav|ogg|mp3 (or inline AudioStream), parent?='.', name?, type?: 1d|2d|3d, bus?='Master', autoplay?, volume_db?, pitch_scale?, loop?, max_distance?, props?} add an AudioStreamPlayer(2D/3D). type defaults to 1d (music/UI) at the scene root or for music, 2d/3d under a Node2D/Node3D entity. loop=true edits the file's import settings (wav/ogg/mp3) so it loops everywhere.

  • stream_info: {path} length, format, mix rate, stereo, loop settings, BPM and import parameters of an audio file.

  • import_loop: {path, loop, loop_offset? (ogg/mp3, seconds), loop_begin?/loop_end? (wav, frames), mode?: forward|pingpong|backward (wav)} set looping in the .import file and reimport.

  • generate_tone: {path: res://sfx/jump.wav, preset?: beep|blip|click|select|jump|coin|pickup|powerup|laser|shoot|hit|hurt|explosion|death|step|error, variation?: 0..1 (+seed) for random variants, wave?: square|sine|saw|triangle|noise (numbers only for the rest), freq?, freq_end? (exponential slide), duration?, attack?, decay?, duty?, volume?=0.6, vibrato_rate?, vibrato_depth?, arp_mult?, arp_time?, noise_mix?, lowpass?, lowpass_end?, loop?, overwrite?=true} synthesize a placeholder sound effect (sfxr-style, 16-bit mono 44.1 kHz) and import it. Preset values can be overridden individually.

particlesA

Particle effects (GPU/CPU, 2D/3D) from tuned presets — fire, smoke, sparks, explosion, dust, rain, snow, magic, hit, trail, confetti, bubbles — with color gradients, size curves, velocities and emission shapes already set, plus friendly editing of the process material. Undoable.

Actions:

  • presets: {} list presets with descriptions.

  • create: {preset?, parent?='.', name?, type?: gpu_2d|cpu_2d|gpu_3d|cpu_3d (default gpu, 2D/3D from the parent), position?, color? (tint the preset), size? (2D px / 3D meters), amount?, lifetime?, one_shot?, emitting?, explosiveness?, preprocess?, local_coords?, additive?, texture? (res:// image or soft|spark|square|streak|ring), process?: {ParticleProcessMaterial props}, props?: {node props}} add a particles node. Presets are tuned in 2D pixels and converted to meters for 3D. One-shot presets (explosion, hit, confetti) fire when the scene starts; call restart() in code to fire again.

  • set: {path, process?: {...}, props?: {...}, preset? (re-apply a preset), color?, amount?, lifetime?, one_shot?, emitting?, explosiveness?, preprocess?, local_coords?, speed_scale?} edit a particles node. Works for GPU (edits the process material) and CPU particles (same names; scale -> scale_amount mapped). Visibility bounds grow to fit faster/longer-lived particles.

  • get: {path} node settings and process values (gradients/curves as point lists).

  • restart: {path} restart emission (previews one-shot effects in the editor).

  • convert: {path, to: cpu|gpu} convert between GPUParticles and CPUParticles keeping settings (CPU has no turbulence/collision).

assetsA

Get art and audio into the game. Instant procedural placeholders (no key needed) keep prototypes playable; free CC0 libraries (Poly Haven textures/HDRIs/models, ambientCG PBR materials, Poly Pizza low-poly models) are searched and imported with credits recorded in res://CREDITS.md; optional AI generators (images via OpenAI, sound effects via ElevenLabs, 3D models via Meshy) use keys from the server environment. Also import presets (pixel art, normal maps) and an inventory of existing assets.

Actions:

  • providers: {} which sources/generators are available (API keys configured).

  • placeholder: {path: res://assets/sprites/player.png, kind?: sprite|spritesheet|tileset|icon, shape?: rounded|rect|circle|triangle|diamond|capsule|star, size?: [32,32], color?, outline?, face?, frames? (spritesheet), colors? (tileset: one tile per color)} generate placeholder art instantly.

  • search: {query, source?: polyhaven|ambientcg|polypizza, type?: texture|hdri|model, limit?=10} search free asset libraries.

  • download: {source, id, resolution?='1k', dest?: res:// folder, material?=true} import an asset from search results. Textures also get a ready StandardMaterial3D .tres; HDRIs are for skies; models are glTF/GLB you can instance.

  • generate_image: {prompt, path: res://assets/sprites/x.png, size?: [64,64] (downscale after generating), transparent?=true, pixel_art?, style?} AI image (sprites, icons, backgrounds, textures). Needs OPENAI_API_KEY.

  • generate_sfx: {prompt: 'retro coin pickup', path: res://assets/sfx/coin.mp3, duration?} AI sound effect. Needs ELEVENLABS_API_KEY.

  • generate_model: {prompt, path: res://assets/models/x.glb, texture?=true, wait_seconds?=60} AI 3D model (takes minutes; returns a job id to poll). Needs MESHY_API_KEY.

  • job: {id, wait_seconds?} poll a 3D generation job; downloads the model when done.

  • import_options: {path | paths, preset?: pixel_art|2d|3d_texture|normal_map|ui, options?: {raw .import params}} change import settings and reimport. No preset/options = show current settings.

  • process_image: {path, resize?: [w,h], nearest?, trim?, save_as?} trim/resize an image (e.g. downscale a generated sprite to 32x32 with nearest).

  • inventory: {path?} project assets grouped by type (textures, audio, models, fonts, scenes, materials).

exportA

Ship the game: manage export presets (export_presets.cfg), check that export templates are installed, and build executables (Windows .exe, Linux, macOS .zip, Web .html, Android .apk) by running a headless Godot export. Typical flow: templates -> add_preset {platform} -> build {preset}.

Actions:

  • presets: {options?: bool} list export presets (name, platform, export_path, runnable) and whether templates are installed.

  • add_preset: {platform: windows|linux|macos|web|android|ios, name?=platform name, export_path?='build//.', options?: {'binary_format/embed_pck': true, 'application/product_name': ..., 'custom_template/release': path, ...}, runnable?=true, export_filter?: all_resources|scenes|resources|exclude, include_filter?, exclude_filter?, custom_features?, dedicated_server?} create a preset (or update the one with the same name). Unlisted options keep Godot's defaults.

  • remove_preset: {name} delete a preset.

  • templates: {} whether export templates for the running Godot version are installed (per platform), where they go, and the download URL.

  • build: {preset? (name or platform; optional if only one), path? (default: the preset's export_path, relative to the project), debug?=false, pack?: export only the .pck/.zip, timeout_s?=900} export the project with a separate headless Godot process (unsaved scenes are saved first; an output folder inside the project gets a .gdignore). Returns ok, output file + size, errors/warnings and a hint (e.g. missing templates).

Prompts

Interactive templates invoked by user choice

NameDescription
new-gamePlan and bootstrap a playable prototype from a one-line pitch.
add-featureImplement a gameplay feature end to end and prove it works.
fix-bugReproduce, diagnose and fix a bug in the running game.
playtestPlay the game like a tester and report issues with evidence.
polishJuice up a mechanic: feedback, animation, particles, sound, screen shake.

Resources

Contextual data attached and managed by the client

NameDescription
project-memoryDesign notes, conventions and decisions for this game. Read at the start of a task; update when decisions are made.
project-summaryLive overview of the connected project (scenes, autoloads, input actions, main scene).
2D PlatformerRecipes and best practices bundled with Godot Forge.
3D BasicsRecipes and best practices bundled with Godot Forge.
Animation (AnimatedSprite2D, AnimationPlayer, AnimationTree, Tween)Recipes and best practices bundled with Godot Forge.
Audio: SFX, Music, Buses, Volume SettingsRecipes and best practices bundled with Godot Forge.
Godot 4 Architecture Best PracticesRecipes and best practices bundled with Godot Forge.
Cameras (2D follow, limits, shake, multi-target, 3D third/first person)Recipes and best practices bundled with Godot Forge.
Dialogue SystemRecipes and best practices bundled with Godot Forge.
Editor-first scene buildingRecipes and best practices bundled with Godot Forge.
Enemies & AI (state machines, navigation, hitboxes)Recipes and best practices bundled with Godot Forge.
Export & PlatformsRecipes and best practices bundled with Godot Forge.
Game Feel ("juice")Recipes and best practices bundled with Godot Forge.
GDScript 2.0 Cheat Sheet (Godot 4.7)Recipes and best practices bundled with Godot Forge.
Input Handling (Keyboard, Mouse, Gamepad, Touch)Recipes and best practices bundled with Godot Forge.
Inventory SystemRecipes and best practices bundled with Godot Forge.
Menus, Pause and Scene FlowRecipes and best practices bundled with Godot Forge.
Multiplayer Basics (High-Level API)Recipes and best practices bundled with Godot Forge.
Particles & VFXRecipes and best practices bundled with Godot Forge.
Performance and OptimizationRecipes and best practices bundled with Godot Forge.
Physics (bodies, layers, raycasts, rigid bodies)Recipes and best practices bundled with Godot Forge.
Pixel Art GamesRecipes and best practices bundled with Godot Forge.
Procedural Generation (seeded RNG, noise, caves, dungeons, chunks)Recipes and best practices bundled with Godot Forge.
Save and LoadRecipes and best practices bundled with Godot Forge.
ShadersRecipes and best practices bundled with Godot Forge.
State Machines (enum FSM, node-based FSM, AnimationTree)Recipes and best practices bundled with Godot Forge.
Testing and Verifying Games with Godot ForgeRecipes and best practices bundled with Godot Forge.
Tilemaps (TileMapLayer + TileSet)Recipes and best practices bundled with Godot Forge.
Top-Down 2D (action / RPG / twin-stick)Recipes and best practices bundled with Godot Forge.
UI: HUD, Menus, Pause, ThemesRecipes and best practices bundled with Godot Forge.

TDQS

A4.1/5.0

Scored across 29 tools

Disambiguation4/5

Most tools target clearly distinct Godot subsystems (files vs. script vs. resource, run vs. game vs. test, project vs. editor). A few boundaries are slightly soft — e.g. editing a .gd file can be done via files.edit or script.edit — but the descriptions consistently clarify which tool to prefer.

Naming Consistency4/5

Tool names are consistently lowercase single nouns (signal, scene, node, physics, navigation, etc.) with no camelCase/snake_case mixing. Minor deviations are the plural forms (files, changes, tiles, particles, assets) and the concatenated 'world3d' instead of 'world_3d'.

Tool Count3/5

29 tools is heavy for an MCP surface and risks selection paralysis. Each tool does cover a distinct subsystem and bundles many actions, so the count is borderline rather than purely excessive for an editor-automation server of this scope.

Completeness5/5

The surface covers project setup, file/scene/node/script/resource lifecycles, signals, animation, tiles, physics, navigation, 3D world building, shaders, UI, audio, particles, asset generation/import, testing, and export. Gaps such as dedicated multiplayer or localization tools are minor relative to the editor-automation domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues