Een leaderboard
uit het niets
Mario Kart Wii is een spel uit 2008. Geen API, geen webhook, geen enkele officiële integratie. Toch hangt er bij ons een live leaderboard in de gang dat reageert op elke race die iemand rijdt. Dit is hoe.
Hoe we hier kwamen
- 2016
Studentenhuis
Foto-placeholderHuiskamer studentenhuisDe gemiddelde toiletsessie is precies lang genoeg voor een potje. Vraag niet hoe ik daarop kwam. Op papier bijhouden kon, maar als de nerd die ik ben was dat niet goed genoeg. Het moest en zou digitaal, met een heus online leaderboard. Maar dat lukte dus niet.
Niels - 2021
Popup Plus
We starten Popup Plus, een ontwikkelbureau in Utrecht. Drie makers, dingen bouwen, plezier hebben. Het leaderboard-idee schuift mee op de achtergrond.
- 21-24
Pogingen
Door de jaren heen een paar pogingen. Een camera op het scherm laten meekijken. Bestanden uit de Wii proberen te plukken. Niks dat lang genoeg overeind bleef, en allemaal te veel werk voor iets dat puur voor de lol moest zijn.
- 2025
AI, en eindelijk iets dat draaide
Niet omdat de code voor ons werd geschreven. Wel omdat zoeken naar "hoe lees ik live de positie uit een draaiende Mario Kart Wii" opeens een richting opleverde in plaats van duizend forumberichten uit 2008. Dolphin Memory Engine bleek het antwoord. Een paar avonden later draaide er een Python-scriptje op een MacBook dat voor het eerst een race-positie live uit Dolphin het scherm op rolde. Geen overlay, geen leaderboard, geen QR-code. Wel het bewijs dat het kon.
- 2026
Live
Eén MacBook in Dotslash Utrecht. Eén scherm in de gang. Buurbedrijven rijden tussen meetings door een rondje, en hun tijden staan binnen een minuut op het leaderboard. Werkt.
De uitdaging
Het idee was simpel: een race-meter waar collega's en buurbedrijven elkaar uitdagen op één race op Coconut Mall. Het probleem: het spel weet niets van het web. Wat het wél heeft is een stuk RAM van 24MB, en daar staat alles in. Positie, lap, tijd, frame counter, finish-tijd.
Dus daar zijn we begonnen.
Hoe het werkt
- 01
Dolphin draait, geheugen ligt open
Een MacBook draait Dolphin, de Wii-emulator. Een Python-proces haakt via
dolphin-memory-enginelive in op het geheugen van het draaiende spel. Geen tussenbestand, geen truc met de UI. Direct lezen uit MEM1, op snelheid. - 02
Geheugen lezen, Wii-stijl
Big-endian, pointer chains, struct offsets. Allemaal conventies uit 2008. We volgen
[0x809B8F70]naar de Raceinfo-struct, lopen door het spelers-array, en plukken er positie, lap, completion en finish-tijd uit. Tientallen keren per seconde, zonder dat het spel er iets van merkt. - 03
Naar de server
De parser duwt elke update via HTTP naar een Next.js-server. De overlay bovenop Dolphin polt diezelfde server eens per seconde en rendert positie, lap-tijd en finish over het spelbeeld heen. Op het scherm in de gang draait dezelfde data, maar dan als rotating leaderboard. Coureurs, Constructeurs, en een live-view tijdens een race.
- 04
QR-code, naam, klaar
Zodra je over de finish komt verschijnt er een QR-code op het scherm. Scannen, naam en bedrijf invullen, en je tijd is geclaimd. MongoDB doet de rest.
Wat we nu lezen
Volgt 0x809B8F70 naar de Raceinfo-struct, dan de spelers-array, dan completion. Live wanneer er gespeeld wordt, anders het laatst geziene snapshot.
Hex en wat het betekent
Wat eruit komt zijn een paar bytes. Wat het betekent staat ernaast.
80 5A 7F 30 00 00 00 04 00 00 00 02 3F 80 00 00 40 40 00 00 00 00 01 0C
- Pointer
0x805A7F30 - Position
4 - Lap
2 / 3 - Completion
3.000 - Frame
268