Update & refactor dark mode (#4114)

## Description:

- The renderer no longer knows what "dark mode" is.
`RenderSettings.dayNight.mode` (`"light" | "dark"`) is gone — passes
read neutral values (`lighting.ambient: number`, `lighting.enabled:
boolean`).
- `render-settings.json` holds the light-mode baseline. Dark mode is
just another override layer, applied the same way as graphics settings
(`darkNames`, `classicIcons`, etc.).
- New `src/client/render/gl/RenderOverrides.ts` exposes two in-place
mutators with matching shapes:
- `applyGraphicsOverrides(settings, overrides)` — replaces the old
`generateRenderSettings`
  - `applyDarkModeOverride(settings, isDark)`
- `ClientGameRunner` regenerates the live settings each time the user
setting changes via `deepAssign(live, createRenderSettings())` + the
override chain. No per-slice copy list, no intermediate object — adding
a new override that touches a new section just works.
- Renamed `dayNight` → `lighting`; collapsed `nightAmbient`/`dayAmbient`
into single `ambient`; renamed `enableLightCompositing` → `enabled`.
- Bumped dark-mode ambient from 0.15 → 0.35 so terrain stays readable.

<img width="1250" height="846" alt="Screenshot 2026-06-02 at 11 47
28 AM"
src="https://github.com/user-attachments/assets/b41e8ffb-6011-4ba0-9e1f-c2a21ff90794"
/>

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-06-02 11:48:52 -07:00
committed by GitHub
parent 2386b4b38a
commit f1045a2022
12 changed files with 125 additions and 125 deletions
+15 -21
View File
@@ -69,8 +69,11 @@ import { createCanvas } from "./Utils";
import { WebGLFrameBuilder } from "./WebGLFrameBuilder";
import { createRenderer, GameRenderer } from "./hud/GameRenderer";
import {
applyDarkModeOverride,
applyGraphicsOverrides,
createDebugGui,
generateRenderSettings,
createRenderSettings,
deepAssign,
GameView as WebGLGameView,
} from "./render/gl";
import { ALL_UNIT_TYPES, UnitState } from "./render/types";
@@ -474,18 +477,6 @@ async function createClientGame(
config,
);
// Bind the WebGL renderer's day/night mode to the existing darkMode
// UserSetting so the in-game map matches the rest of the UI. Initial
// apply + live updates via the per-key settings-changed event.
const applyDayNightMode = (isDark: boolean): void => {
view.getSettings().dayNight.mode = isDark ? "dark" : "light";
};
applyDayNightMode(userSettings.darkMode());
globalThis.addEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:${DARK_MODE_KEY}`,
(e) => applyDayNightMode((e as CustomEvent<string>).detail === "true"),
);
view.setShowPatterns(userSettings.territoryPatterns());
globalThis.addEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:settings.territoryPatterns`,
@@ -493,18 +484,21 @@ async function createClientGame(
);
const graphicsListenerAbort = new AbortController();
const applyGraphicsOverrides = (): void => {
const generated = generateRenderSettings(
userSettings.graphicsOverrides(),
);
const regenerateRenderSettings = (): void => {
const live = view.getSettings();
Object.assign(live.name, generated.name);
Object.assign(live.structure, generated.structure);
deepAssign(live, createRenderSettings());
applyGraphicsOverrides(live, userSettings.graphicsOverrides());
applyDarkModeOverride(live, userSettings.darkMode());
};
applyGraphicsOverrides();
regenerateRenderSettings();
globalThis.addEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:${GRAPHICS_KEY}`,
applyGraphicsOverrides,
regenerateRenderSettings,
{ signal: graphicsListenerAbort.signal },
);
globalThis.addEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:${DARK_MODE_KEY}`,
regenerateRenderSettings,
{ signal: graphicsListenerAbort.signal },
);