How the Drop Dash works in Mania

Discussion in 'Tutorials Archive' started by MainMemory, Nov 25, 2017.

  1. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922

    Now, while I haven't actually played any hacks or fangames that have the Drop Dash in them, I have a feeling that few if any of them are implementing it in exactly the same way that Sonic Mania does, simply because of how complex the calculations actually are. This post is meant to explain the mechanics and physics behind the Drop Dash, I will not give you ASM code to paste into your hack with no effort. At the bottom of the post, I have a Sonic 2 ROM with Drop Dash implemented according to this information as an example.

    This first part of code runs when Sonic is jumping. If the jump button is pressed, the jump ability flag is 1 (meaning you can use an ability), Sonic does not have an elemental shield power, and the moveset is set to Mania, the jump ability flag is set to 2 to signify the initiation of a Drop Dash. Then, if the jump ability flag is greater than 1 and the jump button is held, the flag's value is incremented each frame until the result is greater than 21 (meaning a 20-frame waiting period), at which point the Drop Dash is properly started, playing the sound effect, changing Sonic's animation, and changing his movement routine (you may use a flag instead).
    Now, if the jump button is released before Sonic hits the ground, the Drop Dash is cancelled, restoring the normal rolling sprites and putting him in a falling state and setting the jump ability flag to 0 so he cannot use abilities.
    When Sonic hits the ground with a Drop Dash charged, first the game performs the regular landing speed calculations so his ground speed is set according to X and Y speed in the air and the slope of the ground. The game checks if you are holding Left or Right, and sets Sonic's current direction to the direction you are holding.
    Then, it sets two variables depending on whether you are currently Super Sonic, which I will call dashspeed and maxspeed. Sonic Mania uses 32-bit speed values, but for convenience I will use 16-bit values with decimal versions in parentheses. If you are not Super, dashspeed is set to $800 (8.0) and maxspeed is set to $C00 (12.0); if you are Super, dashspeed is set to $C00 (12.0) and maxspeed is set to $D00 (13.0).
    The dashspeed and maxspeed values and the comparisons in the next lines are all negated if your direction is left, but otherwise the math is the same as when your direction is right. If your X speed (in the air) is greater than or equal to 0, your ground speed (inertia) is divided by four (>> 2) and added to the dashspeed, then it is capped to maxspeed. Otherwise, if your angle is not 0 (on a slope), your ground speed (which is moving backwards because the first check failed) is cut in half and added to the dashspeed, resulting in a slower than normal dash. If you're moving backwards on flat ground, your ground speed is simply set to dashspeed.

    Here's some code directly from the game for when you hit the ground while charging a Drop Dash:
    Code:
        v0->JumpAbilityFlag = 0;
        if ( v0->RightHeld == 1 )
          v0->Direction = 0;
        if ( v0->LeftHeld == 1 )
          v0->Direction = 1;
        if ( v0->SuperMode == 2 )
        {
          dashspeed = 0xC0000;
          maxspeed = 0xD0000;
        }
        else
        {
          dashspeed = 0x80000;
          maxspeed = 0xC0000;
        }
        if ( v0->Direction )
        {
          if ( v0->XSpeed <= 0 )
          {
            v6 = -maxspeed;
            v7 = (v0->GSpeed >> 2) - dashspeed;
            v0->GSpeed = v7;
            if ( v7 < v6 )
              v0->GSpeed = v6;
            goto LABEL_25;
          }
          if ( v0->GroundAngle )
          {
            v0->GSpeed = (v0->GSpeed >> 1) - dashspeed;
            goto LABEL_25;
          }
          dashspeed = -dashspeed;
        }
        else
        {
          if ( v0->XSpeed >= 0 )
          {
            v5 = dashspeed + (v0->GSpeed >> 2);
            v0->GSpeed = v5;
            if ( v5 > maxspeed )
              v0->GSpeed = maxspeed;
            goto LABEL_25;
          }
          if ( v0->GroundAngle )
          {
            v0->GSpeed = dashspeed + (v0->GSpeed >> 1);
            goto LABEL_25;
          }
        }
        v0->GSpeed = dashspeed;
    LABEL_25:
    
    And here's the Sonic 2 with Drop Dash ROM: http://mm.reimuhakurei.net/misc/S2DropDash.zip
    I've also removed the air speed cap and disabled the rolljump behavior.
     
    Last edited: Nov 26, 2017
    DarkexMW, Giovanni, Niko and 14 others like this.
  2. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    Since it's related to the topic, I'll just put this here: Drop Dash in S3K.
     
    ProjectFM, Burst and LuigiXHero like this.