From 6afa3e48f53dd7ba0fb199fb97aab741c977b362 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 22 Jun 2026 12:58:30 -0700 Subject: [PATCH] Add structure dots toggle to graphics settings (#4356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Adds an on/off **Structure dots** toggle to the graphics settings modal (Structure Icons section), controlling whether structures collapse into small dots when zoomed out. ## How The renderer already gates the dots LOD on `structure.dotsZoomThreshold` (structures become dots when `zoom <= threshold`). The debug GUI exposes that threshold as a slider; this surfaces a simple player-facing toggle: - `GraphicsOverrides.ts` — adds `structure.showDots` (boolean) to the override schema. - `RenderOverrides.ts` — when `showDots === false`, `applyGraphicsOverrides` sets `dotsZoomThreshold = 0`. Since zoom is always > 0, the dots LOD never triggers, so structures keep their full icon at every zoom. When enabled (default), the threshold is left untouched. - `GraphicsSettingsModal.ts` — toggle button mirroring the existing Classic icons / Classic level numbers toggles; defaults to On. - `en.json` — `structure_dots_label` / `structure_dots_desc`. The change applies live: a `settings.graphics` change re-runs `applyGraphicsOverrides` onto the live settings object the passes read each frame, and `dotsZoomThreshold` is a per-frame uniform. ## Testing - `tsc --noEmit` clean. - Verified in a headless solo game: the toggle renders (default On), flipping it persists `structure.showDots = false`, and `applyGraphicsOverrides` yields `dotsZoomThreshold` 1.2 when on / 0 when off. 🤖 Generated with [Claude Code](https://claude.com/claude-code) 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 63091b117..4dc9adff9 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -564,6 +564,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 8b2102aa3..b6e5720e0 100644 --- a/src/client/hud/layers/GraphicsSettingsModal.ts +++ b/src/client/hud/layers/GraphicsSettingsModal.ts @@ -485,6 +485,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({ @@ -593,6 +601,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(); @@ -911,6 +920,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 b697e2d24..f18a3b1df 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 001c9ca7d..4219c70b9 100644 --- a/src/client/render/gl/RenderOverrides.ts +++ b/src/client/render/gl/RenderOverrides.ts @@ -42,6 +42,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;