The 2nd 96er

The 2nd 96er (2024)

If you're reading this, it means that we've successfully completed a 2nd 96er, an event where we race all 96 maps available in mario kart 8 (48 standard + 48 DLC tracks).

This year we had 4 participants, Gabba, Sweeney, Noah and myself.

Race Set Up: 2 x 48 race multiplayer grand prix with Tracks in order. 200cc, Frantic Items, Hard CPU (the Mob).

The results were as follows:

#TrackWinnerInsights
1Mario Kart StadiumGabba
2Water ParkGabbaSo many narnies
3Sweet Sweet CanyonGabba
4Thwomp RuinsBen
5Mario CircuitSweeneyFirst consistent
6Toad HarbourNoah
7Twisted MansionBen2 twisted
8Shy Guy FallsGabbaFirst hundy
9Sunshine AirportSweeneyFirst podium
10Dolphin ShoalsGabbaBen 10th and Sweeney 11th
11ElectrodomeSweeneyFirst outside - 'I live outside'
12Mount WarioGabbaSweeney pool time
13Cloudtop CruiseSweeneyKC
14Bone Dry dunesGabbaPodium
15Bowsers CastleGabbaFirst 200ie
16Rainbow RoadGabba
17Moo Moo MeadowsSweeney
18Mario CircuitGabbaStupid narnie on the sean
19Cheep Cheep BeachSweeneyBest map in the game
20Toads TurnpikeGabba2 200s - podium
21Dry Dry desertLink (First Mob)
22Donut PlanesGabbaMob
23Royal RacewayGabbaThe mob is awake
24DK JungleSweeneyPodium
25Wario StadiumGabbaPodium
26Sherbet LandGabba
27Melody MotorwayGabba
28Yoshi ValleyBen* as didn't hit the cannon on the first lap
29Tick Tock ClockSweeney
30Pirahna Plant PipewayGabba
31Grumble VolcanoSweeneyLink is on one
32Rainbow RoadSweeney
33Yoshi CircuitSweeneyFirst narnie snipe by Gabba
34Excitebike arenaSweeney
35Dragon DriftwayGabba
36Mute CityGabbaLink Widening the gap
37Warios Gold MineGabba
38Rainbow RoadGabba
39Ice Ice OutpostGabba
40Hyrule CircuitLink (Still First Mob)All 4 players hit with single bomb
41Baby ParkNoah
42Cheese LandGabba
43Wild WoodsSweeney
44Animal Crossing (Summer)Gabbasummer days
45Koopa CityGabbashit map
46Ribbon RoadGabbathis map is inside
47Super bell SubwayGabbaLink with the steal from Noah
48Big BlueBenLast Race wins (first half)
49Paris PromenadeSweeney
50Toad CircuitSweeney
51Choco MountainGabba
52Coconut MallSweeneyFendin off petey
53Tokyo BlurSweeneyNoah Donut
54Shroom RidgeGabbaCar got in the way of the sean
55Sky GardenTanooki Mario (Mob)First mob win of second half
56Ninja HideawayGabbacan a blue be sent backwards?
57New York MinutePetey Piranha (Mob)sweeney though he had it
58Mario Circuit 3GabbaPodium
59Kalamari DesertGabbaSweeney 11th
60Waluigi PinballGabba
61Sydney SprintTanooki Mario (Mob)
62SnowlandGabba
63Mushroom GorgePetey Piranha (Mob)
64Sky-High SundaeGabbaBen hit my the mob
65London LoopGabba
66Boo LakeGabba
67Alpine PassSweeneyPetey still hitting
68Maple TreewaySweeney
69Berlin BywaysGabba
70Peach GardensSweeney
71Merry MountainSweeneyThe mob in force
72Rainbow RoadGabba
73Amsterdam DriftSweeney
74Riverside ParkBenGreat map
75DK's Snowboard CrossGabbatouche
76Yoshi's IslandSweeney
77Bangkok RushGabba
78Mario CircuitSweeneynot many lightenings on the seans
79Waluigi StadiumGabba
80Singapore SpeedwaySweeneyBowser Junior with the 2nd swoop
81Athens DashGabba
82Daisy CruiserGabbaSweeney hit
83Moonview HighwayGabba
84Squeaky Clean SprintGabba
85Los Angeles LapsGabbahe hate that
86Sunset WildsGabba
87Koopa CapeGabbasweeney unfortunate red
88Vancouver VelocitySweeney
89Rome AvantiBen
90DK MountainSweeney
91Daisy CircuitGabba
92Piranha Plant CoveGabba
93Madrid DriveBen
94Rosalina's Ice WorldGabbaPodium
95Bowser Castle 3Benand thats how it can happen
96Rainbow RoadSweeneyLast race wins

Wins Distribution

The total wins by each player

Points Distribution - First Half

Races 1 - 48

Points Distribution - Second Half

Races 49 - 96

Until Nintendo adds a 96 race grand prix, we are kind of stuck with this 2 x 48 analysis format, because as you may have noticed, drivers between the first and second 48 change. I completely understand why they haven't added this 96 race format, as this whole premise is kind of absurd.

Data Retrieving Methodology

This year, I wanted to see just what kind of data I could somewhat easily record and analyse from the 96er.

So, I thought that it would be a good start to take a photo of the scoreboard after every race (except the 2 I forgot, Cheep Cheep beach and Daisy Cruiser). From here, I was able to over engineer a solution to get the data from the photos into a format that I could analyse.

First, I did have to go through and manually name each of the 94 images I took with something resembling their track name. This took me about half an hour and turns out it wasn't really necessary, but it makes the input data a bit nicer so thats something.

Now that I had all of my 'TRACK_NAME.HEIC' image files:

heic-files

It's time to send it to GPT to ask it to rip out the information I need. Unfortunately, as I was about to learn, GPT does not allow for processing of HEIC images:

unsupported-format

so I had to write another script to convert the images from .HEIC to .PNGs.

png-conversion

which seems to have worked well:

formatted-pngs

Now that I can send the images to GPT to analyse, I had to cook up a prompt to get GPT to return the data in the format I wanted. I went for:

You are mario kart score GPT. Here is a photo of a mario kart scoreboard.

Can you please return this leaderboard as a JSON array of 12 items,
containing the player and score?

Please add a START and END string at the beginning and end of the JSON,
and do not add any formatting (new lines, tabs, etc).

I just needed to run this for all 94 of my newly converted PNGs and I should have all scoring data I need output to a single folder, and voila, it appears to run well:

score-analysis

Now that I have a folder full of the scores from each map, I can really cook.

json-scores

First, I need to write a script that takes all of the JSON files, and extracts the greatest score value. This will help me sort the input data into a somewhat chronological order, which will be easier to plot along an x-axis.

But, here is where I hit another snag - as we did 2 x 48 races, I had 2 similar very score ranges. e.g, Mario Kart Stadium and Paris Promenade were the same values for max points score - and at the moment I didn't have a way to differentiate between which race was in the first 48 and which was the 2nd.

sorting-snafu

However, this is where I was able to repurpose the array I used in the table at the top of this screen. It's in the form:

const results = [
  ...
  {
    track: "Big Blue",
    winner: "Ben",
    insights: "Last Race wins (first half)",
  },
  ...
]

So, if I just rip out the track name and remove the spaces - I should be able to match most of the track names to the score data file I have for that track. This initially worked pretty well, basically leaving only duplicate rainbow roads and the 2 maps I forgot to take photos of:

unordered-maps

From here, I just had to add an index the rainbow road results array to match how I stored the photos of the Rainbow road scores:

sorted-rainbow-roads

here,

  • RainbowRoad_Blue.png - the rainbow road with the tunnel where you should hit the blue at the end
  • RainbowRoad_hardturn.png - the rainbow road with the super hard turn at the start
  • RainbowRoad_Jumps.png - the simpler rainbow road with the little jumps
  • RainbowRoad_NoLaps.png - the rainbow road where it's all continuous, no laps
  • RainbowRoad.png - the first file I named so it just got called rainbow road

Once I factored this in, I was able to sort the race data I had from races 1-96 (except the 2 I forgot):

index-sorting-output

Once I had this, I just had to write this script that outputs the track placing data (our .jsons) into a format that I could use to plot the data on a graph, e.g:

const results = [
  {
  track: 1,
  "Donkey Kong": 15,
  "Black Shy Guy": 12,
  Bowser: 10,
  Toadette: 9,
  "Baby Daisy": 8,
  Waluigi: 7,
  Luigi: 6,
  "Pink Gold Peach": 5,
  "Tanooki Mario": 4,
  "King Boo": 3,
  Link: 2,
  Kamek: 1,
},
{
  track: 2,
  "Donkey Kong": 30,
  "Black Shy Guy": 21,
  Waluigi: 19,
  Toadette: 19,
  Bowser: 17,
  "Pink Gold Peach": 13,
  "Baby Daisy": 13,
  Luigi: 12,
  "King Boo": 7,
  Link: 5,
  "Tanooki Mario": 5,
  Kamek: 3,
},
...
]

And, that's how I got the above line graphs. I only budgeted 4 hours to this whole analysis and am already sick of looking at mario related data, so I'll leave it at that.

See you next time.