SHUFFLEBOARD
Status
Start Year
Duration
Development Platform
Technologies / Concepts
Complete
2023
5 Months
Native C++
C++, Data-Driven Design
OVERVIEW
During my first semester in graduate school, I spent some time working in Easy 68k Assembly to create an implementation of the tabletop and outdoor game Shuffleboard. Though many variations exist, the central mechanic involves players taking turns sliding pieces into target zones.
Done in a modern engine, or at least a standard coding language, this project would have taken all but an hour. However, I saw this as a good challenge to try and practice low-level coding in Assembly.
The many windows used while working in Assembly
Creating a physics collision system in Assembly already seemed like a daunting enough task, however, I also decided to implement these collisions without the use of trig functions as I found the overhead for storing a trig table to be unnecessary. I instead opted to implement the collisions using vector math.
There was, however, one factor of this implementation that vastly simplified calculations. In the game of Shuffleboard, pucks are considered out of play if they fall off the table, meaning that no collisions needed to be calculated with any walls. This meant the only collisions that needed to be calculated in this project were between different pucks.
These calculations are even further simplified when considering that all the pucks are the exact same size and the exact same weight. Although friction is at play, by assuming that the collisions themselves are perfect, it makes the calculations much easier to compute.
Collision Detection Code
The other major implementation in this project was added the score system. This is something that, again, would have been trivial in a modern engine. However, doing so in Assembly proved to be quite a task.
I decided to use 7-Segment Displays for the scores in this game, with each player needing only 1 digit each (the max score conveniently being 9 with 3 pucks each).
I encoded each of the 10 digits to a byte, with each bit representing one of the 7 segments and one bit being spare. I could then easily set the display to one of these 10 variables and have the display render the correct digit.
Each of the 7-Segment Displays
Finished Gameplay
WHAT I LEARNED
Although working in Assembly directly can often be seen as excessive, it did provide me with a good experience with many important take-aways.
The first thing I got from this project was a better understanding of how things function at a lower level. Although I had worked in Assembly previously, it was not to the scale of creating a physics engine and rendering sprites pixel-by-pixel to a screen.
Because of this, it then became easier to see places for optimization. Instead of rendering a sprite every update, instead only update the ones that have moved. Instead of calculating each puck every update, only check the ones that are moving and add another to the list to be checked once it gets hit.
Overall other than serving as a refresher on vector math, this project also helped me better get into the mindset of optimization as well as understanding what type of calculations and optimizations are being made by the game engines commonly used today.