Score
Everything you hear in SLAG SAINT, and the mix it sits in. `BattleBoot` attaches it to `audio_root`.
Score
Everything you hear in SLAG SAINT, and the mix it sits in. BattleBoot
attaches it to audio_root.
Buses
Seven sources, spawned as children of audio_root on awake():
| entity | type | what goes on it |
|---|---|---|
audio_music | Music | the phase score, one streaming track at a time |
audio_bed_a / audio_bed_b | Ambient | the room, crossfading between two beds |
audio_voice | SoundEffect | every spoken line, non-positional so it is always intelligible |
audio_ui | SoundEffect | interface and the big flow stings |
audio_world | SoundEffect, spatial | impacts, moved to the point they happened at |
audio_saint | SoundEffect, spatial | the saint's body, tracking boss_root |
Asking for a noise
No other slice decides how loud anything is:
Rules.sfx("parry_ring")
Rules.sfx("hit_bronze", { at = point, gain = 0.8 })
Rules.say("saint_greet", "THE SLAG SAINT", "WARD. YOU ARE LATE.")
Every key in Rules.SFX_KEYS resolves, plus the beds, the three score tracks
and the fourteen voiced lines. A key with no clip is a no-op, never an error.
The score
One track per phase, crossfaded on phase:changed (out over 1.6s, in over
2.4s). mode:changed decides whether the score plays at all — the title and
the descent run on ambience alone, and the score stops for a victory or a
death so the last line has room.
Ambience
Two Ambient sources crossfade over 3.2s, so the room changes with the grade:
amb_threshold at the title, amb_basin_cold for the first two phases,
amb_basin_fire once the floor opens. Each bed is a seamless loop — the tail
is crossfaded back over the head at bake time — and each is stored as
uncompressed PCM, because a codec that drops the first few milliseconds puts a
click in every lap.
Weight
Footfalls are not events another slice sends. Score measures how far
boss_root and the player's body actually moved and fires a step every stride,
so the sound follows the body rather than an animation guess. The saint's
stride shortens as its phase speed rises.
Ducking
A spoken line drops everything else to 34% for as long as the line lasts, then lets it back up. Nothing else in the game touches those levels.
Methods
:status()— clips registered, missing keys, music and bed state, bus health:preview(key)— play one sound by hand:previewLine(key)— speak one line by hand
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2Score — everything you hear in SLAG SAINT, and the mix it sits in. `BattleBoot` attaches this to `audio_root`. It owns: * the bus layout — music, two ambience beds that crossfade, a voice channel, a non-positional effects channel and a positional one * the clip registry every other slice reaches through `Rules.sfx(key)` and `Rules.clip(key)` * the score, which escalates across the three phases * the ambience, which travels from cold water to open furnace * the ten voiced lines, ducked in over whatever is playing * the saint's weight — footfalls derived from how far it actually moved, so the sound follows the body rather than a guessed animation event Nothing else in the game decides how loud anything is. Other slices ask for a noise by name; this file decides what it costs the mix. Rules.sfx("parry_ring") Rules.say("saint_greet", "THE SLAG SAINT", "WARD. YOU ARE LATE.")
clipTable( ) → void
The clip table Every name is a LITERAL: a computed asset name cannot be pinned as a content reference, and a world refuses to publish a reference it cannot resolve. `asset.tryResolve` returns nil instead of raising, so a clip that has not been baked yet leaves a gap rather than disabling the component.
despawnChildren(root: any) → void
Bus plumbing
| arg | type | description |
|---|---|---|
| root | any |
makeSource(root: any, name: string, opts: { [string]: any }) → any
| arg | type | description |
|---|---|---|
| root | any | |
| name | string | |
| opts | { [string]: any } |
audioOf(e: any) → any
| arg | type | description |
|---|---|---|
| e | any |
hostFor(clip: any, fields: { [string]: any }, at: any) → any
Spawn a host that carries its clip from the first frame.
| arg | type | description |
|---|---|---|
| clip | any | |
| fields | { [string]: any } | |
| at | any |
oneShotHost(clip: any, fields: { [string]: any }, life: number, at: any?) → void
Fire a host and retire it once the clip has had time to finish.
| arg | type | description |
|---|---|---|
| clip | any | |
| fields | { [string]: any } | |
| life | number | |
| at | any? |
restage(old: any, name: string, clip: any, fields: { [string]: any }) → any
Replace a persistent bus's host with one carrying `clip`, keeping its place and settings. Returns the new entity (or nil when the bus goes quiet).
| arg | type | description |
|---|---|---|
| old | any | |
| name | string | |
| clip | any | |
| fields | { [string]: any } |
ensureHost(cur: any, name: string, key: string?, fields: { [string]: any }) → any
Make a persistent bus be carrying `key`, and nothing else. Idempotent: it only spawns when the live host is missing or holding the wrong clip, so it is safe to call every frame and it heals a bus a rebuild took away.
| arg | type | description |
|---|---|---|
| cur | any | |
| name | string | |
| key | string? | |
| fields | { [string]: any } |
shoot(key: string, opts: { [string]: any }?) → void
Fire and forget a one-shot on the bus its key belongs to.
| arg | type | description |
|---|---|---|
| key | string | |
| opts | { [string]: any }? |
speak(key: string, holdSeconds: number?) → void
Speak. The clip goes out on its own bus at full weight and everything else ducks under it for as long as the line lasts. Every line records when it was said. The staging slice raises the story beats through `Rules.say`, and this slice ALSO cues the ones the fight cannot be without — the greeting and the two phase lines — so the saint speaks whether or not anyone else got there first. `spokenRecently` is what stops those two paths from doubling the line.
| arg | type | description |
|---|---|---|
| key | string | |
| holdSeconds | number? |
spokenRecently(key: string, within: number) → boolean
| arg | type | description |
|---|---|---|
| key | string | |
| within | number |
cue(key: string, holdSeconds: number, within: number) → void
Say a line unless something already said it in the last `within` seconds.
| arg | type | description |
|---|---|---|
| key | string | |
| holdSeconds | number | |
| within | number |
wantMusic(key: string?) → void
The score
| arg | type | description |
|---|---|---|
| key | string? |
driveMusic(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
wantBed(key: string?, gain: number?) → void
The room
| arg | type | description |
|---|---|---|
| key | string? | |
| gain | number? |
driveBeds(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
applyPhase(n: number) → void
Reacting to the fight
| arg | type | description |
|---|---|---|
| n | number |
onMode(payload: any) → void
| arg | type | description |
|---|---|---|
| payload | any |
bindEvents( ) → void
sub(name: string, fn: (any) → void
| arg | type | description |
|---|---|---|
| name | string | |
| fn | (any |
distance(a: any, b: any) → number
Weight — footfalls derived from distance actually travelled
| arg | type | description |
|---|---|---|
| a | any | |
| b | any |
asTriple(p: any) → any
| arg | type | description |
|---|---|---|
| p | any |
driveFootfalls(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
buildBuses( ) → void
Lifecycle
awake( ) → void
update(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
status( ) → any
What the sound slice has, for anyone checking the world is not silent.
preview(key: string) → void
Play one key by hand — the probe used to check a clip in a live engine.
| arg | type | description |
|---|---|---|
| key | string |
previewLine(key: string) → void
Speak one line by hand.
| arg | type | description |
|---|---|---|
| key | string |
auditionMode(mode: string) → void
Put the mix into what a given game mode sounds like, without touching `Rules.setMode` — that belongs to staging. The probe for checking that the title has a room and no score, and that the fight has both.
| arg | type | description |
|---|---|---|
| mode | string |
auditionPhase(n: number) → void
Put the mix into what a given phase sounds like, without waiting for the boss to get there. Takes the phase explicitly rather than reading `Rules.state.phase`, which the boss slice is writing at the same time.
| arg | type | description |
|---|---|---|
| n | number |
onDestroy( ) → void
Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
Showing the 199 items nearest this part. It holds more than this page lists.
Problems
Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.
agent_score is exposed.+ quality × 0.35
+ performance × 0.25
± compat factor
Usability ratings
Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".
Scoped to this part · feeds back into the world's score.