v0.15.0 — migrate AudioScapeMusicPlayer to new Roblox Audio API - #13
Merged
Conversation
Replaces legacy `Sound` playback with `AudioPlayer` + `AudioDeviceOutput` + `Wire`. Public method surface unchanged (queue/setQueue/clearQueue/play/ stop/skip/setVolume/setPlayerId/playTrack/destroy + OnTrackChanged / OnQueueFinished callbacks + NowPlaying/IsPlaying/Queue fields). New: - player:getAudioPlayer() returns the live AudioPlayer Instance (or nil) for TweenService-driven volume animation and custom effect-chain wiring. - PlayerOptions.output accepts a caller-provided AudioDeviceOutput or AudioEmitter for spatial / custom-routing setups; auto-created AudioDeviceOutput remains the default. Tests: - tests/musicPlayer.spec.luau — 7 lifecycle scenarios with a fake analytics client and extended mock Instance (Play/Stop/Destroy + Ended signal + created-instance recorder). - tests/openCloud/smokeScript.luau — createPlayer step extended from a 4-line existence check to a full real-engine lifecycle check (Asset, IsPlaying, TimePosition advance, Wire wiring, setVolume propagation, stop/destroy teardown). Confirmed working: Lune 17/17, stylua, selene, luau-lsp analyze all clean; Roblox Studio MCP smoke confirms TimePosition advances and Wire routes AudioPlayer -> AudioDeviceOutput; live ear-test confirms audible playback and natural Ended -> next-track advancement. Sean (OffGridDude)
Was: assert ap.Volume == 0.4 / 0.7 after setting volume = 0.4 then setVolume(0.7). Those values aren't exactly representable in float32, so AudioPlayer.Volume (engine-side float32) round-trips back to the Lua double as 0.4000000059604645 / 0.699999988079071 and the equality asserts fail. Picked 0.5 and 0.25 — both exactly representable in float32 — so the round-trip is exact and the asserts work without a tolerance check. Sean (OffGridDude)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
cc @fifo
Summary
AudioScapeMusicPlayeroff legacySoundtoAudioPlayer+AudioDeviceOutput+Wire. Public method surface unchanged.player:getAudioPlayer()accessor (unblocks the MusicMCP crossfade skill that drivesVolumeviaTweenService).PlayerOptions.outputso spatial setups can feed anAudioEmitterinstead of the auto-createdAudioDeviceOutput.wally.toml,READMEinstall snippet,CHANGELOG).Driven by the handoff at
MusicMCP/docs/handoff-sdk-audioplayer-migration-2026-05-21.md. Open design questions in section 3 of that doc resolved via the recommended defaults (auto-output with override, add accessor, AudioPlayer-only no fallback, minor version bump).What changed
src/AudioScapeMusicPlayer.luau— new audio backbone,getAudioPlayer(),PlayerOptions.output,BindToClosewrapped inpcallso module-load outside a server context (Studio command bar, plugins) does not error.tests/musicPlayer.spec.luau— new spec, 7 lifecycle scenarios with a fake analytics client.tests/_harness/mockGame.luau+tests/_harness/loadSdk.luau— Instance shim now providesPlay/Stop/Destroymethods, anEndedsignal with a test_firehook, and records created instances onInstance.__created.tests/openCloud/smokeScript.luau—createPlayerstep extended from a 4-line existence check to a full real-engine lifecycle check (Asset,IsPlaying,TimePositionadvance, Wire wiring,setVolumepropagation,stop/destroyteardown).Test plan
Asset = "rbxassetid://..."accepted,IsPlaying = true,TimePositionadvances, Wire routes AudioPlayer → AudioDeviceOutput,setVolumepropagates to live AudioPlayer,stop()+destroy()tear down cleanlyAudioPlayer.Endedsemantics matchSound.Endedfor our purposes)