Help with random spawning

i have a system where it randomly spawn exp orbs
but i want it to separate the spawns to prevent loads of xp orbs in one cluster like this

or if you wait 30 min here: and here is the script the line should be some where in the script:

> local function GetOrbs()
> 	local RadWait = math.random(.05, .01)
> 	local Folder =  game.Workspace.orbs
> 	local OrbAreas = Folder:GetChildren()
> 	local Orb = game.Lighting.XP
> 	local proxprompt = Instance.new("ProximityPrompt")
> 
> 	spawn(function()
> 		while true do
> 			for i, v in pairs(Folder:GetChildren()) do
> 				game.Workspace.OrbsValue.Value = i
> 				if #Folder[v.Name]:GetChildren() < 1000 then
> 					
> 					local Area = OrbAreas[math.random(1, #OrbAreas)];
> 					local X = math.random(-Area.Size.x / 2, Area.Size.x / 2);
> 					local Y = math.random(-Area.Size.y / 2, Area.Size.y / 2);
> 					local Z = math.random(-Area.Size.z / 2, Area.Size.z / 2);
> 					local Point = Area.CFrame:ToWorldSpace(CFrame.new(X, Y, Z));
> 					wait(RadWait)
> 					local NewOrb;
> 					local NewProx;
> 					NewOrb = Orb:Clone()
> 					NewOrb.CFrame = CFrame.new(Point.p) 
> 					NewOrb.Parent = Area
> 					if Area:GetChildren() == 1 then -- here
> 						NewOrb:Destroy()
> 					end
> 
> 					NewProx = proxprompt:Clone()
> 					NewProx.KeyboardKeyCode = Enum.KeyCode.E
> 					NewProx.ActionText = "Pick up"
> 					NewProx.HoldDuration = 1
> 					NewProx.Parent = NewOrb
> 					
> 					if i == 1000 then break end
> 
> 					NewProx.PromptButtonHoldEnded:Connect(function(Plr)
> 						if Plr ~= nil then
> 							NewOrb:Destroy();
> 							Plr.leaderstats.XP.Value = Plr.leaderstats.XP.Value + 10
> 						end	
> 					end)
> 				end
> 			end
> 		end
> 	end)
> end
> 
> GetOrbs()

I think the code looks fine in spawning the orbs randomly and evenly distributed in each area
maybe your areas are too small that the orbs are clustering because they’re each bigger than the area
looking at your image, it looks like the areas are like 1x1x1 blocks?

also, math.random(.05, .01) doesn’t work because math.random only accepts integers, so you’re pretty much doing math.random(0, 0) and then your wait(RadWait) becomes just wait()

yea but my map is preatty rough so if i have a big spawn peace the it just becomes wierd

you could set it up so each orb area has a maximum amount of orbs so smaller areas don’t get too many orbs
then also give orb areas weights when randomly selecting them so larger areas get orbs more often than smaller areas

yea but thats exacly what im stugling in

and why i made this post so yea

to automatically give them weights based on their size, you could set the weights to Size.Magnitude
then, to randomly search using weights, here’s an example of how I normally handle it:

Items = {
-- {Item name, Weight},
   {"Cat", 15}, -- will appear if random number is > 0 and <= 15
   {"Dog", 5}, -- will appear if random number is > 15 and <= 20, we get the 20 from adding 5 to 15
   {"Lizard", 10}, -- will appear if random number is > 20 and <= 30, we get the 30 from adding 10 to 20
}
totalWeight = 30 -- Sum of all weights, you could automate this by looping through Items and adding the weights

-- Gets a random item
function getRandom()
   rand = math.random(1, totalWeight)
   for _, item in ipairs(Items) do
      rand -= item[2]
      if rand <= 0 then
         return item[1]
      end
   end
end
print(getRandom())

I think I messed up somewhere, lemme fix it nvm

i dont know how this will help me

you’d assign each orb area a weight based on their size, then, when spawning an orb, that code is for randomly selecting an area

do you need help with limiting the number of orbs in each area too? (I forgot to make an example of it earlier)

sure im not so good at coding so sure

the easiest way I can think of is to store the max number of orbs and current number of orbs for each area
and just select another area if the area it selected is full unless all areas are full
but it might cause lag if you have like 100s of areas and 1 is available because it may constantly select a full area and then need to re-select

the other way I can think of is to re-adjust the weights and totalWeight whenever an area is full
you’d set an area’s weight to 0 and recalculate the total weight
then, if the total weight is 0, wait until an area is available again to wait RadWait before reselecting a random available area