Frame rate independent game loop

Game development specific discussions.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Frame rate independent game loop

Post by paul doe »

Hi everybody

I coded a very simple demo to show how you can implement a frame rate independent game loop. You can download it from here:

https://github.com/glasyalabolas/fb-metaball-demo

Image

Controls:
Arrow keys: move the 'player' (it is just a crappy white ball)
+/- : add/remove metaballs
'p': pauses/unpauses the simulation (but not the rendering, that it's still performed)

The code is copiously commented, and shows a few interesting licks. Be warned, however, that the code is fully OO. Questions, comments and suggestions are greatly appreciated (such as how to upload files to GitHub XD)

Have fun!
Paul

PS: there's another, well-loved forum member that already posted something like this before. See if you can find who he is ;)

UPDATE: 10/31/2017 small code refactoring. Bug fix.
UPDATE: 10/29/2017 small bugfix.
UPDATE: 10/29/2017 added 'metaballsGL.bas', to test the new OpenGL patch to GFX lib by angros47 (need FreeBasic 1.06.0).
UPDATE: added two missing properties to the interface of ILoop. Grrr.
UPDATE: included 'interfaces.bi' which I seem to have dropped when I dragged the folder with ALL needed files to the GitHub file drop box ;)
Last edited by paul doe on Nov 01, 2017 1:33, edited 9 times in total.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Frame rate independent game loop

Post by dafhi »

missing: interfaces.bi
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

dafhi wrote:missing: interfaces.bi
Fixed now. Thanks for pointing it out, dafhi.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

To better be able to compare how two different implementations manage a render-intensive game loop, a fixed-framerate version, implemented using the regulate() function by dodicat, is in 'loop comparison.bas'. Press '1' to switch to the framerate-independent version, and '2' to switch to the fixed-framerate version. The class is a wrapper for the independent frame rate one, and is named, of course, DodiLoop XD

Another wrapper is shown in 'metaballsGL.bas' and uses the OpenGL patch implemented to the FBGFX by angros47. Use '1' to use the normal FBGX, '2' to use the OpenGL version.

Play around with them to see the similarities and differences. Refer to the articles that I mentioned on the first post to see the pros and cons of each one. Questions, comments, insults, are all welcome.

Have fun!
Paul

EDIT: removed the outdated source code. Simply download the code from the repository to have an up to date version.
Last edited by paul doe on Nov 01, 2017 1:38, edited 1 time in total.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Frame rate independent game loop

Post by dafhi »

dodiLoop.bi

Code: Select all

Not overriding any virtual method, found 'override' in 'declare property state() as IState ptr override
Element not defined, state in 'return( m_gameLoop->state
Element not defined, renderDevice in 'return( m_gameLoop->renderDevice
Expected expression, found '->' in 'dim as integer metaballCount = m_gameLoop->state->entityList->count - 1
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

dafhi wrote:dodiLoop.bi

Code: Select all

Not overriding any virtual method, found 'override' in 'declare property state() as IState ptr override
Element not defined, state in 'return( m_gameLoop->state
Element not defined, renderDevice in 'return( m_gameLoop->renderDevice
Expected expression, found '->' in 'dim as integer metaballCount = m_gameLoop->state->entityList->count - 1
It works for me. Did you updated the thing? See the first post, I corrected this bug (which wasn't a 'bug', just GitHub not accepting the commit <grrrrr>)
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Frame rate independent game loop

Post by dafhi »

works!
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

dafhi wrote:works!
Glad to hear that. I just finished uploading everything (again) to Sh*tHub, including the loop comparison. Geez, I don't know what the #%$@ is going on with that site today >:(
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Re: Frame rate independent game loop

Post by h4tt3n »

This is really nice work, points for sharing your code. I took a quick glance at your metaball drawing algorithm and got rid of the nasty doubly for-loop nested square root call in renderer.bi:

Code: Select all

sub FBRenderer.drawMetaballImage( byval context as IRenderContext ptr )
	/'
		Draws a 'metaball'
		
		This function draws an image to be used as a 'metaball' representation. It's declared directly
		in the interface to avoid having to implement low level primitives like pset(), so it's purely
		a convenience.
		
		The parameter it takes is a render context, and fills it with the appropriate image based on
		the size of said context
	'/
	
	' old version:
	'Dim as uint32 ptr mb = context->handle
	'dim as single maxDistance = context->width / 2
	'dim as vec2h centerPoint = vec2h( context->width \ 2, context->height \ 2 )
	'dim as single dist = any
	'
	'for y as uinteger = 0 to context->height - 1
	'	for x as uinteger = 0 to context->width - 1
	'		dist = max( 0, 1 - ( ( centerPoint - vec2h( x, y ) ).length / ( maxDistance ) ) )
	'					
	'		pset mb, ( x, y ), rgba( 255 * dist, 255 * dist, 255 * dist, 255 * dist )
	'	next
	'Next
	
	' new version:
	dim as uint32 ptr mb = context->handle
	dim as single invMaxDistance = 1.0 / ( context->width * context->width * 0.125 )
	dim as vec2h centerPoint = vec2h( context->width \ 2, context->height \ 2 )
	dim as single dist = any
	
	for y as uinteger = 0 to context->height - 1
		for x as uinteger = 0 to context->width - 1
			dist = max( 0, 1 - ( centerPoint - vec2h( x, y ) ).squaredlength * invMaxDistance )
						
			pset mb, ( x, y ), rgba( 255 * dist, 255 * dist, 255 * dist, 255 * dist )
			
		next
	Next
	
	
end sub
Cheers, Mike
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

h4tt3n wrote:This is really nice work, points for sharing your code. I took a quick glance at your metaball drawing algorithm and got rid of the nasty doubly for-loop nested square root call in renderer.bi:
Hi Mike,

Glad you like it. Nice optimization here, Mike. Extra points for actually using the vec2 utility functions ;) Do note, however, that this is only performed at metaball creation, not actual rendering. Very keen eye, indeed.

I will have to point out that the really interesting thing was in the actual game loop, not on the rendering code (which is left intentionally unoptimized, as well as the entire memory management), to better be able to 'feel the effects' of the game loop implementation, so to speak. Nonetheless, some boxes (like deltarho's one) just fly by this thing as if nothing happened LOL

Thanks for the interest, I was beginning to think that the GameDev forum was dead :'(

Paul
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Re: Frame rate independent game loop

Post by h4tt3n »

Hi there Paul,

Yeah, I just realized that the rendering was only used for setting up the demo, not in the main loop, so never mind. It's just an old habit of mine to optimize stuff :-)

I don't think the forum is dead at all, there's new exciting stuff to look into almost every day - like your nice engine right here. I'm wondering if you are having any plans to expand on this and build a game out of it? I'm asking because I've been brewing on a physics engine for some time and I'm starting to look for like-minded people who might want to team up for game development.

Cheers, Mike
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

h4tt3n wrote:Hi there Paul,

Yeah, I just realized that the rendering was only used for setting up the demo, not in the main loop, so never mind. It's just an old habit of mine to optimize stuff :-)
A good habit. No problem, it was just coded that way to be easy to tell what the code is doing. Looks like I've succeeded, no? ;)
h4tt3n wrote: I don't think the forum is dead at all, there's new exciting stuff to look into almost every day - like your nice engine right here. I'm wondering if you are having any plans to expand on this and build a game out of it? I'm asking because I've been brewing on a physics engine for some time and I'm starting to look for like-minded people who might want to team up for game development.
Yes, indeed. In fact, these are just snippets of code from a bigger framework (coded in another language), like dafhi wittingly guesses in this thread:
viewtopic.php?f=8&t=26000
That code was written from scratch (not all of them, however) for explanation purposes, and I designed it to be easy to follow for someone who doesn't quite dig OOP yet.
Teaming up for something? Count me in! What kind of stuff you're interested in? 2D? 3D? And what kind of game, concretely? I need some fun (I'm sick of financial coding stuff) so this could be very interesting.
I would love to see your physics stuff. If time permits, I'll show you a simple implementation of a barebones 2D physics engine that uses Verlet. It's simplistic, but you can do mighty interesting stuff with it. It can be useful for debugging purposes, much like the 3D stuff in the thread that I pointed you before. Looking forward!

Have fun!
Paul
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Frame rate independent game loop

Post by dafhi »

waa

Code: Select all

glRenderDevice.bi(30) error 222: Not overriding any virtual method, found 'override' in 'declare function setRes(..
glRenderDevice.bi(31) error 222: Not overriding any virtual method, found 'override' in 'declare sub setRenderer(..
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

dafhi wrote:waa

Code: Select all

glRenderDevice.bi(30) error 222: Not overriding any virtual method, found 'override' in 'declare function setRes(..
glRenderDevice.bi(31) error 222: Not overriding any virtual method, found 'override' in 'declare sub setRenderer(..
You have the latest version? You need fbc 1.06.0 also ;)
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Frame rate independent game loop

Post by paul doe »

Damnit, GitHub! The latest commit was NOT uploaded. Hang on, mate. I'm reuploading it now.
Post Reply