Skip to content

Scheduler ​

The Scheduler namespace provides save-resilient scheduling on the in-game clock.

A job is a due date, not a countdown, which is what makes it survive the things a countdown does not: quitting, loading another save, coming back a day later. Anything still due when the player returns fires as soon as its handler is registered.

No permission required.

Available since SDK v0.23.0

The Scheduler namespace requires @hotbunny/[email protected] or newer. Run npm install @hotbunny/hackhub-content-sdk@latest to update.

Import ​

typescript
import { Scheduler } from "@hotbunny/hackhub-content-sdk";

Register handlers on every load ​

Jobs outlive the session that created them, so the handler has to exist before the job is due. Register at mod load, every load, above the content that schedules anything.

A job whose handler is missing is held, never dropped. Uninstalling a pack does not destroy the pending world state it created, and reinstalling picks it back up.

Prefix your kinds

The handler registry is shared between mods. Two packs that both register "triage" would silently answer each other's jobs, so prefix every kind with your pack id.

Methods ​

Scheduler.register<P>(kind, handler) ​

Handle jobs of one kind. The handler receives the job's payload and its ScheduledJobInfo, and may be async.

typescript
Scheduler.register<{ reportId: string }>("myPack.triage", ({ reportId }, job) => {
    Mail.send({
        from: "[email protected]",
        subject: `Report ${reportId} triaged`,
        content: "Reviewed and accepted.",
    });
});

Scheduler.unregister(kind) ​

Stop handling a kind. Jobs of that kind are held rather than dropped.

Scheduler.schedule<P>(kind, payload?, delay?, id?) ​

Schedule a job to fire after a delay. Pass id to make the call idempotent: scheduling the same id again replaces the pending job instead of adding a second one.

Returns: string (the job id)

typescript
Scheduler.schedule("myPack.triage", { reportId: "R-1" }, { days: 2 });
Scheduler.schedule("myPack.nudge", { step: 1 }, { realMs: 2500 });

Scheduler.scheduleAt<P>(kind, payload, fireAt, id?) ​

Schedule a job for a specific in-game timestamp, as returned by Time.now().

Returns: string (the job id)

typescript
Scheduler.scheduleAt("myPack.deadline", { caseId }, Time.now() + Time.duration({ days: 7 }));

Scheduler.cancel(id) ​

Cancel one pending job.

Scheduler.cancelKind(kind) ​

Cancel every pending job of one kind.

Scheduler.list(kind?) ​

Pending jobs, in the order they will fire. Pass a kind to filter.

Returns: ScheduledJobInfo[]

Scheduler.remaining(id) ​

In-game milliseconds until id fires, or null when there is no such job.

Returns: number | null

Types ​

ScheduleDelay ​

An in-game delay, expressed the way a designer thinks about it. Omit everything to fire on the next tick.

FieldTypeDescription
minutesnumberIn-game minutes
hoursnumberIn-game hours
daysnumberIn-game days
msnumberIn-game milliseconds, if you would rather be explicit
realMsnumberReal-world milliseconds, converted at the current clock scale

Reach for realMs only when pacing a beat the player is watching, rather than saying anything about how much time passed in the fiction. An e-mail that should land "a couple of seconds after you click" is realMs. A two-day triage is not.

ScheduledJobInfo ​

FieldTypeDescription
idstringJob id
fireAtnumberIn-game timestamp at which the job is due
kindstringThe registered kind
payloadanyWhatever was scheduled with it
createdAtnumberIn-game timestamp the job was created

Full example ​

typescript
import { Scheduler, Mail, Time } from "@hotbunny/hackhub-content-sdk";

// Top level of the pack entry file, so it runs on every load.
Scheduler.register<{ reportId: string }>("myPack.triage", ({ reportId }) => {
    Mail.send({
        from: "[email protected]",
        subject: `Report ${reportId} triaged`,
        content: "Reviewed and accepted. Bounty on its way.",
    });
});

// Later, when the player submits a report:
Scheduler.schedule("myPack.triage", { reportId }, { days: 2 });

A player who submits the report and quits for a week finds the reply waiting when they come back, because the job was a due date rather than a running timer.

HotBunny Interactive Entertainment Inc.