Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
- name: Lint
run: npm run lint

- name: Asset audit
run: npm run assets:audit

- name: Build
run: npx vite build
env:
Expand Down
34 changes: 34 additions & 0 deletions ASSETS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# DEALT / SLIDE Modern Ops Assets

**Art direction:** A compact fictionalized South Florida strip at night, with wet asphalt, palms, simple one-story storefront geometry, cyan-magenta-amber-green emissive accents, restrained physically plausible materials, readable cover lanes, and clean crew/opposition silhouettes. The target is stylized-realistic browser-game output rather than a cinematic or photoreal scene.

## Visual Target

| Name | Role | Size | File | Runtime |
|---|---|---:|---|---|
| Modern Ops visual target | QA reference for composition, camera, palette, cover, HUD, and object density | 2560×1440 | `/home/ubuntu/webdev-static-assets/dealt-slide-modern-ops-visual-target.png` | No; verification reference only |

**Prompt:** Create a clean, sharp 16:9 in-game screenshot target for a modern 3D browser action game, using the supplied rainy neon Florida strip reference only for palette, mood, wet asphalt reflections, palm silhouettes, and storefront identity. Use an over-the-right-shoulder camera; include one player crew member, two readable opposition silhouettes, concrete planter and parked-car cover, a green extraction marker, a wet two-lane road, simple neon storefront boxes, a complete but compact combat HUD, and only effects the implementation will support. Exclude motion blur, depth of field, volumetric fog, crowds, real brands, gore, and cinematic composition.

## Runtime Texture

| Name | Description | Intended size | Source | Runtime path |
|---|---|---:|---|---|
| Modern Ops storefront facade | Four-bay straight-on fictional storefront elevation with cyan, green, magenta, and amber emissive signs | 32 m × 6 m plane; source 1536×864 WebP, 88,376 bytes | `/home/ubuntu/webdev-static-assets/dealt-slide-ops-storefront-facade.png` | `/assets/runtime/generated/environments/street/block_modern_ops_storefront_v001.webp` |

**Prompt:** Create a straight-on orthographic 16:9 game texture plate for four simple fictional Florida strip-mall bays, matching the visual target’s rainy-neon palette. Include charcoal stucco, reflective windows, metal doors, shallow awnings, and short fictional signs: NIGHT MART, 305 CAFE, VICE SHOP, and GOLD PAWN. Exclude people, cars, sidewalk, sky, rain, HUD, weapons, real brands, perspective, depth of field, and dramatic lighting.

The runtime texture is registered as `generated.environments.street.block_modern_ops_storefront_v001` in `frontend/src/assets/runtimeManifest.json` and is included in the repository asset budget.

## Existing Reused Assets

| Asset | Role in the slice | Runtime path |
|---|---|---|
| Las Olas drive-by street plate | Existing palette/place reference and legacy action fallback | `/assets/runtime/generated/environments/street/block_lasolas_driveby_street_v001.webp` |
| Las Olas top-down plate | Strategy/tactical identity continuity | `/assets/runtime/generated/environments/topdown/block_lasolas_topdown_v001.webp` |
| Registered street character art | Tactical/legacy actor art; 3D mode uses lightweight procedural proxies in the first slice | Resolved through `worldActorResolver` |
| Combat effect sheet | Existing effect vocabulary for non-3D action modes | `/assets/runtime/generated/effects/fx_combat_sprite_sheet_v001.webp` |

## Runtime Rules

All runtime images must be registered in `runtimeManifest.json`, pass `npm run assets:audit`, and stay within the 20 MB budget. Babylon receives the storefront through its registered public path. The visual-target PNG remains outside the runtime tree and should be attached with review evidence rather than loaded by the game.
45 changes: 45 additions & 0 deletions MEMORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# DEALT / SLIDE Modern Ops Memory

## 2026-08-26 — Audit and Recovery

The protected default branch is `main-tL2525`. Work is isolated on `feat/modern-gameplay-completion`. The repository had 32 open issues, no open pull requests, and one materially divergent unmerged branch: `copilot/dev-oplan`. Six unique commits from that branch were recovered and reconciled onto the current baseline rather than recreated.

The recovered work registers the seven previously orphaned assets, fixes stale runtime paths, expands Block DNA from 8 to 17 cards, adds persistent local Ghost Crews and tests, adds the City Feed threat banner, and restores the beta smoke tests and release checklist. After recovery, frontend typecheck passed, 685 tests passed across 43 files, and the asset audit passed with zero errors and zero warnings at 5.73 MB.

The default branch’s existing tactical encounter already has a strong deterministic core: `prepareEncounter` produces a typed preparation, `combatSession` owns commands/ticks/RNG/results, and `BlockModeView` applies the result back to block/crew/heat systems. The main missing modern-action requirement was not another simulation but a shared presentation controller and 3D adapter.

## 2026-08-26 — Shared Controller

Added `CombatSessionController` and five focused tests. Camera mode, pause state, selection, shared command sequence, nearest-target fire, reload, interact, retreat, HUD derivation, subscriptions, and disposal live outside the authoritative `CombatSession`. Switching tactical, first-person, and third-person cameras leaves the combat snapshot unchanged. Focused typecheck and 10 combat tests passed.

## 2026-08-26 — Art Direction

Generated a mandatory 2560×1440 visual target at `/home/ubuntu/webdev-static-assets/dealt-slide-modern-ops-visual-target.png`, using the existing Las Olas drive-by plate as a palette and place reference. The target establishes a wet neon strip, over-the-shoulder camera, simple cover, two opponents, extraction marker, and the minimum Modern Ops HUD.

Generated a straight-on four-bay storefront texture from that target, converted it to an 88,376-byte 1536×864 WebP, placed it at `/assets/runtime/generated/environments/street/block_modern_ops_storefront_v001.webp`, and registered it in `runtimeManifest.json`. The visual target is not loaded at runtime.

## Build Environment Note

On the audited default baseline, production bundling transformed 2,437 modules and was terminated by sandbox memory pressure while rendering chunks. Typecheck, tests, lint, asset audit, backend tests, and the latest default-branch CI were healthy. Treat a repeat local build termination as an environment limitation only after confirming there is no TypeScript, test, or asset regression; use CI/Vercel build evidence for the final gate.

## Next Implementation Step

Install Babylon.js, add `frontend/src/game/ops/**` and `frontend/src/components/ops/**`, project encounter terrain into one hero 3D block, wire semantic controls to `CombatSessionController`, add tactical/FPS/TPS cameras, expose Modern Ops from `BlockModeView`, then run focused tests before browser verification.

## 2026-08-26 — Modern Ops Integrated and Browser-Verified

Added Babylon.js, the grid-to-world projection helpers, semantic DOM input, lifecycle-safe scene factory, `OpsWorld`, full-screen React canvas/HUD, generated storefront runtime texture, and lazy `OPS 3D` launchers in `BlockModeView`. The scene supports tactical, first-person, and third-person cameras over one `CombatSessionController`, WASD/arrow movement, fire, reload, extract, retreat, pause, live opponent turns, cover, tracers/impacts, extraction, and deterministic `?demo=1` behavior.

The first browser round found two real defects. Inline canvas callbacks caused the Babylon effect to recreate the engine after every HUD update, and `OpsWorld.dispose()` cleared externally owned controller listeners. Memoizing callbacks and moving controller disposal to encounter unmount fixed camera/HUD persistence. The initial encounter also overran the crew before input; opposition turns now occur every twenty ticks with lower damage, and a deterministic test proves the opening forty ticks remain active and survivable.

Sandbox Chromium/CDP launched the mode through MAP → Strip → OPS 3D with WebGL2, one canvas, no Modern Ops error overlay, and zero captured runtime exceptions. TPS, FPS, and tactical screenshots show the same authored block, cover, actors, objective, ammo, health, and event stream. FPS firing reduced ammo and returned `Shot strikes cover.` without resetting the session.

The deterministic demo reached a secured outcome and applied it through the existing block boundary. Pending income changed $840→$982, heat 1→2, morale 85%→89%, the Modern Ops portal unmounted, and the $2,200 injury/hospital follow-up opened for Lil Dre. No separate economy, crew, or territory copy was introduced.

Evidence is saved under `.audit/`: `ops-third-person.png`, `ops-first-person.png`, `ops-tactical-active.png`, `ops-return-strategy.png`, `browser-findings.md`, and CDP state/event JSON files.

## 2026-08-26 — Final Quality Gauntlet

The completed branch passes TypeScript, all 45 frontend test files / 693 tests, the runtime asset audit (110 assets, 5.81 MB of the 20 MB budget), and all 42 offline backend tests. ESLint reports zero errors and 196 pre-existing warnings.

The production build initially terminated during chunk rendering, reproducing the baseline sandbox failure. Vite’s application-level manual chunks also emitted circular chunk warnings. Removing those forced component chunks, keeping only dependency-oriented chunks (including a dedicated lazy Babylon vendor chunk), and changing the minifier from Terser to esbuild eliminated the circular graph. After closing the completed browser-verification process, the production build succeeded in 21.15 seconds with 2,875 modules transformed. Modern Ops remains a separate lazy chunk (`ModernOpsEncounter` about 24.4 kB plus its Babylon vendor chunk), so the 3D runtime is not loaded until the player launches OPS 3D.
65 changes: 65 additions & 0 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Game Plan: DEALT / SLIDE Modern Ops Slice

**Branch:** `feat/modern-gameplay-completion`
**Baseline:** `main-tL2525@c178861`
**Hero block:** Las Olas / 1208 E Las Olas-derived Block DNA
**Authoritative model:** `frontend/src/game/combat/**`

## Recovered Foundation

The six unique `copilot/dev-oplan` commits have been reconciled onto the current baseline. The recovered work provides zero-warning runtime assets, 17 Block DNA cards, persistent local Ghost Crews, City Feed threat surfacing, beta smoke tests, and a release checklist. The new `CombatSessionController` provides one deterministic command and snapshot boundary for tactical, first-person, and third-person presentation.

## Risk Tasks

### 1. Shared session across cameras

- **Why isolated:** A camera switch must never recreate the encounter, reset RNG, duplicate commands, or commit a result twice.
- **Approach:** Keep `CombatSessionController` outside Babylon scene nodes; let cameras observe the same snapshot and emit typed commands through one monotonically increasing sequence.
- **Verify:** Switch tactical → first person → third person after movement and firing; tick, ammo, health, objective progress, and event IDs remain continuous.

### 2. Pointer-lock first-person controls

- **Why isolated:** Pointer lock requires a direct user gesture and may fail inside embedded browser contexts.
- **Approach:** Start with unlocked mouse-look plus a visible click-to-focus affordance; request pointer lock only from the canvas click, pause on lock loss, and keep keyboard/fire controls usable without lock.
- **Verify:** Camera does not spin on mount; pointer-lock denial shows no fatal error; Escape pauses; re-entry resumes from the same session.

### 3. Third-person shoulder camera

- **Why isolated:** Tight block geometry can place the camera inside cover or storefront meshes.
- **Approach:** Use a bounded follow/orbit camera with a fixed shoulder offset and ray-based obstruction shortening; keep movement grid-authoritative.
- **Verify:** Rotate behind the actor near planters and storefronts; the camera remains outside geometry and the selected actor stays visible.

### 4. DNA-to-3D scene projection

- **Why isolated:** A separate hand-authored 3D map would disconnect the claimed block from strategy and tactical modes.
- **Approach:** Convert encounter terrain cells and the stable hero-block identity into procedural road, sidewalk, storefront, cover, actor, and extraction meshes. Use the generated storefront facade as the authored visual anchor.
- **Verify:** The same preparation produces stable geometry; passable cells remain traversable; high-cover cells create visible cover; extraction occupies the declared grid point.

### 5. React/Babylon lifecycle

- **Why isolated:** Development double-mount and repeated mode entry can leak engines, render loops, events, pointer lock, and canvases.
- **Approach:** Guard engine initialization, centralize listener cleanup, call scene/world/controller disposal, and dispose the engine on unmount.
- **Verify:** Enter and exit Modern Ops five times; one canvas exists while active, no render loop continues after exit, and the next session starts cleanly.

## Main Build

Build a full-screen Babylon.js Modern Ops encounter under `BlockModeView` while preserving the existing Phaser tactical encounter. Add tactical, first-person, and third-person camera buttons; WASD/arrow movement; click/Space fire; `R` reload; `E` extract; `Q` retreat; `V` camera cycle; HUD; cover; opponent return fire; extraction; pause/exit; and atomic `CombatResult` handoff.

- **Assets:**
- `/home/ubuntu/webdev-static-assets/dealt-slide-modern-ops-visual-target.png` — 2560×1440 visual QA target, not runtime-loaded.
- `frontend/public/assets/runtime/generated/environments/street/block_modern_ops_storefront_v001.webp` — generated facade texture on a 32 m × 6 m storefront plane.
- Existing Las Olas street and top-down plates plus registered character sprites remain available to tactical and legacy views.
- **Verify:**
- Movement direction matches input and legal grid movement.
- Camera switching never changes the combat snapshot.
- Fire/reload feedback and opponent return fire are visible.
- The green extraction point resolves the encounter through the shared result boundary.
- HUD is readable at desktop and narrow mobile widths.
- No missing texture, fallback-magenta material, or gray blockout dominates the hero view.
- No browser console error appears during deterministic demo capture.
- Re-entry does not create duplicate engines or rewards.
- Reference consistency: wet neon Las Olas palette, compact block scale, readable cover lanes, authored storefront identity.

## Completion Gates

Run frontend typecheck, focused and full Vitest, runtime asset audit, lint, production build where environment memory permits, backend offline Pytest, deterministic browser smoke, and visual captures of tactical, first-person, third-person, firefight, and resolved strategy state. Update `MEMORY.md`, `ASSETS.md`, `STRUCTURE.md`, the project log, and release checklist before pull request review.
36 changes: 36 additions & 0 deletions STRUCTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# DEALT / SLIDE Modern Ops Structure

## Ownership Model

| Layer | Primary paths | Responsibility |
|---|---|---|
| React strategy shell | `frontend/src/App.tsx`, `frontend/src/components/map/BlockModeView.tsx` | Navigation, launcher UI, briefing, HUD chrome, mode selection, result consequences |
| Strategy state | `frontend/src/stores/**`, `frontend/src/utils/moneyRouter.ts` | Blocks, placements, rivals, crew, money, inventory, heat, morale, persistence |
| Encounter preparation | `frontend/src/game/combat/prepareEncounter.ts` | Stable conversion from selected block, placement, DNA, and rival context into one encounter input |
| Authoritative combat | `frontend/src/game/combat/combatSession.ts`, `types.ts` | Deterministic ticks, commands, RNG, damage, objectives, events, idempotent result |
| Presentation-neutral control | `frontend/src/game/combat/CombatSessionController.ts` | Selection, command sequence, pause, camera mode, shared HUD derivation, subscriptions |
| Tactical presenter | `frontend/src/components/encounter/**` | Existing Phaser tactical rendering and input |
| Modern Ops presenter | `frontend/src/components/ops/**`, `frontend/src/game/ops/**` | Babylon engine lifecycle, procedural 3D projection, cameras, semantic input, effects |
| Result boundary | `BlockModeView.handleEncounterResolved` and `blockStore.applyEncounterResult` | Exactly-once return to territory, heat, morale, crew injury, income, and follow-up UI |

## Modern Ops Runtime

`ModernOpsEncounter.tsx` owns the full-screen React portal, creates one `CombatSessionController`, subscribes to state for the HUD, and commits a completed result once. `ModernOpsCanvas.tsx` owns one Babylon `Engine`, invokes `createModernOpsScene`, handles resize and StrictMode-safe cleanup, and never writes strategy state.

`createModernOpsScene` creates the scene, lights, environment, actor proxies, extraction marker, effects, and three cameras. `OpsWorld` subscribes to the controller, projects grid cells to world coordinates, updates actor transforms and health/readability, interprets semantic input, and converts it into controller commands. Visual interpolation and effects are non-authoritative.

## Coordinate Contract

The combat grid is authoritative. Convert a grid point `{x, y}` to world space using a fixed cell size, centered around the block origin. The X axis follows grid columns; the Z axis follows grid rows; Y is height. Road, sidewalk, storefront, cover, actors, and extraction derive from encounter terrain rather than a separate scene map.

The strategy renderer’s 2.5D projection remains unchanged. Modern Ops does not reuse the 2D pixel projection directly; it reuses the same grid and DNA meaning, with a documented world transform, so every renderer agrees on occupancy, cover, and objectives.

## Asset Hints

Use the generated storefront facade texture as the authored landmark across a simple procedural storefront plane. Use restrained PBR or standard materials for wet road, concrete sidewalk, cover planters, actor proxies, and emissive extraction. Reuse existing registered assets where appropriate; do not introduce unregistered runtime paths. Keep the first slice free of GLB dependencies.

## Data Flow

`BlockModeView → prepareEncounter(block) → CombatSessionController → Modern Ops scene ↔ typed CombatCommand → CombatSnapshot/CombatEvent → CombatResult → BlockModeView.applyEncounterResult`.

Camera changes, interpolation, particles, muzzle flashes, tracer lines, pointer lock, and UI animation never enter `CombatSession`. Strategy stores and money routing never enter Babylon modules.
Loading
Loading