Recently on HN I saw a headline about a small handheld available to teenagers (and people with the money to build one, I suppose) called the Sprig. It's based on the pi pico and runs javascript-based games. Since you can get one for free (they claim $100 value!) just by being a <20 years old and submitting a game to their online gallery, I figured it was a worthwhile endeavor.

the game

I created a game that I called "inconsequential leveldungeon". Find it on the Sprig gallery here. You traverse a smallish, procedurally-generated dungeon, collect some keys, avoid some spikes, and return to your starting area to exit through a portal that you've now unlocked. I started on a Friday after school and finished on Sunday late in the afternoon. Honestly, I would not have expected that I would have so much fun writing a bunch of javascript. I went into it figuring that I would just suffer through it so that i could get the cool little handheld console thingy, but I legitimately derived a large amount of enjoyment out of the creation of this game. At the risk of sounding like a sales pitch, Sprig makes it easy to create a game without excessively restricting what you can do with it. Obviously there's some restrictions inherent to making a game that can fit on a pico (for one, you can only place things within tiles) but these are completely understandable and even serve to make the process more interesting.

observations

As I mentioned before, I found it a ton of fun to create this little game. Putting together all of the boilerplate parts of gamedev (input handling, level design, spriting) was just incredibly easy, especially with the builtin sprite and level editors. The only restriction of the map editor is that you cannot place two sprites on top of each other, which meant that I had to manually place some of the things each time a room was loaded. This wasn't too bad though. The functions that exist for moving around sprites, detecting them, setting stuff up, all are intuitive. However, I did feel like there were a few things missing, especially a builtin to remove all sprites of a particular type. This can be done but in a more roundabout way. For the most part though, Sprig just gets out of your way and lets you do what you want. At first, with things like the map, bitmap, tune keywords I was worried that procedurally generating maps would be infeasible, since there might have been some kind of extra "compilation" step for maps. This doesn't seem to be the case, though, as those keywords only seem to serve as buttons to open the built-in editors. This is really nice, and also means that you can omit them because they seem kind of cluttery. As I mentioned before, the editors are nice and intuitive, with the possible exception of changing the map size in the map editor. I'm still not sure how what I ended up with will look on hardware, since the map size of the titlecards are different than the ones for the game (oops). Finally, the text functions, while useful (and including a font that looks really good) are somewhat clumsy. I'm not really sure why. I understand why they can only have one clearText() function to clear all text, but it's definitely annoying. Also, the text doesn't seem to line up with the tile system in a way that makes sense, unless I'm just stupid.

complaints

Only major complaint is the tune editor. It definitely accomplishes the designated task, allowing you to place square, saw, sin, and triangle wave notes (although no white noise channel is available, which is unfortunate for an interface ostensibly based on wave-synthesis and geared towards retro-aesthetic games) on a couple octaves and vary the playback rate of the song. The editor is probably appropriately limited for children to create simple tunes and edit them, which is great. However, I felt too limited by the editor and just wrote my sound effects by hand. For example, the tune editor does not contain semitones. what. how. Luckily, I checked the source for the tune parser and found that it does, in fact, support semitones, so I was able to write it by hand. The tune engine also supports some other features that the editor doesn't allow you to make use of, namely varying the length and overlap of notes. Basically, you can change the amount of time that is waited for the next note/chord to play as well as the length of the note, so you can cause notes to overlap each other, but only if you do it manually. I didn't mind, though, since the textual tune format is relatively easy to type out. The only (as far as I could tell) unabatable tune issues are 1) if you accidentally click on the tune keyword with a manually written tune that doesn't conform to what the editor thinks is possible, you will feel sad, and 2) the envelope of each note is seemingly immutable. I'm not sure there's a good way for them to fix either of these, and one of them is mitigatable by simply removing the tune keyword, which is totally all good because it's not pretty in the code anyway :).

verdict

Sprig is an excellent platform to create fun, relatively simple (or complex if you're insane like the guy that made a raycaster) games and demos. The platform makes most of what you want to do really easy, and gets out of your way if you want to do more complicated stuff. The limitations honestly make it more interesting, because it would have been lame if maps were just a 2d array of characters, so it's much more fun to dynamically generate and edit them as strings. Even the small tune issues are not particularly significant. I went into this expecting to find something extremely dumbed-down and suitable for very young children and those with no programming experience, and was pleasantly surprised by the competence and usability of it all. The platform makes some likely necessary concessions to accomodate people with much less programming experience than I have, but still manages to keep it sane and fun for experienced users. When I recieve my physical Sprig (hopefully soon!) I will post a review of it here as well, probably in a new post (Update 2023-01-26: here). 9.5/10 would recommend.