gdscript-patterns is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. GDScript conventions: type hints, signals, exports, onready, lifecycle methods, node paths, naming.
When your agent uses it
- Writing or refactoring GDScript — type hints, signals, exports, onready, lifecycle methods, naming conventions
- Reviewing GDScript for idiomatic signals, exports, @onready usage, node references, and naming
Install
summer setup installs every skill for your agent. To add only this one:
claude-code for your agent, such as codex or cursor. See Skills for every option.
The skill
When writing GDScript for Summer Engine projects, follow these patterns. They match the engine’s GDScript 4 conventions and work well with MCP scene operations.Type Hints
Always use type hints for clarity and editor support:Signals
Define signals at the top of the script, then emit them:summer_connect_signal with the emitter path, signal name, receiver path, and method name. The receiver script must have the method defined.
Exports
Use@export for inspector-editable properties:
summer_set_prop after the node exists, but exports are best for values the designer tweaks.
Lifecycle Methods
For character movement, use
_physics_process and move_and_slide().
Node Access
Common Patterns
For health systems, input handling, and state machines, see reference.md.Anti-patterns — introspection traps
The engine’s introspection API has Object-instance methods that look like they should work on script-class references. They don’t. Calling them on aconst ScriptName = preload(...) reference is a parse error, not a runtime no-op.
Rule of thumb: if you’re tempted to write
Klass.has_*("name") on a const Klass = preload(...) reference, you’re confusing class-level introspection (compile-time, automatic) with instance-level introspection (Object method, runtime). GDScript’s parser already does the compile-time check for free.
Side note on has_method vs has_static_method: has_method works on a node/instance to check if the instance has a method. has_static_method works on an Object instance to check if its class has a static method. Neither is callable on a bare Script reference (preload(...) result). To check static-method presence at runtime, call the method inside a try-equivalent. In practice if your code paths are well-typed you don’t need to.
Anti-pattern — @onready var = $Path on nodes that don’t exist on every variant
The engine resolves $Path (the get_node shorthand) at @implicit_ready time. If the node is missing from the current scene, you get Node not found: "X" (relative to "Y") errors before any of your _ready() runtime guards can run.
Common case: a script is shared by multiple scene variants where some variants have an optional child. Even if every code path that touches the variable has a if inventory_ui: guard, the @onready line itself errors at scene load.
Rule of thumb: if the node is required for the script to function at all, use
$Path and rely on the parse-time error. If the node may be missing in some scene variants the script is reused across, use get_node_or_null and guard at every read site.
Anti-pattern — Label3D.label_settings (it doesn’t exist)
LabelSettings is a resource type used by Label (the 2D Control node) to bundle font + size + outline + colors. Label3D does NOT accept it. Assigning LabelSettings to label_settings on a Label3D raises Invalid assignment of property or key 'label_settings' with value of type 'LabelSettings' on a base object of type 'Label3D'.
Label3D exposes the same styling fields as direct properties:
LabelSettings.outline_color (Label 2D) vs Label3D.outline_modulate (Label3D). Easy to miss in copy-paste.
Rule of thumb: LabelSettings is for Label only. For Label3D use direct properties. For RichTextLabel, neither — it has its own theme overrides.
Scene Integration
When the AI adds a node with Summer MCP tools and attaches a script, the script path is set viasummer_set_prop(path, "script", "res://path/to/script.gd"). The script file must exist first. Create it with guarded summer_write_file or edit it with summer_replace_text, then attach the script and connect scene signals.
For signal connections, the receiver must have the handler method. Create the script with the method stub before calling summer_connect_signal.
From a shell
No Summer MCP tools in this session? Run each one as a command; whensummer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.
Files in this skill
Source:
library/skills/gdscript-patterns/SKILL.md, rendered from summer-engine@4.3.0 on npm.
