This guide provides Godot-specific guidance for solution architecture generation.
Ask:
Guidance:
Record ADR: Godot version and language strategy
Ask:
Guidance:
Godot Pattern:
# Player.gd
extends CharacterBody2D
signal health_changed(new_health)
signal died
@export var max_health: int = 100
var health: int = max_health
func take_damage(amount: int) -> void:
health -= amount
health_changed.emit(health)
if health <= 0:
died.emit()
queue_free()
Record ADR: Scene architecture and node organization
Ask:
Guidance:
Pattern:
# EnemyData.gd
class_name EnemyData
extends Resource
@export var enemy_name: String
@export var health: int
@export var speed: float
@export var prefab_scene: PackedScene
Record ADR: Resource and asset loading strategy
Godot’s built-in Observer pattern:
# GameManager.gd (Autoload singleton)
extends Node
signal game_started
signal game_paused
signal game_over(final_score: int)
func start_game() -> void:
game_started.emit()
func pause_game() -> void:
get_tree().paused = true
game_paused.emit()
# In Player.gd
func _ready() -> void:
GameManager.game_started.connect(_on_game_started)
GameManager.game_over.connect(_on_game_over)
func _on_game_started() -> void:
position = Vector2.ZERO
health = max_health
Benefits:
Scene organization patterns:
1. Composition Pattern:
Player (CharacterBody2D)
├── Sprite2D
├── CollisionShape2D
├── AnimationPlayer
├── HealthComponent (Node - custom script)
├── InputComponent (Node - custom script)
└── WeaponMount (Node2D)
└── Weapon (instanced scene)
2. Scene Inheritance:
BaseEnemy.tscn
├── Inherits → FlyingEnemy.tscn (adds wings, aerial movement)
└── Inherits → GroundEnemy.tscn (adds ground collision)
3. Autoload Singletons:
# In Project Settings > Autoload:
GameManager → res://scripts/managers/game_manager.gd
AudioManager → res://scripts/managers/audio_manager.gd
SaveManager → res://scripts/managers/save_manager.gd
Godot-specific considerations:
var health: int = 100)Target Performance:
Profiler:
GUT (Godot Unit Test):
# test_player.gd
extends GutTest
func test_player_takes_damage():
var player = Player.new()
add_child(player)
player.health = 100
player.take_damage(20)
assert_eq(player.health, 80, "Player health should decrease")
GoDotTest for C#:
[Test]
public void PlayerTakesDamage_DecreasesHealth()
{
var player = new Player();
player.Health = 100;
player.TakeDamage(20);
Assert.That(player.Health, Is.EqualTo(80));
}
Recommended Coverage:
Godot-specific folders:
project/
├── scenes/ # All .tscn scene files
│ ├── main_menu.tscn
│ ├── levels/
│ │ ├── level_1.tscn
│ │ └── level_2.tscn
│ ├── player/
│ │ └── player.tscn
│ └── enemies/
│ ├── base_enemy.tscn
│ └── flying_enemy.tscn
├── scripts/ # GDScript and C# files
│ ├── player/
│ │ ├── player.gd
│ │ └── player_input.gd
│ ├── enemies/
│ ├── managers/
│ │ ├── game_manager.gd (Autoload)
│ │ └── audio_manager.gd (Autoload)
│ └── ui/
├── resources/ # Custom Resource types
│ ├── enemy_data.gd
│ └── level_data.gd
├── assets/
│ ├── sprites/
│ ├── textures/
│ ├── audio/
│ │ ├── music/
│ │ └── sfx/
│ ├── fonts/
│ └── shaders/
├── addons/ # Godot plugins
└── project.godot # Project settings
Platform-specific:
Export templates:
Build automation:
godot --export command-line for CI/CDgodot --export-release "Windows Desktop" output/game.exeWhen needed: Games with music, sound effects, ambience Responsibilities:
When needed: Mobile games, large-scale games, complex 3D Responsibilities:
When needed: Multiplayer/co-op games Responsibilities:
When needed: F2P, mobile games with IAP Responsibilities:
@onready variables| Unity | Godot | Notes |
|---|---|---|
| GameObject + Component | Node hierarchy | Godot nodes have built-in functionality |
| MonoBehaviour | Node + Script | Attach scripts to nodes |
| ScriptableObject | Resource | Custom data containers |
| UnityEvent | Signal | Godot signals are built-in |
| Prefab | Scene (.tscn) | Scenes are reusable like prefabs |
| Singleton pattern | Autoload | Built-in singleton system |
| Unity C# | GDScript | Notes |
|---|---|---|
public class Player : MonoBehaviour |
class_name Player extends CharacterBody2D |
GDScript more concise |
void Start() |
func _ready(): |
Initialization |
void Update() |
func _process(delta): |
Per-frame update |
void FixedUpdate() |
func _physics_process(delta): |
Physics update |
[SerializeField] |
@export |
Inspector-visible variables |
GetComponent<T>() |
get_node("NodeName") or $NodeName |
Node access |
ADR-XXX: [Title]
Context: What Godot-specific issue are we solving?
Options:
Decision: We chose [Option X]
Godot-specific Rationale:
Consequences:
This guide is specific to Godot Engine. For other engines, see: