Experience context:
- Experience is a stage-based parkour with different songs for each stage.
- The experience holds about 30 songs in total as assets.
- Each song’s duration is about 1.5-2.5 minutes long, and then it loops.
- Experience link: Electric Dash - Roblox
Error report (last 24hrs):
The number of errors I receive due to sound related issues is extremely concerning.
I have calculated that between 50%-68% of my entire player base encounters sound issues.
Some player’s are even surprised to learn that the game incorporates music.
This greatly hinders the experience, as music is a very critical aspect to it.
Code for playing music:
local ContentProvider = game:GetService("ContentProvider")
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService")
local GameConfig = require(RS.Configs.GameConfig)
local Signals = require(RS.Signals)
local Sounds = require(RS.Sounds)
local player = Players.LocalPlayer
local musicVolume: number = GameConfig.getCurrentSettings().MUSIC_VOLUME
local musicFolder = Instance.new("Folder"); musicFolder.Name = "Music"; musicFolder.Parent = SoundService
local playingFolder = Instance.new("Folder"); playingFolder.Name = "Playing"; playingFolder.Parent = musicFolder
local clientStagesByIndex: {}
local mapNum: number
local currentSong = Instance.new("Sound"); currentSong.Parent = musicFolder
local MAX_RETRIES = 3
local SAFE_LOAD_TIMEOUT_SECONDS = 5
local function safeLoadSound(sound: Sound): boolean
-- Try to preload; pcall so moderation errors don’t crash
local success, err = pcall(function() ContentProvider:PreloadAsync({ sound }) end)
if not success then
warn("Failed to preload sound:", sound.Name, "Error:", err)
-- If it's a permission or moderated asset issue, retrying won't help.
-- You might want to check the error message for keywords.
return false
end
if sound.IsLoaded then return true end
for attempt = 1, MAX_RETRIES do
print(`Sound {sound.Name} not loaded, waiting for it to load... (Attempt {attempt})`)
local loaded = false
local conn
conn = sound.Loaded:Connect(function() loaded = true; conn:Disconnect() end)
local start = tick()
local timeout = SAFE_LOAD_TIMEOUT_SECONDS * attempt
while tick() - start < timeout do if loaded then break end; task.wait(0.1) end
if conn.Connected then conn:Disconnect() end
if loaded then return true end
end
warn(`Song failed to load after {MAX_RETRIES} attempts.`)
return false
end
local function togglePlaySong(songName: string): boolean
print(`Toggling song: {songName}`)
if currentSong and currentSong.Name == songName then
if currentSong.IsPlaying then currentSong:Pause() else currentSong:Resume() end
else
if GameConfig.CURRENT_PLACE_TYPE == "MAIN" and songName ~= clientStagesByIndex["Stage"..mapNum].song then
Signals.BE.ToggleStageMusic:Fire(false)
end
if currentSong and currentSong.Name ~= songName then
currentSong:Stop(); currentSong.SoundId = ""; currentSong.Name = ""; currentSong.Parent = musicFolder
end
local songData = Sounds.Music[songName]
if not songData then
warn("Song", songName, "not found in Sounds.Music! Player:", player.Name); return false
end
local prevSongName, prevSoundId = currentSong.Name, currentSong.SoundId
currentSong.Name = songName; currentSong.SoundId = "rbxassetid://"..songData.id
if not safeLoadSound(currentSong) then
currentSong.Name = prevSongName; currentSong.SoundId = prevSoundId; return false
end
currentSong.Parent = playingFolder; currentSong.Volume = musicVolume; currentSong.Looped = true
currentSong.TimePosition = songData.timePosition or 0; currentSong:Play()
end
return true
end
local function playStageSong()
for i = mapNum, 1, -1 do
local stageSongName: string = clientStagesByIndex["Stage"..i].song
local success: boolean = togglePlaySong(stageSongName)
if success ~= false then break end
end
end
local function onMapUpdated(newMapName: string?, newMapNum: number)
if newMapNum == mapNum then return end
mapNum = newMapNum
playStageSong()
end
local function init()
clientStagesByIndex = Signals.BF.GetClientMapsByIndex:Invoke()
local mapNum = Signals.BF.GetStageNum:Invoke()
onMapUpdated(nil, mapNum)
Signals.BE.NextMapTouchProcessed.Event:Connect(function(nextMapNum: number) onMapUpdated(nil, nextMapNum) end)
Signals.BE.TogglePlaySong.Event:Connect(function(songName: string) togglePlaySong(songName) end)
Signals.RE.MapUpdated.OnClientEvent:Connect(onMapUpdated)
end
init()
I have implemented a safeLoadSound function which tries 3 times to load the sound, however this hasn’t seemed to help. Some clients are just not able to ever load the sound.
Expected behavior
I would like at least 80% of my player base to be able to properly play the game with the music playing.
I would like to greatly reduce the timeout issues, and perhaps even the OutOfMemory issues.
