- © 2010 - 2012 DesuraNET Pty Ltd. All Rights Reserved. Looking for work, ideas man.
- Privacy Policy
- Terms of Use
2 comments by AndySchatz on Nov 17th, 2010
Original post on facebook: LINK
Please geek out with me for a second. I'm not the first to use Steganography to encode game data in easily shared images. I believe that title belongs to the Spore folks. Doesn't make the concept any less cool.

It's a message hidden in another message. In Monaco's case, all of the data that describes a level is hidden in the side-view image of the level itself. What's cool about this? Well, when people make their own levels in Monaco and they want to share them, they can just pass around this image file. I can also host an online repository with user-created levels and you will be able to browse through the levels by looking at the level images. You can get a sense for how big the level is, what time of day it is, whether it is well-crafted or not just by looking at this preview.

And the I use the level data to generate a side view of the level:

And each level has a unique foreground image:

So on the level select screen, I can composite these elements, along with a few other doodads, and then apply a bloom filter to get:

The way levels used to work in Monaco is that there would be an XML file (this is like a text file, for those less techie folks) that contained the basic information about the world. Here's a link to a sample:www.pocketwatchgames.com/Mwyim/images/blog/Prison.xml
This file would then point to a different file containing the actual level data for each floor of the mission. Here's a sample:www.pocketwatchgames.com/Mwyim/images/blog/Prison0.xml

All that junk is actually the level data.
It's run-length encoded, which means that it's really just a whole bunch of numbers mashed together, alternating between the tile-type, and then the number of that tile-type that are in a row. (more about RLE here: En.wikipedia.org) RLE is great for Monaco because every map contains a 53x40 grid of 4 layers of tiles. The Floor layer tends to have fairly long runs of the same tile-type, and the other layers have fairly long runs of blank space.
But I didn't want people to have to pass these meaningless files around if they wanted to share levels. That's not FUN! It's way more fun to pass around these little images!
Remember that Steganography is about hiding messages in other messages. For us we want to hide it in such a way that you don't even notice.
Every pixel in an image is composed of 4 8-bit values, describing how Red it is, how Green it is, how Blue it is, and how Transparent it is. That means that the color and transparency of every pixel in an image is described by 32 binary numbers: 1's and 0's. The first 8 are for Red, then the next 8 for Green, then Blue, then Transparency.
That means that we can have up to 256 shade of red, green, and blue. But when you combine all these possibilities together, you get 16777216 different color possibilities.
In binary, the first digit of the number is the MOST SIGNIFICANT BIT (bit.. bit.. bit... echo echo echo). So a red value of 10000000 is actually halfway up the red scale, despite all those zeros. Modifying that bit will change the color of a pixel drastically.
The last digit is the LEAST SIGNIFICANT BIT (said in my chipmunk voice). So a red value of 00000001 is nearly black, it has 1/256th of red in it.
So if we only modify the least significant bits of the R, G, and B values of each pixel in the image, the viewer probably won't even notice! We're only shifting the shade by 1/256th!
So all I'm doing is I'm taking all that junk level data from above, and spreading it like butter across the least significant bits of every pixel in the image. Considering that the image is 1060x480 pixels (508,800 total pixels) and I have 3 colors which I can modify (I probably don't want to screw around with the transparency data in the image), that means I have 1,526,400 bits to work with. And if I run out, I can always move to the SECOND LEAST SIGNIFICANT BIT!!!
Since I compressed my data with Run-Length-Encoding, I've never actually had to move beyond the least-significant bit. The player will never notice! Especially with all that bloom and other junk obscuring the image.
You can really only see if if you take the image into an image processing program, remove the alpha, zoom in, and increase the contrast/saturation drastically!




Notice in the last image how there is a barely discernible horizontal line in the noise. That's the end of the level data. What this means is that I can actually fit all level data into a 265x120 pixel image, only using the least significant bit.
Something I could do, and I believe that the Spore folks did as well, is actually use ALL of the color bits in pixels that are 100% transparent. Since those pixels are transparent, it doesn't matter what color you set them to. I can't do this, however, since I am using the entire image, which means that I have no transparent pixels to work with.
Only registered members can share their thoughts. So come on! Join the community today (totally free) and do things you never thought possible.
What's going on with Monaco??
hope this game did't die
Cant wait to have it =), Make a demo or somehting ^^
Ah, Monaco finally has a page here on IndieDB. It's pretty much my most anticipated game right now. I can't believe no one came up with this awesome concept before.
Someone did come up with this concept before: Take a look at Subversion by Introversion Software ( Introversion.co.uk ); they've been working on this title for 4 years now.
Awesome! And it's so cool that you worked on Whacked!, played that game so much on my xbox
This is technically awesome. Colour me impressed.
nice
ps: first