From d30385fc56eef6320d25bf34845c6889311a2af2 Mon Sep 17 00:00:00 2001 From: Evan Pelle Date: Sat, 20 Jun 2026 03:35:05 +0000 Subject: [PATCH] Add structure dots toggle to graphics settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an on/off toggle in the graphics settings modal's Structure Icons section that controls whether structures collapse into small dots when zoomed out. When disabled, applyGraphicsOverrides forces the renderer's structure.dotsZoomThreshold to 0 — since zoom is always > 0, the dots LOD never triggers and structures keep their full icon at every zoom level. The debug GUI already exposes the underlying dotsZoomThreshold slider for fine control; this surfaces a simple player-facing toggle. Co-Authored-By: Claude Opus 4.8 --- resources/lang/en.json | 2 ++ .../hud/layers/GraphicsSettingsModal.ts | 28 +++++++++++++++++++ src/client/render/gl/GraphicsOverrides.ts | 3 ++ src/client/render/gl/RenderOverrides.ts | 5 ++++ 4 files changed, 38 insertions(+) diff --git a/resources/lang/en.json b/resources/lang/en.json index 353f6f420..4e7f31793 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -568,6 +568,8 @@ "section_name_labels": "Name Labels", "section_structure_icons": "Structure Icons", "section_terrain": "Terrain", + "structure_dots_desc": "Collapse structure icons into small dots when zoomed out", + "structure_dots_label": "Structure dots", "territory_alpha_desc": "How opaque the territory fill is (lower lets terrain show through)", "territory_alpha_label": "Territory opacity", "territory_sat_desc": "How vivid the territory fill colors are (lower mutes them)", diff --git a/src/client/hud/layers/GraphicsSettingsModal.ts b/src/client/hud/layers/GraphicsSettingsModal.ts index d0b65abac..a7b443aa2 100644 --- a/src/client/hud/layers/GraphicsSettingsModal.ts +++ b/src/client/hud/layers/GraphicsSettingsModal.ts @@ -455,6 +455,14 @@ export class GraphicsSettingsModal extends LitElement implements Controller { this.patchStructure({ classicNumbers: !this.currentClassicNumbers() }); } + private currentShowDots(): boolean { + return this.userSettings.graphicsOverrides().structure?.showDots ?? true; + } + + private onToggleShowDots() { + this.patchStructure({ showDots: !this.currentShowDots() }); + } + private patchPassEnabled(patch: Partial) { const current = this.userSettings.graphicsOverrides(); this.userSettings.setGraphicsOverrides({ @@ -563,6 +571,7 @@ export class GraphicsSettingsModal extends LitElement implements Controller { const iconSize = this.currentIconSize(); const classicIcons = this.currentClassicIcons(); const classicNumbers = this.currentClassicNumbers(); + const showDots = this.currentShowDots(); const highlightFill = this.currentHighlightFill(); const highlightBrighten = this.currentHighlightBrighten(); const highlightThicken = this.currentHighlightThicken(); @@ -880,6 +889,25 @@ export class GraphicsSettingsModal extends LitElement implements Controller { + +
diff --git a/src/client/render/gl/GraphicsOverrides.ts b/src/client/render/gl/GraphicsOverrides.ts index 021450c6a..d5eb1a25a 100644 --- a/src/client/render/gl/GraphicsOverrides.ts +++ b/src/client/render/gl/GraphicsOverrides.ts @@ -17,6 +17,9 @@ export const GraphicsOverridesSchema = z iconSize: z.number(), classicIcons: z.boolean(), classicNumbers: z.boolean(), + // When false, structures keep their full icon at any zoom instead of + // collapsing to dots when zoomed out (forces dotsZoomThreshold to 0). + showDots: z.boolean(), }) .partial(), mapOverlay: z diff --git a/src/client/render/gl/RenderOverrides.ts b/src/client/render/gl/RenderOverrides.ts index 5d53883e5..25ee3e158 100644 --- a/src/client/render/gl/RenderOverrides.ts +++ b/src/client/render/gl/RenderOverrides.ts @@ -41,6 +41,11 @@ export function applyGraphicsOverrides( if (overrides.structure?.classicNumbers !== undefined) { settings.structureLevel.classicFont = overrides.structure.classicNumbers; } + if (overrides.structure?.showDots === false) { + // Zoom is always > 0, so a threshold of 0 means the dots LOD never + // triggers — structures stay as full icons at every zoom level. + settings.structure.dotsZoomThreshold = 0; + } if (overrides.mapOverlay?.highlightFillBrighten !== undefined) { settings.mapOverlay.highlightFillBrighten = overrides.mapOverlay.highlightFillBrighten;