pixi-vn-migration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Pixi'VN Migration guide

Pixi'VN 迁移指南

Official docs: pixi-vn.com/faq/migration. That page also covers the separate
nqtr
and
pixi-vn-ink
packages — this skill only covers the core
@drincs/pixi-vn
package (the
## pixi-vn
section of that page), since that's what this skill set documents.
官方文档:pixi-vn.com/faq/migration。该页面还涵盖独立的
nqtr
和
pixi-vn-ink
包——本 skill 仅涵盖核心
@drincs/pixi-vn
包(该页面的
## pixi-vn
部分),因为这正是此 skill 集所记录的内容。

When to use this skill

何时使用此 skill

Use this skill whenever a task is "upgrade this project's
@drincs/pixi-vn
from version X to the latest", or a developer hits an error that looks like a removed/renamed API. Check the currently installed version first (
package.json
dependency, or
PIXIVN_VERSION
/
GameState.pixivn_version
at runtime — see
pixi-vn-getting-started
), then walk forward through only the version sections below that fall between the installed version and the target — most of these changes don't apply unless a project is crossing that specific boundary.
当任务为“将此项目的
@drincs/pixi-vn
从版本 X 升级到最新版本”,或开发者遇到看起来像 API 被移除或重命名的错误时,使用此 skill。先检查当前安装的版本(
package.json
依赖,或运行时的
PIXIVN_VERSION
/
GameState.pixivn_version
——参见
pixi-vn-getting-started
),然后只向前遍历下面那些处于已安装版本与目标版本之间的版本章节——除非项目恰好跨越特定边界,否则大多数变更都不适用。

v1.9.3 → v1.9.4 — canvas transitions/effects namespaces, top-level
tickers

v1.9.3 → v1.9.4——Canvas 过渡/效果命名空间、顶层
tickers

Canvas transitions and effects namespaces

Canvas 过渡和效果命名空间

Canvas transition helpers and canvas effects are now also grouped under discoverable namespaces:
transitions
contains
showWithDissolve
,
showWithFade
,
moveIn
,
moveOut
,
zoomIn
,
zoomOut
,
pushIn
,
pushOut
,
removeWithDissolve
, and
removeWithFade
;
effects
contains
shakeEffect
.
The previous flat exports remain available in v1.9.4 for compatibility, but are deprecated. Update imports and calls when migrating:
ts
import { moveIn, shakeEffect, zoomIn } from "@drincs/pixi-vn"; // [!code --]
import { effects, transitions } from "@drincs/pixi-vn"; // [!code ++]

await zoomIn("alice", "alice"); // [!code --]
await transitions.zoomIn("alice", "alice"); // [!code ++]

await moveIn("alice", "alice"); // [!code --]
await transitions.moveIn("alice", "alice"); // [!code ++]

shakeEffect("alice"); // [!code --]
effects.shakeEffect("alice"); // [!code ++]
The transition and effect behavior and their options are unchanged. This is an organizational API change intended to make canvas helpers easier to discover. The existing module entry points remain valid; the same namespaces are available from
@drincs/pixi-vn/canvas
.
Canvas 过渡辅助函数和 Canvas 效果现在也被归入易于发现的命名空间:
transitions
包含
showWithDissolve
、
showWithFade
、
moveIn
、
moveOut
、
zoomIn
、
zoomOut
、
pushIn
、
pushOut
、
removeWithDissolve
和
removeWithFade
;
effects
包含
shakeEffect
。
在 v1.9.4 中,之前的扁平导出仍可使用以保持兼容,但已被弃用。迁移时请更新 import 和调用方式:
ts
import { moveIn, shakeEffect, zoomIn } from "@drincs/pixi-vn"; // [!code --]
import { effects, transitions } from "@drincs/pixi-vn"; // [!code ++]

await zoomIn("alice", "alice"); // [!code --]
await transitions.zoomIn("alice", "alice"); // [!code ++]

await moveIn("alice", "alice"); // [!code --]
await transitions.moveIn("alice", "alice"); // [!code ++]

shakeEffect("alice"); // [!code --]
effects.shakeEffect("alice"); // [!code ++]
过渡和效果的行为及其选项均未改变。这是一项组织形式的 API 变更,旨在让 Canvas 辅助函数更容易被发现。现有的模块入口仍然有效;同样的命名空间也可从
@drincs/pixi-vn/canvas
获得。

canvas.tickers
→ top-level
tickers

canvas.tickers
→ 顶层
tickers

Ticker management is no longer part of the canvas manager: it's its own
tickers
singleton, exported from
@drincs/pixi-vn
next to
canvas
,
sound
, etc.
canvas.tickers
still works in v1.9.4 — it just forwards to
tickers
— but it's deprecated. The methods and their arguments are unchanged; only the receiver changes:
ts
import { canvas } from "@drincs/pixi-vn"; // [!code --]
import { tickers } from "@drincs/pixi-vn"; // [!code ++]

canvas.tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code --]
tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code ++]

canvas.tickers.pause({ canvasAlias: "alien" }); // [!code --]
tickers.pause({ canvasAlias: "alien" }); // [!code ++]

await canvas.tickers.forceCompletion(id); // [!code --]
await tickers.forceCompletion(id); // [!code ++]
The same applies to every other member (
addSequence
,
find
,
remove
,
removeAll
,
resume
,
isPaused
,
unlinkComponent
,
transfer
,
completeOnStepEnd
,
onComplete
,
currentTickers
,
currentTickersSteps
). The type
CanvasTickersInterface
is likewise a deprecated alias of the new
TickersInterface
:
ts
import type { CanvasTickersInterface } from "@drincs/pixi-vn"; // [!code --]
import type { TickersInterface } from "@drincs/pixi-vn"; // [!code ++]
TickerBase
,
tickerDecorator
,
RegisteredTickers
, and the
Ticker*
types are still exported from
@drincs/pixi-vn
exactly as before. Saves are unaffected: tickers are still serialized as part of the canvas state.
Only code that reached into canvas internals breaks: the ticker bookkeeping on
CanvasManagerStatic
(
_currentTickers
,
_currentTickersSequence
,
_currentTickersTimeouts
,
_tickersToCompleteOnStepEnd
,
currentTickersWithoutCreatedBySteps
,
currentTickersSequence
,
generateTickerId
,
addTickerTimeoutInfo
,
removeTickerTimeout*
) moved to the
TickersManagerStatic
namespace, where the two former getters are now functions:
ts
CanvasManagerStatic._currentTickers; // [!code --]
TickersManagerStatic._currentTickers; // [!code ++]

CanvasManagerStatic.currentTickersSequence; // [!code --]
TickersManagerStatic.currentTickersSequence(); // [!code ++]
Prefer the public
tickers.currentTickers
/
tickers.currentTickersSteps
over either.
Ticker 管理不再属于 Canvas 管理器,而是成为独立的
tickers
单例, 从
@drincs/pixi-vn
与
canvas
、
sound
等一起导出。在 v1.9.4 中,
canvas.tickers
仍然可用—— 它只会转发到
tickers
——但已被弃用。方法及其参数未改变;只有调用接收者发生了变化:
ts
import { canvas } from "@drincs/pixi-vn"; // [!code --]
import { tickers } from "@drincs/pixi-vn"; // [!code ++]

canvas.tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code --]
tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code ++]

canvas.tickers.pause({ canvasAlias: "alien" }); // [!code --]
tickers.pause({ canvasAlias: "alien" }); // [!code ++]

await canvas.tickers.forceCompletion(id); // [!code --]
await tickers.forceCompletion(id); // [!code ++]
同样的变化也适用于所有其他成员(
addSequence
、
find
、
remove
、
removeAll
、
resume
、
isPaused
、
unlinkComponent
、
transfer
、
completeOnStepEnd
、
onComplete
、
currentTickers
、
currentTickersSteps
)。类型
CanvasTickersInterface
同样是新
TickersInterface
的弃用别名:
ts
import type { CanvasTickersInterface } from "@drincs/pixi-vn"; // [!code --]
import type { TickersInterface } from "@drincs/pixi-vn"; // [!code ++]
TickerBase
、
tickerDecorator
、
RegisteredTickers
和所有
Ticker*
类型仍按原样从
@drincs/pixi-vn
导出。存档不受影响:Ticker 仍作为 Canvas 状态的一部分进行序列化。
只有访问 Canvas 内部实现的代码会受到影响:
CanvasManagerStatic
上的 Ticker 管理状态 (
_currentTickers
、
_currentTickersSequence
、
_currentTickersTimeouts
、
_tickersToCompleteOnStepEnd
、
currentTickersWithoutCreatedBySteps
、
currentTickersSequence
、
generateTickerId
、
addTickerTimeoutInfo
、
removeTickerTimeout*
)已移至
TickersManagerStatic
命名空间,原有两个 getter 现在是函数:
ts
CanvasManagerStatic._currentTickers; // [!code --]
TickersManagerStatic._currentTickers; // [!code ++]

CanvasManagerStatic.currentTickersSequence; // [!code --]
TickersManagerStatic.currentTickersSequence(); // [!code ++]
优先使用公开的
tickers.currentTickers
/
tickers.currentTickersSteps
,而不是上述任一方式。

v1.8.x → v1.9.0 — long-deprecated APIs removed

v1.8.x → v1.9.0——移除长期弃用的 API

This release removes several APIs that had been marked
@deprecated
for a while, with no replacement other than the one already documented at deprecation time:
Repeat
/
Pause(duration)
and the
RepeatType
/
PauseType
types are gone.
canvas.addTickersSequence
now only accepts plain
Ticker
steps — chain tickers by duration instead of pause/repeat markers:
ts
canvas.addTickersSequence("alien", [
  new RotateTicker({ speed: 0.1, clockwise: true }, 2),
  Pause(1), // [!code --]
  new RotateTicker({ speed: 0.2, clockwise: false }, 2),
  Repeat, // [!code --]
]);
See
pixi-vn-canvas
/
tickers.md
for the current sequencing API.
forceCompleteBeforeNext
is gone from every transition helper (
showWithDissolve
,
moveIn
,
zoomIn
, ...) and from
CommonTickerProps
— use
completeOnContinue
directly, it's no longer just an alias:
ts
await showWithDissolve("alice", "alice", {
  forceCompleteBeforeNext: true, // [!code --]
  completeOnContinue: true, // [!code ++]
});
The deprecated
AssetMemory.image
field was removed; use
AssetMemory.alias
/
url
instead.
Game.restoreGameState(data, navigate)
lost its
navigate
overload — pass only
data
, and configure navigation once via
Game.onNavigate
(or
Game.init({ navigate })
) instead:
ts
Game.restoreGameState(data, navigateTo); // [!code --]
Game.restoreGameState(data); // [!code ++]
The singular
Game.onError(...)
handler was removed; use
Game.addOnError
/
Game.removeOnError
(already the recommended API since v1.6.0):
ts
Game.onError((type, error, { notify, uiTransition }) => { ... }); // [!code --]
Game.addOnError((error, { notify, uiTransition }) => { ... }); // [!code ++]
See
pixi-vn-canvas
/
tickers.md
for the current tickers/transitions API and
pixi-vn-getting-started
for the current
Game
API.
此版本删除了多个早已标记为
@deprecated
的 API,且除了弃用时已经记录的替代方案外, 没有其他替代项:
Repeat
/
Pause(duration)
以及
RepeatType
/
PauseType
类型已被移除。
canvas.addTickersSequence
现在仅接受普通
Ticker
步骤——请通过持续时间串联 Ticker,而不是使用暂停/重复标记:
ts
canvas.addTickersSequence("alien", [
  new RotateTicker({ speed: 0.1, clockwise: true }, 2),
  Pause(1), // [!code --]
  new RotateTicker({ speed: 0.2, clockwise: false }, 2),
  Repeat, // [!code --]
]);
有关当前的排序 API,请参阅
pixi-vn-canvas
/
tickers.md
。 所有过渡辅助函数(
showWithDissolve
、
moveIn
、
zoomIn
等)以及
CommonTickerProps
中的
forceCompleteBeforeNext
均已被移除——请直接使用
completeOnContinue
,它现在不再只是别名:
ts
await showWithDissolve("alice", "alice", {
  forceCompleteBeforeNext: true, // [!code --]
  completeOnContinue: true, // [!code ++]
});
弃用的
AssetMemory.image
字段已被移除;请改用
AssetMemory.alias
/
url
。
Game.restoreGameState(data, navigate)
移除了
navigate
重载——只传入
data
,并通过
Game.onNavigate
(或
Game.init({ navigate })
)统一配置导航:
ts
Game.restoreGameState(data, navigateTo); // [!code --]
Game.restoreGameState(data); // [!code ++]
单数形式的
Game.onError(...)
处理器已被移除;请改用
Game.addOnError
/
Game.removeOnError
(自 v1.6.0 起已是推荐 API):
ts
Game.onError((type, error, { notify, uiTransition }) => { ... }); // [!code --]
Game.addOnError((error, { notify, uiTransition }) => { ... }); // [!code ++]
有关当前的 Ticker/过渡 API,请参阅
pixi-vn-canvas
/
tickers.md
; 有关当前的
Game
API,请参阅
pixi-vn-getting-started
。

Manager APIs reorganized into namespaces

Manager API 重组为命名空间

The
canvas
,
sound
,
storage
, and
narration
managers used to expose dozens of unrelated methods directly on the manager (ticker methods, layer methods, and HTML-layer methods all mixed together on
canvas
, for example). This release groups related operations into namespaced sub-APIs —
canvas.tickers
/
.layers
/
.htmlLayers
,
sound.channels
/
.unsaved
,
storage.temp
/
.flags
,
narration.labels
/
.queries
/
.input
/
.choices
— so each manager reads as a short, discoverable surface instead of a flat list, and related options/overloads live next to each other. See
pixi-vn-canvas
,
pixi-vn-sound
,
pixi-vn-storage
, and
pixi-vn-getting-started
for the current shape of each namespace.
Almost every old flat method still works and just forwards to its namespaced replacement — it's marked
@deprecated
but not removed, so migrate at your own pace. Two members are an exception: their type changed, so they break immediately rather than just warning.
sound.channels
was
AudioChannelInterface[]
; it is now an object, and the array moved to
.values
:
ts
sound.channels.map((c) => c.alias); // [!code --]
sound.channels.values.map((c) => c.alias); // [!code ++]
narration.choices
(getter) was
StoredIndexedChoiceInterface[] | undefined
; it now returns a namespace object, and the array moved to
.list
. The setter,
narration.choices = [...]
, is unchanged — it's a shortcut for
.list
:
ts
const choices = narration.choices; // [!code --]
const choices = narration.choices.list; // [!code ++]
Every other rename below is a non-breaking, forward-compatible deprecation.
canvas
's ticker methods moved to
canvas.tickers
(since v1.9.4 that is itself a deprecated alias of the top-level
tickers
— if you are migrating past v1.9.4, go straight to
tickers.*
, see v1.9.3 → v1.9.4 above):
ts
canvas.transferTickers("old", "new"); // [!code --]
canvas.tickers.transfer("old", "new"); // [!code ++]
ts
canvas.currentTickers; // [!code --]
canvas.tickers.currentTickers; // [!code ++]
ts
canvas.currentTickersSteps; // [!code --]
canvas.tickers.currentTickersSteps; // [!code ++]
ts
canvas.findTicker("t1"); // [!code --]
canvas.tickers.find("t1"); // [!code ++]
ts
canvas.addTicker("alien", new RotateTicker({ speed: 0.2 })); // [!code --]
canvas.tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code ++]
ts
canvas.addTickersSequence("alien", steps); // [!code --]
canvas.tickers.addSequence("alien", steps); // [!code ++]
ts
canvas.unlinkComponentFromTicker("alien", RotateTicker); // [!code --]
canvas.tickers.unlinkComponent("alien", RotateTicker); // [!code ++]
ts
canvas.removeAllTickers(); // [!code --]
canvas.tickers.removeAll(); // [!code ++]
ts
canvas.removeTicker("t1"); // [!code --]
canvas.tickers.remove("t1"); // [!code ++]
ts
canvas.pauseTicker({ canvasAlias: "alien" }); // [!code --]
canvas.tickers.pause({ canvasAlias: "alien" }); // [!code ++]
ts
canvas.resumeTicker({ canvasAlias: "alien" }); // [!code --]
canvas.tickers.resume({ canvasAlias: "alien" }); // [!code ++]
ts
canvas.isTickerPaused("alien"); // [!code --]
canvas.tickers.isPaused("alien"); // [!code ++]
ts
canvas.completeTickerOnStepEnd({ id: "t1" }); // [!code --]
canvas.tickers.completeOnStepEnd({ id: "t1" }); // [!code ++]
ts
canvas.forceCompletionOfTicker("t1"); // [!code --]
canvas.tickers.forceCompletion("t1"); // [!code ++]
ts
canvas.onTickerComplete("t1", options); // [!code --]
canvas.tickers.onComplete("t1", options); // [!code ++]
canvas
's layer methods moved to
canvas.layers
:
ts
canvas.gameLayer; // [!code --]
canvas.layers.gameLayer; // [!code ++]
ts
canvas.addLayer("ui", uiLayer); // [!code --]
canvas.layers.add("ui", uiLayer); // [!code ++]
ts
canvas.getLayer("ui"); // [!code --]
canvas.layers.get("ui"); // [!code ++]
ts
canvas.removeLayer("ui"); // [!code --]
canvas.layers.remove("ui"); // [!code ++]
canvas
's HTML-layer methods moved to
canvas.htmlLayers
:
ts
canvas.addHtmlLayer("ui", root); // [!code --]
canvas.htmlLayers.add("ui", root); // [!code ++]
ts
canvas.getHtmlLayer("ui"); // [!code --]
canvas.htmlLayers.get("ui"); // [!code ++]
ts
canvas.removeHtmlLayer("ui"); // [!code --]
canvas.htmlLayers.remove("ui"); // [!code ++]
sound
's transient/unsaved playback methods moved to
sound.unsaved
:
ts
sound.playTransient("ui-click"); // [!code --]
sound.unsaved.playTransient("ui-click"); // [!code ++]
ts
sound.pauseUnsavedAll(); // [!code --]
sound.unsaved.pauseAll(); // [!code ++]
ts
sound.resumeUnsavedAll(); // [!code --]
sound.unsaved.resumeAll(); // [!code ++]
ts
sound.stopTransientAll(); // [!code --]
sound.unsaved.stopTransientAll(); // [!code ++]
sound
's channel creation/lookup methods moved to
sound.channels
(alongside the
.values
change above):
ts
sound.addChannel("music"); // [!code --]
sound.channels.add("music"); // [!code ++]
ts
sound.findChannel("music"); // [!code --]
sound.channels.find("music"); // [!code ++]
storage
's temporary-variable methods moved to
storage.temp
(a new
storage.temp.deadlines
map is exposed alongside them):
ts
storage.setTempVariable("key", "value"); // [!code --]
storage.temp.set("key", "value"); // [!code ++]
ts
storage.removeTempVariable("key"); // [!code --]
storage.temp.remove("key"); // [!code ++]
storage
's flag methods moved to
storage.flags
:
ts
storage.setFlag("introSeen", true); // [!code --]
storage.flags.set("introSeen", true); // [!code ++]
ts
storage.getFlag("introSeen"); // [!code --]
storage.flags.get("introSeen"); // [!code ++]
narration
's label-stack members moved to
narration.labels
:
ts
narration.openedLabels; // [!code --]
narration.labels.opened; // [!code ++]
ts
narration.currentLabel; // [!code --]
narration.labels.current; // [!code ++]
ts
narration.closeCurrentLabel(); // [!code --]
narration.labels.closeCurrent(); // [!code ++]
ts
narration.closeAllLabels(); // [!code --]
narration.labels.closeAll(); // [!code ++]
narration
's read-only queries moved to
narration.queries
:
ts
narration.isLabelAlreadyCompleted(label); // [!code --]
narration.queries.isLabelAlreadyCompleted(label); // [!code ++]
ts
narration.alreadyCurrentStepMadeChoices; // [!code --]
narration.queries.alreadyCurrentStepMadeChoices; // [!code ++]
ts
narration.isCurrentStepAlreadyOpened; // [!code --]
narration.queries.isCurrentStepAlreadyOpened; // [!code ++]
ts
narration.getTimesLabelOpened(label); // [!code --]
narration.queries.timesLabelOpened(label); // [!code ++]
ts
narration.getTimesChoiceMade(index); // [!code --]
narration.queries.timesChoiceMade(index); // [!code ++]
narration
's input-request members moved to
narration.input
:
ts
narration.inputValue; // [!code --]
narration.input.value; // [!code ++]
ts
narration.isRequiredInput; // [!code --]
narration.input.isRequired; // [!code ++]
ts
narration.inputType; // [!code --]
narration.input.type; // [!code ++]
ts
narration.requestInput({ type: "number" }); // [!code --]
narration.input.request({ type: "number" }); // [!code ++]
ts
narration.removeInputRequest(); // [!code --]
narration.input.removeRequest(); // [!code ++]
narration
's choice selection moved to
narration.choices
(alongside the
.list
change above):
ts
narration.selectChoice(choices[0], {}); // [!code --]
narration.choices.select(choices[0], {}); // [!code ++]
过去,
canvas
、
sound
、
storage
和
narration
管理器直接在管理器本身上公开了数十个互不相关的 方法(例如,Ticker 方法、图层方法和 HTML 图层方法全都混在
canvas
上)。此版本将相关操作归入 带命名空间的子 API——
canvas.tickers
/
.layers
/
.htmlLayers
、
sound.channels
/
.unsaved
、
storage.temp
/
.flags
、
narration.labels
/
.queries
/
.input
/
.choices
——使每个管理器都呈现为 一组简短、易于发现的接口,而不是扁平的方法列表;相关选项和重载也会集中在一起。 有关每个命名空间当前的结构,请参阅
pixi-vn-canvas
、
pixi-vn-sound
、
pixi-vn-storage
和
pixi-vn-getting-started
。
几乎所有旧的扁平方法仍然可用,并且只会转发到对应的命名空间替代项——它们被标记为
@deprecated
,但尚未移除,因此你可以按自己的节奏进行迁移。有两个成员例外: 它们的类型发生了变化,因此会立即导致错误,而不只是给出警告。
sound.channels
过去是
AudioChannelInterface[]
;现在它是一个对象,数组则移至
.values
:
ts
sound.channels.map((c) => c.alias); // [!code --]
sound.channels.values.map((c) => c.alias); // [!code ++]
narration.choices
(getter)过去是
StoredIndexedChoiceInterface[] | undefined
;现在它返回一个 命名空间对象,数组则移至
.list
。Setter
narration.choices = [...]
保持不变——它是
.list
的快捷方式:
ts
const choices = narration.choices; // [!code --]
const choices = narration.choices.list; // [!code ++]
以下所有其他重命名均属于非破坏性、向前兼容的弃用。
canvas
的 Ticker 方法已移至
canvas.tickers
(自 v1.9.4 起,它本身又是顶层
tickers
的弃用 别名——如果迁移目标版本晚于 v1.9.4,请直接使用
tickers.*
,参见上文 v1.9.3 → v1.9.4):
ts
canvas.transferTickers("old", "new"); // [!code --]
canvas.tickers.transfer("old", "new"); // [!code ++]
ts
canvas.currentTickers; // [!code --]
canvas.tickers.currentTickers; // [!code ++]
ts
canvas.currentTickersSteps; // [!code --]
canvas.tickers.currentTickersSteps; // [!code ++]
ts
canvas.findTicker("t1"); // [!code --]
canvas.tickers.find("t1"); // [!code ++]
ts
canvas.addTicker("alien", new RotateTicker({ speed: 0.2 })); // [!code --]
canvas.tickers.add("alien", new RotateTicker({ speed: 0.2 })); // [!code ++]
ts
canvas.addTickersSequence("alien", steps); // [!code --]
canvas.tickers.addSequence("alien", steps); // [!code ++]
ts
canvas.unlinkComponentFromTicker("alien", RotateTicker); // [!code --]
canvas.tickers.unlinkComponent("alien", RotateTicker); // [!code ++]
ts
canvas.removeAllTickers(); // [!code --]
canvas.tickers.removeAll(); // [!code ++]
ts
canvas.removeTicker("t1"); // [!code --]
canvas.tickers.remove("t1"); // [!code ++]
ts
canvas.pauseTicker({ canvasAlias: "alien" }); // [!code --]
canvas.tickers.pause({ canvasAlias: "alien" }); // [!code ++]
ts
canvas.resumeTicker({ canvasAlias: "alien" }); // [!code --]
canvas.tickers.resume({ canvasAlias: "alien" }); // [!code ++]
ts
canvas.isTickerPaused("alien"); // [!code --]
canvas.tickers.isPaused("alien"); // [!code ++]
ts
canvas.completeTickerOnStepEnd({ id: "t1" }); // [!code --]
canvas.tickers.completeOnStepEnd({ id: "t1" }); // [!code ++]
ts
canvas.forceCompletionOfTicker("t1"); // [!code --]
canvas.tickers.forceCompletion("t1"); // [!code ++]
ts
canvas.onTickerComplete("t1", options); // [!code --]
canvas.tickers.onComplete("t1", options); // [!code ++]
canvas
的图层方法已移至
canvas.layers
:
ts
canvas.gameLayer; // [!code --]
canvas.layers.gameLayer; // [!code ++]
ts
canvas.addLayer("ui", uiLayer); // [!code --]
canvas.layers.add("ui", uiLayer); // [!code ++]
ts
canvas.getLayer("ui"); // [!code --]
canvas.layers.get("ui"); // [!code ++]
ts
canvas.removeLayer("ui"); // [!code --]
canvas.layers.remove("ui"); // [!code ++]
canvas
的 HTML 图层方法已移至
canvas.htmlLayers
:
ts
canvas.addHtmlLayer("ui", root); // [!code --]
canvas.htmlLayers.add("ui", root); // [!code ++]
ts
canvas.getHtmlLayer("ui"); // [!code --]
canvas.htmlLayers.get("ui"); // [!code ++]
ts
canvas.removeHtmlLayer("ui"); // [!code --]
canvas.htmlLayers.remove("ui"); // [!code ++]
sound
的临时/未保存播放方法已移至
sound.unsaved
:
ts
sound.playTransient("ui-click"); // [!code --]
sound.unsaved.playTransient("ui-click"); // [!code ++]
ts
sound.pauseUnsavedAll(); // [!code --]
sound.unsaved.pauseAll(); // [!code ++]
ts
sound.resumeUnsavedAll(); // [!code --]
sound.unsaved.resumeAll(); // [!code ++]
ts
sound.stopTransientAll(); // [!code --]
sound.unsaved.stopTransientAll(); // [!code ++]
sound
的频道创建和查找方法已移至
sound.channels
(同时包含上文的
.values
变更):
ts
sound.addChannel("music"); // [!code --]
sound.channels.add("music"); // [!code ++]
ts
sound.findChannel("music"); // [!code --]
sound.channels.find("music"); // [!code ++]
storage
的临时变量方法已移至
storage.temp
(同时新增了
storage.temp.deadlines
映射):
ts
storage.setTempVariable("key", "value"); // [!code --]
storage.temp.set("key", "value"); // [!code ++]
ts
storage.removeTempVariable("key"); // [!code --]
storage.temp.remove("key"); // [!code ++]
storage
的标记方法已移至
storage.flags
:
ts
storage.setFlag("introSeen", true); // [!code --]
storage.flags.set("introSeen", true); // [!code ++]
ts
storage.getFlag("introSeen"); // [!code --]
storage.flags.get("introSeen"); // [!code ++]
narration
的标签栈成员已移至
narration.labels
:
ts
narration.openedLabels; // [!code --]
narration.labels.opened; // [!code ++]
ts
narration.currentLabel; // [!code --]
narration.labels.current; // [!code ++]
ts
narration.closeCurrentLabel(); // [!code --]
narration.labels.closeCurrent(); // [!code ++]
ts
narration.closeAllLabels(); // [!code --]
narration.labels.closeAll(); // [!code ++]
narration
的只读查询已移至
narration.queries
:
ts
narration.isLabelAlreadyCompleted(label); // [!code --]
narration.queries.isLabelAlreadyCompleted(label); // [!code ++]
ts
narration.alreadyCurrentStepMadeChoices; // [!code --]
narration.queries.alreadyCurrentStepMadeChoices; // [!code ++]
ts
narration.isCurrentStepAlreadyOpened; // [!code --]
narration.queries.isCurrentStepAlreadyOpened; // [!code ++]
ts
narration.getTimesLabelOpened(label); // [!code --]
narration.queries.timesLabelOpened(label); // [!code ++]
ts
narration.getTimesChoiceMade(index); // [!code --]
narration.queries.timesChoiceMade(index); // [!code ++]
narration
的输入请求成员已移至
narration.input
:
ts
narration.inputValue; // [!code --]
narration.input.value; // [!code ++]
ts
narration.isRequiredInput; // [!code --]
narration.input.isRequired; // [!code ++]
ts
narration.inputType; // [!code --]
narration.input.type; // [!code ++]
ts
narration.requestInput({ type: "number" }); // [!code --]
narration.input.request({ type: "number" }); // [!code ++]
ts
narration.removeInputRequest(); // [!code --]
narration.input.removeRequest(); // [!code ++]
narration
的选项选择已移至
narration.choices
(同时包含上文的
.list
变更):
ts
narration.selectChoice(choices[0], {}); // [!code --]
narration.choices.select(choices[0], {}); // [!code ++]

v1.7.x → v1.8.0 — Tone.js audio engine

v1.7.x → v1.8.0——Tone.js 音频引擎

The audio system moved from
@pixi/sound
to Tone.js (performance, stability, flexibility). Two consequences (full API in
pixi-vn-sound
):
  • A
    media
    's
    volume
    is no longer a plain linear number — it's now a Tone.js decibel
    Param
    :
    ts
    const bgmMedia = sound.find("bgm_cheerful");
    if (bgmMedia) bgmMedia.volume = 90; // [!code --]
    if (bgmMedia) bgmMedia.volume.value = 90; // [!code ++]
  • Editing an already-loaded audio asset directly (
    sound.edit(alias, options)
    ) is no longer possible — there is no replacement call; re-load/re-play with new options instead.
出于性能、稳定性和灵活性的考虑,音频系统从
@pixi/sound
迁移到了 Tone.js。由此产生两项 影响(完整 API 见
pixi-vn-sound
):
  • media
    的
    volume
    不再是普通的线性数字——现在它是 Tone.js 的分贝
    Param
    :
    ts
    const bgmMedia = sound.find("bgm_cheerful");
    if (bgmMedia) bgmMedia.volume = 90; // [!code --]
    if (bgmMedia) bgmMedia.volume.value = 90; // [!code ++]
  • 无法再直接编辑已加载的音频素材(
    sound.edit(alias, options)
    )——没有对应的替代调用; 请改用新选项重新加载/播放。

v1.6.x → v1.7.0 — template integration cleanup

v1.6.x → v1.7.0——模板集成清理

  • HTML layers (
    canvas.addHtmlLayer
    ) now default to
    userSelect: "none"
    (prevents accidental text selection during UI interaction). Opt back in per layer if needed:
    ts
    const htmlLayer = canvas.addHtmlLayer("ui", root, { userSelect: "auto" }); // [!code ++]
  • Navigation is now centralized: use
    Game.onNavigate
    once instead of passing a navigate function to every call site that needs one (see
    pixi-vn-getting-started
    ):
    ts
    Game.onNavigate((path) => navigateTo(path)); // [!code ++]
    
    Game.restoreGameState(data, navigateTo); // [!code --]
    Game.restoreGameState(data); // [!code ++]
  • Custom UI storage reactivity:
    storage.setStorageHandler({ onSetVariable, onRemoveVariable, onClearOldTempVariable })
    lets a UI state store mirror game-storage changes automatically (see
    pixi-vn-storage
    ) — new capability, not a breaking change, but worth knowing this version added it.
  • HTML 图层(
    canvas.addHtmlLayer
    )现在默认使用
    userSelect: "none"
    (可防止 UI 交互期间意外选中文本)。 如有需要,可按图层重新启用:
    ts
    const htmlLayer = canvas.addHtmlLayer("ui", root, { userSelect: "auto" }); // [!code ++]
  • 导航现已集中管理:请一次性使用
    Game.onNavigate
    ,而不是在每个需要导航的调用点传入导航函数 (参见
    pixi-vn-getting-started
    ):
    ts
    Game.onNavigate((path) => navigateTo(path)); // [!code ++]
    
    Game.restoreGameState(data, navigateTo); // [!code --]
    Game.restoreGameState(data); // [!code ++]
  • 自定义 UI 存储响应性:
    storage.setStorageHandler({ onSetVariable, onRemoveVariable, onClearOldTempVariable })
    可让 UI 状态存储自动映射游戏存储的变化(参见
    pixi-vn-storage
    )——这是新增能力,不是破坏性变更, 但值得了解此版本新增了该功能。

v1.5.x → v1.6.0 — sound module rewrite,
Game.start
, storage key convention,
addOnError

v1.5.x → v1.6.0——Sound 模块重写、
Game.start
、存储键约定、
addOnError

The sound API was completely redesigned around the
sound
/
channels
/
media
/
assets
split (see
pixi-vn-sound
for the current shape):
ts
sound.add("bird", "resources/bird.mp3"); // [!code --]
sound.play("bird", { loop: true }); // [!code ++] (sound.play replaces add()+play())

let s = sound.add("bird", { url: "resources/bird.mp3", loop: true }); // [!code --]
s.play(); // [!code --]
s.pause(); // [!code --]
sound.play("bird", { loop: true }); // [!code ++]
sound.pause("bird"); // [!code ++]
Other changes this version:
  • Game.start(label, props)
    was added as the recommended entry point (see
    pixi-vn-getting-started
    ) instead of the previous
    Game.clear()
    +
    narration.call(...)
    pair:
    ts
    Game.clear(); // [!code --]
    narration.call("start", gameProps); // [!code --]
    Game.start("start", gameProps); // [!code ++]
  • Storage keys adopted a
    :
    -separated namespacing convention (e.g.
    character:alice:friendship
    ) — doesn't break existing saves or the API, just a recommended naming style (see
    pixi-vn-storage
    ).
  • Error handling moved to
    Game.addOnError
    (supports multiple stacked handlers) instead of the singular, now-deprecated
    Game.onError
    , and dropped the
    type
    argument (see
    pixi-vn-getting-started
    ):
    ts
    Game.onError((type, error, { notify, uiTransition }) => { ... }); // [!code --]
    Game.addOnError((error, { toast, uiTransition }) => { ... }); // [!code ++]
Sound API 已围绕
sound
/
channels
/
media
/
assets
拆分进行了彻底重新设计 (有关当前结构,请参阅
pixi-vn-sound
):
ts
sound.add("bird", "resources/bird.mp3"); // [!code --]
sound.play("bird", { loop: true }); // [!code ++] (sound.play replaces add()+play())

let s = sound.add("bird", { url: "resources/bird.mp3", loop: true }); // [!code --]
s.play(); // [!code --]
s.pause(); // [!code --]
sound.play("bird", { loop: true }); // [!code ++]
sound.pause("bird"); // [!code ++]
此版本的其他变更:
  • 新增
    Game.start(label, props)
    作为推荐入口(参见
    pixi-vn-getting-started
    ), 用于替代之前的
    Game.clear()
    +
    narration.call(...)
    组合:
    ts
    Game.clear(); // [!code --]
    narration.call("start", gameProps); // [!code --]
    Game.start("start", gameProps); // [!code ++]
  • 存储键采用以
    :
    分隔的命名空间约定(例如
    character:alice:friendship
    )—— 这不会破坏现有存档或 API,只是推荐的命名风格(参见
    pixi-vn-storage
    )。
  • 错误处理迁移至
    Game.addOnError
    (支持叠加多个处理器),不再使用单数形式、现已弃用的
    Game.onError
    ,同时移除了
    type
    参数(参见
    pixi-vn-getting-started
    ):
    ts
    Game.onError((type, error, { notify, uiTransition }) => { ... }); // [!code --]
    Game.addOnError((error, { toast, uiTransition }) => { ... }); // [!code ++]

v1.4.x → v1.5.0 —
pixi.js
external, canvas resize CSS

v1.4.x → v1.5.0——
pixi.js
external、Canvas 调整尺寸 CSS

  • pixi.js
    is now marked external for non-CDN builds (Vite, official templates) — needed because
    pixi.js
    doesn't support multiple bundled instances; only relevant if something in the build config assumed it was bundled.
  • The canvas resizing logic changed; if upgrading an existing (pre-v1.5.4) template, update the base CSS to match the current one (see
    pixi-vn-getting-started
    's exact
    index.html
    /
    styles.css
    ).
  • 对于非 CDN 构建(Vite、官方模板),
    pixi.js
    现在被标记为 external——这是必需的, 因为
    pixi.js
    不支持同时打包多个实例;仅当构建配置原先假定它会被打包时才与此相关。
  • Canvas 调整尺寸的逻辑发生了变化;如果升级的是现有的(v1.5.4 之前)模板, 请将基础 CSS 更新为当前版本(参见
    pixi-vn-getting-started
    中确切的
    index.html
    /
    styles.css
    )。

v1.3.x → v1.4.0 —
stepHistory.back()
takes props, not a navigate function

v1.3.x → v1.4.0——
stepHistory.back()
接受 props,而不是导航函数

To support synchronous multi-step back/continue requests,
stepHistory.back()
's argument changed from a path-navigation callback to the same
StepLabelProps
-shaped object passed to every step — the actual navigate function now lives on
Game.init()
instead (see
pixi-vn-history
/
pixi-vn-getting-started
):
ts
stepHistory.back((_path) => {
  /* navigate in the url path */
}); // [!code --]
const gameProps = {};
stepHistory.back(gameProps); // [!code ++]
ts
Game.init(body, {
  height: 1080,
  width: 1920,
  backgroundColor: "#303030",
  navigate: (_path) => {
    /* navigate in the url path */
  }, // [!code ++]
}).then(() => {
  /* ... */
});
Also removed in this release (all long-deprecated):
stepHistory.goBack
,
narration.goNext
,
PIXI
(the re-exported namespace),
canvas.canvasWidth
/
canvas.canvasHeight
,
canvas.onEndOfTicker
, the
FadeAlphaTicker
/
MoveTicker
/
RotateTicker
/
ZoomTicker
preset classes,
narration.canContinue
(now
stepHistory
-side),
narration.callLabel
/
jumpLabel
(now
call
/
jump
),
narration.choiceMenuOptions
,
storage.startingStorage
/
setVariable
/
getVariable
/
removeVariable
(now
storage.default
/
set
/
get
/
remove
).
为了支持同步的多步后退/继续请求,
stepHistory.back()
的参数已从路径导航回调改为与每个步骤 所接收对象形状相同的
StepLabelProps
——实际的导航函数现在位于
Game.init()
中 (参见
pixi-vn-history
/
pixi-vn-getting-started
):
ts
stepHistory.back((_path) => {
  /* navigate in the url path */
}); // [!code --]
const gameProps = {};
stepHistory.back(gameProps); // [!code ++]
ts
Game.init(body, {
  height: 1080,
  width: 1920,
  backgroundColor: "#303030",
  navigate: (_path) => {
    /* navigate in the url path */
  }, // [!code ++]
}).then(() => {
  /* ... */
});
此版本还移除了以下长期弃用的内容:
stepHistory.goBack
、
narration.goNext
、
PIXI
(重新导出的命名空间)、
canvas.canvasWidth
/
canvas.canvasHeight
、
canvas.onEndOfTicker
、
FadeAlphaTicker
/
MoveTicker
/
RotateTicker
/
ZoomTicker
预设类、
narration.canContinue
(现在位于
stepHistory
一侧)、
narration.callLabel
/
jumpLabel
(现在为
call
/
jump
)、
narration.choiceMenuOptions
、
storage.startingStorage
/
setVariable
/
getVariable
/
removeVariable
(现在为
storage.default
/
set
/
get
/
remove
)。

v1.2.x → v1.3.0 —
canvas.animate
replaces ticker presets

v1.2.x → v1.3.0——
canvas.animate
取代 Ticker 预设

Canvas animation was rebuilt around
canvas.animate
(PixiJS tickers + the
motion
library, see
pixi-vn-canvas
), deprecating the old ticker-preset classes (
FadeAlphaTicker
,
MoveTicker
,
RotateTicker
,
ZoomTicker
) in favor of transition helpers (
showWithDissolve
,
moveIn
, ...) and
canvas.animate
directly.
Canvas 动画已围绕
canvas.animate
(PixiJS Ticker +
motion
库,参见
pixi-vn-canvas
)重新构建。旧的 Ticker 预设类(
FadeAlphaTicker
、
MoveTicker
、
RotateTicker
、
ZoomTicker
)已被弃用,转而使用过渡辅助函数(
showWithDissolve
、
moveIn
等) 和
canvas.animate
。

v0.10.x → v1.0 — the modular rewrite

v0.10.x → v1.0——模块化重写

The first stable release split the engine into independent modules (canvas/characters/history/ narration/sound/storage), introduced the
Game
namespace as the main entry point, and pulled step history out into its own
stepHistory
module (previously part of
narration
). Renames, all still relevant if migrating a pre-1.0 project:
ts
clearAllGameDatas(); // [!code --]
Game.clear(); // [!code ++]

canvas.initialize(body, options).then(...); // [!code --]
Game.init(body, options).then(...); // [!code ++]

getSaveData(); // [!code --]
Game.exportGameState(); // [!code ++]

getSaveJson(); // [!code --]
JSON.stringify(Game.exportGameState()); // [!code ++]

loadSaveData(data, navigate); // [!code --]
Game.restoreGameState(data, navigate); // [!code ++]

jsonToSaveData(json); // [!code --]
JSON.parse(json); // [!code ++]

narration.canGoBack; // [!code --]
stepHistory.canGoBack; // [!code ++]

narration.back(); // [!code --]
stepHistory.back(); // [!code ++]

narration.narrativeHistory; // [!code --]
stepHistory.narrativeHistory; // [!code ++]
See
pixi-vn-getting-started
for the current
Game
API,
pixi-vn-history
for
stepHistory
, and
pixi-vn-saves
for the current
exportGameState
/
restoreGameState
save/load flow.
首个稳定版本将引擎拆分为独立模块(Canvas/角色/历史/旁白/声音/存储), 引入
Game
命名空间作为主要入口,并将步骤历史提取为独立的
stepHistory
模块 (此前属于
narration
)。以下重命名在迁移 v1.0 之前的项目时仍然适用:
ts
clearAllGameDatas(); // [!code --]
Game.clear(); // [!code ++]

canvas.initialize(body, options).then(...); // [!code --]
Game.init(body, options).then(...); // [!code ++]

getSaveData(); // [!code --]
Game.exportGameState(); // [!code ++]

getSaveJson(); // [!code --]
JSON.stringify(Game.exportGameState()); // [!code ++]

loadSaveData(data, navigate); // [!code --]
Game.restoreGameState(data, navigate); // [!code ++]

jsonToSaveData(json); // [!code --]
JSON.parse(json); // [!code ++]

narration.canGoBack; // [!code --]
stepHistory.canGoBack; // [!code ++]

narration.back(); // [!code --]
stepHistory.back(); // [!code ++]

narration.narrativeHistory; // [!code --]
stepHistory.narrativeHistory; // [!code ++]
有关当前的
Game
API,请参阅
pixi-vn-getting-started
;有关
stepHistory
,请参阅
pixi-vn-history
;有关当前的
exportGameState
/
restoreGameState
存档/读档流程, 请参阅
pixi-vn-saves
。

Related skills

相关 skills

  • pixi-vn-getting-started — current
    Game
    API, project setup.
  • pixi-vn-saves — current save/load flow (
    Game.exportGameState
    /
    restoreGameState
    ).
  • pixi-vn-history — current
    stepHistory
    API.
  • pixi-vn-sound — current sound/channel/media API.
  • pixi-vn-canvas — current transition/animation API.
  • pixi-vn-storage — current storage API and key-naming convention.
  • pixi-vn-getting-started——当前的
    Game
    API、项目设置。
  • pixi-vn-saves——当前的存档/读档流程(
    Game.exportGameState
    /
    restoreGameState
    )。
  • pixi-vn-history——当前的
    stepHistory
    API。
  • pixi-vn-sound——当前的 Sound/频道/媒体 API。
  • pixi-vn-canvas——当前的过渡/动画 API。
  • pixi-vn-storage——当前的存储 API 和键名约定。