Shotgun Spread With math.random?

I’m trying to get a good shotgun spread for my game, but sometimes I come across the occasional duplicate, causing my entire shotgun to shoot straight in one line. I’ve looked through all the devforum posts about duplicate math.randoms but I still can’t find any good solution. Here’s what I’ve done so far

	local function random(divide)
		return math.random(-spread,spread)/divide
	end
	
	local function makerandom(division)
		local randomtable = {}
			local randomspread = random(division)
			if table.find(randomtable, randomspread) then
			repeat random(division) until not table.find(randomtable, randomspread)
			return randomspread
			else
			table.insert(randomtable,#randomtable+1,randomspread)
			return randomspread
		end
	end

How can I make this more efficient or get rid of duplicate randoms?

You’re creating a new, empty randomtable each time makerandom() is called, so you’re not actually checking for duplicates. You need to define that table outside of the makerandom function, so that multiple calls to makerandom can add to it.

Once you get that fixed, you’ll also need to be sure that all your randomspread rolls get added to the randomtable, and your code currently won’t add them if it has to re-roll for a duplicate, since you have a return inside your if statement that returns a value of randomspread without adding it to the randomtable.

1 Like

This is great! But I’m getting a script timeout every time I activate the tool.

	local randomtable = {}
	local function random(divide)
		return math.random(-spread,spread)/divide
	end
	
	local function makerandom(division)
			local randomspread = random(division)
			if table.find(randomtable, randomspread) then
			repeat random(division) until not table.find(randomtable, randomspread)
			table.insert(randomtable,#randomtable+1,randomspread)
			return randomspread
			else
			table.insert(randomtable,#randomtable+1,randomspread)
			return randomspread
		end
	end
	```

That’s because you have an infinite loop. Your repeat loop is always checking table.find(randomtable, randomspread) with the same value of randomspread. You can’t throw away the return value from random(division), you need to be doing randomspread = random(division) inside the loop so the value changes.

Your if-then is also unnecessary and makes the code harder to read. Consider doing just this:

local function makerandom(division)   
    repeat
        randomspread = random(division)
    until not table.find(randomtable,randomspread)
    table.insert(randomtable,randomspread)
    return randomspread
end
1 Like

So here’s what I have now.

local randomtable = {}
	local function random(divide)
		return math.random(-spread,spread)/divide
	end
	
	local function makerandom(division)
			local randomspread = random(division)
			if table.find(randomtable, randomspread) then
			repeat randomspread = random(division) until not table.find(randomtable,randomspread)
			table.insert(randomtable,#randomtable+1,randomspread)
			return randomspread
			else
			table.insert(randomtable,#randomtable+1,randomspread)
			return randomspread
		end
	end

I’m still getting the script timeout, what should I do? Sorry if I’m being a bit dull here.

Try what I added above. If it still hangs, it means your random() function is being called with values for spread and divide that result in it generating fewer possible outcomes than the number of times you’re calling it, i.e. it’s running out of unique values.

ok I’ll try that tomorrow, but I’ll get back to you. Thanks for helping me!

I would advise against the table. That shouldn’t be necessary and it is a very expensive calculation to run per bullet, especially up to infinite times per bullet.