Rotating a Player's Character on the Client Breaks Character Replication

If you try the code below, you’ll see that it breaks character replication and causes characters to move as if they are teleporting.

local Players = game:GetService('Players')
local RunService = game:GetService('RunService')

RunService.Heartbeat:Connect(function()
	for _, player in Players:GetPlayers() do
		local character = player.Character
		local root = character and character:FindFirstChild('HumanoidRootPart') :: BasePart
		
		if not root then return end
		
		root.CFrame = CFrame.new(root.Position) * CFrame.Angles(0, math.rad(-90), 0)
	end
end)

Is there a way to fix this? I need it for a 2D game where characters should rotate instantly, ignoring interpolation.

I got it to work using AlignOrientation objects. There is no noticeable interpolation.
In this case, I think it’s better to use physics than to manually set the CFrame. It’ll probably be less buggy.

local Players = game:GetService('Players')
local RunService = game:GetService('RunService')

local function OnPlayerAdded(player)
	player.CharacterAdded:Connect(function(char)
		local alignOrientation = Instance.new("AlignOrientation", char)	
		alignOrientation.Attachment0 = char.HumanoidRootPart.RootAttachment
		alignOrientation.RigidityEnabled = true
		alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
	end)
	
end

game.Players.PlayerAdded:Connect(OnPlayerAdded)
for _, p in pairs (game.Players:GetPlayers()) do
	OnPlayerAdded(p)
end

alignorientation doesn’t provides an instant orientation change

Have you tried setting RigidityEnabled to true? That should make it instant.

RigidityEnabled isn’t meant to force the physics solver to apply things instantly, it’s for making the solver react quickly as possible to alignment. Even if AlignOrientation works, it wouldn’t make a difference in my case, because Roblox applies interpolation to physical objects during replication. Changing another player’s position on either the client or server causes everything to look glitchy when there are active rotation changes. A custom position replication system, or a directly custom character replication system, seems to be the only solution in my situation.