Random Placement Script Reuses

So I’m trying to make a script which automatically duplicates a single enemy and moves it to somewhere random on the map here’s the script:

local Template = script.Parent:FindFirstChildWhichIsA("Model")

local PP = Template.HumanoidRootPart

local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z

local minx = x - 500
local maxx = x + 500

local minz = z - 750
local maxz = z + 750

local rolls = 0
local maxrolls = 100

local isStudio = false

local RunService = game:GetService("RunService")

if RunService:IsStudio() then
	
	isStudio = true
	
end

local studiomaxrolls = 5

if isStudio == true then

	while true do 

		if rolls >= studiomaxrolls then

			Template:Destroy()

			script:Destroy()

		end

		rolls = rolls + 1

		local ranx = math.random(minx, maxx)
		local ranz = math.random(minz, maxz)
		
		print (ranx)
		print (ranz)
		
		local Clone = Template:Clone()
		Clone.Parent = script.Parent
		Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))

	end

end

Now the script works fine, however all the location of all the “randomly placed” zombies are equal excluding the first time the zombie gets cloned (eg. zombie1 coordinates = 5,0,2; zombie 2 coordinates = 27,0,72; zombie 3 coordinates = 27,0,72; zombie 4 coordinates = 27,0,72…), as shown in the output here:

NOTE: Red underline = x coordinate, blue/black underline = z coordinate

image

I would like to know why the “random” values are always the same

Does it change or stay same when you test it multiple times?
If yes, then roblox RNG is broken,
If no, then something is not updating values

1 Like

This is weird, maybe there is something I am missing, but the only thing I can think of is putting the if studio == true inside the while loop instead of the other way around.

1 Like

So I tested it multiple times and here are some results

NOTE: I changed the position reading system so it’s (X, Y, Z)

TEST 1:

ALL the values are the same this time

image

TEST 2:

This time only final four are the same

image

TEST 3:

Still, four are the same

image

So yeah I’m almost 100% sure it’s a Roblox RNG problem, are there any good alternatives for RNG (maybe some kind of bootleg RNG of some kind)

hmmm, i think something is not updating values, try to add print next to RNG command line.
like

		local ranx = math.random(minx, maxx)
                print("test")
		local ranz = math.random(minz, maxz)
1 Like

Try setting the CFrame before Parenting?

local Template = script.Parent:FindFirstChildWhichIsA("Model")

local PP = Template.HumanoidRootPart

local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z

local minx = x - 500
local maxx = x + 500

local minz = z - 750
local maxz = z + 750

local rolls = 0
local maxrolls = 100

local RunService = game:GetService("RunService")

local studiomaxrolls = 5

local ranx,ranz

if RunService:IsStudio() then

	while true do 

		if rolls >= studiomaxrolls then
			Template:Destroy()
			script:Destroy()
			break
		end

		rolls += 1

		ranx = math.random(minx, maxx)
		ranz = math.random(minz, maxz)
		
		print(ranx)
		print(ranz)
		
		local Clone = Template:Clone()
		Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
		Clone.Parent = script.Parent
	end
end

I removed the isStudio variable since you can check RunService:IsStudio() directly

1 Like

The other thing you could do is put the everything in a function and call that function from a while loop. Sometimes calling the function multiple times works.

1 Like

For the X value I got -102 from “rerun” 2-5

image

Results in the same problem…

Hmmm … this is super weird. Maybe try using this code to get a random number?

math.random()*(maxx-minx) + minx
-- and
math.random()*(maxz-minz) + minz

The math.random function with no parameters returns a random between [0.0,1.0), so this is the equivalent of your random code but it will not always return an integer number.

I’m honestly pretty stumped. I guess you could try messing with your randomseed (using math.randomseed), but other than that I don’t have any other ideas.

1 Like

math.random(nothing) returns numbers like
0.57624736597824635786586
(I found that out my naming all of my service tostring(math.random()))

1 Like

@arrowman888 @EmbatTheHybrid @aca1231231

UPDATE: I tried making it super random by randomizing the maxx, minx, minz, and maxz, and THEN making the random number using the newer values, however it still didn’t work, here’s the relevant snippet from the code:

if isStudio == true then

	while true do 

		if rolls >= studiomaxrolls then

			Template:Destroy()

			script:Destroy()

		end

		rolls = rolls + 1
		
		local minx2 = math.random(minx - 50, minx + 50)
		local maxx2 = math.random(maxx - 50, maxx + 50)

		local minz2 = math.random(minz - 50, minz + 50)
		local maxz2 = math.random(maxz - 50, maxz + 50)

		local ranx = math.random(minx2, maxx2)

		local ranz = math.random(minz2, maxz2)

		-- print (ranx .. "," .. y .. "," .. ranz)

		local Clone = Template:Clone()
		Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
		Clone.Parent = script.Parent
		
	end
end

Yep! It returns numbers in the range [0.0,1.0) that aren’t integers. With some math, those numbers can be turned into non-integer numbers between the given range.

2 Likes

I ran this code in studio and it worked for me:

local Template = script.Parent:FindFirstChildWhichIsA("Model")

local PP = Template.HumanoidRootPart

local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z

local minx = x - 500
local maxx = x + 500

local minz = z - 750
local maxz = z + 750

local rolls = 0
local maxrolls = 100

local isStudio = false

local RunService = game:GetService("RunService")

if RunService:IsStudio() then

	isStudio = true

end

local studiomaxrolls = 5

if isStudio == true then

	while true do 

		if rolls >= studiomaxrolls then

			Template:Destroy()

			script:Destroy()
			
			break
		end

		rolls = rolls + 1
		
		math.randomseed(rolls)
		local ranx = math.random()*(maxx-minx) + minx
		local ranz = math.random()*(maxz-minz) + minz
		
		
		print (ranx)
		print (ranz)

		local Clone = Template:Clone()
		Clone.Parent = script.Parent
		Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))

	end

end

Output:

  10:23:33.064  430.65828231356  -  Server - test:50
  10:23:33.065  -648.23510747763  -  Server - test:51
  10:23:33.066  -240.17694369361  -  Server - test:50
  10:23:33.067  494.14353829081  -  Server - test:51
  10:23:33.068  -337.13953443904  -  Server - test:50
  10:23:33.069  683.58567313776  -  Server - test:51
  10:23:33.070  -482.2025176584  -  Server - test:50
  10:23:33.070  -99.756102696435  -  Server - test:51
  10:23:33.071  316.29626754092  -  Server - test:50
  10:23:33.071  -489.27393228615  -  Server - test:51
2 Likes

Omg it worked thanks :smiley: :smiley: :smiley:

2 Likes

@EmbatTheHybrid @PseudoPerson @aca1231231 @RFL890 @arrowman888

There’s still one more problem though, after the NPC is teleported, the HumanoidRootPart doesn’t move “in sync” with the rest of the body, causing the NPC to break.

More information on that on this devforum post (I just made)

what is :isStudio ???

1 Like

It checks if your running the game in studio or in the roblox client

1 Like

whats the differance???

1 Like

See, I cut off a bit of the code to make it simpler to read. So basically what the full code does is it checks to see if I’m in studio or the client, and if I’m in the studio it basically duplicates the zombies 5x instead of 100x. This is the case because when you test things in studio, it turns your PC into the server, and my PC quite frankly isn’t as powerful as the big one at Roblox (their own servers)

1 Like