Sounds
Package: com.hypixel.hytale.server.core.universe.world.SoundUtil
Sounds are played by sending packets to players. The SoundUtil utility class provides static methods for three playback modes: 2D (non-positional, directly in the player’s ears), 3D (positional with distance attenuation), and entity-attached (follows an entity).
Sound Identification
Section titled “Sound Identification”Sounds are defined as SoundEvent assets with string IDs like "SFX_Player_Craft_Item_Inventory". At runtime, you look up the integer index for network efficiency:
int soundIndex = SoundEvent.getAssetMap().getIndex("SFX_Player_Craft_Item_Inventory");Index 0 is reserved as the empty/silent sound — all SoundUtil methods skip playback when the index is 0. If the ID is not found, getIndex() returns Integer.MIN_VALUE.
Playing 2D Sounds
Section titled “Playing 2D Sounds”2D sounds have no position — they play directly in the player’s audio output. Use these for UI feedback, notifications, and player-specific effects.
int soundIndex = SoundEvent.getAssetMap().getIndex("SFX_Player_Craft_Item_Inventory");
// to a specific player (by entity ref)SoundUtil.playSoundEvent2d(ref, soundIndex, SoundCategory.SFX, store);
// to a specific player (by PlayerRef)SoundUtil.playSoundEvent2dToPlayer(playerRef, soundIndex, SoundCategory.SFX);
// with volume and pitch modifiersSoundUtil.playSoundEvent2dToPlayer(playerRef, soundIndex, SoundCategory.SFX, 0.5f, 1.2f);
// to ALL playersSoundUtil.playSoundEvent2d(soundIndex, SoundCategory.SFX, store);Playing 3D Sounds
Section titled “Playing 3D Sounds”3D sounds are positional — they attenuate with distance and are only sent to players within the sound’s MaxDistance (defined in the SoundEvent asset, default 16 blocks).
int soundIndex = SoundEvent.getAssetMap().getIndex("SFX_Block_Break_Dirt");
// to all nearby players within rangeSoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, x, y, z, store);
// with volume and pitch modifiersSoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, x, y, z, 0.8f, 1.5f, store);
// to a specific player at a 3D position (with range check)SoundUtil.playSoundEvent3dToPlayer(playerRef, soundIndex, SoundCategory.SFX, x, y, z, store);From a Source Entity
Section titled “From a Source Entity”When a sound originates from an entity, use the source-entity variants. These automatically respect entity visibility — hidden entities don’t produce sounds for players who can’t see them. These variants always use SoundCategory.SFX.
// from a source entity (respects visibility)SoundUtil.playSoundEvent3d(sourceRef, soundIndex, x, y, z, store);
// also exclude the source from hearing the sound (only applies when source is a player)SoundUtil.playSoundEvent3d(sourceRef, soundIndex, x, y, z, true, store);With a Custom Filter
Section titled “With a Custom Filter”Filter which players receive the sound with a predicate:
// only players that aren't the attacker hear the hit soundSoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, x, y, z, ref -> !ref.equals(attackerRef), store);Entity-Attached Sounds
Section titled “Entity-Attached Sounds”Entity-attached sounds follow an entity as it moves. Use the entity’s network ID:
SoundUtil.playSoundEventEntity(soundIndex, networkId, store);
// with volume and pitchSoundUtil.playSoundEventEntity(soundIndex, networkId, 0.5f, 1.0f, store);Volume and Pitch
Section titled “Volume and Pitch”Each SoundUtil method accepts optional volumeModifier and pitchModifier parameters (both float, default 1.0f). These are linear multipliers applied on top of the base values defined in the SoundEvent asset.
The asset itself defines base volume in decibels (-100 to +10 dB) and pitch in semitones (-12 to +12). The AudioUtil class provides conversion helpers:
float linearGain = AudioUtil.decibelsToLinearGain(decibels);float linearPitch = AudioUtil.semitonesToLinearPitch(semitones);Sound Categories
Section titled “Sound Categories”The SoundCategory enum controls which audio bus a sound plays through:
| Category | Value | Use for |
|---|---|---|
Music | 0 | Background music |
Ambient | 1 | Environmental ambience |
SFX | 2 | General-purpose sound effects |
UI | 3 | UI interaction sounds |
Common Patterns
Section titled “Common Patterns”UI Sound + World Sound
Section titled “UI Sound + World Sound”Play a local UI sound to the acting player and a world sound for everyone else:
// player hears the UI versionSoundUtil.playSoundEvent2d(ref, uiSoundIndex, SoundCategory.UI, store);
// nearby players hear the world versionSoundUtil.playSoundEvent3d(worldSoundIndex, SoundCategory.SFX, pos.x(), pos.y(), pos.z(), store);Damage Sound with Source Exclusion
Section titled “Damage Sound with Source Exclusion”// nearby players hear the hit (except the attacker)SoundUtil.playSoundEvent3d(hitSoundIndex, SoundCategory.SFX, x, y, z, ref -> !ref.equals(attackerRef), store);
// attacker hears a separate confirmation soundSoundUtil.playSoundEvent3dToPlayer(attackerRef, confirmSoundIndex, SoundCategory.SFX, x, y, z, store);SoundEvent Assets
Section titled “SoundEvent Assets”SoundEvent assets define how a sound plays — volume, pitch, distance attenuation, layering, and randomization. The key fields that affect programmatic playback:
| Field | Default | Effect on playback |
|---|---|---|
MaxDistance | 16.0 | 3D sounds only sent to players within this range (blocks) |
StartAttenuationDistance | 2.0 | Distance before volume starts fading |
Volume | 0 dB | Base volume (your volumeModifier multiplies on top) |
Pitch | 0 semitones | Base pitch (your pitchModifier multiplies on top) |
MaxInstance | 50 | Max concurrent instances of this sound |
See Adding Sounds for the full JSON schema, layers, randomization settings, and block/item sound sets.
Packets
Section titled “Packets”All sound playback is packet-based (S->C). See World Packets for field details: PlaySoundEvent2D, PlaySoundEvent3D, PlaySoundEventEntity.