Skip to content
Entertainment
Skill

/sound

Use when playing or stopping background music, sound effects, or voice lines; creating/organizing audio channels; controlling volume, mute, or pan; or wiring Tone.js audio filters (reverb, delay, EQ, etc.) in a Pixi'VN game.

BOOST
From plugin
pixi-vn
15213 skills
Install
$ npx -y skills add drincs-productions/pixi-vn --skill sound --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/sound

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when playing or stopping background music, sound effects, or voice lines; creating/organizing audio channels; controlling volume, mute, or pan; or wiring Tone.js audio filters (reverb, delay, EQ, etc.) in a Pixi'VN game.

SKILL.md

sound.SKILL.md
name: pixi-vn-sound
description: Use when playing or stopping background music, sound effects, or voice lines; creating/organizing audio channels; controlling volume, mute, or pan; or wiring Tone.js audio filters (reverb, delay, EQ, etc.) in a Pixi'VN game.

Pixi'VN sound: channels, playback, volume, and filters

Official docs: [pixi-vn.com/start/sound](https://pixi-vn.com/start/sound). The sound module is a wrapper around [Tone.js](https://tonejs.github.io/examples/); the whole audio system was revised in v1.6.0/1.8.0, so if you find older examples elsewhere, prefer this skill and the doc link above.

When to use this skill

Use this skill whenever a task touches audio in a Pixi'VN project: starting/stopping music, playing a one-shot sound effect or a voice line, pausing/resuming playback, adjusting volume or mute state, or attaching Tone.js filters/effects. Requires `Game.init` to have already run (see `pixi-vn`) and the `tone` peer dependency to be installed.

Core mental model

`sound` (typed `SoundManagerInterface`) is the single entry point — do not import `SoundRegistry` directly, it's internal bookkeeping. Import it from the main package (as the official docs do):

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

(Also available from the narrower `@drincs/pixi-vn/sound` subpath — see `pixi-vn` for when to prefer that.)

The docs describe four elements, from broadest to narrowest:

  • **`sound` (manager)** — controls the entire audio system: manages channels, starts/controls media, and can set overall audio levels (`volumeAll`, `muteAll()`, etc.). Not saved in game saves — intended for game settings.
  • **`channels`** (`AudioChannelInterface`) — named buses (e.g. `"music"`, `"sfx"`, `"voice"`) that contain, start, and manage media. Channel-level settings (`volume`, `pan`, `muted`, filters) affect only what's routed through that channel and are not saved. Every sound is played _through_ a channel — if you don't create one explicitly, everything plays through the implicit default channel, `sound.defaultChannelAlias` (`"general"`).
  • **`media`** (`MediaInterface`) — a single started sound instance, returned by `play()`. Each has its own `paused`, `volume` (a raw Tone.js decibel `Param`, not linear), `loop`, `mute`, `playbackRate`, etc. These settings _are_ saved in the game save. Media instances are tracked by a **media alias** you choose (defaults to the sound's asset alias if you don't pass a separate one), so you can `sound.find()`/`pause()`/`resume()`/`stop()` them later by that alias.
  • **`assets`** (sound assets) — the raw audio files, referenced by alias from the assets manifest (see `pixi-vn-assets` for registering and loading them, local or online). Asset-level settings affect every media created from that asset and are meant to be configured once at load time, not saved.

Key distinction: **channel volume and `sound.volumeAll` are linear** in `[0, 1]` (`channel.volume = 0.5`, `sound.volumeAll = 0.7`), while a **media instance's `volume`** is the underlying Tone.js `Param<"decibels">` inherited from `Tone.Player` (`media.volume.value = -6`, `media.volume.rampTo(-Infinity, 2)`). The `volume` you pass in `play()`'s _options_, however, is linear `[0, 1]` — it gets converted to decibels internally. (The official doc's inline examples set things like `channel.volume = 90` / `media.volume.value = 90` for illustration only — don't copy those numbers literally: on a real channel, `90` is wildly out of the linear `[0, 1]` range and will clip.)

`channel.background` marks a channel whose sounds should **not** be stopped automatically on scene/step transitions (useful for music that should keep playing across narration steps) — non-background channels are auto-stopped on every "continue".

Playing music on a dedicated channel

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

// Create a background music channel once (e.g. right after Game.init resolves)
sound.channels.add("music", { background: true, volume: 0.8 });

// Start looping music through it
await sound.play("theme-song", { channel: "music", loop: true, volume: 0.8 });

`play()` accepts either:

sound.play(alias: string, options?: SoundPlayOptionsWithChannel): Promise<MediaInterface>;
sound.play(mediaAlias: string, soundAlias: string, options?: SoundPlayOptionsWithChannel): Promise<MediaInterface>;

Use the two-argument-alias form when you want to reference the instance under a different name than the underlying asset (e.g. multiple simultaneous instances of the same sound file). `options.channel` defaults to `sound.defaultChannelAlias` ("general"); if the named channel doesn't exist yet it is created automatically. The sound asset is auto-loaded (`sound.load()`) if it isn't already.

Calling `play()` again with the same media alias stops the previous instance and starts a new one, carrying over its previous options unless overridden — a handy way to restart or reconfigure something already playing.

Equivalently, you can call `play()` directly on a channel instead of passing `channel` in the options — `sound.channels.find("music").play("theme-song", { loop: true })` — the two forms are interchangeable; the docs show both.

Fade in / fade out

`play()`'s `fadeIn`/`fadeOut` options (seconds) drive smooth transitions without any manual `rampTo` calls: `fadeIn` only affects the start, while `fadeOut` is remembered on the media and applied automatically both when playback ends naturally _and_ when you call `stop()` later.

const music = await sound.play("theme-song", {
  channel: "music",
  loop: true,
  fadeIn: 2, // 2s fade-in on start
  fadeOut: 3, // 3s fade-out, applied on both natural end and manual stop()
});

sound.stop("theme-song"); // fades out over the 3s configured above, instead of cutting off

Playing a one-shot sound effect

For an SFX that should just fire and not be individually tracked/paused later, use `sound.unsaved.playTransient` — it returns a raw `Tone.Playe

Read more
Ships withpixi-vn

Pixi’VN is a very versatile and powerful story-driven engine. It is based on JavaScript/TypeScript and PixiJS, and supports animated characters through Spine 2D and Live2D.

Get the whole plugin

Other skills on pixi-vn.