At the start of this year I played around with PICO-8 and there were lots of things I loved about it! The focus on being a fantasy console meant that retro aesthetics of the sound, music and graphics were nicely in sync. The image memory and code character limits forced you to focus on achiveable games. The BBS system was very cute, worked well and had some of the "view source" mentality for game dev that helped me get into web dev.
However there were a few things I didn't like; the small caps font in the integrated IDE I found extremely difficult to parse and switching to an external text editor broke immersive beauty of the program. Whilst the focus on character limits and low memory was encouraging for small scope games, it forced you to write very imperatively which I think is kind of bad practice and prefer writing in an event driven style, and this meant certain game types were extremely popular on the BBS (2D platformers I'm looking at you).
The final thing was, I came a bit late to this particular party. I've been told by early adopters that originally it was very "anyone can make a game and publish it" but later in the lifecycle the BBS was populated by exceptional works by highly practiced devs and demo scene style proof of concepts for raytracers and other tech, very impressive but also quite intimidating.
So inspired by PICO-8 and having previously tried making pixel perfect games in Unity and found it wanting, I spent most of my free time in January having a crack at making a similar set of tools as that provided by PICO-8 but with web tech instead. I was aware at the time this has been done before, but this was about learning and fun rather trying to create a competitor.
The idea for my implementation was a set of tooling in which you could pick - or provide - colour pallettes and input capabilities as part of the configuration. You could stick to the SNES style d-pad plus 2 buttons, or you could go full keyboard and mouse, atari style, or anything in between. Allowing you to choose the limitations you wish to work with. As I wasn't planning to actually simulate a console, I had no plans to artifically enforce any kind of image or code memory limitations.
I started with the renderer and discovered quite a few things:
- The Canvas 2D context obeys image rendering properties, and the CSS attributes for these aren't consistent across browsers.
- Almost all functions on the canvas 2D context are anti-aliased, even when you've set canvas image-rendering properties to pixelated or equilivent.
- When you draw lines you need to use a half pixel offset to get sharp lines, or it'll blur the line across 2 pixels.
- Browsers do not display their window content at a 1:1 ratio, 1px in CSS is not 1px on the screen. You have to use the non-standard but prevalant window.devicePixelRatio to adjust the size of the canvas to get a precise number of screen pixels per texel.
I successfully worked out a set of basic drawing methods, which could draw pixels at a specified integer scaling to screen pixels, by using a small subset of the canvas rendering functions. I then discovered that the exact pixels on canvas are accessible as a TypedArray you can directly manipulate, which this Mozilla Hacks article outlines nicely.
Faced with the fact that I should probably re-write the renderer using this method instead, I realised I was spending all my time on tooling and that there was still significant work to do! Knowing that there was a game I wanted to try to make that would have probably been better in 3D anyway, I decided to shelve the project and revisit it when I felt like doing more pixel art.
Now that I come to write this up - knowing that my next two projects were created using Unity3D - a pattern to the projects I attempt emerges. On some projects I write things from scratch, enjoying not being tied to a commercial package and focusing on learning. On others I take advantage of my experience in Unity to create things much more quickly and allowing me to put the majority of time into making a game rather than creating the tooling that I need to effectively make a game! I do think both approaches have merit and I enjoy doing both, and rather than cutting this out, I'm planning to revisit projects when I feel the desire to switch approach.
So to allow me to easily to resume work on this project, I have uploaded it as Hestia on GitHub. I'm sorry there's no pretty pictures to go with this post, but this one didn't get past the coding stage!