Promoting a game by automatically embedding screenshots in social media sites is a common practice, particularly among developers whose games live on those social media platforms, as well as mobile developers.
However, Emma "Eniko" Maassen, of Kitsune Games, put a new spin on this for her indie roguelike MidBoss (not to be confused with 2064: Read Only Memories dev MidBoss), a traditional standalone PC game.
When a MidBoss player finishes a run—usually by dying—they can post a "death card" with the circumstances of their death or transcendence to Twitter. The embedded image doubles as a save files to allow other players to replay from the same seed or salvage loot from the failed run, since all of the information is steganographically encoded into the PNG image file.
Maassen sat down with Gamasutra to talk about the challenges and advantages of using steganography to share more than just text and pictures on social media.
Questions and answers have been edited for brevity and clarity.
Dead, to begin with
Where did the idea of MidBoss's death cards initially come from?
Emma "Eniko" Maassen: I like finding a place for old stuff I never really used in my projects. When we were working on the trailer for MidBoss, we came up with an idea to show parts of the game as trading cards in the trailer to show the volume of content in the game.
I made a card design for that, and that actually made it in the trailer. Around the same time, Alphabear was exploding on Twitter. And we'd been getting some feedback from people that they were sad there wasn't a meta progression system, like in (for instance) Rogue Legacy.
I decided to use the moment of the player's death since most runs end in death in MidBoss. The story that most players share with others when they talk about their experiences in roguelikes is how they died.
Got obliterated by an evil warlock! #LikeAMidBoss pic.twitter.com/CU2RMAQRKi
— Jay Allen (@a_man_in_black) January 16, 2018
I realized that I could combine my [already-made] steganography library with the card design [from the trailer], make it shareable on social media like Alphabear, and came up with the grave goods system (using the cards to carry over items from your inventory to a new game) to soften the blow of not having meta progression.
You had already developed a steganography library before working on MidBoss?
I created a library to do image steganography while I was working on the in-game music instrument playing system for Shroud of the Avatar.
"I was playing Champions Online. A friend sent me their character customization settings, but it was a picture that I could load into the game. It was like magic, so I looked up how they could've done it and [first] came across steganography."
Years ago, I was playing Champions Online. A friend sent me their character customization settings, but it was a picture that I could load into the game. It was like magic, so I looked up how they could've done it and [first] came across steganography.
[A couple years later,] Shroud of the Avatar was taking submissions for game content from backers, and one of their stretch goals had been a system where you can play instruments in game to make music. Mabinogi, which I used to play, and Archeage used MML files to do that. Lord of the Rings Online [and later Terraria] used ABC files. I [created] a framework that could parse the player-transcribed music for all of these games, to give me access to this wealth of playable music. (You can find the source code for the library on my Github.)
[As part of this project,] I created a library to do image steganography to be able to hide the music file data within a music scroll image with the actual notes printed on it. That experiment never went anywhere, though. I was working on this in my spare time and I just didn't have the time to figure out all the intricacies of rendering the bars of music into an image to share.
I cleaned [this framework] up, made it open source, and submitted it [to Shroud of the Avatar developer Portalarium]. It took a while for them to get around to implementing it, but Richard Garriott mentioned how easy the library had been to integrate for them. I was awarded the Order of the New Britannia Empire, an actual medal they award to community members that perform outstanding contributions for the game. It was a very positive experience for everyone involved.
Encoding memorials with steganography
Can you walk through how your steganography implementation works in MidBoss?
It's relatively simple. It takes the binary or byte data you want to encode and the RGBA color information of the image. Then it goes through all the bits in the data you want encoded and overwrites the least significant bit of each color channel to match. That means the colors will only ever be off by 1 from the original, which is imperceptible to the human eye. There's 4 color channels or 4 bits of encoded data per pixel, so every two pixels represent one byte of the encoded data. Death cards are 405x506 pixels in size, so they can hold at maximum about 405*506/2 bytes, minus some transparent pixels, or about 100 kilobytes of data.
Programs don't respect the values of the RGB channels for a fully transparent pixel, so I only put data in pixels that had a certain minimum alpha value so they weren't completely transparent.
I also add a header with the text "BINDATA" in ASCII to the data so I can check if an image contains encoded data, followed by a 4-byte integer containing the length of the data payload in network endian, so that I know how much data there is to read.
What information is saved in a MidBoss death card?
MidBoss saves its game in a zip file that contains a number of XML files. I chose XML early on because I wanted the saves to be hackable [by players]. Inside the save zip is a "header.xml" file which saves everything about the game that isn't specific to a certain floor. That means the game version, seed, game settings, how potions are discovered and which have been discovered, all of the player's stats, abilities, forms, equipped items, inventory, etc. Even the stats that are tracked for that specific game.
I already had all of this information available so the easiest thing is to just store that information in the card, but the text takes up a lot of space. A save header for someone at the end of the game might be around 65 kilobytes; I don't think I've ever seen one over 80 kB. Fortunately, text compresses really well, so I use the deflate algorithm to compress the data before encoding it into the death card image. Once you deflate the header, it'll basically always be under 10 kB, and is usually between 3 and 6 kB.
Getting the images onto Twitter and back again
Once death card images are generated, how do you export them to social media?
I'm a PC only developer [and] I never wound up with enough time to add sharing functions to platforms besides Twitter, so my research focused on that.
I had to make sure to pick a format that would fit Twitter's image sizes. I wanted the whole card to be visible without having to click on it, and I definitely didn't want it to be resized. That's how I came up with the height of 506 pixels, and the width was basically as high as I could get away with while still having the cards feel rectangular enough instead of feeling square.
It turns out that Twitter will re-encode a PNG image that has no transparent pixels as JPG instead, so the data becomes corrupted. That's why the design for death cards always have some transparent pixels in the corners. As for any other platforms, I just hope that the transparent pixels and the small size gets around their image re-compression rules. (I tested death cards on Discord, and they worked there.)
Since I was only targeting Twitter, getting around those rules was almost easier than getting the image from the game up on Twitter and back into peoples' games. [At first], I didn't want to mess with OAuth by creating a Twitter application at all. Unfortunately Twitter doesn't have web intents that let you post images--only text.
What I eventually did is when you click the button to share a card on Twitter the game creates a temporary html file on your local drive which has the image as embedded base64 data. That html file contains a form where you can customize your tweet, and the text and image are then posted to my server. Then my server goes through the OAuth loop and posts the tweet.
And how did you set up re-importing the cards back into the game?
I started with simple drag & drop, which was problematic enough when dragging a file on your local disk onto the game. [It was] inconsistent on Windows due to VAC and various permission settings, but it mostly worked. From browsers, though, it was awful. Some browsers would just give me the url to the image instead of the image itself, some would bizarrely serve me a BMP image, and half the time it just didn't work at all.
MidBoss automatically detects URL links to possible death cards in the clipboard
Eventually I got exasperated with the whole thing and created an option which periodically checks your clipboard for text links to images, but only while the game is active in the foreground. If it thinks it's found a link, it'll fetch it to a temporary file (assuming the image is not too big), and checks if it is in fact a death card. If it is, it asks you if you want to import it. This way, all you have to do is right click the image and copy the image location to your clipboard.
No tags.