Magnificent Mouse Misadventure Belated Anniversary Progress Update.

Miep, wearing birthday hat and nice dress, is looking at a cheesecake. The words say `Magnificent Mouse Misadventure turns a belated one year old!`.

I'm not going to sweeten it— I may not recollect all of what happened through the year and change of development on this game, but I'll try my best.

The kernel of Magnificent Mouse Misadventure started as an Of the Killer fangame. Not much came of it when I first thought of it in August 2022, just a simple typewriter model wherein I imagined the main character hopping on the keys to write a cry for help. It lied dormant Until about March 3rd, 2023. That is when it began proper, and as its' own idea separate from Of the Killer. I simply feel more comfortable making new material, having to work with the "canon" of another just muddles things in my mind.

Primitive 3D model of a typewriter with paper inserted.

I used Godot given that my grievances with Unity are more severe than Godot, and I am not well versed in any other 3D engines. I am decent with 3D modeling hard objects (furniture, buildings, etc.) and I think it is more majestic and easier to portray being small in a Three Dimensional Mode. The character artwork is all drawn by hand, which is quite a workload for one artist. Miep just kind of sprang from my pen within moments, it helps that I'm decent at drawing mice already. So far I've accumulated around 146 "raw" pieces which must then be scanned into my computer, converted into line art, and then appropriately colored. I don't feel a sunk cost fallacy yet, but making art assets this way is quite time consuming.

At the start I realized, after not doing serious gamedev in years, that my programming was not up to snuff. I ask bpseudopod to make a few scripts, a camera script, then a walking script than works with the relative position of said camera script. and before I knew it we had a Git repository. She gets into the nitty gritty of it in her own write-up below, so keep reading! As much as she acknowledges the bones of the code are mine, this game really only felt possible in this iteration because of her contribution. Whenever the game is out we hope to release the code so that others may make walking-about-dynamic-camera-likes. The cutscene system was a big hairball to untangle too.

Scanned artwork of miep the mouse walking and standing still.

I decided that all good games need a music video, so I commissioned Biddy Fox to record the "Motif of Mousehood", a wonderful song I'm glad to include in the game. The music video was a gargantuan effort that took about a week of work spread over a month's time. I'm proud of it though, and it was well received by friends. A friend and game developer fotocopiadora will be doing the rest of the soundtrack, with possible guest musicians being TBA. I also commissioned Kitet Frog to make an art piece that echoes the infamous Metamorphosis drawing. Miep's story in a way is a reversal of the Kafka story— she wants to become the mouse. Though that doesn't mean her new life isn't fraught with danger!

As far as promotions go, I've been spreading news on the game through word of mouse. I was on a twitch podcast"Raturday Night" (VOD here) to talk about the game. Later on bpseudopod and I grinded away on the laptop minigame for a promo video for the Socks Make People Sexy showcase. We're kind of waffling on whether or not to go through the bureaucratic and financial suffering of putting a game on Steam, the place where you can buy Half-Life Two.

I have had problems with motivation, and I think that's why it's taking a while to make this game (even if slow and steady wins the race). I tried the Pomodoro technique, with a mouse kitchen timer too, but it was hard to stick. I'm asking friends for advice on how they keep motivated, but I need to apply what I've learned. I don't want this game to wither like other long term projects I've worked on. I've even procrastinated on writing this blog post. Hopefully writing this is a step in the direction of... getting back to work!

Kitchen timer in the shape of a mouse.

The future of the mouse game is murky, but I foresee it being finished someday. I don't know when, but I need to get up and get at it! To be fair... I'm not really sure where to take the story, this is an important factor in a narrative game. Doesn't help that I gotta do a lot of other things on the game too! Rest assured... Magnificent Mouse Misadventure will be out one day!

...From Another Point of View!

So this whole thing, or my involvement at least, started with Mariken talking about a new game she was conceptualizing in a public Discord server. The original concept for the game was to be a fangame of the "Of the Killer" series by thecatamites, and you can still see a lot of that in the voice that Miep uses in the game, which is inspired by the neurotic ramblings of the main character BB. At first I only offered to write a camera script, roughly emulating the way the camera works in the Of the Killer series, and I was pretty proud of the end product. It had a mode that followed the player, one that tracked them, another that was static, and even a Crash Bandicoot-inspired "boulder cam" for chase sequences. I sent the script to her and thought that would be the end of it. And when she asked for help with the movement code, I thought that would definitely be the end of it.

It wasn't.

But for a while I thought it was. I'm credited as programmer, but in the beginning Mariken wrote most of the scripts herself. I took more ownership of the codebase as time went on, and so went back and made minor revisions to these scripts, but their bones are still Mariken's and I still credit them to her.

An Ant typing away at a shrinkpad laptop with a screen of the game development.

C. pennsylvanicus photo credit: April Nobile / © / CC BY-SA 3.0

My next major contribution was a sketch of the script that drives cutscenes, two and a half weeks after I contributed my first script. A few days later, Mariken gave me access to the Git repository, and if I were to pick any moment that's the point where I went from helpful friend to full-fledged collaborator.

I must at this point express appreciation for Mariken's work on The Music Video. The Music Video is one giant three-minute AnimationPlayer track, laid out keyframe by keyframe. It was an immense amount of work that Mariken handled entirely by herself, working daily over the course of weeks. I think one of my big regrets was not finding some way to make it easier for her. I wrote a small support script for the lyrics. I also wrote a debug script for skipping around in the animation, but I didn't think of it until The Music Video was almost done. I couldn't do much more. Even now, we are both terrified of it, and any time we go back and make major changes to this or that system, the first thing we think is, "Does it break the music video?" This is not a healthy relationship with your creation! That said, the joy and relief of exhibiting our now-complete music video on a virtual big screen to a crowd of supportive friends cannot be overstated.

Soon, we got back to regular development. We were only a couple levels in before Mariken had pushed my Killer-inspired camera beyond its breaking point. The key part of the camera was its simplicity: in the Of the Killer games, the camera is free to go through walls, clip through stairs, and do whatever it has to do in order to stay near BB, and usually the same camera works the same way throughout a given scene. Mariken, however, wanted to do complex camera transitions, swooping around the level to frame and follow player movement.

In Godot 3.5, the version of the Godot engine this project uses, the 'current' property of the Camera node acts strangely. The current property can be set to true on multiple Camera nodes at once; but only one Camera can actually be active at a time. Furthermore, when the current property is disabled on all Cameras in the scene, one get activated arbitrarily. It's very confusing, and fortunately this behavior was changed in 4.x to be much more intuitive.

We weren't using 4.x. Mariken, understandably, stumbled over this. Eventually it became clear that the script I'd wrote in the very beginning wasn't good enough for what she was doing, so I started work on a more capable system--which, of course, would be more complicated.

The end result was loosely inspired by Cinemachine. I will hurl insults at Unity all day, but Cinemachine is well-built and I invite all readers to shamelessly rip it off. The biggest idea I stole from it was the idea of having one true camera that's reused between multiple camera-like objects, which I called Camera Proxies. Before, every camera behavior was stuffed in one script, and the active behavior was set by a field; after the rewrite, each behaviour was a different class of Camera Proxy, so each camera had only one behaviour determined by its type.

There were two big advantages to this system. The first was that I could write custom behaviour around the "current" property to enforce only one camera being current at a time, obviating the issues I detailed above. But the most important advantage was that, with an independent camera, I could do camera transitions! This meant there were no longer situations where the player would walk through a camera change trigger only to immediately walk back through it once the camera switched, and it made every single camera change in the game look a lot slicker. It's not perfect, among its missing features (due to engine limitations) was the "preview" button regular cameras have, and once or twice Mariken has had to work around its limitations, but for the most part it works very well and I'm very proud of it.

I'm a little less proud of my next project. One thing we had to work around with the cutscene script was cleanup: if we wanted a cutscene to take place at the beginning or during a level, rather than at the end, Mariken would have to make a "cleanup" track that would hide all the UI elements and models used during the course of the cutscene. It was a lot of work on her part, error-prone work, and the cutscene script still counted the cleanup track as part of the cutscene, so we'd have to double-check that we worked around that.

So, I thought, can I automate cleanup? My approach was this: every AnimationPlayer node in Godot maintains a track called "RESET", a one-frame track that, when played, resets everything that's animated to how it looks in the editor. Leveraging this auto-generated track, I made it so the cutscene script would make a partial copy of the track and play it at the very end of the cutscene, automating production of the cleanup track. I also wrote code to restore the player and camera's position after the cutscene, in case it gets moved. This is all automated; to use it, you specify a list of nodes as exceptions, which will be omitted from the cleanup track, and the script will take care of the rest.

This script works well, but it has some unfortunate issues in terms of usability which keep me from being proud of it. The exception list is hard to use, and Mariken has continually struggled with it; also, the RESET track isn't authoritative, so it can get out of sync with the cutscene animations and therefore not reset everything that should be. I think overall it has succeeded in reducing work on cleanup tracks; but it's also created new problems for Mariken, who's ultimately the one who does most of the work, and I'm not quite happy with that.

A lot of the things I've learned from this project are about working with other people: how to think about scripts from a second party's perspective, and how to explain the features I've implemented and how to use them. I've gotten much better at this over time. As part of learning to make better user interfaces, I've also learned the basics of writing tool scripts in Godot, meaning scripts that run in the editor as well as at runtime. It's a huge improvement in usability to make changing a property in the editor cause something to instantly and visually update, and I like to think that this tiny improvement has improved the editing process greatly. Most scripts that have meaningful compile-time effects are now tool scripts, and I'm very happy about this.

At this point most of the basic building blocks of the game had been developed satisfactorily, so I got to work on more self-contained scripts. Around this time a demo was coming up, so for a week or so I focused on a little minigame where you jump around on a keyboard so we could use it for our demo reel. This was a great experience: Mariken did the art and modeling (except for a couple custom key models I made), and I put it all together and did the code, including some shader work and some tricky math. The end result looks good and plays well, and it's a finished product that I'm excited to integrate into a larger scene.

There's another minigame I've worked on that hasn't been released to the public yet, and that's also been fun to work on, although (as of writing) it's not quite as complete.

This whole project has been a joy to work on, and I'm eager to continue it. Mariken is wonderful to work with, and I admire her immensely as an artist and a game developer. There's still a great deal of work to be done, however. As of writing we're still working on figuring out where the story will be going, and we have lots of scene ideas that we've yet to implement. I'm looking forward to improving the code further, helping more with asset production, and implementing more minigames.

Post Script.

We have migrated to Godot 4 on bpseudopod's recommendation. There are hiccups to sort out, but hopefully we'll be back on track soon!