Networking Sweps

So I have been confused on this subject for a long time and haven’t found a clear definitive answer. How exactly do you network the shooting, recoil, and lua partical effects so they don’t get ass raped by high ping. I use the default shootbullet and firebullet functions in my base, for reference. it would be much obliged if anyone could help me with this and provide some examples.

Recoil should only be set on one realm, such as client by using SetEyeAngles. If you do punch-view, they can continue to hold the trigger down and the bullets will hit the same spot. That is purely visual; SetEyeAngles actually moves the view and the point of aim.

The helper-function ShootEffects is where you’d do muzzle effects, etc. Both realms, use IsFirstTimePredicted and if you’re unable to target the attachment, encapsulate the util.Effect in a timer.Simple( 0 …

So ShootEffects uses IsFirst by default or will I still need to add it? What should be done when it comes to prediction for shootbullet and firebullet so they impact in the same place client and server side?

My PrimaryAttack calls ShootBullet which in turn calls ShootEffects

So, inside of ShootBullet:
[lua]local _m = self:GetMuzzle( );
– local _ep = self:GetEjectionPort( );
self:ShootEffects( _m, _ep );[/lua]

GetMuzzle
[lua]//
// Helper-Function Josh ‘Acecool’ Moser
//
function SWEP:GetMuzzle( )
local _m = self.Owner:GetViewModel( )

if ( !IsValid( _m ) ) then return; end

local _muzzle = _m:LookupAttachment( "muzzle" );
if ( _muzzle == 0 ) then
	_muzzle = _m:LookupAttachment( "1" );
end

local _attachment = _m:GetAttachment( _muzzle );
-- local _aPos = _attachment.Pos;
-- local _aAng = _attachment.Pos;

-- print( _aAng )

return _attachment or { Pos = Vector( 0, 0, 0 ), Ang = Angle( 0, 0, 0 ) };

end[/lua]

[lua]function SWEP:ShootEffects( muzzle, ejectionPort )
if ( !muzzle ) then return; end

// Recoil
if ( CLIENT ) then
	local recoil = math.Rand( 0.5, 1.5 );
	local _eyes = self.Owner:EyeAngles()
	_eyes.pitch = math.Clamp( _eyes.pitch - recoil, -90, 90 )
	self.Owner:SetEyeAngles( self.Owner:EyeAngles() - Angle( math.Clamp( recoil, -90, 90 ), 0, 0 ) )
end

// Setting up the effect
local effectdata = EffectData( );
effectdata:SetOrigin( self.Owner:GetShootPos( ) );
effectdata:SetEntity( self.Weapon );
effectdata:SetStart( self.Owner:GetShootPos( ) );
effectdata:SetNormal( self.Owner:GetAimVector( ) );
effectdata:SetAttachment( 1 );

// Call the effect inside of a timer.Simple( 0 in order to run it next frame ( issue with getting fix on attachment for some reason without doing this )
timer.Simple( 0, function( )
	if ( !self.Owner ) then return end
	if ( !IsFirstTimePredicted( ) ) then return; end
	util.Effect( "gunsmoke", effectdata );
end );

end[/lua]