Skip to main content

Breaks and the schedule

Your script only takes part if it says so. A bundle that never mentions scheduling is invisible to it: a break never stops it, nothing resumes it, it never starts the shift clock, and schedule.break_soon never fires for it.

"schedule": { "resume": "restart" }

That block is the opt in. Declare it and Hexis decides when to work and when to rest, leaves the server, comes back, and starts your script again with the same settings. None of that needs your script's help beyond the declaration.

A passive script cannot take part, and declaring both is a manifest error. A passive script waits for something to happen rather than working, so counting it would let an armed solver decide when the bot rests.

The clock only runs while a script that opted in is actually driving the player. Stop every such script and the schedule goes idle: no countdown, no break, nothing shown. That is also why you never have to tell Hexis the human took over.

What your script can do is finish the thing it is holding first. A break that lands mid-tree leaves a half-felled trunk; a break that lands between trees leaves nothing at all.

-- bundle.json: "requestedCapabilities": ["schedule.read", ...]

local breaks = hexis.events.subscribe({
type = "schedule.break_soon",
filter = {finish_seconds = 90},
})

while true do
harvest_one_tree()
local pending = hexis.events.next(breaks, {timeout = 0})
if pending.kind == "event" then
hexis.schedule.ready()
return
end
end

Subscribing is what buys you the time. A script that does not subscribe is stopped when the break starts, which is fine for anything that can be interrupted anywhere.

The budget is a promise, not a veto

finish_seconds is how long you may take to reach a safe point, clamped to between 5 and 180. Hexis waits for it, then stops the run whether or not you answered. Declaring three minutes and never calling hexis.schedule.ready() delays one break by three minutes and nothing after that.

Call ready() as soon as you are at a boundary. It is safe to call when no break is pending, so it can live at the end of your unit of work rather than behind a check.

Racing the break with your other work

The subscription is an ordinary event handle, so it belongs in the hexis.select your script already has:

local outcome = hexis.select({candidates = {mining, spawns, breaks}, timeout = 30})
if outcome.kind == "event" and outcome.event.type == "schedule.break_soon" then
finish_up()
hexis.schedule.ready()
return
end

The event carries kind (short_break, long_break, sleep), policy (stay, island, disconnect), starts_in, and until_epoch_seconds. Read policy if you care whether the client is about to leave the server: a short break on your island keeps your position and a disconnect does not.

Reading the clock without subscribing

hexis.schedule.observe() answers the same questions without opening a stream. Poll it when all you want to know is whether to begin another long piece of work:

local schedule = hexis.schedule.observe()
if schedule.break_pending or schedule.changes_in < 120 then
return -- not worth starting another lap
end

It costs schedule.read, the same capability as the event. Note that observing alone does not buy you a wind-down budget; only a subscription does.

Asking for a break

Sometimes your script is the only thing that knows there is nothing worth doing: the inventory is full and nothing is sellable, the contest ended, the spot is contested for the next half hour. Standing still is the least human thing Hexis can do, so ask for a break instead.

-- bundle.json: "requestedCapabilities": ["schedule.control", ...]

local outcome = hexis.schedule.request({minutes = 30, reason = "inventory full"})
if not outcome.accepted then
-- outcome.refused_because is breaks_off, break_already_starting,
-- or schedule_unavailable
hexis.script.stop({reason = "Inventory is full and I cannot sell here"})
end

schedule.control is a separate capability because this is the only member that can take the player's game offline, and the install screen names it. Three things it deliberately cannot do:

  • turn breaks on. If the user has them off, the request is refused. A script does not enable a feature on somebody's behalf.
  • exceed the user's own break range. minutes is clamped to it.
  • choose sleep, or change where the client waits. The leave policy belongs to the user and their server, not to a script.

Coming back

You do not write a route back. Hexis reconnects, replays the server's own lobby route, and starts your script again from the top, so your opening hexis.area.enter is what returns you to your work area exactly as it got you there the first time.

If your script should be stopped by a break but not brought back unattended:

"schedule": { "resume": "never" }

What the player sees

One line in game and one on the dashboard, both saying what is happening, when it changes, and which script comes back. You do not draw any of it, and you do not need to publish a HUD row about the break.