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 tests

40.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:
	pass

40.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.