Cite as
n64decomp/mk64
Original
https://github.com/n64decomp/mk64
Pinned
n64decomp/mk64 @ 58cfcb022e10f83bc3b889d7e97508cae6837098
Accessed
2026-10-22
Licence
none stated (no LICENSE file; the README and the GitHub API name none); the game is Nintendo's
Credit
The n64decomp team's C decompilation of Mario Kart 64, which builds the US, European 1.0, and European 1.1 ROMs. Names and comments quoted in mk64 claims are theirs.
Notes
The README lists each ROM's SHA-1 (US 579c48e211ae952530ffc8738709f078d5dd215e) and says the repo doesn't contain assets, which the build extracts from a copy of the game. Data the build extracts includes the item roulette's tables (`common_grand_prix_human_item_curve` and the others), so their values aren't in the repo. The repo also holds asset and model descriptions (assets/, models/, courses/, yamls/) and assembly (asm/); the atlas fetches only src/, include/, and the README. Kart physics are in src/player_controller.c, CPU driving in src/cpu_vehicles_camera_path.c and its .inc.c parts, and item boxes in src/update_objects.c. Claims read the US build; none of the files they cite has a `VERSION_*` conditional at the cited lines.

Cited on

Claims (11)

In the US 1.0 version of Diddy Kong Racing, a race, challenge, or time trial starts its countdown at 80, and once the HUD signals the start each update takes the update rate off it; "Get Ready" shows while it reads 2 or more. A racer's first fresh press of A after the countdown drops below 80 decides its start boost. A press while the countdown reads 29 to 15 sets a boost timer of 4 up to 11 as the reading falls, half of 24 less the reading's excess over 14, rounded down (computed), and a press while it reads 14 or less sets 20 with a select sound; holding Z also counts a reading of 15 as 20. A first press while it reads 30 to 79 gives no boost and spends the chance. A Master CPU driver takes the start boost a human set, or 5 if none did, and an Expert one copies a human's if there is one. In the car's ground routine, while the boost timer is above 0 after the countdown, the throttle is held open and the factor the code calls traction, unless it's 0, becomes 2.0. Mario Kart 64 instead takes a press of A that begins within 8 race frame counts of its window opening (20 in Time Trials), while the kart's THROTTLE flag isn't already set, and every such start gets the Mushroom's boost timer, 80.src/player_controller.c L3669–3685src/player_controller.c L1112–1120Code
In the US 1.0 version of Diddy Kong Racing, a weapon balloon's type is set by its entry in the track's object list, with no roll: the code names five types, boost, missile, trap, shield, and magnet, which the decompilers' names for the all-balloons cheats pair with blue, red, green, yellow, and rainbow. A racer that touches a balloon takes its type. If the racer already held the same type with any left, the weapon's level rises by one, up to the third (level 2); otherwise it starts at the first. In a challenge the level stops at the second, and trap balloons start there; the Maximum Power-up cheat makes every pickup third-level, and CPU-driven boss vehicles collect none. The weapon and its quantity come from a table the game loads as an asset, two bytes for each type and level, so they aren't in the repo. A CPU racer's driving routine func_80042D20 can also raise a first-level pickup by one, on a percent chance from the AI behavior table. Mario Kart 64 instead picks an item box's item in Grand Prix from a 100-slot row for the driver's place.src/update_objects.c L3687–3696Code
In the US 1.0 version of Diddy Kong Racing, a car's power slide starts in its ground routine when R is held, the stick is past 15 either way, and the car is going forward faster than 3 (the code's velocity below -3). While R stays held the routine multiplies the top-speed value by 1.1. Letting go of R, or slowing to a velocity above -2, ends the slide and sets nothing else. During a slide the car update clamps the stick to 50 either way, quarters steering into the slide, and adds 60 toward it; holding the stick 26 or more against the slide adds the update rate to a count, and past 80 the car spins out and the slide ends. In an atlas search of src/, every write to the boost timer belongs to a zip pad, zipper, the start, a Nitro, a magnet, a plane trick, the loop-the-loop vehicle, or a boss, so a slide ends without a boost. Mario Kart 64 instead charges stages toward a mini-turbo while the stick counter-steers a drift.src/player_controller.c L1148–1160Code
In Excitebike 64's US Rev 1 build, riders are rubber-banded through timeScale, which multiplies the length of each of a rider's physics steps (gPhysDeltaTime). After the countdown, outside time trial and with a human racing, race_update_riders steps each CPU rider's scale by 0.0002 per update toward a target: 1 plus its skill (spread evenly over about ±0.1 by race_init_ai_skills, and used when there are two or more CPU riders), less 0.1 when it's more than 64 ahead of the CPU riders' average raceDist, less the CPU pack's lead over the humans' average beyond 30, divided by 256 and held to ±0.15, all times the track's cpuSpeed for the difficulty (a finished rider targets 1, the Beat This cheat uses the hardest difficulty's cpuSpeed plus 0.05, and a duel 1.15 times the track's). The code's comment says "CPU riders slow down as their pack leads the humans by more than 30 m and speed up as it falls behind". A human's scale steps by 0.001 toward 1 plus their distance behind the humans' average (plus 16 when it's over 2) over 1024, held between 0.95 and 1.05. With one human the target is 1, and since the step has no dead zone the scale alternates between 1 and 1.001. Mario Kart 64 instead adds a force term toward 380 while a pacing flag is set (mk64/rubber-band).include/defines.h L479src/player_controller.c L3086–3092Code
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.src/update_objects.c L3665–3671src/update_objects.c L3673–3685src/update_objects.c L3687–3696src/update_objects.c L3702–3714src/cpu_vehicles_camera_path.c L3918–3920src/code_80057C60.c L1205–1215src/racing/math_util.c L1269–1270Code
In the US version of Mario Kart 64, while a kart drifts on the ground, holding the stick at least 10 of its 53 steps toward the outside of the turn counts up driftStateCounter. Letting the stick back after 18 to 99 counts raises driftState by one, up to 3, and sets the count to 10, so each later step takes 8 more counts (computed); letting it back before 10 counts, or at 100 or more, resets both to 0. When a human player's drift ends with driftState at 2 or more, the kart gets MINI_TURBO_EFFECT for 31 player updates (computed), during which a term in its forward force moves toward 580 by a fifth of the gap each update.src/player_controller.c L1148–1170src/player_controller.c L4166src/player_controller.c L4194–4214include/defines.h L487include/common_structs.h L278src/player_controller.c L3956–3960src/player_controller.c L4862–4869src/player_controller.c L1123–1143src/player_controller.c L2139–2140src/player_controller.c L3093–3107src/render_player.c L863–864src/player_controller.c L2742–2748Code
In the US version of Mario Kart 64, in Grand Prix and Versus the engine class sets each kart's top speed from gTopSpeedTable when it spawns: 290 at 50cc, 310 at 100cc, and 320 at 150cc for Mario, Luigi, Donkey Kong, Wario, and Bowser, and 4 more for Yoshi, Toad, and Peach. Extra uses the 100cc numbers, Time Trials always reads the 100cc row, and Battle gives every driver 245.src/data/kart_attributes.c L63–86src/spawn_players.c L89–110include/defines.h L160–164include/defines.h L187–194Code
In the US version of Mario Kart 64, CPU_FAST_EFFECT, which the decompilers comment as the "CPU Rubberbanding flag", raises a CPU driver's forward force: while it's set, a term in that force moves toward 380 by half the gap each update, and once it's cleared the term falls toward 0 by a tenth of the gap. regulate_cpu_speed sets the flag on a CPU driver below its target speed when the pacing check func_800088D8 returns true, and clears it otherwise.include/defines.h L479src/player_controller.c L3086–3092src/player_controller.c L3107src/render_player.c L863–864src/cpu_vehicles_camera_path/cpu_speed_control.inc.c L203–216Code
In the US version of Mario Kart 64, the start boost's window opens when Lakitu's countdown finishes the animation after its second light sound, before the green-light sound. A press of A that begins within 8 counts of the race frame counter from the first update the window is open (20 in Time Trials) sets START_BOOST_TRIGGER, and letting go of A before the start clears it. The trigger gives the kart the Mushroom's effect and the same boost timer, 80. Once the window is open, a kart that revs to 90% of its top speed without the trigger gets START_SPINOUT_TRIGGER, the spin-out for holding the gas.src/update_objects.c L3037–3063src/player_controller.c L4749–4759src/player_controller.c L3669–3685src/player_controller.c L3703–3704src/player_controller.c L1392–1393src/player_controller.c L1112–1120src/effects.c L522–544include/defines.h L441src/code_80057C60.c L1253–1256Code
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, 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.src/update_objects.c L3665–3671src/update_objects.c L3687–3696Code 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.src/update_objects.c L3665–3671src/update_objects.c L3690–3696Code notes