The Complex Code of Mega Man 2 and How Zipping Works - Behind the Code

Поделиться
HTML-код
  • Опубликовано: 26 дек 2024
  • ИгрыИгры

Комментарии • 275

  • @musickid43
    @musickid43 2 года назад +365

    There are 2 things developers always struggle with. Cache invalidation, naming things, and off by one errors.

    • @VinsCool
      @VinsCool 2 года назад +37

      I see what you did here
      Seems like a carry flag was also incorrectly set in this statement :p

    • @lazsynth
      @lazsynth 2 года назад +2

      loooool

    • @CarbonRollerCaco
      @CarbonRollerCaco 2 года назад +11

      *4 things
      Because the off-by-one here was positive.

    • @drygordspellweaver8761
      @drygordspellweaver8761 2 года назад +1

      I *C* what you did there

    • @owenwexler7214
      @owenwexler7214 2 года назад +14

      Not to
      asynchronous code
      mention

  • @Darxide23
    @Darxide23 2 года назад +176

    Off-by-one is a plague that haunts the nightmares of coders.

    • @Phroggster
      @Phroggster 2 года назад +3

      Fenceposts are just too darned challenging to accurately count.

    • @GameDevMadeEasy
      @GameDevMadeEasy 2 года назад +5

      I recently had to fix an off-by-one bug in work code. Was a pain to find and fix, that's for sure.

    • @angeldude101
      @angeldude101 2 года назад +10

      It's one of the 2 hard problems in computer science, alongside cache invalidation and naming things.

    • @dmas7749
      @dmas7749 Год назад

      @@angeldude101 naming things is easily the hardest because that requires creativity

    • @sourandbitter3062
      @sourandbitter3062 Год назад

      For Of loops to the rescue

  • @NonRandomUser
    @NonRandomUser 2 года назад +14

    "It's just one pixel; no one's going to notice that insignificant discrepancy."

  • @Brocknoth
    @Brocknoth 2 года назад +44

    As a person who can't code to save his life that was really, really informative and easy to understand. Fascinating stuff honestly.

  • @arciks11
    @arciks11 2 года назад +185

    2:30 To answer your rhetorical question. Yes, Mega Man 3 likes to REALLY slowdown. And I know there is an improvement hack for it that significantly minimizes the slowdown that occurs. So Comparing regular MM3 with that hack could shed some light on how that slowdown was fixed.
    In addition to that Mega Man 3 was the entry that removed a physics quirk where Mega Man would slightly slide forwards after stopping which made first 2 Mega Men feel kinda slippery, so that could also be looked into.
    Another Bug is with selecting Rush Items. If you say have Search Snake and go right on select screen you will select an empty Rush Item in that slot. If you then get weapon energy and use it, you will unlock access to it before you're meant to.
    I like Mega Man 3 but of all 6 NES entries it's the one that's held together by glue and prayers the most.

    • @DaWhiteTyger
      @DaWhiteTyger 2 года назад +9

      I know that's right, I felt it growing up when it released and was like, "This feels different than MM2, like it's been added upon..." Thanks for helping to confirm what I've been pondering for years. Now, to find that 'hack' you mentioned. *Rubs hands together*

    • @arciks11
      @arciks11 2 года назад +18

      @@DaWhiteTyger OK I think youtube ate my previous two comments due to mentioning site kinda directly.
      Hack is called Mega Man 3 Improvement.
      It's on a site that is heavily used for "romhacking" on the "net"

    • @vuurniacsquarewave5091
      @vuurniacsquarewave5091 2 года назад +7

      There are definitely some performance issues there, a ton of unused content (sound effects, graphics, an intro that was never actually made) and even some sloppy MMC3 usage. Many times the IRQ fires one or two scanlines too early/late and screen splits are therefore not made at the right place. This is noticeable at the stage select screen and any boss fights where a moving enemy is part of the background. I personally wonder how difficult it could be to fix the weapon energy drain bug of the Top Spin. The energy seems to get drained when you are invulnerable after a hit and the enemy is not insta-killed by the attack.

    • @dudujencarelli
      @dudujencarelli 2 года назад +5

      Which is ironic, considering that Mega Man 7 on the SNES looks like a polished work of 2D sidescrolling art, and that game was in fact put together in 3 months!

    • @Valientlink
      @Valientlink 2 года назад +3

      I honestly liked the physics of megaman 1 and 2 more I think, he just felt so much more airborne. MM3 onwards you can really feel that "snap" to the floor

  • @alexhobbs1208
    @alexhobbs1208 2 года назад +36

    I may not understand everything happening but I thoroughly enjoy these breakdowns

  • @wishexploder
    @wishexploder 2 года назад +16

    This has got to be one of the best video game coding related youtube videos I've seen that blends intermediate programming knowledge with easy to understand narration and examples. Can't wait to check out your other stuff!

    • @GabePuratekuta
      @GabePuratekuta 2 года назад

      On par with Jon Burton's GameHut and Coding Secrets channels.

  • @Wyrdwad
    @Wyrdwad 2 года назад +57

    Adding the extra purple pixel to Mega Man's center to indicate his actual position has the unintended side effect of making it look like he's sticking his tongue out all derpy-like. ;)
    Just figured I'd point that out! Heheh.
    Awesome video, as always!

    • @taben9jake
      @taben9jake 2 года назад +5

      And thats why i read comments before i make one. It also kinda looks like he has a bit of catsup leftover from eating a hotdog.

    • @GabePuratekuta
      @GabePuratekuta 2 года назад

      Nope, it's a clown nose.

  • @meta04
    @meta04 2 года назад +2

    3:25 An amazing sequel to Bismuth's deadpan "Usually this is done by repeatedly jumping, but that's not an option [in the A button challenge]. Figuring out why is left as an exercise to the viewer." delivery...

  • @Guineh76
    @Guineh76 2 года назад +14

    Oh, wow… I went through the code for MM2 a couple of years ago. I remember the environment collision check routines… took a bit of time to wrap my head around all of the bit shifting and packing to figure out how it was arriving at the address of the block it was checking. There was also the enemy spawn routine as you move through the level that was pretty interesting. If I remember there are two lists one for blocks (what you call dynamic) and one for level effects and enemies. It’s been a while since I’ve looked at it. Lots of interesting stuff in the code for sure.
    Loving your behind the code series, btw! I look forward to every episode!

  • @thelastsidewalk
    @thelastsidewalk 2 года назад +20

    I'm surprised to hear it was put together in 3 months.
    For such a short time, I feel the gameplay is a lot more polished than MM1.
    This was an amazing video by the way, fascinating. Thank you.

    • @vksasdgaming9472
      @vksasdgaming9472 2 года назад +3

      I am certain Capcom was able to reuse lots of assets developed for Megaman. Graphics, movement and lots of animation was simply used again so time was saved. It still is very much improved over first. In my books series kept becoming technically better through it's NES-era even if presentation wasn't always as good.

  • @bdjeffyp
    @bdjeffyp 2 года назад +30

    What an amazing and fascinating breakdown! I love how "off-by-one" errors can drastically affect things. One thing that I would love to see you do in the future, perhaps in a "Talkin' Code" segment, is how you go about analyzing the Assembly code and figuring out how the different subs work. I would imagine that you are using breakpoints and modifying values to see what changes in the game, but I would be interested in hearing your thoughts on how you research and figure out the code behavior for these "Behind the Code" videos.

    • @dchardin1
      @dchardin1 2 года назад +1

      I second that!

    • @Gpig20
      @Gpig20 2 года назад

      I think for some of the behind the code videos he walks through the process of analyzing the assembly code in the emulator. Off the top of my head I think the Mega Man charge shot video is a good example but I think there's more

    • @VinsCool
      @VinsCool 2 года назад +1

      It would be nice to see a video of him tracking down a bug, unscripted, and hear his reaction as he explains why things broke and what could be the fix.
      Bonus points for fitting in a 3 bytes Game Genie code :p

    • @lazsynth
      @lazsynth 2 года назад +1

      Good ideas (also hi Vins!)

    • @drygordspellweaver8761
      @drygordspellweaver8761 2 года назад +1

      He just loads it using a disassembler. There wasn’t much need for obfuscation and anti reversing back then so it’s straight forward.

  • @vineheart01
    @vineheart01 2 года назад +20

    i often wonder if the person who wrote the specific code that allowed a rather significant bug realizes years later that they did that and just go /facepalm 'dammit, i see what i did wrong...' lol

    • @Dreamwriter4242
      @Dreamwriter4242 2 года назад +9

      Often, they knew about the bug even before the game shipped. I worked back in the cartridge era before you could patch games, and we had a team of testers testing our games 8 hours a day for months. So we had a database with hundreds of known bugs in it. When the shipping date got close, bugs would start to...disappear. Because fixing bugs could accidentally create new bugs, at some point someone would go to the database and mark all "C-level bugs" as "won't fix". Later they would do that with all "B-level bugs", leaving only the worst bugs as ones to fix - like crash bugs or bugs that would cause the game to fail Nintendo's shipping tests. It was frustrating to know of a bug you had made, and know how to fix it, and not be allowed to.

    • @blarghblargh
      @blarghblargh 2 года назад +4

      This is still how shipping works. For good reason. No matter how innocuous the fix and how it *shouldn't* cause ripple effects, there's a non-zero chance that it will. So if the bug wasn't deemed that important, then after a certain point in the schedule the reward is less than the risk. They did their jobs. This is from someone who has been in QA (for 6 years), dev (for 10), and production/project management (for 3). It's frustrating, but prioritization and cutting is always the right call.
      Plus, this bug may be exploitable by speedrunners, but these days generally consider that "a feature, not a bug". Especially if regular players are basically never going to notice it.

    • @sr.metang8193
      @sr.metang8193 2 года назад

      @@blarghblargh speaking of which, this can be a pretty daunting task for independent developers with little to no beta testers availability most of the time, which in turn might end up in long, ever-postponing unfinished projects that always miss deadlines. Not exactly always perfectionism, but your mileage may vary about that. Is there any kind of concern a dev in such a situation should be considering before attempting to solve bugs before shipping?

    • @blarghblargh
      @blarghblargh 2 года назад +2

      @@sr.metang8193 IMO. Small indie dev isn't the same beast as larger companies with more resources. Once their company and products hit a certain threshold, they will be judged the same metrics as other games. But until then they should focus on doing interesting work and not on doing bulletproof work. Ideally all groups should get some testers though, one way or another.
      Prioritization always exists. There will always be bugs. It's a question of how much they interfere with the enjoyment of the typical player, and what percentage of people end up having their experience go pear shaped.

    • @aaendi6661
      @aaendi6661 2 года назад

      It's better than getting stuck in the wall.

  • @TheSektorz
    @TheSektorz 2 года назад +67

    Oi btw now that I see what "zipping" means - you can do the same thing in the original Sonic games. Would be fun if you make a vid on those too, Sonic 3 in particular I've seen people break the most using a similar technique.

    • @VincentGuillotine
      @VincentGuillotine 2 года назад +17

      marble zone acts 2 and 3 basically don't exist in sonic 1 any% speedruns thanks to zipping

    • @CoolJosh3k
      @CoolJosh3k 2 года назад +5

      It is all in the ejection method. A combination of “which direction” and “where to put the player”.
      Normally the visual indication is just the illusion of a solid wall and you never actually see the ejection take place. You do notice with zipping because the next render does not make sense in a natural way.

    • @Valientlink
      @Valientlink 2 года назад +1

      yeah the instruction manual in sonic 3 suggests you enter the special stage or special zone because Tails will die to a zip for some reason if you don't lol

    • @manjackson2772
      @manjackson2772 Год назад +1

      ​@@ValientlinkIt's not a zip. Ice Cap Act 1 is supposed to be a vertically looping stage. When you first enter the stage, the flag that makes it loop vertically is set during the snowboarding section at the beginning. But only Sonic goes through this section, Tails skips it and doesn't get the flag set. Reloading the level, like by dying or entering and leaving a special stage, does correctly set the flag, but If Tails reaches the looping part without doing any of that, he'll hit the bottom of the level and die.

    • @Valientlink
      @Valientlink Год назад +1

      @@manjackson2772 Yeah I've since figured out how this works, but thanks

  • @kooijbas
    @kooijbas 2 года назад +1

    I love these video's. They have exactly the right amount of depth and complexity to make it interesting and technical, yet still clear enough to follow along.

  • @ryans5615
    @ryans5615 2 года назад +2

    I'm just commenting to say that the purple dot on Mega Man's chin makes it look like he's sticking his tongue out, like the Duck Hunt dog or something. I just can't get past it.
    Also, I do appreciate all the deep dives into the code.
    I know many years ago, I found a website where someone decompiled all the code for the Mega Man games, and gave it good function names, kinda like what you've done, so that people can go take a look. I think it got DMCA'd because I no longer have the bookmark when it was taken down. But the programming in MM1 and 2 is just spectacular. I think it got better with 5 and 6, but those also had bigger ROM sizes which made it a lot easier. Thanks for the series, enjoying the channel!

    • @DisplacedGamers
      @DisplacedGamers  2 года назад

      I was looking for some of that just to see if it was out there to help me along, but I didn't find a whole lot - at least for Mega Man 2. I kinda figured there would be more out there considering how intimately speedrunners seem to know the game.

  • @TheNei
    @TheNei 2 года назад +1

    Megaman 2 and 3 are amazing! Nice graphics, Sounds, etc
    -Thanks for this amazing vídeo!

  • @CoolJosh3k
    @CoolJosh3k 2 года назад +11

    I use that same Tile Detection method in my game Powers of Hex, except I have to deal with Unity’s reliance on floats, instead of carry bits.
    I have a arbitrary epsilon value that acts the same way as the carry bit would, but for detection.

  • @DouglasZwick
    @DouglasZwick 2 года назад +2

    This is so excellent! Another video that's like it's tailor-made for me. And I'm excited about the prospect of more MM2 videos to come!

  • @bluemilkboysgaming
    @bluemilkboysgaming 2 года назад

    This video is incredible. I took basic coding in high school and you were able to break this down enough for me to understand the concepts. The fact that you can comb and interpret code is amazing.

  • @mutexS4
    @mutexS4 2 года назад

    Your channel is BEYOND awesome. I LOVE your deep-dives and lovingly painstaking step-by-step explanations. I have such fond memories of playing on my beloved NES in the late 80s, and your exploration of the mechanics of games (such as one of my all time favorites, Megaman 2) peels back the curtain and reveals the magic that made these games so amazing and mind-blowing to a child of that era.
    It's so awesome to see the breakdown of the 6502 instructions that make these games work. Please keep making videos like this! They are the highlight of my day/week/month when they show up in my feed! The more technical the better!

  • @MangaDungeon
    @MangaDungeon 2 года назад

    I dont know anything about codeing but this is the coolest thing I've seen in my life.
    Subbed, will now binge

  • @infinitehush
    @infinitehush 2 года назад

    I love these videos so much! Looking forward to the Mega Man Talkin' Code follow up that's surely coming soon.....!?

  • @oracleoftroy
    @oracleoftroy 2 года назад +2

    I've been working on an NES emulator in my spare time, and the ADC and SBC instructions were the hardest parts of the CPU to get right. ADC was pretty easy to figure out what I had messed up, but SBC struck me as really weird and I didn't understand how the carry flag was being used until I found an old 6502 manual that walked through various examples (which made for a great test suit!).
    I can completely see a developer accidently clearing carry when they should have set it just before a subtraction! Its reassuring in a way to see that the makers of the games I loved growing up were confused by the same instructions that were giving me trouble. :)

    • @vuurniacsquarewave5091
      @vuurniacsquarewave5091 2 года назад +1

      And it only gets more confusing once you bring signed and/or 16-bit integers into the mix. Sometimes it's easier to ADC a negative value, and sometimes it's easier to negate a value and then SBC it. It all depends on what you're doing and whether you need the carry afterwards to make a decision.

    • @ArneChristianRosenfeldt
      @ArneChristianRosenfeldt Год назад

      I think that Intel does not invert the carry for sbb. Intel also always had sub and add ? Anyway, the first time I read about ADC, I thought that a common (automatic) optimization would be for code to either have the carry clear or to deal with it locally and then have it clear. So unless we do some modulo stuff like waterfall or vram wrap around we would never need two instructions for a simple add or sub. One more xor gate and we could be there. Pebble was probably proud that he saved a single gate ( still 8 gates for the operand are still needed ).
      I have to admit that rotate through carry can leave it in any state. I guess what I wanna say: why so many unused opcodes, but no ADD or SUB ??

  • @dionelr
    @dionelr 2 года назад +1

    Great job. I've seen this being done by speedrunners for years but had no idea the code behind it.

    • @TopShelfTheology
      @TopShelfTheology 2 года назад

      I'd seen that, and knew it had to do with squashing into hit detection in a wall instinctively. What I did not expect was it's bugged due to handling the edge case of disappearing/reappearing blocks, I never considered those.

  • @SkipperTheSuperGamer
    @SkipperTheSuperGamer 2 года назад

    Your fix for the zipping works *almost* perfectly. I say almost because there is one tiny little quirk with it. If you go through a boss door in either the jumping or "tip-toe-ing" state, there's a chance that Mega Man will be standing on the ledge of the boss room instead of falling down. I would think that the easiest way of fixing this would be to very slightly increase the speed at which Mega Man travels while going through a boss door, but I've no idea how to do that.

  • @michaelcalvin42
    @michaelcalvin42 2 года назад

    I saw that "Merry Christmas" in there, you jolly joker. Thanks for another great video!

  • @AtariSwitch
    @AtariSwitch Год назад

    I discovered "zipping" when I noticed I could get significant horizontal movement by holding a direction and then entering and exiting the menu, which got me above a ceiling in the Bubble Man stage. I thought I was stuck, but when I tried to go left I zipped to the other side. Great video!

  • @asteroidchan
    @asteroidchan Год назад

    Wonderful video. Been developing games for quite some time now, never took the time to look into older systems until recently. Very insightful.

  • @aurinator
    @aurinator Год назад +1

    Even more impressive is its soundtrack - best one IMO.

  • @Luigi1000
    @Luigi1000 2 года назад +1

    I know a few people, my self included who would be interested in an exploration of MM2's collision code despite it's length, but don't have the time or technical skill to go through it themselves. If it's ever on the table I would love to see it even if it was broken down into multiple part videos.

  • @wannabecinnabon
    @wannabecinnabon 2 года назад +2

    I'd be very curious to see the coding of Mega Man 3 and Mega Man 4 compared at some point in the future, to perhaps see what makes 4 run so much more smoothly. Great video!

    • @renakunisaki
      @renakunisaki 2 года назад

      Funny, MM4 runs smoothly, but it feels so slow because of the screen transitions... I wonder what the story is with those?

  • @StriderGW2
    @StriderGW2 2 года назад

    I love this video series, the detail and clarity is hugely appreciated

  • @philrottkamp
    @philrottkamp 2 года назад +14

    I’ve been speedrunning MM2 for over 4 years now. Zipping is fun but isn’t always easy, some vertical zips require a lot of effort and the Item 2 Bubble Man zip is extremely dangerous.

    • @f0ngers586
      @f0ngers586 2 года назад +1

      Dangerous and basically frame perfect. Can't decide what's dumber, wood man or item 2 zip. Wait it's neither, it's soft locking in the quick man boss room😭

    • @philrottkamp
      @philrottkamp 2 года назад +1

      @@f0ngers586 the soft locking is pretty frustrating, but after 4 years I’ve gotten better at it. Believe it or not, the Woodman zip isn’t that bad to execute - it’s really long, but with some practice and muscle memory, anyone can stand up to it.

    • @Jasonhoods
      @Jasonhoods 2 года назад

      I speed run on the legacy collection and it's so fun. On Xbox I hold 15th place on MM1 Megamix

  • @6mtzhp55
    @6mtzhp55 2 года назад

    Instant like, been waiting intently ever since the tweet!

  • @NrgSpoon
    @NrgSpoon 2 года назад +1

    I always find it fascinating to compare the speed between each Mega Man game. For example, think about how long it takes the boss health to fill up in MM4, compared to MM5. The same can be said for screen transitions. Mega Man 5 feels like the most well optimized MM game because so many of the incidental animations are so speedy.

  • @Dedicatedtolivinginthepast
    @Dedicatedtolivinginthepast 2 года назад +1

    I beat Megaman 2 kinda recently so it is super interesting seeing why some glitches I experienced happen!

  • @snowgoer540
    @snowgoer540 2 года назад

    This is awesome. I love these videos, and my OCD really appreciates that you provided and explained the fix too.

  • @graemevaughey7432
    @graemevaughey7432 2 года назад +8

    Oh, wow: a retro gaming channel that actually knows he's talking about? (rather than just another bandwagon jumper). Thank you. Subscribed.
    Incidentally, I've been programming an SNES game for a couple of months now, and I had a similar bug with exact corner collisions (a very difficult thing to catch in playtesting). Basically, I was testing _independently_ for top-edge collisions and side-edge collisions on my player sprite, which resulted in a very rare occurrence of single-pixel overlap with level tile corners if you happened to hit them from the exact right angle. Whenever this occurred, neither the top-edge (using the _old_ side-edge value) nor the side-edge (using the _old_ top-edge value) would read it as a collision, so it would be allowed... for that single frame. Immediately afterwards, however, the next frame would perform the collision check, find that the player was already penetrated into the wall, and attempt to rectify the matter by catapulting the player across the level (or zipping, as you call it). I had to add a bunch of visual debuggers, record the gameplay on video, and go through it frame-by-frame to even work out what was happening! Collision programming is a nightmare.

    • @TopShelfTheology
      @TopShelfTheology 2 года назад

      This is why my first coding project was implementing Battleship without a GUI, it was all in ASCII art, lol.

  • @travezripley
    @travezripley 2 года назад +1

    Yes!! Friday is gonna be awesome!

  • @matesafranka6110
    @matesafranka6110 2 года назад +2

    Oh good old off-by-one errors, the null pointer exception's little brother in the family of most aggravating bugs XD

    • @DaWhiteTyger
      @DaWhiteTyger 2 года назад

      Then, how many games can you exploit by this logic?

    • @matesafranka6110
      @matesafranka6110 2 года назад +1

      @@DaWhiteTyger That's pretty much impossible to tell without poring through the source code of every game ever. Plus, OBE's (off-by-one errors) can occur in just about any algorithm, not just collision detection, so they can cause any number of different bugs in different games.

  • @IntoTheVerticalBlank
    @IntoTheVerticalBlank 2 года назад +1

    Oh man, this is great. I'm making a scrolling shooter (Scramble) on right now on the Atari ST with 16x16 tiles on a scrolling background and this ia really helping me refine my collision detection logic.

  • @williamdrum9899
    @williamdrum9899 2 года назад

    7:20 Here we see the Hydra make its return from Blaster Master. Basically this is how a switch statement in C would be compiled into 6502 assembly. The advantage of this is that each case takes the same amount of time to process.

  • @brunomoreno3666
    @brunomoreno3666 2 года назад +1

    excellent video! keep the good work

  • @xfreakerx1
    @xfreakerx1 2 года назад

    Awesome! Perfect timing too, I'm working on collision and physics for a coding project!

  • @thedagit
    @thedagit 2 года назад +1

    I wanted to fix the bug where sometimes under the right conditions touching the side of the screen causes a screen transition where it normally isn't allowed. If you look up a mega man 2 tas you can find examples. The mega man 2 randomizer tends to cause the right conditions more often than vanilla and it was frustrating to players to touch a wall and accidentally get transitioned into some permastuck state or death.
    A japanese person had reverse engineered this particular bug (I think for TAS and speedrun purposes). The game tries to defer sound updates at certain times. I forget the exact conditions, but the analysis by japanese person was that the audio update code clobbers some of the registers. I think the code normally runs during an interrupt and thus registers are restored normally when returning from the interrupt handler. However, if the game were to run these routines in a deferred context instead of their typical context this would result in the Y register (I think?) having an essentially random value after the audio update. (Not actually random, but very hard to predict, the person I mentioned before was looking to make tools to predict the value to exploit it). The value in this register could, in some circumstances, be picked up by other routines as an input. One such routine could be the code that makes a judgement about transitions within a level.
    To fix this bug in the randomizer, I just replaced the jsr for the deferred audio processing with nops. The deferred audio processing typically happens during lag which means you can't really tell whether or not the deferred update happened. The end result is a rom where what we call "delay scrolling" is not possible and no noticeable impact on the audio experience.
    It's such an obscure bug that I think the developers simply had no way to test for it. We're quite fortunate with the modern tools we have.

    • @DisplacedGamers
      @DisplacedGamers  2 года назад

      Wow. That's some fascinating stuff, thedagit.
      Based on the development timeline as well as the "work on it as a side project" approach, I think a lot of code was "patched" instead of "developed" in order to get it done.
      At a glance, it seems like a lot of code operates under assumptions (i.e. "so long as this one thing doesn't happen...we should be OK on these other things that follow...) that aren't very safe assumptions.

  • @DaWhiteTyger
    @DaWhiteTyger 2 года назад +1

    "Collision is occurring right now. Can you see it? Here, I'll turn it off." Megaman passes through floor and dies. LIGHTBULB MOMENT, A-HA! (this is why I wasn't a coder... :( ) But, yeah when you asked the prior question, ALL of the things you spatted off I was thinking of. This is why I envy gents like you, I can handle the physics, but not the actual numbers and code.

  • @Amiculi
    @Amiculi 2 года назад +1

    Rude ass Megaman sticking his tongue out at us for almost the entire video, I'm surprised no one noticed to tell him to knock it off during filming!

  • @namco003
    @namco003 2 года назад

    I really appreciate these videos. While I'm not a programmer and have little knowledge of coding(I used to write my own games, and the ones I got in magazines on the Commodore 64 for fun when I was a kid), it's amazing to see all the hand written code that went into making these games possible. I don't get it, but I totally get it

  • @toffeeFairy
    @toffeeFairy 2 года назад +2

    Really enjoyed this one thanks

  • @fruitsnackia2012
    @fruitsnackia2012 2 года назад

    mega man 2 engine is the base code for the rest of the mega man games on the nes. i can confirm this cause i made a code to controll the pitch and speed of the sound and music in the game and these codes work on every mega man game except mm1 without changing addresses.

  • @kittah4
    @kittah4 2 года назад

    "To insert Mega Man into the ceiling". I lost it at this said with a completely serious and deadpan voice.

  • @atomicnoexcept
    @atomicnoexcept 2 года назад +1

    Such a great video. I learn so much from you!

  • @DaWhiteTyger
    @DaWhiteTyger 2 года назад

    ZIPPING?!?! Why haven't I EVER heard of this before now? And to think, I thought I knew most of what MegaMan 2 was able to be cheated upon... Thanks again for showing us "Behind the Code". I'd NEVER would have ever thought of, nor imagined this... Wonder if it still works in newer iterations of MM2.

  • @DarkHeroAkutare
    @DarkHeroAkutare 2 года назад +2

    "Here, I'll turn it off."
    wait no don't hurt him NO-

  • @VinsCool
    @VinsCool 2 года назад

    Oh joy, great video!
    Just in time as I was diving into 6502 ASM hell myself earlier today.
    Carry and Off by One errors were plentiful for me, but tonight I instead spent a full hour debugging something where a very specific condition triggered a glitch, only to find out an entirely unrelated section of my code had a STA instead of STX like it was intended, and by pure luck it was the very rarely not going to be a BMI branching so whenever I got the bits I needed this would incorrectly be set and then seemingly random effects occured inside of my code, which broke a lot of 16-bit addressing I had just made the day before as a much more compact code I rewrote to make it a lot faster.
    1 instruction, STA mistakenly used instead of STX, a specific condition, and chaos ensued, that was a fun hour tracking down what happened and narrowed it down to the single byte that was the culprit.
    I had a good laugh, and felt very stupid, but now my bug is fixed! Yay

  • @sanderbos4243
    @sanderbos4243 2 года назад

    Loved this breakdown!

  • @Video-Games-Are-Fun
    @Video-Games-Are-Fun 2 года назад

    I LOVE glitches! it's what made me love street fighter 2 (guile's shadow throw glitch was something I used in fighting all the time!) along with his handcuffs and dhalsim disappearing. they make the game that much more fun!

  • @Hylianpuffball
    @Hylianpuffball 2 года назад

    As somebody who has just started tinkering with 6502 Assembly, it is actually a relief to know that even seasoned experts would mix up CLC and SEC, and it's not just my poor baby brain spoiled by modern languages.

  • @reaper84
    @reaper84 2 года назад

    Great video. Please more videos on level data, and collisions with level map data in the future! :)

  • @guillermorodriguez836
    @guillermorodriguez836 2 года назад +1

    If you end up doing a MM3 video, I would love to see why holding right on Controller 2 changes the gameplay soo much. I’m sure you’d have a great take whether it was intentional or a glitch.
    Also, an explanation on being able to select the rush marine, and rush jet before gaining those same power ups.

    • @renakunisaki
      @renakunisaki 2 года назад +1

      I can't remember if it was 3 or 4 that accidentally left in some debug functions using controller 2.

    • @killerb255
      @killerb255 2 года назад

      @@renakunisaki It’s MM3

  • @renardleblanc5030
    @renardleblanc5030 2 года назад

    Speaking as a fine artist, one of the hardest subjects to tackle in figure drawing is "movement." This is the ability to depict (implicitly) the physical effort exerted by a human body to stand in place and upright, fighting against gravity. Effectively, the muscles are pushing the body *upward* at the same acceleration that gravity is pulling the body *downward,* which is *not* the same as being motionless, as such (for comparison, a reclining figure is not exerting muscle strength to fight gravity, the couch (or bed or floor or chaise lounge or dias) is doing that work for the figure... which is why a prone figure has a distinct appearance from a standing one, even if a viewpoint is positioned in the same angle/location relative to the figure). Similarly, a falling figure has a distinct appearance from a figure in freefall (skydivers look different from NASA astronauts... both are in freefall, but there are significant differences in how they exert effort to maintain or correct their posture/orientation).
    I bring this up, because @3:25 my first and only immediate thought was: "floor contact." Because gravity.
    Art and programming collide! :)
    Another good example of figure "movement" is mega mans "standing" sprite, which *looks* ready to spring into action, compared to his falling sprite, which is very clearly accepting whatever fate is be-*falling* him. (In freefall, a relaxed figure is not making an effort to resist gravity, hence no tension, ie no movement).
    Meanwhile: the graphic designer in me is screaming internally at that off-by-one "fencepost" error (if I have a page layout with 3 columns, and 1 gutter space between each, how many gutters do there need to be? Reflexive answer is 3, at a 1:1 ratio, the actual answer being 2).
    Bleaugh, I ramble. Fascinating video!

  • @juanoncho
    @juanoncho 2 года назад

    Thanks for this awesome video. Perfectly explained.

  • @HaveYouTriedGuillotines
    @HaveYouTriedGuillotines 2 года назад +6

    I bet you what happened is that he wrote both the left and right ejection back to back, copy and pasted a bunch of stuff, and tried to mirror the code logically. Since the carry and borrow function do the same thing in opposite directions, that ideally would work. ...But it didn't, as one is enabled by setting a flag, and the other is enabled by disabling a flag.
    Super easy mistake to make.

  • @awesomedata8973
    @awesomedata8973 2 года назад +1

    I love this series. -- This helps modern game programmers to understand the complexities of what people who programmed their favorite games had to go through. :D
    Please keep up these kinds of videos! -- You're teaching people how to (properly) program data-oriented code by showing off these bugs. :D

  • @paraflex5621
    @paraflex5621 2 года назад +1

    Great video! It's fascinating to learn what the specific programmer errors were that resulted in glitches I've known about for years. Another MM2 glitch that might be interesting to explore is the warp from boss room to wily stage gate glitch. Another collision detection issue?

  • @igodreamer7096
    @igodreamer7096 2 года назад +1

    Very interesting, never guessed that MegaMan could take a short cut through walls like that
    HAHAHAHA

  • @JamesLewis2
    @JamesLewis2 2 года назад

    I just tried editing the ROM itself to include the fix mentioned at 14:00 and it turns out that the code was at bank 14, location 38986 (or in an iNES dump, 38996); the relevant code is in the same place in Rockman 2. I haven't yet figured out where the analogous change would be in the other Mega Man games for NES, but I did find that the only place in the original Mega Man where STA $00 SEC (85 00 38) occurs is in a section about how Elec Man moves, and it's a bit tedious to figure out which SEC should become a CLC by reading a disassembly, so I think I'll need to fire the games up in MESEN to use its debugger.
    Also, making that change causes TASes to desync early on, because Rockman will be one pixel too far to the left to make a particular jump, because when falling against a wall just before that, the fix stops him one pixel earlier; still, it's how I verified that the fix at least did something without having to practice setting up a horizontal zip (so I could then check whether *that* doesn't work with the fix either).

  • @Twenty_Six_Hundred
    @Twenty_Six_Hundred 2 года назад

    I was using the ejection method with a homebrew game i was working on. Can't remember my code exactly however im fairly sure i scrapped it all together. Fairly sure i had a tile collision check before the input movement. So if the check detects an nonwalkable/solid tile the player movement input code was completely bypassed. Eliminated clipping issues, although i wasn't using any moving platforms that would create these issues of undesired player placement. I have noticed many devs use this method within the community and i did also. It can be buggy though and i understand for safe measures. I found with carefully placed X and Y cords along with collision data tables for tiles it's not really needed. For my projects anyway

  • @bkid8626
    @bkid8626 2 года назад

    Another great Behind the Code episode as usual. I swear I keep telling myself I'm going to learn 6502 assembly one of these days, and I will... One of these days.. 😑

  • @crtinkering7323
    @crtinkering7323 2 года назад

    Another top notch video!

  • @CarbonRollerCaco
    @CarbonRollerCaco 2 года назад +2

    So why would they make the chip so you have to SET the carry flag to clear borrow and vice versa? Is the bug really in the game, or the hardware running it?
    And that was some neat-o compression trickery there. You do what you can to save space.

  • @ValkyrieTiara
    @ValkyrieTiara 2 года назад

    This video was incredibly ineteresting! I would love to see more videos focused on explaining bugs (particularly speedrunning bugs, which would have the added benefit of more people being familiar with their operation making it easier for them to follow along). A possible candidate could be the double carpet speed bug in Mario 2?

  • @sr.metang8193
    @sr.metang8193 2 года назад

    Thanks for this! As a intermediate level programmer, it's amazing to see how people in the past did what they did with so much more limited resources than we currently have.
    But if I may ask one question: is this kind of code - written decades ago, by a professional programmer, hired by an AAA company, and part of a particularly successful piece of software - properly made with ideal programming habits in mind? Assuming, obviously, that there isn't a "correct", definitive way to code games, but rather distinctive logical checks and time/resource saving tactics that a less experienced developer would probably often miss or have no idea about, at all?

  • @sourandbitter3062
    @sourandbitter3062 11 месяцев назад +1

    I'd like to make a suggestion. I'd really like to know what exactly happens during the bug we call a delay scroll.
    I imagine it could happen because of a race condition? Causing a lag frame during a screen transition makes it so the next screen isn't loaded in time. And the code that does the transition is linked to the display of a new frame so it doesn't wait for the new screen to be loaded? I don't know, it must be more complex.
    And how can you create a lag frame? What operations should you chain together, what takes the most time to process? Item-1 2 or 3, a precise moment in the music, item drops, new enemies spawning etc? Is there randomness involved and if so can you manipulate the rng to help create a lag frame?
    Speedrunners could save about 8-10 seconds in Wily 1 by defeating the dragon with a delay scroll. At some point they could even try to delay scroll the last screen of Bubble Man stage, although that one looks to be crazy difficult, never been done RTA as far as I know. Finding a strat for this would be a huge change to the RTA run.

  • @kri249
    @kri249 2 года назад

    Totally worth the wait. If I knew about this in MM2 I would have exploited the hell out of it when I had it as a kid.

  • @ThaNikilist
    @ThaNikilist 2 года назад +3

    Love your videos! Any chance you could publish your commented code for some games? I'm curious to dig into them but starting off from the uncommented rom is a lot for someone who likes CS but didn't really study it.

    • @DisplacedGamers
      @DisplacedGamers  2 года назад +2

      Thanks, Nicolas. I may publish the comments at some point in the future but do not have plans to do so at this time.
      Some games have had their source code released or reversed (Mega Man 3 might be among those) that are out there right now. They might be a lot more comprehensive than the work that I have done as I try to do just enough for a video and then move along. Not sure how much people have commented on them. Super Mario Bros. might be a good one.

  • @createprince2093
    @createprince2093 2 года назад

    these videos are golden

  • @sHiNkAoLaSu
    @sHiNkAoLaSu 2 года назад +4

    hey, seriously, thank you for doing these, somehow, it feels like they're exactly at my level of understanding this stuff (took EE and CS as bachelor 20y ago)
    so yeah, I mean I do have some background, but the way you explain it is super clear and logical, at least to me^^
    thanks again and please keep them coming :) (Heard/saw the vid with Bob from retroRGB, it was funny/interesting you mentionned mister/fpga as a "dangerous topic" or something along those lines...I mean I get it, but I'm sure you looking at a fpga core to explain how a given game (arcade core/pcb?) or system does copy protection or scaling or cleverly whatever else would be super interesting, at least to me. (and it is a pragmatic way of saying fpga is only as good as you implement it, without triggering fanboys 😂)
    Greets from France!

  • @w00dyblack
    @w00dyblack 2 года назад

    so this zip at 14:31 - if the bug is fixed what happens when you try to do it - would megaman just not be able to go into the ceiling and get crushed and die ?

  • @Sixfortyfive
    @Sixfortyfive 2 года назад

    Even though it's probably a bit beyond the scope you'd like to do, a deep dive into Wily Wars on Genesis would probably be illuminating. It's a port of Megaman 1-3 that's kind of notorious for slowdown. In particular, it tends to chug whenever too many sprites are onscreen when the NES originals were more likely to just flicker instead. Knowing that the original code in the NES versions was more elaborate and taxing than a typical NES game sheds a light as to why that port runs more poorly than you'd expect on more capable hardware; the developers of that version probably didn't have the time or resources to properly reoptimize everything.
    What makes Wily Wars really interesting to me though is that the rerelease of that game produced by Retro-Bit in the past year actually *did* reoptimize the game. It doesn't get rid of the slowdown entirely but there's definitely a noticeable improvement.

  • @PizzerGames
    @PizzerGames Год назад

    1:45 But can't you only apply a color palette for 16x16 pixel blocks?

  • @spacepirateivynova
    @spacepirateivynova 2 года назад

    the trained eye (ie, mine, because i've made collision detection algorithms for my own games) when you turned off collision, you only turned off the floor collision. I noticed that as he fell through the floor, megaman went backwards a bit there... and that was the wall collider saying 'hey, you can't be in the wall!' and the right side wall that pushed him backwards has priority when megaman faces right if you only turned the vertical collision off and faced left, BOOM, zip would have taken over. That one pixel issue is VERY common in programming (ESPECIALLY in memory management. It's like you have to think of the 1st floor of a building as the 0'th floor) We also call it the 'fence post error', i have 10 sections of fence, how many poles to I need? or, I have a fence that's 100 sections long. I have to removed 5 fence posts for another project... how many sections of fence do i have left? both questions require different fence post problem management.
    As a coder, I HAVE to use a certain level of 'zipping' in there, I like to check every frame the following for the 'floor collision' and design it so that it works in as few frames as possible so the game feels very responsive compared tot other ways I've done it (including how I was origially taught)... keep in mind I threw this together late night and i don't know if it works... :
    ' some basic code for you --- yes, this should actually work in qb64
    ' for this we will make some assumptions --
    ' 1 - Screen space is x = 0 and y = 0 locates at the upper left corner of the screen (as per normal.)
    ' 2 - Our 'hero' sprite, model, etc. etc is 16 pixels tall, and his origin is the upper left, putting his feet between
    ' player.x + 2 to player.x + 14, and player.y + 16 (player.y + 0 is the first actual line of the sprite)
    ' We'll call that pfeet.y = player.y + 16
    ' 3 - we have the player at say, 100x, 100y, and a floor box that's 100 wide and 10 pixels high from
    ' 50x to 150x and 200y to 210y
    ' 4 - gravity accelerates up to a maximum fall speed. Player starts at 0 fall (at apex of jump?) and falls at a
    ' of y = y + .2 and maxes out as say, 5 pixels per frame.
    ' 5 - his will be in it's own subroutine called from the main game loop. I could write it as a function, but i'll keep it
    ' as a GOSUB -> RETURN to keep it simple.
    ' set up graphics screen mode:
    screen.res% = _NEWIMAGE(800,600,32) ' give me window, 800 wide, 600 high, and 32 bit RGB value color
    SCREEN screen.res%, 0, 1, 0 ' Set the display port to that screen resolution, and double buffer me
    ' -----------------------------------------------
    ' Initialize some variables
    player.x = 100
    player.y = 100
    floor.x1 = 50
    floor.x2 = 150
    floor.y1 = 200
    floor.y2 = 210
    grav.accel = .2
    grav.max = 5
    ' main game loop:
    WHILE InKey$ = "" ' When I hit any key exit.
    GOSUB draw.floor ' we'll draw the floor in first because we're going to trigger on the non-black area
    GOSUB detect.collision ' Check for floor
    GOSUB physics.player ' Apply physics
    GOSUB draw.player ' Draw our player... thing...
    GOSUB draw.snow ' BONUS LEVEL!
    _LIMIT 60 ' FPS limiter, QB64 makes this nice and easy!
    ' The following prevents flicker from the graphics blitting process
    PCOPY 1, 0 ' We draw to graphics page zero, send that to the visible page 1
    CLS 0 ' Clear the draw screen
    WEND
    ' ---------------------------
    END ' close the program so it doesn't error out when it blarrgs through the subroutines and functions
    ' subs start here
    ' Move the player
    physics.player:
    if floor.detect = 0 then
    if player.y.speed < grav.max player.y.speed = player.y.speed + grav.accel
    else
    player.y.speed = 0 ' a bit of redundancy doesn't hurt. just make sure controls work around that!
    end if
    player.y = player.y + player.y.speed
    pfeet.y = player.y + 16
    RETURN
    ' Check for the floow
    detect.collision:
    floor.detect = 0 ' reset fall detection flag
    for y = 0 to int(player.y.speed) ' how far the player falls in a frame...
    for x = 2 to 14 ' how wide the player's landing area is
    if POINT(player.x + x, pfeet + y) then ' boolean operator, if x/y point isn't black... then
    player.y.speed = 0 ' stop falling
    floor.hit = y - 1 ' the pixel BEFORE the first drawn floor pixel. Fencepost errors!
    floor.detect = 1 ' set fall detection flag
    end if
    if floor.detect > 0 then EXIT FOR ' STOP the looping if triggered.
    next
    if floor.detect > 0 then EXIT FOR ' Again, exit second loop (we are checking a 2d area for floor collision)
    next
    if floor.detect > 0 then
    player.y = player.y + floor.hit ' ZIP the player to the floor

  • @1990heaven_
    @1990heaven_ 2 года назад

    this is so freaking fascinating.

  • @dchardin1
    @dchardin1 2 года назад +3

    That part around 5:22 sounds familiar. I have been trying to get my head around that. It sounds a little bit like that Micro Mages video where the developers talk about the techniques they used to fit rich games into small rom sizes. I think they called it "meta-tiling?" I don't completely get it but it sounds like it's in the same ballpark, please let me know if I'm way off.

    • @madokalover
      @madokalover 2 года назад

      i think thats right. the genesis sonic games do the same thing to make their giant levels.

    • @thomasmathew13
      @thomasmathew13 2 года назад

      Yup. Similar to how micro mages does it. 8x8 is a tile, 16x16 is a meta tile, then they called 32x32 meta-meta tiles.

    • @vuurniacsquarewave5091
      @vuurniacsquarewave5091 2 года назад

      @@thomasmathew13 You can actually keep expanding until you reach 256x256 to directly address rooms. Of course the screen resolution is technically 240 pixels vertically but the memory space actually exists in the game logic.

  • @emmanueloverrated
    @emmanueloverrated 2 года назад

    Having written collision routines for games like MM2, I do understand the error he made. Now lets tackle slope collisions, it's going to be fun... :D

  • @Humbird00
    @Humbird00 2 года назад

    This game's approach to tile collision is surprisingly similar to how I handle collision in all of my own games.

  • @MissAshley42
    @MissAshley42 2 года назад +2

    There are two people who will forever seem like wizards to me: artists and coders.

    • @sr.metang8193
      @sr.metang8193 2 года назад

      Why artists? Now I'm wondering.

    • @MasterKnightDH
      @MasterKnightDH 2 года назад +1

      @@sr.metang8193 Because artists have imaginations and flow to get their work going. Coders, I'm guessing is a byproduct of the causes of Everybody Hates Mathematics.

  • @salvatronprime9882
    @salvatronprime9882 2 года назад +1

    Wow I never knew MM2 was so rushed. It seemed like such a well-made game for the time.

  • @warmCabin
    @warmCabin 2 года назад

    Wow. A one byte bug. That is truly amazing. Glad to know I'm not the only one who can't keep that carry crap straight!
    If you had to pick a zip to explain, I would do Good Wood. The route through the screwed up screen scroll logic still amazes me.
    Also...ever heard of delay scrolls?

  • @michaelwerkov3438
    @michaelwerkov3438 2 года назад

    But what is the NAME of the song playing? (At 8:30)

  • @GadgetUK164
    @GadgetUK164 2 года назад

    Wonderful video =D

  • @gresolio
    @gresolio 2 года назад +1

    Thanks for great videos :) Can you please make more content about Battletoads or/and Battletoads & Double Dragon? Rare did a fantastic job at the time, there are a lot of gems in Battletoads on NES.

  • @tunanoot
    @tunanoot 2 года назад +1

    I would love to see a video about how Flash Man's timestop works!

  • @MisterVercetti
    @MisterVercetti 2 года назад

    I wonder if this is related to the bug where, in certain boss rooms, if you're riding Item 1 next to the boss door and take damage, you end up getting pushed into the next screen, which is typically the first screen of one of the Wily stages, but with the current stage's graphics and attributes loaded in.

  • @aaendi6661
    @aaendi6661 2 года назад

    If the Mega Man games got slower as time went on, that pretty much explains the slowdown in Super Ghouls and Ghosts on the SNES. Probably used existing backwards compatable code from the Mega Man series.

  • @lukarikid9001
    @lukarikid9001 5 месяцев назад +1

    So they round down on both, when one should round up and the other round down?

  • @erikvincent5846
    @erikvincent5846 2 года назад

    Nice video. This was my favorite game of this series, primarily due to nostalgia. A code curiosity I had with Megaman 2 was why is the music all screwed up, if one uses a game genie? I don't know any other games that has this problem, but it does mess with the sound in mm2.

  • @diegocrusius
    @diegocrusius 2 года назад

    informative and entertaining thank you

  • @Zieldak
    @Zieldak 2 года назад

    Apparently Mega Man gets stuck on door ledges with this modification after scroll transitions if Mega Man enters the door via jumping or tip-toeing for some reason. Don't really want to dissect MM2 to find out why. But thankfully there's a value at 0x0390FF which is added to Mega Man's X position fraction every frame during a screen transition.