How would I create an item spawning system that increases with the spawner rarity?

Hello.

I want to create an item spawning system that increases per spawn rarity.

I have a base idea of how to do this, but I am not entirely sure.

Any random item can spawn at any spawner except for mythicals. Mythicals will only spawn if the spawn’s rarity is Rare+.

This is what I’ve done so far.

while true do
	RunService.Heartbeat:Wait()
	
	local children = workspace.TrinketSpawns:GetChildren()
	
	for i = 1, #children do
		local child = children[i]
		local rarityType = child.Rarity.Value
		local objVal = child.Trinket
		local lastSpawned = child.LastSpawned
		
		-- Quick checks
		if objVal.Value then
			return
		end
		
		if not rarities[rarityType] then
			return
		end
		
		if tick() - lastSpawned.Value < globalCooldown and lastSpawned.Value > 0 then
			return
		end
		
		-- We're in
		print("boom")
		
		lastSpawned.Value = tick()
		
		local randomTrinket = rarities:GenerateRandomTrinket(rarityType)
		
		local clonedTrinket = ServerStorage.SpawnableItems:FindFirstChild(randomTrinket.Name):Clone()
		clonedTrinket.CFrame = child.CFrame
		clonedTrinket.Parent = workspace.Trinkets
		
		objVal.Value = clonedTrinket
	end
end

Here are my current rarity types with the items:

function module:GetTrinketRarityTypes()
    local rarityTypes = {
    -----------------------------------
	{
		Rarity = {
			Name = "Common", 
			Chance = .45,
		},
		
		Items = {
			{Name = "Coin"}
		},
	};
	-----------------------------------
	{
		Rarity = {
			Name = "Uncommon",	
			Chance = .32
		};
		
		Items = {
			{Name = "Silver Goblet"}
		},
	},
	
	-----------------------------------
	{
		Rarity = {
			Name = "Rare", 
			Chance = .145
		};
		
		Items = {
			{Name = "Ruby"},	
			{Name = "Emerald"},
			{Name = "Sapphire"},
		},
	};
	-----------------------------------
	{
		Rarity = {
			Name = "Legendary",	
			Chance = .08
		};
		
		Items = {
			{Name = "Diamond"},	
		},
	};
	-----------------------------------
	{
		Rarity = {
			Name = "Mythical",	
			Chance = .005
		};
		
		Items = {
			{Name = "TNT"},
		}
	}
	-----------------------------------
};
	
    -- Just making a group index so I can use that later
    for groupIndex, group in pairs(rarityTypes) do
	    for i, item in pairs(group.Items) do
		    item.GroupIndex = groupIndex
	    end
    end

    return rarityTypes
end

I haven’t done much here, but, this is what I’m trying to do in the function.

function module:GenerateRandomTrinket(spawnerRarity)
    local modifiedItemTypes = module:GetTrinketRarityTypes()

    -- Determine rarity

    -- Return randomized trinket depending on spawnerRarity
    return
end

This is all the setup for the spawning. I don’t know how to progress from here, so that’s why I’m asking for help.

Thank you.

2 Likes

may I ask why you are putting heartbeat in a while loop?

Because it’s waiting for a small amount. That’s the smallest amount possible.

I’ve also heard that using ‘wait()’ could apparently cause problems, so that’s why I use heartbeat more often.

You should consider changing the rarity values to a range, from lowest to highest.

Rare = 0.07
Uncommon = 0.25
Common = 0.68

local newDrop = math.random(0,100) / 100

then for loop it until it finds a rarity of which it’s greater than.

This is an incredibly crude method; ideally you’d want to use normal distribution with a mean number for an item or something else like that.


function module:GenerateRandomTrinket(spawnerRarity)
   local modifiedItemTypes = module:GetTrinketRarityTypes()

   -- Determine rarity
   local rarities = {}

   local rarityTotal = 0
   for _, infoTable in ipairs(modifiedItemTypes) do -- it's an array of objects, ipairs, infoTable is the table
       rarityTotal = rarityTotal + rarities[infoTable.Rarity.Name]
       rarities[infoTable.Rarity.Name] = rarityTotal -- it's the thingy
   end

   randomValue = random:NextNumber(0, rarityTotal)
   local newRarity
   for rarity, value in pairs(rarities) do
       if randomValue < value then -- it'll keep doing this until it finally picks the best option
           newRarity = rarity
       end
   end

   -- Return randomized trinket depending on spawnerRarity
   local item
   for _, itemTable in ipairs(modifiedItemTypes) do
       if itemTable.Rarity.Name == newRarity then
           item = itemTable.Items[random:NextInteger(1, #itemTable.Items)]
           break -- im kinda paranoid, i know this is pointless but it's one of those hypothetical situations
       end
   end

   return item
end

Could you show me how I would incorporate the spawners rarity into the function, to increase the chance of you getting a certain item depending on it’s rarity?

For example, if it a rare spawner, you have more of a chance for a rare item. Not guaranteed, but a potential rare is more available. If it’s an uncommon spawner, then an uncommon item has more potenial to be chosen.