Sleepless

Timers

Last updated on

Timers are small DUI plates that sit on a coordinate, the same way a small marker does. Use one for a cook, a fill, a brew, or any countdown you want in the world.

Give it a duration and it counts down on its own. Omit duration and push progress from your script. A duration timer removes itself at zero, calls onEnd if you passed one, and fires sleepless_waypoints:client:timerEnded.

Timer studio

Pick a style and set the options. The preview and the Lua stay together.

Cooking
8s left

Label, time, and a segmented bar. The preview loops. In game, a duration timer runs once.

Show label
Show time
Mode
Duration
sec
Plate
Distance
m
Start paused
Colour
Breakpoints

The fill keeps the starting colour until progress reaches a stop. Smooth eases into the next colour on the way in. Hard switches at the stop.

client.lua
local id = exports.sleepless_waypoints:createTimer({
coords = vec3(0.0, 0.0, 0.0),
style = 'pill',
label = 'Cooking',
duration = 8000,
})
-- exports.sleepless_waypoints:updateTimer(id, { paused = true })
-- exports.sleepless_waypoints:removeTimer(id)

Styles

StyleReads as
pillLabel, remaining time, segmented bar
barLabel, remaining time, continuous bar
chipCompact label and clock time
stackCaption over a large value
dialSegmented ring with the time in the middle
pieFilled wedge with the time underneath
donutRing with the time in the hole
gaugeArc with the time inside the opening
clockTick ring with the time in the middle
dotsFive dots that fill from the left
signalFive bars that step up from the left

Pill and bar show 8s left while a timer is running. The other styles show 0:08. In script mode every style shows a percent.

Timer data

PropertyTypeDefaultDescription
coordsvector3requiredWorld position. The plate is centered on this point.
styleTimerStyle'pill'One of the styles above
labelstring'TIMER'Caption on the plate
showLabelbooleantrueDraw the caption. false hides it.
showValuebooleantrueDraw the remaining time, or the percent in script mode. false hides it.
durationnumberCountdown length in milliseconds. Omit this to drive the timer yourself.
progressnumber0.00.0 to 1.0. Sets a script timer, or seeks a duration timer.
colorstring'#31a4fc'Progress colour as #rrggbb. Left unused while colors is set.
colorsTimerColorStop[]{ at = 0.0 to 1.0, color = '#rrggbb' }. The fill keeps a colour until progress reaches the next stop.
blendbooleanfalseEase into the next colour as progress gets close to that stop. false switches hard at the stop.
backgroundbooleantrueDraw the black plate
pausedbooleanfalseFreeze a duration timer on spawn
sizenumber1.0Scale multiplier
drawDistancenumber12.0Metres before the timer hides
fadeDistancenumber9.0Metres before it starts fading
removeOnCompletebooleantrueRemove a duration timer when it hits zero
onEndfunctionClient only. Called with the timer id when a duration timer hits zero

Place coords a little above the prop. Twelve metres is enough for something you walk up to. Raise drawDistance if the timer should read from further away.

showLabel and showValue only hide text. The bar, ring, dots, and other fills stay. Chip and stack are only those two texts, so hiding both leaves an empty plate.

Duration timer

local id = exports.sleepless_waypoints:createTimer({
    coords = vec3(100.0, 200.0, 30.4),
    style = 'pill',
    label = 'Cooking',
    duration = 8000,
    onEnd = function(timerId)
        -- The plate is removed after this returns. Grant the result here.
    end,
})

AddEventHandler('sleepless_waypoints:client:timerEnded', function(timerId)
    if timerId ~= id then return end
end)

onEnd runs on the client that created the timer, before the plate is removed. The local event still fires after it, which is useful when another resource needs to hear about every timer.

updateTimer changes only the fields you pass. Passing duration starts that timer over. Passing progress on a duration timer jumps the fill.

exports.sleepless_waypoints:updateTimer(id, { paused = true })
exports.sleepless_waypoints:updateTimer(id, { label = 'Resting', color = '#f5a623' })
exports.sleepless_waypoints:removeTimer(id)

colors replaces that flat colour. Leave blend out, or set it false, and the fill switches the moment progress reaches a stop. blend = true holds the current colour, then eases into the next one on the way into the stop. Pass colors = {} to updateTimer to go back to color.

exports.sleepless_waypoints:createTimer({
    coords = vec3(100.0, 200.0, 30.4),
    style = 'signal',
    label = 'Heat',
    duration = 20000,
    colors = {
        { at = 0.0, color = '#31a4fc' },
        { at = 0.55, color = '#f5a623' },
        { at = 0.85, color = '#b83e3e' },
    },
    blend = true,
})

Set removeOnComplete to false if the plate should stay full until you remove it. onEnd and the ended event still run.

onEnd does not cross the network. A timer created on the server still fires sleepless_waypoints:client:timerEnded on each client that has it. Keep the reward on the server with your own timeout, the same way the example below removes the timer.

Script timer

Leave duration out and set progress whenever your script moves.

local id = exports.sleepless_waypoints:createTimer({
    coords = vec3(100.0, 200.0, 31.2),
    style = 'stack',
    label = 'Filling',
    progress = 0.0,
    color = '#31a4fc',
})

exports.sleepless_waypoints:updateTimer(id, { progress = 0.4 })

Script timers do not end on their own. Remove them when the action is done.

Server

local id = exports.sleepless_waypoints:createTimer(source, {
    coords = vec3(100.0, 200.0, 30.4),
    style = 'bar',
    label = 'Brewing',
    duration = 15000,
})

SetTimeout(15000, function()
    exports.sleepless_waypoints:removeTimer(id)
end)

source can be one player id, a list of ids, or -1 for everyone online. The id you get back is the server id. Use it with updateTimer and removeTimer on the server. It is not the id the client uses locally.

removeAllTimers() drops every server timer. removeAllTimers(playerId) drops timers that were aimed at that one player. Global timers stay up for everyone else.

A player who joins after you create a timer does not receive it. Each client runs the countdown from the moment the timer arrives, and each client fires sleepless_waypoints:client:timerEnded on its own. If the server created the timer, remove it there when the interaction is over.

Client exports are documented on Client. Server exports are documented on Server. Defaults live in Configuration.

On this page