Sign in to follow this  

2D Engine Main Loop - Need advice

This topic is 2040 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi.
I am developing a simple Bomberman clone using SDL and C++. Collision detection, movement, animation have all been implemented. The problem is that the character often seems to skip across the screen. I have researched this and found this to be temporal anti aliasing due to the frame rendering between updates.

I have found two main solutions and wanted input. This engine code should be as smooth as possible and I want to reuse it so I will put in the effort now to understand it. I have found an article on fixed timestep. I really wish I could implement it but I am very confused about how it applies to a non physics application or maybe just to something simpler like moving a character across the screen.

This is the article I am referring to: [url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]

Is this method a little overboard for a non physics intense game?

Can anyone elaborate on what it does and how I would apply it to simple position updates on an x/y plane.

There is also another article I found which covers quite a few different main game loops: [url="http://www.koonsolo.com/news/dewitters-gameloop/"]http://www.koonsolo....tters-gameloop/[/url]

I tried to implement the last option but found that often I got some unexpected warping where it would interpolate that I would be somewhere and then change its mind. It's possible it was a bug on my part (e.g. not factoring it into collision correctly).

Does anyone have a solid 2d main game loop they can break down and explain. I mean, I understand how it works, the components relating to handling input, updating logic and rendering, I am just confused sometimes about how the time is applied to those updates.

Thank you for your time.

Here is my main loop as it stands:


[CODE]
int main(int argc, char *argv[])
{
const int TICKS_PER_SECOND = 60;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;

double next_game_tick = timer.getTime();

int loops;

// Initialize everything
if(!init())
{
errorLog.writeError("Failed to initialize engine components!");
return 1;
}

// While the user hasn't quit
while(quit == false)
{
loops = 0;
while( timer.getTime() > next_game_tick && loops < MAX_FRAMESKIP)
{
update();

next_game_tick += SKIP_TICKS;
loops++;
}
}

render.cleanup();

return 0;
}[/CODE]

Chanz Edited by Chanz

Share this post


Link to post
Share on other sites
The idea of a fixed timestep loop is that you de-couple rendering the scene from doing logic update. In your code, I don't see an explicit [b]render()[/b] call of any sort, so I assume you are rendering inside [b]update()[/b], which isn't optimal.

Here is the basic loop that I use for just about every project I do, stripped of fluff:

[code]

function CoreKernel:run(app, startingstate)
self.statecontext=startingstate
self.running=true
self.oldtime=app:getTime()/1000
self.logicupdatecounter=0
self.logicstep=1.0/self.statecontext.updaterate
event=SEvent()

local thistime=0
local timesincelastshow=0
local framecount=0
local totaltime=0


while(true) do
-- Process input
while (app:getEvent(event)) do
self:handleEvent(event) end
if self.running==false then return end
end

self.curtime=app:getTime()/1000
self.framedelta=(self.curtime-self.oldtime)
totaltime=totaltime+self.framedelta
thistime=thistime+self.framedelta

self.logicupdatecounter = self.logicupdatecounter+self.framedelta
while(self.logicupdatecounter >= self.logicstep) do
-- Update logic
self:updateLogic()
self.logicupdatecounter = self.logicupdatecounter - self.logicstep
end

-- Render
self.percentwithintick = self.logicupdatecounter / self.logicstep
self:addFrameTime(self.framedelta, self.percentwithintick)
app:beginScene()
self:render()
app:set2DMode()
self:renderUI()
app:endScene()
self.oldtime=self.curtime
framecount=framecount+1
end
end

[/code]

The above loop has all the applicable parts. First, it empties the input event queue and handles all events. Then it accumulates time and executes logic updates if it is time to do so. Then it renders the scene. Two time values are used in rendering, applied in the [b]addFrameTime[/b] call: elapsed (self.framedelta) is the value of how much time has elapsed since we started the loop, and is used to advance timers. percentwithintick is used to interpolate objects' Last and Current position and update scene node objects accordingly for smooth rendering.

Share this post


Link to post
Share on other sites
Thank you. I guess what I am confused about is the whole interpolation and the function addFrameTime. What exactly does it do. I understand that the logic updates until it is larger than the logic step and then when rendering the position values are interpolated.

Are these values actually modified? Or are they just interpolated for the rendering (i.e. does the rendering actually modify the values or does it just modify them temporarily for the rendering and then they are permanently changed when the next update() function is run).

What exactly does addFrameTime do? And do you pass this value to your rendering call? Is it possible that it can interpolate a value past collision and have something interpolated into a wall for instance?

Thank you.

Share this post


Link to post
Share on other sites
You're welcome to take a look at my Old Blog (linked in my sig) as it has the steps and the code to one of my games. I do, however, use a 2d physics engine, and I would HIGHLY encourage you to look into using one yourself at some point as it makes writing 2d games EXTREMELY easy.

Share this post


Link to post
Share on other sites
Every object stores its Last position and its current position. In [b]addFrameTime[/b], these values are interpolated and the result is used to set the position of the object's scene node. In [b]UpdateLogic[/b], the Last position is set to Current, and a new Current position is generated based on movement if any movement occurred. For purposes of logic, the object's position is considered to be Current; Last is only stored for the purpose of interpolating to smooth out movement.

Share this post


Link to post
Share on other sites
[quote name='JTippetts' timestamp='1336434151' post='4938217']
Every object stores its Last position and its current position. In [b]addFrameTime[/b], these values are interpolated and the result is used to set the position of the object's scene node. In [b]UpdateLogic[/b], the Last position is set to Current, and a new Current position is generated based on movement if any movement occurred. For purposes of logic, the object's position is considered to be Current; Last is only stored for the purpose of interpolating to smooth out movement.
[/quote]

Brilliant! Thank you.

And yes BeerNuts, I will have a look at the source thank you.

Share this post


Link to post
Share on other sites
Here's my gameloop, as simple as can be.

However, before the loop, I make a call to [size=3]App.SetFramerateLimit(60); This limits the framerate to 60 fps, which is crucial for the physics simulation. It makes things easier. Also, cpSpaceStep() is the physics engine simulaiton step, and I tell it 1/60 seconds has passed since the last step, so it will move the objects accordingly in my world.[/size]

[code]
1 // main game loop
2 while (App.IsOpened())
3 {
4 pOurPlayer->CheckInput();
5
6 cpSpaceStep(pMap->GetSpace(), 1.0f/60.0f);
7
8 /* clear screen and draw map */
9 App.Clear(sf::Color(200, 200, 200, 255));
10
11 pMap->Draw(pOurPlayer->GetBody());
12
13 // Update all the bullets in the world
14 GameData.UpdateBullets(pOurPlayer->GetBody());
15
16 // check for items as well
17 GameData.UpdateItems(pOurPlayer->GetBody());
18
19 // Finaly update all enemies
20 GameData.UpdateEnemies(pOurPlayer->GetBody());
21
22 pOurPlayer->Draw();
23
24 App.Display();
25
26 if (CheckGameEnd(&App))
27 {
28 App.Close();
29 break;
30 }
31 }
[/code] Edited by BeerNutts

Share this post


Link to post
Share on other sites
Beernuts, so the physics engine has the timestep built in and controls the aspect of updating the players? I am writing a simple Bomberman clone. Would using a robust physics engine be overkill? Even if so, I will use this method if I have something a bit more complicated.

Thank you!

Share this post


Link to post
Share on other sites
[quote name='Chanz' timestamp='1336514012' post='4938495']
Beernuts, so the physics engine has the timestep built in and controls the aspect of updating the players? I am writing a simple Bomberman clone. Would using a robust physics engine be overkill? Even if so, I will use this method if I have something a bit more complicated.

Thank you!
[/quote]

Yes, basically, you give every physical object in your game some values to define what it's doing. Walls are static objects with infinity mass, and never move. You give the player and enemy some force or velocity, and just step the physics engine. When collisions happen, the engine handles the object responses (and, hitting an immoveable wall, and giving the player 0 elasticity, the player would just stop), but you can register for callbacks for collisions between certain objects.

Well, if you are making a true bomberman clone, then, for your first foray into physics engine, maybe you shouldn't use it. I would probably still use a physics engine since I'm quite familiar with everything, but, yes, in general, it would probably be overkill.

Let me just say that for anything more complex than bomberman, physics engines make everything so much easier. I made a side-scrolling space shoot-em up years ago and didn't use a physics engine. If I had, the game would've been so much easier, and I could've made cooler objects and maps with the extra time.

Share this post


Link to post
Share on other sites
I have made some progress but am still confused a bit:

First of all, I keep track of locations in integers. I do this because I didn't assume you could be between pixels but now I realize when I am using doubles that effect the x and y values, I might have to make the switch. Edit: I definitely have to make the switch. It seems as if it was dropping the precision on the speed. 0.9 became 0 and 1 was way too fast.

Here is my revised main loop:


[CODE]
int main(int argc, char *argv[])
{
// Initialize everything
if(!init())
{
errorLog.writeError("Failed to initialize engine components!");
return 1;
}

// Time variables
double t = 0.0;
const double dt = 0.01;
double currentTime = SDL_GetTicks();
double accumulator = 0.0;

// Run until the user has requested a quit
while ( !quit )
{
double newTime = SDL_GetTicks();
double frameTime = newTime - currentTime;

if ( frameTime > 0.25 )
frameTime = 0.25;
currentTime = newTime;

accumulator += frameTime;

// Loop until we are ready to render, updating as we go
while ( accumulator >= dt )
{
update( dt );
t += dt;
accumulator -= dt;
}

// Get the time we use for interpolation
const double alpha = accumulator / dt;

// Interpolate the values
player.interpolate(alpha);

// Render the scene
renderScene();

}
return 0;
}[/CODE]

When I interpolate the values, I do so like this:


[CODE]
void Player::interpolate(double alpha)
{
renderXPos = curXPos * alpha + lastXPos * (1.0 - alpha);
renderYPos = curYPos * alpha + lastYPos * (1.0 - alpha);
}[/CODE]

My question is how delta time and time play a role in updating the physics. I have my speed as an integer at 3. It moves about how fast I want it. In the main player update function:


[CODE]
void Player::update(double dt)
{
float pSpeed = speed * dt;

...
collision handling, etc..
position updating...
}[/CODE]

Am I using delta time correctly? Should I be applying it to speed or did I miss the point. Thanks to everyone who has helped me understand this so far.

Edit: Apologies for the formatting. Not sure why it undoes the formatting I have in my IDE. Edited by Chanz

Share this post


Link to post
Share on other sites
Fixed everything with floats. Movement still feels a little bit off. Not sure why...

Anyone willing to test and let me know what you feel.

Feels a lot smoother now compared to what it used to be but a weird issue seems to involve the character moving faster in the open part of the level. It check collision less there when aligned with the grid but I thought the whole purpose of this kind of loop was to remove temporal antialiasing (which is has) and make it steady rendering throughout. How would I modify my main loop to work at a fixed frame rate? Edited by Chanz

Share this post


Link to post
Share on other sites
EDIT: Wait, I see a major problem. SDL_GetTicks returns the time in Milliseconds. You are assigning it to a newTime, and subtracting. The times are going to be large numbers, not fractions. If you want to use SDL_GetTicks(), I'd suggest doing this:
[code]
double currentTime = (double)SDL_GetTicks()/1000; // converts to time in seconds, so 8 milliseconds is .008 seconds
[/code]

Same with other places you use SDL_GetTicks in your code.

[quote name='Chanz' timestamp='1336609193' post='4938825']
[CODE]

// Time variables
double t = 0.0;
const double dt = 0.01;
double currentTime = SDL_GetTicks();
double accumulator = 0.0;

// Run until the user has requested a quit
while ( !quit )
{
double newTime = SDL_GetTicks();
double frameTime = newTime - currentTime;

if ( frameTime > 0.25 )
frameTime = 0.25;
currentTime = newTime;

accumulator += frameTime;

// Loop until we are ready to render, updating as we go
while ( accumulator >= dt )
{
update( dt );
t += dt;
accumulator -= dt;
}

// Get the time we use for interpolation
const double alpha = accumulator / dt;

// Interpolate the values
player.interpolate(alpha);

// Render the scene
renderScene();

}
return 0;
}[/CODE]
[/quote]

I'm confused just trying to understand what your loop is doing. It doesn't make sense to me. What are you trying to accomplish? Explain each step, and what you think it's supposed to be doing. I don't think it's doing what you hope.

I would take a different approach. In my original game, I had frame-rate independent movement, but I updated the screen as often as possible.

The basic premise was this (using your SDL as an example):
[code]
// subtract .01 seconds so 1st loop has some elapsed time
double lastTime = (double)SDL_GetTicks()/1000 - 0.01;
double currentTime;
double elapsedTime;

while(!bQuit) {
currentTime = (double)SDL_GetTicks()/1000;
elapsedTime = currentTime - lastTime;
lastTime = currentTime;

Player.HandleInput();
Environment.Update(elapsedTime);
Items.Update(elapsedTime);
Enemies.Update(elapsedTime);
Player.Update(elapsedTime);
Render();
}

// My player Update would be this
void Player::Update(double elapsedTime)
{
// XLocation, YLocation, XVel, and YVel are all doubles
// XVel and YVel are in pixels/second
XLocation = XLocation + XVel* elapsedTime;
YLocation = YLocation + YVel * elapsedTime;

}
[/code]
The elapsed time is the time it takes to handle the player's input, update everything in the game, and render. Everything will move the correct distance regardless how long the frames are.

I would suggest you look at using this to begin with. You can then extend it as you see fit, but get this working, then try others if you want.

Since you aren't using a physics engine, this is fine. Once you move to using physics engine for simulations, you should fix your timesteps.

Render just renders at the objects' XLocation and YLocation.

Just my suggestion, but, whatever you do, good luck. Edited by BeerNutts

Share this post


Link to post
Share on other sites
He is using fixed time steps (just look at JTippets post), which is a common way to avoid all the potential issues of just scaling everything by frame time.

Why? Think of throwing a rock and just updating velocity and position each frame. It would follow two very different paths on different machines. In a game it can make the different between throwing a grenade into a window or hitting the wall. Even the old X-Wing games had problems that led to fixed time steps. What happened? Because of issues like that, the "replay" of a mission would sometimes be completely different from what actually happened. Inconsistent time steps caused a missile to miss and suddenly there was a ship that should have been gone.

In short: update your physics in fixed steps and don't allow an arbitrarily large or tiny delta time. Unless you don't care about results being somewhat deterministic (which is often the case if your game is offline, non-competitive and has no replay function).

Of course it might seem like overkill for bomberman, considering there should be only simple and linear movement involved. Yet, it's probably better to get used to it on simple projects. Decouple physics and rendering. Generally there is absolutely no reason to run physics updates at maximum rate (ie. every single frame).

Share this post


Link to post
Share on other sites
[quote name='Trienco' timestamp='1336710442' post='4939200']
He is using fixed time steps (just look at JTippets post), which is a common way to avoid all the potential issues of just scaling everything by frame time.

Why? Think of throwing a rock and just updating velocity and position each frame. It would follow two very different paths on different machines. In a game it can make the different between throwing a grenade into a window or hitting the wall. Even the old X-Wing games had problems that led to fixed time steps. What happened? Because of issues like that, the "replay" of a mission would sometimes be completely different from what actually happened. Inconsistent time steps caused a missile to miss and suddenly there was a ship that should have been gone.

In short: update your physics in fixed steps and don't allow an arbitrarily large or tiny delta time. Unless you don't care about results being somewhat deterministic (which is often the case if your game is offline, non-competitive and has no replay function).

Of course it might seem like overkill for bomberman, considering there should be only simple and linear movement involved. Yet, it's probably better to get used to it on simple projects. Decouple physics and rendering. Generally there is absolutely no reason to run physics updates at maximum rate (ie. every single frame).
[/quote]

Trienco, did you look at his code? He may THINK he's doing fixed timesteps, but he's implemented it incorrectly. And, he's not using any physics in his game, so it's not a requirement. I fully understand having a constant delta for running physics simulations is the best possible solution, but that's not the case here.

I typically have the philosophy of KISS for beginners. Once they are more comfortable making games, they can move to more complex solutions.

Share this post


Link to post
Share on other sites
[quote name='BeerNutts' timestamp='1336743970' post='4939294']
Trienco, did you look at his code? He may THINK he's doing fixed timesteps, but he's implemented it incorrectly.[/quote]

Then I'm not seeing it. The only problem I see is with ignoring that SDL_GetTicks returns milliseconds as uint32 and not seconds as double.

Apart from that, what am I missing? He calculates the frame time, caps it just in case, adds it to last iterations remainder, does his updates as many times as fit in and then draws his scene.

Share this post


Link to post
Share on other sites
Everything you need to make a proper fixed-step implementation can be found here: [url="http://lspiroengine.com/?p=378"]Fixed-Time-Step Implementation[/url]

Particularly you need to pat attention to the [b]Implement with Care[/b] section.
#1: Never store raw time in floats or doubles. Only deltas (time since the last update).
#2: Don’t cap the frame rate.
#3: Fix your interpolation. You use “const double alpha = accumulator / dt;” If you were using floats, it should be, “const double alpha = accumulator;”.



L. Spiro

Share this post


Link to post
Share on other sites
[quote name='L. Spiro' timestamp='1336832808' post='4939569']
#3: Fix your interpolation. You use “const double alpha = accumulator / dt;” If you were using floats, it should be, “const double alpha = accumulator;”.
[/quote]

It's not that his version is wrong. He is passing a relative percentage of one time step. The real problem I'm seeing is that the called function can only make sense of this value if it is aware of how long a time step is.

Point is: you can't say his alpha is wrong without knowing what his interpolate function is doing (at least "mathematically" a value between 0-1 actually does make more sense than an absolute time value).

I'm not sure where you see him capping the frame rate. He is capping the number of updates per frame, which makes sense. If your game really stalls for such a long time, you don't want it to make a huge jump forward, taking an endless amount of time for the physics update and stuttering along for several frames until it finally caught up. The idea is that the game experience is ruined anyway, if a frame suddenly takes that long. Freezing and then continuing as normal is a much lesser evil than turning the game into a slide show and crashing the player into whatever he was headed for.

Besides: look at JTippets code. I don't think it's helping much if he does an implementation based on something a moderator posts and then having other people say "no, that's wrong" without going into any detail. That's just going to be confusing.

Share this post


Link to post
Share on other sites
[quote name='Trienco' timestamp='1336889040' post='4939718']
It's not that his version is wrong. He is passing a relative percentage of one time step. The real problem I'm seeing is that the called function can only make sense of this value if it is aware of how long a time step is.

Point is: you can't say his alpha is wrong without knowing what his interpolate function is doing (at least "mathematically" a value between 0-1 actually does make more sense than an absolute time value).
[/quote]
You are correct.


[quote name='Trienco' timestamp='1336889040' post='4939718']
I'm not sure where you see him capping the frame rate. He is capping the number of updates per frame,
[/quote]
You are correct.


[quote name='Trienco' timestamp='1336889040' post='4939718']
which makes sense. If your game really stalls for such a long time, you don't want it to make a huge jump forward, taking an endless amount of time for the physics update and stuttering along for several frames until it finally caught up. The idea is that the game experience is ruined anyway, if a frame suddenly takes that long. Freezing and then continuing as normal is a much lesser evil than turning the game into a slide show and crashing the player into whatever he was headed for.
[/quote]
It doesn’t make sense, or it is somewhat subjective. I certainly would never take that route.
It causes the game to go into slow-motion which in itself causes problems, particularly for network games. The simulation is still stable, but you are still going to crash into that wall. Your game can’t lag behind the server and expect your input to remain real-time. You will still be trying to steer clear of the wall, mashing buttons or pulling back on the stick, even though you have really already crashed, and are just waiting longer to realize it. Stretching out one’s doom and giving him or her false hope of survival would be considered more of an annoying side-effect of game lag.

Offline games don’t need to be so strict on this, but most serious games are built around a fully real-time simulation partly because it just makes sense, but also because it leaves them open to the addition of network play later. Even if they never plan to go online with one game, it only makes sense to build an engine around the idea that it may one day be used to make an online game.


[quote name='Trienco' timestamp='1336889040' post='4939718']
Besides: look at JTippets code. I don't think it's helping much if he does an implementation based on something a moderator posts and then having other people say "no, that's wrong" without going into any detail. That's just going to be confusing.
[/quote]
One of the problems with his reproduction of JTippetts’s code is his use of doubles for storing absolute time.
I write articles covering these kinds of things so I don’t have to repeat them every time. And, frankly, that is something I would encourage him to research on his own anyway instead of just feeding it to him; that tidbit can be found anywhere online, and he should be doing the simple research on his own.


L. Spiro

Share this post


Link to post
Share on other sites
[quote name='L. Spiro' timestamp='1336902443' post='4939736']
It doesn’t make sense, or it is somewhat subjective. I certainly would never take that route.

It causes the game to go into slow-motion which in itself causes problems, particularly for network games.
[/quote]

Actually, it will cause only a single hick up. Look at his cap. If your frames seriously take more than 250ms, the game is absolutely unplayable. Slow motion would require that this happens frequenty in which case no method is ever going to fix anything.

Yes, if there is multiplayer involved then pretending that less time has passed on the client would be a problem. I'd expect the server to override the client state, unless the client is trusted enough to just "believe" it.

Still, for a simple offline game, imagine what happens if the game freezes for a second (because some other application misbehaves or what-not). You would end up doing a ton of physics updates in a single frame. In a complex scene that will take forever, causing the _next_ frame time to be way to large again. You are trading a single long freeze vs. a long freeze followed by prolonged stuttering.

As for doubles, in his current code it would be a trivial change to calculate the frame time before casting it to double. If he was using a library like GLFW he wouldn't even have that option (it always returns time in double). I remember a table listing which type would last how long before precision becomes a problem. While floats are pretty horrible, doubles will still be a decent choice. Especially since SDL returns time since initialization and not 1970, so he would probably have to run his game for days or weeks before noticing the effects.

I'll just blindly quote from Game Programming Gems 4 about doubles for time measuring: "after 80 hours, it's sub-second accuracy is an amazing 0.00000023ms)". I doubt his game will ever be running long enough to notice precision issues.

Share this post


Link to post
Share on other sites
Hi all. Sorry I ducked out for a bit. The first implementation was a bastardization of the main loop on the article: [url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]

To be honest, the physics and calculus nature of his implementation confused me so although I implemented it, I know it was incorrect.

I have since redone the loop using dewitters last game loop (is this also fixed time step), and have gotten good results...

Here's the thing. I am not here to make a quick game, I want this to be a solid engine I can produce a game on, extend and reuse. I know physics will eventually be part of the game and although I don't anticipate writing my own physics engine, I would love to know the actual logic behind it. Because I have been less than clear and confused, and you have all been incredibly helpful in providing articles and source, let me break down my understanding of it and I will ask questions. Again, my apologies.


I will be basing my questions, understand off of: [url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]
Please tell me what I have missed. [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img]
--------------------------

[b] Fixed delta time[/b]

So the inherent problem here is the rate at which you update your game. You shouldn't just update the game as fast as possible as that will make programs/games run faster on faster computers and slower on slower computers. Not ideal.

[b] Variable delta time[/b]

The logical solution (what I tried as well) is to measure the time it takes for each frame and record the time change (the delta). Then pass this into the physics simulation. This will provide consistent speed but differing physics results on different framerates. Also for some reason, they are keeping track of the total time represented by t, for some reason. Why is this? It is used in the integrate function which I understand to be an integral from Calculus.

[b] Semi-fixed timestep[/b]

The solution to this is to ensure the delta time is small and the results will be (nearly) identical every time. If I understand correctly, this loop takes the last frame rate (i think) and then updates the physics continuously, decrementing the frametime until it is zero and finally renders the frame.

FINAL SOLUTION

The final solution is to have a fixed delta time (time between updates) so that your physics are run at regular intervals BUT at the same time, render independently. Again, I am confused by some of his functions like integrate. I assume this is his physics update, just the same as I would update a player's position.

To do this, he caps the delta time which will affect physics at a specific time to avoid the spiral of death.

The next part is where I am confused:

[CODE]
while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}


[/CODE]

When he integrates, what exactly is he updating? How would that apply to moving a character across the screen rather than a calculus function?

Then, when the accumulator is smaller than delta time, he calculates the alpha value which is interpolation?

Then, he interpolated the position of the ball (and in my case, a character) by the value alpha (this makes sense)

My main question about this last loop is about the code I linked above is what exactly is it doing. What does integrate do? Is it just a general physics function? What would I do instead for a simple bomberman clone during that time.

----------------


Thank you again. It's quite funny. I have pretty much everything else coded and yet, my main loop keeps changing. I really appreciate the time you guys have spent helping me. Sorry that I have learned this a bit slow. I will make sure to pay it forward and help others.

Thanks! Edited by Chanz

Share this post


Link to post
Share on other sites
I can answer some of these questions. But, realize, that article is for a physics simulation, not specifically a game, and the integrate() function is for moving objects around in some kind of environment. If you want to know what the integrate function does, check the previous article in that series, which, if you want to understand that, you need some basis in calculus and physics.

[quote name='Chanz' timestamp='1337050348' post='4940274']
Hi all. Sorry I ducked out for a bit. The first implementation was a bastardization of the main loop on the article: [url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]

To be honest, the physics and calculus nature of his implementation confused me so although I implemented it, I know it was incorrect.

I have since redone the loop using dewitters last game loop (is this also fixed time step), and have gotten good results...

Here's the thing. I am not here to make a quick game, I want this to be a solid engine I can produce a game on, extend and reuse. I know physics will eventually be part of the game and although I don't anticipate writing my own physics engine, I would love to know the actual logic behind it. Because I have been less than clear and confused, and you have all been incredibly helpful in providing articles and source, let me break down my understanding of it and I will ask questions. Again, my apologies.


I will be basing my questions, understand off of: [url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]
Please tell me what I have missed. [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img]
[/quote]
[quote]
--------------------------

[b] Fixed delta time[/b]

So the inherent problem here is the rate at which you update your game. You shouldn't just update the game as fast as possible as that will make programs/games run faster on faster computers and slower on slower computers. Not ideal.
[/quote]

That's not correct. The Fixed delta time uses a fixed value for the simulation step and rendering. So, as in my original example above, my fixed timestep is 1/60 (60 fps). Although SFML handles it for me, if it didn't the idea would be, record the time, step physics (giving 1/60 as step) and render, get current time, and wait for current time - original time == 1/60, then repeat.

It isn't updating as fast as possible, it's updating on a fixed time. The down side is some platforms might not be able to maintain 60 fps, which would cause the game to run slower.
[quote]
[b] Variable delta time[/b]

The logical solution (what I tried as well) is to measure the time it takes for each frame and record the time change (the delta). Then pass this into the physics simulation. This will provide consistent speed but differing physics results on different framerates. Also for some reason, they are keeping track of the total time represented by t, for some reason. Why is this? It is used in the integrate function which I understand to be an integral from Calculus.
[/quote]

The down-side for this is only an issue for a physics simulation. If your game doesn't use any physics (or, if it uses it's own physics simulation based on Euler, and not required to be 100% accurate), I would wholly support using this. It covers the case of any speed CPU, and the game would run almost exactly the same (differences probably not noticeable). If you are using a physics engine, then it does change the simulation, and cause some issues.

Again, integate() function uses t as the total time, and is part of it's physics calculations. Check the previous article to understand why.
[quote]

[b] Semi-fixed timestep[/b]

The solution to this is to ensure the delta time is small and the results will be (nearly) identical every time. If I understand correctly, this loop takes the last frame rate (i think) and then updates the physics continuously, decrementing the frametime until it is zero and finally renders the frame.

FINAL SOLUTION

The final solution is to have a fixed delta time (time between updates) so that your physics are run at regular intervals BUT at the same time, render independently. Again, I am confused by some of his functions like integrate. I assume this is his physics update, just the same as I would update a player's position.

To do this, he caps the delta time which will affect physics at a specific time to avoid the spiral of death.

The next part is where I am confused:

[CODE]
while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}


[/CODE]

When he integrates, what exactly is he updating? How would that apply to moving a character across the screen rather than a calculus function?


Then, when the accumulator is smaller than delta time, he calculates the alpha value which is interpolation?

Then, he interpolated the position of the ball (and in my case, a character) by the value alpha (this makes sense)

My main question about this last loop is about the code I linked above is what exactly is it doing. What does integrate do? Is it just a general physics function? What would I do instead for a simple bomberman clone during that time.
[/quote]
This final method just separates the physics simulation from the rendering.

integrate() does handle the physical movements. In the form given, it would update just one object's physical location and velocity. In general, just think of it as updating all your physical objects' position and velocity.

I think your best bet is to follow JTippets loop above if you want to go this route for the game loop as he has a good example.

Obviously, the games I make are for fun for me, and I don't spend a lot of time on my loops. I set the frame-rate to some value (1/60), and just fire and forget and have fun in the other parts of my code.

Share this post


Link to post
Share on other sites
He uses the function name integrate() because a physics solver performs integration to solve the set of equations representing the simulation. Integration might not necessarily apply, though, if you are not performing any kind of actual physics; ie, velocity and acceleration, collision and rebounding, joints and constraints. A more general-case name for it might be UpdateLogic (which is what I use). It is here that you move characters, move projectiles, etc...

integrate() is passed a dt value so that it knows how long to make the timestep, and that value is directly used in calculations. But if you don't base your logic calculations off this timestep, you don't really need to pass it. For instance, you can just specify that an object moves X distance per second, and if you know you update at a rate of 25 fps, you can just move him 1/25 * X each update.

Remember that in order to interpolate for rendering, each object needs to store 2 sets of position/rotation/scale data. So each time update is called, the Last transformation is set to the value of the Current transformation, and Current is set to the new step.

Share this post


Link to post
Share on other sites
Thank you both again. Last question as I have the whole thing implemented and working: Does SDL have an accurate enough timer or should I grab a more precise one? Any recommendations?

Thanks!

Share this post


Link to post
Share on other sites
[quote name='Chanz' timestamp='1337124327' post='4940547']
Thank you both again. Last question as I have the whole thing implemented and working: Does SDL have an accurate enough timer or should I grab a more precise one? Any recommendations?

Thanks!
[/quote]
I think that's up to you. I assume SDL's timer has 1 mS resolution, and if that's good enough, then don't sweat it (for me, it's good enough). Otherwise, if you're using a Windows implementation, you can use QueryPerformanceConter() [url="http://support.microsoft.com/kb/172338"]http://support.microsoft.com/kb/172338[/url]

BTW, one other piece of advise, I would suggest at least looking into SFML. You'll find the functionality it provides (especially in Audio and graphics) is much better than what SDL provides, as SFML sits on top of OpenGL and OpenAL. SDL uses software for it's GFX implementation, and any scaling, rotating, or other high-processor intensive things you want to do, it will becoming HALTINGLY slow.

Share this post


Link to post
Share on other sites

This topic is 2040 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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