How does SMB level compression work?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

How does SMB level compression work?

Post by DementedPurple »

A while back on what I think was the "Don't understand nametables" forum, someone said that SMB (Super Mario Bros. in case you don't know what SMB stands for) uses a form of level compression and that it was probably too complicated for me to understand. Well, I think I'm ready to learn about this, because I want to make a more complicated game then pong.
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Re: How does SMB level compression work?

Post by adam_smasher »

By SMB, do you mean Server Message Blo...oh, Super Mario Bros., I see.

Have you made Pong already then? Even if you have, it'd probably be better to try to make Mario Bros. rather than Super Mario Bros. Even Nintendo had to take baby steps!

Anyway, you don't need to know about SMB's particular level format. That was the approach that Nintendo took to get their game to fit into the particular constraints they had. If you're making a different game, and have different constraints, you're free to approach level storage in whatever way you choose.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How does SMB level compression work?

Post by tokumaru »

SMB's level format is kinda complex and restrictive, and not really needed if all you want is to make a clone of that game. You'd be much better off using a compression format of your own creation and use bankswitching (something simple like UNROM) if you can't fit all the maps you want in 32KB. So yeah, I'm with adam_smasher.
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How does SMB level compression work?

Post by DementedPurple »

I don't want to make a clone of that game, I want to make a game that's similar as in it has large scrolling levels and I don't know how I would fit these level into 32 kilobytes of space. I don't really care if it's the level compression the Super Mario Bros. used, all I care is if it's a form of level compression one way or another. I was just asking for the Super Mario Bros. way of doing it because I assumed it would be less complicated then all of the other ones.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How does SMB level compression work?

Post by tokumaru »

DementedPurple wrote:I don't want to make a clone of that game, I want to make a game that's similar as in it has large scrolling levels and I don't know how I would fit these level into 32 kilobytes of space.
Why are you creating this artificial limitation of 32KB? Back when SMB was made there was a reason for such a limitation, but nowadays you can easily use bankswitching and not have to deal with such a convoluted level format.

SMB's level compression is based on objects, meaning that each screen is initialized to a mostly blank template and is then populated with "objects", which are block-based structures of varying dimensions drawn at specified X&Y coordinates.
I don't really care if it's the level compression the Super Mario Bros. used, all I care is if it's a form of level compression one way or another.
The ideal level compression scheme is the one that takes advantage of the redundancy that exists in the kind of structures the game uses. But for beginners, it's best to go with simpler formats that are easy to encode/decode, so as to not dramatically increase the complexity of the program or the tools used to design the levels.

For side scrolling games, I always recommend a column-based approach: create a dictionary of columns and then reference those columns to create level maps. This results in decent compression ratios but is still dead simple to code, and you can easily build levels without using any tools (just type it all as .db statements).
I was just asking for the Super Mario Bros. way of doing it because I assumed it would be less complicated then all of the other ones.
If you really need to know it, SMB's level compression is pretty well documented (here, for example), so there's no need to repeat any of that information here. IMO, it's actually fairly complicated and restrictive, and that's because they needed to cram a lot of stuff in just 32KB.
tschak909
Posts: 142
Joined: Mon Jul 03, 2017 4:37 pm
Contact:

Re: How does SMB level compression work?

Post by tschak909 »

meh, SMB's level format looks like a typical "figure out exactly what you need, and how often you need it, and design exactly that" solution. :)

-Thom
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How does SMB level compression work?

Post by tepples »

tokumaru wrote:You'd be much better off using a compression format of your own creation
Rephrasing: What would "a compression format of your own creation" look like for level geometry and data rates comparable to those of Super Mario Bros.?
tokumaru wrote:Why are you creating this artificial limitation of 32KB?
tries to construct a plausible reason for the limit
My first guess is remaining eligible for the main NESdev Compo category, which allows UNROM of up to four banks or BNROM of up to two. If UNROM banks 0 and 1 are full of CHR data that gets decompressed to CHR RAM and the music engine and data respectively, only banks 2 and 3 remain for the game including its level data.

So anyway, here's how a format similar to that of Super Mario Bros. might look. I'm more a fan of the concepts behind it than some others might be. Each level has four layers: objects, terrain, wall, and clouds.
  • Clouds is a repeating pattern of columns 16 to 64 metatiles wide. Each column contains one of sixteen objects at one of sixteen heights, with the rest of the column empty. This is used for hills, trees, fences, and the like. In SMB, each object is 3 metatiles tall, and the pattern is always 48 metatiles wide.
  • Wall is a repeating pattern of metatile columns the height of the level (13 metatiles). SMB uses it for the water background, water-filled pits, and the rear wall in 8-3, though you could use it for (say) the interior of a room. If you use wall for an interior, consider putting in a switch per level type to put clouds in front of or behind wall so you can cut windows in the wall.
  • Terrain is one of several 16-bit bitfields that are drawn into a column, one byte per metatile. Many long horizontal runs of bricks are terrain.
  • Objects are a list of things built out of blocks and placed at particular coordinates. Each is two bytes: 4 bits for X, 4 bits for Y, 7 bits for what is at that position, and 1 bit for whether the object is the last on this screen's worth of level data. Y locations below the screen correspond to special objects that, for example, change which wall or terrain applies to a particular part of the level or change where a pipe goes.
Super Mario Bros. 3 and Super Mario World use an object format with 3 bytes per entry. This includes an additional bit for Y (because levels are twice as tall) and additional bits for what's at a position (so that individual objects can have a size that isn't hardcoded). They need this because the "terrain change here" abstraction starts to break down when level decoding doesn't proceed uniformly from left to right.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: How does SMB level compression work?

Post by dougeff »

I briefly discussed this before.

viewtopic.php?f=10&t=15283&p=185353
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does SMB level compression work?

Post by rainwarrior »

I'm actually pretty surprised that the exact format isn't on Data Crystal, which is where I'd normally look first to see if someone has compiled such information:

https://datacrystal.romhacking.net/wiki ... Mario_Bros.

There does seem to be a suitable document on RHDN, though, which is the second place I'd look:

http://www.romhacking.net/documents/76/
http://www.romhacking.net/?page=documents&game=709
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: How does SMB level compression work?

Post by Sumez »

tschak909 wrote:meh, SMB's level format looks like a typical "figure out exactly what you need, and how often you need it, and design exactly that" solution. :)
Welcome to 8bit console game development.
Post Reply