Gnet.Sync() problem with Flip(0)

BlitzMax Forums/BlitzMax Programming/Gnet.Sync() problem with Flip(0)

I've been messing around trying to interface GNET to my own game framework. I was getting a problem where GNET_CREATED messages were not being received, and therefore objects were not getting co-ordinated.

In the end I wrote a small game to test GNET and I didn't get the same problem. I've spent days cross referencing it, and now I've identified the source of the error.

My Game framework uses FLIP(0), and the game used FLIP().

Take a look at this code:
'GNET TEST
SuperStrict
Import BRL.GNet

Graphics 640,480
SeedRnd( MilliSecs() ) 

Global hasQuit% = False
Global host		:TGNetHost	 = CreateGNetHost()
Global player	:TPlayer	 = New TPlayer.Create( Rand(0 , GraphicsWidth() ) , Rand(0 , GraphicsHeight() ) , Rand(0 , 360), $00, $ff, $00 )

Const SLOT_TYPE		:Int = 1
Const SLOT_X		:Int = 2
Const SLOT_Y		:Int = 3
Const SLOT_ROTATE	:Int = 4

Const CLASS_PLAYER	:Int = 1
Const CLASS_BULLET	:Int = 2

'##########
Const SPEED_MOVE	:Float	 = 0.10
Const SPEED_ROTATE	:Float	 = 1.00
Const SPEED_BULLET	:Float	 = 0.20
Const FLIPMODE		:Int	 = 0
'##########

Select Proceed( "Do you want to Host a Game? (No will join a game)" ) 
Case 0	' No to Host (Join)
	GNetConnect( host, "127.0.0.1", 4000 )
Case 1	'#Yes to host
	GNetListen( host, 4000 )
Default
	End
End Select

Local sprite	:TSprite
Local obj		:TGnetObject
While Not(hasquit) 
	Cls
	'#
	GNetSync( host ) 
	For obj = EachIn GNetObjects(host) 
		Select obj.state() 
		Case GNET_CREATED
DebugLog "Create -> " + GetGNetInt(obj,SLOT_TYPE) 
			onCreate( obj ) 
		Case GNET_CLOSED
DebugLog "Closed -> " + GetGNetInt(obj,SLOT_TYPE)
			onClose( obj )
		Case GNET_MODIFIED
'DebugLog "  Modify -> " + getGnetint(obj,SLOT_TYPE) 
'			onModify( obj ) 
		Default
			'# Ignore other states
		End Select
	Next
	'#
	For sprite = EachIn TSprite.list
		sprite.update() 
	Next
	'#
	For sprite = EachIn TSprite.list
		sprite.draw() 
	Next
	'#
	SetColor(255 , 255 , 255) 
	SetRotation(0)
	DrawText( TSprite.list.count() + " sprites",10,10 )
	'#
	If KeyHit(KEY_ESCAPE) Or AppTerminate() Then hasQuit = True
	Flip( FLIPMODE )	
Wend

CloseGNetHost( host ) 
End

Function onCreate( obj:TGnetObject ) 
Local x# , y# , r%
	x = GetGNetFloat( obj , SLOT_X) 
	y = GetGNetFloat( obj , SLOT_Y) 
	r = GetGNetInt( obj , SLOT_ROTATE) 
	'#
	Select GetGNetInt( obj , SLOT_TYPE ) 
	Case CLASS_PLAYER
		New Tplayer.Create( x , y , r , $00,$00,$ff, obj ) 
	Case CLASS_BULLET
		New Tbullet.Create( x , y , r , obj )
	Default
DebugLog "UNKNOWN CLASS OF OBJECT " + GetGNetInt( obj , SLOT_TYPE )
	End Select
End Function

Function onClose( obj:TGnetObject ) 
Local found% = False
	'# Loop through list and find this object
	For Local sprite:TSprite = EachIn TSprite.list
		If sprite.netobj = obj Then	'# Found
			sprite.remove()
			found = True
			Exit
		End If
	Next
	'#
	If Not found Then DebugLog "CANNOT FIND OBJECT " + GetGNetInt( obj,SLOT_TYPE )
End Function

Type TSprite
	Global list:TList = CreateList() 
	'#
	Field x# , y# , w# , h#
	Field r% , g% , b%
	Field rotation%
	Field netobj:TGnetObject
	'#
	Method _create( class%, x# , y# , rot% , w# , h# , r% , g% , b%, obj:TGnetObject = Null )
		Self.x = x
		Self.y = y
		Self.rotation = rot
		Self.w = w
		Self.h = h
		Self.r = r
		Self.g = g
		Self.b = b
		'#
		If obj Then
			netObj = obj
		Else
			netobj = CreateGNetObject( host ) 
		End If
		'#
		SetGNetInt( netobj , SLOT_TYPE , class ) 
		SetGNetFloat( netobj , SLOT_X , x ) 
		SetGNetFloat( netobj , SLOT_Y , y ) 
		SetGNetInt( netobj , SLOT_ROTATE , rotation ) 
		'#
		ListAddLast( list,Self )
	End Method
	'#
	Method update()
	End Method
	'#
	Method draw()
		SetHandle( w/2 , h/2 ) 
		SetRotation( rotation ) 
		SetColor( r , g , b) 
		DrawOval(x,y,w,h)
	End Method
	'#
	Method offscreen%()
		If x-w > GraphicsWidth() Then Return True
		If x+w <0 Then Return True
		If y-h > GraphicsHeight() Then Return True
		If y-h <0 Then Return True
	Return False
	End Method
	'#
	Method remove() 
		If isLocal() Then CloseGNetObject( netobj )
		list.remove( Self )
DebugLog "Object removed"
	End Method
	'#
	Method isLocal%()
		Return GNetObjectLocal( netobj )
	End Method
	'#
	Method isRemote%()
		Return GNetObjectRemote( netobj )
	End Method
	'#
	Method netUpdate() 
		x = GetGNetFloat( netobj, SLOT_X )
		y = GetGNetFloat( netobj, SLOT_Y )
		rotation = GetGNetInt( netobj, SLOT_ROTATE )
	End Method
End Type

Type TPlayer Extends TSprite
	Method Create:TPlayer( x# , y# , rot%, r% , g% , b% , obj:TgnetObject = Null )
		_create( CLASS_PLAYER, x , y , rot , 15 , 15 , r , g , b, obj ) 
	Return Self
	End Method
	'#
	Method update() 
		If isLocal() Then
			If KeyDown( KEY_LEFT ) Then
				rotation = rotation - SPEED_ROTATE
				If rotation <0 Then rotation:+360
				SetGNetInt( netobj, SLOT_ROTATE, rotation )
			End If
			If KeyDown( KEY_RIGHT ) Then
				rotation = rotation + SPEED_ROTATE
				If rotation > 360 Then rotation:- 360
				SetGNetInt( netobj, SLOT_ROTATE, rotation )
			End If
			If KeyDown( KEY_UP ) Then
				x:+ ( SPEED_MOVE * Cos( rotation + 180 ) )
				y:+ ( SPEED_MOVE * Sin( rotation + 180 ) )
				If x > GraphicsWidth() - 15 Then x = GraphicsWidth() - 15
				If x < 15 Then x = 15
				If y > GraphicsWidth() - 15 Then y = GraphicsHeight() - 15
				If y < 15 Then y = 15
				'#
				SetGNetFloat( netobj, SLOT_X, x )
				SetGNetFloat( netobj, SLOT_Y, y )
			End If
			If KeyHit( KEY_TAB ) Then
				New TBullet.Create( x,y,rotation )
			End If
		Else
			netUpdate()
		End If
	End Method
	'#
	Method draw() 
		Super.draw()
		SetHandle(0 , 0) 
		SetColor($ff,$00,$00)
		SetLineWidth(3)
		DrawLine(x,y,x-9,y)
		SetLineWidth(1)
	End Method
End Type

Type TBullet Extends TSprite
	Method Create:TBullet( x# , y# , rot%, obj:TgnetObject = Null )
		_create( CLASS_BULLET , x , y , rot , 3 , 3 , $ff , $00 , $00 , obj )
DebugLog "Bullet created"
	Return Self
	End Method
	'#
	Method update()
		If isLocal() Then
			x:+ ( SPEED_BULLET * Cos( rotation + 180 ) )
			y:+ ( SPEED_BULLET * Sin( rotation + 180 ) )	
			SetGNetFloat( netobj, SLOT_X, x )
			SetGNetFloat( netobj, SLOT_Y, y )
			If offscreen() Then remove()		
		Else
			netUpdate()
		End If
	End Method
End Type


Run it twice on your PC, and host the first. Now watch both windows carefully. Press tab repeatedly (to create bullets), and you will see that some of them do not get created on the other window... (THE BUG).

Now change the code in "Listing1", replacing the speed constants (cos flip(0) is faster) and Flipmode variable. Repeat the same again...

'##########
Const SPEED_MOVE	:Float	 = 1.00
Const SPEED_ROTATE	:Float	 = 5.00
Const SPEED_BULLET	:Float	 = 1.20
Const FLIPMODE		:Int	 = -1		'# DEFAULT
'##########


Any idea why this happens? Have I simply missed something?

yupp.
you forgot regular latency assumptions. you can surely not push the network each frame!
As well, gnet is not realtime targeted, use Pub.ENet if you need realtime.
GNet is targeted at a slower pace due to the massive amount of data (32slots on the gnet objects) it will syncronize

Cheers Dremora, Obvious now you've said it...