Files
Ambient-Audio-Zone/README.md
T
root f11366088c
Build / maven (push) Successful in 44s
Build and publish release / Build and publish Ambient Audio Zone (push) Successful in 44s
fix: prevent overlapping fade and loop playback
2026-08-04 05:55:41 +02:00

4.9 KiB

Ambient Audio Zone

A Paper 26.2 plugin for immersive, directional ambient audio driven by WorldEdit cuboid selections. Zones use any vanilla or resource-pack sound event (minecraft:... or namespace:...), are stored in YAML, and are indexed by chunk rather than scanned globally.

Requirements

  • Paper 26.2 (26.2.build.92-stable API target) and Java 25
  • WorldEdit 7.4.4+ installed on the server (for selection-backed create/region editing)
  • A resource pack installed on clients when using custom sound IDs

Drop AmbientAudioZone.jar into plugins/ and restart. It creates plugins/AmbientAudioZone/config.yml and zones.yml.

Commands

Command Description Permission
/ambientaudio create <name> <sound-id> Creates a zone from your complete WorldEdit selection. Origin starts at your current location. ambientaudio.create
/ambientaudio edit <name> region Replaces the zone cuboid with your WorldEdit selection. ambientaudio.edit
/ambientaudio edit <name> origin [here|x y z] Sets the directional sound source. ambientaudio.edit
/ambientaudio edit <name> sound <sound-id> Changes the sound event ID. ambientaudio.edit
/ambientaudio edit <name> fade <blocks> Sets the selection activation/fade envelope. ambientaudio.edit
/ambientaudio edit <name> volume|pitch <value> Sets the sound gain or pitch. ambientaudio.edit
/ambientaudio edit <name> category <category> Sets a Bukkit SoundCategory, e.g. MUSIC, RECORDS, AMBIENT, MASTER. ambientaudio.edit
/ambientaudio edit <name> loop|enabled <true|false> Changes loop metadata or enable state. ambientaudio.edit
/ambientaudio edit <name> priority <integer> Sets overlap priority. ambientaudio.edit
/ambientaudio delete <name> Deletes a zone. ambientaudio.delete
/ambientaudio list Lists zones. ambientaudio.list
/ambientaudio reload Reloads both YAML files and rebuilds the index. ambientaudio.reload

ambientaudio.admin grants all administrative commands (default: OP). The /aaz alias is available.

Zone configuration

zones:
  nightclub:
    world: world
    sound: lexian:music/nightclub
    origin:
      x: 120
      y: 65
      z: -45
    region:
      min: { x: 100, y: 60, z: -60 }
      max: { x: 140, y: 80, z: -20 }
      fade-distance: 32
      volume: 1.0
      pitch: 1.0
      category: RECORDS
      loop: true
      priority: 100
    enabled: true

fade-distance expands the cuboid's audible envelope. With playback.follow-player: true (the default), the sound is attached to each listener and its volume fades from the configured volume inside the cuboid to silence at the edge of the fade envelope. Set it to false to use the fixed origin as a directional source instead.

Overlaps and performance

By default, only the audible zone with the highest priority is selected. Set playback.blend-overlapping-zones: true in config.yml to play every audible zone. The zone index assigns a zone only to chunks touched by its fade-expanded X/Z bounds; each playback pass then evaluates only the list for a player's current chunk. The interval and grace period are configurable:

playback:
  check-interval-ticks: 10
  leave-grace-ticks: 100
  blend-overlapping-zones: false
  follow-player: true
  loop-restart-ticks: 2680

When a selected zone remains selected, Ambient Audio Zone normally sends no new sound packet. In follow-player mode it uses rate-limited fade updates and stops the previous packet before re-emitting, preventing layered copies of the sound. Bukkit has no mutable-volume packet, so these updates are necessarily discrete; resource-pack loops are the smoothest option. Leaving starts a configurable grace timer; returning before it expires preserves the existing client playback instead of restarting it. loop-restart-ticks is a fallback for sounds whose resource-pack definition does not loop; set it to the exact sound length, while resource-pack loop: true remains the seamless option. Reloading or editing a zone intentionally replaces its active sound.

Resource-pack looping note

Minecraft's public sound packet has no server-controlled playback position, pause, or true loop flag. For seamless loops, define custom events in the resource pack and let the client loop/stream them, for example:

{
  "music/nightclub": {
    "sounds": [{ "name": "lexian:music/nightclub", "stream": true, "loop": true }]
  }
}

Use that event as lexian:music/nightclub in the zone. The plugin deliberately does not repeatedly replay a selected sound—doing so would cause audible starts and destroy seamless loops. Vanilla one-shot events play normally; their exact loop behaviour is determined by the vanilla sound definition.

Build

mvn verify

The GitHub Actions workflow builds with Java 25 on pushes and pull requests.