From 5abb6f1752bf255281c1e187243abd490252204c Mon Sep 17 00:00:00 2001 From: rebaserHEAD <38984539+rebaserHEAD@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:22:56 -0400 Subject: [PATCH] fix: markers classify by what they are, not where they draw MarkerBase (and with it every spawner and atmos-fix marker) draws at Overdoors (+10), the same depth band as doors. The layer filter bucketed purely by draw depth and only tested marker-ness inside the 0..+7 band, so every marker landed in the Doors bucket: the Doors toggle hid them all, and the Markers / Atmos Markers toggles hit nothing. Classify markers before the depth bands. The existing tests all passed depth 0, which is exactly how this slipped through; the new ones pin the real depth. --- CHANGELOG.md | 8 +++++ src/rendering/__tests__/markerLayer.test.ts | 37 +++++++++++++++++++++ src/rendering/entityRenderer.ts | 16 +++++---- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d683390..6e0792c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ workflow copies it into the GitHub release notes. ## [Unreleased] +### Fixed + +- The Markers and Atmos Markers layer toggles did nothing, and the Doors + toggle hid every marker on the map along with the doors. Markers draw in + the same depth band as doors (Overdoors), and the layer filter sorted + purely by draw depth, so all markers landed in the Doors bucket. Markers + now classify by what they are instead of where they draw. + ## [1.4.0] - 2026-07-28 ### Added diff --git a/src/rendering/__tests__/markerLayer.test.ts b/src/rendering/__tests__/markerLayer.test.ts index dfb0e9b..31f7793 100644 --- a/src/rendering/__tests__/markerLayer.test.ts +++ b/src/rendering/__tests__/markerLayer.test.ts @@ -65,6 +65,43 @@ describe('atmos markers sub-layer', () => { }); }); +/** + * MarkerBase draws at Overdoors (+10), the same depth band as doors. Markers + * must classify by what they ARE, not where they draw: at their real depth + * they must still answer to the marker toggles and never to the Doors one. + */ +describe('markers at their real depth (Overdoors, +10)', () => { + const OVERDOORS = 10; + + it('atmosMarkers off hides AtmosFix markers at +10', () => { + const layers = { ...DEFAULT_LAYER_VISIBILITY, atmosMarkers: false }; + expect(isLayerVisible(OVERDOORS, 'AtmosFixBlockerMarker', layers)).toBe(false); + }); + + it('markers off hides spawn points at +10', () => { + const layers = { ...DEFAULT_LAYER_VISIBILITY, markers: false }; + expect(isLayerVisible(OVERDOORS, 'SpawnPointLatejoin', layers)).toBe(false); + }); + + it('doors off leaves markers alone', () => { + const layers = { ...DEFAULT_LAYER_VISIBILITY, doors: false }; + expect(isLayerVisible(OVERDOORS, 'AtmosFixBlockerMarker', layers)).toBe(true); + expect(isLayerVisible(OVERDOORS, 'SpawnPointLatejoin', layers)).toBe(true); + }); + + it('doors off still hides actual doors', () => { + const layers = { ...DEFAULT_LAYER_VISIBILITY, doors: false }; + const registry = fakeRegistry({ AirlockGlass: ['Sprite', 'Door'] }); + expect(isLayerVisible(8, 'AirlockGlass', layers, registry)).toBe(false); + }); + + it('component-detected markers hide with markers off at +10', () => { + const registry = fakeRegistry({ WarpPoint: ['Marker'] }); + const layers = { ...DEFAULT_LAYER_VISIBILITY, markers: false }; + expect(isLayerVisible(OVERDOORS, 'WarpPoint', layers, registry)).toBe(false); + }); +}); + describe('isLayerVisible with the markers layer off', () => { const layers = { ...DEFAULT_LAYER_VISIBILITY, markers: false }; diff --git a/src/rendering/entityRenderer.ts b/src/rendering/entityRenderer.ts index f6b6edf..ba71902 100644 --- a/src/rendering/entityRenderer.ts +++ b/src/rendering/entityRenderer.ts @@ -159,16 +159,18 @@ export function isLayerVisible( layers: LayerVisibility, registry?: IPrototypeRegistry, ): boolean { + // Markers are a semantic category, not a depth band: MarkerBase (and with it + // the whole spawner family) draws at Overdoors (+10), so depth-first + // bucketing would file every marker under Doors. Classify them before depth. + // AtmosFix markers hide with either switch: they are markers, and they + // also have their own toggle so spawn points can stay visible alone. + if (isAtmosFixPrototype(prototype, registry)) return layers.markers && layers.atmosMarkers; + if (isMarkerPrototype(prototype, registry)) return layers.markers; + if (drawDepthValue <= -13) return layers.subfloor; if (drawDepthValue <= -5) return layers.floorObjects; if (drawDepthValue <= -1) return layers.structures; - if (drawDepthValue <= 7) { - // AtmosFix markers hide with either switch: they are markers, and they - // also have their own toggle so spawn points can stay visible alone. - if (isAtmosFixPrototype(prototype, registry)) return layers.markers && layers.atmosMarkers; - if (isMarkerPrototype(prototype, registry)) return layers.markers; - return layers.objects; - } + if (drawDepthValue <= 7) return layers.objects; if (drawDepthValue <= 10) return layers.doors; return layers.objects; // effects, ghosts, overlays }