What’s up! A little later than I had intended but here I am with an update. I’ve been working a lot on GMS Explorer recently, and I have something to show for it.

GMS Explorer main window

It’s fairly basic but I’m quite happy with it. Making a UI that doesn’t break and works how you want is actually more of a challenge than I was expecting! That said, I am learning it at the same time and trying to do it the “proper” way.

Right now, the main functionality is the ability to load and display sprites and backgrounds. Each “sprite” in Game Maker is actually a collection of frames, usually an animation (although occasionally they’re used for various single-frame states of an object). With my program you can step through the frames, and also export the entire animation as a collection of images. The File menu also (along with Open) allows you to extract all sprites. This means it’s actually fit to use for extracting sprites, just like GMExtract does. Backgrounds are also viewable, and my next step will be exporting those too.

One interesting problem I had to deal with was progress bars. Due to exporting taking a little while (especially all sprites), I wanted to show that the program was working, rather than just have it lock up until it’s done. While WPF (the visual framework I’m using) provides a loading bar, to make it update I had to actually implement multi-threading. I wasn’t prepared for this but gave it a shot anyway. Thankfully, C# makes it fairly easy using async methods and await… well at least, it’s easy once you get the hang of it. Basically these allow you to run intensive processes like you would usually, but in such a way that it doesn’t block the UI thread. There’s also a specific way of updating progress bars in this way, without actually modifying the properties directly. So after some reasearch and trying it out, eventually I got it working nicely.

Progress bar

The cancel button was also interesting. To cancel an async method required me to pass a cancel token down, which could then be essentially “activated” when the button is pressed. The async method periodically checks if the token has been activated and if it has, it throws an appropriate exception. I can catch the exception higher up the call stack to detect that the method has been cancelled. It seemed a bit of a strange way of doing it at first, but it eventually made sense. Even explaining it now just helps confirm that I understand it, haha!

Most other things were fairly straightforward though, once I knew what was going on with XAML. A lot of controls such as the list and tabs just work, and look great. Even drawing the sprites wasn’t too bad. The code looks terrifying, but I just followed some sample code and took a few minutes to understand what it was doing. Once I did that it made sense and it works brilliantly.
One thing I’ll always say is that when you find sample code, don’t copy paste. Writing down the code yourself, even if you’re copying it verbatim, is so much more helpful. Not only do you practice the act of writing out code (this is always good), but writing the actual code tends to help you understand it more. Even if you don’t actually know how it works, seeing your IDE bring up method suggestions and auto-format it (perhaps better than the code you’re copying) just gives you a little more intuition about what’s going on.

Lastly, a neat thing I found: basically a free, open-source icon kit by Google. It’s got a ton of simple icons for just about anything that isn’t too specific, and in a few different styles. I came across it while looking for the icons on the step forward-back buttons. They’re just really nice, recognisable icons that are great if you just want something basic for an app. The only thing is that some of them are recognisably by Google (such as the thumbs up/down and some media-related things), but if you don’t mind that it’s perfect. It’s something that I was surprised I hadn’t heard of before and which I think a lot more people should know about, especially solo developers like me.

Anyway, that’s all from me for now. If you’re interested in the specifics on the project the source is up on GitHub.