On this page
  1. Related
  2. Mechanics
  3. References
  4. Sources

The atlas reads Mario Kart: Double Dash!! through the doldecomp project’s decompilation, C++ for a USA debug build that’s still in progress. Names and comments quoted here are theirs. The item manager’s C++ doesn’t yet compile to the game’s code, so its claims say so. Nothing has been measured in the game yet.

The item pick weighs each item by a row for the kart’s place, read from a file on the disc, and adds the driver’s own special item to the nine common ones1. The pick looks at the partner: the special drops out when the partner holds one, and so do lightning, the star, triple mushrooms, and the Spiny Shell when the partner holds the same1. A default pairing weighs its special by half again, and in Grand Prix the CPU drivers’ Spiny Shell weight rises by half while a flag the code calls isPlayerFirst is set1. King Boo and Petey draw from all nine specials instead of one of their own2. In Grand Prix, Mario Kart 64 reads a 100-slot row for the place, with no partner or character in the pick3.

Mechanics

MechanicKindHow
Item distributionBy placeGrand Prix and Versus weigh nine common items and the driver's own special by a row for the place, read from a disc file, with the partner's item ruling some out
Every claim about this game, by concept (2)
Item distributionIn the doldecomp decompilation of Mario Kart: Double Dash!!, which builds a USA debug version (MarioClub_us) and whose item manager, Sato/ItemObjMgr.cpp, does not yet match the game's code, the item pick reads byte weights from a file on the disc, /Item/ItemSlotList.dat (or ItemSlotList1.dat or ItemSlotList2.dat, by the race's item-slot type). The file holds lists, each with a row of weights for every place, and a Grand Prix or Versus pick reads the row for the kart's place less one. Outside LAN play, Grand Prix reads a list by engine class (150cc and Mirror share one) for human players and the next list for CPU drivers, and Versus reads one list for every driver by the number of karts, two to four. The pick adds the row's weights for nine common kinds and for the driver's own special item, draws a whole number below the total (computed), and walks the running sum. The special's weight is multiplied by 1.5 when the two riders are a default pairing (isDefaultCharCombi), and the special is left out when the partner holds or stocks a special item, or when it is ItemHeart and the kart already has one; four common kinds (ItemThunder, ItemStar, ItemKinokoSuc, and ItemFlyTurtle, which the atlas reads as the Spiny Shell) are left out when the partner holds or stocks the same kind. startShuffle clears the flag the code calls _7, and startItemShuffleSingle sets it when its doShuffle argument is true; with it set, the pick first draws among the specials alone. setDynamicRate, which copies the weights the pick reads, writes 0 for any kind whose IsAbleToCreateItem is false (a function the decompilers comment as fabricated), and in Grand Prix multiplies the CPU list's ItemFlyTurtle weight by 1.5 while RivalBodyCtrl::isPlayerFirst() is true. In Grand Prix, Mario Kart 64 instead reads one byte from a 100-slot row for the place, from a human or a CPU table, with no partner or character in the pick.Code notes
In the doldecomp decompilation of Mario Kart: Double Dash!!, which builds a USA debug version (MarioClub_us) and whose item manager, Sato/ItemObjMgr.cpp, does not yet match the game's code, King Boo and Petey (character IDs 19 and 20) get an ItemRndSpecialShuffleMgr for their item picks, as every driver does in Balloon Battle and the battle the code calls ESCAPE_BATTLE; other drivers get the plain ItemShuffleMgr. Where the plain pick adds one special item, the driver's own, the random-special pick adds all nine specials, each weighted from the row's columns 18 to 26, counting from 0 (slotTable[1][i + 18] for i from 0 to 8, computed) and multiplied by 1.5 for a default pairing unless isMiniGame() is true, and leaves out the heart when the kart already has one. It leaves all nine out when the partner holds or stocks a special item. In Grand Prix, Mario Kart 64's pick takes only the place and whether the driver is a CPU.Code notes

References

  1. ^ abcIn the doldecomp decompilation of Mario Kart: Double Dash!!, which builds a USA debug version (MarioClub_us) and whose item manager, Sato/ItemObjMgr.cpp, does not yet match the game's code, the item pick reads byte weights from a file on the disc, /Item/ItemSlotList.dat (or ItemSlotList1.dat or ItemSlotList2.dat, by the race's item-slot type). The file holds lists, each with a row of weights for every place, and a Grand Prix or Versus pick reads the row for the kart's place less one. Outside LAN play, Grand Prix reads a list by engine class (150cc and Mirror share one) for human players and the next list for CPU drivers, and Versus reads one list for every driver by the number of karts, two to four. The pick adds the row's weights for nine common kinds and for the driver's own special item, draws a whole number below the total (computed), and walks the running sum. The special's weight is multiplied by 1.5 when the two riders are a default pairing (isDefaultCharCombi), and the special is left out when the partner holds or stocks a special item, or when it is ItemHeart and the kart already has one; four common kinds (ItemThunder, ItemStar, ItemKinokoSuc, and ItemFlyTurtle, which the atlas reads as the Spiny Shell) are left out when the partner holds or stocks the same kind. startShuffle clears the flag the code calls _7, and startItemShuffleSingle sets it when its doShuffle argument is true; with it set, the pick first draws among the specials alone. setDynamicRate, which copies the weights the pick reads, writes 0 for any kind whose IsAbleToCreateItem is false (a function the decompilers comment as fabricated), and in Grand Prix multiplies the CPU list's ItemFlyTurtle weight by 1.5 while RivalBodyCtrl::isPlayerFirst() is true. In Grand Prix, Mario Kart 64 instead reads one byte from a 100-slot row for the place, from a human or a CPU table, with no partner or character in the pick.Code notesdoldecomp/mkdd · n64decomp/mk64revised
    How we know
    13WIP 1:1 Decompilation of Mario Kart Double Dash!!
    ⋮
    17Currently only the debug version is supported.
    
    README.md lines 13–17 at 1d2918c · upstream ↗
    80  To use a version other than `MarioClub_us` (USA), specify it with `--version`.
    
    README.md line 80 at 1d2918c · upstream ↗
    NonMatching = False
    configure.py#L357 · upstream ↗
    1303            Object(NonMatching, "Sato/ItemObjMgr.cpp"),
    
    configure.py line 1303 at 1d2918c · upstream ↗
    76    static const char *getSlotList(int slotType)
    ⋮
    78        const char *ret = "/Item/ItemSlotList.dat";
    79        switch (slotType)
    ⋮
    81        case 2:
    82            ret = "/Item/ItemSlotList1.dat";
    83            break;
    84        case 3:
    85            ret = "/Item/ItemSlotList2.dat";
    86            break;
    
    include/Sato/ItemObjMgr.h lines 76–89 at 1d2918c · upstream ↗
    1638    u8 *slotListData = (u8 *)ResMgr::getPtr(ResMgr::mcArcMRAM, getSlotList(RCMGetManager()->getItemSlotType()));
    
    src/Sato/ItemObjMgr.cpp line 1638 at 1d2918c · upstream ↗
    1647    switch (RCMGetManager()->getRaceLevel())
    ⋮
    1649    case LVL_50CC:
    1650        slotCount = 0;
    1651        enemySlotCount = 1;
    1652        break;
    1653    case LVL_100CC:
    1654        slotCount = 2;
    1655        enemySlotCount = 3;
    1656        break;
    1657    case LVL_150CC:
    1658    case LVL_MIRROR:
    1659        slotCount = 4;
    ⋮
    
    src/Sato/ItemObjMgr.cpp lines 1647–1662 at 1d2918c · upstream ↗
    1664    if (RCMGetManager()->isLANMode())
    ⋮
    1666        switch (RCMGetManager()->getKartNumber())
    ⋮
    1668        case 2:
    1669            slotCount = 6;
    1670            break;
    1671        case 3:
    1672            slotCount = 7;
    1673            break;
    1674        case 4:
    1675            slotCount = 8;
    1676            break;
    ⋮
    1679            break;
    ⋮
    
    src/Sato/ItemObjMgr.cpp lines 1664–1699 at 1d2918c · upstream ↗
    1719    u8 *defaultSlotList = slotListData + calcBufOffset(slotListData + 1, slotCount);
    1720    setToList(defaultSlotList + 1, &mSlotList);
    ⋮
    1738        u8 *enemyList = slotListData;
    1739        if (RCMGetManager()->getRaceMode() == VERSUS_RACE)
    ⋮
    1741            enemyList += calcBufOffset(enemyList + 1, slotCount);
    1742            enemyList += 1;
    ⋮
    1746            enemyList += calcBufOffset(enemyList + 1, enemySlotCount);
    1747            enemyList += 1;
    ⋮
    1749        setToList(enemyList, &mSlotListEnemy);
    
    src/Sato/ItemObjMgr.cpp lines 1719–1749 at 1d2918c · upstream ↗
    1753u32 ItemShuffleMgr::calcBufOffset(u8 *pData, int n)
    ⋮
    1758        u8 playerCount = *pData++;
    1759        u8 itemCount = *pData++;
    1760        offset += playerCount * itemCount + 2;
    
    src/Sato/ItemObjMgr.cpp lines 1753–1763 at 1d2918c · upstream ↗
    1766void ItemShuffleMgr::setToList(u8 *pData, ItemShuffleMgr::KartSlotData *slotData)
    ⋮
    1768    u8 playerCount = *pData++;
    1769    u8 itemCount = *pData++;
    ⋮
    1776    for (u8 playerIndex = 0; playerIndex < playerCount; playerIndex++)
    ⋮
    1789    for (u8 itemIndex = 0; itemIndex < itemCount; itemIndex++)
    ⋮
    1791        for (u8 playerIndex = 0; playerIndex < playerCount; playerIndex++)
    ⋮
    1793            slotData->mList[playerIndex].slotTable[0][itemIndex] = *pData++;
    
    src/Sato/ItemObjMgr.cpp lines 1766–1795 at 1d2918c · upstream ↗
    1843int ItemShuffleMgr::SlotItem(const int kart_index, const u8 driver_index) {
    1844    bool hasEnemy = !ObjUtility::isPlayerDriver(kart_index);
    ⋮
    1846    if (!RCMGetManager()->isRaceModeGp()) {
    1847        hasEnemy = false;
    ⋮
    1850    const KartSlotData *slotList = hasEnemy ? &mSlotListEnemy : &mSlotList;
    ⋮
    1852    int specialKind = ItemObj::getSpecialKind(kart_index, driver_index);
    1853    int rankIdx = RCMGetKartChecker(kart_index)->getRank() - 1;
    
    src/Sato/ItemObjMgr.cpp lines 1843–1853 at 1d2918c · upstream ↗
    1881    u8 swapped_idx = driver_index == 0 ? 1 : 0;
    1882    ItemObj *equipedItem = GetItemObjMgr()->getKartEquipItem(kart_index, swapped_idx);
    ⋮
    1885        normalKind = equipedItem->getKind();
    ⋮
    1888        normalKind = GetItemObjMgr()->getStockItem(kart_index, swapped_idx);
    ⋮
    1890    const bool combi = RCMGetManager()->getKartInfo(kart_index)->isDefaultCharCombi();
    1891    if (_7) {
    1892        int slot = calcRndSpecialSlot(rankIdx, *slotList, combi);
    ⋮
    1900    return calcSlot(rdata, specialKind, normalKind, combi);
    
    src/Sato/ItemObjMgr.cpp lines 1881–1900 at 1d2918c · upstream ↗
    1564    int sSlotItemIndex[27] = {
    1565        0, 2, 13, 3,
    1566        5, 18, 6, 10,
    1567        15, 17, 1, 4,
    
    src/Sato/ItemObjMgr.cpp lines 1564–1571 at 1d2918c · upstream ↗
    371            case 6:
    ⋮
    373                    removeItem(new ItemStar(6));
    ⋮
    387            case 10:
    ⋮
    389                    removeItem(new ItemThunder(0xa));
    ⋮
    399            case 13:
    ⋮
    401                    removeItem(new ItemFlyTurtle(0xd));
    ⋮
    403            case 14:
    ⋮
    405                    removeItem(new ItemHeart(0xe));
    ⋮
    422            case 18:
    ⋮
    424                    removeItem(new ItemKinokoSuc(18));
    
    src/Sato/ItemObjMgr.cpp lines 371–424 at 1d2918c · upstream ↗
    732int CLPointControllerFlyTurtle::findNextPointNo(CLPoint *point) {
    ⋮
    736        if(RCMGetKartChecker(i)->getRank() == 1)
    737            groupID = GetKartCtrl()->GetKartCenterPtr(i)->getGroupID();
    
    src/Sato/ItemFlyTurtle.cpp lines 732–737 at 1d2918c · upstream ↗
    1957void ItemShuffleMgr::calcRaceUseNormalItem(u32 *pTotal, ItemShuffleMgr::KartSlotRankDataSet *rdata, int maxId)
    ⋮
    1959    for (int i = 0; i < sSlotNormalItemNum; i++)
    ⋮
    1961        int itemIdx = sSlotItemIndex[i];
    1962        if ((((itemIdx != 10) && (itemIdx != 6) && (itemIdx != 0x12)) && (itemIdx != 0xd)) || maxId != itemIdx)
    ⋮
    1964            *pTotal += rdata->slotData->mList[rdata->kart_rank].slotTable[1][i];
    
    src/Sato/ItemObjMgr.cpp lines 1957–1966 at 1d2918c · upstream ↗
    1974void ItemShuffleMgr::calcSpecialItemNum(u32 *pTotal, ItemShuffleMgr::KartSlotRankDataSet *data, int itemID1, int itemID2, bool charCombi)
    ⋮
    1978    for (int i = sSlotNormalItemNum; i < data->slotData->totalSlots; i++)
    ⋮
    1980        if (itemID1 == sSlotKindIndexArray[i]) {
    ⋮
    1983            if (ItemObj::IsSpecialItem(itemID2) || (itemID1 == 0xe && ItemObjMgr::getItemObjMgr()->getHeartItem(data->kart_index))) {
    1984                sTempSlotUseItem[sSlotNormalItemNum] = false;
    ⋮
    1988                u32 chance = data->slotData->mList[data->kart_rank].slotTable[1][i];
    ⋮
    1990                if (charCombi) {
    1991                    chance *= 1.5f;
    ⋮
    1993                *pTotal += chance;
    
    src/Sato/ItemObjMgr.cpp lines 1974–1995 at 1d2918c · upstream ↗
    2024int ItemShuffleMgr::calcRank(KartSlotRankDataSet rdata)
    ⋮
    2027    u32 randomNum = stGetRnd(0)->getRandomMax(rdata.total - 1);
    ⋮
    2032    for (int i = 0; i < sSlotNormalItemNum + 1; i++, prevTotalChance = totalChance)
    ⋮
    2042        totalChance += sTempSlotUseItem[i] ? itemChance : 0;
    2043        if ((prevTotalChance <= randomNum) && (totalChance > randomNum))
    ⋮
    2045            ret = sSlotKindIndexArray[itemIdx];
    
    src/Sato/ItemObjMgr.cpp lines 2024–2046 at 1d2918c · upstream ↗
    2059int ItemShuffleMgr::calcSlot(KartSlotRankDataSet &rdata, int p2, int p3, bool charCombi)
    ⋮
    2065    calcRaceUseNormalItem(&total, &rdata, p3);
    2066    calcSpecialItemNum(&total, &rdata, p2, p3, charCombi);
    ⋮
    2070    return calcRank(rdata);
    
    src/Sato/ItemObjMgr.cpp lines 2059–2070 at 1d2918c · upstream ↗
    511u32 stRandom::getRandomMax(u32 max)
    ⋮
    513    return ((max + 1) * get_ufloat_1());
    
    src/Sato/stMath.cpp lines 511–513 at 1d2918c · upstream ↗
    217        f32 get_ufloat_1()
    ⋮
    226            out.s = (this->get() >> 9) | 0x3f800000;
    227            return out.f - 1;
    
    include/JSystem/JMath/JMath.h lines 217–228 at 1d2918c · upstream ↗
    526bool KartInfo::isDefaultCharCombi()
    ⋮
    530    if (mKartCharacters[0].getPartnerID() == mKartCharacters[1].getCharID())
    531        ret = true;
    
    src/Kaneshige/KartInfo.cpp lines 526–531 at 1d2918c · upstream ↗
    1815void ItemShuffleMgr::setAllDynamicRate()
    ⋮
    1817    setDynamicRate(&mSlotList, false);
    1818    if (!RCMGetManager()->isLANMode() && RCMGetManager()->getRaceMode() == GRAND_PRIX)
    1819        setDynamicRate(&mSlotListEnemy, true);
    ⋮
    1826        if (GetItemObjMgr()->IsAbleToCreateItem(sSlotItemIndex[i]))
    1827            ableToCreate = true;
    ⋮
    1830            if (ableToCreate) {
    1831                slotData->mList[j].slotTable[1][i] = slotData->mList[j].slotTable[0][i];
    1832                if (isGrandPrix && RivalBodyCtrl::isPlayerFirst() && sSlotItemIndex[i] == 0xd) {
    1833                    slotData->mList[j].slotTable[1][i] *= sGPEnemyFlyTurtleItemSlotRatio;
    ⋮
    1836            else {
    1837                slotData->mList[j].slotTable[1][i] = 0;
    
    src/Sato/ItemObjMgr.cpp lines 1815–1838 at 1d2918c · upstream ↗
    1224bool ItemObjMgr::IsAbleToCreateItem(int itemIdx) { // UNUSED, fabricated, size mismatch
    
    src/Sato/ItemObjMgr.cpp line 1224 at 1d2918c · upstream ↗
    70    void startShuffle()
    ⋮
    72        mRollFlags |= 1;
    73        _7 = false;
    
    include/Sato/ItemObjMgr.h lines 70–73 at 1d2918c · upstream ↗
    1325void ItemObjMgr::startItemShuffleSingle(int kart_index, bool doShuffle) {
    ⋮
    1329    mShuffMgr[kart_index][driver_index]->startShuffle();
    1330    if(doShuffle) {
    1331        mShuffMgr[kart_index][driver_index]->set_7(true);
    
    src/Sato/ItemObjMgr.cpp lines 1325–1331 at 1d2918c · upstream ↗
    64    f32 sGPEnemyFlyTurtleItemSlotRatio = 1.5f;
    
    src/Sato/ItemObjMgr.cpp line 64 at 1d2918c · upstream ↗
    3665u8 gen_random_item(s16 rank, s16 isCpu) {
    3666    u16 rand = random_int(100);
    ⋮
    3671    sRandomItemIndex = ((u32) rand + (sRandomItemIndex + gControllerRandom) + gRaceFrameCounter) % 100U;
    
    src/update_objects.c lines 3665–3671 at 58cfcb0 · upstream ↗
    3687    } else if (gModeSelection == BATTLE) {
    3688        curve = segmented_to_virtual((void*) common_battle_item_curve);
    3689        randomItem = curve[sRandomItemIndex];
    3690    } else { // GP Mode
    3691        if (isCpu == 0) {
    3692            curve = segmented_to_virtual((void*) common_grand_prix_human_item_curve);
    3693        } else {
    3694            curve = segmented_to_virtual((void*) common_grand_prix_cpu_item_curve);
    ⋮
    3696        randomItem = *((rank * 100) + curve + sRandomItemIndex);
    
    src/update_objects.c lines 3687–3696 at 58cfcb0 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^In the doldecomp decompilation of Mario Kart: Double Dash!!, which builds a USA debug version (MarioClub_us) and whose item manager, Sato/ItemObjMgr.cpp, does not yet match the game's code, King Boo and Petey (character IDs 19 and 20) get an ItemRndSpecialShuffleMgr for their item picks, as every driver does in Balloon Battle and the battle the code calls ESCAPE_BATTLE; other drivers get the plain ItemShuffleMgr. Where the plain pick adds one special item, the driver's own, the random-special pick adds all nine specials, each weighted from the row's columns 18 to 26, counting from 0 (slotTable[1][i + 18] for i from 0 to 8, computed) and multiplied by 1.5 for a default pairing unless isMiniGame() is true, and leaves out the heart when the kart already has one. It leaves all nine out when the partner holds or stocks a special item. In Grand Prix, Mario Kart 64's pick takes only the place and whether the driver is a CPU.Code notesdoldecomp/mkdd · n64decomp/mk64revised
    How we know
    13WIP 1:1 Decompilation of Mario Kart Double Dash!!
    ⋮
    17Currently only the debug version is supported.
    
    README.md lines 13–17 at 1d2918c · upstream ↗
    1303            Object(NonMatching, "Sato/ItemObjMgr.cpp"),
    
    configure.py line 1303 at 1d2918c · upstream ↗
    101    KING_BOO = 19,
    102    PETEY = 20,
    
    include/kartEnums.h lines 101–102 at 1d2918c · upstream ↗
    176void ItemObjMgr::createShuffleMgr()
    ⋮
    182            if (GetGeoObjMgr()->isBalloonBattle() || GetGeoObjMgr()->isEscapeBattle())
    ⋮
    184                mShuffMgr[i][j] = new ItemRndSpecialShuffleMgr();
    ⋮
    186            else
    ⋮
    188                s32 charID = RCMGetManager()->getKartInfo(i)->getDriverCharID(j);
    189                mShuffMgr[i][j] = !IsSpecialCharacter(charID) ? new ItemShuffleMgr() : new ItemRndSpecialShuffleMgr();
    
    src/Sato/ItemObjMgr.cpp lines 176–193 at 1d2918c · upstream ↗
    1222bool ItemObjMgr::IsSpecialCharacter(s32 charID) { return charID == 0x13 || charID == 0x14; }
    
    src/Sato/ItemObjMgr.cpp line 1222 at 1d2918c · upstream ↗
    105    virtual ~ItemShuffleMgr();                                                     // 08
    106    virtual void calcRaceUseNormalItem(u32 *, KartSlotRankDataSet *, int);         // 0C
    107    virtual void calcSpecialItemNum(u32 *, KartSlotRankDataSet *, int, int, bool); // 10
    108    virtual int calcRank(KartSlotRankDataSet);                                     // 14
    ⋮
    125class ItemRndSpecialShuffleMgr : public ItemShuffleMgr
    ⋮
    131    virtual void calcRaceUseNormalItem(u32 *, KartSlotRankDataSet *, int);
    132    virtual void calcSpecialItemNum(u32 *, KartSlotRankDataSet *, int, int, bool);
    133    virtual int calcRank(KartSlotRankDataSet);
    
    include/Sato/ItemObjMgr.h lines 105–133 at 1d2918c · upstream ↗
    1564    int sSlotItemIndex[27] = {
    1565        0, 2, 13, 3,
    1566        5, 18, 6, 10,
    1567        15, 17, 1, 4,
    1568        21, 8, 11, 7,
    1569        12, 14, 17, 1,
    1570        4, 21, 8, 11,
    1571        7, 12, 14};
    
    src/Sato/ItemObjMgr.cpp lines 1564–1571 at 1d2918c · upstream ↗
    1974void ItemShuffleMgr::calcSpecialItemNum(u32 *pTotal, ItemShuffleMgr::KartSlotRankDataSet *data, int itemID1, int itemID2, bool charCombi)
    ⋮
    1980        if (itemID1 == sSlotKindIndexArray[i]) {
    ⋮
    1988                u32 chance = data->slotData->mList[data->kart_rank].slotTable[1][i];
    
    src/Sato/ItemObjMgr.cpp lines 1974–1995 at 1d2918c · upstream ↗
    2103void ItemRndSpecialShuffleMgr::calcSpecialItemNum(u32 *pTotal, ItemShuffleMgr::KartSlotRankDataSet *data, int itemID1, int itemID2, bool charCombi) {
    2104    if (ItemObj::IsSpecialItem(itemID2)) {
    2105        for (int i = 0; i < sSlotSpecialItemNum; i++) {
    2106            sTempSlotUseItem[i + sSlotNormalItemNum] = false;
    ⋮
    2108        return;
    ⋮
    2111    calcRndSpecialRatio(pTotal, data, charCombi);
    
    src/Sato/ItemObjMgr.cpp lines 2103–2111 at 1d2918c · upstream ↗
    2005void ItemShuffleMgr::calcRndSpecialRatio(u32 *pTotal, ItemShuffleMgr::KartSlotRankDataSet *data, bool charCombi) {
    2006    for (int i = 0; i < sSlotSpecialItemNum; i++) {
    2007        if ((sSlotKindIndexArray[i + sSlotNormalItemNum] == 0xe && ItemObjMgr::getItemObjMgr()->getHeartItem(data->kart_index))) {
    ⋮
    2012            u32 chance = data->slotData->mList[data->kart_rank].slotTable[1][i + sSlotNormalItemNum + sSlotSpecialItemNum];
    ⋮
    2014            if (!GetGeoObjMgr()->isMiniGame() && charCombi) {
    2015                chance *= 1.5f;
    ⋮
    2017            *pTotal += chance;
    
    src/Sato/ItemObjMgr.cpp lines 2005–2019 at 1d2918c · upstream ↗
    2135int ItemRndSpecialShuffleMgr::calcRank(KartSlotRankDataSet slotRankData)
    ⋮
    2143    for (int idx = 0; idx < slotRankData.slotData->totalSlots; idx++, prevTotalChance = totalChance)
    ⋮
    2145        u32 itemChance = idx >= sSlotNormalItemNum ? sTempSpecialRatio[idx - sSlotNormalItemNum] : slotRankData.slotData->mList[slotRankData.kart_rank].slotTable[1][idx];
    ⋮
    2150            ret = sSlotKindIndexArray[idx];
    
    src/Sato/ItemObjMgr.cpp lines 2135–2150 at 1d2918c · upstream ↗
    3665u8 gen_random_item(s16 rank, s16 isCpu) {
    3666    u16 rand = random_int(100);
    
    src/update_objects.c lines 3665–3671 at 58cfcb0 · upstream ↗
    3690    } else { // GP Mode
    3691        if (isCpu == 0) {
    3692            curve = segmented_to_virtual((void*) common_grand_prix_human_item_curve);
    3693        } else {
    3694            curve = segmented_to_virtual((void*) common_grand_prix_cpu_item_curve);
    ⋮
    3696        randomItem = *((rank * 100) + curve + sRandomItemIndex);
    
    src/update_objects.c lines 3690–3696 at 58cfcb0 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^In the US version of Mario Kart 64, gen_random_item picks an item as one byte from a 100-byte row of a table, the row for the driver's current place. In Grand Prix, human players read common_grand_prix_human_item_curve and CPU drivers common_grand_prix_cpu_item_curve, and that branch reads no player count. Versus picks one of three tables by the number of players (two, three, or four), and Battle reads one row whatever the place. The slot is a random number from 0 to 100 (random_int(100)) plus the previous slot, a counter that held A, B, and R buttons advance, and the race frame counter, taken mod 100.Coden64decomp/mk64revised
    How we know
    3665u8 gen_random_item(s16 rank, s16 isCpu) {
    3666    u16 rand = random_int(100);
    ⋮
    3671    sRandomItemIndex = ((u32) rand + (sRandomItemIndex + gControllerRandom) + gRaceFrameCounter) % 100U;
    
    src/update_objects.c lines 3665–3671 at 58cfcb0 · upstream ↗
    3673    if (gModeSelection == VERSUS) {
    3674        switch (gPlayerCountSelection1) {
    3675            case TWO_PLAYERS_SELECTED:
    ⋮
    3678            case THREE_PLAYERS_SELECTED:
    ⋮
    3681            case FOUR_PLAYERS_SELECTED:
    ⋮
    3685        randomItem = *((rank * 100) + curve + sRandomItemIndex);
    
    src/update_objects.c lines 3673–3685 at 58cfcb0 · upstream ↗
    3687    } else if (gModeSelection == BATTLE) {
    3688        curve = segmented_to_virtual((void*) common_battle_item_curve);
    3689        randomItem = curve[sRandomItemIndex];
    3690    } else { // GP Mode
    3691        if (isCpu == 0) {
    3692            curve = segmented_to_virtual((void*) common_grand_prix_human_item_curve);
    3693        } else {
    3694            curve = segmented_to_virtual((void*) common_grand_prix_cpu_item_curve);
    ⋮
    3696        randomItem = *((rank * 100) + curve + sRandomItemIndex);
    
    src/update_objects.c lines 3687–3696 at 58cfcb0 · upstream ↗
    3702u8 gen_random_item_human(UNUSED s16 arg0, s16 rank) {
    3703    return gen_random_item(rank, false);
    ⋮
    3706u8 cpu_gen_random_item(UNUSED s32 arg0, s16 rank) {
    3707    return gen_random_item(rank, true);
    ⋮
    3714    randomItem = gen_random_item_human(gLapCountByPlayerId[arg1], gGPCurrentRaceRankByPlayerId[arg1]);
    
    src/update_objects.c lines 3702–3714 at 58cfcb0 · upstream ↗
    3918                cpu_decisions_branch_item(playerId, &cpuStrategy->branch,
    3919                                            cpu_gen_random_item((s16) gLapCountByPlayerId[playerId],
    3920                                                                gGPCurrentRaceRankByPlayerId[playerId]));
    
    src/cpu_vehicles_camera_path.c lines 3918–3920 at 58cfcb0 · upstream ↗
    1205void randomize_seed_from_controller(s32 arg0) {
    ⋮
    1208    if ((controller->button & A_BUTTON) != 0) {
    1209        gControllerRandom++;
    ⋮
    1211    if ((controller->button & B_BUTTON) != 0) {
    1212        gControllerRandom++;
    ⋮
    1214    if ((controller->button & R_TRIG) != 0) {
    1215        gControllerRandom++;
    
    src/code_80057C60.c lines 1205–1215 at 58cfcb0 · upstream ↗
    1269u16 random_int(u16 arg0) {
    1270    return arg0 * (((f32) random_u16()) / 65535.0);
    
    src/racing/math_util.c lines 1269–1270 at 58cfcb0 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code