Usage¶
Every command takes --project DIR (default: walk up from the current directory),
--json, --quiet, and — for mutations — --dry-run and --no-undo.
Inspect¶
gdcli editor status # open scenes and play state
gdcli scene roots # every open scene
gdcli scene tree --depth 2 # the scene as a tree
gdcli scene tree --props # ...with properties
gdcli prop list Hero --changed
scene tree prints names with their type and marks instanced scenes:
Edit a scene¶
gdcli node add Sprite2D --parent Main --name Hero
gdcli prop set Hero position 'Vector2(64, 96)'
gdcli prop set Hero texture 'res://art/hero.png' --as ref
gdcli node mv Hero --to World --index 0
gdcli node instance res://props/crate.tscn --parent World --name Crate
gdcli scene save
Each of those is one undo step:
Look before you leap
--dry-run validates the whole command and returns the planned operations without
touching the scene:
Values¶
The engine parses the value, so there is no type table to keep in sync:
--as |
Example | Parser |
|---|---|---|
gd (default) |
'Vector2(64, 96)', 'Color(1,0,0,1)' |
str_to_var, the inverse of var_to_str |
json |
'{"a": 1}' |
JSON.parse_string, coerced to the property's type |
ref |
'res://art/hero.png' |
load() |
expr |
'Vector2(1, 2) * 3' |
Expression — arbitrary code, use with care |
Signals and groups¶
gdcli signal connect Btn pressed Player _on_pressed
gdcli signal list Btn --connected-only
gdcli signal disconnect Btn pressed Player _on_pressed
gdcli group add Hero gameplay
gdcli group list Hero
Connections are written persistent (CONNECT_PERSIST), so they end up in the .tscn as
[connection ...] and in the user's undo history.
Project data¶
gdcli project setting set application/config/description "My game"
gdcli project autoload add Game res://autoload/game.gd
gdcli project plugins list
gdcli project plugins disable probe
gdcli fs scan --wait
gdcli script check res://player.gd res://enemy.gd
The input map has its own small event DSL — keys, mouse buttons, joypad buttons and axes:
gdcli project input add-action jump --deadzone 0.2
gdcli project input add-event jump --key Space --modifiers shift
gdcli project input add-event jump --joy-button 0
gdcli project input list --action jump
Screenshots and play¶
gdcli editor screenshot --out shot.png # whole editor window
gdcli editor screenshot --out view.png --viewport 2d
gdcli editor play --wait
gdcli editor stop
Screenshots are written by the editor itself; the CLI only hands over a path. That means they need a real renderer — see Install.
The running game¶
The game side is opt-in. Install the runtime autoload once, then play:
gdcli runtime install
gdcli editor play --wait
gdcli game ping
gdcli game tree --depth 1
gdcli game get Inst/Label text
gdcli game set Inst/Label text '"patched"'
gdcli game eval '1 + 1'
gdcli game logs --kind error
gdcli game screenshot --out game.png
Requests into the game time out after three seconds (NO_GAME) instead of blocking the
editor. game.logs captures the game's own print, printerr, push_error and
push_warning output — the runtime forwards it, because Godot's debugger does not carry it.
Several operations at once¶
batch keeps one connection for a whole NDJSON pipeline, which is much cheaper than starting
over per command:
printf '%s\n' \
'{"cmd":"scene.tree","args":{}}' \
'{"cmd":"prop.get","args":{"target":"Hero","name":"position"}}' \
| gdcli batch
raw sends a single protocol command the CLI does not wrap: