• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[OTClient Mehaia 3.0.2] Randomizing soundtrack

Siegh

Thronar Developer
Joined
Mar 12, 2011
Messages
1,299
Solutions
1
Reaction score
681
Location
Brazil
Hello! I'm trying to have my client play random songs from a list in a loop but, while I do manage to make it randomize songs from a list and keep playing as a loop, as soon as it chooses one music it will stick with it indefinitely.

How can I have it randomize its pick after a song plays entirely?

This is on client.lua:

LUA:
local musicTracks = {
  "/sounds/startup",
  "/sounds/townMusic1",
  "/sounds/townMusic2",
  --"/sounds/dungeonMusic1",
  --"/sounds/dungeonMusic2",
}

local randomTrack = musicTracks[math.random(1,#musicTracks)]

function startup()
    if musicChannel then
        musicChannel:enqueue(musicTracks[math.random(1,#musicTracks)], 3)
        connect(g_game, {
            onGameStart = function()
                musicChannel:stop(3)
                local currentMusic = musicChannel:enqueue(musicTracks[math.random(1,#musicTracks)], 3)
                if currentMusic then
                    currentMusic.onFinish = function()
                        -- Recursive call to pick and play the next random song
                        musicChannel:stop(3)
                        musicChannel:enqueue(musicTracks[math.random(1,#musicTracks)], 3)
                    end
                end
            end
        })
        connect(g_game, {
            onGameEnd = function()
                musicChannel:stop(3)
                local currentMusic = musicChannel:enqueue(musicTracks[math.random(1,#musicTracks)], 3)
                if currentMusic then
                    currentMusic.onFinish = function()
                        -- Recursive call to pick and play the next random song
                        musicChannel:stop(3)
                        musicChannel:enqueue(musicTracks[math.random(1,#musicTracks)], 3)
                    end
                end
            end
        })
    end
 
I think I found the issue.

The problem isn't with math.random(), but with the onFinish callback. The callback is only assigned to the first track that gets queued. When that track finishes, it queues a new random song, but the newly queued track never gets its own onFinish callback, so the chain stops there. Depending on how the client's music system works, it may end up replaying the same track or keeping the last one active.

A cleaner approach is to wrap the logic in a playRandomMusic() function that:
  1. Stops the current track (if needed).
  2. Chooses a random song.
  3. Queues/plays it.
  4. Assigns onFinish = playRandomMusic to the newly created music object.
That way, every song schedules the next random one when it finishes, keeping the playlist random indefinitely.

One other thing I noticed is that randomTrack is declared but never used:
local randomTrack = musicTracks[math.random(1,#musicTracks)]

Using Ctrl + B, i found only 1 time this word (randomTrack) but i dont see an use
 
I had randomTrack declared but thought it could permanently show the same result after it rolled, thats why I thought randomizing inside the function would be better.

Anyway, I think so too, I tried doing a playRandomMusic() function before but still didn't manage to make it change whatever track randomized first on what was supposed to be a loop. I kinda suspect either the onFinish or enqueue dont work the way I'd think they do. Would you have an example of how it could be achieved?

Specially the onFinish, I got it from an AI reply, I'm not sure it even exists lol, I couldn't find a proper example.
 
Back
Top