Talos docs

SaveHandle

Since 0.6

A small JSON store that outlives the run: a best score, an unlocked level, a chosen setting.

Plain text

It survives everything ctx.state does not — {@link SessionHandle.restart}, {@link SessionHandle.loadScene}, and the process. One store per application, shared by every scene and behaviour of it, so pick keys as you would for any shared namespace ("hoplane.best"). Where it lives. argus run <project> and an exported game keep it in the user's data folder under the application's id (%LOCALAPPDATA%\\Argus\\saves\\<application.id>\\save.json, or $XDG_DATA_HOME/argus/saves/…), or where --save-dir says. A bare scene, a test world and the editor's Play have no file: the store works for the length of the run and is then gone, which keeps a playtest from inheriting yesterday's. Editor Play keeps saves in memory; argus run and exported games write to the per-app save folder. critic.play and export.run give the game a folder of their own, removed when it stops. When it is written. At the end of a tick in which something changed, to a temporary file that is then renamed over the old one, so a crash mid-write leaves the previous save intact. A write that fails is logged once and never throws: a full disk must not end a run. It is not part of a snapshot, by design: restoring a world to an earlier tick must not un-earn a high score. Anything a replay has to reproduce belongs in ctx.state. Limits, refused with a thrown SaveError whose message starts with the code: a key is 1–64 characters of A-Z a-z 0-9 . _ - (save-bad-key); the whole store is at most 256 KiB of JSON (save-full). Values are JSON — no functions, no handles, no undefined.

Signature

export interface SaveHandle {
  /** The value saved under `key`, or null. */
  get(key: string): unknown
  /** Save a JSON-serialisable value under `key`. */
  set(key: string, value: unknown): void
  /** Forget `key`. True if there was something to forget. */
  delete(key: string): boolean
  /** Every saved key, sorted. */
  keys(): string[]
}

Import: import type { SaveHandle } from "@argus/api"

Members

MemberSignatureDescription
getget(key: string): unknownThe value saved under key, or null.
setset(key: string, value: unknown): voidSave a JSON-serialisable value under key.
deletedelete(key: string): booleanForget key. True if there was something to forget.
keyskeys(): string[]Every saved key, sorted.

Example

The tested fixture fixtures/app/agent.ts.

import type { Behavior } from "@argus/api"

// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
  init(ctx) {
    ctx.state.arrived = false
    ctx.nav?.goTo(ctx.props.target as [number, number, number])
  },
  update(ctx) {
    if (ctx.nav?.arrived) ctx.state.arrived = true
  },
} satisfies Behavior