The short answer
Organize a Godot 4 project by feature: keep each scene next to its script and the assets only it uses, and put shared code, autoloads, and third-party addons in clearly named folders. Use snake_case for file and folder names, move files inside the Godot FileSystem dock so references update, commit project.godot and the .import and .uid files, and ignore the .godot folder. A clear layout makes a project easier to navigate for you, your team, and the tools that read it.
What does a Godot 4 project folder contain?
The folder that holds project.godot is the project root, and Godot addresses everything inside it with res:// paths. Some files are yours, some are generated by the editor, and knowing the difference keeps version control clean and moves safe.
| Path | What it is | Version control |
|---|---|---|
| project.godot | Project settings, including the main scene, input map, and autoloads | Commit |
| .godot/ | Editor cache and imported asset data that Godot regenerates | Ignore |
| *.import | Import settings saved beside each asset | Commit |
| *.uid | Stable resource IDs saved beside scripts and shaders in Godot 4.4 and later | Commit |
| export_presets.cfg | Export targets and their options | Commit; keep signing passwords and keystores out of the repository |
| A folder containing .gdignore | A folder Godot skips entirely: not imported and not shown in the FileSystem dock | Your choice |
Should I organize folders by type or by feature?
Organize by feature. When the player scene, its script, and its sprites live together, everything you touch for one change sits in one place, and moving or deleting the feature is a single folder operation. Folders such as scripts/ and textures/ that mix every feature together grow hard to navigate as the project grows.
Keep genuinely shared pieces in their own folders: autoload scripts, reusable UI components, and fonts or audio used across the game. Godot’s own guidance also recommends snake_case for file and folder names, which avoids case-sensitivity surprises when an exported game runs on a different operating system. C# scripts are the exception, following PascalCase to match their class names.
res://
├── project.godot
├── autoload/
│ ├── game_state.gd
│ └── audio_bus.gd
├── player/
│ ├── player.tscn
│ ├── player.gd
│ └── player_sprites.png
├── enemies/
│ └── slime/
│ ├── slime.tscn
│ └── slime.gd
├── levels/
│ ├── level_1.tscn
│ └── level_2.tscn
├── ui/
│ ├── hud.tscn
│ └── pause_menu.tscn
└── addons/
└── (third-party plugins)How do I reference scenes so moving files does not break them?
Move and rename files inside Godot’s FileSystem dock rather than in your operating system’s file manager. The editor then updates scenes and resources that point at the moved file. In Godot 4.4 and later, each script and shader also gets a .uid file, which lets references survive a move as long as that file travels with it.
In scripts, prefer an exported PackedScene over a hard-coded path. The Inspector stores the reference as a resource link, so the script keeps working when the scene moves, and a designer can swap the scene without editing code. Reserve preload() for resources that truly never change, and keep those paths in one place.
extends Node2D
@export var enemy_scene: PackedScene
@export var spawn_interval: float = 2.0
var _elapsed: float = 0.0
func _process(delta: float) -> void:
if enemy_scene == null:
return
_elapsed += delta
if _elapsed >= spawn_interval:
_elapsed = 0.0
spawn_enemy()
func spawn_enemy() -> void:
var instance: Node = enemy_scene.instantiate()
if not (instance is Node2D):
push_warning("enemy_scene must have a Node2D root.")
instance.free()
return
var enemy := instance as Node2D
add_child(enemy)
enemy.position = Vector2.ZEROKeep in mind: Typed exports such as @export var enemy_scene: PackedScene also make the Inspector refuse the wrong resource type, which catches broken assignments before you run the game. If the scene’s root is not the expected type, the spawner frees the instance it created so nothing is left orphaned outside the tree.
What belongs in the project root and the addons folder?
Keep the root lean: project.godot, the project icon, and top-level folders. Set the main scene under Project → Project Settings → Application → Run so the entry point is explicit rather than implied by a file at the root.
Third-party editor plugins belong in res://addons/<plugin_name>/, which is where Godot looks for plugin.cfg files. Treat that folder as vendor code: update it as a unit, and keep your own game code elsewhere so an addon update never overwrites it.
- Every scene that runs on its own has its script and private assets beside it.
- Shared autoloads live in one folder with names that match their autoload names.
- File and folder names use snake_case consistently.
- Large source files such as layered artwork or raw audio that the game does not load are kept outside the project, or in a folder marked with .gdignore.
- The .godot folder is listed in your version-control ignore file.
How does a clear structure help GDSense?
GDSense builds a compact project map from this structure and includes it with your conversations: the project name, Godot version, main scene, autoloads, and your scenes and scripts grouped by folder. A feature-based layout reads like a table of contents, so answers can name the right scene or script, and Agent Mode can head straight to the files a task involves. Folders marked with .gdignore are skipped, just as Godot skips them.
Ask about structure the same way you ask about code. GDSense already has the map, so a question about where something belongs can be answered in terms of your actual folders.
I am about to add a second enemy type and a shop screen.
Using my current project map, suggest where each new scene, script, and asset should go.
Keep the existing folders and autoload names. Do not move any files yet.