Multiplayer Movement Interpolation improvements

Blitz3D Forums/Blitz3D Programming/Multiplayer Movement Interpolation improvements

RifRaf(Posted 2011) [#1]
Hi all,

I am pretty happy with Tiny Tanks Network play , but was interested to know if any of you smart people have any modifications, improvements or other insight into how it can be done better..

You can cut and paste the code below into B3D to see how its currently working.




;i always use a program start timer, the millisecs timer on a pc that has been on a long time is not reliable
; see the millisecs2() function below.. 

Global Program_TimeStart#=MilliSecs()

;very simple interplation type, the entity we are effecting, and the desired coordinates
Type InterPolEnt
 Field ent
 Field x#,y#,z#
End Type



;setup scene and dummy block entities
Graphics3D 800,600,0,2
plane=CreatePlane()
EntityAlpha plane,.7
EntityColor plane,0,200,0
mirror=CreateMirror()
ghost_block=CreateCube()
local_block=CreateCube()
EntityAlpha local_block,1
EntityColor local_block,255,0,0
PositionEntity local_block,0,2,0
PositionEntity ghost_block,0,2,0
cam=CreateCamera()
CameraClsColor cam,0,100,200
PositionEntity cam,20,5,20
PointEntity cam,ghost_block

;simulate the fps your game will run at
timer=CreateTimer(35)
intertime#=millisecs2()


movementspeed#=1
movement_inc#=.01
predictionmultiplier#=2

;main test loop
While Not KeyDown(1)
	movementspeed#=movementspeed#+movement_inc#
	If movementspeed#>1.5 Then 	
		movementspeed#=1.45
		movement_inc#=-.01
   ElseIf movementspeed#<0.0 Then
		movementspeed#=.001
		movement_inc#=.01
   EndIf
    
   
	;move the local block around, our ghost block will try to keep up via interpolation
	TurnEntity local_block,0,movementspeed#*5,0
	MoveEntity local_block,0,0,movementspeed#
	aaa#=aaa#+10:If aaa=360 Then aaa=0
	TranslateEntity local_block,0,Cos(aaa)*.2,0
 
	;SIMULATE GETTING A POSITION PACKET 5 TIMES PER SECOND, with 20% packet loss
	If intertime#<millisecs2() Then
        If Rand(1,10)< 9 Then  ;packetloss 20%
		 intertime#=millisecs2()+200
		 x1#=EntityX(local_block)
		 y1#=EntityY(local_block)
		 z1#=EntityZ(local_block)
		 Set_InterPolation(ghost_block,x1#,y1#,z1#,predictionmultiplier#)
      EndIf
	EndIf

    ;update all entities that have an interpolation attachment
	update_interpolation()

	UpdateWorld()
	RenderWorld()
	Flip
	WaitTimer(timer)
Wend



Function Set_InterPolation(ent,x#,y#,z#,addprediction#=1.0)
 ;play with the addprediction amount to fine tune results
 For ipi.interpolent=Each interpolent
   If ipi\ent=ent Then
     addx#=(x-EntityX(ent))*addprediction
     addy#=(y-EntityY(ent))*addprediction
     addz#=(z-EntityZ(ent))*addprediction
 	 ipi\ent=ent
	 ipi\x#=x#+addx
	 ipi\y#=y#+addy
	 ipi\z#=z#+addz
	 Return
   EndIf
 Next
 IPi.interpolent=New interpolent
     addx#=(x-EntityX(ent))*addprediction
     addy#=(y-EntityY(ent))*addprediction
     addz#=(z-EntityZ(ent))*addprediction
 	 ipi\ent=ent
	 ipi\x#=x#+addx
	 ipi\y#=y#+addy
	 ipi\z#=z#+addz
End Function 



Function Update_Interpolation(Smooth# = 0.08,Max# = 25,popdist=1) ;min was .0001 and max was 15
;play with the smooth and max amount to fine tune results
For ipi.interpolent=Each interpolent
	    dist# = Distance( IPI\X,IPI\Y,IPI\Z , EntityX(ipi\ent),EntityY(ipi\ent),EntityZ(ipi\ent) )
	    Movingx#=1
	    Movingy#=1
	    Movingz#=1
	    xdist# = ipi\X - EntityX( ipi\ent )
	    ydist# = ipi\Y - EntityY( ipi\ent )
	    zdist# = ipi\Z - EntityZ( ipi\ent )
	    inair=0
	If dist > ( Max  / Smooth )
	    xdist# = xdist * (smooth*5)
    	ydist# = ydist * (smooth*5)
	    zdist# = zdist * (smooth*5)
	Else
    	xdist# = xdist * Smooth
	    ydist# = ydist * Smooth
    	zdist# = zdist * Smooth
    EndIf
	TranslateEntity ipi\ent, xdist, ydist, zdist
Next
End Function 

Function RemoveInterolation(ent)
 For ipi.interpolent=Each interpolent
     If ipi\ent=ent Then Delete ipi
 Next
End Function 

Function Distance#( x#, y#, z#, x2#, y2#, z2# )
	value#=Sqr((x#-x2#)*(x#-x2#)+(y#-y2#)*(y#-y2#)+(z#-z2#)*(z#-z2#))
	Return value#
End Function

Function Millisecs2#()
	Return MilliSecs()-Program_TimeStart#
End Function










Last edited 2011

Last edited 2011


RifRaf(Posted 2011) [#2]
yikes, nobody ?

thanks anyway. perhaps the above will be useful to someone


Ross C(Posted 2011) [#3]
I've always been interested in this, but my attempts have never been great tbh, which is probably a weakness in my maths, and working with curves etc. Thanks for sharing the code though!


BlitzSupport(Posted 2011) [#4]
I can only repeat what Ross C has said -- I've played around with this stuff before on a number of occasions (using my own attempts at interpolation, cubic splines, etc) to no avail, hoping someone else would take care of it. So, this is just another "thanks for sharing" really!

I have to say, though, just running the demo, it seems to be doing rather a decent job, given that the ghost has no idea where the player really is and it's only getting 5 updates per second.