mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 12:44:37 +00:00
Feature/colorblind mode (#4150)
**Add approved & assigned issue number here:** Resolves #2549 ## Description: Adds colorblind mode. Similar to dark mode, it exists as a toggle in settings. When enabled, it swaps the game's theme (which is refactored to extend from a theme base class) to use more colorblind-friendly colors and brightness variations. Borders are darkened, and terrarin is separated by lightness. Friendly/Foe colors and switched to blue/orange instead of red/green. The theme refactor supports adding new themes without having to reimplement the color distribution system. New themes can extend the BaseTheme and supply the data, such as palettes, team-color variations, and terrain. New setting: <img width="880" height="273" alt="Screenshot 2026-06-04 at 11 30 27 AM" src="https://github.com/user-attachments/assets/d5d573d5-cc64-4ac1-95c2-00627faf17cc" /> New color palette: <img width="1119" height="757" alt="Screenshot 2026-06-04 at 11 30 59 AM" src="https://github.com/user-attachments/assets/2bb15bc9-992b-41ae-ab0e-b01fe0c3c6bb" /> ## 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: jetaviz
This commit is contained in:
@@ -35,6 +35,11 @@ export const GraphicsOverridesSchema = z
|
||||
fx: z.boolean(),
|
||||
})
|
||||
.partial(),
|
||||
accessibility: z
|
||||
.object({
|
||||
colorblind: z.boolean(),
|
||||
})
|
||||
.partial(),
|
||||
})
|
||||
.partial();
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@ import type { RenderSettings } from "./RenderSettings";
|
||||
|
||||
const DARK_AMBIENT = 0.35;
|
||||
|
||||
/**
|
||||
* Apply the user's graphics overrides onto a RenderSettings in place: name
|
||||
* scaling, classic/dark structure and name styling, and the colorblind-safe
|
||||
* affiliation/tint palette.
|
||||
*/
|
||||
export function applyGraphicsOverrides(
|
||||
settings: RenderSettings,
|
||||
overrides: GraphicsOverrides,
|
||||
@@ -67,8 +72,36 @@ export function applyGraphicsOverrides(
|
||||
settings.name.outlineG = channel;
|
||||
settings.name.outlineB = channel;
|
||||
}
|
||||
if (overrides.accessibility?.colorblind === true) {
|
||||
// Swap the red/green friend-foe encoding (the most common confusion axis)
|
||||
// for a colorblind-safe blue/orange pairing (Okabe-Ito).
|
||||
// Alt-view affiliation borders: self/ally in the blue family, enemy orange.
|
||||
settings.affiliation.selfR = 0;
|
||||
settings.affiliation.selfG = 0.447;
|
||||
settings.affiliation.selfB = 0.698;
|
||||
settings.affiliation.allyR = 0.337;
|
||||
settings.affiliation.allyG = 0.706;
|
||||
settings.affiliation.allyB = 0.914;
|
||||
settings.affiliation.enemyR = 0.835;
|
||||
settings.affiliation.enemyG = 0.369;
|
||||
settings.affiliation.enemyB = 0;
|
||||
// Normal-view relationship border tints: friendly blue, enemy orange,
|
||||
// applied strongly so the cue doesn't rely on subtle hue.
|
||||
settings.mapOverlay.friendlyTintR = 0;
|
||||
settings.mapOverlay.friendlyTintG = 0.447;
|
||||
settings.mapOverlay.friendlyTintB = 0.698;
|
||||
settings.mapOverlay.embargoTintR = 0.835;
|
||||
settings.mapOverlay.embargoTintG = 0.369;
|
||||
settings.mapOverlay.embargoTintB = 0;
|
||||
// Strong ratio so the friend/foe tint dominates the darkened territory
|
||||
// border — neutral keeps its (darkened) fill hue, ally reads blue, enemy
|
||||
// reads orange.
|
||||
settings.mapOverlay.friendlyTintRatio = 0.85;
|
||||
settings.mapOverlay.embargoTintRatio = 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
/** Apply dark-mode lighting (ambient + enabled) onto settings when active. */
|
||||
export function applyDarkModeOverride(
|
||||
settings: RenderSettings,
|
||||
isDark: boolean,
|
||||
|
||||
Reference in New Issue
Block a user