跳到正文
cccskills
免费在 GitHub 公开

pixi-vn-assets

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.

中文简介正在准备中。当前显示原文说明。

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md11.3 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Pixi'VN Assets: local vs. online, manifests, bundles, and loading strategy

Official docs: pixi-vn.com/start/assets (storage options) and pixi-vn.com/start/assets-management (loading strategy).

When to use this skill

Use this skill whenever a task involves adding a new image/audio/video file to a project, deciding whether an asset should live locally or be hosted online, editing the assets manifest, or choosing when a bundle of assets should load (blocking at startup, in the background, per-label, per-route). This skill does not cover how an image/sound is displayed/played once loaded — that's pixi-vn-canvas / pixi-vn-sound — only how it gets registered and made available by alias.

The one rule that matters most: always reference assets by their manifest alias, never by raw src path/URL, in game code. Loading by path directly is strongly discouraged — it couples code to a specific file location/host, so moving a file or switching hosting providers silently breaks every reference. Assets.load("bg01-hallway"), not Assets.load("https://.../bg01-hallway.webp").

Local vs. online assets

Assets can be stored locally in the project or hosted online (a CDN, GitHub raw, cloud storage). Frequently used assets (character sprites, backgrounds, background music) are best kept local; assets used once, or large optional files, are better hosted online to keep the project small and the initial download fast.

LocalOnline
Bundled into the appYes — ships in public/assetsNo — fetched at runtime from a URL
Best forFrequently used assets (backgrounds, sprites, core music)Large/optional/rarely-used assets
RequiresPixiJS AssetPack (pre-configured in official templates)A CORS-enabled host with a public URL

Local assets: the src/assets folder + PixiJS AssetPack

Local assets go under src/assets (any folder works, but this is the convention every official template uses), organized into subfolders however makes sense for the project. PixiJS AssetPack — pre-wired into the Vite config of every official template — watches this folder and, on every change (vite dev) or once before a production build (vite build), optimizes the files (compression, WebP/AVIF conversion, texture-atlas packing) into public/assets, and auto-generates src/assets/manifest.gen.json describing every resulting bundle/alias.

// vite.config.ts (already present in official templates — no changes usually needed)
import { AssetPack } from "@assetpack/core";
import assetPackConfig from "./.assetpack.ts";
// a Vite plugin runs `new AssetPack(assetPackConfig).watch()` in dev,
// `.run()` once during `vite build`
// .assetpack.ts (already present in official templates)
import { pixiPipes } from "@assetpack/core/pixi";

export default {
  entry: "./src/assets",
  output: "./public/assets",
  ignore: ["**/*.ts", "**/*.js", "**/*.gen.*"],
  pipes: [
    pixiPipes({ manifest: { output: "src/assets/manifest.gen.json" } }),
    // official templates add two extra pipes here: one bundle per top-level
    // folder (instead of everything in a single "default" bundle), and
    // stripping file extensions from generated aliases
  ],
};

src/assets/manifest.gen.json is generated — never hand-edit it. Any manual change is overwritten the next time AssetPack runs. If a local asset isn't showing up with the alias you expect, check the actual file's path/name under src/assets and let AssetPack regenerate the file, rather than editing the JSON directly.

// src/assets/manifest.gen.json (excerpt — auto-generated, read-only)
{
  "bundles": [
    {
      "name": "mc",
      "assets": [{ "alias": "mc-neutral", "src": "./assets/mc/mc-neutral.png" }]
    }
  ]
}

Online assets: the exact place to register them — src/assets/index.ts

For assets you host online (or any manifest entries beyond what AssetPack generates), the one place to add/edit them is src/assets/index.ts, present in every official template. It imports the auto-generated local manifest and appends hand-written bundles for remote URLs:

// src/assets/index.ts — the exact, single point to add/modify online assets
import generatedManifestJson from "@/assets/manifest.gen.json";
import type { AssetsManifest } from "@drincs/pixi-vn";

export const manifest: AssetsManifest = {
  bundles: [
    ...generatedManifestJson.bundles, // everything AssetPack generated locally
    {
      name: "audio", // pick a bundle name (see "Organizing into bundles" below)
      assets: [
        {
          alias: "bgm_cheerful",
          src: "https://your-cdn.example.com/audio/bgm_cheerful.wav",
        },
        {
          alias: "sfx_whoosh",
          src: "https://your-cdn.example.com/audio/sfx_whoosh.wav",
        },
      ],
    },
  ],
};

Popular CORS-friendly hosting options (see pixi-vn.com/start/assets#assets-hosting for the full comparison of price/limits/editability): GitHub raw URLs (https://raw.githubusercontent.com/[repo]/refs/heads/main/[path], free, 100MB/file limit), image-hosting services (imgbb/imgur, images only), or cloud storage (Cloudflare R2, Firebase Storage, S3, Supabase) for anything larger or non-image. Whichever host is used, it must allow CORS requests or the browser will block loading the asset.

Organizing assets into bundles

Group related assets into bundles instead of registering each one loosely — a bundle loads (or defers loading) as a single unit. Name each bundle after where it's used:

  • a label's id (e.g. startLabel.id) for assets only that label needs
  • a route's path (e.g. "/", "/game/narration") for assets a specific screen needs
  • a character's id for that character's sprite/expression assets

This convention matters most for online assets, where it directly controls what the player waits for; for local assets (which load near-instantly) precise bundle boundaries matter far less.

// src/assets/index.ts
import { startLabel } from "@/content/labels/start.label";

export const manifest: AssetsManifest = {
  bundles: [
    { name: "/", assets: [{ alias: "background_main_menu", src: "..." }] }, // main menu route
    { name: startLabel.id, assets: [{ alias: "bg01-hallway", src: "..." }] }, // one label
    { name: "mc", assets: [{ alias: "mc-neutral", src: "..." }] }, // one character
  ],
};

Initializing and loading

Register the manifest once, near app startup, before relying on any alias:

import { manifest } from "@/assets";
import { Assets } from "@drincs/pixi-vn";

let assetsInitialized = false;
export async function defineAssets() {
  if (!assetsInitialized) {
    const origin = `${location.protocol}//${location.host}/`;
    Assets.resolver.rootPath = origin;
    await Assets.init({ manifest, basePath: `${origin}assets/` });
    assetsInitialized = true;
  }
  await Assets.loadBundle("/"); // block on what the first screen needs
  Assets.backgroundLoadBundle("audio"); // load the rest quietly in the background
}

Then reference assets purely by alias, anywhere (pixi-vn-canvas for images/video, pixi-vn-sound for audio):

const texture = await Assets.load("mc-neutral");

By default assets load on demand, but waiting until the exact moment an asset is needed can cause a visible stall. Common, recommended loading moments, least-to-most eager:

  • At label start (background) — in a label's onLoadingLabel hook, call Assets.backgroundLoadBundle(label.id) (fire-and-forget): the label starts immediately, its bundle streams in without blocking. Prefer this over the blocking variant below unless a step genuinely cannot proceed without the asset.
  • At label start (blocking) — same hook, but await Assets.loadBundle(label.id): the label waits for its bundle before its first step runs. Only use this when the label truly can't start without those assets.
  • At project start — await Assets.loadBundle(...) for anything used on the very first screen (recommended limit: under 100MB, so the initial wait stays short).
  • In the background at project start — Assets.backgroundLoadBundle(...) for larger, non-blocking preloading (recommended limit: under 2GB).
  • Before a route/screen renders — inside a router's loader (e.g. TanStack Router), call await Assets.loadBundle(routePath), paired with a pendingComponent so the player sees a loading state instead of a blank screen.

Real-world project convention (official React template)

src/lib/utils/assets-utility.ts's defineAssets() combines several of the strategies above: guards Assets.init with an assetsInitialized flag (safe to call more than once), blocks on the current route's bundle (await Assets.loadBundle("/")) so the first screen never shows missing assets, then kicks off the audio bundle in the background (sound.backgroundLoadBundle(...) — the sound module's own wrapper, not Assets.backgroundLoadBundle, since it also has to wire the loaded media into a channel). Separately, main.tsx wires Game.onLoadingLabel((_stepId, { id }) => Assets.backgroundLoadBundle(id)) once, globally — so every label's own bundle (named after its id, per the convention above) is background-loaded automatically the moment that label starts, without every label needing its own onLoadingLabel hook. This is the template's convention, not a library requirement — a project is free to load more/less eagerly.

For caching online assets so returning players don't re-download them: official templates pre-configure VitePWA's service worker to cache responses from specific hostnames (a CACHED_EXTERNAL_HOSTNAMES list in vite.config.ts) for 7 days by default — add any CDN/host actually used to that list. See pixi-vn.com/start/assets#caching-assets.

Related skills

  • pixi-vn — the @drincs/pixi-vn/vite plugin's assetsManifest option bridges a manifest (often this skill's src/assets/index.ts) into the plugin's generated type file and dev-server endpoint; Game.onLoadingLabel is where label-scoped bundle loading is wired.
  • pixi-vn-canvas — displaying images/video once their alias is loaded.
  • pixi-vn-sound — playing audio once its alias is loaded, and the sound module's own backgroundLoadBundle/loadBundle wrappers.
  • pixi-vn-narration — labels are a natural bundle-naming unit (label.id).

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

pixi-vn

免费

Index and entry point of the Pixi'VN skill set — start here for any task on a @drincs/pixi-vn project, then follow the skill map to the right skill (narration, canvas, characters, assets, sound, storage, saves, history, ui, minigames, testing, migration). Use when setting up a new or existing project, 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) — every Pixi'VN project needs this before touching canvas, narration, sound, storage, or history.

中文简介正在准备中。当前显示原文说明。

DRincs-Productions/pixi-vn1542026年10月22日 更新

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-vn1542026年10月22日 更新

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-vn1542026年10月22日 更新

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-vn1542026年10月22日 更新

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-vn1542026年10月22日 更新

Use when adding a minigame (snake, quiz, puzzle, timing/reaction game, ...) to a Pixi'VN visual novel — the `useMinigame` lifecycle hook pattern, using PixiJS directly on its own layer instead of `gameLayer`, hotkeys for controls, linking the minigame to a route, and why saving/restoring minigame state is the developer's own responsibility.

中文简介正在准备中。当前显示原文说明。

DRincs-Productions/pixi-vn1542026年10月22日 更新

查看 DRincs-Productions 的全部技能

报告此技能的问题