Code style
Style guide
For consistency across projects, we recommend following these guidelines:
-
Use snake_case for folder and file names (with the exception of C# scripts). This sidesteps case sensitivity issues that can crop up after exporting a project on Windows. C# scripts are an exception to this rule, as the convention is to name them after the class name which should be in PascalCase.
-
Use PascalCase for node names, as this matches built-in node casing.
-
In general, keep third-party resources in a top-level
addons/folder, even if they aren't editor plugins. This makes it easier to track which files are third-party. There are some exceptions to this rule; for instance, if you use third-party game assets for a character, it makes more sense to include them within the same folder as the character scenes and scripts.
Node and Scene References
Node References
Like all programming problems, referencing a node or scene in a Godot script can be done in many ways. I've found that some of these ways can raise issues during development that can cause problems, but which you use depends entirely on the nature of your project.
For example, if you're still in the process of restructuring things, choosing an option that doesn't break while moving nodes around is probably ideal. If you're still in the process of choosing proper names for your nodes, then the export option might be even better. (Something that may be the case during test scenes and such.)
| Option | Breaks on rename | Breaks on reorganizing | Developer experience |
|---|---|---|---|
$Name |
Yes | Yes | Most problematic, but most handy if you're just using it once for some odd thing… Risky, I suppose. Probably a bad habit to use often. |
find_child("Name") |
Yes | No | Once you use it, you're stuck with that name. Can be good, can be annoying. |
%Name |
Yes | No | Functionally similar to the previous option, but now you have to set up % in your scene. I'm a little against this non-code UI option, it feels weird. |
@export var some_node:Node |
No | No | The most robust option, however… It can clutter the property inspector when including a scene that exports variables that shouldn't be changed by other scenes. If you're not careful, you can forget to set it as well, something a little less likely with more explicit options. |
Scene References
Scenes have similar issues, but you're able to reference them in a variety of ways.
General referencing
| Option | Breaks on rename | Breaks on reorganizing | Developer experience |
|---|---|---|---|
load("path/to/file.tscn") |
Yes | Yes | Most problematic. Can cause issues for filesystems that are case sensitive, like web builds or linux builds. |
load(“uid://someuidthing”) |
No | No | Pretty good but you can run into issues with circular dependencies if you're not careful. |
@export var some_scene:PackedScene |
No | No | Functionally similar to the previous option, but with the added benefit of having a preview in editor. You might be able to pull off a read-only exported variable with the previous option to get a similar effect. |
The scenemanager-pattern
The "Scene Manager" (or Autoload/Singleton) approach is the standard architectural pattern for Godot games as they scale.
Instead of Scene A talking directly to Scene B (which causes circular dependencies), both scenes talk to a central Manager. This decouples your code and gives you a single place to handle transitions, loading screens, and global state.
The manager is the only place in the game ,that actually loads scenes. It can use any of the above approaches.