Removing key from table after use?

im writing a puzzle code and using a shuffle method to spawn 11 notes through about 50 different possible spawn locations. I made a post the other day about using tables and thought i had it all figured out, but it turns out i need a little more help.

i have 11 notes stored in a folder in the serverstorage, and about 50 locations in a folder in the workspace. what im trying to do is make each specific note spawn only once, and one per location. each note is an important piece of the puzzle which should spawn only once and one per locations. so pretty much only 11 spawn locations are used even though there is 50ish, and think of the notes as “colored keys”, i dont want two “yellow keys” to spawn, i want one of each “color” in this case.

here is the portion of code responsible for spawning the notes:

local ServerStorage = game:GetService(“ServerStorage”)

local notes = ServerStorage.Lvl5Puzzle:GetChildren()
local locations = workspace.Lvl5NoteLocations:GetChildren()

local function shuffleTbl(t)
local n = #t
for i = n, 2, -1 do
local j = math.random(i)
t[i], t[j] = t[j], t[i]
end
end

shuffleTbl(locations)

for i, note in ipairs(notes) do
local location = locations[i]
local noteClone = note:Clone()
noteClone.Parent = workspace
noteClone.CFrame = location.CFrame
end

when i do this it spawns ALL 11 of the notes at 11 spawns. i tried using table.remove(#notes, 1) but then it removes a random note without spawning it. ahhhhhh is there a better way to do this?? i feel like im going crazy lol any and all help is appreciated!

1 Like

This can be accomplished pretty easily with just a for loop and table.remove.

Basically, you have 11 notes and 50 spawn locations. You want each note to spawn at a random spawn location but only one of each note exists. You also don’t want notes to spawn in the exact same spot.

In order to ensure that only one of each note spawns, just use a for loop through the table of notes to spawn each note once. To make sure that no spawns overlap, just use table.remove on the chosen index of the locations table to make sure it doesn’t get picked again. table.remove will automatically shift over elements to the right of the removed element to fill the gap.

Here’s what this would look like in code:

local ServerStorage = game:GetService("ServerStorage")

local notes = ServerStorage.Lvl5Puzzle:GetChildren()

function spawnNotes()
	local locations = workspace.Lvl5NoteLocations:GetChildren()

	for i,note in ipairs(notes) do
		-- select the location out of the available ones
		local chosenLocationI = math.random(1,#locations)
		local chosenLocation = locations[chosenLocationI]
		
		-- spawn the note at the location
		local noteClone = note:Clone()
		noteClone:PivotTo(chosenLocation.CFrame)
		noteClone.Parent = workspace
		
		-- remove the location from the available table so it doesn't get picked again
		table.remove(locations,chosenLocationI)
	end
end

spawnNotes()

Hope this helps! Let me know if you have any questions.

2 Likes

this script works, just a little too good lol
it was still spawning a couple per location, and after i picked the note up it would spawn another one. i tried removing the notes from the table but it still skips over one note during spawn.

im all out of ideas so if you have any more id be grateful :slight_smile: my next process if this doesnt work out is creating seperate spawn tables for each note seperately and going from there.

2 Likes

I’ll try to help you as well, but I’ll need to know more information:

  • Is each note unique, or are some of the 11 notes duplicates?
  • How are you distinguishing between each note? Do they have different names, or are you using their color or BrickColor?
  • (If there are duplicate notes) Do you want to spawn all 11 notes, or only one of each?

@michael1784

This should work assuming that each note is unique and you wish to spawn all 11:

local ServerStorage = game:GetService("ServerStorage")
local Workspace = game:GetService("Workspace")

local notes = ServerStorage.Lvl5Puzzle:GetChildren()

local locations = Workspace.Lvl5NoteLocations:GetChildren()


local function spawnNotes()
	local randomLocations = {}

	while #randomLocations < 11 do
		local location = locations[math.random(#locations)]
		if table.find(randomLocations, location) then continue end
		table.insert(randomLocations, location)
	end

	for i, location in randomLocations do
		local note = notes[i]:Clone()
		note:PivotTo(location.CFrame)
		note.Parent = Workspace
	end
end

spawnNotes()

@michael1784 I made a mistake, the code should work correctly now :slight_smile::+1:

3 Likes

so each note has a letter on it which spells out a word to open the door. there are two “duplicates” but i have each note with a unique name, including the duplicates. i.e. I & I2, T & T2. so even the duplicates are their own part if thats what you mean.

thank you so much for your help i greatly appreciate it! ill give this a try in a little and get back to you on the results!

1 Like

hey so i just tested the code and it spawned all of the notes at all of the locations lol its great code for anyone wanting to spawn items at all locations in a table, and is actually very useful for an idea i have in the future progress of the game.

as for the puzzle, im not too sure where to go from here. i may tinker around with it later and see what i can do.
i may just create a table of spawns for each note seperate so it just spawns the one note per branch of locations, thats the only problem ive had with using the math.random function is it spawns duplicates at some spots.

again, i super appreciate you taking the time to help me!

Does that mean it spawned a note in all 50 locations, or that it spawned all 11 notes

Either or, I’m quite confused. The while loop should’ve stopped iterating after 11 unique locations were chosen:

And if the issue is that all of the notes were spawned, then how many notes do you want to spawn, or what determines which notes should spawn? If you want notes to spawn after another note was picked up, the code will need to be much more different than it currently is (Come to think of it, there is a way to implement this without needing to modify the code that drastically, assuming that the notes table is sorted in the correct order that they’ll need to be collected)

1 Like

yeah all 11 notes spawned at all 50 spawns. i do want all 11 of the notes to spawn, but only one time as each note is unique. i dont want there to be two “yellow keys” when there should be one of each “color”. and once the note is picked up i dont want another to spawn since then the player could just wait for each note to spawn and speedrun the puzzle lol

I just went ahead and made seperate spawn tables for each note and got it working. a little more code but less of a headache lol thank you @JohhnyLegoKing for all of your help!!

1 Like