Skip to content
Automation
Skill

/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.

From plugin
godotmaker
55941 skills7 agents15 hooks

Claude Code

$ npx -y skills add RandallLiuXin/GodotMaker --skill gdtoolkit --agent claude-code

SKILL.md

gdtoolkit.SKILL.md
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

<!-- agent-operations: run_shell_command -->

> **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-name

When 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 customizat

Read more
@randallliuxin
Ships withgodotmaker

Autonomous text-to-game pipeline for Godot, powered by Claude Code,Codex,Opencode

55941 skills7 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
559
Star history of RandallLiuXin/GodotMaker on GitHub, a chart by star-history.com

Other skills on godotmaker.

platform-strip

platform-strip

Generate non-pixel-art, horizontally repeatable platform strips from real image sources as fixed Texture2D cells or AtlasTexture…

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n12d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about gdtoolkit.

Which coding agents can use gdtoolkit?
gdtoolkit installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.