mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-04-05 06:57:24 +02:00
- Added compatibility lookups for legacy single-SVG callers to ensure existing workflows function during migration to new architecture. - Implemented `getLayerSvg`, `getLayerSurface`, and `queryMap` functions as stable globals. - Migrated relevant code in `draw-state-labels.ts` to utilize the new `queryMap` function for scene-aware lookups. - Updated `layers.js` to manage layer visibility and registration more effectively. - Introduced `LayersModule` to handle layer registration, visibility, and ordering. - Created `WebGLSurfaceLayer` and `SvgLayer` classes to encapsulate layer behavior. - Refactored `TextureAtlasLayer` to utilize the new layer management system. - Updated HTML structure to accommodate new SVG and canvas elements. - Ensured all TypeScript checks pass with zero errors on modified files.
7.2 KiB
7.2 KiB
Story 1.3: Add Layers Registry as the Ordering Source of Truth
Status: in-progress
Story
As a map maintainer, I want a centralized Layers registry, so that visibility, order, and surface ownership are managed consistently instead of inferred from DOM position.
Acceptance Criteria
- Given logical map layers currently rely on DOM placement and ad hoc lookups, when a layer is registered, then the registry stores its
id,kind,order,visiblestate, and surface handle, and callers can query layer state without inferring it from DOM order. - Given runtime layer order changes, when reorder operations are applied through the registry, then all registered layer surfaces receive the updated ordering atomically, and the registry remains the single source of truth for visibility and order.
Tasks / Subtasks
- Create the Layers registry module.
- Define the minimum record shape:
id,kind,order,visible,surface. - Expose lookup and mutation APIs that are narrow enough to become the single ordering contract.
- Define the minimum record shape:
- Bootstrap the current layer stack into the registry.
- Register the existing logical SVG layers in their current order.
- Register the current WebGL surface path so mixed rendering already has a place in the model.
- Move order and visibility mutations behind the registry.
- Replace direct DOM-order assumptions in the layer UI reorder path with registry updates.
- Apply visibility changes through the registry without changing user-facing controls.
- Ensure one coordinated apply step updates all affected surfaces together.
- Preserve compatibility for migration-era callers.
- Keep existing layer IDs and toggle IDs stable.
- Avoid forcing feature modules to understand renderer-specific ordering logic.
- Perform manual smoke verification.
- Reordering through the existing Layers UI still changes the visible stack correctly.
- Visibility toggles still map to the correct runtime surface.
Dev Notes
Context Summary
- The current reorder path is still DOM-driven.
public/modules/ui/layers.jsmaps toggle IDs to concrete DOM groups ingetLayer(id)and then callsinsertAfterorinsertBeforedirectly inmoveLayer. - The initial stack order is created in
public/main.jsby appending groups toviewboxin sequence. Older-map migration code inpublic/modules/dynamic/auto-update.jsalso inserts groups relative to concrete siblings such as#terrainand#borders. - The registry has to become the source of truth without breaking those legacy IDs immediately. This story is about authoritative state ownership, not yet about fully removing all DOM-based insertion helpers.
Technical Requirements
- Implement the registry in
src/as a global module, likelysrc/modules/layers.ts. - Keep the public contract minimal. Do not add export metadata yet; that belongs to Epic 4.
- Store actual surface handles, not just selectors, so later stories can mount independent SVG shells and WebGL surfaces under one contract.
- Ensure reorder application is atomic from the user perspective. Avoid partial states where one surface has moved and another has not.
- Keep the registry boring. No factory layers, schema systems, or speculative metadata beyond
id,kind,order,visible, andsurface.
Architecture Compliance
- This story implements Decision 1 from the architecture: the Layers registry is the single source of truth for ordering and visibility.
- The runtime must support arbitrary future ordering of SVG and WebGL layers. Do not hard-code separate ordering buckets.
- The registry should own state; individual layer modules should not infer state from the DOM.
Previous Story Intelligence
- Story 1.1 introduces stable runtime hosts; the registry should refer to those hosts rather than embedding DOM queries in each layer record.
- Story 1.2 centralizes shared transform state; do not mix camera ownership into the registry API.
- The current sortable UI already maps toggle IDs to concrete layer IDs in
getLayer(id). Preserve those IDs so Story 1.5 can bridge legacy callers cleanly.
Project Structure Notes
- Expected touch points:
src/modules/layers.tssrc/modules/index.tssrc/types/global.tspublic/modules/ui/layers.jspublic/main.jspublic/modules/dynamic/auto-update.js
- Keep migration focused. Do not rewrite every legacy caller in this story.
- Keep the registry implementation in
src/and expose only the smallest legacy-facing hooks needed inpublic/modules/ui/layers.js.
Testing Notes
- Manual verification is sufficient for this tranche.
- Verify the existing sortable Layers UI still works and that no layer disappears from the visible stack after a reorder.
- Do not add Playwright coverage or new automated test infrastructure in this story.
Dependencies
- Story 1.1 provides runtime host references.
- Story 1.2 provides the shared Scene contract that registry-managed surfaces will consume.
References
- [Source: _bmad-output/planning-artifacts/epics.md, Epic 1, Story 1.3]
- [Source: _bmad-output/planning-artifacts/architecture-layered-map-dom-split.md, Decision 1, Decision 2, Migration Plan]
- [Source: public/modules/ui/layers.js,
moveLayerandgetLayer] - [Source: public/main.js, layer append order]
- [Source: public/modules/dynamic/auto-update.js, compatibility inserts relative to existing siblings]
Dev Agent Record
Agent Model Used
GitHub Copilot (Claude Sonnet 4.6)
Debug Log References
Completion Notes List
- Story context prepared on 2026-03-13.
- Implementation completed 2026-03-13.
- Created
src/modules/layers.ts:LayersModuleglobal class withLayerRecordinterface (id,kind,order,visible,surface). Exportsregister(),get(),getAll(),moveAfter(),moveBefore(),setVisible(). DOM sync is atomic — one element move per call. Registered onwindow.Layers. - Added
import "./layers"tosrc/modules/index.ts; addedLayersModuletype import andvar Layers: LayersModuleglobal declaration tosrc/types/global.ts. - In
public/main.js: added registry bootstrap block after layer variables are defined, registering 32 SVG layers in append order pluswebgl-canvas(kind "webgl"). Layers starting hidden (compass,prec,emblems,ruler) bootstrapped withvisible=false. - In
public/modules/ui/layers.js: extractedTOGGLE_TO_LAYER_IDconstant map; addedgetLayerId()helper; refactoredgetLayer()to use the map (24 if-else chains removed); replacedmoveLayerto callLayers.moveAfter()/Layers.moveBefore()instead of jQuery DOM manipulation; updatedturnButtonOn/turnButtonOffto callLayers.setVisible(); updatedapplyLayersPresetto callLayers.setVisible()per layer. auto-update.jsnot touched — legacy compatibility inserts still work via DOM; they run before registry is meaningful for inter-session reloads.- Automated tests skipped per project instruction. Manual smoke verification pending.
File List
- src/modules/layers.ts (new)
- src/modules/index.ts (modified)
- src/types/global.ts (modified)
- public/main.js (modified)
- public/modules/ui/layers.js (modified)