Wednesday, December 23, 2015

Find Junk Tools: Leveler

I've made several small tools to aid in development of Find Junk. The oldest, and largest, is the "Leveler". This is where I set up the outlines and hit areas for all objects in all levels. I'm going to talk a bit about its evolution, from how it was back when I was working on iOS, to the current state.

I won't really show much code here, I don't think there's much of interest there. This is just to give an overview of how it works and some of the advancements that have been made.

Let's start out with a couple screenshots! First, this is the main window from the original tool, circa 2009 or so (screenshot is from today with Win10 styling... this is just the build from then):
Find Junk Leveler, 2009
And here's the main window today:
Find Junk Leveler, 2015

There are a few obvious differences, and a few that don't really show in a screenshot. The first thing you might notice is that with the new Leveler, you can see a lot more of the image. In the original version, I would work with the final cropped and sized image (with a fixed resolution of 320x420). I could resize the window to get a closer view of what I was doing, but that's about it. If I decided to reframe the image at all, I'd have to manually move every shape. When I started to revive the project, I knew I would be using the higher resolution original photos, so the cropping would likely change as well. But I also wanted to redo the outlines anyways, so I wasn't worried about that work. But, if the Leveler works with the full uncropped image, it will be much easier to make further tweaks later, so I won't be locked into any decisions. Anyways, so the Leveler takes in the original photo, and I can crop it within the program (the lighter grey areas on the sides are going to be cropped away). When I export the data, the images are cropped and resized as appropriate.

Aside from that, the outline in the preview image is drawn much nicer. The line is thicker and I can see at a glance where each control point is. Previously, I just drew the line, and highlighted whichever point the mouse was over. I also support zooming, so I can get an even better view than just by resizing the window.

Apart from the user interface and editing abilities, I've also changed how the data is stored on disk. The old Leveler would work with the same files as were bundled with the game. Each level would have a text file with a list of the shapes in it, along with x,y coordinates for each point in the drawn outline and hit shape, and also a separate jpg to go with the level. These were loaded and parsed as needed (so before switching to a level, I would read in the text file to find out what shapes are there, and load the image). In addition to that I had another file that listed how many objects could be found in each level, which I edited manually. Overall, this meant a lot of separate files to deal with:
Level files packaged with the game, 2009
This lead to a few problems during my rewrite efforts. First, when developing for Windows Phone in Visual Studio, I need to add every content file to the project. While maybe not the worst thing ever, this was an inconvenience and popped up in other places besides these level files. Second, the "challenges.lst" file that I had to set up manually was really annoying. It existed because I originally didn't want to load all the level descriptions up front (I don't know why, that was a long time ago), but I still needed to know how many total objects there were and where I could find them. This time around I decided to load everything but the images during startup. And of course, reading and parsing a text file is not the best thing if it can be avoided.

I was already making some major changes to how the Leveler dealt with files, because I needed to store a bunch of extra info that wasn't needed for the game (how to crop the image, path for the source image), so while I was at it I also revised how this stuff is stored. Now the files that are bundled with the game look like this:
Level files packaged with the game, 2015
The files with the cleverly "dat" extension store the list of objects in all levels, as well as the final cropped and resized images for each (still kept in JPG format, to keep file size down a bit). With Windows Phone, I can add those "scale-" annotations so that when I request a file named "levels.dat", it'll actually give me the appropriate version for the device's screen. So each one has the same images, but scaled to different resolutions. I've split out the object names into a separate "strings" file, again with a "lang-" annotation so I'll get the correct language for the user's settings. Leveler doesn't currently support multiple languages, but it's nice to have that available if I decide to do it eventually.

The files are laid out in a way that I can load them with just a couple of reads. Generally first there's a small header saying how big the data is; and then I can read the rest as a single chunk into one block of memory. I can then reference the individual pieces by treating different sections as arrays of structs. I keep the handle for the "dat" file open, so that as the game is played I can stream in the images as needed.

I mentioned that I have additional editor-only data that I need to keep track of. This does not go into the "dat" or "strings" files. Those are exported by the Leveler, and contain exactly what the game needs. Instead, I have a separate location to store all my source data. This includes the original photos, individual sprite images, and several JSON files describing fonts, string tables, levels, etc.

The levels description file is where this extra metadata is kept. So Leveler loads and saves the JSON file, and then I can run an Export which takes that and dumps out the final "strings" and "dat" files. There's no need for the tool to be able to read in those exported files.

So I think that's about it for now. If you're reading this, thanks! Feel free to leave any comments or questions. Next time around I may go into more technical detail of what the exported files look like, and how I use them.

No comments:

Post a Comment