• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Xanather

Basic Game Loop

12 posts in this topic

Hello there, I quickly developed this solution to developing a fixed time step for a server. (client is XNA so time step is already taken care of there).


[source lang="csharp"]
Stopwatch stopwatch = new Stopwatch();
float timer = (1f / 60f) * 1000000;
while (true)
{
stopwatch.Reset();
stopwatch.Start();
//start update world
//end update world
Thread.Sleep(1);
while (stopwatch.ElapsedTicks < timer) { }
Console.WriteLine(stopwatch.ElapsedTicks);
stopwatch.Stop();
}[/source]

Its pretty basic, it sleeps for 1 millisecond to prevent 100% CPU usage (well really it sleeps for less than 15-16 milliseconds just because of the way Thread.Sleep works) then uses the stopwatch to see when its time to loop again. It does print out 16667 every cycle which is good, except for some times when it abnormaly printed out 32000+ (32 milliseconds). I am guessing this is due to the point of how Thread.Sleep works. The question is: is the code above good for a completely fixed time-step? should I also make use of winmm.dll (i think thats what it was called) for a more accurate fixed time step?

Also id love to not use Thread.Sleep() but I just cant find another way, the server is console based.

Replies are appriciated, Thanks! Edited by Xanather
0

Share this post


Link to post
Share on other sites
I'm assuming this is c#
This might help [url="http://msdn.microsoft.com/en-us/library/ff650674.aspx"]http://msdn.microsof...y/ff650674.aspx[/url]

EDIT:
I realized after some reading that the Stopwatch uses the high performance counter.

I haven't really programmed in c# but here is my attempt:

[source lang="csharp"]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace StopwatchApp
{
class TimeStep
{
public TimeStep(float Step)
{
Enable = true;

mStep = Step;

mCurrent = Stopwatch.GetTimestamp();
mLast = mCurrent;

mFrequency = Stopwatch.Frequency;
}

public void Reset() {mLast = Stopwatch.GetTimestamp();}

public bool WaitNextStep()
{
if(Enable)
{
mCurrent = Stopwatch.GetTimestamp();

long diff = mCurrent - mLast;
mDelta = (float)diff / (float)mFrequency;

float msDelta = 1000.0f * mDelta;
float msStep = 1000.0f * mStep;

if(msDelta < msStep)
{
int msSleep = (int)(msStep - msDelta);
if (msSleep == 0) msSleep = 1;
Thread.Sleep(msSleep);
}

mLast = mCurrent;
}
else return false;
return true;
}

public float GetDelta() {return mDelta;}

public bool Enable;

private long mFrequency;
private long mLast;
private long mCurrent;
private float mStep;
private float mDelta;
}

class Program
{
static void Main(string[] args)
{
TimeStep LoopStep = new TimeStep(1.0f/60.0f);

while (LoopStep.WaitNextStep())
{
float fDelta = LoopStep.GetDelta();

// Do stuff

Console.Clear();
Console.Write(fDelta);

if (Console.KeyAvailable)
{
LoopStep.Enable = false;
}
}
}
}
}[/source]

Never mind, this has the exact problem you are having. It does boil down to Thread.Sleep(msSleep). I think it's the nature of the OS returning control to your app. Edited by Neometron
0

Share this post


Link to post
Share on other sites
After playing with Thread.Sleep I learned this:

Thread.Sleep(1) = ~15ms
Thread.Sleep(15) = ~15ms
Thread.Sleep(16) = ~30ms

Windows probably allocates 15ms per thread and then switches to next thread.
0

Share this post


Link to post
Share on other sites
Grr, this is anoying. I thought creating a basic time-specified loop would be extremely easy, but instead it turns out windows does not like that... I will probably use this solution for the time being, the only problem is 10% of the CPU is being used all the time when using this method (and I have 8 cores), so really more than 50% of the core is being used. Thanks for the replies. Edited by Xanather
0

Share this post


Link to post
Share on other sites
Another method that doesn't require fiddling with the Windows API would be to use an event instead:

[source lang="csharp"]using System;
using System.Diagnostics;
using System.Threading;

static class P
{
static void Main()
{
var stopwatch = new Stopwatch();
var timer = (int)Math.Round((1f / 60f) * 1000f);
var wait = new ManualResetEvent(false);
while (true)
{
stopwatch.Reset();
stopwatch.Start();
//start update world
//end update world
wait.WaitOne((int)Math.Max(0, timer - stopwatch.ElapsedMilliseconds));
Console.WriteLine(stopwatch.ElapsedMilliseconds);
stopwatch.Stop();
}
}
}[/source]

This approach will work with a millisecond resolution only, but I seriously doubt that a higher resolution would be required anyway... especially given the fact that Windows is not a real-time OS and won't allocate thread execution time slots at a significantly higher resolution anyway :) Edited by darookie
1

Share this post


Link to post
Share on other sites
What about something like this (pseudocode, no idea how to use XNA):

[CODE]
// Init timekeeping variables

step = 0;
timeSinceLastUpdate = 0;

while(notDeadYet)
{
// total up the time pool, including leftovers from the last run through
step += timeSinceLastUpdate;
// Get the start of the update
start = currentTime();

// as long as there's enough time to step, step
while(step > timestepAmount)
{
stepGameState();

// Take a step out of the time pool
step -= timestepAmount;
}
render(); // Or not, it's whatever

// How long did that update take? If you're not rendering, you best hope it's less than timestepAmount
// or that variations are due to external processes or else your system is in the positive feedback loop
// of death and despair and youneedoptimisationness
timeSinceLastUpdate = currentTime() - start;
}
[/CODE]

Basically, instead of hoping your system runs once a frame, you see how long it was since it last ran, and run it as long as there are ticks to run; i.e. if your step is 15ms and the game loop takes 30ms due to the scheduler or renderer, the game ticks twice, and if the game loop takes 14ms, it doesn't tick at all because it's not ready yet. I used += for step to accumulate partial ticks so the loop won't have a problem with two 14ms updates in a row, and if you pass the partial amount to the renderer it can use that to smooth animations and other motion. You could also probably modify it to step one tick into the "future" and use the partial tick to interpolate between the states to display instead of extrapolate to a guess (though at 60FPS I don't know how visible this is).
1

Share this post


Link to post
Share on other sites
[quote name='darookie' timestamp='1343480755' post='4963936']
Another method that doesn't require fiddling with the Windows API would be to use an event instead:
[/quote]

Events with timeouts depend on the system clock too, so this will behave exactly the same as using Sleep.
0

Share this post


Link to post
Share on other sites
[quote name='Firestryke31' timestamp='1343515738' post='4964126']
What about something like this (pseudocode, no idea how to use XNA):
[/quote]

That would typically be my preferred method since you don't need to rely on or change the granularity of the system clock, but it will result in 100% CPU usage, which is precisely what he was trying to avoid by using Sleep. I'm not sure why that is a big deal in a game server unless he plans on running many instances of the game server application on the same machine at the same time.
0

Share this post


Link to post
Share on other sites
Throw in a Sleep() before/after render? Or if it's a server then instead of rendering. Edited by Firestryke31
1

Share this post


Link to post
Share on other sites
Darookie, never knew of that ManualResetEvent method (I need to dig into .net more lol), thanks I will try your method.

Firestryke, that seems like a alright idea (only because this is the server im talking about), even with using Thread.Sleep(x) I can make sure the world is updated 60 times a second with that code, once I finish developing the server I may attempt to use that idea and see how well it works aswell. Thanks :)
0

Share this post


Link to post
Share on other sites
Firestrykes approach is also described in the well known article
http://gafferongames.com/game-physics/fix-your-timestep/
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0