How would I make math.random() not repeat?

I’ve already tried to search the internet for the answer of this, but none of the scripts worked for an audio table, and for some reason this script makes the same sound repeat every time waited (but the sound changes every time a new server is made!) and I’m not sure why. Help.

Here’s my basic script that I originally had.

local sound1 = script.Parent:WaitForChild("1")
local sound2 = script.Parent:WaitForChild("2")
local sound3 = script.Parent:WaitForChild("3")
local sound4 = script.Parent:WaitForChild("4")
local sound5 = script.Parent:WaitForChild("5")
local sounds = {
	{"1", sound1},
	{"2", sound2},
	{"3", sound3},
	{"4", sound4},
	{"5", sound5}}
local random = math.random(1, #sounds)
local waittime = math.random(6,14)

while true do
	wait(waittime)
	sounds[random][2]:Play()
end

You need to declare the “random” variable inside of the while loop so it is different each time. Currently you’re only defining once, so it will never change.

3 Likes

Oh my gosh that was so simple thank you. Sorry I forget the simplest things haha

Ok wait… I forgot about the math.random() still repeating lol. Any tips or tricks for that?

You’re better off remaking this, I’ve done a simple one for you that won’t repeat.

local sounds = workspace.Songs:GetChildren() -- assuming you got all your sounds in some sort of folder
local lastsong = nil
local song = nil

local function play()
    repeat song = sounds[math.random(1,#sounds)] until song ~= lastsong
    lastsong = song    

    song:Play()
    song.Ended:Connect(function()
        play()
    end)
end

play()
1 Like

You made a script that picks a random sound from the 1st to the number of sounds you have.
Then you go into a loop that just keeps playing the same sound. This is more of a logic error.

while true do
    local random = math.random(1, #sounds)
    local waittime = math.random(6,14)

	wait(waittime)
	sounds[random][2]:Play()
end

Small change will make this work fine.


But … if your real goal here is just what you asked then we can get a bit more hardcore with it by creating a resetting whitelist …

local sound1 = script.Parent:WaitForChild("1")
local sound2 = script.Parent:WaitForChild("2")
local sound3 = script.Parent:WaitForChild("3")
local sound4 = script.Parent:WaitForChild("4")
local sound5 = script.Parent:WaitForChild("5")

local sounds = {sound1, sound2, sound3, sound4, sound5}

local playedSounds = {}

while true do
    local unusedSounds = {}

    for _, sound in ipairs(sounds) do
        if not playedSounds[sound] then
            table.insert(unusedSounds, sound)
        end
    end

    if #unusedSounds == 0 then
        playedSounds = {}  -- Reset the table when all sounds have been used
    else
        local random = math.random(1, #unusedSounds)
        local selectedSound = unusedSounds[random]

        selectedSound:Play()
        playedSounds[selectedSound] = true

        wait(math.random(6, 14))
    end
end

This is good to learn, as blacklisting/whitelisting comes in handy in many cases.

@vxsqi, @2112Jay, both solutions work! Thanks!

sorry if i’m a little late to the party…

--this will seed the random number for a 'different' set each run
math.randomseed(tick())  

print(math.random(1,10))  --non determinate number between 1 and 10


--this will seed the random numbers for the 'same' set each run
math.randomseed(1)  

print(math.random(1,10))  --same set of random numbers per run

Basically, keep track of the last played, and if the random hits the index of that last song, you redo the random function!

Also a bit unrelated, but if you want your math.random() function to be more “random”, you can put many of them side by side like:

local random = (math.random(1, 10) + math.random(1, 10)) % 10 + 1

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.