-
Notifications
You must be signed in to change notification settings - Fork 0
Integrate analytic dungeon systems into rules layer #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Integrate analytic dungeon systems into rules layer #16
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)]; |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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