Coin Spawning Rarities

Hello!
I’m looking for assistance for two things.

  1. I’m trying to create a system that will spawn coins around a map.

I don’t have a lot of scripting knowledge, but I did think of something that might work. I could be able to create a part, and then use math.Random to choose random areas for coins to spawn on this part. I’m just not exactly sure what type of script I need to use, and what I would need specifically in it. If there is a more efficient way, feel free to tell me.

  1. I’m trying to create a script that can differentiate rarity, and spawn coins according to this rarity hierarchy.

I have 6 coins, and I would like a bronze coin to spawn more often than a gold coin. I’m not exactly sure how to do this, but I know there are “tables” in lua.

I’m not asking for a script. I’m asking for what type of script is necessary, and what the basic fundamentals could be to create these functions. Thanks!

1 Like

Ok, so

1. Have a dictionary with the rarity as the key and a table with all the coins in that rarity as the value.

2. Use math.random(1,10) to come up with a number, then…

3. Use an if statement to choose (Ex:

if randNum < 5 then
	coinToSpawn = coinsDict['common'][math.random(1, #coinsDict['common'])]

)

In effect all this did was if its less than 5, then the coin to spawn is a common coin in the coin dictionary (coinDict). The math.random is to choose a random common coin (like if copper and bronze coin were both common). The hashtag (#) is to get how long the table of common coins are, so you dont have to change the second number every time you add something new.
Square Brackets ([]) are a way to access a certain index in a table.

This probably wasn’t very descriptive, I typed this up in 1 minute lol, I apologize for that.
I hope this helps though.

1 Like

When making a chance system, I recommend you use some sort of module, I personally recommend using LootPlan. It’s pretty easy to use and works well.

local ReplicatedStorage = game:GetService("ReplicatedStorage");
local LootPlan = require(ReplicatedStorage.LootPlan); --Put the LootPlan module in ReplicatedStorage.

local coinLootPlan = LootPlan.new("single"); --This makes a new loot plan
coinLootPlan:AddLoot("coin", 50); --This makes a new loot called "coin" with a 50% chance of dropping
coinLootPlan:AddLoot("coin2", 25); --This makes a new loot called "coin2" with a 25% chance of dropping
coinLootPlan:AddLoot("coin3", 5); --This makes a new loot called "coin3" with a 5% chance of dropping

function spawnCoin()
	local chosenCoin = coinLootPlan:GetRandomLoot(); --This will pick a random coin name from the loot pool we made above
	print(chosenCoin); --Now you can do with this as you will
end
spawnCoin();
1 Like

Ahem, did you not read this? Please make sure you fully understand the question before replying.

I was just showing an example of how to use the module I proposed. OP said he doesn’t know too much about programming, so I decided to write something to show how to use a module in case they didn’t know.

1 Like

If you’re going to pull this card, you also didn’t say what type of script to use. You just said use a dictionary and a table.

Didn’t say anything about if that should just be a dictionary at the top of their script, or if it should be a module script.

All I’m trying to say, is we aren’t here to ridicule or attack others, and your reply doesn’t sound like the nicest reply when we’re trying to be in a helpful, constructive environment on the DevForum.

2 Likes

To do this, you will need a Randomizing skill. Let me take an example. Create a for loop for 6 Coins. Like this for Coin in 1, NumberOfCoins do. Then inside it you will give it a spawning script right? But you want it to have different type of coins that spawn rarer and one spawn more often ( here is gold coin and broze coin. ). Then you can do

local CoinRarity = {
   ["Brozen"] = 70, -- Have 70% to spawn
   ["Gold"] = 30 -- Have 30% to spawn
}

for Coin in 1, NumberOfCoins do
   local RandomCoinType = RandomWithPercentage(CoinRarity) -- Give it the loot table
   print(string.format("%s Coin has spawned!", RandomCoinType))
   wait(5) -- Give it 5 seconds before another spawn
end

You can get the RandomWithPercentage function from the Forum. But the LootPlan make exploiters able to mess around with it. So I will give you my old function which works pretty well in my game.

function RandomWithPercentage(LootTable)
	if LootTable then
		local Total_Percentage = 0
		for _, total_percent in pairs(LootTable) do
			Total_Percentage += total_percent
		end
		
		if Total_Percentage == 100 then
			local WeightedLootTable = {}

			-- Get Multiplys

			local WeightedMultiplys = 1
			for _, percentage in pairs(LootTable) do
				if percentage < 1 then
					local TotalMultiplied = 0

					for i = 0, 10 do
						if percentage < 1 then
							percentage *= 10
							TotalMultiplied += 1
						end
					end
					if TotalMultiplied > WeightedMultiplys then
						WeightedMultiplys = TotalMultiplied
					end
				end
			end

			-- Multiplying WeightedTable
			
			for item, percentage in pairs(LootTable) do
				local WeightedPercentage = percentage
				for i = 0, WeightedMultiplys do
					WeightedPercentage *= 10
				end
				
				WeightedLootTable[item] = WeightedPercentage
			end
			
			-- Doing a Double Check
			
			local Smallest_Percent = math.huge
			for _, percentage in pairs(WeightedLootTable) do
				if percentage < Smallest_Percent then
					Smallest_Percent = percentage
				end
			end
			
			if Smallest_Percent > 10 then
				for item, percentage in pairs(WeightedLootTable) do
					WeightedLootTable[item] = percentage / 10
				end
			end
			
			-- Randomizing
			
			local sum = 0

			for k, v in pairs(WeightedLootTable) do
				sum = sum + v
			end

			local r = math.random(sum)

			for k, v in pairs(WeightedLootTable) do
				r = r - v

				if r <= 0 then
					return k
				end
			end
		end
	else
		warn("Randomizing requires a loot table!")
	end
end

local CoinRarity = {
   ["Brozen"] = 70, -- Have 70% to spawn
   ["Gold"] = 30 -- Have 30% to spawn
}


local RandomCoinType = PercentageRandomizing(CoinRarity)
print(RandomCoinType)

This used Weighted Percentage, you can mess around with it and I’ve made this to work with decimal!

EDIT : MAKE SURE THE LOOT TABLE SUM IS 100, NOT GREATER OR SMALLER.

Fair point, I stand corrected.

So, I’m gonna try your way first, if it doesn’t work out then I’ll try the others in the thread.

So, I assume that I would need some sort of folder, possibly in Rep Storage, then I need to put the coins in the folder. I would then need to get the script to find the folder, and clone the coins at random area and use this script as a loot table for them?

Edit: Sorry if I’m wrong, like I said, I’m just now trying to learn scripting.

You can just get the Random Coin Type like the Script I gave you. You will notice that it’s printing different type. If you change the percentage, it will spawn different. But make sure it add up to 100. To get the coins, you can do

local CoinStorage = -- Where you store the coins

local RandomCoinType = -- Use the random function I gave you

local CoinMeshes = CoinStorage:FindFirstChild(RandomCoinType.."Coin") -- If it give Gold rarity, then you should have a Coin meshes named ```GoldCoin```.
local ClonedCoin = CoinMeshes:Clone()
ClonedCoin.Position = Vector3.new(math.random(1, 100), 1, math.random(1, 100)) -- Spawn it in random position
ClonedCoin.Parent = workspace
1 Like

And this would go as a regular Script in ServerScriptService?

You can give it inside the Workspace as a Regular Script.

Ok, so I have my folder in Rep Storage, and my coins inside. I have my script in workspace, and everything in it setup, but when I test it, I get this:
image

As long as you use LootPlan on the server, there is no risk of exploiters abusing it. This applies to all code.

As a general rule of thumb, never trust the client. Anything important, especially things that effect several players, should be done by the server.

Can you please provide the code you are using?

Yup! Sorry about this, I know it’s probably missing a lot of what you gave me and I know this might be annoying for you.

local CoinStorage = game.ReplicatedStorage.CoinFolder-- Where you store the coins

local RandomCoinType = function RandomWithPercentage(LootTable)-- Use the random function I gave you

   local CoinMeshes = CoinStorage:FindFirstChild(RandomCoinType.."Coin") -- If it give Gold rarity, then you should have a Coin meshes named ```GoldCoin```.
local ClonedCoin = CoinMeshes:Clone()
ClonedCoin.Position = Vector3.new(math.random(1, 100), 1, math.random(1, 100)) -- Spawn it in random position
ClonedCoin.Parent = workspace

Can you please change to this? You will need to define the function first.

function RandomWithPercentage(LootTable)
	if LootTable then
		local Total_Percentage = 0
		for _, total_percent in pairs(LootTable) do
			Total_Percentage += total_percent
		end
		
		if Total_Percentage == 100 then
			local WeightedLootTable = {}

			-- Get Multiplys

			local WeightedMultiplys = 1
			for _, percentage in pairs(LootTable) do
				if percentage < 1 then
					local TotalMultiplied = 0

					for i = 0, 10 do
						if percentage < 1 then
							percentage *= 10
							TotalMultiplied += 1
						end
					end
					if TotalMultiplied > WeightedMultiplys then
						WeightedMultiplys = TotalMultiplied
					end
				end
			end

			-- Multiplying WeightedTable
			
			for item, percentage in pairs(LootTable) do
				local WeightedPercentage = percentage
				for i = 0, WeightedMultiplys do
					WeightedPercentage *= 10
				end
				
				WeightedLootTable[item] = WeightedPercentage
			end
			
			-- Doing a Double Check
			
			local Smallest_Percent = math.huge
			for _, percentage in pairs(WeightedLootTable) do
				if percentage < Smallest_Percent then
					Smallest_Percent = percentage
				end
			end
			
			if Smallest_Percent > 10 then
				for item, percentage in pairs(WeightedLootTable) do
					WeightedLootTable[item] = percentage / 10
				end
			end
			
			-- Randomizing
			
			local sum = 0

			for k, v in pairs(WeightedLootTable) do
				sum = sum + v
			end

			local r = math.random(sum)

			for k, v in pairs(WeightedLootTable) do
				r = r - v

				if r <= 0 then
					return k
				end
			end
		end
	else
		warn("Randomizing requires a loot table!")
	end
end

local CoinRarity = {
   ["Brozen"] = 70, -- Have 70% to spawn
   ["Gold"] = 30 -- Have 30% to spawn
}

local CoinStorage = game.ReplicatedStorage.CoinFolder-- Where you store the coins

local RandomCoinType = RandomWithPercentage(CoinRarity)

local CoinMeshes = CoinStorage:FindFirstChild(RandomCoinType.."Coin") -- If it give Gold rarity, then you should have a Coin meshes named ```GoldCoin```.
local ClonedCoin = CoinMeshes:Clone()
ClonedCoin.Position = Vector3.new(math.random(1, 100), 1, math.random(1, 100)) -- Spawn it in random position
ClonedCoin.Parent = workspace

Ok, so I added your code, and added the rest of the coins, but now I’m not sure about this, I can’t find where to put the “}”.

I tried putting it in the original spot but it didn’t work.

You are missing the } when definding the Loot Table, change it to

local CoinRarity = {
   ["Brozen"] = 45
} -- You are missing this

I added that under “Infi” and it gave the same error, and it underlined it in red.