pyxen.Sound
A short audio clip attached to an Entity as a component.
Sounds are loaded entirely into memory — use them for short effects like jumps, hits, and pickups.
For audio concepts, see Audio.
Constructor
Sound(filename, *, volume=1.0, pan=0.0, loop=False, delay=0.0, pitch=1.0)
filename is the one positional argument: the name of a WAV audio asset in the project. The other five are keyword-only and set the starting value of the property of the same name (see Component Properties).
Parameters
| Parameter | Type | Description |
|---|---|---|
filename | str | Name of the WAV asset, without its extension; a sound inside a sound bank is bank/sound |
volume | float | Starting gain. Defaults to 1.0 |
pan | float | Starting stereo position, -1.0 to 1.0. Defaults to 0.0 |
loop | bool | Restart when the sound ends. Defaults to False |
delay | float | Seconds of silence before it starts. Defaults to 0.0 |
pitch | float | Playback rate, 0.25 to 4.0. Defaults to 1.0 |
Example
jump_sound = Sound("jump")
quiet_echo = Sound("jump", volume=0.3, delay=0.15)
high_jump = Sound("jump", pitch=2.0)
Attaching a Sound
During spawn:
sfx = world.spawn(sound=Sound("jump"))
Or later:
entity.sound = Sound("jump")
Assigning a sound starts playback immediately.
Component Properties
Access via entity.sound:
| Property | Type | R/W | Description |
|---|---|---|---|
loop | bool | R/W | Enable looping |
volume | float | R/W | Gain (clamped >= 0.0) |
pan | float | R/W | Stereo panning (-1.0 to 1.0) |
time | float | R/W | Current playback position (seconds) |
delay | float | R/W | Seconds of silence before it starts |
pitch | float | R/W | Playback rate (0.25 to 4.0) |
duration | float | R | Total length (seconds) |
finished | bool | R | True when playback has completed |
loop
entity.sound.loop = True
When enabled, the sound restarts automatically after finishing.
volume
entity.sound.volume = 0.5
Values below 0.0 are clamped to 0.0.
pan
entity.sound.pan = -1.0 # full left
entity.sound.pan = 1.0 # full right
entity.sound.pan = 0.0 # center
Clamped to the range -1.0 to 1.0.
time
t = entity.sound.time
entity.sound.time = 0.25 # skip the first quarter second
The playback position in seconds. Assigning to it seeks; a value past the end is clamped to the end, and seeking a finished sound starts it playing again.
delay
entity.sound.delay = 0.002 # start two milliseconds from now
Seconds of silence before the sound starts. Unlike time this does not skip anything — the
sound still begins at its first sample, it just begins later.
This is what to reach for when the same effect fires several times in one frame. Copies of one waveform that start on the same sample add up in phase: two are twice the amplitude, not 1.4 times, and ten will take a mix past full scale however carefully each one was set. A few milliseconds apart is enough to decorrelate them and far too short to hear as a gap.
for i, brick in enumerate(broken):
e = world.spawn(sound=Sound("brick"))
e.sound.delay = i * 0.002
What a delay separates is the attacks, so it helps most with short percussive effects and does nothing for a sustained tone — once every copy of a steady sound is playing, they sum to the same level whatever order they started in.
pitch
entity.sound.pitch = 2.0 # an octave up
entity.sound.pitch = 0.5 # an octave down
How fast the sound is played: 1.0 as recorded, 2.0 an octave higher and in half the time,
0.5 an octave lower and twice as long. Values are clamped to 0.25 to 4.0, two octaves
either way. One sound at a rising pitch is a scale, so a chain or a streak needs one sound,
not one per note:
def on_match(step):
world.spawn(sound=Sound("match", pitch=1 + 0.12 * step))
time and duration stay in the sound’s own seconds: at pitch 2.0, a one-second sound
plays for half a second while its time runs from 0.0 to 1.0.
duration
d = entity.sound.duration
Read-only. Total length of the sound in seconds, as recorded (whatever its pitch).
finished
if entity.sound.finished:
world.destroy(entity)
Read-only. True when the sound has finished playing (and loop is False).
Format
Sound assets must be WAV files.
Common Errors
Missing Filename
Sound()
ValueError: Sound must have a file
Invalid Asset
Sound("nonexistent")
ValueError: Sound 'nonexistent' not found. For sounds inside a sound bank, use 'bank/sound'.
The game stops with this error. Name the asset without its .wav extension; a sound inside a sound bank is named bank/sound.
Snippets
In Pyxen’s home, under Snippets:
- Sound() one-shot — Click to play a short WAV.
- sound.loop / pan / volume — Continuous sound — mouse drives stereo pan.