10 ms·
A Comprehensive Super Mario Bros. Disassembly
- zxy_xyz 9y agoIs the gameplay logic in a different file or did i miss something?
- psyc 9y agoIt's all in there. Probably start with PlayerCtrlRoutine.
- jordigh 9y agohttps://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L6011 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L601... I think this is where the real gems start. The biggest contribution that SMB had was the "physics engine", to retrofit a modern term. The friction, the jumping, the inertia. If you compare it with the primitive physics in Donkey Kong or Mario Brothers, you can really grasp the groundbreaking novelty that was SMB. You can change direction in mid-air, but not too much. When you run, you skid if you try to run in the opposite direction. The height of your jumps is affected by your running speed. It's all of these little details combined, barely noticed in tandem, which made the game new and fun.
- davidscolgan 9y agoI once read that the way SMB was able to pull off the physics engine on such limited hardware was that it used lookup tables for physics instead of actually calculating velocity. My assembly-fu is weak but it looks like your link is to the section that contains all the lookup tables. I think JumpMForceData for example is a series of offsets for each successive frame after you hit the jump button. https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L6116 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L611... This line shows the calculation that makes use of the JumpMForceData.
- dieterrams 9y agoLookup tables were indeed a common technique used by games in the past.
- asveikau 9y agoAnd present, too, right? It's not the same reason as it would have been in the 80s, but today in performance critical code it is not uncommon to reduce the number of conditionals for better CPU pipelining, and lookup tables are a very common tool for this.
- derefr 9y agoI have a strong feeling that Super Mario Maker always has the same physics engine going, but just has four different lookup tables that it switches between depending on the level theme. Anyone want to partially disassemble it for comparison?
- ageitgey 9y agoSuper Mario Maker uses "New SMB" physics for all themes. It doesn't actually mimic the exact physics of each game (aside from small tweaks like not letting you wall-jump or carry shells depending on the theme). They did this because newer players found it super confusing to go back to the older physics. From Takashi Tezuka: > “In the end we used the New Super Mario Bros. U system for all of the game styles. There was quite a lot of discussion about this within the team. Staff who had strong attachment to the original games expressed a strong desire to see implemented the same system they remembered. However, when players who are used to the modern Mario physics tried playing with the old physics, they found it much more difficult than they remembered." People on reddit have done some pretty extensive breakdowns of the physics of different Mario versions vs. SMM: - https://imgur.com/XC38rcX https://imgur.com/XC38rcX - https://www.reddit.com/r/MarioMaker/comments/4iqa5s/super_mario_world_physics_another_reason_why/d310ay5/ https://www.reddit.com/r/MarioMaker/comments/4iqa5s/super_ma...
- vardump 9y ago
- corysama 9y agoI'll plug the book http://www.game-feel.com/ http://www.game-feel.com/ here because it has a 28-page chapter devoted to the physics of SMB.
- james_hague 9y agoNot platformers I realize, but lots of outer space games with actual acceleration/velocity calculations preceded SMB. Off the top of my head: Lunar Lander (1979), Asteroids (1979), Defender (1981), Gravitar (1982), Sinistar (1982). Just want to keep the history straight. Several of these modeled gravity as well.
- blt 9y agoUsed to have a Gravitar clone for DOS. It was one of the harder games I've ever played :)
- tomduncalf 9y agoThis seems like a really impressive effort to make sense of all this! Would the original game have been written in assembly? And if so, would the source have looked similar to this? Having never touched assembly language (aside from learning some very basic cracking many years ago swapping JE for JNE in the serial check routine, haha), it seems like a true dark art to me, so I’m really curious to know!
- Kelbit 9y agoYes, the original game would have been written in 6502 assembly, and probably would have looked something like this. The label names and defines would have been different, since the ones in this file are the interpretation of the person who did the disassembly.
- bluedino 9y agoYes, the original NES games were written in assembler. However, the source probably didn't look quite like this. I'd guess the assembler of the time didn't have as many features or things like long label names. Here's some actual Atari 7800 (a less popular console from the same generation) code that was found on disks in a dumpster when some Atari offices closed. They both use a 6052-based CPU but have very different sound/graphics chips. I'd bet the NES code looked a lot more like this - https://github.com/OpenSourcedGames/Atari-7800 https://github.com/OpenSourcedGames/Atari-7800
- aquova 9y agoYes, all old NES games were written in 6502 assembly (named after the NES's 6502 processor), and even most games into the Super Nintendo and Game Boy days were written using assembly language. The source would've looked very similar to this, although I can assume the original labels would've been in Japanese. The difficulty in creating a disassembly like this isn't converting the machine code back into assembly, which can be done rather simply, but instead re-adding all the label names, which are lost when the game is built. It's quite the undertaking, and the author must know the complete game back to front.
- Pulcinella 9y ago
- 1zael 9y agoThis is insane.
- khedoros1 9y agoThere's also a Legend of Zelda disassembly, but it's not as nice: https://github.com/camthesaxman/zeldasource https://github.com/camthesaxman/zeldasource It's a much larger game, though. I haven't checked, but I'm assuming that a lot of the giant chunks of statically-defined data are just graphics and audio (unlike many games, LoZ stored graphics interspersed with the program code and copied data over to an in-cartridge RAM chip, instead of storing the complete graphics data in a ROM chip.)
- derefr 9y ago> unlike many games, LoZ stored graphics interspersed with the program code and copied data over to an in-cartridge RAM chip, instead of storing the complete graphics data in a ROM chip This is because Zelda 1 was a port from the Famicom Disk System—no memory-mapped ROM chip to rely on, so you've got to load everything you're going to use to RAM. (Also like this: Metroid.) I believe this is why both LoZ's and Metroid's maps are built out of individual "screens" with a "pause to transition" effect between them: in the FDD version, the game would be reading the new map from disk, and there'd (sometimes, if the load took long enough) be a loading screen involved. (You can see the screen for LoZ here: http://tcrf.net/The_Legend_of_Zelda/Console_Differences#Loading_Screen http://tcrf.net/The_Legend_of_Zelda/Console_Differences#Load...)
- khedoros1 9y agoCool, I never dug in to see why they were that way, but those were both test cases when I built an NES emulator.
- wgrover 9y agoLooks like data for the various songs here: https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L16027 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L160... I'd love to see the process of extracting actual audio from that.
- strangecasts 9y agoThe NES had a memory-mapped APU[1], so the game just sets sound registers to play the appropriate notes, and ticks down a timer until it's time to switch to the next note: https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L15610 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L156... [1] https://wiki.nesdev.com/w/index.php/APU https://wiki.nesdev.com/w/index.php/APU
- earenndil 9y agoThere're tools that can extract audio from snes roms, I'm sure there's something similar for nes.
- segmondy 9y agoThe entire game in 16,000 lines of assembly code. :-)
- looperhacks 9y agoYou might also be interested in the dissambly of the first pokemon games: https://github.com/pret/pokered https://github.com/pret/pokered And some other pokemon games: https://github.com/pret/pokered#see-also https://github.com/pret/pokered#see-also
- raldi 9y agoCheck out the section under "DemoActionData": this is where it stores (and plays) the demo you see when you don't push Start and Mario runs around on his own volition. It just simulates player input and runs it through the regular game engine. (The alternative, playing a recorded video, would have been laughably data intensive.)
- dEnigma 9y agoSame thing goes for Super Mario 64. The popular TASer pannenkoek actually explored whether it was possible to manipulate Demo-Mario's starting position in such a way that he collects a star with the demo input (this was for the purposes of special "A-Button Challenge" speedruns, where pressing the A-Button must be kept to a minimum, but since the demo input isn't actual player input it isn't counted) Sadly I think there was no conceivable way to do it. (i.e. manipulating the starting position is possible, but not in a way that leads to collecting a star) https://youtu.be/-0emgkIEobI https://youtu.be/-0emgkIEobI
- opdahl 9y agoThat's an amazing youtube channel. Here [1] the creator describes in an over seven-minute long video the intricacies of Mario falling asleep. [1] https://www.youtube.com/watch?v=7OtW-LLZ2OA https://www.youtube.com/watch?v=7OtW-LLZ2OA
- dEnigma 9y agoThat's nothing! He has two videos on walls, floors and ceilings, each longer than half an hour (and both of them extremely interesting) Part 1: https://www.youtube.com/watch?v=UnU7DJXiMAQ https://www.youtube.com/watch?v=UnU7DJXiMAQ Part 2: https://www.youtube.com/watch?v=f1kbABTyeo8 https://www.youtube.com/watch?v=f1kbABTyeo8
- camhenlin 9y agoFor people interested in the SMB disassembly, you may also be interested in this one: http://bisqwit.iki.fi/jutut/megamansource/ http://bisqwit.iki.fi/jutut/megamansource/ NES MegaMan disassembly, with some comments
- webXL 9y agoI love stuff like this. Seeing the disassembly somehow adds to the nostalgia for a childhood pastime. What's this endlessloop for: https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L712 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L712 (Yes, please ;)
- jepler 9y agoYou can see that just above the endless loop, the code will "enable NMIs". I'm not sure about the nomenclature here (because normally NMI stands for non-maskable interrupts, meaning you can't disable them) but basically the game at this point becomes event (interrupt) driven, probably from the vertical retrace interrupt or another kind of timer interrupt. When no event is being handled, the CPU idles within this endless loop.
- jepler 9y agohttps://wiki.nesdev.com/w/index.php/PPU_registers#Controller_.28.242000.29_.3E_write https://wiki.nesdev.com/w/index.php/PPU_registers#Controller... states that bit 7 of the register at $2000 (which they call PPUCTRL, and this disassembly calls PPU_CTRL_REG1) will "generate an NMI at the start of the vertical blanking interval"
- salqadri 9y agoTu tu tu turuturu turuturutururur...
- binarymax 9y agoI love that this is just a gist. Like 'hey just needed to copy and paste this for a minute'
- DonHopkins 9y agoI wrote this earlier on another forum but I'll repost it here: I've seen Shigeru Miyamoto speak at several game developer conferences over the years. He's absolutely brilliant, a really nice guy, and there's so much to learn by studying his work and listening to him talk. Will Wright calls him the Stephen Spielberg of games. At one of his earlier talks, he explained that he starts designing games by thinking about how you touch, manipulate and interact with the input device in the real world, instead of thinking about the software and models inside the virtual world of the computer first. The instantaneous response of Mario 64 and how you can run and jump around is a great example of that. Shigeru Miyamoto GDC 1999 Keynote (Full): https://www.youtube.com/watch?v=LC2Pf5F2acI https://www.youtube.com/watch?v=LC2Pf5F2acI At a later talk about how he designed the Wii, he said that he now starts designing games by thinking about what kind of expression he wants it to evoke on the player's faces, and how to make the players themselves entertain the other people in the room who aren't even playing the game themselves. That's why the Wii has so many great party games, like Wii Sports. Then he showed a video of a little girl sitting in her grandfather's lap playing a game -- http://youtu.be/SY3a4dCBQYs?t=12m29s http://youtu.be/SY3a4dCBQYs?t=12m29s , with a delighted expression on her face. The grandfather was delighted and entertained by watching his granddaughter enjoy the game. This photo -- https://i.imgur.com/zSbOYbk.jpg https://i.imgur.com/zSbOYbk.jpg -- perfectly illustrates exactly what he means! Shigeru Miyamoto 2007 GDC Keynote - Part 1: https://www.youtube.com/watch?v=En9OXg7lZoE https://www.youtube.com/watch?v=En9OXg7lZoE Shigeru Miyamoto 2007 GDC Keynote - Part 2: https://www.youtube.com/watch?v=jer1KCPTcdE https://www.youtube.com/watch?v=jer1KCPTcdE Shigeru Miyamoto 2007 GDC Keynote - Part 3: https://www.youtube.com/watch?v=SY3a4dCBQYs https://www.youtube.com/watch?v=SY3a4dCBQYs Shigeru Miyamoto 2007 GDC Keynote - Part 4: https://www.youtube.com/watch?v=jqBee2YlDPg https://www.youtube.com/watch?v=jqBee2YlDPg Shigeru Miyamoto 2007 GDC Keynote - Part 5: https://www.youtube.com/watch?v=WI3DB3tYiOw https://www.youtube.com/watch?v=WI3DB3tYiOw Shigeru Miyamoto 2007 GDC Keynote - Part 6: https://www.youtube.com/watch?v=XvwYBSkzevw https://www.youtube.com/watch?v=XvwYBSkzevw Shigeru Miyamoto Keynote GDC 07 - Wife-o-meter: https://www.youtube.com/watch?v=6GMybmWHzfU https://www.youtube.com/watch?v=6GMybmWHzfU
- notaboutdave 9y agoThe Miyamoto approach of starting with a desired emotion and working backward toward a design is profound. This is radically different from most things I've read which involve cramming emotion into existing designs. This changes everything for me. Thanks for sharing.
- DonHopkins 9y agoHow I love the sleek smooth razor sharp columns of three letter 6502 opcodes. The right edge of columns of opcodes in other instruction sets look so rough and jagged like sandpaper in comparison. That's what I've always hated about x86 code. It looks rough and torn.
- andyjohnson0 9y agoNice observation. Its 35+ years since I last did any 6502, and this morning teenage-me looked at those opcodes and smiled a little.
- justin_ 9y agoI remember using this disassembly many years ago when writing a little NES emulator. Having a reference available for a popular game is incredibly useful. Here's one of my favorite parts: https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L942 https://gist.github.com/1wErt3r/4048722#file-smbdis-asm-L942 The byte here is for the BIT instruction, but why is it just a lonely byte? Well, the BIT instruction in this case also includes the two following bytes. When the game processes that instruction, the `ldy #$04` is swallowed up as part of the BIT instruction, effectively skipping over it. IIRC this was a pretty common trick used among 6502 programmers. It allows you to jump ahead over the next (2byte) instruction with just a single byte!
- MBCook 9y agoIs there a version of this somewhere that people have changed it to C or some other higher level language for easier skimming? I’d love to see that. (Yes, I know it was written in ASM).
- x3ro 9y agoIn case anyone else is trying to re-assemble this into a working game, here's one way to do it :) https://github.com/x3ro/super-mario-bros-build https://github.com/x3ro/super-mario-bros-build
- KGIII 9y agoWhat is the goal of a project like this? I'm absolutely not meaning that as a pejorative. I am just curious if there's an actual goal here. Is the goal to make a faithful reproduction, historical reference, a hacking challenge, or? Is it just curiosity? I see lots of links in the thread, many for different games. Curiosity is as valid a reason as any other, but is there some sort of end result trying to be had? The various links don't actually seem to enumerate this very well, unless I missed it.
- PyroLagus 9y agoIt has many uses really. It's a nice resource for learning assembly, especially 6502 assembly; it's a good reference for creating NES games, whether those are original titles or simply romhacks; it's also a great reference for building an emulator for the platform or a level editor for the game. And of course, disassembling a game and documenting the source code is a great hacking challenge that will leave you confident that you know asm. So, all the reasons that you listed, I suppose.
- KGIII 9y agoI can also understand a 'just because' answer. I was just curious if there's a greater goal. I'm not a gamer but I do kind of pay attention to some aspects.
- indescions_2017 9y agoMaster list of SMB glitches makes a nice companion to this. Sorry in advance if it results in anyone staying up well past their bedtime ;) https://www.mariowiki.com/List_of_Super_Mario_Bros._glitches https://www.mariowiki.com/List_of_Super_Mario_Bros._glitches
- laurent123456 9y agoThat'd be great if someone knowing the disassembly well enough could explain some of these glitches, for example the Minus World[0]. I guess the logic (or bug) to active this appears somewhere in the disassembly. [0] https://www.mariowiki.com/Minus_World https://www.mariowiki.com/Minus_World
- LocalH 9y agohttps://www.youtube.com/watch?v=Hv_h_R3o9r8 https://www.youtube.com/watch?v=Hv_h_R3o9r8
- jzl 9y agoBen Fry, the creator of Processing, created a beautiful visualization of the disassembled machine code of Super Mario Bros with arrows representing jump instructions: http://benfry.com/dismap/mario-large2.jpg http://benfry.com/dismap/mario-large2.jpg via: http://benfry.com/dismap/ http://benfry.com/dismap/ I've always loved this as a visualization of machine code. It's simultaneously amazing how complex it is and yet how simple it is when you consider that it represents the entire game all in one graphic. This is from 2007 I believe. I love that 10 years later the machine code is now fully annotated and understood.
- retSava 9y agoWow, that is amazingly complex! It's beautiful, in a way. I tried to see if there was something very central, called from lots of places, but there doesn't seem to be any such place. There are a few, but not something singular that stands out as completely dominant. Long jumps get a more dominant visual appearance than short jumps. Would be interesting to see what it would look like with the address printed in size proportional to eg how many places call it, or how CPU intensive that subroutine is, etc.
- retSava 9y agoAlso check out the other example dismap shows: Excitebike! Much fewer and longer subroutines. Interesting, I wonder if that in turn is mostly a result of developer coding style differences, or a result of game mechanics being different.
- 7scan 9y agoI also have a makefile and game genie code generator for this on github: https://github.com/nwoeanhinnogaehr/smb-assembler https://github.com/nwoeanhinnogaehr/smb-assembler
- kchr 9y agoLots of retro game reverse engineering stuff on HN lately; please continue this trend :-)
- andyjohnson0 9y agoI'm not familiar with the history of this work, so I'll just ask. Is this the assembler code that was written by the original dev team, or were the comments reverse-engineered from a dissassembly of the game's machine code?
- thristian 9y agoIt's a "disassembly", so it's the work of somebody converting machine code back into assembler, and studying it long and hard to add comments, break out numbers into sensible-named constants, and choose decent names for loop labels. The original dev team was almost certainly not involved.
- andyjohnson0 9y agoThanks for the clarification. Given what you've said and the size of the thing, this is an awesome piece of work. The level of detail and perseverance required is enormously impressive.
- tinus_hn 9y agoI love how the ‘author’ expresses his thanks for everyone and his dog, except for the people at Nintendo who actually wrote the code.