Teaching Claude to name nodes consistently
by Fireal Software · ~7 min read
Ask Claude to generate five enemy scenes and you’ll end up with something like enemy.tscn, Enemy2.tscn, enemy_boss.TSCN, EnemyFast.tscn, enemy-ranged.tscn. Every one picks a different casing, a different separator, a different naming instinct based on whatever pattern the model grabbed from its training data.
Human developers have this problem too. The fix is a style guide. Godot Catalyst gives Claude three tools that make the style guide enforceable.
The three tools
src/tools/convention-tools.ts registers three tools:
godot_check_conventions— scan the project for naming and structure violationsgodot_fix_conventions— auto-fix a specific issue in a specific filegodot_set_convention_rules— save project-specific rules to.godot-catalyst-conventions.json
The default rules are boringly standard for Godot 4:
- Scene files (
.tscn): PascalCase (Player.tscn,MainMenu.tscn) - Script files (
.gd): snake_case (player.gd,main_menu.gd) - Resource files (
.tres): snake_case (red_potion.tres) - Folders: snake_case (
enemies/,ui/)
All three can be overridden per-project. The default matches the official Godot style guide, which matches what most GDScript projects in the wild use.
Why conventions matter more for agents
When a human developer writes code, inconsistent naming is annoying but not fatal. You can grep, you can read, you can remember “oh right, this file is the one with the weird name”.
Agents don’t have that muscle memory. When Claude writes extends "res://scripts/player.gd" in one place and extends "res://Scripts/Player.gd" in another, Godot’s case-insensitive filesystem on Windows might let it slide — then break on Linux or macOS when the project ships. When Claude searches for a node type, it won’t find @Node@12345 because it’s looking for EnemySpawner.
The convention matters most at generation time. If Claude knows the rules up front, it generates correctly. If it doesn’t, it generates slop and you clean up after it. Fixing it at generation is cheaper than fixing it at review.
There’s also a specific bug worth naming here. Early versions of godot_batch_create_nodes had a parameter-forwarding issue where the handler dropped node_type, node_name, and properties, creating generic @Node@xxxx nodes with autogenerated names. The fix is in the code now (all three fields forward correctly), but the pattern is instructive: batch tools that generate content need to pass every field through cleanly, or you get consistency-free output.
How check works
godot_check_conventions walks the project (skipping .* and addons/), looks at every file and folder, and applies the rules:
- Scene files: if the name doesn’t match the configured pattern, flag it
- Script files: same
- Resource files: same
- Folders: if not snake_case, flag it
Returns a JSON report:
{
"success": true,
"rules": {
"scene_naming": "PascalCase",
"script_naming": "snake_case",
"resource_naming": "snake_case"
},
"violation_count": 3,
"violations": [
{
"file": "scenes/enemy_boss.tscn",
"rule": "scene_naming",
"message": "Scene 'enemy_boss.tscn' should be PascalCase (e.g. 'EnemyBoss.tscn')",
"fixable": false
}
]
}
The fixable: false on scene renames is deliberate. Renaming a .tscn file breaks every reference to it — other scenes that instance it, scripts that load it, project settings that point to it. Auto-renaming without updating references leaves the project broken. Godot Catalyst flags but doesn’t fix this class of violation. Human review is the right answer.
What auto-fix handles
godot_fix_conventions handles the safe fixes. Currently:
- Signal naming in GDScript files:
signal PlayerDied→signal player_died - Potentially more as the rule set grows
The bar for adding an auto-fixer: it has to be safe to run without review. Renaming a signal is safe because the emitter and the connection both break at the same time (all references live in GDScript which can be refactored statically). Renaming a scene file is unsafe because references span TSCN, GDScript, and project.godot.
For anything not safe to auto-fix, Claude reports the violation and leaves the choice to you.
Custom rules
godot_set_convention_rules writes .godot-catalyst-conventions.json in your project root:
{
"scene_naming": "PascalCase",
"script_naming": "snake_case",
"resource_naming": "snake_case"
}
You can also pass rule overrides directly to godot_check_conventions:
godot_check_conventions({
"rules": {
"scene_naming": "snake_case",
"script_naming": "snake_case"
}
})
If your project uses snake_case for everything (unusual but valid), set both to snake_case and the checker stops complaining about player.tscn.
The generation-time version
Conventions at check time are reactive. The better flow is at generation time — Claude should know the rules before it creates the first node.
Drop this in your project’s CLAUDE.md:
This project follows Godot style conventions:
- Scene files: PascalCase (Player.tscn, MainMenu.tscn)
- Script files: snake_case (player.gd, main_menu.gd)
- Resource files: snake_case (red_potion.tres)
- Node names: PascalCase (Player, AttackTimer, HealthBar)
- Signal names: snake_case (player_died, health_changed)
Run `godot_check_conventions` after generating new files to catch violations.
Claude will follow this naturally. The check tool is the safety net — it catches cases where the model slipped (or where legacy files already violate the pattern).
Node naming vs file naming
File naming is checked by the tools. Node naming inside scenes is checked by your own guidance. If you prompt “add a player node with a sprite child”, Claude might create Player → Sprite2D (fine) or player → sprite (GDScript conventional, awkward as a node name).
Godot’s own conventions are:
- Files: snake_case
- Folders: snake_case
- Classes (
class_name): PascalCase - Node names: PascalCase (matches the scene file they’re in)
- Variables, functions, signals: snake_case
The mismatch between file naming (snake_case scripts) and class naming (PascalCase) is a frequent source of confusion. player.gd contains class_name Player. The node is named Player in the scene. The script file is player.gd. This is correct Godot style even though it looks inconsistent.
Running it in a loop
If you’re migrating a legacy project to consistent conventions, the pattern is:
godot_check_conventionsto find all violations- For each
fixable: trueviolation,godot_fix_conventionsto apply the fix - For each
fixable: falseviolation, manual rename withgodot_rename_node/ file moves (updating references) - Re-run
godot_check_conventionsto confirm clean
On a 200-script project, this takes Claude about five minutes. Doing it by hand takes an afternoon.
Convention tools need GODOT_PROJECT_PATH set.
Turn Claude into a Godot co-developer
Godot Catalyst is an MCP server with 240+ tools for Godot 4.x. GDScript LSP, DAP debugging, offline parsing, asset pipelines. 7-day free trial, $25 one-time.
Try Godot Catalyst