Codeloop sync in C# .Net

Started by
5 comments, last by theLoneCoder 14 years, 2 months ago
This is probably a pretty common question, but despite my searching I haven't managed to find a definitive answer. I am writing a game in .Net and I wish to synchronise the game code and rendering. I want the game logic to execute at a constant 60 times/second, and I want to redraw the scene as often as possible but no faster than the monitor refresh rate. I came across the issue that I am not able to make any thread sleep for a specific period of time only: you can make a thread sleep for at least the specified period of time, but the thread is not guaranteed to resume immediately after that amount of time has finished due to the way processes are scheduled. The only accurate solution I found so far is to spin on a while loop until the required time has been attained. To me this doesn't sit right; consuming the cpu doing nothing. Is this a common approach in games? I used to use a game authoring tool to write 2d games and these games don't seem to consume the cpu in this manner, and for the most part are using the cpu so little it appears as 0%. The game loop is executed a fixed number of times per second and is accurate. How can I achieve this exactly?
Advertisement
Perhaps slightly off topic, but have you looked into XNA? They handle the general update/render loops for you, and give you the option of running at a fixed framerate or not.

What you want to be using for your timing is a high performance timer. Something like this.

Here's the thing though - if you are only running your updates a 60 times a second, but your rendering code is running faster - say 70 times a second, won't 10 of those frames be identical to what is already being rendered? I can understand wanting to run a physics engine at a fixed interval (say 50 Hz), but other than that it is just better to use time-adjusted movements (ie: adjusting logic based on how much time has passed from the previous frame, not on a fixed step).
you are right - spinning in a loop is a bad, bad idea. You definitely don't want to be doing that. In general, if you do decide to go for a fixed interval update, you want to do something like this in a loop:
Render the current state of thingsIs it time to do an update yet (ie: has 1/60th of a second passed since the last update?)  - Yes?  Do an update based on how much time has passed since the previous update  - No? Try waiting a little bit. 

This way it'll render for every iteration, but will only perform updates every 1/60th of a second (or longer, if your framerate drops below 60 fps).

I'd try playing around with it a little bit. It's been a while since I have messed around with this sort of stuff, so don't take my word for anything.
This article talks about this topic in great detail.

Also, when doing high performance timing in C#, use the System.Diagnostics.Stopwatch class to access the QPC.
Mike Popoloski | Journal | SlimDX
Quote:Original post by Mike.Popoloski
Also, when doing high performance timing in C#, use the System.Diagnostics.Stopwatch class to access the QPC.

Ah, I knew there was a .Net equivalent. I just couldn't remember what it was called.
Quote:Original post by Moe
Perhaps slightly off topic, but have you looked into XNA? They handle the general update/render loops for you, and give you the option of running at a fixed framerate or not.

What you want to be using for your timing is a high performance timer. Something like this.

Here's the thing though - if you are only running your updates a 60 times a second, but your rendering code is running faster - say 70 times a second, won't 10 of those frames be identical to what is already being rendered? I can understand wanting to run a physics engine at a fixed interval (say 50 Hz), but other than that it is just better to use time-adjusted movements (ie: adjusting logic based on how much time has passed from the previous frame, not on a fixed step).


I see what you are saying about having 10 identical frames. I just figured that you can't really have 50fps with a monitor that refreshes at 60hz. So drawing at 60fps is just a way to sync with a monitor at 60hz, it's not aimed at providing smoother animation, simply monitor-synchonized animation without tearing. Maybe my understanding of that is completely wrong...

I have thought about XNA but I am not particularly interested. Using a framework takes all the fun out of learning for me. I am aiming to learn some more OpenGL while I am at it, and want to handle all of this myself (which is how I end up with questions like this).

I can see how using a time difference in the code loop for timing is beneficial, and for a technically minded person this seems fairly reasonable, but I would like to incorporate my work into something that can be used by those who are less technically able, don't have the interest in the technical aspects of game making or are just starting out. For this reason I think it's much simpler to understand that "my code runs 60 times every second". If I want to increment a counter by 60 every second I can just add 1 to it on every code loop, easy. Using the latter approach, what do I add to my counter exactly? Of course I can work that out but it's not immediately obvious. I guess some form of timer would make this a lot easier, but it's hard to convey the fact that the resolution of the timer is not down to the millisecond, it is limited by the duration of the codeloop itself. So at least in my perspective, a fixed codeloop frequency is more intuitive and gives rise to more predictable timings. I do welcome a better alternative if one can be suggested.

I attempted a sort of mixture between the empty loop and sleep attempts. This still seems to give quite large variations in the frame rate but it's better than just sleeping. The basic idea is to only give up the cpu when we are reasonably certain that we can get it back in time, and then hang for a little bit for the sake of precision.

Any alternative suggestions appreciated...

Quote:Original post by Mike.Popoloski
This article talks about this topic in great detail.


I shall make sure to read this.
Something that you might want to keep in mind is that if you base the movement of objects on the amount of time passed since the last frame, that it will cause gigantic jumps if you set a break point then step through.
When debugging it is much better to have a set time increment.

This topic is closed to new replies.

Advertisement