Add real server pool, race roster overhaul, and ship energy system

Server browsing & matchmaking:
- HL2-style main menu (QUICK PLAY/SERVER SELECT/OPTIONS/PROFILE/QUIT)
  replaces the old CASUAL/RANKED tiles; RANKED removed end-to-end
  (menu, matchmaking-api's Mode.ranked queue path, MMR matching) until
  ranked is real.
- New menu/server_select.gd lists real servers from the matchmaking
  API's GET /servers and connects directly, retiring the old
  unreachable menu/server_browser.gd.
- Real game-server pool: NetworkManager.host_server() self-registers on
  boot and heartbeats every 8s with live player counts; API computes
  available/full status from player_count, and a background sweep marks
  any server offline once its heartbeat goes stale (catches a crashed
  server that never deregistered).
- Server-select rows get a live UDP ping probe (query port = game port
  + 10000) instead of trusting stale DB numbers; post-connect HUD shows
  live RTT off ENet's own peer stats.

Race roster overhaul:
- Swapped Terran/Mechanos/Vorg for the pivoted roster — Apex Dynamics,
  Inner Sphere Navy, Outer Rim Collective — each with a 3-ship
  Fighter/Gunner/Tank lineup, art cropped from concept sheets with
  background removal + orientation fixes per sheet.
- Live headcount + roster + "TEAM FULL" lock on the race-select screen,
  shared between the initial pre-spawn pick and the pause menu's live
  SELECT TEAM swap.
- Bot personalities (bots/bot_personality.gd): aggression/caution/
  accuracy/reaction/awareness traits rolled per bot instead of one
  fixed AI profile.

HUD additions:
- Player list (roster, teammates white/enemies yellow, bots flagged),
  kill feed, minimap, and explosion VFX on death.
- Health and energy now render as bars (hud/stat_bar.gd) instead of
  text in the top-left HUD.

Ship energy system:
- Per-role max energy (Fighter 100 / Gunner 150 / Tank 250), 75 energy
  per shot, flat regen (100 per 2.5s), fully server-authoritative and
  piggybacked on the existing per-tick state broadcast alongside health.
- New blue "mirrored" bar top-middle of the screen (hud/energy_bar.gd)
  whose fill drains from both edges toward the center instead of
  left-to-right.

Ship handling tuning:
- Turn rate reduced (4.0 -> 1.0 rad/s) so a quick tap no longer
  over-rotates; holding past 0.15s ramps to double speed (2.0 rad/s) for
  fast full turns, gated the same way damage already is so replay during
  reconciliation can't double-count the hold timer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 17:56:33 -04:00
parent c0b5f421c5
commit 7b44b2f2dc
112 changed files with 3349 additions and 872 deletions
+107 -60
View File
@@ -1,84 +1,131 @@
# Races & Ship Classes
## Chosen Races: 1, 4, 3
## Setting
From the 10 concepts below, races **1 (Terran Republic)**, **4 (Mechanos Sovereignty)**, and **3 (Vorg Swarm)** were selected.
Three factions fight inside the massive shielding, pipes, and superstructure of
refineries, shipyards, and mining stations — not open void. Grounded, blue-collar
sci-fi in the vein of *The Expanse* (corporate hegemony vs. disciplined inner-planet
military vs. gritty outer-belt miners), but built as a fast, arcade 2D tactical
arena shooter rather than a hard-sci-fi sim. Tight factory corridors and choke
points are the map language — see `multiplayer.md`.
> **Current in-game status:** Team selection now uses the real race names and real ship art for all 3 chosen races (`assets/images/ships/<race>/`). Each race has its own 5-ship roster — Interceptor, Gunship, Bomber, Support, Heavy — matching the tables below. See `team_select.gd`.
> **Status:** This replaces the previous 10-alien-race concept pool and the
> Terran Republic / Mechanos Sovereignty / Vorg Swarm roster. Doc-only for now —
> game code (`team_select.gd` RACES data, `GameConfig`, existing
> `assets/images/ships/<race>/` art) still reflects the old races until that work
> is scheduled.
---
## The 3 Chosen Races
## The 3 Factions
### 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.
### Apex Dynamics — The Corporate Syndicate
**Weapon type:** High-tech energy (coherent light / plasma)
**Visual:** Sleek, pearlescent-white hulls with razor-sharp geometric lines and
glowing neon-blue engine trails — looks more like a high-end luxury smartphone
than a military weapon.
**Feel:** High-tech and precise. Wins by not being seen until it's too late.
**Tactical ability:** **Active Camouflage** — see [Faction Abilities](#faction-abilities-universal-system)
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Warframe** | Interceptor | Very fast, rapid weak laser bursts. Built to close distance instantly and chip away at anything in range. |
| 2 | **Striker** | Gunship | Super fast fire rate, very low damage lasers. Trades hitting power for volume of fire. |
| 3 | **Deployer** | Bomber | Fast lasers plus an EMP mine dropped in your wake. Strong for area denial and covering a retreat. |
| 4 | **Link Node** | Support | Lasers plus a small repair pack dropped for allies to pick up. Keeps a team topped off in prolonged fights. |
| 5 | **Bastion** | Heavy | Tankier and slower, but its laser hits harder than anything else in the fleet. Anchors a push. |
### Inner Sphere Navy (ISN) — The Military
**Weapon type:** Standard-issue ballistics / ordnance
**Visual:** Gunmetal-gray, wedge-shaped hulls with hard militaristic angles, dense
protective plating, and prominent forward-facing gun turrets.
**Feel:** Disciplined, heavy, frontal. Wins by tanking a choke point and forcing
the fight.
**Tactical ability:** **Overcharged Aegis** — see [Faction Abilities](#faction-abilities-universal-system)
### Outer Rim Collective (ORC) — The Belters
**Weapon type:** Kinetic / repurposed mining hardware
**Visual:** Blocky, gritty patchwork of mismatched metal plating and exposed
hydraulic wiring, dominated by external fuel tanks and heavy industrial hardware
bolted onto the hull.
**Feel:** Scrappy and improvised. Wins by controlling terrain and denying space.
**Tactical ability:** **Proximity Scrap-Mine** — see [Faction Abilities](#faction-abilities-universal-system)
---
### Race 4 — Mechanos Sovereignty ✅ Chosen
**Weapon type:** Cannon / Missile
**Visual:** Heavy industrial war machines, chrome-and-gunmetal plating, red accent lighting. Modular, interchangeable parts. Clearly machine-made.
**Feel:** Brute-force industrial muscle. Durable, hard-hitting, built to grind a fight down rather than outmaneuver it.
## Ship Classes
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Sentinel** | Interceptor | A light scout mech with twin rapid cannons. Fast and maneuverable for a Mechanos hull. |
| 2 | **Vanguard** | Gunship | Dual autocannons built for sustained fire. Durable enough to hold a line, fast enough to reposition. |
| 3 | **Ravager** | Bomber | Drops heavy ordnance and mines from its cargo pods. Best used to seal off a chokepoint. |
| 4 | **Aegis** | Support | Projects a short-range shield and deploys a repair drone for nearby allies. |
| 5 | **Colossus** | Heavy | A walking fortress bristling with cannons. Slow and telegraphed, but absorbs enormous damage. |
Every faction fields the same 3-ship structure, re-skinned to its own theme:
| Class | Role |
|-------|------|
| **Fighter** | Single, high-precision, high-damage shot |
| **Gunner** | Rapid-fire spray/burst, more shots for less damage each |
| **Tank** | Bigger and slower; fires both bullets and missiles |
### Apex Dynamics
| Ship | Class | Weapon |
|------|-------|--------|
| **Lancet** | Fighter | A single, high-precision bolt of blue coherent light |
| **Pulsar** | Gunner | A wide, rapid-fire fan of low-damage green plasma pulses |
| **Sovereign** | Tank | Homing micro-missiles alongside dual heavy plasma batteries |
### Inner Sphere Navy (ISN)
| Ship | Class | Weapon |
|------|-------|--------|
| **Patriot** | Fighter | A single, hard-hitting high-caliber explosive shell |
| **Barrage** | Gunner | A relentless quad-barrel spray of fast, low-damage light bullets |
| **Behemoth** | Tank | Heavy tracking torpedoes plus massive physical deck-guns |
### Outer Rim Collective (ORC)
| Ship | Class | Weapon |
|------|-------|--------|
| **Rail-Jack** | Fighter | A single, heavy magnetic railgun slug |
| **Scrap-Spitter** | Gunner | A rotary scrap-cannon spraying rapid, low-damage metal shrapnel |
| **Iron-Clad** | Tank | Unguided explosive rockets plus continuous vulcan machine-gun fire |
---
### Race 3 — Vorg Swarm ✅ Chosen
**Weapon type:** Bio / Acid (DoT)
**Visual:** Organic insectoid creatures rather than built ships — chitin, wings, bioluminescent glow. No two look mechanically alike.
**Feel:** Chaotic organic swarm. Corrosive damage-over-time chips away at anyone who lingers nearby.
## Faction Abilities (Universal System)
| # | Ship | Role | Description |
|---|------|------|-------------|
| 1 | **Stinger** | Interceptor | Fast, acid shots with light damage-over-time. Swarms a target from range. |
| 2 | **Spitter** | Gunship | Faster-firing acid with a stronger damage-over-time effect. Sustained corrosive pressure. |
| 3 | **Broodling** | Bomber | Normal acid shots that also spawn a small slowing swarm cloud. Locks down a retreat or chokepoint. |
| 4 | **Nurse** | Support | Acid shots plus a small health/regeneration pack dropped for allies. |
| 5 | **Behemoth** | Heavy | Tankier and slower, with heavy acid shots that carry a large damage-over-time effect. The swarm's apex predator. |
Each faction has exactly one tactical ability. Every ship in that faction gets
it — what changes per class is scale, not kind, so the ability reads instantly
off a ship's faction regardless of which of the 3 hulls it's flying. Same energy
cost and cooldown across factions; duration/impact scales with the hull:
---
| Class | Scaling rule |
|-------|--------------|
| Fighter | Fast cooldown, short/light effect |
| Gunner | Baseline cooldown and effect |
| Tank | Long cooldown, largest/heaviest effect |
## All 10 Race Concepts (Reference)
### Apex Dynamics — Active Camouflage
Ship turns 90% transparent and disappears from radar. Firing or taking damage
breaks it instantly. Fighter gets a quick, short slip; Tank's lasts longest but
is riskiest to commit a slow hull to.
**Use:** Slip past a defender in a narrow pipe, flank, or break a missile lock.
<details>
<summary>Click to expand all 10 races</summary>
### Inner Sphere Navy — Overcharged Aegis
A frontal hard-light barrier absorbs 100% of incoming damage from the front for
a few seconds. Sides and rear stay exposed, turn rate drops, and the ship can't
fire while it's up. Tank's barrier is wide enough to shield teammates trailing
behind it; Fighter's is a narrow, quick poke.
**Use:** Push straight through a defended choke point, soaking fire so teammates
can follow.
### Race 2 — Xel'Nara Collective
**Weapon type:** Laser / Crystal Energy | **Feel:** Alien elegance, glass cannon
### Outer Rim Collective — Proximity Scrap-Mine
Ejects a magnetized mine that arms after ~1 second and goes dark on radar.
Detonates on enemy proximity for heavy damage in a small radius plus knockback;
alert enemies can shoot it from a distance to trigger it safely. Only one mine
per ship at a time — dropping a second detonates the first. Tank's mine has a
larger blast radius; Fighter's arms faster but hits smaller.
**Use:** Cover a retreat down a corridor, or seed a choke point/objective before
a push.
### Race 5 — Void Wraiths
**Weapon type:** Dark Energy / Gravity / Phase | **Feel:** Terrifying and unpredictable, gravity wells and phase attacks, hard to pin down
### The Rock-Paper-Scissors Loop
### Race 6 — Solari Imperium
**Weapon type:** Plasma / Solar Fire | **Feel:** Ancient empire, slow and devastating
- **ORC mines counter Apex cloak** — a cloaked ship blundering through a mined
corridor eats the blast, which also breaks the cloak.
- **ISN shield counters ORC mines** — the frontal barrier absorbs a mine
detonation, clearing the path for the team behind it.
- **Apex cloak counters ISN shield** — a slow, frontal-shielded push leaves the
ISN ship's flank and engines open for a cloaked ship to slip around and
punish.
### 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>
No ability wins a fight by itself — it depends on the map and the moment it's
used, same as a smoke/flash/molotov in CS:GO.
+17 -6
View File
@@ -9,8 +9,8 @@ spacewar/ ← repo root
├── autoload/
│ └── game_config.gd ← autoload singleton (tuning values, player state, signals)
├── menu/
│ ├── main_menu.tscn/gd ← entry point / main scene
│ ├── server_browser.tscn/gd ← server browser UI (built, not in active flow yet)
│ ├── main_menu.tscn/gd ← entry point / main scene; HL2-style vertical nav
│ ├── server_select.tscn/gd ← server list UI, backed by matchmaking-api's GET /servers
│ ├── pause_menu.tscn/gd ← in-game pause overlay (ESC / Start button)
│ └── team_select.tscn/gd ← race + ship selection overlay (shown on world load)
├── ships/
@@ -19,6 +19,8 @@ spacewar/ ← repo root
│ └── bullet.tscn/gd ← projectile
├── chat/
│ └── chat_box.tscn/gd ← WoW-style chat overlay (T=all, Y=team), added to world.tscn
├── hud/
│ └── player_list.tscn/gd ← top-left player roster (white=team, yellow=enemy, "(b)"=bot), added to world.tscn
├── bots/
│ ├── bot_manager.gd ← autoload; server-only bot fill (join/leave reconciliation)
│ ├── bot_ai.gd ← class_name BotAI; seek-nearest-enemy-and-shoot brain
@@ -47,6 +49,11 @@ spacewar/ ← repo root
MainMenu (Control) ← main_menu.gd builds all UI in _ready()
```
### `menu/server_select.tscn` — server list
```
ServerSelect (Control) ← server_select.gd builds all UI in _ready(), fetches GET /servers
```
### `world/world.tscn` — game world
```
World (Node2D) ← world.gd instances MAP_SCENE into MapContainer on _ready()
@@ -56,7 +63,8 @@ World (Node2D) ← world.gd instances MAP_SCENE into MapContainer o
│ └── HealthLabel
├── PauseMenu (CanvasLayer, layer=10) ← menu/pause_menu.tscn
├── TeamSelect (CanvasLayer, layer=20) ← menu/team_select.tscn; queue_free()s after selection
── ChatBox (CanvasLayer, layer=5) ← chat/chat_box.tscn
── ChatBox (CanvasLayer, layer=5) ← chat/chat_box.tscn
└── PlayerList (CanvasLayer, layer=4) ← hud/player_list.tscn
```
### `world/maps/map_01.tscn` — hand-painted map
@@ -95,14 +103,17 @@ Player (CharacterBody2D) ← ship_movement.gd
```
main_menu.tscn
├── CASUAL → world.tscn
├── QUICK PLAY → matchmaking queue (casual) → world.tscn
│ ├── TeamSelect overlay: pick race (2 random of 3 offered)
│ ├── TeamSelect overlay: pick ship
│ └── Player spawns → game live
── RANKED → disabled (coming soon)
── SERVER SELECT → server_select.tscn → pick a server → world.tscn (same TeamSelect flow)
├── OPTIONS → stub, coming soon
├── PROFILE → callsign-edit overlay (also auto-opens from QUICK PLAY if no callsign is set)
└── QUIT
```
> **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. It still uses the old hardcoded-1280px layout style (see Display below) — not yet updated since it isn't reachable in the live flow.
Ranked matchmaking is removed from the menu entirely (not just disabled) until it's real — see `CLAUDE.md` Current Tasks.
## Display
+12 -3
View File
@@ -1,15 +1,20 @@
# Task Log
Task 1
I want to build an energy system for each ship. Below the health put an energy of 100/100 for the fighter/ 150/150 for middle ship and big ship 250 energy. Each bullet takes 75 to shoot. Have a blue energy bar that is mirrord top middle appear at the top . Have it take 2.5 seconds to refill 100
## Completed
| # | Task | Notes |
|---|------|-------|
| 0 | Format all design docs as Markdown | Done |
| 24 | Energy system (Fighter 100 / Gunner 150 / Tank 250, 75 per shot, blue center-out mirrored bar top-middle, +100 per 2.5s regen) | `GameConfig.ship_max_energy_by_role`/`bullet_energy_cost`/`ship_energy_regen_rate`; server-authoritative in `ships/ship_movement.gd` (broadcast via `_receive_state`, same pattern as health); role threaded through `PlayerRegistry` loadout + bots; text readout `HUD/EnergyLabel` below HP, visual bar `hud/energy_bar.gd`/`.tscn` |
| 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 |
| 4 | ~~Server browser screen~~ | Superseded by #21's `menu/server_select.gd` |
| 5 | ~~Main menu (CASUAL/RANKED tiles)~~ | Superseded by #21's HL2-style nav menu |
| 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 |
| 8 | Replace placeholder races with chosen 3 (Terran Republic, Mechanos Sovereignty, Vorg Swarm) | Done |
@@ -17,6 +22,9 @@
| 13 | Multiplayer networking — ENet authoritative server | Done |
| 18 | In-game chat (T=all, Y=team, last 10 messages, bottom-left) | `chat/chat_box.gd` + `autoload/chat_manager.gd` — see `chat.md` |
| 11 | Bot fill for casual (min 7v7) | `bots/bot_manager.gd` + `bots/bot_ai.gd` — see `bots.md` |
| 17 | Select Team in pause menu (live team swap) | Reopens `TeamSelect` mid-match via `PlayerRegistry.submit_local_loadout`'s existing respawn path; bot fill rebalances the vacated race too (`PlayerRegistry.race_changed`) |
| 20 | Live headcount/roster + TEAM FULL lock on race select | Shared by the initial pick and #17's reopen; humans only (bots excluded), blocks joining a race >2 humans ahead of the other, exempts your own current race |
| 21 | HL2-style main menu + real server select | `main_menu.gd` rebuilt as plain white vertical nav (QUICK PLAY/SERVER SELECT/OPTIONS/PROFILE/QUIT); RANKED removed entirely; new `menu/server_select.gd` lists real servers via `MatchmakingClient.list_servers()` (`GET /servers`) and connects directly, retiring `menu/server_browser.gd` |
## Up Next
@@ -27,4 +35,5 @@
| 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 |
| 22 | Options screen (currently a disabled stub on the main menu) | Low |
| 23 | Real rank/level backend for the main menu's top-right badge | Low |
+1 -1
View File
@@ -95,6 +95,6 @@ but nothing calls it yet.
- [x] Position sync with interpolation
- [x] Ship class registration per peer
- [x] Server-authoritative health/death
- [x] Matchmaking API (queue + lobby assignment) — client wired end-to-end; real server pool and ranked MMR-window widening still open, see Current Tasks in `CLAUDE.md`
- [x] Matchmaking API (queue + lobby assignment) — client wired end-to-end for casual; ranked mode implementation removed until it's real (see `CLAUDE.md`); real server pool still open, see Current Tasks in `CLAUDE.md`
- [ ] GodotSteam auth + VAC
- [ ] Lag compensation (basic rewind)