Just an FYI cause it's coming up a lot in the comments, this is indeed a re-upload of the video I released last month. Sorry it took so long to get back up!
@@JustAlfy nobody remembers (based on the comments on the text post he made after removing it), which just goes to show how silly and innocuous it was in the first place ¯\_(ツ)_/¯
It's so, so huge. Floating point co-processors were an extremely advanced feature for a computer to have all the way up to like 5th generation consoles (the PSX didn't even have one from what I understand!).
@@NesHacker yep, I worked on a few Nintendo DS games and it didn't have a floating point coprocessor either. It had a coprocessor to handle integer division and square root, everything else was done in fixed point. You could do floating point but the compiler would translate float operations into integer operations, which was very very slow.
The N64 had floating point hardware, but still often used fixed point to represent angles, among other uses, though you could argue that it's not really fixed point because it's not really a number of integer bits and a number of fractional bits, and more just an abstract angle unit between 0 and 65535, where 32768 is simultaneously 180° and π. Wrapping integer arithmetic can be really handy when the unit you're using wraps around anyways (65536 angle units = 360° = 2π = 0).
@@angeldude101 that's just a matter of user library though, there's nothing in the platform itself that tells you to use trig functions with that convention for angles. How vertex buffers are sent to the RSP (the gpu) is a totally different question and in the case of the N64 they indeed used fixed point coordinates. Of course it's easier and faster to do all the transforms in fixed point and use floats only for texture decoding (the jpeg reference decoder uses floats for example) and other stuff which are not directly tied to the hardware.
You don’t know how much this helps me. I’m currently writing a platformer (or at least trying to) and I never had so much trouble programming something as with implementing the controls. Those techniques will definitely make it easier for me to do that. Thank you!
I started testing platform physics back with XNA on 360. I started with learning Mario physics and the concept of subpixels. Once I figured all that out it was onto collision detection which can be just as tough as physics.
This such a cool demo. Also, SMB3 is both the game that got me hook line and sinker, into video games as a lifelong pastime. The controls in this game weren't just tight, they defined the concept of 'tight' in video game controls. If the game wasn't smb3 and wasn't 35 years old, it could be reskinned and published on steam by a good Indy studio, and we'd all be none the wiser about it's age. Super cool to see the tech demo'd for that, and as a person that has 'make an honest run at a gamedev project someday' on my bucket list, this is the coolest video i've stumbled upon in a long while. I'm glad I re-found the channel, I love this stuff!
That's such high praise, thank you so much! I had an absolute blast programming the demo and picking apart the movement in SMB3, and it's awesome to hear from someone who enjoys the game and it's craftsmanship at least as much as I do :)
Dude, you're actually the most interesting content creator that I know ! I could listen to you for an entire decade in a row... I'd like to express my extreme gratitude to you and wish you all the best too. Can't wait to discover your next video.
It’s really mind blowing how programmers did all this math in assembly, with no float point calculations and essentially had to write their own math rules. Programming took a different kind of genius back then, especially to pave the way and come up with all of this as a standard for things like movement.
Im a physics student, and i love computers but ive never really had the interest for coding until i neede it for my career, thats when i realize that coding is a god damn combination of art and math. My respect goes to every coder out there
This video was made with love and care, and information, and it shows. I didn't even have to understand everything you said to reach to that conclusion. Thank you. New subscriber.
Great video! This format certainly is working for you, and I’m sure you’ll keep making polished content, but I’m also sure your fans would appreciate slowly paced deep-dives, even if they’re far less scripted/formal!
So currently, I am actually writing a 6502 assembler and linker in Rust cause I think it would be fun! Seeing your code keeps giving me ideas to support more features in my assembler!
Just wanna say thanks for inspiring me. This was the video that kicked off an adventure of mine where I started programming a platformer for the NES. It took a while, and I did eventually get to have way more detail and features than the open source demo you gave (music, verticle and horizontal scrolling, detailed animations, etc) but I never would've gotten started without your demo. Thank you.
1:49 My answer: Use fixed points, so basically you have an integer but then you add a decimal point somewhere in the middle, there are also floating points that are used in almost every new modern game nowadays but old consoles don't support those. edit: Oh also subpixels are basicaly fixed points
Oh my god thank you. There are so many game design videos out there that go over concepts of game design - and that's fantastic - but to have one that _actually_ delves into the coding aspect, how to apply that knowledge, is something I've wanted for a long time. This might be one of my favorite channels in recent years
This might be your best video so far. To be sure, you need a deep enough understanding of ASM6502 to really absorb the content, but once you have it, this video hits the mark pretty much across the board. (It's definitely my favourite of your videos... so far!) Well done!
Hey. thank you so much! I really enjoyed making it and had a feeling I was striking a good balance between high level concepts and low level technical details when I was making it :)
The NES used a Rocoh 2A03 processor which was basically a 6502 with binary coded decimal disabled. The cool thing was that NES and the Commodore C64 shared the same CPU, so if you knew one it was fairly easy learning to write code for the other (except for the PPU/VIC-II respectively).
I always go into your videos with high hopes of following everything and inevitably half way through get lost. Glad I can cheat and code the same effect in Unity much more easily
Don't give up! ASM6502 is definitely challenging but not impossible. I still find I'm rewatching these kinds of videos multiple times before I "get" it. Also, I wouldn't be afraid to throw some questions in the comments. Judging by the remarks of others, you'll probably get a reply that helps you out.
I nearly understood the content, and appreciate it's been a lot of amazing work compressed into 10 minutes. But the quick jumps between content distracted me from your narration which may have been fine had RUclips not had that annoying shade on pause feature meaning it was very hard to read the text.
So this is the reupload where you have thrown the frog out.😄 BTW, I have just become one of your patrons. Your videos are excellent and really helpful, so I wanted to support you.
Ayo this is sick! I actually made some similar findings as the things mentioned in this video when I tried to remake Mario3 in the Godot game engine. Didn't look at the game's original code at all, I just captured Mario 3 footage, did frame-by-frame analysis and extrapolated a lot of stuff from there. I KNEW there must've been a set timelimit for how much you can hold the jump button and it affecting the "Gravity" applied on Mario! My estimate was 23Frames, the formula that i came up with didn't exactly line up with how many pixels Mario moved upwards per frame visually, So i went with 23 despite having a gut feeling on 24. Some things i just couldnt extrapolate precisely just by analyzing footage so i did wing it for a bit, arrived to 90px/sec or 1.5px/F as Mario's First Maximum Speed, and that it took him 20Frames to reach that Speed, so i went with 4.5Speed/F for Acceleration, and -3.5Speed/F for Friction. Dont quite remember the Friction Value i used for when Mario presses the opposite direction while moving, though. I also made Mario's TopSpeed a threshhold that changed depending on certain conditions, TopSpeed 1 is just when Mario moves, TopSpeed 2 (2.5px/F) unlocks when Mario has reached TopSpeed 1 and is pressing the Run button, and TopSpeed3 (3.5px/F) unlocks when filling the "P-Meter" by having stayed at TopSpeed2 for a certain amount of time. JumpHeight is also intertwined with Mario's Horizontal Speed in this game, so I assumed the game used a simple equation for that, I could never get it super accurate, just a decent approximation with irregularities between the JumpHeight in my game and the one in Mario3, so i assume there is something i was missing there. I did get Mario's FullJump at 0Speed to be 70pixels in height, and 101pixels at TopSpeed3, which i think is accurate, it's JumpHeights between 0 and TopSpeed3 that had inaccuracies. I'm happy I arrived at a fairly accurate Gravity, FallingGravity being 5times stronger than JumpingGravity was correct, let's go. I felt like the internet was trying to gaslight me into accepting that FallingGravity was 3times stronger, glad to have gone with my gut with that one. Also, I'm not crazy by thinking that Mario's feet and body have 2 separate collisions right? Mario's Body slides off edges, and his Feet are just a really precise rectangle, or at least that's what i gathered from my testing. Anyway, keep it up man, this is fascinating information you're sharing with us, thank you.
Wuhhh, you that sounds like a lot of work you did, good job! As far as the hit detection is concerned I don’t know, I haven’t really dug into it for this game 🤔
@@NesHacker @@NesHacker I Made a ton of little discoveries with that Project, some of which i don't think are documented anywhere, nowhere i could find them anyway. Things like jump edge correction being 4pixels, and the Game teleporting Mario on top of platforms he misses by 4pixels(?) of height, or that Mario changes to his Jumping Sprite without leaving the Floor for a single frame, this means Mario has a single frame of preJump, Mario is unaffected by Gravity in this particular Frame, so i guess You could argue Mario3 has coyote time if You do a frameperfect jump off a ledge. Sorry for rambling, i found an excuse to share these things so brain going nerd mode rn.
Very cool video Ryan! I didn't realize Mario was running in 60FPS! Love the way that you really break down the math and science behind the animation in Super Mario Bros 3.
Been (inconsistently) trying to study to become a software developer one day for a while now, and every now and then I’ll come across a video like this where it looks interesting and something I want to learn about but once I click and start watching I quickly realize that I’ll never be smart enough to actually understand any of it. This is all just goes way over my head.
I mean a couple of things here… One, this is a pretty math heavy concept I’m talking about here and it is for a very old system. This means that it’s not fully relevant to modern programming. And two, while some folks may be more naturally inclined for programming it’s not like they could magically just do it. It takes effort and years of practice to be a solid developer. I’ve went to college for CS and have been programming for thirty years. The first five of which I was pretty bad tbh 😂
On top of speed being in subpixels/frame, SMB1 and SMB3 (+ most likely others) also have a subspeed, a further division of speed into 16 units used when accelerating. Mario has a variable acceleration depending on the situation (in SMB1, he famously accelerates twice as fast backwards since he was made to slow down faster than he speeds up), so the subspeed tracks 16ths of a subpixel per frame and is truncated in the speed calculation. Certain speedrun tricks require subspeed manipulation, in the sense that Mario can move ever so slightly more in the same amount of time if he accelerates from 0.9375 than if he accelerates from 0.0000 speed. I don't remember the exact numbers, but his speed on every frame might look like 0, 2, 4, 5, 7, 8... instead of 0, 1, 3, 4, 6, 7... Over the course of a full acceleration from standing still to full speed, this could add up to a full frame's worth of extra distance, or 3 extra X pixels (4 with positional subpixel manipulation) on the screen after doing a bump on a block to set up a wrong warp!
It’s absolutely astounding to me what the speed running community gets up to when pushing the limits of this and so many other games. Honestly watching runs and demos gets me so pumped to go into the games and figure stuff out for myself 😊
That is not really the case in SMB3 though, Bismuth. Or at least that's the first I ever hear about it. Though it's not fully true that Mario always accelerate at a speed of 1 unit/frame. You are unable to accelerate to the right on the frames when address 055C is at 0 or 1, and E and F for left. This address is independent on what Mario's speed is at that time, nothing else; to my knowledge, tracks Mario's speed other than 00BD which is always consistent. Other exceptions to 1px/frame is when you have a speed >0 and press left, at which you'll always move 2 speed units/frame, and vice versa for the other direction. Then things like being on a slope will be different or while being Frog Mario. All of which ignore the 055C address. But yeah, Bismuth, not sure what you mean in this case actually =/. Though I'll love if you fill me in!
@@TompaA I may have conflated the two here. I was almost positive if the mechanic existed in SMB1, it had to in SMB3 as well. I figured that it existed but I didn't remember it coming up as particularly important in speedruns, but thinking back on it, it probably wouldn't have been reset on every level, so it would have affected wall clips like subpixels do. Interesting that SMB3 did away with subspeed!
"Fixed point math" is a new word to me. And I think I've been doing a bit of it in my own code. I've been writing a game engine where I try to avoid use of floating point numbers. Not 100% , but the basic hypothesis is that it's easier to figure out anti-aliasing when your math is "pixel-perfect" or... for lack of a better word... "fence-post-perfect" as in "not even off by 1".
I’ve been looking for an explanation of how keyframe animations are actually written, so this is incredibly helpful! I’m going to dig into your sample code but I’d love to see a whole video on it in your signature style. Huge, huge fan of your channel.
-3:14-- The issue with that is you can only represent numbers as big as 7.9375- actualy wait no this is just an example but in a video game you would actualy want to use more digits
Even after so many years NES Mario games are the gold standard in terms of character movement. So many modern games are lacking in this regard it's actually sad to see! Great video and thanks for sharing!
Thanks for the re-upload, I still need this to try to figure out how to replicate it in Game Maker 2.3, I worked 2 months without success and need the video for references.
One major thing Mario games do so well that i feel other games easily overlook is holding down the jump button to jump higher. You can keep adding to the upwards velocity every frame the jump button is held, but I find that that doesnt feel as smooth. The way i found to do this felt pretty natrual control; The frame the jump button is pressed, a short timer starts. While this timer is active, the gravity is loosened a bit, and when either the timer runs out or the jump button is released, gravity returns to normal. With a bit of fine tuning with max vertical velocities and gravity strength , it can make things feel a whole lot smoother.
this is really, really good! like, i don't think ive ever seen people talk about how to make stuff the way you do. So nice job! -now ive gotta learn assembly lmao-
@@NesHacker don't worry it was a joke I don't have the brains nor the resources to learn and use the damn thing only language I somewhat know is Lua -lmao-
I key point to also understand in this conversation is that a fixed frame rate is needed in order for this method to work the way you want it to. I was making a platform in engine in Processing using floating point calculations, I realized it only worked if the frame rate fixed. I derailed the entire project when I tried to generalize the engine for different frame rates, opened a huge can of worms I am so impressed by everything modern video game engines can handle
You don't have to rely on fixed frame rates. What you need is a stable timer. The reason fixed frame works is the video sync refresh is a stable timer with a reliable 0.02 second interval per tick. All you need to do is anchor the arithmetic to any stable timer you can find in the system then the frame rate can do anything it likes. That's how modern games work: The frame rate varies with the complexity of the scene but motion in the game remains consistent because the timer on which all the action is based isn't the screen refresh, it's something else.
@@jakeenvelopes9561 yes, exactly. well put, I came up with the same conclusion but couldn't put it nearly as succinctly as you did. i thought about it like i was going to need to separate the physics engine clock from the graphics engine refresh rate
This video almost made me want to start doing asm6502 again. But then I remember how hard it is for the brain when I do it in my spare time while also doing app development for my day job. I might try it again after I retire. Like in another 20-30 years, if I am still alive that is. LOL. BTW, you’ve got a new subscriber. This is good.
id Software went from an accelerating player in Comander Keen 1-3 (which felt super spongy) to a player with no acceleration in Comander Keen 4-6, which felt super tight and precise. That shows that player acceleration isn't always the best choice.
Yeah it really depends on the game and what you're trying to accomplish I think. That said, pixel value only velocities are usually always the "wrong" choice when the resolution is so limited, so using fixed point there is still quite useful.
0:12 Kinda ironic that out of the 3 NES Mario games, you call the one out of them that is the worst feeling and the most like All-Stars SMB or even NSMB in terms of slipperiness, as the "Quintessential examples of a game with good controls". NES SMB1, or SMW would have been MUCH better examples.
Looks like 6502 assembly language . Used to use it with basic on my Atari 800 back in 1980 to make games. I used to shift every bit on the background (all refined chars 1bit and then add or minus a byte depending on which way the background was scrolling (defender type game)
Great explanation. Another interesting video idea would be on implementing trig functions using lookup tables to make more complex platformer elements.
Watching this video is like watching magician revealing his tricks but still doesn't understand at all. I just watched till the end because i love the magic.
Although it's quite obvious in retrospect to use dollars and cents to explain fixed-point arithmetic, I would have never thought to do so in the context of subpixels! Great connection.
ah, this brings back some good memories - using assembler to manager unsigned and signed integers via bit shifting . . . joy lol - nowadays all of this is wrapped up into 'physics engines' and properties and methods exposed to leverage.
Amazing ! I'm going to translate your video to my language and teach children learning coding and of course, giving you the credits. Thank you for your nice job
My first code was on the Vic 20 in 1985. I am not a programmer, I'm more into gfx. But I do remember having to code a negative screen movement using a positive integer. Vel=Vel+(0-Int). It was in basic so ignore me if I'm talking absolute nonsense.
I always wanted to make a Mario-esque game! And now I can! Thank you! Even if you give it away as you said anyone can use it, I'd suggest , as I would do as well, that you get credit as at least at the end with "special thanks" section! Because I believe in giving credit where credit is due! 😉😉😁😁
Is this a reupload or something? I swear like a month or 2 ago I saw a video that went over similar information, but don't remember it being so concise. Great video... just felt like deja vu lol
Hmm, I can't say I've ever seen an X/Y pixel position straddle across two bytes like that. Surely the simplest solution is one byte is the pixel value and another byte is 1/256ths of a pixel. If you don't need that much precision you just change that value in increments of 8, 16, 32 or 64. When the fractional byte overflows you increment or decrement the pixel byte, no need for any bitshifting gymnastics.
help me! I need to know the name of the first game that appears in the video (at the second 0:01, the character dressed in green who shoots dragons) I've been looking for it for years but I could never find it! I would greatly appreciate it!
I used CA65, which is a 6502 assembler, and VS Code as my editor. I have a video about how to get a basic development environment setup from a couple years ago.
Thank you so much. I'm trying to recreate mario bros in pygame and it'll be a lot helpful to define corrently the physics. Even though I don't understand assembly, this is certainly a great starter!
Ahh, subpixel movement... the bane of 2D platformers. In a world perfectly represented, pixel for pixel, where you can tell exactly where you and everyone else is located with exact specification... there is always the subpixel to throw a half-pixel's worth of randomness into your decision making.
@@NesHacker That's what I mean! From a player perspective, I love 2D platformers because I can see every single element that is needed for perfect decision making... except for one, really. In many cases it's a nearly-perfectly-represented world, which I think is lost in a lot of ways in the transition to 3D.
Can you study Ninja Gaiden 2 for NES please? I think it has one of the best graphics for the system, and also is very fast paced. You can also study Captain Tsubasa 2 for NES, I can't believe 13 hours of gameplay could be a thing, and the animations are very detailed. Good video!
When I experimented a bit with doing a pixel art game in OpenGL I ran into the issue of pixels looking bad when scrolling trough the screen. It seems to be the case that when you render pixels with float screen space positions some pixels on the same column or line get rounded up or down inconsistently. I end up moving sprites by entire pixels (ints) in this particular prototype, so the speed the character would move could be over 1 pixel like 1, 2, 3 pixels per frame or under 1 pixel per frame, like 1 pixel every 2 frames. It was kind of confusing and it obviously there was no granular control of speed but solved the issue. Of course this is much easier to deal with when doing a console game since the resolution is fixed, that is not the case in PC so this can't work quite well. Later on other 3D projects I started sprite batching, merging all sprites meshes in one mesh and drawing everything in one draw call, that seemed to have fixed the issue. Very interesting video, thanks.
Yeah that's definitely an issue in OpenGL if you're trying to get crispy looking graphics. The way I used to do it was to draw things in the actual resolution (like 256x256) into a texture, then render it onto a quad and use shaders to mess with how the final result looked. It's been *YEARS* since I messed around doing stuff like that though 👴
As a 7800 coder, this is still useful. Though I handle collision differently, ICT4 and 5 have a fine resolution of 2560 sub pixels (320 pixel width) And honestly, I have kinda cheated the Subpixel thing on the vertical scale. I just divide VMOVE by 4. It was pretty smooth in ICT4, so I'm just gonna keep doing it that way.
@@NesHacker YES. DO. IT. I’m mainly 7800 & 2600, but I’ve also done 5200, A8 bit, Apple 2, ZX spectrum, Amstrad CPC, Some MSX, some C64 stuff, and NES. Would like to do SMS/GG soon too. Though my favorite just has to be the 7800, for these simple reasons: Up to 32 sprites per line Sprites can be up to 512x16 (in some modes) Sprites can have up to 12 colors plus transparency (in some modes) 256 colors with 25 per scanline Mid-line interrupts WSYNC 4K of RAM External audio can be mixed in with the standard TIA Max stock cartridge size of 112K External IRQ line of that wasn’t good enough Maximum resolution of 320x240 Edit- if you’d like, I can also hand over the source code to It’s Cyrus Time 4 for you if you want to dive into Atari 7800, or It’s Cyrus Time 3 (2600) if you wanna dive into Atari 2600.
I would be more interested to learn how you code the floor. Would a platform stop all Y negative acceleration instantly? How do you code falling past the floor to a lower platform? Won't subpixel calculations cause the player to end up inside the terrain sometimes when changing platform elevation? 😮
What you're referring to is called "Collision Detection" and it is a whole topic unto itself. I plan on making videos in the future that show some of the techniques that you can use to make it work.
Just an FYI cause it's coming up a lot in the comments, this is indeed a re-upload of the video I released last month. Sorry it took so long to get back up!
What was the change you made in the video?
@@4rumaniThere was a meme in the original that upset a couple snowflakes.
He made some small joke or reference to a meme that someone thought was offensive or something (?) so he probably just removed that
@@JustAlfy nobody remembers (based on the comments on the text post he made after removing it), which just goes to show how silly and innocuous it was in the first place ¯\_(ツ)_/¯
@@JustAlfyit was a sad Pepe image. Pretty ridiculous thing to unlist a video over imo but hey, his channel not mine
its 02:54 AM and I am here binge watching videos on how to code NES games.
this is amazing
2:49 am here
Fixed point math seems like the secret sauce for so many 8-bit games, glad to see it illustrated so clearly.
It's so, so huge. Floating point co-processors were an extremely advanced feature for a computer to have all the way up to like 5th generation consoles (the PSX didn't even have one from what I understand!).
@@NesHacker yep, I worked on a few Nintendo DS games and it didn't have a floating point coprocessor either. It had a coprocessor to handle integer division and square root, everything else was done in fixed point. You could do floating point but the compiler would translate float operations into integer operations, which was very very slow.
The N64 had floating point hardware, but still often used fixed point to represent angles, among other uses, though you could argue that it's not really fixed point because it's not really a number of integer bits and a number of fractional bits, and more just an abstract angle unit between 0 and 65535, where 32768 is simultaneously 180° and π. Wrapping integer arithmetic can be really handy when the unit you're using wraps around anyways (65536 angle units = 360° = 2π = 0).
@@angeldude101 that's just a matter of user library though, there's nothing in the platform itself that tells you to use trig functions with that convention for angles. How vertex buffers are sent to the RSP (the gpu) is a totally different question and in the case of the N64 they indeed used fixed point coordinates. Of course it's easier and faster to do all the transforms in fixed point and use floats only for texture decoding (the jpeg reference decoder uses floats for example) and other stuff which are not directly tied to the hardware.
Doom also used fixed point math.
You don’t know how much this helps me. I’m currently writing a platformer (or at least trying to) and I never had so much trouble programming something as with implementing the controls. Those techniques will definitely make it easier for me to do that. Thank you!
That’s fantastic to hear. The whole point of these videos is to help folks learn about the system and game programming 😊
whats the name of the platformer
I started testing platform physics back with XNA on 360. I started with learning Mario physics and the concept of subpixels. Once I figured all that out it was onto collision detection which can be just as tough as physics.
@@infinitypowergaming2995 Doesn’t have a name yet. It also won’t be commercially available. It’s only for a school project.
What engine are you using man? Most current game engines handle this stuff very easily for you.
This such a cool demo. Also, SMB3 is both the game that got me hook line and sinker, into video games as a lifelong pastime. The controls in this game weren't just tight, they defined the concept of 'tight' in video game controls. If the game wasn't smb3 and wasn't 35 years old, it could be reskinned and published on steam by a good Indy studio, and we'd all be none the wiser about it's age.
Super cool to see the tech demo'd for that, and as a person that has 'make an honest run at a gamedev project someday' on my bucket list, this is the coolest video i've stumbled upon in a long while. I'm glad I re-found the channel, I love this stuff!
That's such high praise, thank you so much! I had an absolute blast programming the demo and picking apart the movement in SMB3, and it's awesome to hear from someone who enjoys the game and it's craftsmanship at least as much as I do :)
I’m not a computer programmer but seeing the logic and math that goes behind making our beloved game characters move is so wholesome.
Dude, you're actually the most interesting content creator that I know ! I could listen to you for an entire decade in a row...
I'd like to express my extreme gratitude to you and wish you all the best too.
Can't wait to discover your next video.
Thanks so much! It’s really nice to hear that 😀
@@NesHacker My pleasure !
27 seconds into the video, I realize I've discovered a new channel to geek over. Easiest sub.
It’s really mind blowing how programmers did all this math in assembly, with no float point calculations and essentially had to write their own math rules. Programming took a different kind of genius back then, especially to pave the way and come up with all of this as a standard for things like movement.
The most concise and efficient rundown of nes assembler for smb3 movement, a beautiful tribute to the art of video game kinematics! amazing work!
Thank you very much!
Im a physics student, and i love computers but ive never really had the interest for coding until i neede it for my career, thats when i realize that coding is a god damn combination of art and math. My respect goes to every coder out there
This video was made with love and care, and information, and it shows. I didn't even have to understand everything you said to reach to that conclusion. Thank you. New subscriber.
You’re very welcome, and thank you so much for watching 😀
Man quite a bit of this went over my head, but I was hooked the entire time. Fantastic video!
Well I’m glad you enjoyed it :)
Great video! This format certainly is working for you, and I’m sure you’ll keep making polished content, but I’m also sure your fans would appreciate slowly paced deep-dives, even if they’re far less scripted/formal!
I’m often experimenting with different ideas and approaches for videos so it’s definitely an option on the table.
So currently, I am actually writing a 6502 assembler and linker in Rust cause I think it would be fun! Seeing your code keeps giving me ideas to support more features in my assembler!
Heck yeah, that sounds like a fun project! I wrote one a while back in JS but it was very barebones 😆
Just wanna say thanks for inspiring me.
This was the video that kicked off an adventure of mine where I started programming a platformer for the NES.
It took a while, and I did eventually get to have way more detail and features than the open source demo you gave (music, verticle and horizontal scrolling, detailed animations, etc) but I never would've gotten started without your demo.
Thank you.
Always wondered about this. Thanks for the great breakdown. Zelda 2 had particularly memorable subpixel coding.
Man… now I wanna do a breakdown of Z2 movement 😂
Damn, this is incredibly animated and very easy to follow along. You will reach a million subs in no time for sure
Haha, I would feel incredibly vindicated if I got to 1M subs 🤣
1:49 My answer: Use fixed points, so basically you have an integer but then you add a decimal point somewhere in the middle, there are also floating points that are used in almost every new modern game nowadays but old consoles don't support those. edit: Oh also subpixels are basicaly fixed points
Oh my god thank you. There are so many game design videos out there that go over concepts of game design - and that's fantastic - but to have one that _actually_ delves into the coding aspect, how to apply that knowledge, is something I've wanted for a long time. This might be one of my favorite channels in recent years
You’re very welcome, I’m happy to know that my videos help so much! ☺️
This might be your best video so far. To be sure, you need a deep enough understanding of ASM6502 to really absorb the content, but once you have it, this video hits the mark pretty much across the board. (It's definitely my favourite of your videos... so far!) Well done!
Hey. thank you so much! I really enjoyed making it and had a feeling I was striking a good balance between high level concepts and low level technical details when I was making it :)
Rick and Morty
The NES used a Rocoh 2A03 processor which was basically a 6502 with binary coded decimal disabled. The cool thing was that NES and the Commodore C64 shared the same CPU, so if you knew one it was fairly easy learning to write code for the other (except for the PPU/VIC-II respectively).
I always go into your videos with high hopes of following everything and inevitably half way through get lost. Glad I can cheat and code the same effect in Unity much more easily
That sounds like I’ve still got work to do to make these topics more accessible 😁
Don't give up! ASM6502 is definitely challenging but not impossible. I still find I'm rewatching these kinds of videos multiple times before I "get" it. Also, I wouldn't be afraid to throw some questions in the comments. Judging by the remarks of others, you'll probably get a reply that helps you out.
I nearly understood the content, and appreciate it's been a lot of amazing work compressed into 10 minutes. But the quick jumps between content distracted me from your narration which may have been fine had RUclips not had that annoying shade on pause feature meaning it was very hard to read the text.
So this is the reupload where you have thrown the frog out.😄
BTW, I have just become one of your patrons. Your videos are excellent and really helpful, so I wanted to support you.
Thank you so much for your support, I appreciate it :)
Hell yeah, new NesHacker video!
Kinda, this is a re-release as I fixed a thing in the video.
Ayo this is sick! I actually made some similar findings as the things mentioned in this video when I tried to remake Mario3 in the Godot game engine. Didn't look at the game's original code at all, I just captured Mario 3 footage, did frame-by-frame analysis and extrapolated a lot of stuff from there. I KNEW there must've been a set timelimit for how much you can hold the jump button and it affecting the "Gravity" applied on Mario! My estimate was 23Frames, the formula that i came up with didn't exactly line up with how many pixels Mario moved upwards per frame visually, So i went with 23 despite having a gut feeling on 24.
Some things i just couldnt extrapolate precisely just by analyzing footage so i did wing it for a bit, arrived to 90px/sec or 1.5px/F as Mario's First Maximum Speed, and that it took him 20Frames to reach that Speed, so i went with 4.5Speed/F for Acceleration, and -3.5Speed/F for Friction. Dont quite remember the Friction Value i used for when Mario presses the opposite direction while moving, though. I also made Mario's TopSpeed a threshhold that changed depending on certain conditions, TopSpeed 1 is just when Mario moves, TopSpeed 2 (2.5px/F) unlocks when Mario has reached TopSpeed 1 and is pressing the Run button, and TopSpeed3 (3.5px/F) unlocks when filling the "P-Meter" by having stayed at TopSpeed2 for a certain amount of time.
JumpHeight is also intertwined with Mario's Horizontal Speed in this game, so I assumed the game used a simple equation for that, I could never get it super accurate, just a decent approximation with irregularities between the JumpHeight in my game and the one in Mario3, so i assume there is something i was missing there. I did get Mario's FullJump at 0Speed to be 70pixels in height, and 101pixels at TopSpeed3, which i think is accurate, it's JumpHeights between 0 and TopSpeed3 that had inaccuracies.
I'm happy I arrived at a fairly accurate Gravity, FallingGravity being 5times stronger than JumpingGravity was correct, let's go. I felt like the internet was trying to gaslight me into accepting that FallingGravity was 3times stronger, glad to have gone with my gut with that one.
Also, I'm not crazy by thinking that Mario's feet and body have 2 separate collisions right? Mario's Body slides off edges, and his Feet are just a really precise rectangle, or at least that's what i gathered from my testing.
Anyway, keep it up man, this is fascinating information you're sharing with us, thank you.
Wuhhh, you that sounds like a lot of work you did, good job! As far as the hit detection is concerned I don’t know, I haven’t really dug into it for this game 🤔
@@NesHacker @@NesHacker I Made a ton of little discoveries with that Project, some of which i don't think are documented anywhere, nowhere i could find them anyway. Things like jump edge correction being 4pixels, and the Game teleporting Mario on top of platforms he misses by 4pixels(?) of height, or that Mario changes to his Jumping Sprite without leaving the Floor for a single frame, this means Mario has a single frame of preJump, Mario is unaffected by Gravity in this particular Frame, so i guess You could argue Mario3 has coyote time if You do a frameperfect jump off a ledge. Sorry for rambling, i found an excuse to share these things so brain going nerd mode rn.
@@tacosalvapor9264 How did you ping him 2 times?
@@RandomBloonStuff RUclips mobile things, I prolly did it by accident.
@@tacosalvapor9264 Maybe.
Very cool video Ryan! I didn't realize Mario was running in 60FPS! Love the way that you really break down the math and science behind the animation in Super Mario Bros 3.
Thanks Eric, I really appreciate it 😀
Been (inconsistently) trying to study to become a software developer one day for a while now, and every now and then I’ll come across a video like this where it looks interesting and something I want to learn about but once I click and start watching I quickly realize that I’ll never be smart enough to actually understand any of it. This is all just goes way over my head.
I mean a couple of things here… One, this is a pretty math heavy concept I’m talking about here and it is for a very old system. This means that it’s not fully relevant to modern programming. And two, while some folks may be more naturally inclined for programming it’s not like they could magically just do it. It takes effort and years of practice to be a solid developer. I’ve went to college for CS and have been programming for thirty years. The first five of which I was pretty bad tbh 😂
On top of speed being in subpixels/frame, SMB1 and SMB3 (+ most likely others) also have a subspeed, a further division of speed into 16 units used when accelerating. Mario has a variable acceleration depending on the situation (in SMB1, he famously accelerates twice as fast backwards since he was made to slow down faster than he speeds up), so the subspeed tracks 16ths of a subpixel per frame and is truncated in the speed calculation.
Certain speedrun tricks require subspeed manipulation, in the sense that Mario can move ever so slightly more in the same amount of time if he accelerates from 0.9375 than if he accelerates from 0.0000 speed. I don't remember the exact numbers, but his speed on every frame might look like 0, 2, 4, 5, 7, 8... instead of 0, 1, 3, 4, 6, 7... Over the course of a full acceleration from standing still to full speed, this could add up to a full frame's worth of extra distance, or 3 extra X pixels (4 with positional subpixel manipulation) on the screen after doing a bump on a block to set up a wrong warp!
It’s absolutely astounding to me what the speed running community gets up to when pushing the limits of this and so many other games. Honestly watching runs and demos gets me so pumped to go into the games and figure stuff out for myself 😊
That is not really the case in SMB3 though, Bismuth. Or at least that's the first I ever hear about it.
Though it's not fully true that Mario always accelerate at a speed of 1 unit/frame. You are unable to accelerate to the right on the frames when address 055C is at 0 or 1, and E and F for left. This address is independent on what Mario's speed is at that time, nothing else; to my knowledge, tracks Mario's speed other than 00BD which is always consistent.
Other exceptions to 1px/frame is when you have a speed >0 and press left, at which you'll always move 2 speed units/frame, and vice versa for the other direction. Then things like being on a slope will be different or while being Frog Mario. All of which ignore the 055C address.
But yeah, Bismuth, not sure what you mean in this case actually =/. Though I'll love if you fill me in!
@@TompaA I may have conflated the two here. I was almost positive if the mechanic existed in SMB1, it had to in SMB3 as well. I figured that it existed but I didn't remember it coming up as particularly important in speedruns, but thinking back on it, it probably wouldn't have been reset on every level, so it would have affected wall clips like subpixels do. Interesting that SMB3 did away with subspeed!
"Fixed point math" is a new word to me. And I think I've been doing a bit of it in my own code. I've been writing a game engine where I try to avoid use of floating point numbers. Not 100% , but the basic hypothesis is that it's easier to figure out anti-aliasing when your math is "pixel-perfect" or... for lack of a better word... "fence-post-perfect" as in "not even off by 1".
Yeah, ints are way easier than floats if for nothing else but cumulative error that occurs with the latter if you're not especially careful.
I’ve been looking for an explanation of how keyframe animations are actually written, so this is incredibly helpful! I’m going to dig into your sample code but I’d love to see a whole video on it in your signature style. Huge, huge fan of your channel.
Yoooo what a great way to start the day. Looking forward to all these lessons culminating in a full NesHacker game hahaha
Hahaha, making a full game would distract from my video making though…
-3:14-- The issue with that is you can only represent numbers as big as 7.9375- actualy wait no this is just an example but in a video game you would actualy want to use more digits
I love this video. You say things very clearly and directly.
I'm very happy you like it :)
this will be very helpful, especially the source code. Thank you for your great work!
Nice, let me know if you end up doing anything cool with it!
Even after so many years NES Mario games are the gold standard in terms of character movement. So many modern games are lacking in this regard it's actually sad to see!
Great video and thanks for sharing!
But when modern games get it right it's kinda amazing... (lookin' at you "Celeste").
Thanks for the re-upload, I still need this to try to figure out how to replicate it in Game Maker 2.3, I worked 2 months without success and need the video for references.
Oh man I feel so bad, sorry I didn't have it up for so long! It's here now though!
I like your voice. Thanks for sharing the thought process!
Thanks, I think it sounds better when I don't try to put on a "youtube" voice
0:17 this got me
2:52 Also I think the Sonic games use 256 subpixels
A friend of mine mentioned this channel. I'm surprised by the quality of the videos and editing, great job!
One major thing Mario games do so well that i feel other games easily overlook is holding down the jump button to jump higher. You can keep adding to the upwards velocity every frame the jump button is held, but I find that that doesnt feel as smooth. The way i found to do this felt pretty natrual control; The frame the jump button is pressed, a short timer starts. While this timer is active, the gravity is loosened a bit, and when either the timer runs out or the jump button is released, gravity returns to normal. With a bit of fine tuning with max vertical velocities and gravity strength , it can make things feel a whole lot smoother.
Awesome new video ! I was allways wondering how they got Mario to feel so smooth
Glad you liked it :)
this is really, really good!
like, i don't think ive ever seen people talk about how to make stuff the way you do.
So nice job!
-now ive gotta learn assembly lmao-
Thanks! RIP your future in assembly programming I guess…
@@NesHacker
don't worry it was a joke
I don't have the brains nor the resources to learn and use the damn thing
only language I somewhat know is Lua -lmao-
I key point to also understand in this conversation is that a fixed frame rate is needed in order for this method to work the way you want it to. I was making a platform in engine in Processing using floating point calculations, I realized it only worked if the frame rate fixed. I derailed the entire project when I tried to generalize the engine for different frame rates, opened a huge can of worms
I am so impressed by everything modern video game engines can handle
You don't have to rely on fixed frame rates. What you need is a stable timer. The reason fixed frame works is the video sync refresh is a stable timer with a reliable 0.02 second interval per tick. All you need to do is anchor the arithmetic to any stable timer you can find in the system then the frame rate can do anything it likes. That's how modern games work: The frame rate varies with the complexity of the scene but motion in the game remains consistent because the timer on which all the action is based isn't the screen refresh, it's something else.
@@jakeenvelopes9561 yes, exactly. well put, I came up with the same conclusion but couldn't put it nearly as succinctly as you did. i thought about it like i was going to need to separate the physics engine clock from the graphics engine refresh rate
Incredibly fascinating. I could see a Metroid, Zelda, and Mega Man series being super cool.
Oooh, you're giving me too many ideas 🤣
Nice simple explanation, can't wait for the one for moving and jumping on and between platforms :)
I love your detailed explanation for the code! I'd love to make an NES game one day!
This video almost made me want to start doing asm6502 again. But then I remember how hard it is for the brain when I do it in my spare time while also doing app development for my day job. I might try it again after I retire. Like in another 20-30 years, if I am still alive that is. LOL.
BTW, you’ve got a new subscriber. This is good.
id Software went from an accelerating player in Comander Keen 1-3 (which felt super spongy) to a player with no acceleration in Comander Keen 4-6, which felt super tight and precise. That shows that player acceleration isn't always the best choice.
Yeah it really depends on the game and what you're trying to accomplish I think. That said, pixel value only velocities are usually always the "wrong" choice when the resolution is so limited, so using fixed point there is still quite useful.
Sub pixels. I suspect this is why it also takes me a few frames (and a coffee) to get going in the morning.
I feel that… Here’s to coffee and wrong warping into our days 😆
3:46 But that leaves 4 bits unused so why not take advantage of the unused bits and have a byte of whole and a byte of fraction
As a web designer/dev, someone who studied CS and a huge 8/16 bit fan, I’m immediately liking and subscribing. Looking forward to seeing more videos!
I'm okay with watching this again. It's really informative!
Haha heck yeah. As the creator of said content I wouldn’t mind you watching it a third time too 😝
Ahhh I hope millions will play this gameee!
I've wanted to recreate smb3 physics in Roblox for while!
It's good that you reuploaded the video, it had been deleted.
Yah, I’m glad it is back
Subpixels would be what today we call "delta time", which is basically the S(t) = vo + vt formula.
Incredible content! Nintendo's programmers were really geniuses
For real
The code is maizing!!! It is just beautiful for the pov of someone who baraly know assembly. It even
makes me want to do more low-level projects.
Thanks so much, I'm glad you found it inspirational!
0:12 Kinda ironic that out of the 3 NES Mario games, you call the one out of them that is the worst feeling and the most like All-Stars SMB or even NSMB in terms of slipperiness, as the "Quintessential examples of a game with good controls". NES SMB1, or SMW would have been MUCH better examples.
the slippery makes me feel more free
it was so cool to learn about this keep up the good work
Thanks, will do :)
Looks like 6502 assembly language . Used to use it with basic on my Atari 800 back in 1980 to make games. I used to shift every bit on the background (all refined chars 1bit and then add or minus a byte depending on which way the background was scrolling (defender type game)
Yep 6502, the NES uses a modified version of the chip
Great explanation. Another interesting video idea would be on implementing trig functions using lookup tables to make more complex platformer elements.
Imagine that a subpixel is a bus stop...
🫡
vroom vroom
Watching this video is like watching magician revealing his tricks but still doesn't understand at all. I just watched till the end because i love the magic.
Glad to see this video is back!
Me too :)
*Fistbumps NesHacker.
*explodes off the bump* Heckin' yeah
SMB3 is one of those games that were so good, I forget it was for the NES and not the Super Nintendo
Yeah it is quite good
Although it's quite obvious in retrospect to use dollars and cents to explain fixed-point arithmetic, I would have never thought to do so in the context of subpixels! Great connection.
ah, this brings back some good memories - using assembler to manager unsigned and signed integers via bit shifting . . . joy lol - nowadays all of this is wrapped up into 'physics engines' and properties and methods exposed to leverage.
Amazing ! I'm going to translate your video to my language and teach children learning coding and of course, giving you the credits. Thank you for your nice job
My first code was on the Vic 20 in 1985. I am not a programmer, I'm more into gfx. But I do remember having to code a negative screen movement using a positive integer. Vel=Vel+(0-Int). It was in basic so ignore me if I'm talking absolute nonsense.
I always wanted to make a Mario-esque game! And now I can! Thank you! Even if you give it away as you said anyone can use it, I'd suggest , as I would do as well, that you get credit as at least at the end with "special thanks" section! Because I believe in giving credit where credit is due! 😉😉😁😁
Right on, I wish you the absolute best of luck!
Is this a reupload or something? I swear like a month or 2 ago I saw a video that went over similar information, but don't remember it being so concise.
Great video... just felt like deja vu lol
Yeah it's a re-upload, I had to fix something. Sorry about that!
@@NesHacker all good. Great video non the less! Happily got both my views xD haha
Hmm, I can't say I've ever seen an X/Y pixel position straddle across two bytes like that. Surely the simplest solution is one byte is the pixel value and another byte is 1/256ths of a pixel. If you don't need that much precision you just change that value in increments of 8, 16, 32 or 64. When the fractional byte overflows you increment or decrement the pixel byte, no need for any bitshifting gymnastics.
Indeed, but this is how it’s stored in the actual game.
@@NesHacker in SMB3? In the disassembly I have the Player_X byte is just copied directly to the objectsX table, no bitshifting going on.
Do I have deja vu, or is this a reupload? :D Amazing job!
It is, sorry about that! I'm glad you enjoyed it twice though 🤣
Well it’s no wonder why those supermarobros games just play sooo smooth because the designers tout and tested everything about it to feel right.
Yep, not to mention the level design, enemies, power ups and all the other stuff they had to balance. Games like Mario Bros are truly works of art.
help me! I need to know the name of the first game that appears in the video (at the second 0:01, the character dressed in green who shoots dragons) I've been looking for it for years but I could never find it! I would greatly appreciate it!
Little Samson
This will really help in my school project
Awesome I’m glad I could help!
Excellent video and editing, sir! What did you use to build and run this little demo you made?
I used CA65, which is a 6502 assembler, and VS Code as my editor. I have a video about how to get a basic development environment setup from a couple years ago.
@@NesHacker Ah, shoulda done my research… Perfect! I’ll check it out. Thanks a bunch!
I tried a simple platformer on my Amiga500 in the 1980s was struggling exactly with this kind of smooth and exact movement of the character.
There’s always some trick, but sometimes the tricks are kinda esoteric or technical 🤔
@@NesHackerI just was not able to figure out fixed point arithmetic in assembly as a teenager and information was hard to get by back then ;)
What 6502 assembler are you using for this? Great video and content!
CA65 is what I use
This video is like a concise college lecture, lol.
I bet I could go ultra deep if I did a full 50 minute lecture on the topic 😂
Awesome video, very intesting and well done
Thanks so much!
Thank you so much. I'm trying to recreate mario bros in pygame and it'll be a lot helpful to define corrently the physics. Even though I don't understand assembly, this is certainly a great starter!
Thank you so very, very much for sharing this.
You're very, very welcome. It was a lot of fun to make and no use hoarding all for myself xD
Ahh, subpixel movement... the bane of 2D platformers. In a world perfectly represented, pixel for pixel, where you can tell exactly where you and everyone else is located with exact specification... there is always the subpixel to throw a half-pixel's worth of randomness into your decision making.
It’s still technically an exact specification but it’s just that you can’t see the sub pixels 🧐
@@NesHacker That's what I mean! From a player perspective, I love 2D platformers because I can see every single element that is needed for perfect decision making... except for one, really. In many cases it's a nearly-perfectly-represented world, which I think is lost in a lot of ways in the transition to 3D.
Can you study Ninja Gaiden 2 for NES please? I think it has one of the best graphics for the system, and also is very fast paced. You can also study Captain Tsubasa 2 for NES, I can't believe 13 hours of gameplay could be a thing, and the animations are very detailed. Good video!
I will definitely take a look. Both are great suggestions 😊
@@NesHacker Thanks! You're the best!
Great video, really helpful Ryan, thank you
You're welcome!
Great video! as a recomendation use also decimal numbers
Thanks!
When I experimented a bit with doing a pixel art game in OpenGL I ran into the issue of pixels looking bad when scrolling trough the screen. It seems to be the case that when you render pixels with float screen space positions some pixels on the same column or line get rounded up or down inconsistently. I end up moving sprites by entire pixels (ints) in this particular prototype, so the speed the character would move could be over 1 pixel like 1, 2, 3 pixels per frame or under 1 pixel per frame, like 1 pixel every 2 frames. It was kind of confusing and it obviously there was no granular control of speed but solved the issue. Of course this is much easier to deal with when doing a console game since the resolution is fixed, that is not the case in PC so this can't work quite well. Later on other 3D projects I started sprite batching, merging all sprites meshes in one mesh and drawing everything in one draw call, that seemed to have fixed the issue. Very interesting video, thanks.
Yeah that's definitely an issue in OpenGL if you're trying to get crispy looking graphics. The way I used to do it was to draw things in the actual resolution (like 256x256) into a texture, then render it onto a quad and use shaders to mess with how the final result looked. It's been *YEARS* since I messed around doing stuff like that though 👴
I love you and yes Siri you’re a great teacher you make the complicated things simple and I wish everybody else will do that have a good day
I’m happy to help, hope you have a good day too
stellar editing
Thanks so much!
Read the title as "The Code That Makes the Mario Movie" and thought you hacked into theater or Illumination.
Oh wow, yeah “Mario Movie” and “Mario Move” are super close. I haven’t seen the movie yet, if it any good? 😂
Me neither. @@NesHacker
Pretty informational video, thanks.
You're welcome, and I am glad you found it so.
Really well explained, well done.
As a 7800 coder, this is still useful.
Though I handle collision differently, ICT4 and 5 have a fine resolution of 2560 sub pixels (320 pixel width)
And honestly, I have kinda cheated the Subpixel thing on the vertical scale. I just divide VMOVE by 4. It was pretty smooth in ICT4, so I'm just gonna keep doing it that way.
Oh interesting… I should totally dive into system someday 🤓
@@NesHacker YES. DO. IT.
I’m mainly 7800 & 2600, but I’ve also done 5200, A8 bit, Apple 2, ZX spectrum, Amstrad CPC, Some MSX, some C64 stuff, and NES. Would like to do SMS/GG soon too.
Though my favorite just has to be the 7800, for these simple reasons:
Up to 32 sprites per line
Sprites can be up to 512x16 (in some modes)
Sprites can have up to 12 colors plus transparency (in some modes)
256 colors with 25 per scanline
Mid-line interrupts
WSYNC
4K of RAM
External audio can be mixed in with the standard TIA
Max stock cartridge size of 112K
External IRQ line of that wasn’t good enough
Maximum resolution of 320x240
Edit- if you’d like, I can also hand over the source code to It’s Cyrus Time 4 for you if you want to dive into Atari 7800, or It’s Cyrus Time 3 (2600) if you wanna dive into Atari 2600.
This topic is really interesting! Thanks!
I would be more interested to learn how you code the floor. Would a platform stop all Y negative acceleration instantly? How do you code falling past the floor to a lower platform? Won't subpixel calculations cause the player to end up inside the terrain sometimes when changing platform elevation? 😮
What you're referring to is called "Collision Detection" and it is a whole topic unto itself. I plan on making videos in the future that show some of the techniques that you can use to make it work.
I love the content on your channel
Thank you so much 😊