Math.random isnt random everytime


local itemTable = {

	["C_BasicWand"] = {Name = "Basic Wand", Rarity = "Common", Physical = nil, Spell = nil, Value = 1, Req = 1, Upgrades = nil, CurrentUpgrades = 0},
	["UC_BasicWand"] = {Name = "Basic Wand", Rarity = "Uncommon", Physical = nil, Spell = nil, Value = 1, Req = 1, Upgrades = nil, CurrentUpgrades = 0},
	["R_BasicWand"] = {Name = "Basic Wand", Rarity = "Rare", Physical = nil, Spell = nil, Value = 1, Req = 1, Upgrades = nil, CurrentUpgrades = 0},
	["E_BasicWand"] = {Name = "Basic Wand", Rarity = "Epic", Physical = nil, Spell = nil, Value = 1, Req = 1, Upgrades = nil, CurrentUpgrades = 0},
	["L_BasicWand"] = {Name = "Basic Wand", Rarity = "Legendary", Physical = nil, Spell = nil, Value = 1, Req = 1, Upgrades = nil, CurrentUpgrades = 0},


}

local lootTable = {

	{Name = itemTable.C_BasicWand, Chance = 55}, 
	{Name = itemTable.UC_BasicWand, Chance = 40}, 
	{Name = itemTable.R_BasicWand, Chance = 25}, 
	{Name = itemTable.E_BasicWand, Chance = 15}, 
	{Name = itemTable.L_BasicWand, Chance = 1}, 
}



local function returnSumOfWeight(lootTable)
	local sum = 0
	for _, item in ipairs(lootTable) do
		sum = sum + item.Chance
	end
	return sum
end

local function getRandomItem(lootTable)
	local randomNumber = math.random(returnSumOfWeight(lootTable))

	for _, item in ipairs(lootTable) do
		if  randomNumber <= item.Chance then
			return item.Name
		else
			randomNumber = randomNumber - item.Chance
		end
	end
end

function Items.PickItem()

	local item = getRandomItem(lootTable)
	
	
	return item

end

return Items

so i have a random item picker here and in the itemTable i want each item to have a random physical, spell, and amount of upgrades but if i just do math.random for the values then for that playtest all of the values will be that picked random value and i do not want that, i want it random every single time for each and every one how could i do that?

1 Like

That’s unusual. If you try and get multiple items does it give you the same number each time too?

1 Like

Try putting math.randomseed(tick()) at the start of your code. Pseudorandom number generators will give you the same sequence of numbers if you use the same seed. And studio in the past has given me the same default seed every time.

1 Like

well its working as it should if i set it there. because im setting it to a random value at that point then it will forever be that random value (for that server anyways) and to answer your question yes

2 Likes

where exactly do you mean the start of my code?

1 Like

Just at the top. Or, anywhere before math.random(). Upon rereading I might have misunderstood your question though. Is the problem that it’s always picking the same item? Or are you trying to find a way to randomize the properties of the picked item?

1 Like

trying to do this. but currently it will just pick a random number and that would be the set number for the playtest

1 Like

The only time you’re using math.random is when you’re drawing a weight for the item rarity, never when you’re differentiating the stats from the normal.
local randomNumber = math.random(returnSumOfWeight(lootTable))

You can label a min/max for each rarity per each stat within itemTable, then cycle through them and do something like (stat_name_max - stat_name_min) * math.random() + min or if you’re doing it by percent something like:
upgrades * stat_difference_percent * math.random() + upgrades

and if you want to make that difference also be negative, easily done with
local random = Random.new(seed_id)

as
(stat_name_max - stat_name_min) * random:NextNumber(-1, 1) + stat_name_min

or
upgrades * 0.20 * random:NextNumber(-1, 1) + upgrades

so to list out the min/max or difference you can edit your list relative to:

{
    Name = "Basic Wand", 
    Rarity = "Legendary", 
    PhysicalMin = 5, PhysicalMax = 10, -- // Kept on the same line for legibility
    SpellMin = 5, SpellMax = 10,
    UpgradesMin = 5, UpgradesMax 10,
    Value = 1, 
    Req = 1, 
    CurrentUpgrades = 0
}

-- // Or rename the extra variable type to [StatName]PercentDifference
-- // Whatever makes this more legible to you or whichever is more convenient

Not that these are the best ways but I found these to be the easiest or most orderly to implement myself.

1 Like

Instead of math.random, I tend to use Random.new():NextInteger(min, max) or Random.new():NextNumber(min, max). I believe it’s better at retrieving pseudorandom values.

Always seed math.random() otherwise the input value to the function will default to 0 meaning the same number will be returned, and so on. Call math.randomseed(os.time()) at the start of the script to give (but not guarantee) random results. The core code in the standard library, that math.random() calls, is over 30 years old and well established as flawed and far from random . You are better using Random.new() which uses entropy to generate number arrays, without seeding, and will produce less repeatable results.