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:

The default rules are boringly standard for Godot 4:

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:

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:

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 PlayerSprite2D (fine) or playersprite (GDScript conventional, awkward as a node name).

Godot’s own conventions are:

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:

  1. godot_check_conventions to find all violations
  2. For each fixable: true violation, godot_fix_conventions to apply the fix
  3. For each fixable: false violation, manual rename with godot_rename_node / file moves (updating references)
  4. Re-run godot_check_conventions to 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