drincs-productions/pixi-vn/sound
Claude Code and agent skill by drincs-productions/pixi-vn
- community
Checking that the SKILL.md file is still in the repository.
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.
Install
npx vskill@latest install drincs-productions/pixi-vn/soundSKILL.md
Pixi'VN sound: channels, playback, volume, and filters
Official docs: pixi-vn.com/start/sound. The sound module is a wrapper around Tone.js; 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):
(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 byplay(). Each has its ownpaused,volume(a raw Tone.js decibelParam, 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 cansound.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-assetsfor 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
play() accepts either:
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.
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.Player, is not added to sound.find()'s registry, and disposes itself automatically when it finishes:
Transient playback can also be routed through a channel. This keeps it out of save/export state while applying the channel's volume, mute, pan, and filters. The returned Tone.Player can be stopped directly, which is useful for looping ambience tied to a screen or room:
Use sound.unsaved.stopTransientAll() to stop all transient players when individual references are not available.
If you do need to reference the effect later (pause it, stop it by alias, check if it's still playing), use regular play() on an "sfx" channel instead:
Playing a voice line
Voice is just another channel by convention — nothing special in the API distinguishes it from music/sfx, but keeping it on its own channel lets you separately mute/adjust volume for voice vs. music vs. effects (e.g. an in-game "voice volume" slider):
Pause / resume
Both the channel and the manager expose bulk helpers; individual instances expose paused:
Changing volume
Muting works the same way at every level: sound.muteAll() / sound.unmuteAll() / sound.toggleMuteAll(), channel.muted = true, and instance.mute = true (the MediaInterface.muted alias still works but is deprecated in favor of mute).
Stopping sounds
Filters
Filters are plain Tone.js audio nodes — construct them directly from tone (new Tone.Reverb(...), new Tone.FeedbackDelay(...), new Tone.Distortion(...), new Tone.Chorus(...), etc.; tone must be installed as a peer dependency). They can be attached per-sound or per-channel, and are currently only settable when a media/channel is created (no live filter add/remove after the fact).
Per-sound, via play()'s filters option:
Per-channel, so every sound routed through it is affected — either at creation time or later via chain():
Other/menu features
For settings screens or other menus, use the unsaved pause helpers instead of the regular ones — they don't perturb what gets restored from a save:
For transient UI sounds (button clicks, hovers) that must never leak into a save file, prefer sound.unsaved.playTransient() (see above) and sound.unsaved.stopTransientAll() to stop all of them at once.
Real-world project convention (official React template)
The library imposes no particular channel layout or settings architecture — everything above (channel names, how many channels, whether/how to persist volume) is up to the project. The following is how the official "TS narration + React" template (what npm create pixi-vn@latest scaffolds) does it in practice; treat it as one proven convention to copy or adapt, not a requirement of the library itself.
Named constants instead of hardcoded strings. Channel ids live in a constants file and are imported everywhere, so a rename is a one-line change:
Set up channels once, right after `Game.init` resolves, mirroring the background distinction from earlier in this doc — the music channel keeps playing across narration steps, the SFX channel is left non-background so one-shots don't linger:
Persist a settings-screen master volume/mute to localStorage, syncing it to the manager on init and on every user change (UI works in a 0-100 scale; the library is linear 0-1):
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/sound/SKILL.md
Popularity
- Repository stars
- 137
- Repository forks
- 8
- 7-day trend score
- 25
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/drincs-productions/pixi-vn/sound)