We were required to clone a game as our first project in the Game Project course. Our group was made of three students, 2 programmers, and one artist, and we chose Super Mario Bros(SMB) 1985 as our goal. Artist Lari was responsible for all the art resources and sound, Sina for levels and enemies and I developed the camera and main control of Mario.
Initial Idea
It's always not hard to implement all the basic functions in SMB. But I realize that it might take lots of time on tuning parameters to make it feel exactly the same as SMB. So I decided to list all the parameters related to the Mario movement. After I implemented all the functional aspects and then tuned parameters to make it feel right.
At first, I list those parameters:
After I have finished my code, I started to record videos of Mario Jump, Mario Walk, Mario Dash, etc., and analysis them frame by frame trying to calculate the above parameters. If we look at the equation:
We can solve this equation and get v_0 and a with only two pairs of s, t. But this could be inaccurate since the position of Mario is not continuous in the game but updated according to frame rate. So, it's better to get all the data points and fit the curve with linear regression.
It looks nice after I got all the parameters using this method and put them into our game. But I found that Mario can't jump between these two pipes using dash jump in our game, which could be done in the original game.
I thought this might be caused by different jump speeds during the dash. But after I analyzed the dash jump curve, I found not only jump speed but also gravity changed. I realized that things could be far more complex than I thought.
SMB's Physics
After I found out that both initial jump speed and gravity would change according to horizontal speed, I thought it would be too much effort to analyze all conditions. Thanks to god, my teammate sent me an article that gave us all the parameters of SMB's Physics.
If I didn't look at this article, it will take much more effort to make it feel right. Not only both gravity and initial vertical initial velocity will change according to horizontal speed, but also there is another parameter called air momentum, which is horizontal acceleration in air, that will change according to the current speed.
It's always interesting to think about why designers make things so complicated. Let's look at the first chart which shows the relation between gravity, initial jump velocity, and horizontal speed. We can plot the curve of Mario holding "A" jump as the following chart.
We can find that actual dash jump and walk jump spend the same time in the air, but the distance they jump is different because of different horizontal speeds. This gives players better control of when Mario will reach the highest point. And designers grant Mario with larger initial jump velocity and also larger gravity to ensure Mario reaches the highest point at the same time with greater height. If players want to jump to a block tile, using dash jump will have a bigger available time slot compared to walk jump, so players don't need to carefully calculate jumping-off points. This mechanism encourages players to use dash jump.
How to implement an accurate jump
After I have implemented Mario jump and adopted all the parameters according to that article. There are still some bugs. My Mario even can not jump onto the first platform. My parameters and mechanisms are exactly the same. But why?
I found the answer in a GDC talk: Math for programmers: Building a better jump. This is because I implement jump with Euler integration, which is not accurate and will be influenced by the frame rate.
It's better to use Runge-Kutta 4 or Verlet to implement jump. But it would be expensive to implement that algorithm. In our project, I just tunning the parameters a little bit bigger.
Final outcomes: https://awesomew.itch.io/supermariobros-clone
Comments