I’ll be teaching you how to move character movement to the server. Also called server authoritative character movement.
Just know, I’m simply teaching you this for fun and experimental purposes only to see what it would be like. This exact code is very simple and should not be included in actual games. While server authoritative character movement is a great concept, this code is not created with visual feedback for the player in mind.
Character movement is normally handled on the client so the player has instant control over what they do for a better gameplay experience.
First, why would you want to do this? You wouldn’t. Using this simple, exact code is a bad idea as it creates many unnecessary issues and delays for players and overall drags down the gameplay experience. However, using the server authoritative movement concept is a good idea if you instantly provide visual feedback to the player, which I will not cover.
This is useful for a sort of anti-cheat system for movement based exploits such as teleports and speed. You’re better off creating an actual anti-cheat system as this is not ideal.
To do this just change the network owner of the BaseParts of the player’s character to the server. This includes any body parts, accessories, etc.
Let’s get started. Create a script in ServerScriptService and put this code inside:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local function setNetworkOwner(part)
if part:IsA("BasePart") then
part:SetNetworkOwner() -- Set the network owner to the server
end
end
local function onCharacterAdded(character)
RunService.Heartbeat:Wait() -- Allow the character to load into the workspace
for _, descendant in character:GetDescendants() do -- Existing descendants
setNetworkOwner(descendant)
end
character.DescendantAdded:Connect(function(descendant)
setNetworkOwner(descendant)
end)
end
local function onPlayerAdded(player)
if player.Character then -- Existing player character
onCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)
end
for _, player in Players:GetPlayers() do -- Existing players
onPlayerAdded(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
And that’s it! Make sure not to include this in actual games and to only use it for experiments. You can try this out here.