Files
YeetGeese/AI Docs/02-ARCHITECTURE.md
letteka c36afc75e5
Validate Project / validate (push) Successful in 16s
Moving documents to their own folder.
2026-09-04 09:24:34 -07:00

1.7 KiB

YeetGeese Architecture Notes

Core Loop

  1. WaveRunner reads a WaveTable Resource → spawns enemies onto a shared NavigationRegion2D path.
  2. Player drags a tower placement cursor → confirms → instantiates a tower scene at the grid cell.
  3. Towers run a continuous find_target() → call fire() → spawn a goose projectile from ProjectileSpawner.
  4. Geese travel to the target, deal damage, and grant currency on kill.

Key Design Choices

  • Stats as Resources: Every balanceable value (damage, fire rate, enemy HP) lives in .tres/.tres files, not hardcoded. This keeps tuning non-invasive.
  • Signals over polling: Towers emit target_acquired, enemies emit health_changed, HUD listens via %HUD. No frame-polling managers.
  • Placement grid decoupled from navigation: The buildable area is a Vector2i grid checked against _can_build_at(). Pathfinding uses Godot's built-in NavigationServer2D.

Scene Expectations (for AI)

  • Tower: TowerBase.gd (Node2D) with child ProjectileSpawner (Marker2D) and TargetFinder.
  • Enemy: EnemyMob.gd extending Area2D, uses _ready() to assign a path via $NavigationPath2D.bake_path_from_parent().
  • Projectile: Goose.gd extending RigidBody2D or CharacterBody2D with linear velocity toward target.

Data Flow Example

# WaveRunner creates an enemy from a resource
var mob_scene = enemy_res.instantiate().tree_entered.connect(_on_mob_spawned)
add_child(mob_scene)

# Tower acquires and fires
func fire_at(target: Node2D) -> void:
    var goose := projectile_res.instantiate() as Goose
    add_child(goose)
    goose.yeet_from($ProjectileSpawner.global_position, target.global_position)