本文へ移動
cccskills
無料GitHub で公開

pixi-vn-storage

Use when reading or writing persistent game variables in a @drincs/pixi-vn game — simple flags/counters via `storage`, custom persisted classes via `StoredClassModel`, temporary (label-scoped) variables, and how any of this survives save/load and history go-back. Load this before writing any `storage.set`/`storage.get`/`storage.flags.set` code or a class that extends `StoredClassModel`.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Pixi'VN Storage

When to use this skill

Use this skill whenever a task involves storing game state that must persist across steps and saves: flags ("has the player met Liam?"), counters (gold, affection points), arbitrary objects, or a custom class whose instances need to survive save/load (e.g. a quest-tracking model). It does not cover characters specifically (see the characters skill, which is itself built on top of the pattern described here) or how the history/go-back system is implemented internally (see the history skill).

Official docs (authoritative for terminology and recommended patterns): storage, flags, storage classes, temporary storage, save & load.

import { storage, StoredClassModel } from "@drincs/pixi-vn";

(Also available from the narrower @drincs/pixi-vn/storage subpath — see pixi-vn-getting-started for when to prefer that.) storage is a ready-made singleton (StorageManagerInterface) — you never instantiate StorageManager yourself.

1. Simple variables: storage.set / storage.get

See pixi-vn.com/start/storage.

storage.set("test", "test1");
storage.get("test"); // "test1"

storage.set("Test", "test2"); // keys are case-sensitive, "Test" !== "test"
storage.get("nope"); // undefined

storage.set("variable1", { test: "test", test2: 1 }); // objects/arrays are fine too
storage.set("variable6", null);
storage.set("variable7", undefined); // undefined removes the key entirely

Allowed value types (StorageElementType, from src/storage/types/StorageElementType.ts): strings, numbers, booleans, null/undefined, plain objects and arrays of these — no functions, class instances, or Maps/Sets. For anything richer, use a StoredClassModel (below).

Other storage methods:

  • storage.remove(key) — deletes a variable.
  • storage.flags.set(key, value: boolean) / storage.flags.get(key) — a dedicated boolean-flag store (docs), kept separate from set/get; flags default to false when never set. Keys are case-sensitive here too. The docs recommend flags over storage.set for booleans specifically because of save size: internally all active flags are kept as a single array of names, which is much lighter to serialize than one storage entry per boolean. A documented pattern is exposing a class boolean property that's backed by a flag name (a string) instead of a literal boolean, so the getter/setter transparently reads/writes storage.flags.get/set.
  • storage.default = { key: value, ... } — sets the starting values used when the game boots or after storage.clear(); if you later remove() a key (or it was never set()), reading it falls back to this default instead of undefined.
  • storage.clear() — wipes all stored variables (used by tests/new-game flows), after which reads fall back to storage.default.

Temporary (label-scoped) variables

See pixi-vn.com/start/temp-storage. storage.temp.set(key, value) behaves like storage.set for reads — storage.get(key) checks temp variables first, then falls back to the permanent store — but the value is deleted once the label it was set in closes. It's for scratch state that should reset once the player moves on:

storage.temp.set("counter", counter + 1);
// ... reads still go through storage.get("counter")
storage.temp.remove("counter");

Per the docs' own description of the lifecycle: if the label that set the temp variable calls another label (nested call, e.g. call), the variable stays accessible from that child label too — it's only deleted once the originating label itself closes. But if control moves on via jump (closing the current label and starting a new one instead of nesting into it), the temp variable is gone immediately, since it belonged to the now-closed label. Implementation-wise this is tracked as a deadline against how many labels are open on the call stack at the moment temp.set runs — see tests/storage.test.ts, setTempVariable & getTempVariable, where a temp counter set inside a called label keeps incrementing across narration.continue() steps but is reset once narration.labels.closeCurrent() /closeAll() unwind the label stack. Don't rely on temp variables for state that must outlive the label that set it — use storage.set for that.

2. Custom persisted classes: StoredClassModel

See pixi-vn.com/start/stored-classes. For a richer object whose instances need to persist (survive save/load) and whose fields should be individually get/set, extend StoredClassModel instead of storing a plain object with storage.set. Each instance is identified by a categoryId (shared by all instances of that class) plus a per-instance id; properties are read/written with the protected getStorageProperty/setStorageProperty helpers:

import { StoredClassModel } from "@drincs/pixi-vn";

interface QuestProps {
  title: string;
}

class QuestModel extends StoredClassModel implements QuestProps {
  constructor(id: string, props: QuestProps) {
    super("quest", id); // categoryId, instance id
    this.defaultTitle = props.title;
  }
  readonly defaultTitle: string;

  get title(): string {
    return this.getStorageProperty<string>("title") ?? this.defaultTitle;
  }
  set title(value: string) {
    this.setStorageProperty("title", value);
  }

  get completed(): boolean {
    return this.getStorageProperty<boolean>("completed") ?? false;
  }
  set completed(value: boolean) {
    this.setStorageProperty("completed", value);
  }
}

const findLiam = new QuestModel("find_liam", { title: "Find Liam" });
findLiam.completed = true; // persists under the "quest" category

The constructor arg passed in (e.g. props.title) becomes the default, kept in memory on the instance; setStorageProperty writes an override into storage that takes priority when reading. Passing undefined to setStorageProperty removes that property from storage (falling back to the in-memory default on the next read). This is exactly the pattern CharacterBaseModel uses for name/surname/age — see the characters skill (the docs' own example uses a plain category name like "city"; the library's built-in models happen to fence theirs as "___character___" to avoid any accidental collision, but that underscore style is just a convention, not a requirement — a plain string like "quest" or "city" works the same way).

3. Reserved keys

Do not manually set/read storage keys that collide with the engine's own bookkeeping. The docs' rule of thumb (storage docs) is: system variables use a ___-fenced prefix, so avoid that prefix in your own keys. The full reserved key list lives in the SYSTEM_RESERVED_STORAGE_KEYS constant (src/constants.ts) — in practice most entries are plain namespaced strings without the ___ fence ("dialogue", "dialogue:step_counter", "choice:options", "input:value", "input:info", "character", "label:opened", "choices:made", etc.), with "___glue___" being the one that actually uses the fenced style. Either way, treat every value in that constant as off-limits for your own storage.set/flag keys, to avoid confusion when inspecting exported save data.

4. Relation to save/load and history

Building save/load itself (the Game.exportGameState()/restoreGameState() flow, and how to persist the result) is covered by pixi-vn-saves — you generally don't touch storage directly for that; every variable set through storage is included automatically. The same is true for step-by-step rewind: a snapshot of storage is captured at each recorded history step, so storage variables participate in "go back" too, not just save/load — see pixi-vn-history. storage.clear() resets variables back to whatever was set via storage.default, which is what tests use to get a clean slate between scenarios.

Related skills

pixi-vn-getting-started, pixi-vn-saves, pixi-vn-characters, pixi-vn-history, pixi-vn-narration

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use when adding, organizing, registering, or loading non-code files (images, audio, video) in a Pixi'VN project — local assets processed by PixiJS AssetPack vs. online/remote-hosted assets, the AssetsManifest/bundle/alias system, where to edit the manifest for each case, and when to load bundles (at startup, in the background, per-label, per-route). Load this before writing any code that references an image/sound/video path directly, or before adding entries to a manifest.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

Use when adding, moving, or removing images, sprites, text, or video on the Pixi'VN game canvas, or when applying or creating transitions (dissolve, fade, move, zoom, push, wipe, iris, split, flash, blur, pixelate, or a custom one built on `canvas.animate`/`filters.animate`), shake/animation effects, or ticker-based animations built on PixiJS. Covers the `canvas` singleton exported from `@drincs/pixi-vn`. For UI layers (HTML or PixiJS) mounted on top of the canvas, see `pixi-vn-ui` instead.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

Use when defining visual novel characters for a @drincs/pixi-vn game — creating a character with a name, color, icon and other props, registering it so it can be looked up by id, and referencing it from dialogue/narration. Load this before writing any `CharacterBaseModel` or `RegisteredCharacters` code.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

Use when setting up a new or existing project on @drincs/pixi-vn, wiring the main.ts entry point, or calling the top-level Game API (Game.init, Game.start, Game.onEnd, Game.addOnError, Game.onNavigate, Game.clear) — this is the entry point every Pixi'VN project needs before touching canvas, narration, sound, storage, or history.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

Use when implementing "go back" / "rewind" / step-navigation features in a Pixi'VN game, or when you need to read the player-facing dialogue/choice history (e.g. for a backlog or "history log" UI) — covers the History module's `stepHistory` API and the "step" vs "paragraph" goBackMode.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

Use when upgrading an existing @drincs/pixi-vn project to a newer version, or when a runtime/type error matches a known breaking change. Covers every breaking change between versions with before/after code.

日本語の概要は準備中です。原文の説明を表示しています。

DRincs-Productions/pixi-vn1512026年10月1日 更新

DRincs-Productions のスキルをすべて見る

このスキルの問題を報告する