Can't figure out how to use math.random to get tables under tables

I’m trying to make a rarity roller, I already have the rarity part scripted, however the part where it starts picking from each table isn’t working.

I’ve tried adding extra lines for the table.clones to clone the tables under the original table, but it doesn’t seem to change anything.


local Skill = {
	
	Legendaries = {
		TestLegendary1 = {
			DisplayText = "Hey this is a cool leg 1",
			TalentDesc = "This is a description leg 1"
		},
		TestLegendary2 = {
			DisplayText = "Hey this is a cool test leg 2",
			TalentDesc = "This is a description leg 2"
		},
	},
	Rares = {
		TestRare1 = {
			DisplayText = "Hey this is a cool test rare1",
			TalentDesc = "This is a description rare 1"
		},
		TestRare2 = {
			DisplayText = "Hey this is a cool test rare 2",
			TalentDesc = "This is a description rare 2"
		},
	},
	Commons = {
		TestCommon1 = {
			DisplayText = "Hey this is a cool test com 1",
			TalentDesc = "This is a description com 1",
		},
		TestCommon2 = {
			DisplayText = "Hey this is a cool test com 2",
			TalentDesc = "This is a description com 2",
		},
	}
}

local test = table.clone(Skill.Legendaries)
print(#test) -- Prints out 0 for some reason?
local test2 = math.random(1, #test) -- Error
local real = test[test2]

The reason #test returns 0 is because your table is a dictionary. # Only counts successive indexes starting from 1 (so basically arrays, though the table can contain other kinds of keys)

You can either change your table into an array, which is probably what I’d recommend, or you can count how many values are in the dictionary by looping over it, perhaps storing the index into an array, and then selecting a random index from that array

This code wouldn’t work even if it didn’t error, because test2 would be a number, but the indexes of the test table are strings, so real would be nil

2 Likes

How would I do that exactly? I’m still pretty new to dictionaries and arrays in scripting so I’m not really sure how I’d start on that.

So here are the two solutions I talked about,

The first one where your main table is modified to be an array rather than a dictionary

local Skill = {

	Legendaries = {
		{ -- By removing the name before the {}, it becomes an array with indexes 1, 2, 3, ...
			Name = "TestLegendary1",
			DisplayText = "Hey this is a cool leg 1",
			TalentDesc = "This is a description leg 1"
		},
		{
			Name = "TestLegendary2",
			DisplayText = "Hey this is a cool test leg 2",
			TalentDesc = "This is a description leg 2"
		},
	},
}

local test = Skill.Legendaries -- No need to clone the table
print(#test) -- Prints 2
local test2 = math.random(1, #test) -- Choses a random number
local real = test[test2] -- Get the table

print(real)

And the second solution where the indexes of the dictionary and inserted into a array to be able to chose a random index, and then a random table

local Skill = {

	Legendaries = {
		TestLegendary1 = {
			DisplayText = "Hey this is a cool leg 1",
			TalentDesc = "This is a description leg 1"
		},
		TestLegendary2 = {
			DisplayText = "Hey this is a cool test leg 2",
			TalentDesc = "This is a description leg 2"
		},
	},
}

local test = Skill.Legendaries -- No need to clone the table
local indexes = {} -- Create an array containing every index from test

for i, _ in pairs(test) do 
	table.insert(indexes, i) -- insert index into the array
end

print(#indexes) -- Prints 2
local test2 = math.random(1, #indexes) -- Choses a random number
local index = indexes[test2] -- Retreive the index at that number

real = test[index] -- Get the table from the index

print(real)

Feel free to ask any questions about stuff you don’t understand in here. The goal is not to spoon feed code, as you wont learn from that

Oh I get it now, thanks for the help! I don’t think I have any questions on it, I just didn’t know where to start with it.

1 Like