Random Item Selector

Scripting is kind of hard for beginners, so I made this “Random Item Selector” script while I was bored. Let me go step by step on how this script works:

local tools = game:GetService("ReplicatedStorage"):WaitForChild("Tools") -- change this variable to the folder/model with all of the tools.
local numberValue = 1

local tableTools = {}

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		for i, v in pairs(tools:GetChildren()) do -- Starts off with a normal table.
			table.insert(tableTools, numberValue, v.Name)
			numberValue = numberValue + 1
		end
		numberValue = 1
		character:WaitForChild("Humanoid").Died:Connect(function()
			local random = math.random(1, #tools:GetChildren())
			wait(8)
			
			repeat wait() -- Removes everything but the selected item itself.
				for i, v in pairs(tools:GetChildren()) do
					if i ~= random then
						table.remove(tableTools, i)
					end
				end
			until next(tableTools)
			
			local clone = tools:WaitForChild(tableTools[1]):Clone()
			clone.Parent = player.Backpack
			
			repeat wait() -- removes everything even the selected item.
				for i, v in pairs(tools:GetChildren()) do
					table.remove(tableTools, i)
				end
			until next(tableTools)
			
			for i, v in pairs(tools:GetChildren()) do -- Resets the table back into its original form
				table.insert(tableTools, numberValue, v.Name)
				numberValue = numberValue + 1
			end
			numberValue = 1
		end)
	end)
end)

So lets start off with the first for loop. Instead of creating the loop in the actual script source, I decided to make a for loop just incase you add more items and you probably don’t know or you’re to lazy to add it inside the table.

for i, v in pairs(tools:GetChildren()) do -- Starts off with a normal table.
			table.insert(tableTools, numberValue, v.Name)
			numberValue = numberValue + 1
		end
		numberValue = 1

In my opinion, this was the hardest part to script. First I had to generate a random number using roblox’s math.random system. Then I removed every item but the selected item from the table.

local random = math.random(1, #tools:GetChildren())
			wait(8)
			
			repeat wait() -- Removes everything but the selected item itself.
				for i, v in pairs(tools:GetChildren()) do
					if i ~= random then
						table.remove(tableTools, i)
					end
				end
			until next(tableTools)

Then, I had to put the selected item in the player’s backpack and refreshed the whole table.

local clone = tools:WaitForChild(tableTools[1]):Clone()
			clone.Parent = player.Backpack
			
			repeat wait() -- removes everything even the selected item.
				for i, v in pairs(tools:GetChildren()) do
					table.remove(tableTools, i)
				end
			until next(tableTools)
			
			for i, v in pairs(tools:GetChildren()) do -- Resets the table back into its original form
				table.insert(tableTools, numberValue, v.Name)
				numberValue = numberValue + 1
			end
			numberValue = 1

In conclusion, I hoped this help. If there are any bugs please message me back and I will attempt to fix them. Toodaloo!

11 Likes

P.S. This only works when you reset instead of joining the game :confused:

Community Tutorials is for in-depth explanations about accomplishing certain things on the platform. As you’ve posted a script and are only explaining how it works, it does not belong as a Community Tutorial. I’ve recategorised it over to Community Resources.

2 Likes

Yep. That’s because all the main code is in the CharacterAdded event. To fix this, move all the code into the CharacterAdded event to a local function called updatePlayerTools. Then, call this function in the PlayerAdded and CharacterAdded events.

3 Likes

This is how I would do it:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local RNG = Random.new()
local Tools = ReplicatedStorage.Tools

local toolChildren = Tools:GetChildren()

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local choice = RNG:NextInteger(1, #toolChildren)
		local chosenTool = toolChildren[choice]

		local newTool = chosenTool:Clone()
		newTool.Parent = character
	end)
end)

Comments


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

Players
ReplicatedStorage

Listing the services you are going to use at the top is good practice. In fact, listing all dependencies up top is good practice in any language.


local RNG = Random.new()
local Tools = ReplicatedStorage.Tools

Random

When the game starts, ReplicatedStorage has to load its contents first before any scripts can run, which means you can use simple dot indexing instead of :WaitForChild.


local toolChildren = Tools:GetChildren()

:GetChildren

Tools:GetChildren creates an array that looks like this:

-- PSEUDOCODE
{
	[1] = FirstTool,
	[2] = SecondTool,
	[3] = ThirdTool,
	...
	[n] = NthTool,
}

It lists every tool in the Tools folder, indexed by number from 1 to the total number of tools. That line also assumes we never add a new tool to the Tools folder.


Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)

.PlayerAdded
.CharacterAdded

Event-oriented programming is another entire avenue of tutorials that this short code snippet couldn’t even begin to cover.

Basically, every time a player joins the game, whatever function used as an argument to Players.PlayerAdded:Connect will be called, with the player who joined as the argument.

That function makes it so that every time that player’s character is spawned into the game, whatever function was used as an argument to player.CharacterAdded:Connect will be called, with the character that spawned as the argument.


		local choice = RNG:NextInteger(1, #toolChildren)

# operator

# is an operator that returns the number of items in an array, so #toolChildren returns the # of tool children. In this line, RNG:NextInteger picks out a random number between 1 and the # of tools, which is later used to index toolChildren


		local chosenTool = toolChildren[choice]

This line returns the existing tool at the given index of [choice]. If we were to directly parent the tool to someone’s character, it could potentially be switching to a new character every time someone respawns. In fact, when a player’s character despawns with this tool, the tool is destroyed, meaning its .Parent will be locked and any future assignments to .Parent will error.


		local newTool = chosenTool:Clone()
		newTool.Parent = character

:Clone
.Parent

In order to fix this, we use this next line, which simply creates a copy using :Clone(). We then parent the cloned tool to the character.


	end)
end)

Sorry if I am misunderstanding the post, but can’t you just do tools[math.random(#tools)]?

1 Like

Which part are you attempting to change?

I would of used Random.new, but roblox keeps changing their scripts very so often, and I can’t seem to keep up. Would you recommend some websites to catch up?

1 Like

Most of the time, I find out about new stuff by answering other people’s questions in #help-and-feedback:scripting-support and browsing #updates, more specifically #updates:release-notes. In fact, I use the dev forum’s notification system (in preferences) to watch for new topics in that category, other categories too like #resources:community-resources.

I also used to do extensive research in the developer hub’s API reference. Roblox’s API is useful for 50% of the programming I do, so I try to keep myself informed by going there whenever I don’t know what part of something does.