# 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 |