Setting it to 0.0 leaves in about a few seconds of transition, meaning it doesn't activate as soon as darkness begins to set, which is defined by default to be in terms of being between the 0.45 and 0.55 fraction of day-ticks.
Not exactly sure what "darkness_to_turn_on" is tuned with, or if it's just hard-coded to a given day-tick or faction of day-ticks like the LUT color_lookup table currently is, but the expected behaviour should be that "0.0" triggers whenever identity begins to transition (and when it's fully back to normal), and "1.0" when it's fully transitioned.
Currently the only way to make this reliable is to emulate the calculations yourself, and overwrite the daytime_color_lookup LUT table using lua scripting, whenever it's detected that night vision should be activated.
[2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
Thanks for the report however I'm not seeing anything broken here. The check logic is as simple as it can be: if (surface.darkness > night_vision.darkness_to_turn_on) then it is on. That's it, that's the full logic for how this is used.
If you want to get ahold of me I'm almost always on Discord.
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
Well then, the issue is that the calculated (how?) LuaSurface darkness does not accurately follow the empirical reality of however the LUT transition of daytime_color_lookup works in practice, and since the principle of NightVisionPrototypes is to affect the LUT, this is what it should be benchmarked against (not just the formal darkness, which is used for gameplay purposes).Rseding91 wrote: Thu Jul 09, 2026 1:09 pm Thanks for the report however I'm not seeing anything broken here. The check logic is as simple as it can be: if (surface.darkness > night_vision.darkness_to_turn_on) then it is on. That's it, that's the full logic for how this is used.
Is the darkness property hardcoded to change at specific ticks or is it dynamically calculated in relation to the current color table definitions? Comments seem to imply it's hardcoded and the color table _should_ follow the general principle of night being between 0.45 and 0.55 (or something to that effect), but in practice, there is a transitional state that happens around that time that induces the discrepancy.
So the issue is either that the color table transition behavior (undocumented) makes it not as trivial as something like "darkeness scales linearly from 1.0 to 0.0 between 0.45 and 0.55", because at 0.45 the transition has already begun.
Since I'm assuming the definition of darkness to affect gameplay (solar panels and such), and the color lookup table is already somewhat documented to imply when day and night _should_ relatively be, the way to fix this is to change the check in LuaNightvisionPrototype to either follow the daylight_color_lookup table, on one side, to respect the way transitions are handled (leaving in a visual margin of error to be determinated), and/or on the other side, to follow however arbitrarily it's defined (optional, which would make this more a feature).
I can only make guesses as to what is happening here, you can try this yourself by using this proof of concept:
https://mods.factorio.com/mod/true_nightvision
Expected behavior should be that setting darkness_to_turn_on to 0.0, would activate night vision as soon as the color transition begins, in practice there is still a noticeable lag of a few seconds.
Last edited by dupraz on Thu Jul 09, 2026 5:55 pm, edited 1 time in total.
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
darkness has nothing to do with the LUT logic. It's just this:
Where all of these values can be adjusted here:
https://lua-api.factorio.com/stable/cla ... ks_per_day
https://lua-api.factorio.com/stable/cla ... .html#dusk
https://lua-api.factorio.com/stable/cla ... .html#dawn
https://lua-api.factorio.com/stable/cla ... ml#evening
https://lua-api.factorio.com/stable/cla ... ml#morning
Code: Select all
float DayTime::getDarkness(double maxDarkness) const
{
if (this->position < this->dusk)
return 0;
if (this->position < this->evening)
return float(Math::min(maxDarkness, 1 - (this->evening - this->position) / (this->evening - this->dusk)));
if (this->position > this->dawn)
return 0;
if (this->position > this->morning)
return float(Math::min(maxDarkness, 1 - (this->position - this->morning) / (this->dawn - this->morning)));
return float(maxDarkness);
}https://lua-api.factorio.com/stable/cla ... ks_per_day
https://lua-api.factorio.com/stable/cla ... .html#dusk
https://lua-api.factorio.com/stable/cla ... .html#dawn
https://lua-api.factorio.com/stable/cla ... ml#evening
https://lua-api.factorio.com/stable/cla ... ml#morning
If you want to get ahold of me I'm almost always on Discord.
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
Right, this is what I expected, the issue being that in practice the LUT table color transition which formally follow these definitions, but in practice, leaves in a _visual_ transitional state around the time between day and the beginning of dusk, where both of the following happen at the same time:Rseding91 wrote: Thu Jul 09, 2026 5:48 pm darkness has nothing to do with the LUT logic. It's just this:
Where all of these values can be adjusted here:Code: Select all
float DayTime::getDarkness(double maxDarkness) const { if (this->position < this->dusk) return 0; if (this->position < this->evening) return float(Math::min(maxDarkness, 1 - (this->evening - this->position) / (this->evening - this->dusk))); if (this->position > this->dawn) return 0; if (this->position > this->morning) return float(Math::min(maxDarkness, 1 - (this->position - this->morning) / (this->dawn - this->morning))); return float(maxDarkness); }
https://lua-api.factorio.com/stable/cla ... ks_per_day
https://lua-api.factorio.com/stable/cla ... .html#dusk
https://lua-api.factorio.com/stable/cla ... .html#dawn
https://lua-api.factorio.com/stable/cla ... ml#evening
https://lua-api.factorio.com/stable/cla ... ml#morning
- LUT is no longer identity and is already transitioning (dusk has already _visually_ begun to set)
- darkness is still 0, because we're not formally in the dusk period yet.
Hence the functional discrepancy. night vision should be tuned against the LUT behavior, not the surface formal darkness, because that's where it's actually relevant.
Ideally they would both match but somehow the LUT behavior is not totally consistent with these values.
See: https://github.com/wube/factorio-data/b ... s.lua#L469
Assuming the LUT transition is expected behavior such that it's visually smoother (visual darkness begins slightly before formal darkness), the issue still lies in how the NightVisionPrototype check in implemented, which should follow actual behavior. If it's not the expected behavior then the issue lies in the LUT color transition which is somewhat inaccurate relatively to its formal values. I can't really guess since this is mostly undocumented (only mentions a "smooth transition"):
https://lua-api.factorio.com/latest/typ ... Table.html
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
I know your code excepts are (obviously) consistent with the current game behavior, but can you at least try and explain/document what's happening with the LUT transition that makes it not accurately follow its formal boundaries, such that I might properly fix it by myself in lua instead of just having to override every surface daylight_color_lookup table because of how inconsistent its behavior currently is? Actually this might be impossible to fix at runtime, because the relevant lookup tables would then be read-only. So there is no practical way to fix this unless NightVisionEquipmentPrototype, which is currently the only way to overrite them, is no longer gated behind darkness_to_turn_on, since it isn't currently accurate in regard to visual effects.
There are exactly 2 ways to fix this, depending on the original intent:
- Make night vision follow the visual LUT behavior (if the visual transition quirk is intended and decoupled from formal darkness)
- Make the LUT behavior follow the formal darkness calculation (if the transition is bugged and should in theory follow formal darkness)
Currently, they're not matching and one is undocumented.
There are exactly 2 ways to fix this, depending on the original intent:
- Make night vision follow the visual LUT behavior (if the visual transition quirk is intended and decoupled from formal darkness)
- Make the LUT behavior follow the formal darkness calculation (if the transition is bugged and should in theory follow formal darkness)
Currently, they're not matching and one is undocumented.
Last edited by dupraz on Thu Jul 09, 2026 7:35 pm, edited 5 times in total.
Re: [2.1.9] NightVisionEquipmentPrototype.darkness_to_turn_on doesn't accurately follows the default day-night cycle.
Actually, come to think of it, changing "surface.darkness > night_vision.darkness_to_turn_on" into "surface.darkness >= night_vision.darkness_to_turn_on" would fix my use-case, because then at darkness_to_turn_on = 0, night vision would always be active, which makes sense and is a logical solution to the general problem, it's a one-character fix that is inconsequential for anything else.Rseding91 wrote: Thu Jul 09, 2026 1:09 pm Thanks for the report however I'm not seeing anything broken here. The check logic is as simple as it can be: if (surface.darkness > night_vision.darkness_to_turn_on) then it is on. That's it, that's the full logic for how this is used.
Wouldn't change the current oddity of LUT transition behavior, but I guess you might not want to bother trying to fix it.

