godot-gdscript-mastery

Expert GDScript landmine guidance: static typing opcodes, signal-up/call-down, %UniqueName/@onready lifecycle, Callable bind/unbind, await sequences, typed collections, and safe Dictionary iteration. Use for code review, refactoring hot paths, or project standards. Trigger keywords: static_typing, s

By thedivergentai · 432 installs

npx skills add thedivergentai/gd-agentic-skills --skill godot-gdscript-mastery

Source repository · Upstream listing

GDScript Mastery Expert guidance for writing performant, maintainable GDScript — Godot landmine decision trees, not a style guide reprint. Do NOT Load Do not load this skill for general prose style or Godot engine version upgrades (3→4 / 4.x hops) — those live in [godot version migration](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot version migration/SKILL.md) (plus official upgrading guides via that hub). Do not preload every script below; open only the MANDATORY pointer for the Core Directive you are implementing. Do not treat EditorScript utilities ( type checker , performance analyzer , signal architecture validator ) as runtime gameplay code. NEVER Do in GDScript NEVER use @onready and @export on the same variable — Initialization order will cause @onready to overwrite the Inspector value. NEVER modify a Dictionary's size while iterating it — Use dict.keys().duplicate() or iterate a clone to safely erase elements. NEVER use string based connect("signal", ...) — Always use the Signal object syntax ( button.pressed.connect(...) ) for compile time safety. NEVER attempt to override non virtual native engine methods — Overriding queue free() or get class() is unsupported and will be ignored by engine callbacks. NEVER use dynamic get node() or $ inside process() — Fetching paths every frame stalls the CPU. Cache and use @onready . NEVER use Parent.method() calls — Violates "Signal Up, Call Down". Use signals to communicate with parents. NEVER use is followed by a hard cast — If the type check passes but the object changes, it crashes. Use as and check for null. NEVER use print() for production debugging — Use push error() , push warning() , or breakpoints. NEVER pre load huge resources in ready() — Use ResourceLoader.load threaded request() for async loading. NEVER use global variables in Autoloads when static var is sufficient — Static variables offer better encapsulation. Core Directives (decision trees + MANDATORY scripts) 1. Strong Typing & Performance Landmine Decision Hot path still Variant ? Annotate vars/returns; prefer typed collections Generic math in process ? Use typed helpers ( absf , ceili , clampf ) Green safe lines missing? Fix inference with := or explicit types MANDATORY : [typed collections mastery.gd](scripts/typed collections mastery.gd), [array preallocation perf.gd](scripts/array preallocation perf.gd), [type checker.gd](scripts/type checker.gd) (EditorScript audit). 2. Signal Architecture Landmine Decision Child needs parent reaction? Emit signal up — never call parent methods Cross script payload unsafe? Typed signal name(arg: Type) Connect visibility? Prefer ready() connects over invisible editor only wiring MANDATORY : [typed signal definitions.gd](scripts/typed signal definitions.gd), [signal architecture validator.gd](scripts/signal architecture validator.gd). 3. Node Access & Lifecycle Safety Landmine Decision Need child nodes? @onready / %UniqueName — never in init() Scene instanced node with ctor args? Use @export injection — init(args) breaks PackedScene.instantiate() Path lookup every frame? Cache once; never $ / get node in process MANDATORY : [safe type casting.gd](scripts/safe type casting.gd). 4. Callable & Signal (First Class) Landmine Decision Extra context on callback? Callable.bind(...) Discard unused signal args? Callable.unbind(n) One off timeout logic? Inline lambda OK; keep refs if create callback style longevity matters MANDATORY : [callable binding context.gd](scripts/callable binding context.gd), [unbind signal args.gd](scripts/unbind signal args.gd), [advanced lambdas.gd](scripts/advanced lambdas.gd), [functional lambda logic.gd](scripts/functional lambda logic.gd). 5. Async, Statics & Safe Collections Landmine Decision Sequence timers without threads? await chains — see await manager Global state without Autoload bloat? static var (+ nullify large statics when done) Erase while iterating Dictionary? Clone keys first MANDATORY : [await sequence manager.gd](scripts/await sequence manager.gd), [static var singleton alt.gd](scripts/static var singleton alt.gd), [dictionary safe iteration.gd](scripts/dictionary safe iteration.gd), [performance analyzer.gd](scripts/performance analyzer.gd) (EditorScript). Script Catalog (all files) Script When to open [typed collections mastery.gd](scripts/typed collections mastery.gd) Typed Array/Dictionary opcodes [functional lambda logic.gd](scripts/functional lambda logic.gd) reduce / all / any [advanced lambdas.gd](scripts/advanced lambdas.gd) Higher order Callables [safe type casting.gd](scripts/safe type casting.gd) as + null checks [typed signal definitions.gd](scripts/typed signal definitions.gd) Typed signal boundaries [callable binding context.gd](scripts/callable binding context.gd) bind() context injection [unbind signal args.gd](scripts/unbind signal args.gd) unbind() arity trim [await sequence manager.gd](scripts/await sequence manager.gd) Non blocking await flows [array preallocation perf.gd](scripts/array preallocation perf.gd) resize() pre alloc [static var singleton alt.gd](scripts/static var singleton alt.gd) Lightweight global state [dictionary safe iteration.gd](scripts/dictionary safe iteration.gd) Safe erase while iterate [type checker.gd](scripts/type checker.gd) EditorScript typing audit [performance analyzer.gd](scripts/performance analyzer.gd) EditorScript hot path scan [signal architecture validator.gd](scripts/signal architecture validator.gd) EditorScript signal up checks Quick Landmines Prefer dict.get("key", default) over dict["key"] when presence is uncertain. Toggle Access as Scene Unique Name and read via %Name for critical UI/nodes. Script layout order: extends → class name → signals/enums/consts → exports/onready → lifecycle → public → private . Expert knowledge (on demand) LLM ignorance rule: If a general agent would not know it before reading, load the reference — never delete expert deltas. [gdscript core directives.md](references/gdscript core directives.md) — restored baseline pedagogy (architecture, WHY, implementation depth) Reference Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice. Official Documentation [GDScript basics](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript basics.html) — Language core for typed vars/funcs, signal declarations, await , and first class Callables this skill standardizes. [GDScript style guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript styleguide.html) — Canonical script order ( extends → class name → signals → exports → lifecycle → methods) used in reviews and refactoring. [Static typing in GDScript](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/static typing.html) — Why typed Arrays/Dictionaries and return types unlock optimized opcodes and editor safe lines. [GDScript: An introduction to dynamic languages](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript advanced.html) — Lambdas, higher order Callables, and advanced patterns behind filter/map/reduce helpers. [GDScript warning system](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/warning system.html) — Turn unsafe casts, unused signals, and untyped hot paths into CI visible warnings. [Logic preferences](https://docs.godotengine.org/en/stable/tutorials/best practices/logic preferences.html) — When to prefer declarative signals vs imperative calls so scripts stay decoupled. [Scene organization](https://docs.godotengine.org/en/stable/tutorials/best practices/scene organization.html) — Official “signal up, call down” ownership rules this skill enforces. [Using signals](https://docs.godotengine.org/en/stable/getting started/step by step/signals.html) — Connect/emit model and why string based connect by name is avoided. [Callable](https://docs.godotengine.org/en/stable/classes/class callable.html) — bind() / unbind() APIs for injecting or discarding callback arguments without wrapper nodes. [Array](https://docs.godotengine.org/en/stable/classes/class array.html) — Typed arrays, resize() , and functional methods ( filter / map / reduce / all / any ) used in the scripts. [Dictionary](https://docs.godotengine.org/en/stable/classes/class dictionary.html) — Safe .get() defaults and why size must not change while iterating keys. [CPU optimization](https://docs.godotengine.org/en/stable/tutorials/performance/cpu optimization.html) — Cache @onready / %UniqueName instead of get node / $ inside process loops. Related Skills Prerequisites [godot project foundations](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot project foundations/SKILL.md) — Project layout, Autoload registration, and scene ownership conventions that typed GDScript scripts plug into. [godot composition](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot composition/SKILL.md) — Component boundaries clarify which scripts own signals vs call down APIs before style enforcement. Complements [godot version migration](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot version migration/SKILL.md) — Engine version upgrades (3→4 language breaks, 4.x hops); this skill stays on current GDScript 2.0 idioms. [godot signal architecture](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot signal architecture/SKILL.md) — Deepens connect flags, buses, and sequencers after this skill’s typed signal/Callable basics. [godot autoload architecture](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot autoload architecture/SKILL.md) — Contrasts heavy Autoloads with the static var singleton alternatives shown here. [godot resource data patterns](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot resource data patterns/SKILL.md) — Prefer Resources for shared config; keep GDScript modules thin and typed around Resource payloads. [godot scene management](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot scene management/SKILL.md) — @onready , unique names, and await sequences must stay valid across scene swaps and loaders. [godot testing patterns](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot testing patterns/SKILL.md) — Typed signals and Callables make watch signals / spies reliable in unit tests. [godot debugging profiling](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot debugging profiling/SKILL.md) — Pair style/perf smells from this skill with profiler and custom monitors when hot paths remain slow. [godot state machine advanced](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot state machine advanced/SKILL.md) — FSM enter/exit handlers should follow the same typed signal and await sequencing conventions. Downstream / consumers [godot performance optimization](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot performance optimization/SKILL.md) — Escalate when typed GDScript alone is not enough; servers, pooling, and broader CPU/GPU tactics live there. [godot auditor](https://github.com/thedivergentai/gd agentic skills/blob/main/skills/godot auditor/SKILL.md) — Project wide audits consume the typing, signal up, and hot path rules codified in th