Client-Side Torso Tilt Not Replicating Properly to Other Players

Topic:
Client-Side Torso Tilt Not Replicating Properly to Other Players

The Issue:
I’m implementing a torso tilt system where characters lean when moving. It works perfectly on the local client, but when trying to apply the same tilt to other players:

  • Their tilt is weaker/stiffer than the local player’s
  • Modifying C0 on other players characters doesn’t work smoothly due to network ownership
  • Server side solutions introduce noticeable delay

What I’ve Tried:

  1. Client Side Only

    • Modifying HumanoidRootPart and joint C0 values directly
    • Works for local player, but other players’ torsos resist changes due to network smoothing
  2. Server Side Replication

    • Sending tilt values via RemoteEvents and applying on server
    • Results in delayed tilt for all players
    • Unoptimized
  3. Hybrid Client Server Approach

    • Predicting tilt locally while syncing via server
    • Still get visual inconsistencies

Question:
How do games like Phantom Forces, Arsenal, or Ghoul Re achieve smooth, synchronized torso tilt? Is there a proven solution that:

  • Keeps tilt responsive on the local client
  • Properly replicates to other players
  • Doesn’t require excessive bandwidth?
local function TorsoTilt(dt)

    -- Math calculations above here
	Torso["Right Hip"].C0 = Torso["Right Hip"].C0:Lerp(delta_r_hip, lerp_time)
	Torso["Left Hip"].C0 = Torso["Left Hip"].C0:Lerp(delta_l_hip, lerp_time)
	M6D.C0 = M6D.C0:Lerp(delta_root_joint, lerp_time)
	Torso.Neck.C0 = Torso.Neck.C0:Lerp(delta_neck, lerp_time)
	
	local WindSpeed = Character:FindFirstChild("SprintSpeed")
	if WindSpeed then
		local tiltRotationDegrees = math.deg(DeltaTorso) * 2
		WindSpeed.Weld.C0 = WindSpeed.Weld.C0:Lerp(CFrame.Angles(0, math.rad(180 - tiltRotationDegrees), 0), 0.01)
	end

	ROTATION += dt
	
	--[[SendTiltData:FireServer({
		DeltaXZ = DeltaXZ,
		DeltaX = DeltaX,
		DeltaTorso = DeltaTorso,
		Sprinting = Sprinting,
		Vaulting = Vaulting
	})]]
end

local function OnRenderStepped(dt)
	TorsoTilt(dt)
end

RunService.RenderStepped:Connect(OnRenderStepped)

Video:

These games do utilize remotes for replicating that information to every client. It’s best to have a tick rate of 1 / 15 or slower, and then interpolate/tween the values on the client.

1 Like

I recently started learning about the buffer library. Would using it here be a significant optimization strategy?

No, you just need to fire the remote with a single number (CurrentCamera.CFrame.LookVector.Y).

1 Like