Posted: 22nd May 2023 18:40
Hello everyone, does anyone have an algorithm to synchronize the animation according to the delta so that it is more fluid?

I'm creating a LAN multiplayer game, and I noticed that if I create an application out of fullscreen, and for some eventuality, I click on the border of the window, the application freezes, and regardless of the time it remains frozen, the animation of the 3d object, no synchronizes with the " freeze ", and if the 2 computers are side by side, the animations are not running in the synchronized frame ... can someone help me?
Posted: 22nd May 2023 19:09
not used myself but have you tried accounting for the difference with SetObjectAnimationFrame() ?
Posted: 22nd May 2023 19:16
I've tried, but I still have no idea of the necessary mathematical logic ...

I made this algorithm below to know the % of the delta differential, but i don't know how to apply it....
+ Code Snippet
if (Delta > 0.02) then

deltaTimeBefore = 0.016
deltaTimeAfter = Delta

percentVariation = ((deltaTimeAfter - deltaTimeBefore) / deltaTimeBefore) * 100


PrintC("percent_variation = "..StrF(percentVariation ))
end
Posted: 22nd May 2023 20:20
Update( FrameTime )

This will update Animations, Physics, Tween, based upon the input time... if we use 0 then AppGameKit uses the Time between the current and last Sync (i.e. GetFrameTime( )) although keep in mind this function is inaccurate.
If we manually call this, it WILL override it's call within Sync( ) although it is better to use Render( ) : Swap( ).

Now in order to get both Client and Server to be running the same time., we can use GetSecondsFromUnix( )
Keep in mind this value is going to be universal...

+ Code Snippet
Type Time
	Previous As Float
	Current As Float
	Duration As Float
	Elapsed As Float
	Frequency As Float
EndType

Function Time( Frequency As Float )
	Local Out As Time
	Out.Frequency = Frequency / 1000.0
	Out.Current = Timer()
EndFunction Out

Function SyncTime( This Ref As Time )
	This.Previous = This.Current
	This.Current = Timer()
	This.Duration = This.Current - This.Previous
	Inc This.Elapsed, This.Duration
	
	If This.Elapsed >= This.Frequency
		Dec This.Elapsed, This.Frequency
		ExitFunction -1
	EndIf
EndFunction 0


This is a Timer Type and Function... pretty simple to figure out how to use it.
By Default, this is NOT going to be Synchronised between Applications, but we can change that using Unix Time.

+ Code Snippet
Print( "Calibrating... Please Wait" )
Sync()
Repeat
	ResetTimer()
Until GetSecondsFromUnix( GetUnixTime() ) = 0
Print( "Calibration Complete" )
Sync()


Alright, so now any Timers we create are Synchronised with the Unix Time WHEN you created them.
Now remember both Unix Time and Timer( ) should be Synchronised., meaning we can now send the Trunc( TimeName.Duration ) (Integer... Milliseconds) and Unix Seconds (Integer) together.
We then compare it on the Client Side when we receive the Message.

Latency# = Abs( ( ClientSecond + (ClientMillisecond * 0.001) ) - ( HostSecond + (HostMillisecond * 0.001) ) )

This will give us the Latency (in Seconds) ... now as a note if we want this in Milliseconds we just * 1000.0
Remember that Latency# is going to be an Offset., so we want to then add that to our Update( MainLoop.Duration + Latency# ) and this will ensure that ALL Clients are Synchronised with the Host Application.

It might also be a good idea to store Latency over 1s Periods., as this IS going to be useful for Network Prediction purposes.
But I wont delve into that here.
Hopefully this is helpful.
Posted: 22nd May 2023 21:32
looks solid, Raven. i hadn't thought of a use for unixtime until i saw this