Live data from Hacker News

A Comprehensive Super Mario Bros. Disassembly

gist.github.com

51–60 of 87 posts

Re: A Comprehensive Super Mario Bros. Disassembly

#51
post #45
post #23

Earlier quoted context omitted.

Same 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 th…

That'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

That'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

Part 2: https://www.youtube.com/watch?v=f1kbABTyeo8

Re: A Comprehensive Super Mario Bros. Disassembly

#52
post #3

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…

I 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.…

I may be missing something, but how is that not "actually calculating velocity"?

Re: A Comprehensive Super Mario Bros. Disassembly

#53
post #26

Earlier quoted context omitted.

And 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.

I 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?

Super 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://www.reddit.com/r/MarioMaker/comments/4iqa5s/super_ma...

Re: A Comprehensive Super Mario Bros. Disassembly

#54

Earlier quoted context omitted.

I 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.…

I may be missing something, but how is that not "actually calculating velocity"?

That is, instead of using y velocity = acceleration * time and then adding in gravity, they made something like this, as I understand it:

speeds = [0, 1, 2, 4, 8, 4, 2, 1, 0]

And then you keep track of how many frames it's been since you jumped, and then just do

yVelocity = speeds[ticksSinceJump]

No math needed at all.

Re: A Comprehensive Super Mario Bros. Disassembly

#55

Earlier quoted context omitted.

I 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.…

The second game, melee, definitely had a more traditional engine running it, too many ~bugs~ fantastic features to have been taking advantage of lookup tables.

Are you thinking of Super Smash Bros.? This is Super Mario Bros. for the NES, over a decade older :)

Re: A Comprehensive Super Mario Bros. Disassembly

#56
post #32

Earlier quoted context omitted.

> it is not uncommon to reduce the number of conditionals for better CPU pipelining, and lookup tables are a very common tool for this. On modern CPUs, data dependency, such as lookup tables often cause pipeline stalls — worse pipelining. L1 cache is at a premium as well, you rarely want to waste it to access LUTs. You can compute a lot in 12 cycles caused by L2 hit (L1 miss). In theory up to 32 * 12 = 384 floating p…

To be fair, replacing a series of ALU ops with a lookup table doesn't usually add a "data dependency" - the data dependency probably already existed, but perhaps flowed through registers rather than memory. What adding a lookup table can do is to add the load-latency to the dependency chain involving the calculation, which seems to be what you are talking about here. For an L1 hit that's usually 4 or 5 cycles, and fo…

> To be fair, replacing a series of ALU ops with a lookup table doesn't usually add a "data dependency"

If it's not vectorizable, LUT result is often used for indirect jump/call (like large switch statement) or memory access (say, a histogram etc.).

> What adding a lookup table can do is to add the load-latency to the dependency chain involving the calculation, which seems to be what you are talking about here.

Yeah, used a bit sloppy terminology. Loads can affect performance system wide. To be a win, LUT function needs to be something pretty heavy, while LUT itself needs to be small (at least > If the method is really hot, e.g., in a tight(ish) loop, then you are mostly going to be getting L1 hits.

That really depends. It's generally good to keep L1 footprint small. There are just 512 of 64-byte L1 cache lines. Hyperthread shares L1 as well. There can be other hot loops nearby that could also benefit from hot L1. It's very easy to start to spill to L2 (and further). Microbenchmarks often miss "system" level issues.

> The comparison with 384 FOPs seems a bit off

384 was for the extreme vectorization case, 12 x 2 x 8 FMACs (AVX). Most vendors count FMACs nowadays as two FOPs...

> If it's vectorization, then the whole equation changes

Well, isn't that where the performance wins are and what you need to do to extract maximum performance from that hot loop? A good truly parallel vector gather implementation could make (small) LUTs very interesting performance wise.

Re: A Comprehensive Super Mario Bros. Disassembly

#57
What 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.

Re: A Comprehensive Super Mario Bros. Disassembly

#59

I 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 ho…

The 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.

Re: A Comprehensive Super Mario Bros. Disassembly

#60
post #3

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…

I 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.…

When I wrote Atari 800 Donkey Kong, I used 16-bit precision arithmetic for the motion, with pretty good results. All the jumping was done with a horizontal velocity, a vertical velocity and a vertical acceleration. A jump is just setting Mario's vertical velocity to some value, and you need to do floor collisions (but you want those anyway, so other objects can interact with floors).

There was a funky "bounce" at the edge of the screen in the arcade version that I captured pretty well by reversing X and Y velocity on a wall collision; this could not have been done well with a lookup table. It wasn't that much code, and the simple parameter space made playability tuning really easy.

Post reply on HN