Skip to content

Commit 70d2621

Browse files
committed
Move protocol validation into shared module
1 parent 59bf7ab commit 70d2621

32 files changed

+513
-502
lines changed

docs/ARCHITECTURE.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ This is the heart of the project. All game rules live in a shared folder, making
4242
| `hex.ts` | 306 | Axial hex math: distance, neighbours, line draw, pixel conversion | **Fully generic** — zero game knowledge |
4343
| `util.ts` | 170 | Functional collection helpers (`sumBy`, `minBy`, `indexBy`, `cond`, etc.) | **Fully generic** — no game knowledge |
4444
| `types/` | 389 | All interfaces: `GameState`, `Ship`, `Ordnance`, C2S/S2C messages, scenarios (split into `domain.ts`, `protocol.ts`, `scenario.ts` with barrel re-export) | Game-specific |
45+
| `protocol.ts` | 433 | Shared runtime C2S validation and normalization (trimmed chat, bounded payloads) | Mostly generic |
4546
| `constants.ts` | 135 | Ship stats, ordnance mass, detection ranges, animation timing | Game-specific |
4647
| `movement.ts` | 435 | Vector movement with gravity, fuel, takeoff/landing, crash detection | Game-specific |
4748
| `combat.ts` | 627 | Gun combat tables, LOS, range/velocity mods, heroism, counterattack | Game-specific |
@@ -92,7 +93,7 @@ The backend leverages Cloudflare's edge network.
9293
| Module | Purpose | Reusability |
9394
|--------|---------|-------------|
9495
| `index.ts` | Worker entry: `/create`, `/ws/:code`, `/error`, `/telemetry`, static asset proxy | Generic pattern |
95-
| `protocol.ts` | Room codes, tokens, seat assignment, message validation | **~80% generic** — room/token/seat logic is game-agnostic |
96+
| `protocol.ts` | Room codes, tokens, init payload parsing, seat assignment, shared-validator re-export | **~85% generic** — room/token/seat logic is game-agnostic |
9697
| `game-do/game-do.ts` | Durable Object: WebSocket lifecycle, state persistence, broadcasting | **~70% generic** — multiplayer plumbing is reusable |
9798
| `game-do/messages.ts` | S2C message construction from engine results | Game-specific |
9899
| `game-do/session.ts` | Disconnect grace period, alarm scheduling | **Fully generic** |
@@ -104,6 +105,8 @@ The backend leverages Cloudflare's edge network.
104105

105106
- **`runGameStateAction(ws, action, onSuccess)`**: Generic handler that reduces boilerplate across all 12+ action handlers. Fetches current state from storage → runs engine function in try/catch → on validation error sends error message to the WebSocket → on exception logs with game code/phase/turn and sends error (state is preserved via clone-on-entry) → on success invokes `onSuccess` callback (typically save state + broadcast). `handleTurnTimeout` has equivalent try/catch protection for the alarm-driven code path.
106107

108+
- **Shared protocol validation**: Runtime C2S validation now lives in `shared/protocol.ts` instead of the server shell. The Durable Object still consumes `validateClientMessage()`, but the message-shape ownership sits beside the shared protocol types rather than inside server-only plumbing.
109+
107110
- **Single state-bearing outbound message per action**: `publishStateChange()` persists state and events first, then emits exactly one state-bearing message (`movementResult`, `combatResult`, or `stateUpdate`). If the resulting state is terminal, the DO appends a separate `gameOver` notification after that state-bearing message. This keeps client phase transitions aligned with a one-action/one-update contract.
108111

109112
- **Filtered broadcasting**: `broadcastFiltered()` checks whether the current scenario has hidden information (fugitive identities in escape scenarios). If no hidden info, the same state goes to both players. If hidden info, `filterStateForPlayer(state, playerId)` is called separately per player — own ships are fully visible, unrevealed enemy ships show `type: 'unknown'`. When adding new hidden state, extend `filterStateForPlayer()` and the check in `broadcastFiltered()`.
@@ -180,7 +183,7 @@ Delta-V is a fully installable PWA. A lightweight hand-written service worker pr
180183

181184
**Server→Client (S2C)**: `welcome`, `matchFound`, `gameStart`, `movementResult`, `combatResult`, `stateUpdate`, `gameOver`, `rematchPending`, `opponentDisconnected`, `chat`, `error`, `pong`
182185

183-
All messages are discriminated unions validated at the protocol boundary. `GameState` is the single source of truth — clients never mutate it; server owns all state mutations.
186+
All messages are discriminated unions validated at the protocol boundary. Chat payloads are trimmed before validation and blank post-trim messages are rejected, so non-UI clients cannot inject empty log entries. `GameState` is the single source of truth — clients never mutate it; server owns all state mutations.
184187

185188
### Multiplayer Session Lifecycle
186189

docs/BACKLOG.md

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,6 @@ Current direction is good. This plan is aimed at removing the
1010
main correctness and coordination risks found in the latest
1111
project review without rewriting working systems.
1212

13-
### Phase 0.5. Tighten protocol boundary consistency
14-
15-
- Trim chat text before validating it in `src/server/protocol.ts`.
16-
- Reject messages that become empty after trimming so non-UI
17-
clients cannot produce blank chat log entries.
18-
- Add protocol tests for whitespace-only chat and normal trimmed
19-
chat payloads.
20-
2113
### Phase 1. Consolidate protocol validation
2214

2315
- Move C2S/S2C runtime schema ownership next to the shared
@@ -58,10 +50,9 @@ project review without rewriting working systems.
5850

5951
### Suggested order
6052

61-
1. Phase 0.5: chat boundary tightening.
62-
2. Phase 1: protocol schema consolidation.
63-
3. Phase 2: client store/transition consolidation.
64-
4. Phase 3: direct shared-type imports and boundary enforcement.
53+
1. Phase 1: protocol schema consolidation.
54+
2. Phase 2: client store/transition consolidation.
55+
3. Phase 3: direct shared-type imports and boundary enforcement.
6556

6657
---
6758

docs/SPACESHIPS.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,35 @@ In the vacuum of space, form follows delta-v and orbital mechanics. Our ship des
1414

1515
### The Corvette
1616
A compact warship optimized for high-acceleration intercepts.
17-
![Corvette](./assets/corvette_concept_art_1773597420059.png)
17+
![Corvette](./assets/corvette_1774105559884.png)
1818

1919
### The Dreadnaught
2020
A colossal, armored slab of railguns and fusion fire.
21-
![Dreadnaught](./assets/dreadnaught_concept_art_1773597559656.png)
21+
![Dreadnaught](./assets/dreadnaught_1774105575602.png)
2222

2323
### The Frigate
2424
An agile missile platform with high-ISP propulsion.
25-
![Frigate](./assets/frigate_concept_art_1773597577616.png)
25+
![Frigate](./assets/frigate_1774105594550.png)
2626

2727
### The Torch
2828
An experimental vessel built around a massive, high-ISP engine.
29-
![Torch](./assets/torch_ship_concept_art_1773597435309.png)
29+
![Torch](./assets/torch_ship_1774105612448.png)
3030

3131
### The Liner
3232
A luxurious interplanetary passenger vessel oriented purely for zero-g (no artificial gravity rings).
33-
![Liner](./assets/liner_concept_art_1773597591879.png)
33+
![Liner](./assets/liner_1774105633411.png)
3434

3535
### The Corsair
3636
A gritty, mismatched raider used for deep-space intercepts.
37-
![Corsair](./assets/corsair_concept_art_1773597605619.png)
37+
![Corsair](./assets/corsair_1774105650461.png)
3838

3939
### The Industrial Fleet
4040
A modular transport system carrying fuel and cargo across the system.
41-
![Industrial Fleet](./assets/transport_tanker_concept_art_1773597452866.png)
41+
> *[IMAGE: To be generated - A modular transport system carrying fuel and cargo across the system]*
4242
4343
### The Orbital Base
4444
A sprawling industrial hub and defensive fortress.
45-
![Orbital Base](./assets/orbital_base_concept_art_1773597468716.png)
45+
> *[IMAGE: To be generated - A sprawling industrial hub and defensive fortress]*
4646
4747
## Implementation Notes
4848
These images serve as the "mood board" for future asset development. Key color palettes identified:

docs/TECHNOLOGY.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ By understanding these visual motifs, players can immediately recognize the capa
1212
Current chemical rockets have high thrust but terrible fuel efficiency (Specific Impulse / ISP), while ion drives have incredible ISP but microscopic thrust. Delta-V ships rely on sustained **Magnetic Confinement Fusion Drives**. Using Deuterium/Helium-3 reactions, these engines direct exhausted plasma out the back via a magnetic nozzle, providing both brutal thrust and incredible fuel efficiency, allowing for continuous rapid brachistochrone trajectories across the solar system.
1313

1414
**Visual Description & Image Placeholder:**
15-
> *[IMAGE: To be generated - Close up of a massive Torch Drive]*
15+
![Torch Drive](./assets/torch_drive_1774105359319.png)
1616
- Massive, realistically scaled engine bells or exposed magnetic nozzle rings.
1717
- Emits a blinding, high-energy cyan or pure white exhaust plume.
1818
- Usually surrounded by heavy, cylindrical magnetic confinement coil rings.
@@ -25,7 +25,7 @@ Current chemical rockets have high thrust but terrible fuel efficiency (Specific
2525
In the vacuum of space, dissipating the extreme waste heat from fusion drives and railguns is a monumental challenge. Older ship designs use bulky, fragile radiator fins. The modern Delta-V fleet uses **Liquid Droplet Radiators** (spraying a stream of hot molten coolant directly into the vacuum and catching it meters away to radiate heat) and **Micro-Channel Cooling Arrays** (pumping coolant through hair-thin channels etched directly into the hull plating).
2626

2727
**Visual Description & Image Placeholder:**
28-
> *[IMAGE: To be generated - Close up of a droplet radiator/glowing hull array]*
28+
![Droplet Radiator](./assets/droplet_radiator_1774105375024.png)
2929
- Sleek, flush-mounted hull panels that glow faintly cherry-red or amber under load.
3030
- Exposed mechanical arrays where a precise, glowing stream of liquid stretches momentarily through the vacuum between two catch-basins.
3131
- *Absence* of protruding, vulnerable traditional fins.
@@ -38,7 +38,7 @@ In the vacuum of space, dissipating the extreme waste heat from fusion drives an
3838
Combat in Delta-V happens over vast distances, requiring extreme projectile speeds. Ship weaponry relies on electromagnetism rather than chemical explosives to accelerate solid tungsten or depleted uranium slugs to significant fractions of light speed. Firing these weapons requires massive bursts of energy, pulling directly from the ship's capacitor banks and reactor.
3939

4040
**Visual Description & Image Placeholder:**
41-
> *[IMAGE: To be generated - Close up of a spine-mounted Railgun]*
41+
![Spine Railgun](./assets/spine_railgun_1774105392008.png)
4242
- Extremely long, heavy, spine-mounted or turreted barrels.
4343
- Exposed magnetic coils spaced evenly along the length of the barrel.
4444
- Flanked by incredibly thick power conduits and hazard warnings due to massive electromagnetic fields.
@@ -51,7 +51,7 @@ Combat in Delta-V happens over vast distances, requiring extreme projectile spee
5151
To survive kinetic railgun impacts, deep space warships utilize layered defenses. The outermost layer is a **Whipple Shield**—a thin, sacrificial bumper designed to vaporize incoming high-velocity slugs upon impact. This spreads the kinetic energy over a much wider area so that the underlying, thick **Ablative Armor** can absorb and slowly slough off the remaining energy without the vital modules being penetrated.
5252

5353
**Visual Description & Image Placeholder:**
54-
> *[IMAGE: To be generated - Close up of scarred ablative armor overlapping]*
54+
![Ablative Armor](./assets/ablative_armor_1774105408814.png)
5555
- Thick, dense, overlapping hexagonal outer plating.
5656
- Highly utilitarian aesthetic, commonly painted in gunmetal or navy tones.
5757
- Frequently marred with impact craters, scorch marks, and replaced modular segments.
@@ -64,7 +64,7 @@ To survive kinetic railgun impacts, deep space warships utilize layered defenses
6464
Deep space logistics requires standardized mass optimization. Fuel (liquid hydrogen and oxygen) is stored in perfect spheres—the most efficient shape for maintaining pressure with minimal material weight. To prevent the cryogenic fuel from boiling off due to solar radiation, the tanks are wrapped in highly reflective Multi-Layer Insulation (MLI).
6565

6666
**Visual Description & Image Placeholder:**
67-
> *[IMAGE: To be generated - Close up of gold-foil spherical tanks on a bare truss]*
67+
![Spherical Tanks](./assets/spherical_tanks_1774105429347.png)
6868
- Clusters of perfectly spherical tanks exposed to space.
6969
- Wrapped heavily in crinkled, highly reflective metallic silver or Kapton gold foil.
7070
- Supported firmly by a skeletal framework of exposed, bare-metal modular trusses.
@@ -77,7 +77,7 @@ Deep space logistics requires standardized mass optimization. Fuel (liquid hydro
7777
While massive fusion drives handle main acceleration, ships still need to pitch, yaw, roll, and perform delicate docking maneuvers over short distances in zero-g. They rely on networked clusters of small, hypergolic chemical thrusters or cold-gas jets to provide this precise rotational thrust on all axes.
7878

7979
**Visual Description & Image Placeholder:**
80-
> *[IMAGE: To be generated - Close up of an RCS thruster quad block]*
80+
![RCS Thruster](./assets/rcs_thruster_1774105445305.png)
8181
- Small "quad-block" thruster nozzles protruding from the corners and extremities of the hull.
8282
- Often feature scorch marks radiating out from the tiny bells against the plating.
8383
- Visually emits short, sharp, pale bursts of exhaust.
@@ -90,7 +90,7 @@ While massive fusion drives handle main acceleration, ships still need to pitch,
9090
For vessels that don't need continuous massive fusion power (like Orbital Bases) or as auxiliary power backups, enormous deployed solar panels are used to convert sunlight directly into electricity. Because sunlight significantly weakens in deep space, these arrays must be incredibly large to generate sufficient voltage for the station's needs.
9191

9292
**Visual Description & Image Placeholder:**
93-
> *[IMAGE: To be generated - Close up of deploying solar panels against the void]*
93+
![Solar Arrays](./assets/solar_arrays_1774105459204.png)
9494
- Enormous, flat, dark-blue or black rectangular grid arrays extending far from the main hull.
9595
- Supported by delicate-looking unfolding rigid booms and trusses.
9696
- Highly reflective, flat, and fragile appearance compared to the armored main hull.
@@ -103,7 +103,7 @@ For vessels that don't need continuous massive fusion power (like Orbital Bases)
103103
In the vast, silent void of the solar system, communicating telemetry and targeting data requires highly focused, narrow-beam frequency transmissions. Large parabolic dish antennas are designed to pierce through background radiation to maintain contact with planetary bases or other ships at extreme ranges.
104104

105105
**Visual Description & Image Placeholder:**
106-
> *[IMAGE: To be generated - Close up of a massive targeting/comms dish antenna]*
106+
![Comms Dish](./assets/comms_dish_1774105476101.png)
107107
- Large parabolic dishes mounted on articulating mechanical gimbals.
108108
- Extensive wiring and complex central receiver feeds bridging the center of the dish.
109109
- Often clustered near the command deck or sensor booms to minimize signal delay.
@@ -116,7 +116,7 @@ In the vast, silent void of the solar system, communicating telemetry and target
116116
Visual confirmation is useless at engagement ranges of thousands of kilometers. Ships rely on sophisticated active and passive sensor suites, including LiDAR (Light Detection and Ranging) arrays and thermal imaging, to detect enemies, debris, and navigation hazards. These are mounted on extendable booms to get them away from the electronic "noise" and radiation of their own primary fusion drives.
117117

118118
**Visual Description & Image Placeholder:**
119-
> *[IMAGE: To be generated - Close up of sensor spine extending from a warship]*
119+
![Sensor Spine](./assets/sensor_spine_1774105490297.png)
120120
- Long, fragile-looking structural spines protruding from the prow or sides of the ship.
121121
- Tipped with irregular, geometric sensor heads, domed cameras, and flat phased-array radar panels.
122122
- Highly detailed, asymmetrical, and purely utilitarian visual clutter.
@@ -129,7 +129,7 @@ Visual confirmation is useless at engagement ranges of thousands of kilometers.
129129
Directly extrapolated from modern naval Close-In Weapon Systems (CIWS) like the Phalanx, PDCs are fast-tracking rotary cannons designed as a ship's last line of defense. They fire curtains of solid tungsten slugs or proximity-fused flak intended to physically shred incoming missiles and drones before they hit the hull.
130130

131131
**Visual Description & Image Placeholder:**
132-
> *[IMAGE: To be generated - Close up of an articulated multi-barrel rotary cannon]*
132+
![Rotary Cannon](./assets/rotary_cannon_1774105506192.png)
133133
- Small, aggressively spiked multi-barreled rotary cannons housed in armored turrets.
134134
- Mounted on extremely fast-turning spherical or pivoting gimbals scattered across the hull to provide 360-degree overlapping fields of fire.
135135
- Thick, heavy ammunition feed tracks leading down into the ship's magazines.
@@ -142,7 +142,7 @@ Directly extrapolated from modern naval Close-In Weapon Systems (CIWS) like the
142142
Because stealth is virtually impossible in the frozen vacuum of space (where the heat of a drive plume shines like a star against the background), combat relies heavily on sheer velocity and overwhelming numbers. Space-rated missiles are essentially autonomous drone-ships, featuring their own sophisticated hypergolic chemical or dirty fusion drives, designed to out-accelerate PDCs through swarm tactics.
143143

144144
**Visual Description & Image Placeholder:**
145-
> *[IMAGE: To be generated - Close up of flush hexagonal missile launch tubes]*
145+
![Missile Tubes](./assets/missile_tubes_1774105521423.png)
146146
- Deeply recessed, flush-mounted clusters of hexagonal or cylindrical launch tubes built directly into the armor plating.
147147
- Often glowing amber or red from internal pre-heating before a launch sequence.
148148
- Clean, heavy-duty armored hatch covers meant to protect unfired ordnance from glancing blows.
96 KB
Loading
125 KB
Loading
84.3 KB
Loading
-665 KB
Binary file not shown.
111 KB
Loading
-729 KB
Binary file not shown.

0 commit comments

Comments
 (0)