I’m trying to make a mob spawn and move forward for a practice tower defense system.
I have two scripts, one server side and one client. The server script spawns the mob(s) and fires all clients. The client script receives this and tweens the humanoid root part of the mob(s). From the players’ view, it looks totally normal but the issue comes from the server side. From my knowledge, the mobs should be completely still in the server side. However, when I click test and swap to server view, the mobs move. There are no errors or anything, I’m just confused on how the server sided mobs are moving.
I’m not looking for a different method of moving the mobs, I’d just like an explanation please.
I’ve attached what I believe is the relevant part of the code. Please let me know if the explanation lies within code that I have not attached.
--Server Side
function spawnMob(amount)
for i = 1, amount, 1 do
--Spawn the mob
local spawnedMob = mob:Clone()
local isAlive = spawnedMob:FindFirstChild("isAlive")
local humanoid = spawnedMob:FindFirstChild("Humanoid")
local hrp = spawnedMob:FindFirstChild("HumanoidRootPart")
spawnedMob.HumanoidRootPart.CFrame = start.CFrame + Vector3.new(0, 1, 0)
spawnedMob.Parent = workspace.towerDefense.mobs
--Move the mob
isAlive = true
rs.events.moveMob:FireAllClients(hrp, start, finish)
task.wait(1)
end
end
task.wait(4)
spawnMob(3)
--Client Side
moveMobEvent.OnClientEvent:Connect(function(hrp, start, finish)
local distance = (finish.Position - start.Position).Magnitude
local speed = 2 -- adjust this to control how fast they move
local duration = distance / speed
local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Linear)
local tween = TweenService:Create(hrp, tweenInfo, {CFrame = finish.CFrame + Vector3.new(0, 1, 0)})
tween:Play()
end)
It could be cause of network ownership. On the server while creating new mobs try setting the networkownership to nil.
function spawnMob(amount)
for i = 1, amount, 1 do
--Spawn the mob
local spawnedMob = mob:Clone()
spawnedMob.HumanoidRootPart:SetNetworkOwnership(nil)
local isAlive = spawnedMob:FindFirstChild("isAlive")
local humanoid = spawnedMob:FindFirstChild("Humanoid")
local hrp = spawnedMob:FindFirstChild("HumanoidRootPart")
spawnedMob.HumanoidRootPart.CFrame = start.CFrame + Vector3.new(0, 1, 0)
spawnedMob.Parent = workspace.towerDefense.mobs
--Move the mob
isAlive = true
rs.events.moveMob:FireAllClients(hrp, start, finish)
task.wait(1)
end
end
task.wait(4)
spawnMob(3)
It’s similar to how a player moves and it is replicated to the server. For example, your character’s NetworkOwnership is set to your player, therefore any movement on the client is automatically replicated to the server, the premise is the same in this case. You’re setting the ownership back to the server therefore no client can move the mob.
Robloxs physics by default will divide up its work by sending your computer objects to run physics for. One of the biggest reasons is it makes it so objects you are interacting with feel more responsive since there is no network latency. When your computer is doing the physics for something you are considered the network owner. You of course own your character, and Roblox looks at what is near you and will transfer you ownership of those items so that the physics feels more natural when you try to interact with it. When you have ownership though, Roblox believes your computer no matter what it says about the physics state of the object (position rotation and the like). In other words when we are talking about physics properties if you own the object, your computer can change it including local scripts. Setting network owner to nil like the solution says simply tells Roblox not to offload that objects physics to a users computer and to always process it on the server.
Also to be clear only PHYSICS PROPERTIES can be modified while you own it without FE getting involved. If you try to change other properties the server doesn’t believe you