🔒 Locked
main game loop implementation?
Advertisement
Original Post
Good evening folks, I have a question today about how to implement the main loop for a game. It seems pretty clear that this should be separated from the rendering loop. Ideally, the game loop would cycled at regular timed intervals, and not be affected by how frequently frames were getting rendered at all. I remember seeing a post a while ago about multi-threaded games. This makes sense to me, as you could have your game thread execute, sleep for a while, and repeat while your graphics loop just gets frames in whenever it can. Is this standard practice? Is there a different way to get a regularly timed call to execute game logic that won't wait for the rendering proccess to return? If multi-threaded IS the way to go, are there some good C++ tutorials out there? What is a good amount of time to sleep between executions? Any other sage advice? Thanks very much for any help, Mike
My two cents: avoid multithreading as much as possible. Multi-threaded games are an order of magnitude harder to debug and two orders of magnitude harder to write properly without actually decreasing performance. The combination of the two means that you'll be spending a lot of time going "What the heck is wrong with it this time?"
Quote:
Original post by SiCrane
My two cents: avoid multithreading as much as possible. Multi-threaded games are an order of magnitude harder to debug and two orders of magnitude harder to write properly without actually decreasing performance. The combination of the two means that you'll be spending a lot of time going "What the heck is wrong with it this time?"
Couldn't have said it better myself. Multithreading might sound good, but the difficulties of its implementation make it a horrid mess. How ironic, since next-gen game processor designers are looking to exploit parallelism in games (ie, IBM and the Cell architecture). I was at ISPASS this year and Kunle Olukotun of Stanford gave a great little talk during the panel discussion about the future of multithreaded programming. He suggested that there should be "something better" than the current multithreaded programming model. In fact, here's a link to his presentation (only 6 slides, you can handle it): Presentation Slides.
Now if he doesn't convince you that multi-threading is the work of the digital devil, then you're hopeless. [wink]
Basically:
1. Input
2. AI
3. Physics
4. Play Sounds
5. Render
1. Input
2. AI
3. Physics
4. Play Sounds
5. Render
Quote:It’s not "the work of the digital devil" Its just not appropriate for every type of application. Can you imagine A GUI OS with out multithreading?
Original post by Roots
Now if he doesn't convince you that multi-threading is the work of the digital devil, then you're hopeless. [wink]
Hmm. So if multithreading is more hassle than it's worth, what do you use for a regularly-timed loop? I mean you need some sort of deal:
while game playing
{
gather input;
make state changes;
}
Then how does the rendering loop figure in to that? How do you prevent the rendering proccess from slowing down the input and game logic?
Mike
while game playing
{
gather input;
make state changes;
}
Then how does the rendering loop figure in to that? How do you prevent the rendering proccess from slowing down the input and game logic?
Mike
This quite recent thread addresses that question, albeit from a slightly different standpoint:
Game Timing
I only mention this because I made a fairly significant contribution, of course ;)
-Twilight Dragon
Game Timing
I only mention this because I made a fairly significant contribution, of course ;)
-Twilight Dragon
Canconical Game Loop.
It infact scales well to a MT implimentation as well, however as others have said MT is a right dog to program, even a simple proof-of-concept program I did a while back nearly caused my brain to explode [wink]
It infact scales well to a MT implimentation as well, however as others have said MT is a right dog to program, even a simple proof-of-concept program I did a while back nearly caused my brain to explode [wink]
its not so much the language that matters as keeping all the data straight when dealing with multiple execution paths, trying to debug things when different threads can change the data can be a right nitemare, making it work properly for a game loop just compounds the problem [smile]
Not saying its impossible, just not something most people want to try, certainly not until you've played with simple MTing and maybe not if you have to ask how a game loop should be structured, a bit of experiance with a simple single thread system will stand you in good stead.
Not saying its impossible, just not something most people want to try, certainly not until you've played with simple MTing and maybe not if you have to ask how a game loop should be structured, a bit of experiance with a simple single thread system will stand you in good stead.
Here's what I do (C++ Pseudocode). It's very simple and doesn't have much frame control but it will have a constant rate of presentation:
(Note, this is contained in the main window function)
There are more complex ways of controlling frame rate but this simple way will suffice for a beginner. I'm sure you'll find plenty of articles/threads on advanced frame rate control. (Look up 64 Bit High Precision Timers)
(Note, this is contained in the main window function)
int nTimer = 0, nPrevTimer = 0;int nDelay = 12; // Arbitrary delay counterwhile( 1 ){nTimer = GetTickCount();if( nTimer - nPrevTimer > nDelay ){nPrevTimer = nTimer;// Get input// Do AI// Do physics// Do misc game processing}// Render}This way you render each frame but the rest of the processing will follow a constant frame-rate.// Call break to exitThere are more complex ways of controlling frame rate but this simple way will suffice for a beginner. I'm sure you'll find plenty of articles/threads on advanced frame rate control. (Look up 64 Bit High Precision Timers)
as for multithreading you could still move the network code into a seperate thread without affecting the rest of the game
why wouldn t you use dual cores?
in order to reduce latency i would do all the packing unpacking and decompression
in a seperate thread
mainloop
{
//network input
read latest decompressed and unpacked messages read from the network
//end network input
rest
as already suggested above
}
networkthread
{
read network packages
check compression and packing
decompress
debitpack
mutexlock;
add decompressed packet to message queue
mutexunlock
}
not sure if you can lock the mainloop of your process but you can move this into another thread just for handling the mainloop and let the process wait until the threads terminate
the read i would move it to a seperate thread is to avoid lag spikes that will occure if you receive an insane amount of e.g. huffman compressed bitpacked data
its a lot of work to decompress a 1 kb large packet at runtime and this probably for several clients
this is just my suggestion but i would rather keep all the compression and decompression work out of the mainloop instead of risking lag spikes
which is more annoying than 20 fps less performance especially when playing on a low bandwidth connection that already suffers high latencies due to bandwidth limitation
[Edited by - Basiror on August 24, 2005 9:28:29 AM]
why wouldn t you use dual cores?
in order to reduce latency i would do all the packing unpacking and decompression
in a seperate thread
mainloop
{
//network input
read latest decompressed and unpacked messages read from the network
//end network input
rest
as already suggested above
}
networkthread
{
read network packages
check compression and packing
decompress
debitpack
mutexlock;
add decompressed packet to message queue
mutexunlock
}
not sure if you can lock the mainloop of your process but you can move this into another thread just for handling the mainloop and let the process wait until the threads terminate
the read i would move it to a seperate thread is to avoid lag spikes that will occure if you receive an insane amount of e.g. huffman compressed bitpacked data
its a lot of work to decompress a 1 kb large packet at runtime and this probably for several clients
this is just my suggestion but i would rather keep all the compression and decompression work out of the mainloop instead of risking lag spikes
which is more annoying than 20 fps less performance especially when playing on a low bandwidth connection that already suffers high latencies due to bandwidth limitation
[Edited by - Basiror on August 24, 2005 9:28:29 AM]
In c++ish psuedo code
This gives you a near constant update rate, but it is only a start and needs a lot of work before you use it.
main_loop(){ render(); int updates; if(updates = (current_time()-last_update)/updates_per_sec) { for(;updates!=0;--updates) { update(); } last_update = current_time(); } swap_buffers();}This gives you a near constant update rate, but it is only a start and needs a lot of work before you use it.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement