C2-64B: J: "C:\xampp-8.1.6-0\projects\ge.4.test\ge.4.test Archives\ge.4.test 2026-0706-1913-3359 (AUTOMATIC GE GAMES BACKUP + C2-66A - GE - Dungeon - CSV Optimization - Wip).zip" ge.4.test 2026-0706-1913-3359 (AUTOMATIC GE GAMES BACKUP + C2-66A - GE - Dungeon - CSV Optimization - Wip).zip Zip Archive 1. Automatically Set all actors as Inert that are twice beyond each dimension of the view portal. 2. Automatically unset Inert from all actors that are within each dimension of the view portal. 3. When cycling thru actor templates, skip all that are set as Inert. Ariel: I’ll patch this as the next Dungeon delta from the uploaded C2-66A backup: inspect the active actor/viewport/template code, apply the Inert distance gating, then repack only changed files plus a README. I found the existing C2-65 inert stack. I’m going to layer this as a C2-66B viewport-distance inert gate rather than disturbing actor position/post restoration logic. J: Don't forget, some actors have width/height flags. Ariel: Good catch. I’ll include actor footprint flags in both sides of the gate: wider/taller actors should stay active while any part of their region is within the portal dimensions, and only go Inert once the full region is safely beyond the outer threshold. I’m using the actor region helper path already in C2-65B/C2-64O. The new gate will work from the actor’s full occupied rectangle, not just its origin tile. The width/height path is present, so I’m not adding a duplicate region system. I’m patching the existing runtime Inert modules to use actorOccupiedCells() as the source of truth. Thought for 15m 24s Done — C2-66B delta is ready. Download the C2-66B Dungeon Viewport Inert Gate delta Changed: DungeonInertConditions.js DungeonInertPostViewGuard.js Added README Implemented: Actors become runtime Inert only when their full occupied region is beyond the expanded View Portal gate. Runtime Inert clears when any occupied actor cell intersects the current View Portal. Width/height actor flags are honored through the existing actorOccupiedCells() / region helper path. Actor template cycling and Auto-Walk arming skip actors that remain Inert while outside the visible portal. Player Unit actors remain protected. No obsoletion script needed. Validated: node --check passed for both changed JS files. Zip integrity passed. A minimal mock test verified far actor inerting, visible actor un-inerting, and template skipping. C2-66C: J: This time around: 1. Have any non-Inert Actor outside the View Portal flag as Inert. 2. Have any Inert Actor inside the View Portal not flag as Inert. 3. Skip conditions processing for all Inert Actors. Ariel: I’ll revise this as the next serial delta, tightening the logic to pure View Portal membership: outside means runtime Inert, inside means not Inert, and condition evaluation should early-skip inert actors. I’ve narrowed the change: C2-66B still had the “twice beyond View Portal” buffer. I’m removing that buffer entirely so the View Portal itself is now the activation boundary. Thought for 2m 35s Done — C2-66C delta is ready. Download the C2-66C Dungeon Direct Viewport Inert Gate delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js public/alpha/Dungeon/2D/js/DungeonInertPostViewGuard.js Added README Implemented: Any non-player-unit actor fully outside the View Portal now receives runtime Inert. Any runtime-Inert actor whose occupied region intersects the View Portal now clears runtime Inert. Conditions processing filters out all actors that are still Inert. Actor width/height/region flags are honored through actorOccupiedCells() and the existing region fallback path. Removed the C2-66B “twice beyond View Portal” buffer behavior. Validated: node --check passed for both changed JS files. Zip integrity passed. Mock runtime test passed for outside inerting, inside inert clearing, wide actor viewport intersection, persistent inert condition-skip, and condition actor filtering. No obsoletion script needed. C2-66D: J: Inert-toggling should be per tick, not animation frame. Ariel: I’ll make this the next serial delta and move the viewport Inert reconcile off render/animation-frame hooks onto the engine tick path, so it runs once per logical tick. The remaining frame-driven behavior is from per-call refreshes in template/processing checks, especially during render/template cycling. I’m converting those checks to consume the last tick snapshot instead of recomputing visibility immediately. J: All conditions should process per tick, not continuously. Ariel: Understood. I’ll treat both viewport Inert reconciliation and all condition evaluation as logical-tick work only: no render-loop, animation-frame, hover/template, or continuous polling side effects. J: GE Cursor should update per animation frame. Ariel: Got it: gameplay state changes stay tick-driven, while GE Cursor remains frame-driven for smooth visual input. I’ll keep cursor rendering/movement out of the condition/Inert tick throttle. I found the prior delta still recomputes Inert in template/processing paths. I’m changing those to read the last logical tick snapshot, while leaving pollGamepad() and cursor hover updates in the frame loop. //// J: GE Cursor should update per animation frame. //// Ariel: Got it: gameplay state changes stay tick-driven, while GE Cursor remains frame-driven for smooth visual input. I’ll keep cursor rendering/movement out of the condition/Inert tick throttle. Ariel: Yes — I’m preserving that split exactly: GE Cursor stays animation-frame based, but conditions and viewport Inert reconciliation move to the logical tick cadence only. I’m treating your quoted exchange as the acceptance rule: GE Cursor update stays in the frame loop, but any GE condition recomputation, actor-condition processing, and Inert flips are tick-gated. The patch is now using a cached per-tick condition snapshot. Frame-time paths like template lookup can skip an actor based on the last tick, but they no longer flip Inert or update GE conditions themselves. Thought for 11m 36s Done — C2-66D delta is ready. Download the C2-66D Dungeon Tick Conditions Inert Gate delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js Added README Implemented: View Portal Inert toggling now happens only during the logical condition tick. Actor/world condition processing now runs at most once per logical tick. Inert actors are skipped during actor-condition processing. Template/frame-time paths use the last tick snapshot and no longer flip Inert or update GE condition skip counters. GE Cursor polling/hover behavior remains per animation frame. Validated: node --check passed. Zip integrity passed. Mock test passed for tick-gated conditions, tick-gated Inert toggling, wide actor footprint visibility, and frame-driven GE Cursor updates. C2-66E: J: This hangs badly: http://ge.4.test/alpha/Dungeon/2D/?dungeon=025 Ariel: I’ll produce a follow-up fix delta against the current C2-66D state. The likely hang point is condition/Inert tick recursion or scanning too much every tick on Map 025, so I’ll inspect the patched condition gate first and throttle/fix the hot path without changing GE Cursor frame updates. The hot spots are clearer now: the C2-66D tick wrapper can re-enter before it records the tick as processed, and the viewport test still walks every occupied cell for region actors. I’m fixing both so Map 025 doesn’t explode on its skull/alcove region actors. Thought for 3m 34s Done — C2-66E hang-fix delta is ready. Download the C2-66E Dungeon Tick Gate Hang Fix delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js Added README Fixed: Removed the expensive per-cell View Portal scan for wide/tall region actors. View Portal membership now uses fast rectangle intersection while still honoring actor width/height/region flags. Suppressed same-tick recursive actor/world condition processing. Conditions and Inert toggling remain logical-tick only. GE Cursor frame updates remain untouched. Validated: node --check passed. Zip integrity passed. Mock test passed for: frame-based GE Cursor updates, tick-only actor/world condition processing, recursive condition re-entry suppression, visible actor Inert clearing, outside actor Inert setting, wide/huge actor region checks without expensive occupied-cell enumeration. No obsoletion script needed. C2-66F: J: Divide the map into 8x8 sections on load, and store a unique Actor list per their populated section. Then have the engine only process the visible sections. Ariel: I’ll make this C2-66F on top of the latest C2-66E delta: add an 8×8 actor section index at map load time, then restrict tick-side condition/Inert processing to sections intersecting the View Portal. The section index is now in the patched file: each actor is assigned to every 8×8 section its full region overlaps, so width/height actors are included in all touched sections without duplicates. J: I meant there should be a unique actor list per 8x8 section Ariel: Yes — I’ll enforce uniqueness per section specifically: each 8×8 section owns a de-duplicated actor list. A large actor may appear in multiple overlapped sections, but never more than once inside the same section list. J: Also, actors must be able to move from one 8x8 section to the next. Ariel: I’ll add incremental section migration: the index is seeded on load, but each moving/processed actor can be re-keyed into its current 8×8 section set as it crosses boundaries. Thought for 8m 50s Done — C2-66F delta is ready. Download the C2-66F Dungeon Actor Section Processing delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js Added README Implemented: Map actors are indexed into 8×8 sections on load. Each section stores its own unique actor list. Width/height actor regions can occupy multiple sections, but only once per section. Actors can migrate from one 8×8 section list to another as they move. The section index supports incremental per-actor re-keying. The section index also rebuilds on the next logical tick when the engine spatial revision changes. Condition ticks operate against visible 8×8 sections, plus Player Unit actors. Runtime Inert reconciliation uses current visible sections plus the previous visible section set for departure cleanup. GE Cursor remains animation-frame driven. Validated: node --check passed. Zip integrity passed. Mock runtime test passed for section indexing, unique per-section lists, wide actor overlap, actor migration, revision-triggered section rebuild, load-time Inert seeding, visible-section condition context, newly visible actor activation, previous-visible actor retirement, and Player Unit retention. No obsoletion script needed. C2-66G: J: Skip processing sections that are not visible. Ariel: I’ll make this the next serial delta on top of C2-66F: visible sections should be the only section buckets iterated for actor condition work, with no fallback pass across hidden buckets. I found the remaining hidden-section work: C2-66F kept the previous visible section set in the reconcile pass for departure cleanup. I’m removing that hidden-section carryover so ticks use current visible buckets only. Thought for 1m 41s Done — C2-66G delta is ready. Download the C2-66G Dungeon Visible Section Only Processing delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js Added README Implemented: Logical ticks now process only the current visible 8×8 section buckets. Removed the previous-visible-section cleanup pass from tick processing. Hidden/non-visible section buckets are no longer iterated during condition/Inert ticks. Section lists remain unique per 8×8 section. Width/height actors still populate every overlapped section once. Actors can still migrate between sections as they move. GE Cursor frame updates remain untouched. Validated: node --check passed. Zip integrity passed. Mock runtime test passed for visible-section-only processing, hidden section skipping, actor migration, wide actor uniqueness, and visible actor activation. No obsoletion script needed. C2-66H: J: Alcove Passages fail to Mask Radius properly. Ariel: I’ll make this C2-66H. Since the section-only optimization can accidentally exclude Mask source/target actors outside the currently visible buckets, I’ll inspect the Mask Radius path and keep the tick optimization while making contiguous Alcove/Skull passages reveal correctly. The failure is likely from C2-66G’s temporary visible-section this.actors context leaking into mask overlap/source discovery. Mask Radius should still discover the player’s exact overlap source from the full actor set, even though condition processing remains visible-section-only. Thought for 3m 4s Done — C2-66H delta is ready. Download the C2-66H Dungeon Mask Radius Full Actor Source delta Changed: public/alpha/Dungeon/2D/js/DungeonInertConditions.js Added README Fixed: Alcove/Skull Passage Mask Radius source discovery now uses the full actor set, even while condition processing is temporarily limited to visible 8×8 sections. This preserves C2-66G’s visible-section-only actor condition processing. The full-list mask lookup restores the previous actor context and spatial-index cache immediately afterward. Width/height actor regions still use the existing region-aware occupancy path. GE Cursor frame updates remain untouched. Validated: node --check passed. Zip integrity passed. Mock runtime test passed for Alcove Passage Mask Radius lookup from a section-limited actor context, context restoration, spatial-index restoration, and mask condition update behavior. No obsoletion script needed. C2-66I: J: Alcove/Skull passages should be tiles with Mask: Radius 1.6 and Blocking 0 in the legend. Not actors. Alcove/Skull passages should be tiles with Mask: Radius 1.6 and Blocking 0 in the legend with ZIndex 3. Not actors. Ariel: I’ll revise this as C2-66I: move Alcove/Skull passage Mask data into tile legend definitions (Mask: Radius: 1.6, Blocking: 0, ZIndex: 3) and remove the actor-based assumption from the previous mask fix. This changes the model more than the previous C2-66H fix: the Mask source and the masked drawing target both need to come from legend.csv/map cells, not actor.csv. I’m patching both the Map 025 data and the tile mask runtime path. J: Make a custom tile that has an Actor index assigned to it. Actors should link directly from their tile, not directly from their actor id. Ariel: Got it. I’ll fold that into C2-66I: Alcove/Skull passages become tile-driven Mask/ZIndex/Blocking data, and the custom tile will carry an Actor index link so actor behavior is resolved through the map tile rather than direct actor-id lookup. J: Actor tiles should be a second tile layer. Ariel: Memory updated Understood — Actor tiles should not replace the terrain/passsage tile. I’ll treat them as a second tile layer: base tile layer holds Alcove/Skull Mask/Blocking/ZIndex, actor-tile layer links to actor indexes. Thought for 2m 49s I’m making the actor-tile layer optional and data-driven: map.csv remains base terrain/passages, while a new second layer maps tile cells to actor indexes. That keeps terrain Mask tiles independent from actor placement. Done — C2-66I delta is ready. Download the C2-66I Dungeon Tile Mask Actor Layer delta Changed: public/alpha/Dungeon/2D/js/Dungeon.js Updated maps: 002, 006, 007, 016, 019, 020, 025 Added actor-map.csv second-layer actor tile files for those maps Updated README Implemented: Alcove/Skull passages are now tile-driven, not actor-driven. Passage legend tiles use: Mask: Passage Mask Radius: 1.6 Blocking: 0 ZIndex: 3 Mask Mode: transparency Contiguous passage tile groups generate unique Mask component IDs automatically. Skull and Alcove passage tiles can participate in the same contiguous Mask group. Player Unit exact logical overlap with a Mask tile activates that tile group’s Mask Radius. Proximity alone does not activate Mask Radius. Actor tiles are now supported as a second tile layer via actor-map.csv. actor-map.csv cells contain exact Actor indexes; -1/blank means no actor. Actors are placed from their linked actor tile on load. The actor tile layer syncs as actors move. Data cleanup: Removed Skull Passage actor rows from the affected maps. Removed the Map 025 Alcove Passage actor row. Converted their map cells to passage tile IDs instead. Validated: node --check passed for Dungeon.js. CSV counts and dimensions validated. Zip integrity passed. No obsoletion script needed.