Advertisement

Making Breakout - Code Structure help requested

Started by September 11, 2017 01:08 PM
77 comments, last by Kylotan 7 years, 5 months ago

Looks to me like some of the important code we need is missing - such as how those timers get updated and calculated.

If you are calculating the interpolation value based on real time after it gets used for the draw call, then I wouldn't at all be surprised if the values look wrong. It's not meant to measure or accommodate rendering time, just to get a fractional update amount with which to improve the rendering.

Just now, Kylotan said:

Looks to me like some of the important code we need is missing - such as how those timers get updated and calculated.

If you are calculating the interpolation value based on real time after it gets used for the draw call, then I wouldn't at all be surprised if the values look wrong. It's not meant to measure or accommodate rendering time, just to get a fractional update amount with which to improve the rendering.

Not missing, all the code is there at the bottom of the reply below the image, I put it inside spoiler to not occupy the whole page :)

Advertisement

Ugh. I never look for spoiler tags, and there's too much code there anyway. My comment above stands - if you're calculating the interpolation value after its use, that's clearly wrong.

7 minutes ago, Lactose said:

I was also passed this link by Frob I think, I didn't read it because I thought the first link was enough (got passed both links), I'll go reading this one too, thanks :)

1 hour ago, Lactose said:

But shouldn't you recalculate the current time after every "integrate" (which can be an arbitrary function) completes?

Edit: I read the last paragraph again and it makes sense. Basically, you use the previous frame time as a prediction of the current frame time (although, I would rather use some moving average to smooth this a bit) and updates a number of times equal to the most complete delta's that are contained in this time. The remaining fraction is transferred to future frames.

As a small note, I think it would make more sense to subtract the (predicted) render time from the frame time, since we now assume render time is neglectable.

🧙

43 minutes ago, matt77hias said:

But shouldn't you recalculate the current time after every "integrate" (which can be an arbitrary function) completes?

According to that link, you're not recalculating the current time after every integrate. Instead, you're calculating how much time has accumulated since the last integrate, or the " measure of just how much more time is required before another whole physics step can be taken. For example, a remainder of dt/2 means that we are currently halfway between the current physics step and the next. A remainder of dt*0.1 means that the update is 1/10th of the way between the current and the next state." Then the last paragraph literally states to use that to get a blending factor for the "previous and current physics state".

Advertisement

I am actually not convinced about that way of doing thing from that link. Explain me this, quoting the article:

Quote

Interpolation and Prediction

Like I said the game code runs on it’s own frames per second, so when you draw/render your frames, it is possible that it’s in between 2 gameticks. Let’s say you have just updated your gamestate for the 10Th time, and now you are going to render the scene. This render will be in between the 10Th and 11Th game update. So it is possible that the render is at about 10.3. The ‘interpolation’ value then holds 0.3. Take this example: I have a car that moves every game tick like this:



    position = position + speed;

If in the 10Th gametick the position is 500, and the speed is 100, then in the 11Th gametick the position will be 600. So where will you place your car when you render it? You could just take the position of the last gametick (in this case 500). But a better way is to predict where the car would be at exact 10.3, and this happens like this:



    view_position = position + (speed * interpolation)

The car will then be rendered at position 530.

 

So, following the logic above, interpolation regulate how much speed we apply to the position of our object. But notice this is not per second, but between 2 game updates, which is in 40ms time.We are applying the speed to the object 25 times every second. I would think that the logic thing to do for the car example above would be to specify the speed traveled in 1 second or something and then multiply by DeltaTime, but if I where to do that, now for it to work I would need to pass:


view_position = position + ((speed * UpdateDeltaTime) * Interpolation);

Correct me if I am mistaken.

The first "position + " would be the current position let's say for the 10th update, and "(speed * UpdateDeltaTime)" would be the speed traveled in an update time (40ms), and then " * Interpolation " that range from 0 to 1, to blend between the predicted position on the new update. And this if I want Speed to rapresent something concrete like how many pixel are traveled in 1 second time. Otherwise I need to rely on some tiny arbitrary value, if following the original example from that link.

This now looks fishy because I am updating the object in one way and drawing it in another, it really increases a lot the opportunity for mistakes (unless I abstract it in some method that compute the right resoult for an arbitrary variable without me manually messing with interpolation and dt)... Is anyone actually doing this?! Or I am just blindly following some questionable advice?!

Important distinction here:

The DeWitters game loop actually uses the 'interpolation' to extrapolate a view position. This is easier to implement, as it doesn't need to buffer past states, but is basically rendering things slightly in the future based on their current velocity, which can result in some marginally incorrect renderings when objects change direction, which are usually not visible.

The Gaffer On Games game loop uses proper interpolation, but that requires keeping both the old state and the new state, and the view position is the interpolated value between them. This doesn't produce wrong renderings like DeWitters, but it is more complex, and it basically renders things slightly in the past.

Both have a similar idea of tracking how far they are through the 'next' update step when rendering in order to reduce visible temporal aliasing, but both have significant differences, and their own pros and cons.

What does the game loop do if you have not overriden any Fixed Updates in your scripts? I guess the whole accumulation loop is skipped?

🧙

2 minutes ago, matt77hias said:

What does the game loop do if you have not overriden any Fixed Updates in your scripts? I guess the whole accumulation loop is skipped?

I do not understand the question

This topic is closed to new replies.

Advertisement