Files
BMAD-METHOD/bmad/bmm/workflows/3-solutioning/templates/game-engine-godot-guide.md

11 KiB

Godot Game Engine Architecture Guide

This guide provides Godot-specific guidance for solution architecture generation.


Godot-Specific Questions

1. Godot Version and Language Strategy

Ask:

  • Which Godot version? (3.x, 4.x)
  • Language preference? (GDScript only, C# only, or Mixed GDScript+C#)
  • Target platform(s)? (PC, Mobile, Web, Console)

Guidance:

  • Godot 4.x: Modern, Vulkan renderer, better 3D, C# improving
  • Godot 3.x: Stable, mature ecosystem, OpenGL
  • GDScript: Python-like, fast iteration, integrated with editor
  • C#: Better performance for complex systems, familiar to Unity devs
  • Mixed: GDScript for game logic, C# for performance-critical (physics, AI)

Record ADR: Godot version and language strategy


2. Node-Based Architecture

Ask:

  • Scene composition strategy? (Nested scenes, scene inheritance, or flat hierarchy)
  • Node organization patterns? (By feature, by type, or hybrid)

Guidance:

  • Scenes as Prefabs: Each reusable entity is a scene (Player.tscn, Enemy.tscn)
  • Scene Inheritance: Extend base scenes for variations (BaseEnemy → FlyingEnemy)
  • Node Signals: Use built-in signal system for decoupled communication
  • Autoload Singletons: For global managers (GameManager, AudioManager)

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


3. Resource Management

Ask:

  • Use Godot Resources for data? (Custom Resource types for game data)
  • Asset loading strategy? (preload vs load vs ResourceLoader)

Guidance:

  • Resources: Like Unity ScriptableObjects, serializable data containers
  • preload(): Load at compile time (fast, but increases binary size)
  • load(): Load at runtime (slower, but smaller binary)
  • ResourceLoader.load_threaded_request(): Async loading for large assets

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-Specific Architecture Sections

Signal-Driven Communication

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:

  • Decoupled systems
  • No FindNode or get_node everywhere
  • Type-safe with typed signals (Godot 4)

Godot Scene Architecture

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

Performance Optimization

Godot-specific considerations:

  • Static Typing: Use type hints for GDScript performance (var health: int = 100)
  • Object Pooling: Implement manually or use addons
  • CanvasItem batching: Reduce draw calls with texture atlases
  • Viewport rendering: Offload effects to separate viewports
  • GDScript vs C#: C# faster for heavy computation, GDScript faster for simple logic

Target Performance:

  • PC: 60 FPS minimum
  • Mobile: 60 FPS (high-end), 30 FPS (low-end)
  • Web: 30-60 FPS depending on complexity

Profiler:

  • Use Godot's built-in profiler (Debug > Profiler)
  • Monitor FPS, draw calls, physics time

Testing Strategy

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:

  • 80% minimum test coverage (from expansion pack)
  • Test game systems, not rendering
  • Use GUT for GDScript, GoDotTest for C#

Source Tree Structure

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

Deployment and Build

Platform-specific:

  • PC: Export presets for Windows, Linux, macOS
  • Mobile: Android (APK/AAB), iOS (Xcode project)
  • Web: HTML5 export (SharedArrayBuffer requirements)
  • Console: Partner programs for Switch, Xbox, PlayStation

Export templates:

  • Download from Godot website for each platform
  • Configure export presets in Project > Export

Build automation:

  • Use godot --export command-line for CI/CD
  • Example: godot --export-release "Windows Desktop" output/game.exe

Specialist Recommendations

Audio Designer

When needed: Games with music, sound effects, ambience Responsibilities:

  • AudioStreamPlayer node architecture (2D vs 3D audio)
  • Audio bus setup in Godot's audio mixer
  • Music transitions with AudioStreamPlayer.finished signal
  • Sound effect implementation
  • Audio performance optimization

Performance Optimizer

When needed: Mobile games, large-scale games, complex 3D Responsibilities:

  • Godot profiler analysis
  • Static typing optimization
  • Draw call reduction
  • Physics optimization (collision layers/masks)
  • Memory management
  • C# performance optimization for heavy systems

Multiplayer Architect

When needed: Multiplayer/co-op games Responsibilities:

  • High-level multiplayer API or ENet
  • RPC architecture (remote procedure calls)
  • State synchronization patterns
  • Client-server vs peer-to-peer
  • Anti-cheat considerations
  • Latency compensation

Monetization Specialist

When needed: F2P, mobile games with IAP Responsibilities:

  • In-app purchase integration (via plugins)
  • Ad network integration
  • Analytics integration
  • Economy design
  • Godot-specific monetization patterns

Common Pitfalls

  1. Over-using get_node() - Cache node references in @onready variables
  2. Not using type hints - Static typing improves GDScript performance
  3. Deep node hierarchies - Keep scene trees shallow for performance
  4. Ignoring signals - Use signals instead of polling or direct coupling
  5. Not leveraging autoload - Use autoload singletons for global state
  6. Poor scene organization - Plan scene structure before building
  7. Forgetting to queue_free() - Memory leaks from unreleased nodes

Godot vs Unity Differences

Architecture Differences:

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

Language Differences:

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

Key Architecture Decision Records

ADR Template for Godot Projects

ADR-XXX: [Title]

Context: What Godot-specific issue are we solving?

Options:

  1. GDScript solution
  2. C# solution
  3. GDScript + C# hybrid
  4. Third-party addon (Godot Asset Library)

Decision: We chose [Option X]

Godot-specific Rationale:

  • GDScript vs C# performance tradeoffs
  • Engine integration (signals, nodes, resources)
  • Community support and addons
  • Team expertise
  • Platform compatibility

Consequences:

  • Impact on performance
  • Learning curve
  • Maintenance considerations
  • Platform limitations (Web export with C#)

This guide is specific to Godot Engine. For other engines, see:

  • game-engine-unity-guide.md
  • game-engine-unreal-guide.md
  • game-engine-web-guide.md