Zannick / logic-graph

Tools for video game logic representation and analysis, particularly routing and beatability checks for speedruns and randomizers.
MIT License
3 stars 0 forks source link

How to appropriately calculate diagonal speed #174

Open Zannick opened 3 weeks ago

Zannick commented 3 weeks ago

In AV2, for example, we have some different methods of movements.

Normal movement is along the x-axis, with independent movement possible in the y-axis (jumping and falling). They're independent because they apply separately and have no effect on each other, so we calculate the time to traverse a distance of (x,y) is the larger time to traverse one dimension.

Nanite Mist movement and portal movement are less clear because they're freely directable in the plane and not affected by y gravity. The question is, are the x and y speeds independent, or is it truly a radial speed? If they're independent, the diagonal speed is faster than orthogonal as straight-line speed, but this won't ever be relevant since it won't increase the component speed, and the result is that we can calculate the time in the same way.

But if it's really radial speed, we have some interesting calculations to make to determine the actual speed: because we arbitrarily chose our coordinate scale, it doesn't correspond to the actual Cartesian coordinates the game must use (ours is stretched), and we have differing measurements of speed $v_y > v_x$ (because the coordinate system uses a widescreen as the unit rectangle).

For a distance $(d_x, d_y)$,

  1. We can normalize the velocity by dividing $v_y$ by $(v_y / v_x)$.
  2. This is equivalent to normalizing the coordinate system in the same way: conceptually, dividing by a ratio greater than 1 reduces the distance in that dimension, thus reducing the numerical speed because the time is the same. So we normalize the distance the same way.
  3. $$d = \sqrt{{d_x}^2 + \frac{{d_y}^2}{(v_y/v_x)^2}}$$
  4. Since the speed is radial, the velocity is $v_x$ in any direction.
  5. $$t = \frac{d}{v_x} = \frac{\sqrt{{d_x}^2 + \frac{{d_y}^2}{(v_y/v_x)^2}}}{v_x} = \sqrt{\frac{d_x}{v_x}^2 + \frac{d_y}{v_y}^2}$$

This is effectively the same as drawing a right triangle with sides equal to the orthogonal times and calculating the hypotenuse.