school_projects /

SNESK

Connell Reffo, Hillary Nguyen

overview

SNESK is a re-implementation of snake with additions required for an assignment in the course CPSC 359. It runs on a bare-metal (no underlying operating system) Raspberry Pi 4 and is controlled using a SNES controller (the driver for it was written in a previous assignment).

gameplay_mechanics

The game consists of 2 rounds: collect and hunt. The collect rounds requires the player to collect every flag on the screen before the time runs out while new ghosts periodically spawn throughout the map. The hunt rounds requires the player to eliminate every ghost on the screen before the time runs out. Around the map, there are power-ups that are generated frequently and can be collected to help the player.

Grow power-up increases the length of the snake and is the colour purple.

Shrink power-up decreases the length of the snake by and is the colour orange.

Portal power-up allows the snake to go through one side of the screen and come out the other side. It is the colour blue.

Ghost power-up allows the snake to eat exactly one ghost. It is the colour red.

implementation_details

Creating a game without an operating system introduced challenges such as lack of dynamic memory allocation and no async runtime. Additionally, running on Raspberri Pi 4 meant the game had to be highly optimized to run at a reasonable speed. Below are some of the implementation details that were used to overcome these challenges.

Fixed size arrays were used to store the snake and other entity positions. Specifically, the snake was stored as an array of a lot of structs (~100) that represented each segment of the snake. This array acted as a circular buffer where the head and tail indicies rotated around the array each move. The snake was able to grow by simply not moving the tail index.

Surgical re-rendering was implemented to only update the parts of the screen that changed. This was straightforward since Snake operates on a grid and only a few cells change each frame.

Custom font/sprite engine was created to render text on the screen. Every character (and sprite) is hardcoded as an 8x8 byte array. However, this representation of characters could have been improved by using a single 64-bit integer to represent each character instead.

Event loop was used to handle input from the SNES controller, update the game state, and render everything on the screen to make the game feel responsive. The game would tick a certain number of times per second and the event loop would run as fast as possible by subtracting the time it took to run from the time it was supposed to run using the Pi's internal clock.

images

Below is some images taken of the game.

SNESK menu SNESK collect round gameplay SNESK hunt round gameplay SNESK pause menu SNESK lose screen SNESK win screen