New games every week!
Little Levels Blog
14th December 2013
Over on the Monkey forum, a discussion about level data set me off thinking about making this post.

Whenever I put levels into my games, I tried to keep them as small as I possibly can. I've been doing it this way for years, and always figured it's nice to compress my data into something that's easily shareable.
.. True, I rarely ever get around to actually making these things easily shareable, but for the most part I try to keep things as minimal as possible.

-=-=-

Take Alien Deathmatch as an example.
In Alien Deathmatch, the level data was a simple .png image, with simple black and white areas defining the map.
Instead of having a "proper" map editor, the user would simply doodle on a .png image, and the game itself would figure things out.
Where a "Floor" met a "Not Floor", the level loader would figure out exactly what sort of wall tile should fit between the two, and as such the user never needed to mess about with anything complicated.
This also has the side effect of leaving the level data as small as possible.


The data is tiny, the level is only 737 bytes because I'm trusting the .png file format to compress it, and I'm using just a few colours to define my map.
In play, the loader reforms the data from simple to complex, and the end result is much nicer to look at.


The same goes with other games, and although I tend to stick with .png image data, I'm also a fan of using ASCII data to store my level maps.

JNKPlat uses ASCII maps, and they're simple enough to understand, too.
Most of the level is made up of 0's, which is nothing. 1's are the red floor bars, 2's are walls, 3's are ladders and S is the start point.

Other things like Baddies are similarly defined. B is usually a Bat, and is placed within an enclosed area of the map. As the level loads, the engine figures out where the bat can and can't go to, and stores that data in it's object, in memory. The saved data is kept simple, but the internal memory includes all the complexities of the AI, like the bat's animation frames, and current movement, and all of that stuff.
Basically, instead of trying to cram WAY too much useless data into the level map, I simply get the loader to figure out what needs doing, and let the map be as small as possible.

Once the data is formatted as ASCII data, I can then compress it with my JNKrunch functions.
JNKrunch takes a string, and counts repetitions, so instead of having "00000", it simply says "50".
It's not the world's most complex compression system, but since JNKPlat tends to have a lot of similar tiles next to each other, it means that the data comes out a little smaller.

The most recent edition of JNKrunch is available here for Monkey or BlitzMax.

The resulting single-line string of data can then be placed wherever is necessary.
In Monkey's case, I tend to create a large function which returns a string of level data, as requested.
Function FetchLevel$(fn)
Select Level
Case 1 Return "C0A3A0A2B0A4A0A3A0A2 D0A3A0A2B0ASA0A3A0A2 A0G1"
End Select
End Function

A simple JuNKrunch of the data, followed by a scan through to reform the text into the level, and the game is up and running in an instant. No XML or anything fancy like that. Everything is tiny, and fits neatly into the compressed exe/apk/whatever.
Small neat little lines of text that can be posted to forums, or tweeted, or shared in files... If I can be bothered to implement that!

Remember folks : Smaller is better!
If you can rethink your data in the smallest possible format, you'll find it much easier to work with, and you'll probably have a bit of fun playing with all the possibilities!
Views 26, Upvotes 5  
Daily Blog
New games every week!
Site credits : This was all done by Jayenkai
(c) Jayenkai 2023 and onwards, RSS feed 81

Blog - Little Levels - AGameAWeek