Integrate analytic dungeon systems into rules layer#16
Integrate analytic dungeon systems into rules layer#16
Conversation
…nability Refactor main orchestration into modular helpers
…, repoint ecs-lib
…n-simulation-iwvzyn Render analytic demo dungeon with FOV overlays
…y-items Show pickup tooltip within reach
…-mechanics Improve overlay interactions and movement
…iptref Refactor rules scripting to use shared ScriptRef
…th-emissive-torches Add emissive torch lighting with occlusion
…add-lightning-spell-mechanic Add lightning gesture casting and improve movement
wooden bow + projectile
…hanics Fix touch targeting and ranged ammo handling
…ctional-movement Add grid-based movement and wall glyph rendering
…le-for-passageway Add demo entry door and shrink player collision radius
There was a problem hiding this comment.
Pull Request Overview
This PR integrates analytic dungeon systems into the rules layer, enabling multi-floor dungeon support with deterministic portal traversal, kernel caching, and cross-floor lighting propagation.
- Moves analytic dungeon kernel, portal registry, and cache implementations into
src/rules/analyticwith pure-JS utilities - Adds ECS components (
FloorRef,PortalV,PortalTrace,GeomHandle,FloorState,LightingAccelHandle,DungeonLevel) and reusable systems (portal use, kernel prewarm, lighting bake, floor activation) - Ports regression test suites to validate round-trip traversal and cross-floor lighting with an ECS harness helper
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/helpers/ecsHarness.mjs | New test ECS harness with component definition, system registry, scheduler composition, and world management |
| tests/analytic/test-roundtrip.mjs | Regression test validating deterministic round-trip portal traversal with drift tolerance checks |
| tests/analytic/test-fov-lighting.mjs | Test suite for cross-floor lighting propagation through portals with visibility attenuation |
| src/rules/systems/portalUseSystem.js | System handling portal traversal detection, floor changes, and PortalTrace management for round-trip returns |
| src/rules/systems/lightingBakeSystem.js | Maintains lighting acceleration structures synchronized with analytic kernels |
| src/rules/systems/kernelPrewarmSystem.js | Pre-warms analytic kernels near portals to avoid traversal stalls |
| src/rules/systems/geomKernelSystem.js | Ensures analytic kernels are available and synchronized per floor |
| src/rules/systems/floorActivationSystem.js | Tracks active dungeon floors and records pause metadata |
| src/rules/components/index.js | Exports new analytic dungeon components |
| src/rules/components/PortalV.js | Component for vertical portals connecting floors with transform validation |
| src/rules/components/PortalTrace.js | Ephemeral component tracking portal entry/exit for deterministic round-trips |
| src/rules/components/PortalH.js | Component for same-floor portals (doors, gates) |
| src/rules/components/LightingAccelHandle.js | Handle component for cached lighting acceleration data |
| src/rules/components/GeomHandle.js | Handle component for cached analytic kernel references |
| src/rules/components/FloorState.js | Component storing floor state hashes for kernel invalidation |
| src/rules/components/FloorRef.js | Component identifying which dungeon floor an entity occupies |
| src/rules/components/DungeonLevel.js | Component aggregating floor IDs and active floor selection |
| src/rules/analytic/lightingAccel.js | Lighting acceleration structures and portal light propagation logic |
| src/rules/analytic/kernelCache.js | LRU cache for analytic kernels with hot-set marking |
| src/rules/analytic/index.js | Exports for analytic dungeon module |
| src/rules/analytic/analyticDungeon.js | Core analytic dungeon kernel with 2D geometry primitives, portal registry, and raycast/sweep operations |
| app/rules/scheduler.js | Integrates analytic dungeon systems into main game scheduler |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for (const entry of iterator) { | ||
| const entity = entry[0]; | ||
| const floorRef = entry[1]; | ||
| const position = entry[2] ?? entry[1 + (facingComponent ? 1 : 0)]; |
There was a problem hiding this comment.
The fallback logic entry[1 + (facingComponent ? 1 : 0)] always evaluates to entry[2] when facingComponent is truthy and entry[1] when falsy, which means the fallback is redundant and confusing. If facingComponent is provided, entry[2] is already position from the query, so the fallback should just be entry[2].
| const position = entry[2] ?? entry[1 + (facingComponent ? 1 : 0)]; | |
| const position = entry[2]; |
| position.y = exitPos.y; | ||
|
|
||
| if (facingState && typeof portal.arrivalFacing === "number") { | ||
| facingState.facing = portal.arrivalFacing; |
There was a problem hiding this comment.
Type mismatch: The Facing component has fields x and y (vector components), but this code attempts to set a scalar facing field. The arrivalFacing in PortalV is a scalar angle (0.0 default), but the Facing component expects a vector. This will either create an incorrect field or fail to update the facing direction properly. Convert the angle to a unit vector: facingState.x = Math.cos(portal.arrivalFacing); facingState.y = Math.sin(portal.arrivalFacing);
| facingState.facing = portal.arrivalFacing; | |
| facingState.x = Math.cos(portal.arrivalFacing); | |
| facingState.y = Math.sin(portal.arrivalFacing); |
Summary
Testing
Codex Task