Anvil
Anvil is a Godot 4 (C#) editor plugin that generates compile-time safe StringName constants for the names and paths your project already has — tracked folders, global groups, input actions, and audio buses — so you stop typing raw strings by hand and stop finding out about typos at runtime.
Why
Referencing resources, groups, actions, and buses by raw string is fragile:
// note: you can use UID instead, this is just an option when working with raw file paths
GD.Load<AudioStream>("res://sfx/planted.wav"); // typo-prone, breaks silently if the file moves
AddToGroup("enimies"); // no compiler error, just a bug
Input.IsActionPressed("interact"); // same risk if the action gets renamed
Anvil scans folders you choose, plus your project's global groups, input actions, and audio buses, and generates a single Storage class with strongly-typed StringName constants for everything it finds:
using Anvil;
GD.Load<AudioStream>(Storage.Sfx.Planted);
AddToGroup(Storage.GlobalGroups.Enemies);
Input.IsActionPressed(Storage.InputActions.Interact);
Rename a file, delete a folder, or mistype an ID, and you get a compile error instead of a silent runtime bug.
Features
- Folder tracking — right-click any folder in the FileSystem dock and choose Track with Anvil... to generate an ID for every file inside it.
- Two generation modes per tracked folder:
Id— constants are just the file's base name (Storage.Sfx.Planted), plus aHintStringfor use with[Export(PropertyHint.Enum, ...)].FullPath— constants are the fullres://path to the file, useful when you need toLoad()it directly.
- Recursive scanning — optionally include subfolders.
- Global groups — every group declared in Project Settings → Globals → Groups is generated automatically as
Storage.GlobalGroups.*, no tracking required. - Input actions — every custom action in Project Settings → Input Map is generated as
Storage.InputActions.*(Godot's built-inui_*actions are excluded), no tracking required. - Audio buses — every bus in the current audio bus layout is generated as
Storage.AudioBuses.*, no tracking required.
Installation
- Copy the
addons/anvilfolder into your project'saddons/directory. - Enable the plugin under Project → Project Settings → Plugins.
- Anvil will generate
Storage.csandanvil_rules.tresautomatically on load, and again whenever you run Generate Anvil IDs from the Project → Tools menu.
Usage
Tracking a folder
Right-click any folder in the FileSystem dock and select Track with Anvil....

You'll be asked for:
| Field | Description |
|---|---|
| Output Name | The name of the generated nested class, e.g. Sfx → Storage.Sfx |
| Recursive | Whether to include files in subfolders |
| Mode | Id or FullPath, as described above |

Already-tracked folders show Edit Anvil Tracking... and Untrack from Anvil instead, so you can reconfigure or stop tracking a folder at any time.
Generating IDs
Anvil generates automatically on project load. To regenerate manually (e.g. after adding new files to a tracked folder), use Project → Tools → Generate Anvil IDs.
Using generated IDs
using Anvil;
GD.Load<AudioStream>(Storage.Sfx.Planted);
AddToGroup(Storage.GlobalGroups.Enemies);
Input.IsActionPressed(Storage.InputActions.Interact);
AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex(Storage.AudioBuses.Music), -6f);
[Export(PropertyHint.Enum, Storage.Sfx.HintString)]
public string SoundId;
If you're referencing IDs from one folder repeatedly in a file, using static drops the Storage. prefix:
using static Anvil.Storage;
GD.Load<AudioStream>(Sfx.Planted);
AddToGroup(GlobalGroups.Enemies);
How it works
Anvil stores your tracked-folder configuration in res://addons/anvil/anvil_rules.tres — a plain Godot Resource (AnvilRuleSet, containing a list of AnvilRule), editable either through the context menu dialog or directly in the inspector.
On generation, Anvil:
- Loads
anvil_rules.tres. - Validates every rule — skipping (with a warning) any rule with an empty output name, a duplicate output name, or a folder that no longer exists.
- Scans each valid tracked folder (respecting the
Recursiveflag and excluding.import/.uidfiles). - Scans declared global groups and input actions.
- Reads the current audio bus layout from
AudioServer. - Writes everything into
res://addons/anvil/generated/Storage.cs.
Storage.cs is generated at runtime into res://addons/anvil/generated/ — not part of the repo itself.
Known limitations
- Renaming or moving a tracked folder in the FileSystem dock is not detected automatically — Anvil matches rules by exact string path, so a rename leaves the old rule pointing at a path that no longer exists (reported as a warning on generation) and the new location untracked. Re-track the new location and remove the stale rule manually.
Storage.csis regenerated in full every time — don't hand-edit it, your changes will be overwritten.
License
MIT
Changelog for version v2.1.0
No changelog provided for this version.