Log In  
Log In  

Cart [#56470#] | Code | 2018-09-10 | License: CC4-BY-NC-SA | Embed

Uncompressed Source Code: https://paste.ee/p/5KOG5 (warning: it's pretty gross)

Late last year (2017) I started work on a port of Super Mario Bros [NES] to Pico-8. The goal was to be authentic as possible to the original game, while working within the Pico-8 limitations. Something like Super Mario Bros Deluxe [GBC] (https://www.mariowiki.com/Super_Mario_Bros._Deluxe).

In the end I was able to get 1-1 and 1-2 mostly complete before starting to hit serious memory limits which make it seem near impossible to ship the full game.

With that in mind, I'm releasing it as-is for now so that people can check it out and see where it was headed.

If you are curious, the biggest factor for memory is the level data which is quite huge. At some point I'd like to document how my level authoring process worked, but for now you can check out this twitter thread of me slowly wittling down the level data size:


Update: I have managed to squeeze in all for World 1 now!

Music by: https://twitter.com/gruber_music

P#55697 2018-08-26 01:28 ( Edited 2018-10-22 00:03)

I'm not sure if you're already doing this or not, but as for level data goes in a mario game. It seems reasonable that you could just need to have the floor be a solid rectangle of tiles, so basically the only info you need is the tile type and then the location of the pits, which you just cut out. Then all that's just is the location of objects. It would be reasonable to assume you're already doing it this way. I haven't taken a look, but if you ever wanna bounce ideas on reducing data size, hit me up. I love that stuff. Maybe we could work out something cool.

P#55704 2018-08-26 02:35 ( Edited 2018-08-26 06:35)

@Cabledragon: That's actually similar to how the original cart did it, although I don't. I store map tiles using a kind of run-length encoding.

P#55705 2018-08-26 02:54 ( Edited 2018-08-26 06:54)

Really good job! Never played it on actual hardware but this works quite well. I don't remember goombas chasing you though.
P.S. If you released multiple cartridges on the same thread with different level data, you might be able to do all the levels. I don't know how well it would work, but it is an idea.

P#55771 2018-08-27 12:20 ( Edited 2018-08-27 16:22)
:: dw817

Trying out your MARIO, MH. Spot on graphics and feel.

I noticed when you are on a pipe, in the original game if you press down, Mario will crouch down. Does not do that in here - if you're going for authenticity. And - no castle to enter at the end of the level ?

Marvelous work what I've seen so far.

P#55775 2018-08-27 13:57 ( Edited 2018-08-27 17:59)

Run Length was my first idea but then when I got to thinking about how the floors are in mario levels, it made more sense to just have teh floor be a constant repeated single tile so no data is needed except for the type of tile and the location of pits. Then for other objects or groups there of you could story their values and positions and have a lot less data on your hands and then frmo there you could FURTHER compress with some RLE stuff.

P#55777 2018-08-27 14:13 ( Edited 2018-08-27 18:13)

I noticed it doesn't revert back to the mushroom powerup when you get hit with a fire flower. Just a small difference, although it makes it a bit harder.

P#55826 2018-08-28 17:35 ( Edited 2018-08-28 21:35)

@hw2002: The goombas don't chase you. They just walk forward and change direction when they hit stuff.

Releasing multiple carts is probably how I would do it. I can fit about 10 levels per cart right now but there are still some additional objects to implement which may reduce that number.

I'm not sure about going back to Mushroom when you get hit. I thought I checked what the original did and copied that but I might be mistaken. Confirmed: Mario always returns to small Mario when hit by an enemy in the original game.

@dw817: Thanks! You are correct. Duck and end castles are 2 things I cut for space.

@Cabledragon: if I come back to the project I probably give that repeating floor idea a try to see how it affects memory and token counts.

P#55872 2018-08-29 20:46 ( Edited 2018-08-30 04:19)

IIRC the original SMB game uses a "templating" strategy for its levels: the tile data is defined as large objects like "pipe", "stairs", etc. and then pasted into the scene at the appropriate x scroll position. The levels are actually tiny when using that strategy since so much template content gets shared, and it explains the existence of the "minus world" and similar invalid yet playable levels.

However, the original cart is also 256kb so that probably still won't get you to the full game.

Edit: Actually, it's 32kb so maybe? SMB3 was 256kb.

P#55900 2018-08-30 19:53 ( Edited 2018-08-31 02:19)

@triplefox: yes, the compression on Super Mario is like that but even more complex. The X,Y coordinate of the object also defines the object type, and what all the bits mean.

So an object of Type 1 at Y position 0 might be a coin, but object of Type 1 at Y position 32 might be a flag pole. It's all very clever and based on all the mutually exclusive information the designers knew about the game (eg. you can't place a coin below the floor, so we can use that limitation to say "coin below floor" means "flag pole" and flag poles are always at the same y position so we can ignore the fact that it is positioned below the floor).

It goes a step further to break up the meaning of each bit of the object such that the first few are the page, the next few are position on that page, and then the last few can mean different stuff depending on the object type.

I did dig into that quite a bit and implemented a first pass. It saved good chunk of compressed memory, but added a huge amount of tokens to handle all those cases. It was pretty neat though: being about the copy raw Hex data out of the ROM, and into Pico-8, and see it load the level. :)

P#55919 2018-08-31 01:02 ( Edited 2018-08-31 05:12)

Small update (version 0.1.2):

  • Added moving platforms to World 1-2.
  • Implemented placeholder warp zone in 1-2.
  • Added proper ending to 1-2.

This makes the whole experience feel much more complete.

P#55921 2018-08-31 01:10 ( Edited 2018-08-31 05:10)

@mhugson I have a working version that use my good ol' json parser. It clocks at ~7300 tokens (started from the pastebin version).

note: I didn't dig too much into it, but the whole hex to map thing could eventually be replaced by a json number array + RLE encoding (as the json parser already supports hex&number string to values)

P#55925 2018-08-31 04:11 ( Edited 2018-08-31 08:11)

@freds72: That's pretty cool! But 7300 tokens sound like a lot, isn't it? That only leaves ~900 left for the game itself.

P#55991 2018-09-01 00:33 ( Edited 2018-09-01 04:33)

Aha! nope - this is the same game minus ~450 tokens!

P#55993 2018-09-01 02:17 ( Edited 2018-09-01 06:17)

@freds72: oh haha sorry. I totally misinterpreted your post :D

So what did you change to save those tokens? Would you mind posting the p8 file somewhere so I can do a diff?

P#56009 2018-09-01 13:42 ( Edited 2018-09-02 04:18)

Hi Matt, really enjoyed playing this. I appreciate the design choices you have made, particularly the white look-out circles, and the sound effects (I think the shell kicking sound is more similar to the later games?). Here are a few of things I noticed that seem out-of-place:

  • At the end of the level intro, there is a frame displaying the actual level in the wrong place
  • The mushroom/fireflower blocks yield a coin if you hit them again (I quite like this one!)
  • Mario's collision dimensions are larger than the original game (in SMB Small Mario is 12x12px, not sure about Super Mario, maybe 12x24px)
  • The small coin at the top is distorted (sspr?)
  • The controls are inverted (may be a matter of preference, but on my 360 pad, I expect the bottom face-button to jump)

Really impressed at how faithful this recreation is.

P#56182 2018-09-04 17:34 ( Edited 2018-09-04 21:36)

@Lafolie: Thanks for the thoughtful critique!

"At the end of the level intro, there is a frame displaying the actual level in the wrong place"
Yah, I know what you're talking about. Looks like a frame hitch while it loads the level or something. I'll get to it some day... :)

"The mushroom/fireflower blocks yield a coin if you hit them again (I quite like this one!)"
A bug for sure, but I like it, so I think I will keep it!

"Mario's collision dimensions are larger than the original game (in SMB Small Mario is 12x12px, not sure about Super Mario, maybe 12x24px)"
I'll need to double check but I thought I made sure this was accurate to the original.

"The small coin at the top is distorted (sspr?)"
Yup, it is the regular coin scaled down with sspr. Gotta save sprite memory wherever I can!

"The controls are inverted (may be a matter of preference, but on my 360 pad, I expect the bottom face-button to jump)"
I use "A" and "B" which is correct, but if you use "X" and "A" it's backwards. I'd like to do some so of key config if possible. But i'm sure i won't have the tokens for it!

P#56253 2018-09-06 00:51 ( Edited 2018-09-06 04:51)

This is very impressive. Fantastic work!

P#56335 2018-09-06 19:25 ( Edited 2018-09-06 23:25)


The latest version of the game now includes:

  • All 4 levels of World 1
  • All enemies of World 1 (incl. Bowser!)
  • All Power-ups!

I had to remove some features to fit it all in, but I think it feel pretty complete at this point.

Give it a play-through, and let me know what you think!

P#56471 2018-09-10 00:46 ( Edited 2018-09-10 04:46)

This is incredible! It's so close to the original! Even the music is good. I didn't think this kind of thing was possible on Pico-8.

P#57678 2018-10-08 04:26 ( Edited 2018-10-08 08:26)

You get hit even if you touch a transparent pixel.

P#58224 2018-10-21 20:03 ( Edited 2018-10-22 00:03)

[Please log in to post a comment]

About | Contact | Updates | Terms of Use
Follow Lexaloffle:        
Generated 2019-03-22 20:08 | 0.104s | 4194k | Q:69