Skip to main content

Examples

A business's hours​

A building opens and closes by its hours and the town's power, and counts visitors while open. See Kalem at a glance.

The town's power​

A World script: the grid is cut for maintenance for an hour at night, but never on Sundays or in summer.

/// Runs the town's power: cuts it for an hour at night for maintenance; not on Sundays or in summer.
server script PowerGrid extends World
label "Power grid"
category "World"

group "Maintenance"
/// When the power goes off.
property cutsAt: time = 03:00 "Cut"
/// When the power comes back.
property restoresAt: time = 04:00 "Back"
end

writes power.on: bool

timer cut daily at cutsAt
timer restore daily at restoresAt

on ready
power.on = true
end

on timer cut
if weekday() != 7 and season() != "summer"
power.on = false
end
end

on timer restore
power.on = true
end

A street lamp​

A Part script: on in the evening, off in the morning, never without power. One function decides, power first, so an evening timer during a cut cannot light the lamp.

/// On in the evening, off in the morning; never without power.
server script StreetLamp extends Part
label "Street lamp"
category "Server behaviours"

group "Hours"
property onAt: time = 19:30 "On"
property offAt: time = 06:00 "Off"
end

group "Start"
property startsPowered: bool = true "Power"
end

memory hasPower: bool = startsPowered "Power"

writes lamp.lit: bool

timer evening daily at onAt
timer morning daily at offAt

on ready
decide()
end

on timer evening, morning
decide()
end

on city.powerChanged(powered)
hasPower = powered
decide()
end

function decide()
lamp.lit = hasPower and clock().between(onAt, offAt)
end

A resident's day​

A Character script: Fedai wakes up in the morning and goes to bed at night. See Getting started.

A neon sign​

A VisualEffect: the sign's colour, flickering; bound to business.open, it lights while the business is open.

/// Gives the part the neon's colour and makes it flicker; unlit while its signal is off.
client script Neon extends VisualEffect
label "Neon flicker"
category "Visual effects"

// Bound in the Inspector to a boolean server signal, e.g. business.open. Unbound, it keeps its
// default and always lights.
input lit: bool = true

property neonColor: color = #ffd580 "Colour" was "color"
property speed: float = 1.0 "Speed · Hz" range 0.1 to 5 step 0.1
property intensity: float = 0.7 "Flicker" range 0 to 1 step 0.05

// Lit, the neon replaces the colour and keeps only its alpha; unlit, it leaves the colour as it
// is, and the part looks as it does without effects.
function apply(baseColor: color, elapsedSeconds: float): color
let wave = (1.0 + sin(elapsedSeconds * speed * 2.0 * pi)) / 2.0
return if lit then neonColor.scaled(1.0 - intensity * wave).withAlpha(baseColor.a) else baseColor
end

A lamp's light​

A Light: the lamp lights the door, the wall and the ground around it while it is on. Bound to a street lamp's lamp.lit, it follows the server.

/// Makes the part a light: while on, it lights what is around it; no shadows.
client script LampLight extends Light
label "Lamp light"
category "Visual effects"

// Bound in the Inspector to a boolean server signal, e.g. a street lamp's lamp.lit; off until
// a value arrives.
input lit: bool = false

property lightColor: color = #ffd878 "Light colour"
property brightness: float = 1.0 "Brightness" range 0 to 3 step 0.1
/// How far the light reaches from the part's middle.
property reach: float = 6.0 "Reach · m" range 1 to 20 step 0.5

// The colour of the light the part casts this frame; black casts none.
function apply(elapsedSeconds: float): color
return if lit then lightColor.scaled(brightness) else #000000
end