You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Restore utility helpers, DOM helpers, and update docs
Recover src/shared/util.ts (16 functional collection helpers),
src/client/dom.ts (declarative DOM helpers), and their tests from
git history after accidental deletion during folder reorganization.
Update CODING_STANDARDS.md with functional style guidance and DOM
helper recommendations. Add utility adoption as top P2 priority
in BACKLOG.md. Align doc cross-references with new folder structure.
Copy file name to clipboardExpand all lines: docs/ARCHITECTURE.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ Delta-V employs a full-stack TypeScript architecture built around a **shared pur
8
8
9
9
### Key Technologies
10
10
-**Language**: TypeScript (strict mode) across the entire stack.
11
-
-**Frontend**: HTML5 Canvas 2D API for rendering (`client/renderer.ts`), raw DOM/Events for UI and Input. No heavy frameworks (React/Vue/etc.) are used, ensuring maximum performance for the game loop.
11
+
-**Frontend**: HTML5 Canvas 2D API for rendering (`client/renderer/renderer.ts`), raw DOM/Events for UI and Input. No heavy frameworks (React/Vue/etc.) are used, ensuring maximum performance for the game loop.
12
12
-**Backend**: Cloudflare Workers for HTTP routing and Cloudflare Durable Objects for authoritative game state and WebSocket management.
13
13
-**Build & Tools**: `esbuild` for lightning-fast client bundling, `wrangler` for local testing and deployment, and `vitest` for unit testing.
14
14
@@ -21,7 +21,7 @@ The architecture is divided into three distinct layers: Shared Logic, Server, an
21
21
### A. Shared Game Engine (`shared/`)
22
22
This is the heart of the project. The decision to keep all game rules in a shared folder makes the system incredibly robust and completely unit-testable.
23
23
24
-
-**`game-engine.ts`**: A pure functional state machine. It takes the current `GameState` and player actions (e.g., astrogation orders, combat declarations) and returns a new `GameState` along with events (movements, combat results). **Crucially, it has no side effects (no DOM manipulation, no network calls, no storage access).**
24
+
-**`engine/game-engine.ts`**: A pure functional state machine. It takes the current `GameState` and player actions (e.g., astrogation orders, combat declarations) and returns a new `GameState` along with events (movements, combat results). **Crucially, it has no side effects (no DOM manipulation, no network calls, no storage access).**
25
25
-**`movement.ts`**: Contains the complex vector math, gravity well logic, and collision detection. Moving a ship is resolved strictly on an axial hex grid (using `hex.ts`).
26
26
-**`combat.ts`**: Evaluates line-of-sight, calculates combat odds based on velocity/range modifiers, and resolves damage.
27
27
-**`types.ts`**: The single source of truth for all data structures (`GameState`, `Ship`, `CombatResult`, network message payloads). This ensures the client and server never fall out of sync.
@@ -30,7 +30,7 @@ This is the heart of the project. The decision to keep all game rules in a share
30
30
The backend leverages Cloudflare's edge network.
31
31
32
32
-**`index.ts`**: The standard Worker entry point. It creates tokenized game rooms, generates collision-checked 5-character codes, and forwards valid WebSocket requests.
33
-
-**`game-do.ts` (Durable Object)**: Each game instance is backed by a single Durable Object. This ensures that all WebSocket connections for a specific game hit the same exact machine in Cloudflare's network, preventing race conditions.
33
+
-**`game-do/game-do.ts` (Durable Object)**: Each game instance is backed by a single Durable Object. This ensures that all WebSocket connections for a specific game hit the same exact machine in Cloudflare's network, preventing race conditions.
34
34
- Acts as the authoritative session and transport layer around `game-engine.ts`.
- Validates inputs before dispatch, passes them to the pure engine, stores the resulting state using the Durable Object `ctx.storage`, and broadcasts updates to connected clients.
@@ -40,10 +40,10 @@ The backend leverages Cloudflare's edge network.
40
40
The frontend is responsible for rendering the pure hex-grid state into a smooth, continuous graphical experience.
41
41
42
42
-**`main.ts`**: The client-side controller. Manages WebSocket connections, local-AI execution, phase transitions, and orchestrates the Renderer, Input, and UI.
43
-
-**`renderer.ts`**: A highly optimized Canvas 2D renderer. It separates logical hex coordinates from pixel coordinates. It features smooth camera interpolation, persistent trails, and movement/combat animations that occur *between* turn phases.
43
+
-**`renderer/renderer.ts`**: A highly optimized Canvas 2D renderer. It separates logical hex coordinates from pixel coordinates. It features smooth camera interpolation, persistent trails, and movement/combat animations that occur *between* turn phases.
44
44
-**`input.ts`**: Manages the complex state of user interaction (selecting burn vectors, queuing attacks, choosing targets) before finalizing and sending them to the server.
45
-
-**`game-client-*.ts` / `renderer-*.ts` helper modules**: Pure client-side helpers for combat selection, input planning, minimap geometry, phase derivation, formatting, and tooltip/view-model logic. These keep the large coordinators testable without introducing a client framework.
46
-
-**`ui.ts` / `audio.ts`**: Handles the HTML overlay (menus, HUD) and Web Audio API interactions.
45
+
-**`game/` / `renderer/` / `ui/` subfolders**: Pure client-side helpers for combat selection, input planning, minimap geometry, phase derivation, formatting, and tooltip/view-model logic. These keep the large coordinators testable without introducing a client framework.
46
+
-**`ui/ui.ts`** / **`audio.ts`**: Handles the HTML overlay (menus, HUD) and Web Audio API interactions.
47
47
-**Visual Polish**: Employs a premium design system with glassmorphism tokens (backdrop-filters), tactile micro-animations (recoil, scaling glows), and pulsing orbital effects for high-end UX.
48
48
49
49
### D. Progressive Web App (`static/sw.js`, `static/site.webmanifest`)
@@ -71,16 +71,16 @@ Delta-V is a fully installable PWA. A lightweight hand-written service worker pr
71
71
The next architectural gains are mostly about keeping the current design readable, not replacing it:
72
72
73
73
### A. Shared Engine
74
-
-**Split `game-engine.ts` by phase when it becomes painful to navigate**: The engine remains a strong fit for pure functions and plain data. If the file continues to grow, phase-oriented modules are the natural next split.
74
+
-**Engine is now decomposed by phase** (`engine/game-engine.ts`, `engine/combat.ts`, `engine/ordnance.ts`, `engine/victory.ts`, `engine/util.ts`): The engine remains a strong fit for pure functions and plain data.
75
75
-**Avoid premature ECS migration**: The current rules engine has a small, stable entity set and turn-based processing. An ECS would likely make the rules harder to follow before it creates meaningful flexibility.
76
76
-**Prefer a lightweight event log over full event sourcing**: Replays, reconnect catch-up, and spectator mode would benefit from an append-only turn log, but snapshots should remain the source of truth.
77
77
78
78
### B. Client
79
79
-**Continue extracting pure helpers from `main.ts`**: Phase derivation, HUD view models, and local/remote result application should keep moving out of the main controller so browser orchestration stays thin.
80
-
-**Split `renderer.ts` by render pass only when needed**: The renderer is large enough to justify future decomposition, but the right split is by visual responsibility, not by introducing a generic rendering framework.
80
+
-**Renderer is now decomposed by visual responsibility** (`renderer/renderer.ts` plus `combat.ts`, `entities.ts`, `vectors.ts`, `effects.ts`, etc.): Further splits should follow the same pattern of visual responsibility.
81
81
-**Add browser-side tests around input/UI/orchestration**: Shared rules are already well covered. The bigger refactor risk now sits in client coordination code.
82
82
83
83
### C. Server / Operations
84
-
-**Keep refactoring `game-do.ts`by concern**: Session/auth handling, engine-result publishing, and timeout management should stay separate so features like spectators or replay catch-up can be added without bloating one class.
84
+
-**`game-do/` is now split by concern** (`game-do.ts`, `messages.ts`, `session.ts`, `turns.ts`): Features like spectators or replay catch-up can be added without bloating one class.
85
85
-**Public lobby hardening remains future work**: Longer opaque identifiers, rate limiting, and optional identity/account binding matter more than swapping validation libraries.
86
86
-**Persistence beyond active rooms is still optional**: Durable Object storage is a good fit for live matches; D1 or another store only becomes necessary once match history or player progression matters.
Copy file name to clipboardExpand all lines: docs/BACKLOG.md
+100-8Lines changed: 100 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,25 +11,117 @@ No open P0 items currently.
11
11
### Continue mobile HUD/layout polish
12
12
The HUD now measures its live top/bottom offsets instead of relying on fixed `rem` guesses, and the mobile top bar/action cluster have been tightened. There is still follow-up work to validate real-device behavior and finish any remaining overlap or clipping issues on very small screens.
`main.ts`is the only coordinator still over 1,000 lines. Its methods are mostly 5-20 line glue between extracted helpers — no single block is large enough for easy extraction. Consider whether a second-level split (e.g., separating local-game orchestration from network orchestration) is worthwhile.
18
+
### 20. Adopt utility helpers across the codebase
19
+
`src/shared/util.ts`provides functional collection helpers (`sumBy`, `minBy`, `maxBy`, `filterMap`, `compact`, `count`, `partition`, `indexBy`, `groupBy`, `cond`, etc.) and `src/client/dom.ts` provides declarative DOM helpers (`el`, `show`/`hide`/`visible`, `byId`). These are tested and documented in CODING_STANDARDS.md but not yet widely used. Sweep the codebase to replace manual reduce/loop/filter patterns with the util helpers, and replace verbose createElement/addEventListener chains with the DOM helpers.
20
20
21
-
**Files:**`src/client/main.ts`
21
+
**Benefit:** Reduces boilerplate, makes intent clearer, and establishes consistent patterns across the codebase.
22
+
23
+
**Files:** All files under `src/shared/` and `src/client/` — look for manual `reduce`, `for` loops building accumulators, `.filter().length`, `.map().filter(x => x != null)`, `document.createElement` chains, and `getElementById` with non-null assertions.
24
+
25
+
### 2a. Pull PlanningState out of the Renderer
26
+
`PlanningState` lives on the `Renderer` but is mutated by `InputHandler`, `main.ts`, and read by renderer sub-modules. Move ownership to `GameClient`. The renderer and input handler receive it as a read reference. Mutations go through existing helpers like `createClearedCombatPlan`.
27
+
28
+
**Benefit:** Eliminates the tightest coupling in the codebase — three systems reaching into the same mutable bag. Enables snapshotting for debugging/undo.
### 2b. Transport adapter for local vs network play
35
+
9 `if (this.isLocalGame)` branches in `main.ts` duplicate logic. Define a `GameTransport` interface with `WebSocketTransport` and `LocalTransport` implementations.
36
+
37
+
**Benefit:** Eliminates all `isLocalGame` branching. Opens the door for replay playback and test harness transports.
38
+
39
+
**Files:**`src/client/main.ts`, new `src/client/game/transport.ts`
40
+
41
+
**Details:** See REFACTORING.md Priority 2.
42
+
43
+
### 2c. Command dispatch
44
+
Unify ~30 action-handler methods into a single `dispatch(cmd: GameCommand)` bottleneck. The existing `KeyboardAction` discriminated union maps almost directly to `GameCommand`.
45
+
46
+
**Benefit:** One place for logging, guard conditions, and input routing. Keyboard, UI, and input handler all produce the same command type.
Replace `UIManager`'s ~15 nullable callback properties with a single typed `UIEvent` union and emitter. Events feed into the dispatch function from 2c.
54
+
55
+
**Benefit:** Makes the relationship between UI events and game actions visible and greppable.
`ai.ts` is at 62.66% statements, 58.61% branches, 54.05% functions. Significant gaps in ordnance AI, combat target selection, and fleet-building decisions.
P3 items are independent of each other and of P2. They can be interleaved freely.
27
118
28
119
## Done
29
120
30
-
-~~Decompose game-engine.ts~~ — Extracted into `engine-util.ts`, `engine-victory.ts`, `engine-ordnance.ts`, `engine-combat.ts` with backward-compatible re-exports (681 lines, down from 1957)
121
+
-~~Decompose game-engine.ts~~ — Extracted into `engine/util.ts`, `engine/victory.ts`, `engine/ordnance.ts`, `engine/combat.ts` with backward-compatible re-exports (681 lines, down from 1957)
31
122
-~~Add map-data.test.ts~~ — 23 tests covering map builder, body gravity, base placement, scenarios
0 commit comments