# The Pixel Maze: a Pico-8 game
## Current status
Completed.
## Overview
In this game, the protagonist explores a maze to uncover its secrets. This project is a solo-development that delves into the exploration of game development mechanics and principles.
The game engine was created using Lua and Pico-8. To maintain a retro aesthetics, I decided to use a 1-bit palette, which presented a unique set of challenges. The game features a lighting system based on a marching square algorithm.
URL: https://oneearedrabbit.itch.io/the-pixel-maze
## Project
I have been doing software development for over 15 years, and I thought that I could use some of my skills in another development domain, and do it just for fun. This time I wanted to make something different and began working on a tiny 1-bit retro game.
I have heard many horror stories that game development is hard, and I was eager to gain first-hand experience of these challenges. Although prior experience is certainly helpful, game development demands a multidisciplinary approach. This includes composing music, creating sound effects, designing and drawing tiles and sprites, thinking carefully about game mechanics, among many other aspects.
I am a solo-developer, so I had to prioritize ruthlessly, determining whether a new idea meaningfully contributes to a game, or is simply nice to have but will ultimatelly drain my energy and lead to the project's abandonment quickly. I've been fortunate to meet great people in game development groups; the community is exceptionally friendly and supportive. It was a rewarding experience.
![[pixel-maze.gif]]
Source code (no assets): https://github.com/oneearedrabbit/maze.
The 1-bit lighting uses a marching square algorithm, wherein a two dimensional field is “stretched over” a list of 17 dithering patterns. I use a custom polygon fill function that clips sprites according to the specific case produced by the algorithm.
A clipping function partially renders a tile, subsequently painting black a clipped part. For instance:
```lua
fillp(dither[bright])
rectfill(box, 0x70)
fillp()
customfill(15 - case, 0)
```
`customfill` function manages 16 cases based on a contour lines lookup table, as well as the mirrored contours for case 15.
When dealing with case 15, I draw the entire sprite and render a rectangle with a pattern fill based on the brightness. Case 0 corresponds to a solid black rectangle.