One of my favourite games at the moment is indie game, Rogue Legacy. It’s a fun little game that involves hacking and slashing one’s way round a randomly generated castle.
Me being the way I am, I couldn’t resist doing a bit of hacking of the other kind. That is, I decided to have a little poke around with the game’s data files and see if I could view them and/or modify them.
It turns out that yes, it is possible (although not straightforward!) to customise the in-game graphics. So, if you’d like to find out how to have your portrait hanging on the castle wall in your own personalised version of Rogue Legacy, then read on.
You will need:
A genuine legal copy of Rogue Legacy installed on a PC. (I tested this on Windows, with the latest Steam version 1.0.13 of the game.)
QuickBMS - An advanced tool for reverse engineering files.
The GIMP - A graphics editing package
Note that you follow these instructions at your own risk. This won’t blow up your computer, but if you corrupt any of the game files, you may need to re-install it from Steam. This could mean losing your saved progress, so be careful.
1) Locate the game’s graphic data resource files.
On my installation of the game they were in C:\Program Files (x86)\Steam\SteamApps\common\Rogue Legacy\Content\GameSpritesheets
The files are Microsoft .xnb files. Unfortunately they are compressed, so you can’t view or change them the way they are.
2) Copy the file you are interested in to a working directory and open a command window so that you can run commands in that directory.
quickbms.exe RL_uncmp_xnb.bms FILENAME.xnb
This will create an uncompressed version of the xnb file called FILENAME_unpacked.xnb
quickbms.exe RL_extract_bmp.bms FILENAME_unpacked.xnb
This will extract the texture data from the unpacked .xnb file and put it into a file in Windows .bmp format called FILENAME_unpacked.bmp 5) Edit FILENAME_unpacked_.bmp file in an image editing program.
I used GIMP. If you just want to view the images (maybe you want to see the hidden programmer portraits?) then any graphics editing/viewing software ought to work. However, if you want to make changes then I recommend GIMP, as MSPaint won’t save the files in the correct format for repackaging.
Note that the image will be upside down. You’ll probably want to flip it the right way up to work on it, but remember to flip it back upside down once you’re done.
quickbms.exe RL_repack.bms FILENAME_unpacked.bmp
This will create a file called FILENAME_unpacked_repacked.xnb
8 ) Copy FILENAME_unpacked_repacked.xnb into the Rogue Legacy GameSpritesheets directory, back up the old version of the file and give the new file the correct name.
9) Play Rogue Legacy and enjoy your new graphics!
In this example you can see where I’ve crudely scrawled my initials onto the bookshelf. This doesn’t work out all that well, since Rogue Legacy mirrors a lot of the graphics in order to add variety, thus causing my initials to be back to front on some of the screens.
Here you can see where I replaced one of the in-game portraits with one of the hidden programmer portraits
This page contains details of how to parse the .xnb file format, as well as the handy ParseXnb.exe tool for checking the .xnb file contents.
The ParseXnb tool quickly showed me that the original .xnb files were compressed and hence would need unpacking before I could do anything else with them.
I looked in the game’s exe directory for clues as to which decompressor was used, but couldn’t see anything. (There is one in the Nuclex Framework, but Rogue Legacy only uses the input handling dll.) As a first guess, then, I suspected the game would use the standard XNA decompression, however, it didn’t work with the default parameters.
The Process Monitor tool is very useful for watching a process to see what it is doing. Something I’ve noticed other XNA games doing is that they read and decompress their resource data in blocks. In Rogue Legacy that block size is not stored in the files, so there’s no way of knowing what it should be. However, watching the process with Process Monitor shows that it reads the xnb files in 64kb chunks, so it’s a fair guess that that’s the block size the decompression code needs to use.
Once I had turned the .xnb files into their uncompressed equivalents, the ParseXnb tool was then able to tell me what was in them. It is also relatively straightforward to see this in a hex editor, anyway. I use 010 Editor as my hex editor of choice.
At this point I checked to make sure that Rogue Legacy could still read the .xnb files even when they weren’t compressed. It wouldn’t be too hard to write a Quick BMS script to re-compress the data, if necessary, anyway. In fact I probably ought to have included that step, too, just for completeness, but it isn’t required to get this to work.
Note that the RL_uncmp_xnb.bms script may also be used to uncompress the font and shader resource files, although the RL_extract_bmp.bms script won’t be able to do anything with the .xnb files that this produces.