Can someone convert timing code for me?

BlitzMax Forums/BlitzMax Programming/Can someone convert timing code for me?

Chapman7(Posted 2016) [#1]
I've seen a timestep article posted a few times here and it seems like a good chunk of information but I can't seem to wrap my head around it entirely. Just wondering if someone could convert it to BlitzMax for me so hopefully I could understand it better.

http://gafferongames.com/game-physics/fix-your-timestep/

It's the code after "The final touch"

I'd really appreciate it!


Chapman7(Posted 2016) [#2]
Or maybe if someone could explain it better... I'm just having a hard time wrapping my head around it entirely


Derron(Posted 2016) [#3]
Forum search


@the final touch
The problem is:

- you split Update and Render
- you do "Update()" a bit off from the time you are at when calling "Render()"
- to accumulate this, you use the "remainder" to interpolate.

if the remainder is 30 of a interval of 60, this means you are at 30/60 = 0.5 (50%).
In your interpolation you then just "do" as if you were already 50% ahead of time.

Imagine you move by 10 pixels each time. When now drawing you draw displaced by 0.5 * 10 pixels (remainderFraction * velocity).

If your update-rate was "once every second", the remainder of 50% says: we are about 500ms since the last physical update and 500ms before the next one.

So you get a fraction to help you interpolating between two values.
If In "update 1" the value has to be 100, and in "update 2" it should be 150, you have a value of "100 + remainder * (150-100)" at a moment in between.


bye
Ron


RustyKristi(Posted 2016) [#4]
There's a lot of sample demos and games posted in the archives and forum. Just search for delta time and timestep.

Basically delta time means the render time between 2 frames. I thought these 2 excerpts can give you more info and understanding re: this topic:


Framerate independent vs dependent games

Framerate independent games are games that run at the same speed, no matter the framerate. For example, a game might run at 30 FPS (Frames Per Second) on a slow computer, and 60 FPS on a fast one. A framerate independent game progresses at the same speed on both computers (objects appear to move at the same speed). On the other hand, a framerate dependent game progresses at half the speed on the slow computer, in a sort of slow-motion effect. Making framerate independent games is important to make sure your game is enjoyable and playable for everyone, no matter what kind of computer they have. Games which slow down when the framerate dips can severely affect gameplay, making players get frustrated and quit!




Frame-Based vs. Time-Based Game Loop

Should the game loop be frame-based or time-based?

A single update to the gameplay elements is commonly called a tick or a step. Each time the game is rendered is a frame, and the time between two frames is known as the delta time. The basic approach when building a game is to design game objects to update in discrete steps — for example, the player game object may move 3 pixels along the x-axis each tick.

Simply updating as quickly as possible can cause problems. The delta time for each frame is not always consistent, so if game objects are configured to move in discrete, consistent steps, the game will appear choppy. There are three approaches to resolving this issue.

1. Use a variable delta time. Advance everything in partial steps based on delta time rather than in whole steps.
2. Set a fixed delta time. Limit rendering to a specific time interval so that game elements can still be stepped discretely.
3. Decouple frames and steps. Rather than update and render simultaneously, separate them so that physics can update based on a set time interval and rendering can happen as fast as the device allows.



Source:
https://www.scirra.com/tutorials/67/delta-time-and-framerate-independence
http://devblog.lukesterwebdesign.com/frame-based-vs-time-based-game-loop/


Chapman7(Posted 2016) [#5]
Thanks guys


Chapman7(Posted 2016) [#6]
Does this look right to you guys?

Global DeltaTime:Float = 0.01
Global Time:Float = 0.0
Global OldTime:Float = MilliSecs()
Global Accumulator:Float = 0.0
Global UPS:Int = 0
Global UPSTicks:Int = 0
Global Interpolation:Float = 0.0
Global StartTime: Float = MilliSecs() 'MIGHT NOT NEED THIS AFTER TEST



Function UpdateClient()
	PollSystem()
	
	'If AppTerminate() Then Print "Yes"

	If MilliSecs() - FPSTime > 1000 Then
		FPS = FPSFrames
		FPSFrames = 0
		FPSTime = MilliSecs()
		
		MemoryAllocated = GCMemAlloced()
		
		UPS = UPSTicks
		UPSTicks = 0
	Else
		FPSFrames = FPSFrames + 1
	EndIf
	
	Local NewTime:Float = MilliSecs()
	Local FrameTime:Float = (NewTime - OldTime) / 1000
	If FrameTime > 0.25 Then FrameTime = 0.25
	OldTime = NewTime
	
	Accumulator = Accumulator + FrameTime
	
	While (Accumulator >= DeltaTime)
		UPSTicks = UPSTicks + 1
		
		IntegrateGame(Time, DeltaTime)
		
		Time = Time + DeltaTime
		Accumulator = Accumulator - DeltaTime
	Wend
	
	Interpolation = Accumulator / DeltaTime
	
	RenderGame(Interpolation)
	
	If DisplayStatistics = True Then
		DrawText("FPS: " + FPS, 0, 0)
		DrawText("UPS: " + UPS, 0, 10)
		DrawText("Memory: " + MemoryAllocated, 0, 20)
		
		DrawText("Time: " + Time, 0, 40)
		DrawText("RealTime: " + (MilliSecs() - StartTime), 0, 50)
	EndIf
	
	Flip
	SetClsColor(0,0,0)
	Cls
EndFunction



After about 20 minutes of running it, the variable "Time" ends up being about 3-4 seconds off realtime. Is that normal?


Derron(Posted 2016) [#7]
Maybe floating point issues?


Also: "DeltaTime" is fixed - and you do this:

Loop {
DoSomething() 'might take "DeltaTime + 2 ms"
AddTime DeltaTime
}

Instead of doign "Time = Time + DeltaTime" you might also do "Time = Time + FrameTime" (right after "Wend").

In short: "Time" is not the time gone since the first call, it is the "sum of deltatime-steps" (it is the product of "deltatime * IntegrateGame-Call-Times").


bye
Ron


Chapman7(Posted 2016) [#8]
Got it, thanks Derron!


Chapman7(Posted 2016) [#9]
Okay two more questions:

1. Is there a cross-platform higher resolution timer than MilliSecs()?

2. In this example:

Loop {
DoSomething() 'might take "DeltaTime + 2 ms"
AddTime DeltaTime
}

Does that mean that "Time" could eventually become innacurate compared to other machines? If it takes DoSomething() longer on one machine than another, doesn't that make the simulations off? If Time is smaller on one machine and its Integrating using that and just a fixed Delta-Time, I feel like it wouldn't make the programs run the exact same


Derron(Posted 2016) [#10]
This is what
While (Accumulator >= DeltaTime)

is for.

It only does the inner thing if there is enough time for a planned update.


Bye
Ron