3
$\begingroup$

We are game developers currently working on a new game. We are looking to solve the following problem:

We start with the following variables:

$$x = 0, h = 1;$$

The variable x should always increase over time depending on $h$—the larger the $h$ the larger the rate that $x$ increases. On the other hand $h$ decreases over time with a steady velocity. $h$ ranges from 0 to 1.

After time $t$ the variable $x$ will become:

$$x := x + \sum( C_1 \cdot ( h + V \cdot n ) ) \mathrm{\ for\ } n = [0, t]. $$

$C_1$ is a constant. $V$ is the change rate of $h$.

Whenever we calculate $x$ we need to calculate the new value of $h$ like so:

$$h := h + V \cdot t$$

So what happens in order is this:

  • $x := x + \sum( C_1 \cdot ( h + V \cdot n ) ) \mathrm{\ for\ } n = [0,t]$
  • $h := h + V \cdot t$

Both of these formulas could be wrong of course, this is simply what we are trying to achieve.

The variable t is essentially time in seconds. The problem is that if say $t = 2$ then $x$ will have a certain value if we calculate it like so:

  • $x := x + \sum( C_1 \cdot ( h + V \cdot n ) ) \mathrm{\ for\ } n = [0,2]$
  • $h := h + V \cdot 2$

and a different value if we calculate it like so:

  • $x := x + \sum( C_1 \cdot ( h + V \cdot n ) ) \mathrm{\ for\ } n = [0,1]$
  • $h := h + V \cdot 1$
  • $x := x + \sum( C_1 \cdot ( h + V \cdot n ) ) \mathrm{\ for\ } n = [0,1]$
  • $h := h + V \cdot 1$

Essentially the values are different if we break up the calculation into more steps.

We need the values to be the same in both cases. We cannot do this with these formulas so I was wondering if there is another way to do this. I understand that my explanation might be a little difficult to understand but it's not very easy for me to explain this!

Thank you

2 Answers 2

3

You can use the differential equations to get an exact solution. You have

$x'=C_1h$ where the prime is the derivative with respect to time

$h'=-C_2t$ Then

$h=h(0)-C_2t$

$x=x(0)+C_1h(0)t-\frac 12 C_2 t^2$

In your case $x(0)=0,\ h(0)=1$, so

$h=1-C_2t$

$x=C_1t-\frac 12 C_2 t^2$

  • 0
    Thank you very much for responding. Please look at my answer below...2012-07-04
0

Thanks a lot for responding. These look like the equations of motion ( they are the equations of motion! ) and this makes sense. However this is also an approximation isn't it? If you calculate a value by adding a time unit to $t$ each time then you will come up with a different number than if you calculated the value of $x$ by using a big amount of $t$.

In our case $t$ is in milliseconds so if we calculate $x$ after 3000 milliseconds we will get a different value than if we calculated $x$ after 1000 milliseconds, then another 1000 and then another 1000.

Try it out if you will with $C_1 = 0.001$ and $C_2 = 0.0001$.

The result for $t = 3000$ is $x = -147.3$ if we calculate it like so:

$x(3000) = x(0) + x(1000) + x(2000) + C_1h(2000)*1000−0.5*C_2 * 1000 ^ 2 $

and $x=-447$ if we calculate it like so:

$x(3000) = x(0) + C_1h(0)*3000−0.5*C_2 * 3000 ^ 2$

However the values converge if we make $C_2$ smaller and smaller. So is the solution to just use small values for $C_2$ ?

  • 0
    Ross' answer gives the exact solution if you let the time step tend to 0. The advantage of using an exact solution is that you can vary your time step without affecting the results (modulo rounding errors on the order of a couple of ULP). However, if you want to complicate the equations by going to solid bodies, handling collisions, etc. then incremental calculation with fixed time step is likely to be more straightforward. There's a separate gamedev.stackexchange.com where you'll find plenty of questions and answers about building physics engines.2012-07-04
  • 0
    Hi Peter. I'm not building a physics engine, it's a coincidence that the equations are similar. The game is networked and I want to calculate my new $x$ after any amount of time as requested by a client. So $t$ = current_time - last_request_time. When I calculate $x$ I want to store it and when the next request comes in I want to calculate the new $x$ for the time that passed after my last calculation. Using Ross' equations I will get a different result if I get requests less frequently and this is what I'm trying to avoid.2012-07-04
  • 0
    You are asking essentially that $x(t_2)-x(t_1)$ be proportional to $t_2-t_1$. This will only be true if $C_2=0$, which you prohibited in the original post. To calculate $x(t)$, just plug $t$ into the equation, as you did in the last line. If you want $x(t_2)-x(t_1)$, calculate them both and subtract. The earlier calculation is simply incorrect.2012-07-04
  • 0
    Essentially what I presented to you is a simplification of the actual system. What I'm trying to do is avoid numerical integration and calculate the result after any amount of t. If pluging t in the equation yields a different result than pluging 1 but t times, then we simply cannot use this system like this. Thank you for all your responses though they are very helpful.2012-07-04
  • 0
    Remember that we need to set h to previous_h - $C_2*t$ every time we calculate x. This is what messes up the calculations probably.2012-07-04
  • 1
    This explicitly avoids numerical integration and calculates the result at any $t$. You are trying to impose timesteps for some reason. You can certainly say $h(t_2)=h(t_1)-C_2(t_t-t_1),\ x(t_2)-x(t_1)=C_1(t_2-t_1)-\frac 12 C_2(t_2^2-t_1^2)$ if you want but you do need the quadratic term.2012-07-04
  • 0
    Please look at my response below because I can't fit it in a comment.2012-07-04
  • 0
    you're simultaneously saying "we want to avoid numerical integration" and then you're insisting on using timesteps. If you don't want to include the hardcoded analytic solution to the ODE, you have no choice but to deal with timesteps and the resulting numerical inaccuracy. Plugging $t$ into the analytical solution will give the same result every time. Anything else will depend on how often you update $t$, since it gets more accurate by making smaller jumps and reusing the improved estimates.2012-07-04
  • 0
    Thanks Robert that makes sense. I have also been making a mistake all this time as the equation will run for the full amount of time t and and it will run again only when one of the other parameters has changed ( and not only t ). So this should work. Thank you all again2012-07-04
  • 0
    Hey Ross this last formula solves my problem! I was making the mistake of not calculating the quadratic term correctly that's why my results were different if there were timesteps in the mix.2012-07-05