Initial commit before folder reorganization

Checkpoint of the existing flat file layout prior to restructuring
into autoload/, menu/, ships/, world/, and assets/ folders.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 20:26:48 -04:00
commit e1410c234a
63 changed files with 3926 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
# Bots — Casual Mode Fill
## Rules
- Each casual match picks **2 of the 3 races** at random
- Bots fill empty slots until the match reaches **7v7** (14 total)
- Once 7v7 is reached, **no more bots are added** — additional human players replace bots as they join
- Bots are removed when real players join their team slot
## Why 7v7 Minimum
- Ensures the match feels active even at low population
- Avoids the ghost-town feeling of a 25v25 map with 3 players
- Bots are not added beyond 7v7 so human players always dominate strategy
## Implementation Notes (not yet built)
- Bots use simplified AI: thrust toward nearest enemy, shoot when in range
- Bot difficulty: intentionally easy (this is casual — bots are filler, not challenge)
- Bot names: procedurally generated callsigns so they're not obviously bots in the HUD
- Server tracks human vs bot count per team and manages swap-in on player join
+5
View File
@@ -0,0 +1,5 @@
# Dev Notes
- First Godot project — learning the engine while building
- GDScript is the primary language; UI is built programmatically in `_ready()` rather than in the editor scene tree
- Steam Deck is the primary target: fixed 1280×800, controller support required alongside keyboard/mouse
+45
View File
@@ -0,0 +1,45 @@
# Monetization
## The Problem
- Selling for **$5** reduces hacking/smurfing (small barrier to entry)
- But limits long-term revenue after launch
---
## Monetization Options
### Option A — Buy to Play + Cosmetics (Recommended)
- **$5 upfront** on Steam (barrier against hackers/smurfs)
- Free cosmetic battle pass each season (optional paid tier)
- Cosmetic shop: ship skins, thruster trails, kill effects, UI themes
- No pay-to-win — all gameplay items are free
### Option B — Free to Play + Cosmetics
- Lower barrier to entry = more players = better matchmaking
- Revenue comes 100% from cosmetic shop and battle pass
- Risk: harder to combat hackers/smurfs without a price barrier
- Mitigation: phone verification or Steam account age requirement
### Option C — Buy to Play + Expansions
- $5 base game
- Future paid DLC: new races, new map packs
- Risk: splits playerbase
---
## Recommendation
**Option A** is the safest starting point:
- $5 keeps bad actors out
- Cosmetics fund ongoing development
- No pay-to-win preserves competitive integrity
- Can always go F2P later if playerbase needs a boost
---
## Anti-Cheat / Anti-Smurf Notes
- $5 price is a soft deterrent, not a hard one
- Consider VAC (Steam's anti-cheat) integration via Godot Steam plugin
- Phone verification for ranked queue is another option (like Valorant)
+59
View File
@@ -0,0 +1,59 @@
# Multiplayer — Maps & Game Modes
## Maps
- **10 maps total** at launch
- Design philosophy: **CSGO-tight** — intentional lanes, clear sightlines, no wasted space
- Subspace Continuum's Trench Wars maps were too large and too open — avoid this
- All maps are 2D top-down space environments (asteroid fields, space stations, nebulae, etc.)
| Map Size | Used For |
|----------|----------|
| Small | Ranked 5v5 |
| Medium | Ranked 5v5 / Casual 25v25 |
| Large | Casual 25v25 only |
---
## Ranked Mode — 5v5
Competitive, skill-based, MMR/ELO ladder. Penalty for leaving mid-match. Smallmedium maps only.
### Ranked Mode Ideas
| Mode | Description |
|------|-------------|
| **Flagship Assault** | Each team has a Flagship (large ship). Destroy the enemy Flagship while defending yours. *(Recommended starting mode)* |
| **Control Point** | One central point on the map. Hold it longer than the enemy to win. First to X seconds wins. |
| **Deathmatch** | First team to X kills wins. Clean, simple, easy to understand. |
| **Relay Capture** | A neutral carrier drifts across the map. Escort it to the enemy base to score. |
> **Suggestion:** Start with **Flagship Assault** only. It's unique, has natural tension (offense and defense), and maps can be designed around it. Add modes later as seasons.
---
## Casual Mode — 25v25
No penalty for leaving. Larger maps. Chaotic and fun — you can drop in mid-match.
### Casual Mode Ideas
| Mode | Description |
|------|-------------|
| **Sector Control** | Map divided into sectors. Hold more sectors at time limit. Ties to galactic war meta. |
| **King of the Hill** | One contested zone in the center. Hold it to rack up points. |
| **Annihilation** | Pure kills. Last team standing or first to X kills. Chaos mode. |
| **Base Assault** | One team attacks a fortified base, one defends. Roles swap each round. |
| **Convoy Escort** | One team escorts a slow-moving freighter across the map, other team destroys it. |
> **Suggestion:** Start with **Sector Control** for casual. It ties into the galaxy meta (Helldivers-style), encourages teamwork without hard requirements, and naturally scales to 25v25.
---
## Galaxy Meta (Helldivers-Style)
- The galaxy is divided into **sectors**
- Casual 25v25 matches determine which race controls which sector
- Ranked 5v5 results also contribute to sector control
- A live galaxy map on the main screen shows the current war state
- This gives low-stakes players (casual) real impact on the ongoing war
+64
View File
@@ -0,0 +1,64 @@
# Space Game — Project Overview
## Concept
A 2D pixel-art top-down space shooter inspired by **Subspace Continuum**, built for **Steam Deck and PC**. Three alien races fight for control of a galaxy. Fast matchmaking like Rocket League — quick in, quick out.
## Core Loop
1. Launch → Main Menu
2. Enter callsign → click CASUAL
3. World loads → pick your race (2 of 3 randomly offered per match) → pick your ship
4. Fight in a 25v25 battle
5. Return to main menu
## Game Modes
| Mode | Size | Status |
|------|------|--------|
| Casual | 25v25 (bots fill to 7v7 minimum) | In progress |
| Ranked | 5v5, competitive MMR | Disabled — coming later |
## Current Game Flow (as built)
```
Main Menu
└─ CASUAL ──► World loads immediately (game active)
└─ TeamSelect overlay appears
├─ Pick race (2 random of 3 offered)
└─ Pick ship (4 available, sprites shown)
└─ Player spawns centred, invincible briefly
└─ ESC / Start ──► Pause menu overlay
├─ RESUME
├─ SETTINGS (stub)
├─ SELECT TEAM (stub)
├─ QUIT TO MENU
└─ QUIT TO DESKTOP
```
## Races
3 playable races chosen from a pool of 10 concepts — see `racesclasses.md`. Each race has 5 ship classes:
| Class | Role |
|-------|------|
| Interceptor | Fast, agile generalist |
| Bomber | Area damage, slow |
| Support | Heal/rally; allies can attach |
| Stealth | Assassin, hit-and-run |
| Heavy | Tank, massive firepower |
Races are visually distinct — critical for reading a 25v25 battlefield at a glance.
## Match Setup
- Each match randomly picks **2 of the 3 races** to field
- Player picks which of those 2 they fight for, then picks their ship
- Bot fill ensures a minimum of **7v7** in casual; no bots added beyond that
## Design Philosophy
- Maps inspired by CSGO — tight, intentional, not the sprawling Subspace Trench Wars layout
- 10 maps at launch (small for ranked, medium/large for casual)
- All art: pixel art
- Platform primary: Steam Deck (1280×800, controller-first)
+84
View File
@@ -0,0 +1,84 @@
# Races & Ship Classes
## Chosen Races: 1, 4, 5
From the 10 concepts below, races **1 (Terran Republic)**, **4 (Mechanos Sovereignty)**, and **5 (Void Wraiths)** were selected.
> **Current in-game status:** The team selection screen uses temporary placeholder names ("Terran Federation", "The Collective", "Iron Order") with placeholder sprites until proper art and lore are integrated for the 3 chosen races.
---
## The 3 Chosen Races
### Race 1 — Terran Republic ✅ Chosen
**Weapon type:** Projectile / Ballistic
**Visual:** Angular gray-blue military ships, recognizable fighter jet silhouettes, clean livery
**Feel:** Standard military. Balanced and familiar. Easiest to learn.
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Falcon** | Interceptor | Fast all-rounder. Standard guns, high agility. Best 1v1 duelist. |
| 2 | **Devastator** | Bomber | Launches grenades + missiles with large splash radius. Slow, massive damage. |
| 3 | **Sentinel** | Support | Deploys repair drones + turrets. Allies can attach. Mobile spawn point. |
| 4 | **Ranger** | Stealth | Cloaks, fires a single high-damage sniper shot, recloaks. |
| 5 | **Juggernaut** | Heavy | Armored fortress. Drops proximity mines, fires suppression bursts. Near-unkillable solo. |
---
### Race 4 — Mechanos Sovereignty ✅ Chosen
**Weapon type:** Railgun / Drone / EMP
**Visual:** Perfectly geometric chrome-and-gold ships. No organic curves. Modular, interchangeable parts. Clearly machine-made.
**Feel:** Pure precision AI. Railgun sniping, drone swarms, and tactical disruption.
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Warframe** | Interceptor | Fires precise railgun bursts. Fast. Rewards aim skill. |
| 2 | **Fabricator** | Bomber | Deploys explosive drone clusters — set-and-forget area denial. |
| 3 | **Core Hub** | Support | Broadcasts repair nanobots to nearby allies. Creates mobile spawn beacon. |
| 4 | **Phantom Unit** | Stealth | Hacks enemy targeting — turns off their HUD radar briefly. Hard to detect. |
| 5 | **Siege Engine** | Heavy | Locks into stationary mode for massive railgun barrage. Vulnerable while moving. |
---
### Race 5 — Void Wraiths ✅ Chosen
**Weapon type:** Dark Energy / Gravity / Phase
**Visual:** Inky black ships with white particle trails. Look like holes in space. Shifting, unstable edges. Eerie.
**Feel:** Terrifying and unpredictable. Gravity wells, phase attacks, hard to pin down.
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Shade** | Interceptor | Partially phases — hard to hit. Fires void energy bolts. |
| 2 | **Rift Caster** | Bomber | Opens gravity rifts that pull nearby enemies toward the center then collapse. |
| 3 | **Nexus Wraith** | Support | Creates phase portals allies can teleport through. Ally rally point. |
| 4 | **Specter** | Stealth | Fully phased and invisible. Only visible for 0.3s when firing. |
| 5 | **Void Titan** | Heavy | Absorbs incoming damage, then releases it all in a single omni-directional burst. |
---
## All 10 Race Concepts (Reference)
<details>
<summary>Click to expand all 10 races</summary>
### Race 2 — Xel'Nara Collective
**Weapon type:** Laser / Crystal Energy | **Feel:** Alien elegance, glass cannon
### Race 3 — Vorg Swarm
**Weapon type:** Bio / Organic (acid, spores) | **Feel:** Zergs in space, DOT chaos
### Race 6 — Solari Imperium
**Weapon type:** Plasma / Solar Fire | **Feel:** Ancient empire, slow and devastating
### Race 7 — Kryx Hivemind
**Weapon type:** Swarm Missiles / Acid | **Feel:** Insectoid swarm, volume of fire
### Race 8 — Nebulon Drifters
**Weapon type:** Gas Clouds / Toxin | **Feel:** Environmental control, zone denial
### Race 9 — Iron Covenant
**Weapon type:** EMP / Railgun / Hacking | **Feel:** Disruptor faction, breaks enemy systems
### Race 10 — Eldari Ascendancy
**Weapon type:** Psionic / Reality Distortion | **Feel:** Psychic manipulation, bullets that curve
</details>
+91
View File
@@ -0,0 +1,91 @@
# Project Structure
## File Tree
```
spacewar/ ← repo root
└── spacewar/ ← Godot project root (open this in Godot editor)
├── project.godot
├── game_config.gd ← autoload singleton (tuning values, player state, signals)
├── main_menu.tscn/gd ← entry point / main scene
├── server_browser.tscn/gd ← server browser UI (built, not in active flow yet)
├── world.tscn ← game world
├── node_2d.tscn ← player ship scene
├── ship_movement.gd ← player ship logic
├── bullet.tscn/gd ← projectile
├── pause_menu.tscn/gd ← in-game pause overlay (ESC / Start button)
├── team_select.tscn/gd ← race + ship selection overlay (shown on world load)
├── asteroid_movement.gd ← stub
└── images/
├── background/skybox/ ← 6 space background PNGs (1.png 6.png)
└── ships/Example_ships/ ← 4 placeholder ship sprites (1.png, 1B.png, 2a.png, 3b.png)
```
## Scene Graph
### `main_menu.tscn` — entry point
```
MainMenu (Control) ← main_menu.gd builds all UI in _ready()
```
### `world.tscn` — game world
```
World (Node2D)
├── TextureRect ← static space background (skybox/1.png)
├── Player ← instance of node_2d.tscn
├── HUD (CanvasLayer)
│ └── HealthLabel
├── PauseMenu (CanvasLayer, layer=10) ← pause_menu.tscn
└── TeamSelect (CanvasLayer, layer=20) ← team_select.tscn; queue_free()s after selection
```
### `node_2d.tscn` — player ship
```
Player (CharacterBody2D) ← ship_movement.gd
├── CollisionShape2D ← CircleShape2D
├── Sprite2D ← texture set at runtime from GameConfig.player_ship_path
└── VisibleOnScreenNotifier2D
```
## Input Map
| Action | Key | Controller |
|--------|-----|------------|
| `move_up` | W | — |
| `move_left` | A | — |
| `move_right` | D | — |
| `move_down` | S | — |
| `shoot` | Space | — |
| `toggle_pause` | Esc | Start / Options button (JoyButton 6) |
## Game Flow
```
main_menu.tscn
├── CASUAL → world.tscn
│ ├── TeamSelect overlay: pick race (2 random of 3 offered)
│ ├── TeamSelect overlay: pick ship
│ └── Player spawns → game live
└── RANKED → disabled (coming soon)
```
> **Note:** `server_browser.tscn` was built (Task 1) and is functional, but the current flow bypasses it — CASUAL goes directly to the world and TeamSelect handles name/race/ship. The server browser will be re-integrated when real multiplayer server listing is built.
## Key Autoload — `GameConfig`
| Property | Type | Set by |
|----------|------|--------|
| `player_name` | String | Main menu callsign input |
| `player_race` | int | TeamSelect race pick |
| `player_ship_path` | String | TeamSelect ship pick |
| `team_selected` | signal | Emitted by TeamSelect when done |
| `ship_thrust` | float | Tuning constant |
| `ship_max_speed` | float | Tuning constant |
| `ship_rotation_speed` | float | Tuning constant |
| `ship_fire_rate` | float | Tuning constant |
| `bullet_speed` | float | Tuning constant |
| `ship_max_health` | int | Tuning constant |
| `ship_respawn_delay` | float | Tuning constant |
| `ship_invincibility_time` | float | Tuning constant |
| `bullet_damage` | int | Tuning constant |
| `ship_wall_damage` | int | Tuning constant |
+29
View File
@@ -0,0 +1,29 @@
# Task Log
## Completed
| # | Task | Notes |
|---|------|-------|
| 0 | Format all design docs as Markdown | Done |
| 1 | Design 10 races, pick 3 | Races 1, 4, 5 chosen — see `racesclasses.md` |
| 2 | Ranked + casual mode ideas | See `multiplayer.md` |
| 3 | Multiplayer engineering doc | See `tech.md` |
| 4 | Server browser screen | Player name, race buttons, server list, JOIN — stores in `GameConfig` |
| 5 | Main menu | CASUAL / RANKED (disabled), callsign input, rank badge, quit button |
| 6 | In-game pause menu | ESC / controller Start; game runs behind it; working: RESUME, QUIT TO MENU, QUIT TO DESKTOP |
| 7 | Team & ship selection | On world load; 2 random races offered; ship grid with real sprites; player spawns after |
## Up Next
| # | Task | Priority |
|---|------|----------|
| 8 | Replace placeholder races with chosen 3 (Terran Republic, Mechanos Sovereignty, Void Wraiths) | High |
| 9 | Real ship sprites for all 3 races (5 ships each) | High |
| 10 | Asteroids + environment hazards | Medium |
| 11 | Bot fill for casual (min 7v7) | Medium — see `bots.md` |
| 12 | Sound effects (thrust, shoot, explosion, UI clicks) | Medium |
| 13 | Multiplayer networking — ENet authoritative server | High (big) |
| 14 | Galaxy war meta + sector control | Low (post-networking) |
| 15 | Ranked matchmaking + MMR | Low (post-networking) |
| 16 | Settings screen (audio, controls, display) | Low |
| 17 | Select Team in pause menu (live team swap) | Low |
+89
View File
@@ -0,0 +1,89 @@
# Tech Stack
## Engine & Language
- **Engine:** Godot 4.7 (Forward Plus renderer)
- **Language:** GDScript
- **Project path:** `/mnt/code/spacewar/spacewar/` (inner folder is the Godot project root)
- **Platform target:** Linux (Steam Deck native, 1280×800), Windows PC
- **Art style:** Pixel art (placeholder sprites in use currently)
See `structure.md` for the full file tree and scene graph.
---
## Multiplayer Architecture (Planned)
```
[Client] ──── [Matchmaking Server] ──── [Dedicated Game Server]
[Backend API]
(queue, ranks, accounts)
```
### Authoritative Server Model
- Dedicated game servers run the authoritative simulation (not player-hosted)
- Clients send **inputs** (movement, fire, ability) — server validates and broadcasts results
- No client-side cheating possible on critical state (position, HP, kills)
- Player position simulated server-side; clients predict locally and reconcile
### Godot Networking Layer
```gdscript
# Server: move a player
@rpc("authority", "call_local", "reliable")
func set_position(new_pos: Vector2) -> void:
position = new_pos
# Client: send input to server
@rpc("any_peer", "call_remote", "unreliable")
func send_input(dir: Vector2, firing: bool) -> void:
pass
```
- **Transport:** ENet (UDP, built into Godot) for low-latency game data
- **Reliable channel:** critical state (HP, death, respawn)
- **Unreliable channel:** high-frequency position/velocity updates
### Client-Side Prediction & Lag Compensation
1. Client predicts own movement locally (feels instant)
2. Server confirms or corrects (reconciliation)
3. Other players interpolated between last two known positions
4. Lag compensation: server rewinds state slightly to validate hitscan shots
### Matchmaking Backend
| Component | Tech |
|-----------|------|
| API Server | Go or Node.js |
| Queue / State | Redis |
| Database (accounts, ranks) | PostgreSQL |
| Hosting | VPS (Hetzner / DigitalOcean) or self-hosted |
**Flow:**
1. Client sends "find match" with MMR + mode
2. Backend queues player, finds lobby within MMR range
3. Lobby full → backend assigns a game server
4. Backend sends client the server IP + session token
5. Client connects directly to game server
### Steam Integration
- **GodotSteam** plugin (open source, wraps Steamworks SDK)
- Handles: Steam auth, VAC anti-cheat, Steam lobbies, achievements
- No separate account system needed at launch
---
## Networking Checklist
- [ ] Godot ENet server/client setup
- [ ] Player input RPC structure
- [ ] Position sync with interpolation
- [ ] Ship class registration per peer
- [ ] Server-authoritative health/death
- [ ] Matchmaking API (queue + lobby assignment)
- [ ] GodotSteam auth + VAC
- [ ] Lag compensation (basic rewind)