PURPOSE
Canonical registry of named palette presets and the biome-to-preset preference map. Each preset is a small parameter tuple (temperature, brightness, saturation, optional hue_bias) that the palette generator expands into a full cohesive palette. Adding a new look costs 3–4 numbers, not 7 hex picks. Also resolves a biome id (plus an optional mission seed) to a chosen preset id.
OWNS
PRESETS: the canonical list ofPalettePresetrows (id, displayName, temperature, brightness, saturation, optional hue_bias, optional overrides)._presetById: an internalMap<string, PalettePreset>for id lookup, built once fromPRESETS.BIOME_PREFERRED_PALETTES: aRecord<string, string[]>mapping biome id to an ordered list of preferred preset ids.- Three preset families documented in source: near-greyscale/reference (
pure_grey,noir,ice_seed); cool atmospherics (voidmilk,deep_frost,cold_ember,amethyst_drift); pastel/jade/pink/light-blue (rose_quartz,dusty_rose,mint_jade,seafoam,cotton_sky,periwinkle,peach_cream,lavender_haze). - Biome entries:
landing_site,sunrise_city,the_voidstar,obsidian_spire,jungle_canopy,crystal_cavern,delphi,old_earth. - Curation history: presets
ember_drift,solar_flare,blood_furnace,sunlit_moss,monochrome_hotwere explicitly dropped (Nate 2026-04-22) for being too warm/saturated.
READS FROM
./palette-types:Palette,PalettePresettype imports../palette-generator:generatePalette(presetId, preset)— called bygetPaletteByPresetIdto expand a preset into a full palette.
PUSHES TO
getPaletteByPresetId(id): returns a fully-generatedPalette, with hand-tunedpreset.overrides(if present) applied on top viaObject.assign. Throws on unknown id.getAllPresetIds(): returns all preset ids in declared order.getPresetMeta(id): returns the rawPalettePresetrow for debug UIs. Throws on unknown id.BIOME_PREFERRED_PALETTES: exported record consumed by anything that needs the raw biome-to-preset table.pickPresetForBiome(biomeId, seed?): returns a single preset id chosen from the biome’s preferred list. With no seed, returns the first preferred. With a seed, indexes the preferred list byMath.abs(Math.floor(seed)) % prefs.length. Falls back to'voidmilk'for biomes without an entry.
DOES NOT
- Does not generate palette colors itself — delegates all expansion to
generatePaletteinpalette-generator. - Does not cache generated palettes — each
getPaletteByPresetIdcall re-runs the generator and re-applies overrides. - Does not register or query biomes from the biome system — the biome-to-preset table is a literal in this file.
- Does not handle daily/boss/event override paths — the source note says those runs may force an off-preset palette for variety, but that selection lives elsewhere.
- Does not validate that overrides are well-formed — they are blindly
Object.assign’d onto the generated palette. - Does not coerce or wrap seeds in any RNG abstraction — uses
Math.abs(Math.floor(seed))directly on the raw number.
Signals
None. This module exposes pure functions and exported constants only; it raises no events and runs no side effects beyond the one-time _presetById map construction at import.
Entry points
getPaletteByPresetId(id: string): Palette— primary resolution path used when a preset id is already known.pickPresetForBiome(biomeId: string, seed?: number): string— primary mission-seed entry point; picks the preset id for a biome+seed pair.getAllPresetIds(): string[]— used by debug UIs and tooling that need to enumerate presets.getPresetMeta(id: string): PalettePreset— used by debug UIs that need to display raw preset parameters.BIOME_PREFERRED_PALETTES— direct read access for code that needs the full table.
Pattern notes
- Data-table-in-code: presets and biome preferences are literal arrays/records in this file rather than JSON, so types are checked at compile time and renames flow through TypeScript references.
- Crash-on-unknown: both
getPaletteByPresetIdandgetPresetMetathrow on missing ids rather than returning a default — consistent with the project’s no-silent-fallbacks rule for internal lookups. - Soft fallback only at the biome edge:
pickPresetForBiomedefaults to['voidmilk']for biomes with no entry, treating biome ids as a softer boundary than preset ids. - Overrides as escape hatch:
preset.overridesexist for the rare case where the generator produces a slot that reads flat or clashes with art direction — the source comment marks them as deliberately sparing. - Seed indexing is deterministic and symmetric around zero: negative seeds map to the same index as their absolute value.
- Preset rows are aligned column-style in source for readability; new rows should follow the same column layout.
- Three documented preset families act as informal categories; the source comments serve as the design rationale for each family’s parameter range.