Weapon Prediction

So i’m trying to wrap my head around making my weapons fully predicted.

Here’s a useful post from an old thread:

My understanding is that shared code is run out of synch (it is run on the client slightly ahead of the server) and so to compensate it gets called over and over on the client until it is in synchronicity with the server.

With that in mind, i am trying to make a slightly more intricate weapon base. I need to fix my current code to work in MP.

[lua]
function SWEP:ReloadThink()

if self.ReloadTime and CurTime() >= self.ReloadTime then // the viewmodel is moved fully so play animations

	self.Weapon:SendWeaponAnim( ACT_VM_RELOAD ) 
	self.Owner:SetAnimation( PLAYER_RELOAD )
		
	self.ReloadEnd = CurTime() + self.Primary.ReloadEnd
	self.ReloadPlays = {}
	self.ReloadTime = nil

end

if self.ReloadEnd then
	
	for k,v in pairs( self.ReloadSounds ) do // play custom reload sounds - i cut this code out for readability
	
	end

	if CurTime() >= self.ReloadEnd then // move the viewmodel back and set the clip to full

		self.Weapon:SetViewModelPosition( self.ReloadPos, self.ReloadAng, self.Primary.AnimSpeed, true )
		self.Weapon:SetClip1( self.Primary.ClipSize )
		
		self.ReloadEnd = nil
		
	end

end

end

function SWEP:Reload()

if self.Weapon:Clip1() == self.Primary.ClipSize or self.Weapon:IsReloading() then return end

self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.ReloadEnd + self.Primary.AnimSpeed * 3 )
self.Weapon:SetViewModelPosition( self.ReloadPos, self.ReloadAng, self.Primary.AnimSpeed )

self.ReloadTime = CurTime() + self.Primary.AnimSpeed // first we move the viewmodel to its reload position before the next part

end[/lua]

Essentially, SetViewModelPosition is the code that does ironsights except i’ve modified it to suit my needs. My code works well when i am testing on my own server but i can guarantee it will run like absolute shit in MP. Apparently the HL2MP shotgun uses only a single DTbool in its reload code, how does it manage that? My reload sequences have multiple parts (first the viewmodel moves, then it plays animations, then it moves back) so how can i properly make these sequences predicted? Any help would be appreciated. I think i’m just looking at it all the wrong way.

When m_bInReload is true, run the viewmodel animation. Create a simple timer that lasts as long as that animation lasts. Put a timer in it that runs for however long one shell is put in, for number of shells in the max clip. After that, draw back. No timer is needed because your last animation should already be done before you draw back.

EDIT:
I’m probably completely off.

Here’s a quick explanation of prediction:

The client is always in the future in the sense of world time. The client is constantly generating moves and then simulating them, which is where you see the IsFirstTimePredicted. These moves haven’t necessarily happened on the server yet. Instead what’s really happening is that every time the client gets an acknowledge from the server, it will reset the world to the state it received, and then apply all the moves it’s been predicting onto that new state, this is where a move has not been predicted before.

For example, you could fire your gun on the client (first time prediction), get a world update, and then the client will run that move again, but this time it won’t be first time prediction. This is where you would use an IsFirstTimePredicted guard if you have special events like sounds (you can’t undo or restart a sound without the player noticing).

edit:
I actually don’t like the example I pasted, the SDK really is the best reference for getting your head around prediction and what to do with networked variabled.

So my current code is usable provided that i put IsFirstTimePredicted() checks in the appropriate places?