Ahhh Lag of the Century

Blitz3D Forums/Blitz3D Programming/Ahhh Lag of the Century

Whats My Face(Posted 2009) [#1]
I'm trying to do a simple network game where the server and clients are all on my system. When I add more than one client the server starts to fall way behind so if I press move on one guy the other client won't see that for several seconds or worse.

Server:
;set up
Graphics 640,480,16,2
SetBuffer FrontBuffer()
AppTitle "Server"

;constants
Const NEWPLAYER = 1
Const PLAYERDATA = 2

;type to put all the users into
Global u.user
Global us.user
Type user
	Field id
	Field recvBank
	Field sendBank
	Field x#,y#,z#
End Type

;open the server
Global svrGame = CreateTCPServer(8080)

;main loop 
While Not KeyHit(1)
	Cls
	
	;see if there is somebody new 
	Local connect = AcceptTCPStream(svrGame)
	If connect Then 
		;make a new user for that person
		u.user = New user
		u\id = connect
		u\recvBank = CreateBank(64)
		u\sendBank = CreateBank(64)
		WriteLine u\id,u\id 
		
		;tell all the other users that he exists
		;and tell him that all the other users exist
		For us.user = Each user
			PokeByte us\sendBank,0,NEWPLAYER
			PokeInt us\sendBank,1,u\id
			WriteBytes us\sendBank,us\id,0,64
			
			PokeByte u\sendBank,0,NEWPLAYER
			PokeInt u\sendBank,1,us\id
			WriteBytes u\sendBank,u\id,0,64
		Next
	EndIf 
	
	y = 0
	For u.user = Each user
		If ReadAvail(u\id) <> 0 Then 
			ReadBytes u\recvBank,u\id,0,64
			u\x# = PeekFloat(u\recvBank,0)
			u\y# = PeekFloat(u\recvBank,4)
			u\z# = PeekFloat(u\recvBank,8)
			Text 0,y,"ID: " + u\id + ",  X: " + u\x# + ",  Y: " + u\y# + ",  Z: " + u\z#
			y = y + 10
		EndIf 
		
		For us.user = Each user
			If us\id <> u\id Then 
				PokeByte us\sendBank,0,PLAYERDATA
				PokeInt us\sendBank,1,u\id
				PokeFloat us\sendBank,5,u\x#
				PokeFloat us\sendBank,9,u\y#
				PokeFloat us\sendBank,13,u\z#
				WriteBytes us\sendBank,us\id,0,64
			EndIf 
		Next
	Next
	
	Delay 5
Wend




Client:
Graphics3D 640,480,16,2
SetBuffer BackBuffer()
SeedRnd(MilliSecs())
AppTitle "Client"

Const NEWPLAYER = 1
Const PLAYERDATA = 2

;for all the other users that are on the same server
Global ou.otherUser
Type otherUser
	Field sphere
	Field id 
	Field x#,y#,z#
End Type 

;open the stream to the server
Local strmGame = OpenTCPStream("127.0.0.1",8080) 
While Not ReadAvail(strmGame)
Wend 
Global playerID = ReadLine(strmGame)

;player variables
Global playerX# = 0
Global playerY# = 0
Global playerZ# = 0

;player banks
Global sendBank = CreateBank(64)
Global recvBank = CreateBank(64)

;basic 3D scene
Local light = CreateLight()
Local plane = CreatePlane()
Local camera = CreateCamera():PositionEntity camera,0,1,0:CameraRange camera,.1,1000
Local sphere = CreateSphere(8,camera)

For n = 1 To 50
	cube = CreateCube()
	PositionEntity cube,Rnd(-200,200),.5,Rnd(-200,200)
	EntityColor cube,Rnd(0,255),Rnd(0,255),Rnd(0,255)
Next

;main loop
While Not KeyHit(1)
	If KeyDown(200) MoveEntity camera,0,0,.1
	If KeyDown(208) MoveEntity camera,0,0,-.1
	If KeyDown(203) TurnEntity camera,0,2,0
	If KeyDown(205) TurnEntity camera,0,-2,0 
	
	;write to the server telling it everything about the player
	PokeFloat sendBank,0,EntityX#(camera)
	PokeFloat sendBank,4,EntityY#(camera)
	PokeFloat sendBank,8,EntityZ#(camera)
	WriteBytes sendBank,strmGame,0,64
	
	;see if we've recieved any new data
	If ReadAvail(strmGame) Then
		;read the packet
		ReadBytes recvBank,strmGame,0,64
		;if its a new player
		Local initialbyte = PeekByte(recvBank,0) ;the first byte tells what the packet is about
		If initialbyte = NEWPLAYER Then
			;make sure that the ID is new and then make a new player
			Local id = PeekInt(recvBank,1)
			Local oldID = False
			For ou.otherUser = Each otherUser
				If id = ou\id Then
					oldID = True 
				EndIf
			Next
			If id <> playerID Then 
				ou.otherUser = New otherUser
				ou\sphere = CreateSphere() : EntityColor ou\sphere,255,0,0
				ou\x# = 0
				ou\y# = 0
				ou\z# = 0
				ou\id = id 
			EndIf 
		ElseIf initialbyte = PLAYERDATA Then
			For ou.otherUser = Each otherUser
				Local dataID = PeekInt(recvBank,1) 
				If dataID = ou\id Then
					ou\x# = PeekFloat(recvBank,5)
					ou\y# = PeekFloat(recvBank,9)
					ou\z# = PeekFloat(recvBank,13)
					PositionEntity ou\sphere,ou\x#,ou\y#,ou\z#
				EndIf 
			Next
		EndIf 
	EndIf 
	
	RenderWorld()

	Flip
	Delay 5
Wend

Function Debug(msg$="")
	Cls
	Text 0,0,msg$
	Flip
	Delay 1500
End Function



Wings(Posted 2009) [#2]
The issue is a BufferOverrun error.
you are simply put the 8000 bytes buffer of tcpip to full. this will cause the client to stall/halt while stream recover to both clients and server.

to helpout one needs to have law and order in stream. so it will keep smoth. and not fill it.

In udp this is not issue as packet gets nuked or flashed or comes other ways around.

here down i fixed your code just som minior changes. and it works like a charm. but still i have not change it to much i hope. it can be improved.

try drawing down your packet handler software. what shall server respond to and how to make SURE not owerflow TCP stream.


;Server Code





;CLient part