A Deep Dive Into Super Mario 64’s Memory Misadventure

Super Mario 64, released in 1996, is a nostalgic classic for many, but there’s a shocking truth beneath the surface: the game is memory hungry. Thanks to the work of modder Kaze Emanuar, we get to see how this legendary Nintendo 64 game used its 4 megabytes of RAM in ways that were, at times, surprisingly wasteful.
Emanuar’s investigation begins with the game’s RAM map, a blueprint of how Super Mario 64 organizes its data at runtime. The Nintendo 64’s 4 megabytes of fast RDRAM had to hold everything: textures, code, music, output buffers and actor states. To put that in perspective that’s roughly the size of a single modern smartphone photo. In levels like the Castle Grounds memory was so tight that adding two small textures would crash the game. Yet despite this constraint Emanuar found that significant portions of that precious memory was wasted due to coding oversights, unused data and inefficient design choices.
LEGO Super Mario: Mario Kart – Mario & Standard Kart Building Set for Adults – DIY Book Shelf & Room…
- HERE WE GO! – Speed down Rainbow Road with the LEGO Super Mario: Mario Kart – Mario & Standard Kart (72037) collectible building set for adults 18…
- DYNAMIC DISPLAY STAND – Position Mario at dramatic racing angles to recreate that perfect drift moment or high-speed action from your favorite Mario…
- POSEABLE MARIO FIGURE – The brick-built Mario features movable head and arms, letting you customize his racing pose for the ultimate display
One of the biggest issues is with the frame buffers which store the visual output at 320×240 with triple buffering. These buffers take up the last half megabyte of memory but include black bars at the top and bottom of the screen to accommodate old TVs’ overscan issues. These bars are always drawn and waste space equivalent to about three Mario 64 textures. By overlapping the buffers or reducing the rendered image to 224×320 the developers could have saved enough memory for more visual details but this was missed likely due to time constraints or lack of necessity.
More inefficiencies are found in the memory layout, as programmers manually assigned memory addresses leaving empty spaces between data portions. One such gap at 275 kilobytes is equivalent to about 23 textures worth of unused memory. Another 224 kilobyte empty space is equivalent to 73 textures and appears to be a simple memory allocation error. These voids which total 93 textures worth of space are a huge waste. If the compiler had been allowed to optimize memory placement, these gaps could have been closed and given room for more assets or smoother performance.
The engine element, which interprets level and actor scripts, is another source of waste. This code takes up an eighth of a megabyte and was written with debugging in mind not efficiency. According to Emanuar, compiling for size could cut this down by half and deleting unnecessary code (like the remains of a cancelled split-screen multiplayer mode) could reduce it by another 50%. This would have given room for dozens of textures or performance enhancing techniques like memory banking, thus giving the game a 5% speed boost.
Math functions, especially the sine and cosine tables, cause memory bloat. These tables are crucial for 3D rendering and have data for one and a quarter circle rotations. By using circular symmetries the table could have been quartered, saving 12KB – enough for 4 new textures and slightly speeding up the game.
Another example of inefficiency is the music system which takes up 512KB. Super Mario 64 collects notes and instruments and mixes them at runtime to create the music. But because they didn’t reuse buffers properly the game allocates 4 sample buffers per note when only 1 is needed. This uses up 51KB of memory which is 17 textures. Emanuar’s own code showed that 18% of the music area (about 31 textures) is unused and filled with zeros. These audio inefficiencies account for 40 textures worth of wasted space.
The most surprising waste is in the memory pool, which holds geometry, textures and collision data for levels and actors. Each actor, even simple objects like stationary geometry, is allocated 608 bytes regardless of complexity. This uniform allocation is unnecessary bloat. The game loads entire memory banks including irrelevant objects like seaweed or water mines when only 1 item is needed. Later games like The Legend of Zelda: Ocarina of Time loaded data per room to minimize waste. Uncompiled collision and armature data loaded once and never used again further bloats the pool with Mario’s armature alone taking up 11.6KB of dead memory. Emanuar estimates a 33% reduction in this pool’s size saving about 483KB or 143 textures worth through better data management.
Adding all of this up, Emanuar believes Super Mario 64 may lose roughly 2 megabytes of its 4 megabyte footprint. It doesn’t quite fit in the PlayStation 1’s 2 megabyte RAM, but the PS1 has separate VRAM for frame buffers and CD-based audio storage, so it could be done with some more modification. For example, reducing the actor pool limit by 60 objects (without affecting gameplay) might reduce the game’s RAM usage to 1 megabyte, which is outstanding for a game of this scale.
[Source]
A Deep Dive Into Super Mario 64’s Memory Misadventure
#Deep #Dive #Super #Mario #64s #Memory #Misadventure