Skip to content
S3LightFixes
guide

Overrides and exclusions

Give one light its own color, radius, duration or flags, relight one interior cell, and leave lights, cells and plugins alone.

The multipliers treat every light of a kind the same way. Overrides pick lights and cells out by id and give them values of their own. Both kinds of override go in lightconfig.toml, or on the command line for one run.

Overrides and exclusions are keyed by regular expressions, matched without regard to case and anywhere in the id: torch matches torch, Torch_256 and light_torch_blue. Anchor them to be exact: ^torch$.

One light§

[light_overrides.Light_Com_Candle_02]
red = 255
green = 128
blue = 64

[light_overrides.Torch_256]
red = 64
green = 128
blue = 255
hue = 220
value_mult = 0.75
radius = 254
duration = 1199.0

[light_overrides."^torch_128$"]
hue_mult = 0.3
red_mult = 1.1
radius_mult = 1.0
flag = ["CAN_CARRY", "PULSE_SLOW"]

Against Morrowind's own lights, those three give:

LIGH "light_com_candle_02" from "Morrowind.esm": color [245, 140, 40, 0] -> [255, 128, 64, 0], radius 128 -> 153, duration 120 -> 300, flags LightFlags(DYNAMIC | CAN_CARRY | FIRE | FLICKER_SLOW) -> LightFlags(DYNAMIC | CAN_CARRY | FIRE)
LIGH "torch_256" from "Morrowind.esm": color [245, 140, 40, 0] -> [48, 96, 191, 0], radius 256 -> 254, duration 210 -> 1199, flags LightFlags(DYNAMIC | CAN_CARRY | FIRE | FLICKER_SLOW) -> LightFlags(DYNAMIC | CAN_CARRY | FIRE)
LIGH "torch_128" from "Morrowind.esm": color [245, 140, 40, 0] -> [154, 60, 46, 0], duration 210 -> 525, flags LightFlags(DYNAMIC | CAN_CARRY | FIRE | FLICKER_SLOW) -> LightFlags(CAN_CARRY | PULSE_SLOW)

The candle has exactly the color it was given, and the standard radius and duration multipliers still apply to what the override leaves out. The second torch's fixed color is turned to hue 220° and dimmed by a quarter. The third keeps its radius, radius_mult = 1.0, and has exactly the flags listed.

A pattern that is not a bare TOML key, like ^torch_128$, needs quotes. When several patterns match a light, the first one listed is used and the others are ignored for that light.

KeyTypeDoes
red, green, blue0 to 255Replace the light's color, as the Construction Set shows it. All three or none
hue0 to 360Sets the hue, in degrees
saturation, value0.0 to 1.0Set the saturation or the brightness
hue_mult, saturation_mult, value_multnumberMultiply the hue, saturation or brightness
red_mult, green_mult, blue_multnumberMultiply one channel, after everything else. Results stay within 0 to 255
radius0 to 4294967295Sets the radius
radius_multnumberMultiplies the radius
durationnumberSets the duration, truncated to a whole number. -1 never burns out
duration_multnumberMultiplies the duration, unless it is -1
flagname, or list of namesReplaces all of the light's flags

A key and its _mult form cannot both be set: radius and radius_mult, duration and duration_mult, hue and hue_mult, and so on. hue, saturation and value outside their range are clamped into it. Every multiplier must be a finite number.

How the color is worked out§

  1. The starting color is the light's own, or red, green and blue if they are set.
  2. Hue, saturation and value are each taken from the override: its _mult multiplies, or its fixed

value replaces.

  1. A component the override leaves out gets the global multiplier for the light's kind, such as

standard_value, but only when the override has no red, green and blue. A fixed color is meant as the color, so it is not dimmed behind your back.

  1. The result goes back to red, green and blue, and red_mult, green_mult and blue_mult apply

last.

So red = 255, green = 160, blue = 80 alone gives exactly that color, and adding value_mult = 0.5 halves its brightness.

Radius, duration and flags§

Radius and duration follow the same pattern: the override's multiplier, else its fixed value, else the global multiplier. A fixed duration also applies to a light that never burns out, which is the one way to give it a finite time; multipliers leave -1 alone.

flag replaces the whole set, including flags S3LightFixes would have removed, so flag = "FLICKER" makes a light flicker even with disable_flickering on. flag = "NONE" clears every flag. The names are the Construction Set's light flags, in any case: DYNAMIC, CAN_CARRY, NEGATIVE, FLICKER, FIRE, OFF_BY_DEFAULT, FLICKER_SLOW, PULSE and PULSE_SLOW. NONE cannot be combined with any of them.

An override never applies to a negative light that disable_negative_lights has already turned off.

On the command line§

--light takes the pattern, =, and the keys as key=value pairs separated by commas. Flags are joined with |. Single quotes keep the shell away from $ and |:

s3lightfixes --light '^torch$=radius=400,red=255,green=160,blue=80' --light '^torch_128$=flag=CAN_CARRY|PULSE_SLOW'
LIGH "torch" from "Morrowind.esm": color [245, 140, 40, 0] -> [255, 160, 80, 0], radius 256 -> 400, duration 210 -> 525, flags LightFlags(DYNAMIC | CAN_CARRY | FIRE | OFF_BY_DEFAULT | FLICKER_SLOW) -> LightFlags(DYNAMIC | CAN_CARRY | FIRE | OFF_BY_DEFAULT)
LIGH "torch_128" from "Morrowind.esm": color [245, 140, 40, 0] -> [140, 74, 46, 0], radius 128 -> 153, duration 210 -> 525, flags LightFlags(DYNAMIC | CAN_CARRY | FIRE | FLICKER_SLOW) -> LightFlags(CAN_CARRY | PULSE_SLOW)

Without the anchors, torch would also match torch_128, and as the first match it would be the only one used.

Several overrides may also share one --light, separated by colons, so a pattern given on the command line cannot contain : or =. Unknown keys and conflicting keys are errors there, before anything runs:

error: invalid value 'torch=radius=5,radius_mult=2' for '--light <LIGHT_OVERRIDES>': Key radius is mutually exclusive with radius_mult

Command-line overrides come after the ones in lightconfig.toml. One with the same pattern as a file entry replaces it and moves to the end.

One cell§

[ambient_overrides."caius cosades' house"]
fog_density = 0.5

[ambient_overrides."caius cosades' house".ambient]
red = 64
green = 48
blue = 32

An ambient override matches interior cell ids, which are the cell names in lower case, like balmora, caius cosades' house, and replaces what it sets:

KeyTypeReplaces
ambientred, green, blue, 0 to 255The cell's ambient light
sunlightred, green, blue, 0 to 255The cell's sunlight
fogred, green, blue, 0 to 255The fog color
fog_densitynumberThe fog density

A color may instead be written as hue, saturation and value, all three, which older versions used; it is converted to red, green and blue. Unlike light overrides, every ambient override that matches a cell applies, in order, so a later one's values win.

On the command line, fields are separated by semicolons and colors are always red, green and blue:

s3lightfixes --ambient "caius cosades' house=ambient=red=64,green=48,blue=32;fog_density=0.5"
CELL "balmora, caius cosades' house" from "Morrowind.esm": ambient [75, 65, 65, 0] -> [64, 48, 32, 0], fog_density 0.75 -> 0.5

Only interior cells that have ambient data can be overridden. The cell written to the plugin keeps everything else from the plugin it came from, and carries none of its objects.

Leaving things alone§

excluded_ids = [
    # Every light or cell with "purple" in its id
    "purple",
    # Ids ending in glow
    "glow$",
]

excluded_ids matches light ids and interior cell ids. An excluded light or cell is not written to the plugin at all, so the game uses whichever version it would have used without S3LightFixes.

excluded_plugins matches plugin file names. An excluded plugin is not read, so its lights neither win nor lose against others: the last plugin that is read and has the light supplies it.

excluded_plugins = [
    "deleted_groundcover.omwaddon",
    "Clean_Argonian Full Helms Lore Integrated.ESP",
    "Baldurwind.omwaddon",
    "Crassified Navigation.omwaddon",
    "LuaMultiMark.omwaddon",
    "S3maphore.esp",
    "Toolgun.omwaddon",
    # Everything from OAAB
    "^OAAB",
]

The first seven are the built-in list, of plugins the reader cannot parse. Setting excluded_plugins replaces that list, which is why the first run writes it into lightconfig.toml: add to it there rather than starting a new one.

On the command line, -x and -X take comma-separated patterns and add them to the file's lists for that run:

s3lightfixes -x 'purple,glow$' -X '^OAAB'