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

30 lines
1.7 KiB
Markdown

# 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
```gdscript
# 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)