Issues with Entity Physics Being Synced

Hi all,

In a custom SWEP primary fire function I create an entity, set its angle to match the owner’s aim vector, and adjust it’s position to be outside of the player model. Once I Spawn the entity, I set it’s velocity to shoot out from the player’s sight.

In my game it spawns in the correct position with the correct angle. However, the velocity is not applied to the entity on the “client side”. In fact, the object is in a completely different position because the velocity did not sync. I printed both values to the screen to show this:

In the above image, the first position is on the server and the second position is on the client. I am guessing that the order in which I am calling these functions is wrong. Would anyone be able to point my in the right direction of the correct way to spawn an entity and set the velocity from the server-side? Here is the code:

Spawn Code


function SWEP:PrimaryAttack()
	if not self:CanPrimaryAttack() then return end

	if SERVER then
		ent = ents.Create("custom_ball")

		ent:SetAngles(self.Owner:GetAimVector():Angle())
		ent:SetPos(self.Owner:EyePos() + self.Owner:GetAimVector() * 30)

		ent:Spawn()
		ent:Activate()
		ent:GetPhysicsObject():SetVelocity(ent:GetAngles():Forward() * 1000)

		self:Remove()
	end
end

custom_ball.lua


ENT.Type = "anim"

ENT.PrintName		= "Custom Ball"
ENT.Author			= "Cruben"

function ENT:Initialize()

	self:SetModel( "models/Combine_Helicopter/helicopter_bomb01.mdl" )
	self:PhysicsInit( SOLID_VPHYSICS )      -- Make us work with physics,
	self:SetMoveType( MOVETYPE_VPHYSICS )   -- after all, gmod is a physics
	self:SetSolid( SOLID_VPHYSICS )         -- Toolbox

  	local phys = self:GetPhysicsObject()
	if (phys:IsValid()) then
		phys:Wake()
		phys:SetMaterial("gmod_bouncy")
	end
end

I am running a 4-player server hosted in my Gmod application (NOT dedicated). Let me know if you need any additional info to help out. Thanks!

A few things: you should precache your model before you set it so that it is definitely in the model cache before the client sets up its physics object. You also shouldn’t be setting the physics object’s velocity directly unless you do it shared – if you are moving the entire entity, run SetLocalVelocity and it will be networked to the client. Side note, you probably want to use

Entity:PhysicsInitSphere for your ball. Also, you don’t have to call SetSolid since the PhysicsInit* functions will already do it.

Thanks for those tips. I precached the model and changed my velocity code to the following:


ent:SetLocalVelocity(self.Owner:GetAimVector() * 1000)

However, when I ran it I am still experiencing the same sync issue. I even got rid of the server-side velocity code and placed the following in the Initialize hook after the physics object is ready:


self:SetLocalVelocity(Vector(0,0,100))

I tried self:SetVelocity as well. Even if no velocity is applied to the entity, the position and velocity still loses sync. Is there something wrong with the way I defined the entity? Is this a problem with hosting the server while you are playing?

I mean, Source prediction allows a small margin of error between server and client synced vectors and angles, but the initial velocity and position should be networked with the entity creation.

You’re not supposed to initialize physics on the server AND client (like 99% of the time). Make sure anything physics related in your custom_ball.lua happens on the server only.



function ENT:Initialize()

    if SERVER then
        self:SetModel( "models/Combine_Helicopter/helicopter_bomb01.mdl" )
        self:PhysicsInit( SOLID_VPHYSICS )      -- Make us work with physics,
        self:SetMoveType( MOVETYPE_VPHYSICS )   -- after all, gmod is a physics
        self:SetSolid( SOLID_VPHYSICS )         -- Toolbox

        local phys = self:GetPhysicsObject()
        if (phys:IsValid()) then
            phys:Wake()
            phys:SetMaterial("gmod_bouncy")
        end
    end
end


Why?

For some reason if you initialize your physics in client, entity will move really weird, like you can grab the model, but the physics origin stays where you spawned it

You can initialize it shared with a bit of extra work (manually updating the shadow).

This solved it for me. Once I only initialized the physics on the server it started to sync up properly. Thank you very much!