Project Structure, Version Control & Style Guide
Organize by feature (keeps scenes, scripts, and assets that belong together close):
40.1 Project structure
Organize by feature (keeps scenes, scripts, and assets that belong together close):
Use snake_case for all file and folder names (exports to case-sensitive filesystems safely).
res://
├── addons/ # third-party plugins (GUT, gdUnit4, Dialogic...)
├── autoload/ # game_state.gd, events.gd, audio_manager.gd
├── common/ # shared components, shaders, UI theme
│ ├── components/ # health_component.gd, hitbox.gd
│ └── ui/theme.tres
├── entities/
│ ├── player/ # player.tscn, player.gd, player.png, states/
│ └── enemies/slime/ # slime.tscn, slime.gd, slime_data.tres
├── levels/ # level_01.tscn ...
├── ui/ # main_menu.tscn, hud.tscn, pause_menu.tscn
├── data/ # items/*.tres, dialogue/*.json
└── test/ # unit tests40.2 Version control (Git)
Commit: project.godot, scenes, scripts, resources, *.import files, *.uid files (4.4+), export_presets.cfg.
Ignore: .godot/ (imported cache, regenerated automatically).
Add .gitattributes with * text=auto eol=lf to avoid line-ending churn; use Git LFS for large binaries (PSD, WAV, FBX, videos).
Text scenes (.tscn) merge reasonably, but avoid two people editing the same scene simultaneously; split big scenes into sub-scenes.
Since 4.4, .uid files make references survive file moves — move files inside the editor's FileSystem dock so references update.
# Godot 4 .gitignore
.godot/
/android/
*.tmp
export_credentials.cfg
build/40.3 GDScript style guide (official conventions)
Classes (class_name) Functions & variables take_damage(), max_speed _velocity, _update_ui() snake_case, past tense health_changed, door_opened Constants & enum members MAX_SPEED, State.IDLE ≤ 100 characters (prefer 80) is_, has_, can_ prefixes
40.4 Code order
Leave two blank lines between functions. Document public APIs with ## comments (support BBCode-like tags such as [param amount], [method foo], @deprecated, @experimental).
@tool
@icon("res://icons/player.svg")
class_name Player
extends CharacterBody2D
## Brief description of the class.
##
## Longer description; shown in the editor's built-in help.
signal died
signal health_changed(value: int)
enum State { IDLE, RUN }
const MAX_SPEED := 300.0
@export var speed := 200.0
var health := 100
var _state: State = State.IDLE
@onready var _sprite: Sprite2D = $Sprite2D
func _init() -> void: pass
func _enter_tree() -> void: pass
func _ready() -> void: pass
func _process(_delta: float) -> void: pass
func _physics_process(_delta: float) -> void: pass
## Public method docs go here.
func take_damage(amount: int) -> void:
pass
func _private_helper() -> void:
pass
class InnerHelper:
pass40.5 Tooling
gdtoolkit (pip install gdtoolkit — use version 4.x for Godot 4): gdformat (formatter) and gdlint (linter).
Pre-commit hooks to run gdformat --check and tests.
Editor: enable *Text Editor → Behavior → Files → Trim Trailing Whitespace On Save*, and *Add Type Hints* in completion settings.