TL;DR: In this post I'm describing how a theoretical implementation (or port) of the puzzlescript interpreter would work on a Playdate device. I explore the basics of what a puzzlescript game needs to run, and then I elaborate on some ideas about converting colorful graphics to a black-and-white screen, as well as some rough ideas about distribution. And I stop there. I don't have time to implement any of this, so if you are interested, feel free to explore these ideas.
Puzzlescript is an open-source game engine for (mostly turn-based) low-resolution puzzle games. The games themselves are described in a simple text file, including the graphics and the levels. With enough creativity, people can even create a metroidvania puzzle game.
Puzzlescript games are tile-based. All movement happens on a grid. In fact, it doesn't even have sprites per se, but just tiles over multiple layers (i.e. the player is just a tile that has the player graphic, rendered on top of other tiles and on top of the background tile). The games can also generate some basic sound effects, but no music.
Graphics-wise, each tile (or Object) has exactly 5x5 pixels, and can have multiple colors (mostly chosen from a restricted palette, but arbitrary RGB colors are also possible). Each level can be as large as needed, and the engine will automatically scale the tile rendering.
The input is simple: arrow keys, plus an action key, plus an
undo key, plus a
reset level key.
Given the restrictions and the simplicity of puzzlescript, I believe it is a good candidate to be ported to Playdate. It will be quite lightweight, as most games run around 2 fps, or even don't run at all unless the player presses some buttons. That means such games will be very battery-efficient, and it also means they will likely be lightweight on the device CPU.
The main issue is, of course, the graphics. Not limited to 2-colors, most puzzlescript games need to be adapted to the Playdate 1-bit screen.
If playing on Playdate, how large can the levels be? Assuming no scrolling is implemented, this is how we can render 5x5-sized tiles on the 400x240 screen:
|Scale||Tile size||Level size|
Of course, the
1x scale is certainly too small and hard to read, and anything over
10x is likely too large to be useful for most games.
The height is the most limiting dimension, so an implementation on Playdate could allow smooth vertical scrolling, controlled by the crank. In my mind, horizontal scrolling doesn't seem to be feasible nor intuitive, so I wouldn't implement it.
Of course, the user should have the option to manually set whatever scaling they prefer, and/or disable the vertical scrolling.
If we assume no levels would ever be played on
1x scale, that means we can implement multiple levels of gray (and even multiple textures) by different dithering patterns for each scaled tile-pixel. For instance, at
2x scale we can have at least 7 distinct 2x2 patterns.
In that case, a puzzlescript interpreter for Playdate could automatically map different colors to different patterns. This is essentially equivalent to a palette.
This automatic solution doesn't work for games that specify colors using RGB values. The automatic palette can also lead to sub-optimal results. How can we do better?
Once a puzzlescript game is loaded in Playdate, the engine knows how many distinct colors are used. The engine could have an "advanced" panel that would let the player to remap the colors themselves. This is somewhat inspired by how GameBoy Color adds colors to GameBoy games (it has a handful of built-in 4-color palettes that the user can choose for each game), and also how Super GameBoy allows the user to change the palette of GameBoy games.
The next stage would be to augment the puzzlescript game source-code to add a fine-tuned palette specifically designed for that game. Again, this is similar to how some GameBoy (Color) games behave.
If we want to improve the user experience even further, we can provide "high-res texture packs" together with a puzzlescript game. This would be very similar to how such packs behave on certain games and emulators: the engine would render the customized high-res 1-bit graphic, instead of upscaling the low-res 5x5 color graphic.
Care still needs to be taken regarding multiple scaling levels and the high-res texture. Maybe multiple high-res versions are needed, one for each scaling factor.
Similar to how game mods (and IPS patches) are distributed, we could have a repository of "enhancements" that would contain only the needed changes for a puzzlescript game. Thus, the engine would read from the original puzzlescript source-code, followed by reading extra data from this "enhancement pack". This extra data would customize the palette dithering, replace the graphics, provide high-res textures, and add whatever extra data we might need (e.g. the preferred scaling factor for this game, or if vertical scrolling should be enabled by default).
These enhancement packs would be community-supplied, so multiple packs could potentially be available for the same game. (Similar to how Minecraft has multiple texture packs, or how Steam has several Steam Input profiles submitted by multiple gamers for the same game.)
The final step, the holy grail, would be to collaborate with the puzzlescript developer(s), and augment the puzzlescript language to incorporate all these "enhancements" into the main game source-code.
Ideally, it would be nice to browse and look for new puzzlescript games directly within Playdate itself. The puzzlescript engine would have to be installed once, but afterwards it would be cable to query a service to list the available games, and then download the game the user wants to play.
However, there is no Internet access in the current Playdate SDK. Until that happens, each game (or collection of games) would need to be bundled together into one package and then manually installed on the device. Although possible, this is more inconvenient than a built-in gallery of downloadable games.
Well, I had this idea in my mind, and I wished to share with a larger community. However, I don't have time to implement it.
If you liked this idea, please, go on and be wild about it! Hack together some prototype, implement parts of the engine, validate if this idea works. And go ahead to build it!