Minetest Baby Chick

Why Game Characters Moonwalk–How to Prevent Foot Sliding

The “Moonwalk” is all fun and games, but not when it is unintentional. Then it can be a problem. “Foot usliding” really kills my gaming experience (especially if frequent or constant) and can hinder immersion even if it only happens in edge cases. By hinder immersion, I mean that when it happens, I remember I am playing a game and feel less emotionally connected to the character (less invested in the character’s safety, exertion, and position in the case of foot sliding). This article explains the calculations to prevent or correct foot sliding in your game. I used the calculations to correct the Baby Chick for minetest.org, how to use other speeds without foot sliding, and ideas for Blender best practices for Minetest modders (and anyone making a game) to make the values in the source code easier to maintain.

Minetest Baby Chick
Minetest Baby Chick

Minetest has 10 units per meter internally, so there is an extra step for Minetest modders in the design and speed measurement processes (make model 10x real-life size in Blender, and divide resulting land speed by 10 before using the number in your code, respectively).

In Blender, I measured the foot velocity manually (whenever I say “write down” below, you can type/paste it into a text editor or calculator–I recommend the public licensed Speedcrunch which keeps a visible history–for GNU+Linux systems, search for it in your Software application). There is no remotely easy way yet:

  • create an Empty, move it to the tip of the toe, write down the location (only the value for the axis matching character’s facing direction)
  • go to the next frame in the walk sequence
  • move the empty to the new position of the toe, and write down the new location
  • manually subtract the first location from the second location and write down the absolute (positive) value (that’s your distance per frame)
  • multiply the distance by frame rate (that’s your result [m/s]!)
  • [then divide by 10 for Minetest]

In the case of my baby chick, my result was .32 m/s (meters per second) at 14 fps.

So for that example, the following frame rates apply:

        speed_normal = 14,  -- since I used 14 fps, the default Blender frame rate, to animate this model
        speed_run    = 28,  -- since I used the same frames for both running and walking, but want running to be twice as fast (not usually recommended, since walking and running are mechanically and hence visually different, but may be ok for bugs and baby chicks)

You would use the following velocity values to avoid foot sliding:

        walk_velocity = .32,  -- since that is the land speed calculated in Blender, and the original frame rate is used for speed_normal above
        run_velocity = .64,  -- foot*(28/14) since frame rate of run animation sequence is 28 above, double of original

If you need a value higher than the velocity values above, multiply frame rate (14) by the ratio of .32 (the Blend file’s foot speed, divided by 10 for Minetest) and the velocity.

Examples:

IF you use

    run_velocity = .96,  -- .32*3 (a multiple of the original foot speed from Blender)

then also change:

    speed_run = 46,  -- = 14fps*3

IF you instead use

    run_velocity = 1,

then also change:

    speed_run = 43.75,  -- = 14fps * (1/.32)

Since the visual_scale is one, no additional changes to values are needed.

The 14 only applies to 14 fps animations like the current version of the Minetest Baby Chick (arbitrarily decided by the animator for each model, in the editing application).

The land speed could affect the frame rate using the formula fps = original_fps * (current_v / original_v) / scale which is used above (scale is always 1 above, so it is excluded).

You could adjust the frame rate in real time if you store those variables:

original_fps = 14
original_v = .32

However, supporting multiple sequences is better for teams and existing models that can’t be edited (Animators usually make the feet move faster when creating run sequences so they can see the real outcome while editing, though I suggest changing it before exporting the model):

original_fps["walk"] = 14
original_v["walk"] = .32

A major way that games fail at this point in the process is by using the character’s “desired” land speed instead of the actual current land speed, such as when walking against a wall (fully or partially facing the wall) that reduces speed:

To avoid that issue, you must get the top view (ground plane) distance between the previous frame and the current frame:
traversed = vector.distance(pos, previous_pos)
Then you would divide that by the amount of time that passed to get meters per second:

precision = 1000000  -- this must be set to #of ticks per second
passed = ((minetest.get_us_time() - prev_tick) / precision)
if passed >= 0.001 then
    -- if enough time passed to calculate anything
    if previous_pos then
        previous_pos.y = pos.y  -- eliminate vertical delta to get ground traversed--so if game were z-up, set z instead
        traversed = vector.distance(pos, previous_pos)
        if prev_tick then
            current_v = traversed / passed
        end
    end
    prev_tick = minetest.get_us_time()
    previous_pos = pos
end

or

precision = 1.0  -- this must be set to #of ticks per second
passed = ((minetest.get_gametime() - prev_tick) / precision)
if passed >= 0.001 then
    -- if enough time passed to calculate anything
    if previous_pos then
        previous_pos.y = pos.y  -- eliminate vertical delta to get ground traversed--so if game were z-up, set z instead
        traversed = vector.distance(pos, previous_pos)
        if prev_tick then
            current_v = traversed / passed
        end
    end
    prev_tick = minetest.get_gametime()
    previous_pos = pos
end

To reduce the difficulty for people using your model in games, I suggest using a standard land speed and frame rate for all models in your project:
1 meter/sec (in Blender, to make setting the frame rate according to speed even easier–make velocity and frame rate have a perfect 10:1 ratio).
at 10 fps (low frame rate should not reduce the animation smoothness, since Irrlicht and other major game engines do tweening [generate frames in between]).

If you planned for certain running physics (vertical movement per airtime), annotate the values (frame rate and forward velocity) for the developers:

original_fps["run"] = 14
original_v["run"] = .32

If you do not use the suggested 1 m/sec at 10 fps standard, you would have to record the annotations above for every model in your project to avoid foot sliding.

:edit 2022-02-18: You can either made a ground that moves to help visualize where feet should be or animate the character moving then change it back to a game-ready character (a character that stays at 0,0 from the top view) using the [currently alpha but working] In Placer Add-on for Blender.

:edit 2022-02-18: Animating a run sequence at 1 m/sec may seem tricky for artists, but you can simply animate at 5 m / 5 sec or any other 1:1 ratio.

For existing character management systems such as Mobs Redo for Minetest, there is no feature for adjusting the frame rate automatically. Therefore, I suggest putting a comment before velocity similar to the one in baby_chick.lua (in the link at the top of article):
-- at 14 fps, the feet move at .32 meters/sec
I plan to add this style of comment to every Lua file that uses a model I edit for minetest.org from now on.

Don’t forget: If you change the model scale, the feet will move faster in world coordinates! Therefore you either must either divide the frame rate (“speed_*”) by that amount (and use that value for the new “speed_*”) or multiply the velocity by that amount (and use that value for the new velocity), not both (or relationship will diverge)!

Example:

        walk_velocity = .32,
        run_velocity = .64,  -- since frame rate of run animation sequence is 28, double of original (only applicable if you use same frames for run and walk)
-- affected by:
        visual_scale = 2,
-- results in fps (the animation of the feet must move slower to match the velocity since the resulting model is larger at this scale):
        speed_normal = 7  -- = 14 * (.32/.32) / 2
        speed_run = 14  -- = 14 * (.64/.32) / 2

Example of making it smaller instead:

        walk_velocity = .32,
        run_velocity = .64,  -- since frame rate of run animation sequence is 28, double of original
-- affected by:
        visual_scale = .5,
-- results in fps (the animation of the feet must move faster to keep up since the resulting model is smaller at this scale):
        speed_normal = 28  -- = 14 * (.32/.32) / .5
        speed_run = 56  -- = 14 * (.64/.32) / .5

Example of changing speed (fps) instead (may be desireable for a giant version of a character that can move faster due to size):

        speed_normal = 14  -- = 14 * (.32/.32)
        speed_run = 28  -- = 14 * (.64/.32)  -- increase frame rate since velocity is double of original Blender foot speed
-- affected by:
        visual_scale = .5,
-- results in velocity (the character must move slower to match the slower world space movement of the smaller feet at this scale, if frame rate must remain the same):
        walk_velocity = .16,
        run_velocity = .32,  -- 

What if you want to still change the velocity without causing the relationship to diverge? That’s still possible. You can use that fps formula I provided earlier (if your character management system allows adjusting the character in real time), using the values above as the “original_*” values.

Eventually if I create a “attachment point” metadata generation feature in b3view, I can also make another feature based on vertex selection: measure vertex speed. Then I could get correct foot speeds of more models that do not yet use the above proposed 1 m/s at 10 fps standard. Until then I’m begging for a Blender plugin to measure speed numerically or a 4D enhancement to its MeasureIt Add-on.

Unfortunately there is another major problem which I call “foot stab,” where the toe stabs into the ground. A toe bone, affecting the toe joint and toes only, (or toe point for “block style” games like Minetest) should remain pinned to the ground while the body’s forward movement pulls the heel off the ground. Then when the the body is too far forward, it pulls the toes off the ground separately. At that stage, the very tip can be the pivot point as the toes lift (unless the whole bone lifts–this may depend on the character’s way of walking; or unless your scene requires even greater detail, in which case you can use bendy bones like in Blender or even a fully anatomically correct number of foot bones).

One more area to consider is transitions between animation sequences or poses. In the transition below (from standing to action), when the character changes to standing on one foot, the left foot slides inward. You could synchronize the foot with the ground by moving the body left when the foot moves right, like would happen in real life (near the end of the video you can also see that the walk sequence is not synchronized with the ground, which turned me off to the game each time I tried major releases, and which may have prevented PlaneShift from achieving more popularity).

Parametric curve on spell effects – PlaneShift MMORPG

As an artist, you must be a good observer. As an animator, you must study the details of motion–watching videos in slow motion helps. Even if you are making a fantasy game, there has to be some realism in the area of physics, even if the physics are exaggerated–there must be a strong connection between the characters and their environment. If the characters and the environment clash in some way that is difficult to quantify without knowing how to observe it, then even with high quality static aspects of characters (modeling, lighting, texturing, etc.) you can end up with something “jarring” like Star Wars Episode I. If you want to invest your time where it matters, you must make a connection between characters and their environments.


Posted

in

by