Violet

Scheduler

On this page

The core.scheduler module lets a script add its own steps and conditions to the web menu's Scheduler. A registered step appears in the Scheduler's step list under From your scripts, with a form built from its fields. A registered condition can be used in a step's If, a recurring task's If and in rules.

The Scheduler runs one step at a time. When it reaches your step it calls your script's on_step_start(step); your script does the work, usually in on_tick, and reports back with step:done() or step:fail(). When the Scheduler ends the step itself (its time limit, a skip, a pause or a safety stop) it calls on_step_stop(step, reason).

Info

Only the script that registered a step receives its callbacks. Steps and conditions are removed when their script unloads, and a step that is still running then fails.

lua
core.scheduler.register_step("daily_bosses", {
    name = "Daily bosses",
    description = "Clears the bosses you pick",
    fields = {
        { key = "bosses", type = "multi", label = "Bosses", options = { "Zakum", "Horntail", "Papulatus" }, default = { "Zakum" } },
        { key = "party", type = "checkbox", label = "Wait for party", default = false },
    },
})

local active

function on_step_start(step)
    active = step
    core.log("Running " .. #step.params.bosses .. " bosses")
end

function on_tick(stage)
    if not active or stage ~= core.stage.FIELD then return end
    -- do the work, then report it:
    active:progress(0.5, "Zakum down")
    -- active:done("All bosses cleared")  or  active:fail("Out of potions")
end

function on_step_stop(step, reason)
    active = nil
end

Functions

core.scheduler.register_step(id: string, definition: table)

Adds a step the Scheduler can run, or replaces this script's step with the same id. id is 1 to 40 lowercase letters, digits or _. Raises an error for an invalid definition, when called outside a loaded script, or when the script already offers 16 steps.

definition fields:

FieldTypeDescription
namestringShown in the step list. Defaults to id.
descriptionstringOptional. Shown under the name.
fieldstableOptional. Up to 12 inputs for the step's form; their values arrive in step.params. An array keeps its order; a map of key = field is sorted by each field's order, then by key.

Field types:

typeValue in step.paramsOther keys
checkboxbooleandefault
numbernumberdefault, min, max, step
dropdownstringoptions (1 to 32 strings), default
multitable of stringsoptions (1 to 32 strings), default
textstringdefault, max_length (1 to 200, default 200)

Every field has a key (1 to 32 lowercase letters, digits or _; the table key in map form) and an optional label (defaults to key). A value the field doesn't accept, such as a number outside min/max or an option that isn't listed, is replaced by the field's default before on_step_start runs.

lua
core.scheduler.register_step("farm_map", {
    name = "Farm a map",
    fields = {
        runs = { type = "number", label = "Runs", default = 3, min = 1, max = 20, order = 1 },
        mode = { type = "dropdown", label = "Mode", options = { "Normal", "Hard" }, default = "Normal", order = 2 },
    },
})

core.scheduler.unregister_step(id: string) -> boolean

Removes this script's step. Returns true if it existed. A schedule that still uses it fails at that step.


core.scheduler.register_condition(id: string, definition: table, check: function)

Adds a yes/no condition the Scheduler can use in If conditions and rules, or replaces this script's condition with the same id. definition takes name and description like register_step. check is called about once a second; any result other than false or nil counts as true. A check that raises an error counts as false, and its first error is reported to the console. Up to 16 conditions per script.

lua
core.scheduler.register_condition("boss_ready", { name = "Boss is ready" }, function()
    return boss_cooldown_left() == 0
end)

core.scheduler.unregister_condition(id: string) -> boolean

Removes this script's condition. Returns true if it existed.


core.scheduler.current() -> table | nil

Returns this script's running step, the same table on_step_start received, or nil when the Scheduler isn't running one of its steps.

Step

The step table passed to on_step_start and on_step_stop:

FieldTypeDescription
idstringIdentifies this run of the step.
typestringThe id the step was registered with.
paramstableThe values chosen in the step's form, keyed by field key.
resumedbooleantrue when the step starts again after a pause.

step:progress([fraction: number] [, text: string]) -> boolean

Reports how far the step is: fraction from 0 to 1, and a short text (up to 120 characters) shown on the run in the Scheduler. Updates are sent at most once a second and the latest one wins. Returns false if the step is no longer running.


step:done([text: string]) -> boolean

Finishes the step and the schedule moves on. Returns false if the step is no longer running.


step:fail([reason: string]) -> boolean

Ends the step as failed with reason (up to 200 characters); the schedule's retry and skip settings apply. Returns false if the step is no longer running.


step:is_active() -> boolean

Returns true while the Scheduler is running this step.

Stop reasons

on_step_stop is called when the Scheduler ends the step itself, never after step:done() or step:fail(). When it runs the step is already over: step:is_active() returns false and step:done() does nothing.

reasonWhen
"time"The step reached its time limit or its stop condition.
"skipped"The step was skipped.
"stopped"The schedule was stopped.
"paused"The schedule was paused, or a recurring task interrupted the step. The step starts again later with resumed = true.
"safety"GM detection or Panic Mode stopped it.
"replaced"Another step started in its place.
Warning

After a "safety" stop, stop everything the step was doing and don't restart it on your own.

Info
  • If the script isn't running when its step comes up, the Scheduler turns the script on for the step and off again afterwards.
  • A script step always has a time limit in the Scheduler, so a step that never calls done() can't hold the schedule forever.
  • An error raised inside on_step_start fails the step with that error.