How to get a table in a table

So i’ve made a Rock table that will go through a different variety of rocks and include it’s stats and loot table. However I do not know how I will get everything including the loot table from the table. Any help will be appreciated!

Table:

local module = {}

module.Rocks = {
	
	["Stone"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = math.random(3,7), --Amount of Xp it can drop
		{Name = "Stone", Weight = 100, Amount = math.random(2,5)}, --Loot Table
	},

	["Coal Ore"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = math.random(3,7), --Amount of Xp it can drop
		Loot = {
			{Name = "Copper", Weight = 100, Amount = math.random(1,5)}, --Loot Table
		},
	},

	["Geode"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = math.random(10,20), --Amount of Xp it can drop
		Loot = {--Loot Table
			{Name = "Amethyst", Weight = 12.5, Amount = math.random(1,4)}, 
			{Name = "Topaz", Weight = 12.5, Amount = math.random(1,4)}, 
			{Name = "Sapphire", Weight = 12.5, Amount = math.random(1,3)}, 
			{Name = "Amber", Weight = 12.5, Amount = math.random(1,3)}, 
			{Name = "Ruby", Weight = 12.5, Amount = math.random(1,3)}, 
			{Name = "Diamond", Weight = 12.5, Amount = math.random(1,3)}, 
			{Name = "Emerald", Weight = 12.5, Amount = math.random(1,3)}, 
			{Name = "Onyx", Weight = 12.5, Amount = math.random(1,2)}, 
		},
	},
3 Likes

You can use table.insert() to add Items, Variables, or Tables Together.

To Clear or Remove a Child from a Table, you can use table.remove() or table.clear()

2 Likes

I’m aware however how will i be able to grab the items from the loot table when its inside of the table.

1 Like

The reply above deals solely with arrays, not dictionaries.
This is how you access elements of dictionaries.

module.Rocks
module.Rocks.Stone -- Rocks doesn't actually have a Loot entry.
module.Rocks["Coal Ore"].xp
local element = "Geode"
module.Rocks[element].Loot[2].Name
-- Also the random value in Amount is constant, it won't make a new random number every time you access Amount

You could look up a tutorial on dictionaries if you want to have this explained better than I could.

2 Likes
local myWeaponsModule = require(yourModulePath)

for i, v in pairs(myWeaponsModule.Rocks) do
      -- let's say you're trying to display your rocks in a specific gui template as the rock's details.
     local template = myGuiTemplatePath:Clone()
     template.Name = i
     templae.RockName.Text = i
     template.SpawnChance.Text = v["SpawnChance"]
     template.xp.Text = v["xp"]
end

Of what I understood of your question, this is an example of how it works, hopefully this is helpful.

2 Likes

You can usually use table.find()

2 Likes

ill try and test the table.find() and hopefully it’ll work

1 Like

If it doesnt work,
Try following the other Posts! They are also trying to help you and I recommend that you try them too

2 Likes

What exactly are you using it for? How we would script this would most likely depend on the use, but if we are just going over the list of loot in order to show it (or something like that), I would use a for loop. (for geode)

local rock = rocks.Geode

for i,v in pairs(rock.Loot) do
    print(v.Name, v.Weight, v.Amount)
end

Also, this could be a problem later on, but, when calling math.random in the data table

That sets the Amount to that, and never changes it. The only way to fix it would be to put it into a table like so:

Amount = {1,4}

and call math.random later on

received = math.random(loottbl.Amount[1], loottbl.Amount[2])

In this fixed case I provided, the earlier script I showed, would instead look something like this:

local rock = rocks.Geode

for i,v in pairs(rock.Loot) do
    print("Name: "..v.Name)
    print("Weight: "..v.Weight)
    print("Amount: "..v.Amount[1].."-"..v.Amount[2])
    print("")
end
1 Like

Cant you just do this?

received = loottbl[math.random(1, #loottbl)]
1 Like

That’s to receive a random loot, I was talking about the amount of the received item. Sorry if that confused you.

1 Like

initially im using the table to store the data of mineable rocks, showing their spawnchance, loot table, and xp drops.

1 Like

Yes, I know, but I figured that would eventually be a problem since the value would be set. Also, if you are responding to what you are using it for, I mean how are you using it, like what is it going to be doing? Are you iterating over the loot in order to give loot out or are you simply showing the loot on the screen, etc?

1 Like

i plan to use the table to give out loot from loot table once the rock is mined and xp. The server will then run through each rock’s spawn-chance/weight and pick a random rock to spawn in varying on its spawn-chance/weight.

hopefully that clears up how i was intending to use it

1 Like

Alright, yes, then my point about the amount is valid. So, here’s an example/partly completed script you may be able to use parts of:
Module first

local module = {}

module.Rocks = {
	["Stone"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		{Name = "Stone", Weight = 100, Amount = {2,5}}, --Loot Table
	},

	["Coal Ore"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		Loot = {
			{Name = "Copper", Weight = 100, Amount = {1,5}}, --Loot Table
		},
	},

	["Geode"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {10,20}, --Amount of Xp it can drop
		Loot = {--Loot Table
			{Name = "Amethyst", Weight = 12.5, Amount = {1,4}}, 
			{Name = "Topaz", Weight = 12.5, Amount = {1,4}}, 
			{Name = "Sapphire", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Amber", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Ruby", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Diamond", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Emerald", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Onyx", Weight = 12.5, Amount = {1,2}}, 
		},
	},
local rocks = require(rockmodule)

local totalchance = 0
for i,v in pairs(rocks) do totalchance += v.SpawnChance end

function spawnrock()
	local rannum = math.random(totalchance)
	local curnum = 0
	
	for i,v in pairs(rocks) do
		curnum += v.SpawnChance
		
		if curnum <= rannum then
			--spawn this rock
		end
	end
end

function givereward(plr, rockname) --probably pass the player here
	local rock = rocks[rockname]
	
	local lootgained = {}
	for i,v in pairs(rock.Loot) do
		table.insert(lootgained, i, v) lootgained[i].Amount = math.random(v.Amount[1], v.Amount[2])
	end
	
	local xpgained = math.random(rock.xp[1], rock.xp[2])
	
	--give the gained stuff
end
2 Likes

Ok I see now. I’ll try and test it out whenever I can. Unfortunately. I’ll cannot test it out at the moment but whenever I can I will notify you when I do. I really appreciate the help and thank you all for helping me out!!!

2 Likes

So I used your code but had to retype some stuff due to bugs, however whenever I tried to print the XP gained and the loot gained however the loot gained table would only print this.

image

also tried to print the rock name within the same function and returned as a table again.

image

here’s the code

function spawnrock()
	local rannum = math.random(totalchance)
	local curnum = 0

	for i,v in pairs(RockMod.Rocks) do
		curnum += v.SpawnChance

		if curnum <= rannum then
			print(curnum, rannum)
		end
	end
end

function givereward(plr, rockname) --probably pass the player here
	local rock = RockMod.Rocks[rockname]
	
	print(rock)
	
	local lootgained = {}
	for i,v in pairs(rock.Loot) do
		table.insert(lootgained, i, v) lootgained[i].Amount = math.random(v.Amount[1], v.Amount[2])
	end

	local xpgained = math.random(rock.xp[1], rock.xp[2])
	
	for i,v in pairs(lootgained) do
		print(i,v, xpgained)
	end
end

RS.RemoteEvents.UsePickaxe.OnServerEvent:Connect(function(player, target, tool)
	if target.Mined then --Checks if the target is a rock
		if target.Mined.Value == false then
			--irrelevant code
		else
			--more irrelevant code
			
			wait(0.5)
			
			givereward(player,target.Name)
		end
	end
end)
1 Like

But instead of having a Variable do it, do this:

print(RockMod.Rocks[rockname])
2 Likes

still returned as a table oddly enough. I tried print("Rock: "..rockname) and it returned the actual rock’s names but non of the stuff in it. I believe that table it’s printing is the actual rock’s table, i just need to find out how to grab all the stats without it being weird.

this is what it looks like now just in case.

function givereward(plr, rockname) --probably pass the player here
	local rock = RockMod.Rocks[rockname]
	
	print("Rock: "..rockname)
	
	local lootgained = {}
	for i,v in pairs(rock.Loot) do
		table.insert(lootgained, i, v) lootgained[i].Amount = math.random(v.Amount[1], v.Amount[2])
	end

	local xpgained = math.random(rock.xp[1], rock.xp[2])
	
	for i,v in pairs(lootgained) do
		print(i,v, xpgained)
	end
end
1 Like

What’s being weird about it? The lootgained would look something like this:

{
	{Name = "Copper", Weight = 100, Amount = 2}
}

which means what’s inside would be a table, leading to that table you found when printing that. As for the XP, it should simply be a number 3-7 (assuming it was coal ore), so there shouldn’t be a problem?

2 Likes