Initial checkin
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
name: Verify Export Config
|
||||||
|
on: workflow_dispatch
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Download export templates (cached)
|
||||||
|
run: |
|
||||||
|
mkdir -p .godot/export_templates
|
||||||
|
wget -qO- https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_export_templates.tpz \
|
||||||
|
| tar xzf - -C .godot/export_templates --strip-components=1
|
||||||
|
- name: Validate project compiles cleanly
|
||||||
|
run: godot --headless --quit-after-editor-checks 2>&1 | tee editor.log
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
name: GDScript Lint
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run gd-lint
|
||||||
|
run: |
|
||||||
|
pipx install godot-lint
|
||||||
|
gd_lint src/ --error-on-warn --ignore=core/,tools/
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
name: Run Tests
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install Godot CLI
|
||||||
|
run: |
|
||||||
|
wget -q https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip
|
||||||
|
unzip -qq *.zip -d /tmp/ && sudo cp "/tmp/Godot v4.3 stable/Godot_v4.3-stable_linux.x86_64" /usr/local/bin/godot && chmod +x /usr/local/bin/godot
|
||||||
|
- name: Run headless tests
|
||||||
|
run: |
|
||||||
|
godot --headless --script res://tests/run_tests.gd --quit-after-tests
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# Auto-generated by Godot
|
||||||
|
.godot/
|
||||||
|
*.import
|
||||||
|
*.gdignore
|
||||||
|
export_templates/
|
||||||
|
|
||||||
|
# IDE & OS
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
# Build output (keep out of src/)
|
||||||
|
bin/
|
||||||
|
osu!/
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# How to Ask for Help on YeetGeese
|
||||||
|
|
||||||
|
When prompting an AI about this project, include:
|
||||||
|
1. **Godot version:** "Godot 4.x" (use GDScript 4 syntax: typed signals, `@onready`, match/enums)
|
||||||
|
2. **Node context:** e.g., "`TowerBase.gd` extending `Node2D` with a child `ProjectileSpawner` Marker2D"
|
||||||
|
3. **Goal + constraint:** "Make fire rate scale with tower level without hardcoding values."
|
||||||
|
|
||||||
|
## Coding Conventions We Follow
|
||||||
|
- Prefer `Resource`-backed stats over exported hardcoded numbers where balance changes are expected.
|
||||||
|
- Use named signals: `signal damage_dealt(amount: int)`, `signal mob_killed(currency_reward: int)`
|
||||||
|
- Keep scenes small; compose behavior across nodes rather than one 1000-line script.
|
||||||
|
- Always type variables and return values in GDScript 4 style.
|
||||||
|
|
||||||
|
## Prompt Templates That Work Well
|
||||||
|
- "Write a GDScript 4 `find_target()` that picks the enemy furthest along its path from this tower, using `_get_enemies_in_range() -> Array[EnemyMob]`."
|
||||||
|
- "Refactor this hardcoded fire rate into a `TowerStats.res` Resource and show how the tower reads it on spawn."
|
||||||
|
- "Implement a placement preview cursor that snaps to a grid and turns red where `_can_build_at()` returns false."
|
||||||
|
|
||||||
|
## What I Expect From You (AI)
|
||||||
|
- Return complete, runnable GDScript 4 with comments explaining node setup.
|
||||||
|
- Flag any Godot 3 vs 4 API differences (e.g., `move_and_slide()` behavior, signal typing).
|
||||||
|
- If a request needs multiple scenes, describe the scene hierarchy before showing code.
|
||||||
|
|
||||||
|
Read `ARCHITECTURE.md` for system boundaries and data flow expectations.
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# 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)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# YeetGeese 🪿🚜
|
||||||
|
|
||||||
|
A farm-themed tower defense where you yeet geese at oncoming livestock. Built with Godot 4.x.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
1. Open this folder in **Godot 4.3+** (stable recommended).
|
||||||
|
2. Run `main.tscn` from the editor's Play button.
|
||||||
|
3. Place towers along the animal path and watch the geese fly!
|
||||||
|
|
||||||
|
## Folder Layout
|
||||||
|
- `src/core/` - Autoloads & global state (wave progress, currency)
|
||||||
|
- `src/towers/` - Base tower node + individual yeeter scenes
|
||||||
|
- `src/projectiles/` - Goose projectile logic & impact handling
|
||||||
|
- `src/enemies/` - Animal mob scenes & path navigation data
|
||||||
|
- `src/waves/` - `WaveTable.res` (balance file) + runner system
|
||||||
|
- `src/ui/` - HUD, placement gizmo, menus
|
||||||
|
|
||||||
|
## For AI Assistants
|
||||||
|
Read `AI_HELP.md` before writing code. It contains our GDScript 4 conventions, scene expectations, and prompt templates tailored to this project.
|
||||||
|
|
||||||
|
## License
|
||||||
|
TBD (placeholder for indie release)
|
||||||
Reference in New Issue
Block a user