| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | v2 Patch Download Link Below! To copy the Mario Kart 64 Death Race Gameshark code to put in your emulator or (somehow) on an actual Gameshark or Everdrive, go to the "Copy The Code" tab below. The rest of the tabs are the various portions of the Death Race code organized and commented. I hope that people can study this rather complex Gameshark code and learn a thing or two about making codes for N64 games. Enjoy the Death Race! Have a comment, question, concern, or found a bug? Leave a comment here or email me at triclon@gmail.com | |||||||||||||||||||||||||
2 | ||||||||||||||||||||||||||
3 | Description | |||||||||||||||||||||||||
4 | The Death Race is one of the most complex Nintendo 64 Gameshark codes I have created. I will try my best to explain how it all works. The idea behind this started in the Discord64 chat. A user suggested I make a Death Race code, most likely as a joke, akin to the Death Race in F-Zero or Mario Kart 8’s battle mode. I thought it was a cool idea so here it is in its full glory. Each player gets 3 hit points (HP). Spin outs, hits, getting squished, or having Lakitu picking you up causes 1 HP worth of damage. Lose all your HP, you are dead. | |||||||||||||||||||||||||
5 | ||||||||||||||||||||||||||
6 | Download Link | v2 | https://drive.google.com/file/d/1mj2OG9gvshSY7ovIVerjxZFE6ugP_ITP/view?usp=share_link | |||||||||||||||||||||||
7 | v1 (old) | https://drive.google.com/file/d/1KJdYxLAfpCmGwEfhBhz-cvEmM9Y7oGey/view | ||||||||||||||||||||||||
8 | ||||||||||||||||||||||||||
9 | Videos | |||||||||||||||||||||||||
10 | v1 Release video - Mushroom Cup 50 cc Playthrough | https://youtu.be/T-bGpFs37Bk?si=aWnAYKmhPJHlV8V8 | ||||||||||||||||||||||||
11 | Old Mushroom Cup 50 CC GP Playthrough | https://youtu.be/eo5t4A4-CNo | ||||||||||||||||||||||||
12 | Old trailer | https://youtu.be/qVP1-PkEe2o | ||||||||||||||||||||||||
13 | ||||||||||||||||||||||||||
14 | Ideas for Modes | |||||||||||||||||||||||||
15 | Race with Death- GP or VS. modes. Same as regular racing but with 3 HP per player. | |||||||||||||||||||||||||
16 | Death Race - GP or VS. modes. Unlimited laps. 3 HP per player. Each lap heals 1 HP. Kill everyone else to win. | |||||||||||||||||||||||||
17 | GP Survival Mode - You get a total of 3 HP per track. Can you survive a whole GP without dying? 1 player and 2 player GP modes. | |||||||||||||||||||||||||
18 | Battle Race - Battle mode, except this time you battle on the tracks. Each player gets 3 HP. Last player standing wins. No healing. | |||||||||||||||||||||||||
19 | ||||||||||||||||||||||||||
20 | Explanation of hit detection | |||||||||||||||||||||||||
21 | ||||||||||||||||||||||||||
22 | The hit detection scheme relies on a few quirks of how Gameshark codes actually work. Gameshark codes loop infinitely, and the Gameshark can check and modify a single byte OR two bytes right next each other. By selectively modifying one byte or both, we can track if a hit IS occurring and if a hit HAS occurred. This is important because the code loops infinitely, we only want to take damage AFTER a hit has occurred, not DURING, or else the damage would rack up as the code loops and the player would instantly run out of HP and die. One byte tracks if a hit is in progress, and the other tracks if a hit has occurred (or not). A player only takes 1 HP worth of damage AFTER a hit has occurred. Now while the game has built in hit detection in battle mode, it is unknown how hits are registered in the game’s code, or if the code is even loaded into RAM during GP or VS races. This means we have to make up our own hit detection. Luckily the folks over at tasvideos.org sluthed out what they have called "states" (see http://tasvideos.org/GameResources/N64/MarioKart64.html#StatesTable). We can check these states for all possible things that can count as a "hit" | |||||||||||||||||||||||||
23 | ||||||||||||||||||||||||||
24 | Taking damage | |||||||||||||||||||||||||
25 | ||||||||||||||||||||||||||
26 | Once the hit occurred byte = 10 and the hit in progress byte = 00, we query both bytes along with what the player’s HP is, and subtract 1 HP accordingly. Once the damage is taken, the hit occurred byte is set back to 00 to await the next hit that might occur. | |||||||||||||||||||||||||
27 | ||||||||||||||||||||||||||
28 | Memory Map | |||||||||||||||||||||||||
29 | ||||||||||||||||||||||||||
30 | To do this, we must find at least two bytes in RAM that are unused. Multiply that by 8 possible players/CPUs and we need to find 16 bytes of unused memory. 80602000 and the surrounding memory all appear to be blank. Perfect! Now we can exploit it for our purposes 2 bytes can be set, byte 1 = hit or healing occurred, byte 2 = hit or healing in progress. Only when hit has occurred but is not in progress does player take damage. | |||||||||||||||||||||||||
31 | ||||||||||||||||||||||||||
32 | In hex this looks as follows: | |||||||||||||||||||||||||
33 | No hit | 0000 | ||||||||||||||||||||||||
34 | Hit in progress | 1001 | ||||||||||||||||||||||||
35 | After hit (take damage) = 1000 | 1000 | ||||||||||||||||||||||||
36 | Heal | 2000 | ||||||||||||||||||||||||
37 | ||||||||||||||||||||||||||
38 | The byte after tracks HP. | |||||||||||||||||||||||||
39 | ||||||||||||||||||||||||||
40 | The memory locations used for each player’s hit detection are as follows: | |||||||||||||||||||||||||
41 | P1 HIT: | 81602000 | P1 HP: | 80602002 | ||||||||||||||||||||||
42 | P2 HIT: | 81602004 | P2 HP: | 80602006 | ||||||||||||||||||||||
43 | P3 HIT: | 81602008 | P3 HP: | 8060200A | ||||||||||||||||||||||
44 | P4 HIT: | 8160200C | P4 HP: | 8060200E | ||||||||||||||||||||||
45 | P5 HIT: | 81602010 | P5 HP: | 80602012 | ||||||||||||||||||||||
46 | P6 HIT: | 81602014 | P6 HP: | 80602016 | ||||||||||||||||||||||
47 | P7 HIT: | 81602018 | P7 HP: | 8060201A | ||||||||||||||||||||||
48 | P8 HIT: | 8160201C | P8 HP: | 8060201E | ||||||||||||||||||||||
49 | ||||||||||||||||||||||||||
50 | ||||||||||||||||||||||||||
51 | Race starting flag mem loc. | 80602022 | ||||||||||||||||||||||||
52 | Race not starting | 0000 | ||||||||||||||||||||||||
53 | Race is starting | 0001 | ||||||||||||||||||||||||
54 | ||||||||||||||||||||||||||
55 | ||||||||||||||||||||||||||
56 | GP lose flag mem loc. | 80602020 | ||||||||||||||||||||||||
57 | Game running | 0000 | ||||||||||||||||||||||||
58 | GP race loss sequence running | 0001 | ||||||||||||||||||||||||
59 | GP race loss sequence finished | 0002 | ||||||||||||||||||||||||
60 | GP race win | 3 | ||||||||||||||||||||||||
61 | ||||||||||||||||||||||||||
62 | ||||||||||||||||||||||||||
63 | Race win flag mem loc. | 81602024 | Byte 1 denotes if win is occuring, byte 2 denotes winner | |||||||||||||||||||||||
64 | Default | 0000 | ||||||||||||||||||||||||
65 | P1 Wins | 0101 | ||||||||||||||||||||||||
66 | P2 wins | 0102 | ||||||||||||||||||||||||
67 | P3 wins | 0103 | ||||||||||||||||||||||||
68 | P4 wins | 0104 | ||||||||||||||||||||||||
69 | ||||||||||||||||||||||||||
70 | VS mode score mem loc. | |||||||||||||||||||||||||
71 | P1: | 80602026 | ||||||||||||||||||||||||
72 | P2: | 80602027 | ||||||||||||||||||||||||
73 | P3: | 80602028 | ||||||||||||||||||||||||
74 | P4: | 80602029 | ||||||||||||||||||||||||
75 | ||||||||||||||||||||||||||
76 | Flag to end a race | 8060202A | ||||||||||||||||||||||||
77 | In race | 0 | ||||||||||||||||||||||||
78 | End reace | 1 | ||||||||||||||||||||||||
79 | Race is completely over | 2 | ||||||||||||||||||||||||
80 | ||||||||||||||||||||||||||
81 | ||||||||||||||||||||||||||
82 | ||||||||||||||||||||||||||
83 | ||||||||||||||||||||||||||
84 | ||||||||||||||||||||||||||
85 | ||||||||||||||||||||||||||
86 | ||||||||||||||||||||||||||
87 | ||||||||||||||||||||||||||
88 | ||||||||||||||||||||||||||
89 | ||||||||||||||||||||||||||
90 | ||||||||||||||||||||||||||
91 | ||||||||||||||||||||||||||
92 | ||||||||||||||||||||||||||
93 | ||||||||||||||||||||||||||
94 | ||||||||||||||||||||||||||
95 | ||||||||||||||||||||||||||
96 | ||||||||||||||||||||||||||
97 | ||||||||||||||||||||||||||
98 | ||||||||||||||||||||||||||
99 | ||||||||||||||||||||||||||
100 | ||||||||||||||||||||||||||