/gdtoolkit
Lint and format GDScript files using gdtoolkit (gdlint + gdformat). Use after writing or modifying .gd files, when asked to check code style, fix lint errors, format code, or set up linting configuration. Also use when gdlint/gdformat errors appear in output and need diagnosis.
$ npx -y skills add RandallLiuXin/GodotMaker --skill gdtoolkit --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/gdtoolkit
Context preview
The summary Claude sees to decide when to auto-load this skill.
Lint and format GDScript files using gdtoolkit (gdlint + gdformat). Use after writing or modifying .gd files, when asked to check code style, fix lint errors, format code, or set up linting configuration. Also use when gdlint/gdformat errors appear in output and need diagnosis.
SKILL.md
gdtoolkit.SKILL.mdname: gdtoolkit
description: |
Lint and format GDScript files using gdtoolkit (gdlint + gdformat).
Use after writing or modifying .gd files, when asked to check code style,
fix lint errors, format code, or set up linting configuration.
Also use when gdlint/gdformat errors appear in output and need diagnosis.
Does NOT require Godot — runs as a standalone Python tool.
gdtoolkit — GDScript Lint & Format
> **Currently disabled (v0.3.4+).** `gm-verify` no longer invokes > `gdlint` / `gdformat`, and `gm-build` / `gm-fixgap` have removed this > skill from their Available Skills tables. Reason: repeated > `gdtoolkit/linter/class_checks.py:144 NotImplementedError` crashes on > common ECS-style GDScript class shapes, plus low signal-to-noise vs > the headless compile + reviewer pattern checks. Re-enabling tracked as > ROADMAP `R-112`. The reference content below is preserved for ad-hoc > use outside the pipeline and for the future re-enablement.
Wraps two CLI tools from the `gdtoolkit` Python package:
- **gdlint** — static analysis and style checking
- **gdformat** — deterministic auto-formatter
Prerequisites
pip install "gdtoolkit==4.*" # Godot 4 projects
pip install "gdtoolkit==3.*" # Godot 3 projects
Verify installation: `gdlint --version && gdformat --version`
If not installed, tell the user and offer to install. The version major must match the project's Godot major version (read from `project.godot` `config/features`).
Lint workflow
Run gdlint
gdlint path/to/file.gd # single file
gdlint path/to/directory/ # all .gd files recursively
Interpret output
Each problem is one line on stderr:
path/to/file.gd:42: Error: Function name "MyFunc" is not valid (function-name)
Format: `{file}:{line}: Error: {message} ({rule-id})`
Exit codes:
- **0** — no problems (stdout: `Success: no problems found`)
- **1** — problems found (stderr: `Failure: N problem(s) found`)
Fix lint issues
For each reported issue, either: 1. **Fix the code** — rename to match convention, remove unused arg, reorder members 2. **Suppress inline** — when the violation is intentional:
# gdlint:ignore = rule-id
var _unusedButNeeded := 0 # this line + next line are suppressed
3. **Suppress region** — for larger blocks:
# gdlint: disable=function-name
func ALLCAPS_required_by_engine():
pass
# gdlint: enable=function-nameWhen suppressing, always add a brief comment explaining why.
Format workflow
Run gdformat
gdformat path/to/file.gd # format in-place
gdformat path/to/directory/ # format all .gd files
gdformat --check path/ # check only, don't modify (exit 1 if changes needed)
gdformat --diff path/ # show unified diff on stderr, don't modify
Exit codes:
- **0** — already formatted / formatting succeeded
- **1** — check mode found differences / parse error / safety check failed
Safety checks
gdformat runs three safety checks by default (disable with `--fast`):
- **TreeInvariantViolation** — parse tree changed after formatting
- **FormattingStabilityViolation** — formatting isn't idempotent
- **CommentPersistenceViolation** — comments were lost
If a safety check fails, report the error to the user — do NOT use `--fast` to bypass it. This likely indicates a gdtoolkit bug; the file should be formatted manually or the problematic section excluded.
Rule reference
Naming rules (regex-configurable)
| Rule ID | Default convention | Example | |---|---|---| | `function-name` | snake_case or `_on_PascalCase_signal` | `move_player`, `_on_Button_pressed` | | `class-name` | PascalCase | `PlayerController` | | `sub-class-name` | _PascalCase (leading underscore) | `_InternalHelper` | | `signal-name` | snake_case | `health_changed` | | `class-variable-name` | snake_case or _private | `speed`, `_cache` | | `function-variable-name` | snake_case | `local_var` | | `function-argument-name` | snake_case or _unused | `target_pos`, `_ignored` | | `loop-variable-name` | snake_case or _unused | `item`, `_i` | | `constant-name` | UPPER_SNAKE_CASE | `MAX_SPEED` | | `enum-name` | PascalCase | `Direction` | | `enum-element-name` | UPPER_SNAKE_CASE | `NORTH`, `SOUTH_EAST` |
Code quality rules
| Rule ID | Default | What it checks | |---|---|---| | `max-returns` | 6 | Too many return statements per function | | `max-public-methods` | 20 | Too many public methods per class | | `function-arguments-number` | 10 | Too many function arguments | | `max-file-lines` | 1000 | File too long | | `max-line-length` | 100 | Line too long |
Style rules
| Rule ID | What it checks | |---|---| | `unnecessary-pass` | `pass` in non-empty body | | `duplicated-load` | Same resource loaded twice | | `expression-not-assigned` | Standalone expression with no effect | | `unused-argument` | Argument never used (fix: prefix with `_`) | | `comparison-with-itself` | `x == x` | | `private-method-call` | Calling `_private_method()` from outside | | `class-definitions-order` | Members not in canonical order (see below) | | `trailing-whitespace` | Trailing spaces | | `mixed-tabs-and-spaces` | Mixed indentation | | `no-elif-return` | Unnecessary elif after return | | `no-else-return` | Unnecessary else after return |
Class member order (class-definitions-order)
gdlint expects this top-to-bottom order: 1. `@tool` 2. `class_name` 3. `extends` 4. Docstring 5. Signals 6. Enums 7. Constants 8. Static variables 9. `@export` variables 10. Public variables 11. Private variables (`_prefixed`) 12. `@onready` public variables 13. `@onready` private variables 14. Remaining declarations
Configuration
gdlintrc
Create `.gdlintrc` (or `gdlintrc`) in the project root. YAML format. gdlint searches upward from CWD, uses the first file found.
Generate defaults: `gdlint -d > .gdlintrc`
Example with customizations:
# Relax line length to match gdf
Read more
name: gdtoolkit description: | Lint and format GDScript files using gdtoolkit (gdlint + gdformat). Use after writing or modifying .gd files, when asked to check code style, fix lint errors, format code, or set up linting configuration. Also use when gdlint/gdformat errors appear in output and need diagnosis. Does NOT require Godot — runs as a standalone Python tool.
gdtoolkit — GDScript Lint & Format
> **Currently disabled (v0.3.4+).** `gm-verify` no longer invokes > `gdlint` / `gdformat`, and `gm-build` / `gm-fixgap` have removed this > skill from their Available Skills tables. Reason: repeated > `gdtoolkit/linter/class_checks.py:144 NotImplementedError` crashes on > common ECS-style GDScript class shapes, plus low signal-to-noise vs > the headless compile + reviewer pattern checks. Re-enabling tracked as > ROADMAP `R-112`. The reference content below is preserved for ad-hoc > use outside the pipeline and for the future re-enablement.
Wraps two CLI tools from the `gdtoolkit` Python package:
- **gdlint** — static analysis and style checking
- **gdformat** — deterministic auto-formatter
Prerequisites
pip install "gdtoolkit==4.*" # Godot 4 projects pip install "gdtoolkit==3.*" # Godot 3 projects
Verify installation: `gdlint --version && gdformat --version`
If not installed, tell the user and offer to install. The version major must match the project's Godot major version (read from `project.godot` `config/features`).
Lint workflow
Run gdlint
gdlint path/to/file.gd # single file gdlint path/to/directory/ # all .gd files recursively
Interpret output
Each problem is one line on stderr:
path/to/file.gd:42: Error: Function name "MyFunc" is not valid (function-name)
Format: `{file}:{line}: Error: {message} ({rule-id})`
Exit codes:
- **0** — no problems (stdout: `Success: no problems found`)
- **1** — problems found (stderr: `Failure: N problem(s) found`)
Fix lint issues
For each reported issue, either: 1. **Fix the code** — rename to match convention, remove unused arg, reorder members 2. **Suppress inline** — when the violation is intentional:
# gdlint:ignore = rule-id var _unusedButNeeded := 0 # this line + next line are suppressed
3. **Suppress region** — for larger blocks:
# gdlint: disable=function-name
func ALLCAPS_required_by_engine():
pass
# gdlint: enable=function-nameWhen suppressing, always add a brief comment explaining why.
Format workflow
Run gdformat
gdformat path/to/file.gd # format in-place gdformat path/to/directory/ # format all .gd files gdformat --check path/ # check only, don't modify (exit 1 if changes needed) gdformat --diff path/ # show unified diff on stderr, don't modify
Exit codes:
- **0** — already formatted / formatting succeeded
- **1** — check mode found differences / parse error / safety check failed
Safety checks
gdformat runs three safety checks by default (disable with `--fast`):
- **TreeInvariantViolation** — parse tree changed after formatting
- **FormattingStabilityViolation** — formatting isn't idempotent
- **CommentPersistenceViolation** — comments were lost
If a safety check fails, report the error to the user — do NOT use `--fast` to bypass it. This likely indicates a gdtoolkit bug; the file should be formatted manually or the problematic section excluded.
Rule reference
Naming rules (regex-configurable)
| Rule ID | Default convention | Example | |---|---|---| | `function-name` | snake_case or `_on_PascalCase_signal` | `move_player`, `_on_Button_pressed` | | `class-name` | PascalCase | `PlayerController` | | `sub-class-name` | _PascalCase (leading underscore) | `_InternalHelper` | | `signal-name` | snake_case | `health_changed` | | `class-variable-name` | snake_case or _private | `speed`, `_cache` | | `function-variable-name` | snake_case | `local_var` | | `function-argument-name` | snake_case or _unused | `target_pos`, `_ignored` | | `loop-variable-name` | snake_case or _unused | `item`, `_i` | | `constant-name` | UPPER_SNAKE_CASE | `MAX_SPEED` | | `enum-name` | PascalCase | `Direction` | | `enum-element-name` | UPPER_SNAKE_CASE | `NORTH`, `SOUTH_EAST` |
Code quality rules
| Rule ID | Default | What it checks | |---|---|---| | `max-returns` | 6 | Too many return statements per function | | `max-public-methods` | 20 | Too many public methods per class | | `function-arguments-number` | 10 | Too many function arguments | | `max-file-lines` | 1000 | File too long | | `max-line-length` | 100 | Line too long |
Style rules
| Rule ID | What it checks | |---|---| | `unnecessary-pass` | `pass` in non-empty body | | `duplicated-load` | Same resource loaded twice | | `expression-not-assigned` | Standalone expression with no effect | | `unused-argument` | Argument never used (fix: prefix with `_`) | | `comparison-with-itself` | `x == x` | | `private-method-call` | Calling `_private_method()` from outside | | `class-definitions-order` | Members not in canonical order (see below) | | `trailing-whitespace` | Trailing spaces | | `mixed-tabs-and-spaces` | Mixed indentation | | `no-elif-return` | Unnecessary elif after return | | `no-else-return` | Unnecessary else after return |
Class member order (class-definitions-order)
gdlint expects this top-to-bottom order: 1. `@tool` 2. `class_name` 3. `extends` 4. Docstring 5. Signals 6. Enums 7. Constants 8. Static variables 9. `@export` variables 10. Public variables 11. Private variables (`_prefixed`) 12. `@onready` public variables 13. `@onready` private variables 14. Remaining declarations
Configuration
gdlintrc
Create `.gdlintrc` (or `gdlintrc`) in the project root. YAML format. gdlint searches upward from CWD, uses the first file found.
Generate defaults: `gdlint -d > .gdlintrc`
Example with customizations:
# Relax line length to match gdf
Autonomous text-to-game pipeline for Godot, powered by Claude Code,Codex,Opencode
Repo: RandallLiuXin/GodotMaker
Other skills on godotmaker.
- /background-map
Generate and validate a fixed-viewport background, map base, or parallax plate as a ready-to-load Texture2D.
Open skill - /card-kit
Produce reusable card art sources and native Godot card UI resources.
Open skill - /character-bundle
Produce one illustrated character SpriteFrames resource from high-level body-action intent, optional character and style references, and a resolved animation plan.
Open skill - /compact-prop-pack
Produce a reusable compact-prop atlas from one provider source sheet, with independently loadable AtlasTexture resources for every declared prop.
Open skill - /fx-bundle
Produce a standalone static Texture2D effect or one explicitly timed animated SpriteFrames effect.
Open skill - /platform-strip
Generate non-pixel-art, horizontally repeatable platform strips from real image sources as fixed Texture2D cells or AtlasTexture regions.
Open skill

