5 Commits
Author SHA1 Message Date
Andrew Yeet d632abd93c Defining collision layers, Issue 3 Task 4
Validate Project / validate (push) Successful in 16s
2026-09-07 18:55:38 -07:00
Andrew Yeet 92cc3cb4ed Adding gamestate autoload templates
Validate Project / validate (push) Successful in 15s
2026-09-07 16:47:30 -07:00
Andrew Yeet 15098c887a Issue #3 Task #3, basic structure
Validate Project / validate (push) Successful in 15s
2026-09-07 15:40:02 -07:00
Andrew Yeet e8386c99d4 Change to over the shoulder third person instead of first person.
Validate Project / validate (push) Successful in 16s
2026-09-04 15:05:25 -07:00
Andrew Yeet 639c11ad9c Adding a basic game design doc
Validate Project / validate (push) Successful in 16s
2026-09-04 13:27:15 -07:00
9 changed files with 235 additions and 11 deletions
+1
View File
@@ -17,3 +17,4 @@ osu!/
.env .env
.env.gitea .env.gitea
*.uid
+15 -1
View File
@@ -22,4 +22,18 @@ When prompting an AI about this project, include:
- Flag any Godot 3 vs 4 API differences (e.g., `move_and_slide()` behavior, signal typing). - 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. - If a request needs multiple scenes, describe the scene hierarchy before showing code.
Read `ARCHITECTURE.md` for system boundaries and data flow expectations.
## Handling Ambiguity & Assumptions (Crucial!)
When a request is ambiguous, incomplete, or requires knowledge outside the scope of the provided documents:
1. **DO NOT guess.** Do not write code based on assumptions you cannot validate.
2. **Acknowledge the Gap:** Explicitly state what information is missing or unclear (e.g., "The current architecture does not specify how \`WaveRunner\` handles player death.").
3. **Propose Assumptions:** If a concrete implementation path *must* be shown, list all assumptions made clearly before writing code. Use a dedicated section like:
\`\`\`markdown
**[ASSUMPTIONS MADE]**
1. We assume that the \`PlayerStats\` Resource is accessible from the global scope.
2. We are assuming the signal for enemy death will be named \`mob_killed\`.
\`\`\`
This ensures that the final code provided by AI can be reviewed against project reality before integration.
+10 -10
View File
@@ -1,4 +1,4 @@
Here is a practical phase plan for **YeetGeese**, a first-person tower defense game where the main weapon is thrown geese, built in **Godot 4**. Im assuming the core fantasy is: the player is in a 3D arena, enemies approach, and the player throws geese either as projectiles, temporary turrets, or both. The plan below is structured so you can build a small playable prototype first, then expand into a full indie game. Here is a practical phase plan for **YeetGeese**, an over-the-shoulder third-person tower defense game where the main weapon is thrown geese, built in **Godot 4**. Im assuming the core fantasy is: the player is in a 3D arena, enemies approach, and the player throws geese either as projectiles, temporary turrets, or both. The plan below is structured so you can build a small playable prototype first, then expand into a full indie game.
--- ---
@@ -103,14 +103,14 @@ Here is a practical phase plan for **YeetGeese**, a first-person tower defense g
--- ---
# Phase 1: Core Playable Prototype # Phase 1: Core Playable Prototype
**Goal:** Prove that throwing geese at enemies in a first-person tower defense arena is fun. **Goal:** Prove that throwing geese at enemies in an over-the-shoulder third-person tower defense arena is fun.
This is the most important phase. Do not focus on art yet. Use greybox shapes and placeholder audio. This is the most important phase. Do not focus on art yet. Use greybox shapes and placeholder audio.
## Core Systems to Build ## Core Systems to Build
### 1. First-Person Player Controller ### 1. Third-Person Player Controller
Create a first-person controller using Godots `CharacterBody3D`. Create an over-the-shoulder third-person player controller using Godots `CharacterBody3D`.
Basic structure: Basic structure:
```text ```text
@@ -273,7 +273,7 @@ A single playable scene where the player can:
# Phase 2: Tower Defense Core Systems # Phase 2: Tower Defense Core Systems
**Goal:** Turn the prototype into a real tower defense game by adding towers, upgrades, enemy variety, and a more complete loop. **Goal:** Turn the prototype into a real tower defense game by adding towers, upgrades, enemy variety, and a more complete loop.
This phase is where YeetGeese becomes its own genre hybrid: first-person action + tower defense strategy. This phase is where YeetGeese becomes its own genre hybrid: third-person action + tower defense strategy.
## Design Decision: How Do Geese Function as Towers? ## Design Decision: How Do Geese Function as Towers?
@@ -527,7 +527,7 @@ Enemies attack the player directly.
Pros: Pros:
- Simple. - Simple.
- Feels first-person. - Feels third-person.
Cons: Cons:
- Less tower defense feel. - Less tower defense feel.
@@ -710,7 +710,7 @@ Audio mixing:
- UI sounds should be subtle. - UI sounds should be subtle.
## Performance Goals ## Performance Goals
For a first-person 3D indie game, aim for: For a third-person 3D indie game, aim for:
- 60 FPS on mid-range PC. - 60 FPS on mid-range PC.
- 30 FPS minimum on low-end PC. - 30 FPS minimum on low-end PC.
- Stable frame time. - Stable frame time.
@@ -1006,7 +1006,7 @@ Prepare:
- Tags: - Tags:
- Indie. - Indie.
- Tower Defense. - Tower Defense.
- First-Person. - Third-Person.
- Action. - Action.
- Strategy. - Strategy.
- Funny. - Funny.
@@ -1312,7 +1312,7 @@ For a tighter indie scope, the full project could be around **612 months part
- Keep the MVP small. - Keep the MVP small.
- Cut anything that is not core to “thrown geese.” - Cut anything that is not core to “thrown geese.”
## 2. First-Person + Tower Defense Confusion ## 2. Third-Person vs. Tower Defense Confusion
**Risk:** Players do not understand whether this is a shooter, platformer, or tower defense. **Risk:** Players do not understand whether this is a shooter, platformer, or tower defense.
**Solution:** **Solution:**
@@ -1397,7 +1397,7 @@ If you want a very concrete start, do this for two weeks.
- Create simple greybox arena. - Create simple greybox arena.
## Days 47: Player + Goose ## Days 47: Player + Goose
- Build first-person controller. - Build third-person player controller.
- Add mouse look. - Add mouse look.
- Add throw input. - Add throw input.
- Create goose projectile. - Create goose projectile.
+22
View File
@@ -0,0 +1,22 @@
# 🚀 YeetGeese - Phase 0 Design Summary
**Genre:** Third-Person Over-the-Shoulder Tower Defense
**Core Fantasy:** A lone defender in a farm arena, utilizing powerful projectile geese to defend their base from waves of approaching enemies. The goal is simple but satisfying: yeet and survive!
## 🦢 Core Loop
Enemies spawn → Player maneuvers & aims → **Yeets Goose** (Damage/Stun) → Currency collected (Feathers) → Player upgrades defenses/geese → Wave ends → Repeat with increased difficulty.
## 🎯 Minimum Viable Product (MVP) Scope
| Feature | Detail | Status |
| :--- | :--- | :--- |
| **Arena** | Single, open 3D farm arena. | Defined |
| **Player** | Third-person controller (WASD + Mouse Look). Basic Health System. | Defined |
| **Weapon** | One basic Goose projectile (medium damage, spinning, self-lifetime). | Defined |
| **Enemies** | Two types: **Pigs** (Slow/Tank) & **Chickens** (Fast/Skirmisher). | Defined |
| **Progression** | 5 Waves total. Basic economy (Feathers collected from kills). | Defined |
| **UI/Win/Loss** | Health bar, Feather Count, Wave Counter. Win: Survive 5 waves. Loss: Player HP $\le$ 0. | Defined |
## ⚙️ Technical Foundation
* **Engine:** Godot 4.x (3D, Forward+).
* **Architecture:** Utilize autoloads (`GameState`, `EventBus`, etc.) to manage state centrally and decouple systems.
* **Key Systems:** Input mapping (Movement, Aim, Throw), defined collision layers (Environment, Player, Enemy, Goose, Currency).
+134
View File
@@ -0,0 +1,134 @@
# YeetGeese - Design Document
## Game Concept
**YeetGeese** is an over-the-shoulder third-person tower defense game where the player defends a base by throwing geese as powerful projectiles. The core fantasy is absurdly simple but deeply satisfying: enemies approach your objective, and you yeet geese at them to stop them.
---
## Core Fantasy
> *"I am alone in a 3D farm arena, viewed from behind my shoulders. Farm animals march toward my base. I aim with mouse, throw with a click, and watch geese crash into foes with satisfying honks, spins, and impact. Each throw feels powerful and purposeful."*
- **Player**: A lone defender in over-the-shoulder third-person
- **Weapon**: Throwable geese that act as both projectiles and temporary turrets
- **Objective**: Protect the base from waves of approaching farm animals (Pigs, Chickens)
- **Juice**: Every goose hit produces satisfying feedback (honks, feathers, screen shake)
---
## Core Loop
```
[ENEMIES SPAWN] → [PLAYER MOVES & AIMS] → [YEET GEESE] →
[GEESE DAMAGE/DISTRACT ENEMIES] → [CURRENCY COLLECTED] →
[BUY UPGRADES/NEW GEESE] → [WAVE COMPLETE?] → [NEXT WAVE (HARDER)]
```
### Breakdown:
1. **Enemies spawn** at designated points and march toward the base
2. **Player moves** through the arena in third-person, positioning for optimal throws
3. **Player aims and yeets geese** using mouse look and click
4. **Geese impact enemies**, dealing damage or causing knockback/stun
5. **Currency drops** (feathers) from defeated enemies
6. **Player spends currency** on upgrades or new goose types
7. **Wave ends** when all enemies are eliminated
8. **Next wave begins**, with more/enemy variety/difficulty
---
## MVP Scope
### One Arena
- Simple, open arena with clear spawn and base zones
- Neutral terrain allowing free movement
### One Player Controller
- **Player Controller**: Over-the-shoulder third-person view (WASD + mouse look, throw input)
- **Basic health system**
### One Goose Type
- **Basic Goose**: Standard projectile goose
- Medium damage, standard speed
- Spins on throw
- Flees after impact or short lifetime
### Two Enemy Types
1. **Pig** (formerly Grunt) Slow, low health, standard damage (meat shield)
2. **Chicken** (formerly Runner) Fast, low health, reaches base quickly
### Five Waves
| Wave | Enemies | Description |
|------|-----------------------------------|---------------------------------|
| 1 | 3 Pigs | Tutorial wave |
| 2 | 5 Pigs | Slight increase |
| 3 | 4 Pigs + 2 Chickens | Introduction of speed |
| 4 | 6 Mixed (Pig/Chicken) | Mix of both types |
| 5 | Boss wave: Oinker Boss | Large, high-health farm animal |
### Basic Economy
- **Starting currency**: 100 feathers
- **Enemy drop**: 510 feathers per kill
- **Goose cost**: Free for first type
- **Upgrade/shop unlock**: Every 10 kills unlocks new goose slot
### Basic UI
- Top-left: Health bar, feather count
- Top-right: Wave number
- Pause menu (Escape)
- Game over / Victory screens
### Win/Lose Conditions
- **Win**: Survive all 5 waves
- **Lose**: Player health reaches 0
---
## Godot Setup Summary
### Project Type
- Godot 4.x, 3D project, Forward+ renderer
### Directory Structure
```
res://
├── scripts/ # GDScript files
├── scenes/ # .tscn files
├── assets/
│ ├── audio/
│ ├── meshes/
│ ├── textures/
│ ├── materials/
│ └── animations/
├── ui/ # HUD, menus
├── data/ # Wave/upgrade configs
├── autoload/ # GameState, EventBus, AudioManager
└── tests/
```
### Autoloads
- `GameState.gd` Wave state, currency, lives, pause
- `EventBus.gd` Central signals for gameplay events
- `AudioManager.gd` SFX and music playback
- `SettingsManager.gd` Settings persistence
### Collision Layers
| Layer | Type |
|-------|-------------------------|
| 1 | Environment |
| 2 | Player |
| 3 | Enemy |
| 4 | Goose projectile |
| 5 | Goose turret |
| 6 | Currency/pickups |
| 7 | UI / trigger zones |
---
## Exit Criteria for Phase 0
- [ ] Design document is complete (this one page)
- [ ] Godot project opens cleanly in 3D mode
- [ ] Folders and autoloads are created
- [ ] Input map is configured (WASD, mouse, throw, pause)
- [ ] MVP scope is documented and understood
---
*This document defines the foundation for a small but complete playable prototype. Phase 1 will build exactly this scope; additional content comes later.*
+14
View File
@@ -0,0 +1,14 @@
# AudioManager.gd
extends Node
var music_player # Reference to AudioStreamPlayer for background music
func _ready():
print("AudioManager loaded. Ready to play sounds.")
func play_sfx(sound_path: String):
# Logic to play a sound effect
pass
func play_music(stream: AudioStream):
# Logic to set and play background music
pass
+14
View File
@@ -0,0 +1,14 @@
# SettingsManager.gd
extends Node
const SETTINGS_PATH = "user://settings.save"
func save_setting(key: String, value):
print("Saving setting: " + key)
# Logic to serialize and save settings data
pass
func load_setting(key: String):
print("Loading setting: " + key)
# Logic to read saved setting data
return null
+7
View File
@@ -0,0 +1,7 @@
# EventBus.gd
extends Node
signal event_fired(event: String, data: Dictionary)
func emit_event(event: String, data: Dictionary = {}):
print("Emitting event: " + event)
emit_signal("event_fired", data)
+18
View File
@@ -0,0 +1,18 @@
# GameState.gd
extends Node
# --- COLLISION LAYERS (TASK 4) ---
const LAYER_ENVIRONMENT = 1 # Environment/terrain
const LAYER_PLAYER = 2 # Player character
const LAYER_ENEMY = 3 # Enemy mobs
const LAYER_GOOSE_PROJECTILE = 4 # Goose projectiles
const LAYER_TURRET = 5 # Fixed towers/turrets
const LAYER_PICKUP = 6 # Currency, power-ups
const LAYER_UI_TRIGGER = 7 # UI interaction zones
var score = 0
var currency = 100
var current_wave = 0
var game_state = "PAUSED" # States: PAUSED, RUNNING, WIN, LOSE
func _ready():
print("GameState loaded. Initializing core systems.")