Romhacking => Newcomer's Board => Topic started by: Marscaleb on January 28, 2014, 12:02:36 pm

Title: Reverse engineering MegaMan's controls?
Post by: Marscaleb on January 28, 2014, 12:02:36 pm
Does anyone have any information about (or discovered by) reverse-engineering Mega Man on the NES?

Okay, here's what I'm looking for.  I'm creating my own 2D sidescroller.  I'm looking at a number of the classics for inspiration, especially in the basic gameplay.  The basic gameplay and controls are the most critical, because without that, the game simply isn't fun to play.
So I'm trying to copy out some of the game control from classic titles, and right now I'm working on jumping, and I've got my eye set on Mega Man, specifically Mega Man 5 (since #2 feels just a bit too loose.)

Simply looking at and trying to emulate those controls isn't getting me as far as I'd like.  I'm juggling too many variables and still getting things just a bit off.
My next step would be to record some high-quality video and go frame-by-frame to analyze how much he moves every 1/30 of a second.  But honestly, that's not very exact, and it takes a lot of effort to find out how to re-create that.  So I began to wonder if someone here has tried to adjust exactly how the game runs, or can take a look inside and retrieve some specific numbers.

I mean, how did that game handle the physics of its jumping?  I'd really like to get my hands on an equation or a function for exactly how they figured how fast Mega Man should be falling, how they applied the force of him jumping, and how they handled a lot of the controls like getting him to stop when the player released the button.

Modern physics engines just apply too much realism, so I need to hard-code my character's behavior anyway.  I might as well base that behavior off of a game that was fun to play.
Title: Re: Reverse engineering Megaman V jump/fall timings
Post by: FAST6191 on January 28, 2014, 02:03:20 pm
First from I have seen Megaman does have tight controls but more importantly it seems to be that in combination with the memory/puzzle of the levels that sorts things for most people, certainly having gone through a few basic attempts at level hacks (which would not change the controls) the experience is not the same (and, some GB entries aside, I have not memorised things for any megaman game). That is perhaps besides the point though.

Personally I would go with the capture footage and analyse it routine, fiddling around with the game functions is likely to see you step through an annoying timer/accumulator routine and that is never fun. To make life easier you might wish to drop some of the backgrounds/layers (or blank them out in game). The main problem there will be if the game has a "lag" camera (the later megaman zero titles on the GBA seem to have this) or you pick a bad reference point (I just checked with megaman and bass and it seems there is a leg animation that gets in the way), but if you then figure out what layer you can keep as a reference and pick a good reference point on the sprite it should be fine.

To a point the longer you hold the button the higher you jump. This may seem obvious but it is a thing that would have to be programmed. In megaman as well you have things like Rush Spring that might provide a set amount of bounce.
Air control. In real life in a gas you do not tend to have this unless you are skydiving or have the means to move a large volume of air. In the game you behave more like you are in a liquid and can stop, turn and more in mid jump.
Gravity. Until you hit terminal velocity gravity keeps accelerating you. Here you hit that speed (or a speed limit) after less than a sprite height of falling. I will have to find one of those multiple falling screens (ones that usually have a spike pit at the bottom or an energy can halfway down on) or make a cheat to do a proper test, megaman and bass seems to have this though.
Gravity also acts more properly in the normal jumping. I watched the OAM values in megaman and bass (by the way if you did want exact things to make an equation for then plot those) and it appeared to act like it would in real life (rapid launch, slowing to a stop, then accelerating in the reverse manner, you can see it where the sprite in question will hang more at certain ranges of values and almost skip through others), or at least real life as defined by the basic equations of motion for constant acceleration. You could probably approximate it with the other gravity thing using a linear equation or a sine curve.
Even ignoring the air control stuff it does not appear to obey the first law of motion (object in motion stays in motion, stand on a horizontally moving platform and jump) in the megaman and bass game I checked, or from what I can recall of the others. According to "Weight: 105 kg (230 lbs)" which means the third law might apply at some points but you can probably ignore it, the game certainly seems to.

I also noticed a wind mechanic. On that theme damage makes you invulnerable for a very short while, which could play into puzzles/solving rooms.

Going back to the first the button immediately launches a jump but holding in when in the air changes things, you can demonstrate this by turning on autofire for jump.

This is fairly similar to a lot of old school platformers I find, things like prince of persia and maybe games with a ledge grab mechanic usually being the main things to differ.

Functionally you can reduce this down an awful lot. Doing so might not allow you to finesse the values though.
Title: Re: Reverse engineering MegaMan's controls?
Post by: Marscaleb on January 28, 2014, 03:28:48 pm
There was a lot I did simply by observing the game in play, but I'm really hoping to find some real numbers.

What I did in my last incarnation was to amplify the downward momentum of my main character, because merely increasing the gravity failed to do that.  Probably because I was using an engine that ran a lot of physics, and realistically, increased gravity does NOT equal increased falling speed.  In that same incarnation, I simply applied a force to the player when he jumped, and mostly let physics handle the rest.  To get control over the jump, I checked for when the button was released, and when it was, I simply directly changed the current velocity in Z to 0, and let gravity (and my accelerated momentum that was added every frame) do the rest.

Horizontal movement is simply the exact same every frame, whether in air or on ground.

But the problem with that system is that it was running everything off of modern physics engines.  You don't jump like you used to because they are using more advanced and more precise calculations, taking into account far more variables.
That's why I'm changing my system to calculate everything in my code.  And since I'm emulating calculations that were so much simpler, I shouldn't have a problem doing this.

Mega Man has a terminal velocity.  Fantastic.  But what was it?  How was it calculated?  Hell, how did they figure any kind of speed at all?
Title: Re: Reverse engineering MegaMan's controls?
Post by: tomaitheous on January 28, 2014, 06:03:51 pm
There's Megaman 1 disassembly in the doc's section. It's commented too. Should be able to find out everything you need from there.
Title: Re: Reverse engineering MegaMan's controls?
Post by: Marscaleb on January 29, 2014, 11:39:39 am
Wow, I'd need someone to translate that.  There're a few various bits of text in plain English, but mostly it's just a bunch of hexidecimal and punctuation.  Is this what assembly looks like?  It's more than I can chew.
Title: Re: Reverse engineering MegaMan's controls?
Post by: Madao on January 29, 2014, 06:43:49 pm
If you knew assembly or were willing to learn it, I recommend debugging the game. That's how I learned about a few games I played, like Megaman X for SNES. I also use cheat engine to do memory editing to see what it's like to change the game physics. It was fun. I believe it's very helpful to see the actual numbers, rather than solely relying on what you see on the game screen while playing.

I can learn so much about a game, just by finding the memory location of a few variables  :) .
Title: Re: Reverse engineering MegaMan's controls?
Post by: Marscaleb on February 10, 2014, 11:35:29 pm
Well, I wound up recording some footage (which turned out to be a bigger hassle than I thought. :P ) and tried measuring the distances in each frame (which wasn't exact because my footage was a little blurry.)
After analyzing the numbers, while I didn't get a direct pattern, it was easy enough to extrapolate what the correct pattern is, after granting some tolerances for my inaccurate recording methods.

I'm sharing the results here, in case anyone is is curious, or comes looking for this information in the future.

Quite simply, gravity increases downward velocity by one pixel-per-frame each frame.  Jumping seems to add 10 ppf to the velocity, (although collecting data for the initial frame seems to vary).  This works out so that the distance traveled in each frame for a standard jump is:
0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0
which translates to the player's distance from the ground being:
0, 10, 19, 27, 34, 40, 49, 52, 54, 55, 55, 54, 52, 49, 45, 40, 34, 27, 19, 10, 0
Measured to the bottom of the player's foot.

Terminal velocity is 15 pixels per frame, which is reasonable since the collision blocks are 16 pixels, and if an object traveled faster than 16 pixels per frame it would pass through a whole block without being detected.  It is likely that no object in the game can ever exceed that speed in any direction.