Brief presentation and history
As I was developing some small arcade-style games for my portfolio, I missed the fun of old-school graphics architectures, like the ability to easily deform the screen, recolor objects at runtime, etc. It turns out that developing this kind of raster effects is not easy at all. After all, I spent more than two years to develop this clone of Outrun called Highway Runners (link):
So I set myself to create a simple engine for these effects. Since I'm a huge fan of the arcade boards of the late 80s, I took this model: what if we still made this graphics architecture nowadays? Arcade machines of the time were often overpowered and sometimes required games to come with their own CPU, so what if we could just plug in modern CPU/memory and power the board with modern games?
Technical decisions
- Since I wanted to make the games to be easy to share, I chose after some deliberation to go with Javascript. Although I would have loved other choices like Lua, mainly in order to be able to restrict the VM, I found Javascript to be much more fun to play with when hacking around with my API, plus it would save a lot of development time and would still be portable in case needed.
-
I wanted the game to load instantly, just like a ROM image, and have a simple programming model with named graphic data, something like `drawObject('mario', x, y)`, or `drawObject('mario', x, y, { palette: 'luigi'})`. So I made an architecture with multiple ROM areas (one for Palette, one for Sprite and one for Tilemap) which contains all graphics pre-baked at ROM build time.
- Furthermore the graphics memory would all be accessible for read and write (for instance replace colors on the fly, swap tiles or sprites with others to animate the whole screen, add/remove objects in tilemaps).
- Since it runs on the web, I wanted competitive space usage. For that I'd simply use PNG images for resources and putting indexed color data in the RGBA components. PNG are compressed as a variant of ZIP, thus providing additional compression for the whole ROM for free.
- It should run entirely on the GPU through shaders (i.e. not drawing tile by tile, but one BG/sprite = one poly).
- The additional step of building the ROM images could be cumbersome, but it was not avoidable if you wanted to define which hardware palettes were associated with what graphics (you don't want to create one palette per sprite, else you lose many of the advantages of indexed colors), and also for many advanced ideas, so I made the best of this; furthermore this can be implemented as a process that watches for any changes in the graphics directory and rebuilds the ROM + transpiles JS files instantly when needed.
Initially I went with limitations off-the-roof; the idea was:
- "Infinite" full-screen BG layers with matrix transformation (baseline: 8 of them)
- "Infinite" sprites of any size, as freely deformable quads (similar to the Sega Saturn), further transformable as a whole plane (initial tests showed that I could draw quite more of them than Pixi).
- 4 or 8 bits per pixel (256 colors)
- 32 bits RGBA master palette entries
- 2048x2048 sprite data and map data textures (up to 16384x2048 sprite pixels, 4096x2048 map cells), 256x256 palette data (65536 colors).
- BG layers can scroll, be splitted horizontally or vertically, scaled/rotated per line.
This architecture proved to be extremely powerful, but there was one catch: it just wasn't fun at all to make games with. After all, why bother with parallax when you can just overlay an infinite number of sprites or tilemaps? Why even bother with tilemaps, with palettes? And when do you know when your game is inefficient, when it might not run on some mobile devices? Good practices are not inferred through the API at all. There's not even stylistic guidelines, like 8 bit frameworks give you (simple colors, animations, avoid over-crowding the screen, etc.), you feel just as lost as with Unity, and it's not even as powerful. What I wanted deep within was to give people a glance at the fun of developing games in the 80s, and also a playful opportunity to learn.
Enter the FANTASY ZONE CONSOLE
It was clear, I needed to think about limitations. This framework wouldn't be for everyone, but what it was targeted at should be great. I'm living in Tokyo and know well the author of Pico8, who coined the term of "fantasy console". Since my original models were such as Sega System 16, Outrun hardware, Namco System 24, etc. I chose to go with 2 BG layers only, 256 sprites covering up to once the screen, add transparency effects but with no overlay support and only one effect for the whole scene. And see what I could do from there.
I would say that the most difficult task of the project in the end was to decide and experiment with these limitations. I've noticed that many people who make frameworks have problems defining it right for users because they only use it for one of their projects (usually a big one), or because they use graphics from existing games for their tests. I realized that I was guilty of all that too, and it's only when I started creating small games on my own (after all, if my framework is as simple and fun to use as I say, I should want to make loads of games with it!) that I realized that the human constraints for making graphics, code and music/sfx in 2019 are pretty different than that of 1980s. As much as you'd love animating the graphics of Castle Of Illusion, you will find yourself at trouble trying to draw something of similar quality! Therefore the framework should not be made to be used primarily with such graphics, but likely some simpler, lower resolution ones. And limitations should be there to guide you, prevent you from overworking the graphics, but rather instead toy with them in the code for instance.
The initial target as far as game styles go are:
- Racing games (both Outrun "raster" or F-Zero "mode 7" style)
- Platformers
- Space shooters
I'm currently making a "top-view" platformer with it (pseudo-3D with the shadow on the ground to guide the player), I'll show a first demo soon.
Try it?
I'll continue with other blog posts about development, and especially what those constraints ended up to become exactly, but I've already got online a first version with some demos. It runs directly in modern browsers, although I know that there are some remaining issues on some browsers.
https://brunni132.github.io/vdp16-samples/
Try it and let me know what you think any feedback is extremely valuable!
Very cool, thanks for sharing! Love this limited old-school development experiences, I'll have to give it a go sometime!