Miniturbo

From MKWii TAS Wiki
Jump to navigation Jump to search
Not to be confused with Stand-still miniturbo.

The miniturbo, or mini-turbo / MT is a speed boost technique present in Mario Kart Wii. Miniturbos can only be performed on manual transmission; they are disabled for automatic drift.

Overview

Miniturbos charge over time while drifting, with an integer value tracking progress (the miniturbo charge). After a miniturbo is charged, ending the drift triggers a brief speed boost, adding 20% to maximum IV. There are two tiers of miniturbos in Mario Kart Wii: a standard miniturbo, displayed by blue sparks at the rear wheel(s), and a super miniturbo / SMT, displayed by orange sparks. Super miniturbos are only available to karts.

The rate of charge of a miniturbo depends on the horizontal stick input held during the drift. There are 15 possible horizontal stick inputs, ranging from -7 to +7. For inputs between +3 and +7 during a right drift, or -3 to -7 during a left drift, the miniturbo charge increases by 5 each frame. Otherwise, the miniturbo charge increases by 2 each frame.

Standard miniturbos can be released from the frame after the charge is strictly greater than 270. Therefore, miniturbos take anywhere between 55 and 136 frames to charge. On karts, the super miniturbo's progress is tracked by a separate charge value that starts increasing once the first charge value exceeds 270; the SMT is charged when its charge value exceeds 300, which takes between 61 and 151 additional frames. Small blue and orange sparks appear when the charge values reach 150 and 180, respectively, but they are purely cosmetic.

The boost length depends on the miniturbo statistic, affected by both vehicle and character choice. Standard miniturbos can be as short as 15 frames (Jetsetter + Waluigi, Bowser, King Boo, or Funky Kong) and as long as 48 frames (Bullet Bike + Koopa Troopa or Dry Bones). Super miniturbos are always three times as long as a standard miniturbo; the length ranges from 45 to 141 (Mini Beast + Koopa Troopa or Dry Bones).

Techniques

On bikes, miniturbos are used after nearly every turn to quickly accelerate from drift speed to max wheelie speed. Miniturbos replace the bike's regular (slow) acceleration with a constant 3 u/f^2 acceleration while they're active, making it effortless to reach max speed in a miniturbo. This is an important reason why manual transmission is almost always better than automatic; due to the lack of miniturbos, auto bikes have to slowly accelerate up to wheelie speed out of every turn.

Softdrift

Main article: Drift#Softdrift

As mentioned earlier, the charge rate is the same for all inputs between +3 and +7 during a right drift. Therefore, holding +3 gives a much wider drift trajectory than holding +7 would, without delaying the miniturbo release at all.

Luke's rule

Recall earlier that (standard) miniturbos can be released when the charge value is strictly greater than 270. In a right drift, holding +3 to +7 for 54 frames gives a charge value of exactly 270, but the miniturbo is not considered charged until the next frame (and can first be released frame after). Replacing one frame with a +2 to -7 input decreases the charge of 267, which allows for a wider drift without delaying the miniturbo charge.

This off-by-one oddity is known as Luke's rule. While the most common use case is described above, it can be useful for mixed drifts too. Depending on how many countersteer inputs have been performed, sometimes one countersteer input can be added without delaying the miniturbo, while others it will delay the miniturbo charge by one frame. In particular, Luke's rule applies if the number of countersteer frames in the drift is 0 or 2 mod 5.[1]

Luke's rule can be used twice when charging super miniturbos: once while the initial charge value increases to 270, and once more while the second charge value increases to 300.

Relevant code

// TODO: context, comments
// NOTE: This has not been confirmed to match yet, but is at least functionally equivalent
void Kart::KartMove::calcMtCharge() {
    if (mDriftState >= 3) {
        return;
    }

    KartState *state = mAccessor->getState();
    if (state->mFlags & ONLINE_REMOTE) {
        return;
    }

    addMtCharge(1, mMtCharge, BASE_MT_CHARGE, MAX_MT_CHARGE);
    addMtCharge(2, mSmtCharge, BASE_SMT_CHARGE, MAX_SMT_CHARGE);
}

bool Kart::KartMove::addMtCharge(s32 driftState, s16 &mtCharge, s16 baseMtCharge, s16 maxMtCharge) {
    bool charged = false;
    if (mDriftState == driftState) {
        mtCharge += baseMtCharge;
        addExtraMtCharge(mtCharge, EXTRA_MT_CHARGE, NO_EXTRA_MT_CHARGE, BONUS_CHARGE_STICK_THRESHOLD);
        if (checkMtCharge(mtCharge, maxMtCharge)) {
            charged = true;
            ++mDriftState;
        }
    }
    return charged;
}

void Kart::KartMove::addExtraMtCharge(s16 &mtCharge, s16 left, s16 right, f32 bonusStickChargeThreshold) const {
    s16 leftTurningBonus = left;
    s16 rightTurningBonus = right;
    if (mHopStickX == -1) {
        leftTurningBonus = right;
        rightTurningBonus = left;
    }

    f32 stickX = mAccessor->getState()->getStickX();
    if (stickX < -bonusStickChargeThreshold) {
        mtCharge += leftTurningBonus;
    } else if (stickX > bonusStickChargeThreshold) {
        mtCharge += rightTurningBonus;
    }
}

// This function is never seen anywhere in the binary
// However, it's heavily speculated to exist due to the assembly instructions
inline bool Kart::KartMove::checkMtCharge(s16 &mtCharge, s16 maxMtCharge) {
    if (maxMtCharge < mtCharge) {
        mtCharge = maxMtCharge;
        return true;
    }
    return false;
}

References