I spent the past year making a game for the Playdate console. I have finally released it.
https://uguu-org.itch.io/magero
Warning! Spoilers ahead! Please try to complete the game before reading on.
After releasing Ikaruga Snake last year, I was still on week 3 of Playdate's 24 game release schedule, and I got to experience Time Travel Adventure with its smooth crank operation. The first few levels were great, but around level 9 was when you really have to crank that thing to get going, at a rate so fast that I thought I was going to break the crank. I thought the crank-based input experience was compelling, but the game was just not for me. There was only one thing to do, which was to make my own crank-based game.
I was thinking about things that would be a good fit for a crank-based control, then I recalled all the years we spent working with industrial robots. Those robots commonly come with 6-axes of movement and I have just one crank, but I only need 3 joints in 2D space, and I have got a D-Pad with 4 directions, so a two-handed operation where player holds D-Pad with their left hand while operating the crank with their right hand should work. For comparison, manual operation of industrial robots are also done with both hands -- you hold the teach pendant while squeezing the deadman switch with your fingers, hold shift key with your left thumb, and press the axes +/- keys with your right thumb. So a D-Pad plus crank combination is at least not any less ergonomic than a real robot.
The D-Pad plus crank input system was implemented by recording "delta" on D-Pad presses, then set joint angles to be "delta + crank". The top of arm.lua explains this in detail. There were some minor complications with how the middle joint (elbow) should work -- mechanically, it seems to make more sense that would rotate in the opposite direction with respect to the two end joints (shoulder and wrist), but I just couldn't get used to alternating crank directions while testing. Eventually I made the rotation direction a configurable option that defaults to clockwise on all joints, where an elbow+shoulder or elbow+wrist movement would cause the elbow joint to rotate in the opposite direction than it normally would. It's less intuitive in a mechanical sense but more intuitive for actual game play.
A greater complication is what happens when the arm hits itself, and how do we adjust "delta" to balance the "joint = delta + crank" equation. But more generally, the question we really want to answer is what do we do when the arm hits anything. Basically we need to think about how the robot would interact with the world.
I thought about the kind of actions that would be interesting to do, and implemented them roughly in this order:
These actions also got used in the game description metadata (the description should be read in the same beat as Technologic). The game title is translated from the first two words: "bend it" = "magero" (曲げろ). It was short and I didn't find any other game with that name.
As to how the actions would be executed, I made a system of finding actionable points near the hand, and showing a cursor to indicate the nearest viable action. Viable is defined as being able to reach all intermediate poses needed to complete the action, so when a cursor is visible, the player would be able to perform the action right away because the action plan of all intermediate poses has already been computed. An alternative scheme of not precomputing anything and only try to perform an action on demand wouldn't work, because player would end up trying to find actions at every joint angle, since they don't know what they can do.
Action execution is bound to the Down button on D-Pad. In this sense, the game plays a lot like certain puzzle games where Left/Right/Up are used to adjust falling blocks and Down is used to drop the blocks, except this game also got some crank input mixed in with Left/Right/Up.
As I made more progress in the game, I added two more actions:
The coding part of the project took maybe less than 1/3 of the total development time. Majority of the time was spent on graphics.
Drawing the robot arm was straightforward -- handling rotation is what vector graphics were made to do, and Inkscape handled it very well. There was one inconvenience where rasterizing from the command line always produced anti-aliased images, and I needed sharp edges for black and white. There was already a patch for this but it hasn't made it to stable release yet, so I was running the nightly build of Inkscape until April 2024, when the first 1.4 beta (still not stable) was released.
Drawing the world was a more involved endeavor due to its size. Early in the process, I did a little bit of math and some minimal testing, and concluded that I can comfortably load and render a world with 300x200 tiles, at 32x32 pixels per tile, in 3 layers, animated in 4 frames. The "comfortably" part turned out to be untrue as I discovered that Lua tables costs a lot more memory than I expected, and I had to add minimal compression to make it work. The large world size also seem to cause lots of trouble with Inkscape, such as weird behavior object tree selection, frequent crashes with the XML editor, and so forth. One of the issues I found involving grayscale export actually got fixed, but for the most part I just workaround all issues rather than waiting for them to get fixed. I spent a fair bit of time optimizing the rasterization pipeline so that I can iterate faster, include some SVG optimizations that I was fairly proud of.
Having gained sufficient experience in wrangling Inkscape, I tried to add details to the world in ways that I thought would be fun. At least ~12% of the world were covered in chain reaction tiles because they were somewhat rewarding to watch, and I dedicated a whole corner of the map to play with the bouncy ball effect. And then there are lots of small item graphics that are random references. I mostly took my time and did not rush in drawing everything, and the final map had pretty much everything I wanted. Below are two snapshots of the world, first from December 2023, and second from the final completed state.
I also kept an album of the progress, along with some statistics so that I can stay on top of memory usage.
The last thing to do was to make some demo videos, make the project public on itch.io, then announce it to various places.
Reddit was driving most of the downloads on itch.io, and after a while, I got enough downloads to make it to the "new and popular" ranking for Playdate games. I reached 200 downloads on Thursday, 5 days after the release. For comparison, Ikaruga Snake saw 56 downloads in its first week, so Magero was definitely doing a lot better.
I did a test run just before releasing the game to make sure that the game can be completed, and that there are no obvious bugs. The run took 2:10:39. After releasing the game, I did another run and that took 1:51:37. It's weird to think that something that took a year to make is basically over in under 2 hours, but that ratio of long-time-to-produce to short-time-to-consume is generally true of most things if I think about it, I just haven't had too many personal projects that would take me a whole year.
This would have been my second game for the Playdate console, but I took a diversion due to a random comment on Hacker News and made a bouncing DVD logo. That only took a few hours. So I made two games in the past year, one of them was possibly my longest project, and the other was possibly my shortest project.
During the one year of development, I didn't make any public posts of any sort, didn't post any screenshots anywhere, and there were only a handful of people who saw the in-progress game, all of them in-person. My worry was that I was working on something that I thought was a fairly obvious idea, and that someone must have done it already. And if nobody has done it, it's only because they haven't thought of this idea yet, and would be able to release a similar game overnight. So I developed the game in stealth and my very first public post of the game was basically announcing that it's done. Fortunately, it turned out to be unique at least as far as the Playdate catalog goes. I hope that this uniqueness is something that players will enjoy.
Previous (2024-07-01): ICFP 2024
Next (2024-10-11): Rock Paper Scissors