Skip to content

Plugins overview

Plugins are the support half of the extension ecosystem: opt-in engine policies that make a game practical to ship — saving, offline catch-up — without touching its rules. Like mechanics, each one is a factory returning an Extension<T> behind its own public subpath.

Browser-specific bridges (page lifecycle, rAF frames, screen info) are not plugins — they live in @idlekitjs/browser.

The catalog

PluginSolves
AutosaveProgress lost when the tab dies without a recent save
Offline progress"I was away 3 hours, where's my production?"

The standard shipping stack

Most browser games install both, plus the page lifecycle bridge; they were designed to compose:

ts
import { autosave } from "@idlekitjs/plugins/autosave";
import { offlineProgress } from "@idlekitjs/plugins/offline-progress";
import { pageLifecycle } from "@idlekitjs/browser/page-lifecycle";

engine.use(pageLifecycle());
engine.use(offlineProgress({ maxMs: 8 * 60 * 60 * 1000 }));
engine.use(autosave({ manager: save, getState: () => engine.state, intervalMs: 15_000 }));

How they interlock:

  1. The player hides the tab → page-lifecycle pauses the loop (no battery burn) and autosave writes a save (the tab may never come back).
  2. The player returns → page-lifecycle resumes and emits resume with the elapsed milliseconds.
  3. offline-progress hears resume (and loaded, after engine.load) and calls engine.advance with the elapsed time, capped by your policy.

Each is independently optional — a headless simulation uses none of them.

Why these are not in core

Nothing pauses or saves behind your back unless you installed the thing that does it: these behaviors are policy, and @idlekitjs/core ships no policy. offlineProgress listens to engine events. autosave drives a SaveManager and includes browser lifecycle triggers (setInterval, visibilitychange, pagehide) in its current implementation; use it for browser games.