Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions src/rendering/__tests__/markerLayer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down
16 changes: 9 additions & 7 deletions src/rendering/entityRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Loading