Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
058aa3796a | ||
|
|
0f22125007 |
@@ -17,4 +17,3 @@ osu!/
|
|||||||
.env
|
.env
|
||||||
.env.gitea
|
.env.gitea
|
||||||
|
|
||||||
*.uid
|
|
||||||
+1
-15
@@ -22,18 +22,4 @@ 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
@@ -1,4 +1,4 @@
|
|||||||
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**. I’m 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**, a first-person tower defense game where the main weapon is thrown geese, built in **Godot 4**. I’m 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**, an over-the-shoulder third-per
|
|||||||
---
|
---
|
||||||
|
|
||||||
# Phase 1: Core Playable Prototype
|
# Phase 1: Core Playable Prototype
|
||||||
**Goal:** Prove that throwing geese at enemies in an over-the-shoulder third-person tower defense arena is fun.
|
**Goal:** Prove that throwing geese at enemies in a first-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. Third-Person Player Controller
|
### 1. First-Person Player Controller
|
||||||
Create an over-the-shoulder third-person player controller using Godot’s `CharacterBody3D`.
|
Create a first-person controller using Godot’s `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: third-person action + tower defense strategy.
|
This phase is where YeetGeese becomes its own genre hybrid: first-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 third-person.
|
- Feels first-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 third-person 3D indie game, aim for:
|
For a first-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.
|
||||||
- Third-Person.
|
- First-Person.
|
||||||
- Action.
|
- Action.
|
||||||
- Strategy.
|
- Strategy.
|
||||||
- Funny.
|
- Funny.
|
||||||
@@ -1312,7 +1312,7 @@ For a tighter indie scope, the full project could be around **6–12 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. Third-Person vs. Tower Defense Confusion
|
## 2. First-Person + 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 4–7: Player + Goose
|
## Days 4–7: Player + Goose
|
||||||
- Build third-person player controller.
|
- Build first-person controller.
|
||||||
- Add mouse look.
|
- Add mouse look.
|
||||||
- Add throw input.
|
- Add throw input.
|
||||||
- Create goose projectile.
|
- Create goose projectile.
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
# 🚀 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).
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
# 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**: 5–10 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.*
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# 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.")
|
|
||||||
Reference in New Issue
Block a user