Difficulties when trying to get random

So I am trying to get a random item from a table based on a set percentage, but I am getting a error that looks something like this: attempt to perform arithmetic (sub) on number and table. Anyways I am trying for about 1 hour to fix this and couldn’t find why it doesn’t really work, maybe because its fired through a event? Here is the code.


-- // MODULE \\ --


local module = {
	exhibits_groups_meta = {
		Common = 92,
		Rare = 5,
		Legendary = 3,
	};
	
	
	Common = {
		"PCs",
		"Phones",
		"Swords",
		"Spears & Bows",
		"Maces & Axes",
		"TVs",
		"Planes",
		"Blimps",
		"Modern Art",
		"Iron",
	};
	
	Rare = {
		"Modern Military",
		"Roman Art",
		"Roman History",
		"Sports Cars",
		"Chemistry",
		"Japanese Art",
		"Samurai",
		"Tanks",
		"Toys",
		"Renaissance",
	};
	
	Legendary = {
		"T-Rex",
		"Triceratops",
		"Gravity",
		"Ocean",
		"Japanese Architecture",
	};
}

-- CONSTANTS
local R = Random.new()
local totalWeight = 0

-- LOOP
for _, weight in pairs(module.exhibits_groups_meta) do
	totalWeight += weight
end

-- UTILITIES
function module.getRandomExhibit(weightedItems)
	local RandomFactor = R:NextNumber(0, totalWeight)
	local result
	for item, weight in pairs(weightedItems) do
		RandomFactor -= weight
		if RandomFactor < 0 then
			result = item
			break
		end
	end
	return result
end


return module
-- // EVENT HANDLER \\ --


-- VARIABLES
local Events = game.ReplicatedStorage.Remotes
local GetExhibit = Events.GetExhibit

local RandomUnit = require(game.ReplicatedStorage.Modules.Data.RandomUnit)

-- FUNCTIONS
local function ping(a)
	return a
end

-- EVENTS
GetExhibit.OnServerEvent:Connect(function()
	local rss = RandomUnit:getRandomExhibit(RandomUnit.exhibits_groups_meta)
	print(rss)
end)

When you call a function in a table with the colon operator (:), the table gets passed as the first argument in the function. What you’re doing right now is basically this:

RandomUnit.getRandomExhibit(RandomUnit, RandomUnit.exhibits_groups_meta)

For example if you had

local t = {}
t.func = function(...)
	print(...)
end

and then you called the function like so

t:func(123)

then it would print table, 123.

To fix your error, either call the function with the dot operator like this:

RandomUnit.getRandomExhibit()

… or define the function with a colon like this:

function module:getRandomExhibit(weightedItems)

Also, if you’re gonna call getRandomExhibit with the same set of weights from the module every time, then you can just use self inside of the function to get the weights table for you

function module:getRandomExhibit()
	local RandomFactor = R:NextNumber(0, totalWeight)
	local result
	for item, weight in pairs(self.exhibits_groups_meta) do -- self == module
		RandomFactor -= weight
		if RandomFactor < 0 then
			result = item
			break
		end
	end
	return result
end
1 Like

Yeah thank you for clarifying that, so the problem was that I put a dot when calling the module from the server script and in the module itself it was with a semicolon, thanks! :slight_smile:

1 Like