How to fix the fall of server-sided NPC through terrain/models created by client side

Hello, guys. I am making a game with infinitely generated terrain which was created using the Infinite Terrain plugin in Roblox Studio, and NPC with an interval of a few seconds would spawn near the player within a radius of 10-15 studs.

My problem is that terrain is created on the client side and NPC on the server side. The NPC falls through the terrain that is created by the client when it spawns.

I tried to make the spawn of NPC through the client but the problem was that the NPC spawned without animations and couldn’t walk or do anything. Maybe someone had the same problem and can help me?

1 Like

Hello, spawn the NPC locally and make its “Animate” script local as well, Let me know if this works.

I made a local script that spawns NPCs and put it in StarterPlayerScripts and also replaced “Animate” with the local script but it remains unchanged.

Would love an answer to this question as well! Had same problem!

Tell me what happens when you test it, did it fall through terrain, does it not move, or does it not animate.

It doesn’t fall through the floor but instead, it just stands without animation or any movements/actions
NPCScreenshot
.

Check if it’s HumanoidRootPart is unanchored, and also can you show me your script in StarterPlayerScripts.

local maxCopies = 10
local cooldown = 5

local npcModel = game.Workspace:FindFirstChild("Entity")

local modelQueue = {}

local function createNPC()
	local player = game.Players.LocalPlayer
	local playerPosition = player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character.HumanoidRootPart.Position

	if playerPosition and npcModel and npcModel:IsA("Model") then
		local radius = 50
		local minDistance = 25
		local randomOffset = (Vector3.new(math.random(), 0, math.random()) - Vector3.new(0.5, 0, 0.5)).unit * (radius + minDistance)
		local npcPosition = playerPosition + randomOffset

		local newNPC = npcModel:Clone()
		newNPC:SetPrimaryPartCFrame(CFrame.new(npcPosition))
		newNPC.Parent = game.Workspace

		table.insert(modelQueue, newNPC)

		if #modelQueue > maxCopies then
			local oldestNPC = table.remove(modelQueue, 1)
			oldestNPC:Destroy()
		end
	end
end

while true do
	createNPC()
	wait(cooldown)
end

Apologies, leave the Npc’s “Animate” script server-side. And put the Npc in replicated storage.

No change. I added NPC to ReplicatedStorage and also changed the Animate from LocalScript to Script.

For your script, delete the first if statement, next define the player position like this.

Local character = player.Character or player.CharacterAdded:wait()

Local playerPosition = character.HumanoidRootPart.Position

Also set the Npc Cframe after you set the parent to workspace.

For your npc, go in explorer and name it “NpcModel” and put it in replicated storage. Next reference it in your script like this,

Local npcModel = game.ReplicatedStorage.NpcModel

local maxCopies = 10
local cooldown = 5

local npcModel = game.ReplicatedStorage.NpcModel

local modelQueue = {}

local function createNPC()
	local player = game.Players.LocalPlayer
	local playerPosition = player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character.HumanoidRootPart.Position

	local character = player.Character or player.CharacterAdded:wait()

	local playerPosition = character.HumanoidRootPart.Position

	local radius = 50
	local minDistance = 25
	local randomOffset = (Vector3.new(math.random(), 0, math.random()) - Vector3.new(0.5, 0, 0.5)).unit * (radius + minDistance)
	local npcPosition = playerPosition + randomOffset

	local newNPC = npcModel:Clone()
	newNPC:SetPrimaryPartCFrame(CFrame.new(npcPosition))
	newNPC.Parent = game.Workspace

	table.insert(modelQueue, newNPC)
	
	if #modelQueue > maxCopies then
		local oldestNPC = table.remove(modelQueue, 1)
		oldestNPC:Destroy()
	end
end

while true do
	createNPC()
	wait(cooldown)
end

Delete the first playerPosition variable and set the npc cframe after making the parent workspace.

Is it okay now?

local maxCopies = 10
local cooldown = 5

local npcModel = game.ReplicatedStorage.NpcModel

local modelQueue = {}

local function createNPC()
	local player = game.Players.LocalPlayer
	
	local character = player.Character or player.CharacterAdded:wait()
	local playerPosition = character.HumanoidRootPart.Position

	local radius = 50
	local minDistance = 25
	local randomOffset = (Vector3.new(math.random(), 0, math.random()) - Vector3.new(0.5, 0, 0.5)).unit * (radius + minDistance)
	local npcPosition = playerPosition + randomOffset

	local newNPC = npcModel:Clone()
	newNPC:SetPrimaryPartCFrame(CFrame.new(npcPosition))
	newNPC.Parent = game.Workspace

	table.insert(modelQueue, newNPC)
	
	if #modelQueue > maxCopies then
		local oldestNPC = table.remove(modelQueue, 1)
		oldestNPC:Destroy()
	end
end

while true do
	createNPC()
	wait(cooldown)
end

also, if you have it run on the client, other players in game wont be able to track the NPC’s actions.

I know the game is single-player.

not in my case sadly. idk how to fix :roll_eyes:

I am very sorry, I didn’t read the post properly, what you wanted was an Npc that spawns close to the player and chases them? This script only spawns the npc. You have to add to the script for it to chase the player.

The script didn’t make a new NPC in the Workspace when I launched the game. How should I add the script? Through a script in StarterPlayerScripts or in the NPC itself?