Repository navigation
Lighting
Every sector has a light property: a Vector3 of red, green, blue in the range 0-255
(255, 255, 255 is full white, 0, 0, 0 is dark). sector.light.x = 0 changes one channel; a
value stored in a variable is a copy, so assign it back after changing it.
local base = sector.light -- copy
sector.light = Vector3(base.x * 0.5, base.y * 0.5, base.z * 0.5) -- half brightnessAll scripts on this page are sector scripts.
Attach to: a sector with a broken light.
Holds a random brightness for a random short time, then picks another.
-- Scripts/Lighting/Flicker.lua (sector script)
public number minBrightness = 0.3
public number maxBrightness = 1.0
public number minInterval = 0.03
public number maxInterval = 0.15
local base
local timer = 0.0
function Start()
base = sector.light -- remember the light the designer painted
end
function Update()
timer = timer - GameTime.deltaTime
if timer > 0 then return end
timer = mathT.RandomF(minInterval, maxInterval)
local k = mathT.RandomF(minBrightness, maxBrightness)
sector.light = Vector3(base.x * k, base.y * k, base.z * k)
end
function OnDisable()
if base ~= nil then sector.light = base end -- restore
endAttach to: a sector with a glowing thing: a reactor room, a heartbeat.
-- Scripts/Lighting/Pulse.lua (sector script)
public number period = 2.0
public number minBrightness = 0.35
public number maxBrightness = 1.0
local base
local clock = 0.0
function Start()
base = sector.light
end
function Update()
clock = clock + GameTime.deltaTime
-- Sine wave remapped from -1..1 to 0..1, then to minBrightness..maxBrightness.
local wave = 0.5 + 0.5 * math.sin(clock / period * 2 * math.pi)
local k = mathT.Lerp(minBrightness, maxBrightness, wave)
sector.light = Vector3(base.x * k, base.y * k, base.z * k)
endAttach to: a sector that should flash red while an alarm is on.
The alarm is a channel in the shared Global table (the same trick the doors use), so any
script can trigger it: Global.channels = Global.channels or {} then
Global.channels["alarm"] = true.
-- Scripts/Lighting/AlarmStrobe.lua (sector script)
public string channel = "alarm"
public number flashesPerSecond = 2
public Vector3 alarmColor = Vector3(255, 0, 0)
local base
local clock = 0.0
local wasActive = false
function Start()
base = sector.light
end
function Update()
local active = Global.channels ~= nil and Global.channels[channel] == true
if not active then
if wasActive then
sector.light = base -- alarm just ended: restore the normal light
wasActive = false
end
return
end
if not wasActive then
wasActive = true
clock = 0.0 -- restart the flash pattern each time the alarm begins
end
clock = clock + GameTime.deltaTime
-- Two half-cycles per flash: even = alarm color, odd = dark.
local lit = math.floor(clock * flashesPerSecond * 2) % 2 == 0
if lit then
sector.light = alarmColor
else
sector.light = Vector3(base.x * 0.15, base.y * 0.15, base.z * 0.15)
end
endNotes
- Every strobe sector restarts its clock on the frame the alarm switches on, so sectors that share a channel flash in sync without needing a shared timer.
- A
Vector3public field (alarmColor) can be assigned straight tosector.light.
Attach to: an outdoor sector (or one script per outdoor sector).
Blends through a list of colors over a day.
-- Scripts/Lighting/DayNight.lua (sector script)
public number dayLength = 120
public number startTime = 0.5
-- One entry per key moment of the day, evenly spaced from midnight (0) around to midnight (1).
local KEYFRAMES = {
{40, 50, 90}, -- midnight
{255, 170, 110}, -- dawn
{255, 255, 255}, -- noon
{255, 130, 80}, -- dusk
{40, 50, 90}, -- midnight again (so it loops)
}
local clock = 0.0
local function SampleDay(t)
local segments = #KEYFRAMES - 1
local scaled = (t % 1) * segments
local index = math.floor(scaled)
local blend = scaled - index
local a = KEYFRAMES[index + 1]
local b = KEYFRAMES[index + 2]
return Vector3(
mathT.Lerp(a[1], b[1], blend),
mathT.Lerp(a[2], b[2], blend),
mathT.Lerp(a[3], b[3], blend)
)
end
function Start()
clock = startTime
end
function Update()
clock = (clock + GameTime.deltaTime / dayLength) % 1
sector.light = SampleDay(clock)
endNotes
-
%is Lua's modulo, so(t % 1)keeps the time inside0..1. - The keyframe table is plain Lua data. Add more entries to add more moods, and the math adapts
because it uses
#KEYFRAMES.
Attach to: the sector whose lights you want to toggle.
Press a key while standing in the sector to toggle its lights.
-- Scripts/Lighting/LightSwitch.lua (sector script)
public Entity player = nil
public Key toggleKey = Key.F
public number offBrightness = 0.1
local base
local lightsOn = true
local function PlayerIsInside()
for i = 1, sector.entityCount do
if sector:GetEntity(i).id == player.id then return true end
end
return false
end
function Start()
base = sector.light
end
function Update()
if player == nil or not Input.GetKeyDown(toggleKey) or not PlayerIsInside() then return end
lightsOn = not lightsOn
if lightsOn then
sector.light = base
else
local k = offBrightness
sector.light = Vector3(base.x * k, base.y * k, base.z * k)
end
end