Analyze GDScript code for quality, best practices, anti-patterns, and refactoring opportunities. Use this when the user wants to review code quality, check for Godot-specific issues, or improve code maintainability.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
npx agent-skills-cli listSkill Instructions
name: gdscript-quality-checker description: Analyze GDScript code for quality, best practices, anti-patterns, and refactoring opportunities. Use this when the user wants to review code quality, check for Godot-specific issues, or improve code maintainability. domain: code-quality type: checker version: 1.2.0 allowed-tools:
- Read
- Glob
- Grep
- Write
GDScript Quality Checker Skill
This skill analyzes GDScript files to identify code quality issues, Godot-specific anti-patterns, performance problems, and refactoring opportunities.
When to Use This Skill
Invoke this skill when the user:
- Asks to "check code quality" or "review my code"
- Says "refactor [script_name].gd" or "analyze [script_name]"
- Wants to find code duplication or anti-patterns
- Asks "is this good GDScript?" or "how can I improve this code?"
- Requests performance analysis
- Says "check my scripts" or "code review"
Analysis Categories
1. Godot-Specific Best Practices
Check for:
Node References:
- β Using
get_node("NodeName")or$NodeNamein_ready()or repeatedly - β
Should use
@onready var node_ref = $NodeName
Signals vs. Polling:
- β Checking conditions in
_process()every frame (e.g.,if health <= 0:) - β
Should emit signals when state changes (e.g.,
health_depleted.emit())
Process Functions:
- β Physics operations in
_process(delta) - β
Should use
_physics_process(delta)for physics - β Empty
_process()or_physics_process()functions (remove them)
Resource Loading:
- β Loading resources at runtime:
load("res://...") - β
Should preload:
const RESOURCE = preload("res://...")
Node Access:
- β Deep node paths:
get_node("../../UI/HUD/Label") - β Should use signals or dependency injection
Type Safety:
- β Untyped variables:
var speed = 100 - β
Should type:
var speed: float = 100.0 - β Untyped function returns:
func get_damage(): - β
Should type:
func get_damage() -> int:
2. Performance Anti-Patterns
Check for:
Expensive Operations in Loops:
# β Bad
for enemy in enemies:
var player = get_tree().get_first_node_in_group("player")
# β
Good
var player = get_tree().get_first_node_in_group("player")
for enemy in enemies:
String Operations:
- β String concatenation in loops:
str += "text" - β
Use String formatting:
"%s: %d" % [name, value]
Unnecessary get_tree() Calls:
- β Repeated
get_tree()calls - β
Cache in
@onready var tree = get_tree()
Array/Dictionary Operations:
- β Using
append()in hot paths without pre-sizing - β
Consider pre-allocating:
array.resize(expected_size)
Node Creation:
- β Instantiating nodes every frame
- β Use object pooling for frequently created/destroyed nodes
Type Conversions:
- β Unnecessary string/int conversions
- β Keep consistent types
3. Code Organization Issues
Check for:
Magic Numbers:
# β Bad
velocity.x = 200
health -= 15
# β
Good
const MAX_SPEED: float = 200.0
const BULLET_DAMAGE: int = 15
Long Functions:
- Functions over 30-40 lines (consider breaking up)
- Multiple responsibilities in one function
Duplicate Code:
- Similar code blocks across files (extract to shared function/class)
- Copy-pasted enemy/weapon logic (use inheritance or composition)
Poor Naming:
- Single-letter variables (except loops):
var d = 10 - Unclear function names:
func do_thing() - Generic names:
var temp,var data
Missing Documentation:
- No docstrings for public functions
- No comments explaining complex logic
- No
@exporthints for designer-facing variables
4. Memory Management
Check for:
Signal Leaks:
- β Connecting signals without disconnecting:
signal.connect(callback) - β
Disconnect in
_exit_tree()or use one-shot:signal.connect(callback, CONNECT_ONE_SHOT)
Queue Free:
- β Calling
free()directly (can cause crashes) - β
Use
queue_free()for safe deferred deletion
Circular References:
- Nodes holding references to each other without cleanup
- Signals creating circular dependencies
Resource Cleanup:
- Not freeing manually allocated resources
- Holding references to destroyed nodes
5. Error Handling
Check for:
Null Checks:
# β Bad
var target = get_target()
target.take_damage(10) # Crashes if null
# β
Good
var target = get_target()
if target:
target.take_damage(10)
Array Access:
- β Direct index access:
array[5](can crash) - β
Check bounds:
if array.size() > 5:
Type Assumptions:
- Assuming node types without verification
- Not checking
is_instance_valid()
6. Code Duplication Patterns
Look for repeated logic in:
- Enemy scripts (movement, health, death)
- Weapon scripts (targeting, firing, cooldown)
- UI scripts (showing/hiding, updating)
Suggest:
- Base classes:
enemy_base.gdwith shared behavior - Composition: Extract systems (health_component.gd, movement_component.gd)
- Utility functions: Shared helper scripts
7. Godot 4.x Specific Issues
Check for:
Deprecated Syntax:
onready varβ Should use@onready varexport varβ Should use@export varyield()β Should useawait- Old signal syntax β Should use
.emit()
New Features Not Used:
- Not using typed Arrays:
var items: Array[Item] - Not using
@export_range,@export_enumfor better editor integration - Not using
@warning_ignorefor intentional code patterns
8. Project-Specific Patterns (Mech Survivors)
Check for:
Delta Scaling:
- Using
deltawhen should useDeltaScale.get_scaled_delta(delta)(for test acceleration) - Inconsistent delta scaling across systems
Manager Access:
- Direct scene tree queries instead of using managers (PassiveManager, VFXManager, etc.)
- Creating VFX/damage numbers manually instead of using managers
Weapon Pattern:
- Weapons not following established pattern (target selection, cooldown, firing)
- Missing required methods:
fire(),select_target(),reset()
Enemy Pattern:
- Enemies not inheriting from
enemy_base.gd - Not using shared health/damage/death systems
How to Perform Analysis
- Identify scope: Ask which files to analyze, or find all .gd files
- Read code: Load script contents
- Run checks: Go through all 8 analysis categories
- Cross-reference: Look for duplication across multiple files
- Prioritize findings: Critical bugs > Performance > Style
- Provide examples: Show bad code and suggested refactor
- Generate report: Create the markdown report content
- Display in chat: Show the complete report to the user
- Save to file: Write the exact same report to a markdown file in
docs/code-reviews/
Output Format
# GDScript Refactor Report: [script_name].gd
## Summary
- Lines of code: X
- Issues found: X
- Severity: π΄ Critical | π‘ Warning | π’ Suggestion
---
## Critical Issues (Fix Immediately)
### 1. [Issue Name] - Line X
**Problem:**
```gdscript
# Current code
[problematic code]
Impact: [Why this is critical]
Fix:
# Suggested refactor
[improved code]
Performance Warnings (Should Fix)
[Same format]
Code Quality Suggestions (Nice to Have)
[Same format]
Code Duplication Analysis
[If multiple files checked, show similar code blocks]
Refactoring Recommendations
- [High-level refactor suggestion]
- Extract [X] to [Y]
- Benefits: [Improved maintainability/performance/etc.]
- Effort: [Low/Medium/High]
Overall Assessment
[1-2 paragraph summary with priority recommendations]
## Report File Output
**CRITICAL: Every analysis must be saved to a file in addition to being shown in chat.**
### File Location
Save reports to: `docs/code-reviews/[script-name]_review_[YYYY-MM-DD].md`
**Examples:**
- Single file: `docs/code-reviews/player_review_2025-01-15.md`
- Multiple files: `docs/code-reviews/weapon-scripts_review_2025-01-15.md`
- Specific component: `docs/code-reviews/enemy-ai_review_2025-01-15.md`
### File Naming Convention
- Use the script name (without `.gd` extension)
- Convert to kebab-case if needed
- Append `_review_[date]` where date is YYYY-MM-DD format
- If reviewing multiple related scripts, use a descriptive group name
### Process
1. Generate the complete markdown report
2. Display the report in chat to the user
3. Use the Write tool to save the **exact same content** to the appropriate file path
4. Confirm to the user where the report was saved
### Report Header Addition
Add this metadata at the top of the saved file (but not in chat):
```markdown
---
review_date: YYYY-MM-DD
reviewed_files:
- path/to/script1.gd
- path/to/script2.gd
reviewer: Claude Code (gdscript-quality-checker skill)
---
Then include the full report content below the metadata.
Analysis Rules
- Be specific: Reference exact line numbers and code snippets
- Show examples: Always show before/after code
- Context matters: Consider prototype vs. production quality
- Prioritize correctly: Game-breaking bugs before style issues
- Explain "why": Don't just say "bad", explain the consequences
- Godot-first: Focus on Godot-specific issues before generic coding practices
Important Notes
- Type safety is important but not critical for prototypes
- Prefer readability over micro-optimizations during prototyping
- Suggest refactors that reduce duplication (DRY principle)
- Highlight patterns that will cause bugs during playtesting
- Consider the "weekend prototype" context from CLAUDE.md
Example Invocations
User: "Check my player.gd script" User: "Review all weapon scripts for issues" User: "Refactor the enemy AI code" User: "Is my code following Godot best practices?" User: "Find performance issues in my scripts"
Workflow Summary
When this skill is invoked:
- Analyze the specified GDScript file(s)
- Generate comprehensive markdown report
- Display the report in chat
- Save the exact same report to
docs/code-reviews/[name]_review_[date].md - Confirm file location to the user
This ensures both immediate feedback and persistent documentation of code reviews.
More by cautiouskurns
View allCreate and maintain a Game Design Bible documenting design vision, pillars, mechanics philosophy, and creative direction. Use this when establishing design principles or documenting high-level creative decisions.
Implement a feature spec by creating all necessary scenes, scripts, and resources. Use this when the user wants to implement a documented feature from the docs/features/ directory.
Read a prototype GDD and generate a phased implementation roadmap with concrete tasks, organized by implementation phases with specific deliverables and test criteria.
Build and maintain a living architecture document tracking scene trees, data structures, system hierarchies, and game architecture. Use this when visualizing game structure, documenting scene hierarchies, or tracking data schemas.
