# Starfleet Clash

Real-time multiplayer browser game: command a small fleet of ships in top-down 2D space combat.
Authoritative Node.js + `ws` server, vanilla HTML5 canvas + ES modules client (no build step).

See [SEED.md](SEED.md) for the full design brief, architecture, ship classes, and milestones.

## Quick Start

```bash
npm install
node server/server.js
```

Then open `client/src/index.html` in two browser tabs. Each tab joins as a separate player — press **WASD** to move your ship.

## Ship Classes

Starfleet Clash features **5 ship classes**, each with distinct stats and weapons that create a rock-paper-scissors combat dynamic. Fleet composition is a strategic choice: mix classes to counter the enemy's lineup.

### Class Overview

| Class | HP | Speed | Weapon | Range | Role |
|-------|----|-------|--------|-------|------|
| **Corvette** | 80 | 7 | Light Cannons | 180 | Nimble rapid-fire gunship |
| **Frigate** | 100 | 6 | Railguns | 220 | Balanced medium fighter |
| **Destroyer** | 120 | 5 | Torpedoes | 280 | Slow heavy artillery |
| **Carrier** | 90 | 5.5 | Missiles | 250 | Light self-defense, launches fighters |
| **Support** | 70 | 6.5 | Repair Beam | 150 | Healer, repairs friendlies |

### Rock-Paper-Scissors Cycle

```
  Corvette > Frigate > Carrier > Destroyer > Support > Corvette
```

Each class has one clear advantage (beats one class) and one disadvantage (is beaten by one class):

- **Corvette** beats **Frigate** — fast fire rate (5 ticks) + high tracking (0.8) outguns the frigate
- **Frigate** beats **Carrier** — railguns deal 12 damage at range 220, poking the carrier
- **Carrier** beats **Destroyer** — missiles (range 250) outrange the destroyer's tracking
- **Destroyer** beats **Support** — heavy torpedoes (18 damage) overwhelm the light support
- **Support** beats **Corvette** — repair beam (range 150) heals through the corvette's rapid fire

### Server API

Ship classes are defined in `server/entities.js`:

- **`SHIP_CLASSES`** — object mapping class IDs to class definitions (hp, speed, turn, weapon stats, RPS beats)
- **`getShipClass(classId)`** — returns the class definition for a given ID
- **`getRPSAdvantage(classId)`** — returns the class ID this class beats
- **`getRPSDisadvantage(classId)`** — returns the class ID that beats this class
- **`isRPSAdvantage(attackerClassId, defenderClassId)`** — returns true if attacker has RPS edge
- **`createShipByClass(classId, shipId, x, y, teamId)`** — factory function that creates a ship entity with class stats

### Testing

```bash
node server/tests/ship_classes.test.js
```

## Architecture

- **Server** (`server/`): authoritative game state, fixed-tick simulation, WebSocket rooms
- **Client** (`client/src/`): vanilla HTML5 canvas, interpolates server snapshots, captures orders
- **Wire protocol**: JSON messages (join, move, snapshot, matchEnd)

## Layout

- `server/` — authoritative ws server + fixed-tick sim (server.js, sim.js, entities.js, protocol.js, room.js)
- `client/src/` — canvas client (net.js, input.js, render.js, hud.js, camera.js, main.js)
