# Compound fractions decaying over time

1. May 14, 2012

### RagingPineapple

Hi all,

I'd appreciate a little help here. I'm making a video game, and one of the features is the ability to slow down time - a kind of Matrix-esque Bullet Time effect. I know there's a computing section, and a physics section, but I felt the issue is primarily mathematical, which is why I've put it here.

The problem is with acceleration by a fixed amount over time.

The system works this way:

The player's character contains a record of his position (we'll look at only one axis for simplicity, the Y axis). He contains a separate record for his current speed.

Internally, the flow of time is stored as a floating-point value which defaults to 1.0. A value of 0.5 means that time is going twice as slow (or half as fast, if you're a 'cup-half-full' kind of person) and 2.0 means it's going twice the speed of normal time.

The player's speed is always stored relative to normal time, but when the player is moved on the screen, he is moved by his speed in pixels per frame * the time ratio.

So if he's falling at a rate of 2px/f (pixels per frame), and the time ratio is 0.25, he will appear to move 2*0.25=0.5 pixels on each frame.

When the game is slowed down, obviously there are more frames being processed per game second, which means that timed events are divided by the time ratio to make their delays still coincide with everything.

The problem is with acceleration. Acceleration must be applied on every frame so that it appears smooth, but each time I update his acceleration, the percentage reduction for the time ratio compounds on each frame, gradually creating inaccurate results.

It's probably clearer if I show a worked example. Below shows a comparison between a scenario at 100% normal time and 50% of normal time, and how the two data sets begin to separate.

In this case, the character starts with a negative Y inertia (he's jumping upwards). Gravity is applied at 1 screen pixel per frame at normal time (0.5 pixels at 50% time).

Can anyone clear this up for me? I understand that it's basically to do with the fact that 50% applied twice on a reducing-balance basis won't equal the same as one lot of 100%, so I need to find some way of countering this so that the figures are consistent.

Please note that I'm not trying to simulate physics with any real-world accuracy here - I just want my little character to move consistently at different frame rates:

Code (Text):

At 50%            Gravity 1px per frame     At 100%
Inertia Position                    Inertia Position
-5  1000                        -5  1000
-4.5     997.75
-4   995.75                     -4   996
-3.5     994
-3   992.5                      -3   993
-2.5     991.25
-2   990.25                     -2   991
-1.5     989.5
-1   989                        -1   990
-0.5     988.75
0   988.75                      0   990
0.5     989
1   989.5                       1   991
1.5     990.25
2   991.25                      2   993
2.5     992.5
3   994                         3   996
3.5     995.75
4   997.75                      4  1000
4.5    1000
5  1002.5                       5  1005
5.5    1005.25
6  1008.25                      6  1011

2. May 15, 2012

### Diffy

So I think your problem is similar to people's confusion of APR versus APY.

Apr vs Apy

Now if you read that, and understand the difference between APR and APY I can explain the results you are seeing

You want the leap from -5 to -4 to be at 50%
But you are using APR, thus your yield from -5 to -4 is not actually 50%.

I think it would help to if you gave some more formulas for us to look at.

Anyway, I don't see why you couldn't just calculate the -4 value at 100% then split the difference for 50% time

So if you start with 1000 at -5, you can calculate 996 at -4 with 100% gravity. But then why not just take -4.5 to be the average of 1000 and 996 = 998? then make your -4 value exactly what it should be (996) then repeat.

That way all your values will line up, no?

3. May 15, 2012

### Stephen Tashi

When you slow down time does it instantly slow down? Or does it gradually slow down?

The units of accleration are distance per time-squared. How did you come up with the effect of gravity being in units of pixels per frame. Doesn't that amount to distance per unit time instead of distance per unit time-squared?

4. Jun 7, 2012

### RagingPineapple

Hi Stephen and Diffy,

Apologies for the late response, I was on holiday.

To answer Stephen's questions: When you press the 'Slowdown' button, the game will set its target slowdown rate (say a rate of 50% normal game time) and a controller gradually increases the length of each frame to achieve that. It's an aesthetic effect so the sound effects don't just snap from one speed to another but gently slow down like they do in the Matrix.

And yes, sadly my choice of storing an acceleration in pixels per frame rather than pixels per second per second was an oversight on my part - a legacy from making games where the physics didn't need to be anywhere near realistic.

I've had a play around and looked into real world physics a bit better and found that that was my problem - my new formula works essentially like this:

Average Velocity = ( Old Velocity + New Velocity ) / 2
Distance Travelled = Duration of this frame in seconds * Average Velocity

That seems to do it - that and storing all my speeds as pixels per second and accelerations as pixels per second per second.

Can you foresee any problems with this, or have we got it fixed? :)

5. Jun 7, 2012

### chiro

Hey RagingPineapple and welcome to the forums.

If you want to do this, I recommend you incorporate a data structure for each object that specifies the rate of change of time and other required parameters for the updates of associated physical parameters like velocity, acceleration and so on.

By using this to calculate the right delta's, you then use this to feed in to all your sub-systems like the physics systems (amongst others) which will be universal for all delta-parameters.

In other words, your physics systems including your numerical integrators will just take values generated by your time-delta template (just a data structure) and you won't have to modify anything in a hacky kind of way.