animating characters during network update

Blitz3D Forums/Blitz3D Programming/animating characters during network update

chrisnorris007(Posted 2009) [#1]
I have a game I am working on....the animation works great for the main character (local) but when the game is updating network players...how do I make the walking animations work as a network player is updated?

chris

posted below is my code for network updates


Function UpdateNetwork()
While RecvNBMsg(mainstream)
	Select NBMsgType(mainstream)
		Case 100 ;New Player
			serverid$ = converttoid(serverip,serverport)
			If nbuserid = serverid
			checknbdatabase(mainstream) ;Make sure the host only does this
			ElseIf nbuserid <> serverid ;If you are not the server
			i.nbplayer = New nbplayer
			i\name = nbmsgdata(mainstream)
			i\ip = nbmsgip(mainstream)
			i\port = nbmsgport(mainstream)
			i\id = converttoid(i\ip,i\port)
			EndIf
			p.player = CreatePlayer(0,10,0, nbmsgfrom(mainstream) )
			pack$ = EntityX(play\entity) +" "+ EntityY(play\entity) +" "+ EntityZ(play\entity)
			SendNBMsg(1,pack,nbmsgfrom(mainstream),mainstream)
			pitch# = EntityPitch(play\entity)
			roll# = EntityRoll(play\entity)
			pack$=LSet$( pitch,7 )+LSet$( EntityYaw(play\entity),7 )+LSet$( roll,7 )
			SendNBMsg(3,pack,nbmsgfrom(mainstream),mainstream)


		Case 101 ;Player Left
			For p.player = Each player
		DebugLog("entity id:"+p\net_id +" netid:" + nbmsgfrom(mainstream))
			If p\net_id = nbmsgfrom(mainstream);Left$(nbmsgfrom(mainstream),Len(nbmsgfrom(mainstream))-3)
			FreeEntity p\model
			For n.nbplayer = Each nbplayer
				If n\id = p\net_id Then Delete n
				Next
			Delete p : Exit
			EndIf
			Next
		Case 1 ;Position File
			For p.player = Each player
			If p\net_id = nbmsgfrom(mainstream)
			dat$ = nbmsgdata$(mainstream)
			Local num1$,num2$,num3$,count
			For wc = 1 To Len(dat)
			let$ = Mid(dat,wc,1)
			If let = " " Then count = count + 1
			If let <> " "
				If count = 0
				num1 = num1 + let
				ElseIf count = 1
				num2 = num2 + let
				ElseIf count = 2
				num3 = num3 + let
				EndIf
			EndIf
			Next
			p\px = Float(num1) : p\py = Float(num2) : p\pz = Float(num3)
			HideEntity p\entity
			PositionEntity p\entity,p\px,p\py,p\pz : ShowEntity p\entity
			Exit
			EndIf
			Next
		Case 2 ;Movement File
			For p.player = Each player
			If p\net_id = nbmsgfrom(mainstream)
			move = nbmsgdata$(mainstream)
			If move = 1 ;Forward
			MoveEntity p\entity,0,0,1
			DebugLog("moved entity f" + p\net_id)
				AnimateMD2 p\model,1,p\anim_speed,3,31,1
	AnimateMD2 p\model,1,1,32,100,1

			ElseIf move = 2;Back
			MoveEntity p\entity,0,0,-1
	AnimateMD2 p\model,1,p\anim_speed,1,31,1
	AnimateMD2 p\model,1,1,32,100,1

			DebugLog("moved entity b" + p\net_id)
			ElseIf move = 3;Left

	AnimateMD2 p\model,1,p\anim_speed,1,31,1
	AnimateMD2 p\model,1,1,32,100,1
			TurnEntity p\entity,0,6,0
			DebugLog("moved entity l" + p\net_id)
			ElseIf move = 4;Right

	AnimateMD2 p\model,1,p\anim_speed,1,31,1
	AnimateMD2 p\model,1,1,32,100,1
			TurnEntity p\entity,0,-6,0
			DebugLog("moved entity r" + p\net_id)
			EndIf
			Exit
			EndIf
			Next
	
		Case 3 ;Rotation File
			For p.player = Each player
			If p\net_id = nbmsgfrom(mainstream)
			dat$ = nbmsgdata$(mainstream)
			rotx# = Float(Mid(dat,1,7)) :roty#=Float(Mid(dat,8,7)) : rotz#=Float(Mid(dat,15,7))
			RotateEntity p\entity,rotx,roty,rotz
			Exit
			EndIf
			Next
	End Select
Wend

For p.player = Each player
If p\net_id <> nbuserid
TranslateEntity p\entity,0,-.2,0
EndIf
Next
End Function



Ross C(Posted 2009) [#2]
You don't really need to send frame information for each player. Just send a state of the players animation. Such as 0 = static, 1 = walking, 2 = running ... etc etc

Then compare this with what the player is currently doing. If there are in a different state of animation, then change it accordingly.


chrisnorris007(Posted 2009) [#3]
can you show me this in a brief snippet of code?
this has been a major issue of mine


Ross C(Posted 2009) [#4]
Say for instance, you extract your animations:

global walk = extractanimseq(BLAH,BLAH)
global run = extractanimseq(BLAH,BLAH)
global idle = extractanimseq(BLAH,BLAH)

(Number wise, i think walk would be 1, run would be 2 and idle would be 3. that is the way blitz seems to assign these numbers)

main loop


   check_network()

end main loop

function check_network() ; for example sake, say your character is using animation state 2, idle.

   receive network packets(received_animation_state)
   ;animation_state = 1 in this example

   if animation_state <> received_animation_state then
      animation_state = received_animation_state
      animate player,1,1,animation_state
   end if

end function



Obviously you don't check the player that is being controlled on your side, as you will be sending out animation data to the other machines networked to your game.

It's important to remember you don't need to sync or have things running the exact same on every computer. Things like particles, the clouds running across the sky, the shadows... etc etc they don't matter much to the game play. If you had an explosion triggered by YOU, you only would send a message telling the other machines that an explosion has happened at (x,y,z), and maybe the size of explosion. Let each machine locally compute the direction of particles and sounds etc etc.