Skip to content

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).

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.

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 modifiers
SoundUtil.playSoundEvent2dToPlayer(playerRef, soundIndex, SoundCategory.SFX, 0.5f, 1.2f);
// to ALL players
SoundUtil.playSoundEvent2d(soundIndex, SoundCategory.SFX, store);

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 range
SoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, x, y, z, store);
// with volume and pitch modifiers
SoundUtil.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);

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);

Filter which players receive the sound with a predicate:

// only players that aren't the attacker hear the hit sound
SoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, x, y, z,
ref -> !ref.equals(attackerRef), store);

Entity-attached sounds follow an entity as it moves. Use the entity’s network ID:

SoundUtil.playSoundEventEntity(soundIndex, networkId, store);
// with volume and pitch
SoundUtil.playSoundEventEntity(soundIndex, networkId, 0.5f, 1.0f, store);

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);

The SoundCategory enum controls which audio bus a sound plays through:

CategoryValueUse for
Music0Background music
Ambient1Environmental ambience
SFX2General-purpose sound effects
UI3UI interaction sounds

Play a local UI sound to the acting player and a world sound for everyone else:

// player hears the UI version
SoundUtil.playSoundEvent2d(ref, uiSoundIndex, SoundCategory.UI, store);
// nearby players hear the world version
SoundUtil.playSoundEvent3d(worldSoundIndex, SoundCategory.SFX,
pos.x(), pos.y(), pos.z(), store);
// 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 sound
SoundUtil.playSoundEvent3dToPlayer(attackerRef, confirmSoundIndex,
SoundCategory.SFX, x, y, z, store);

SoundEvent assets define how a sound plays — volume, pitch, distance attenuation, layering, and randomization. The key fields that affect programmatic playback:

FieldDefaultEffect on playback
MaxDistance16.03D sounds only sent to players within this range (blocks)
StartAttenuationDistance2.0Distance before volume starts fading
Volume0 dBBase volume (your volumeModifier multiplies on top)
Pitch0 semitonesBase pitch (your pitchModifier multiplies on top)
MaxInstance50Max concurrent instances of this sound

See Adding Sounds for the full JSON schema, layers, randomization settings, and block/item sound sets.

All sound playback is packet-based (S->C). See World Packets for field details: PlaySoundEvent2D, PlaySoundEvent3D, PlaySoundEventEntity.