With a new year beginning, I can sit back and reflect on the amazing things that happened last year. One of my favorite things is making the snake game on the Raspberry Pi. It's been quite a journey!
The idea
2022 was going to be my IoT year. After coming back from parental leave in January, I got to work creating my indoor irrigation system. It was a moderate success. I got to blog about it and tried out some new tech. It even got some reach on Reddit! The system was in use for about two months taking up precious space in our washroom, much to my fiances' frustration.
After the irrigation system project, I saw a video of a man creating a LED video cube. It was really a cool idea and I wanted to attempt making one. After reading a few tutorials I ordered the parts and got to building a LED cube. There was not a lot of complicated hardware to learn as I decided to use an adafruit HAT to connect the LED matrix to the Raspberry Pi. This made the communication from code to matrix easy as there were many pre-made libraries available. All are powered by a 5V 5A power supply.
I had many thoughts about what I wanted the cube to do, but I landed on making a snake game for it. A snake game is something that I thought would work well in a cube format. A challenging part of making snake on a cube is handling when a snake goes over an edge. 5 matrices are connected in a chain and make up a rectangle of 320 x 64 pixels (or 160 x 32 pixels when the matrix is 32 x 32). When folding this into a cube, we have to map out where the snake head continues on that rectangle. There's special handling when going from the top matrix to one of the sides and vice versa. Also, there's a special handling for going around the end of the rectangle.
The microcomputer inside the cube is a Raspberry Pi 3B+.
The snake game was initially a demo that I made in F#, but I ported it to C# for convenience's sake. Some pointers:
- The game is made by a 2-dimensional array consisting of a snake body with a direction, an apple, and empty spaces.
- Stores the head position for every tic and traverses through the snake's body to be able to find the tail.
- You have a limited number of steps until the snake starves and you have to eat apples to gain more steps.
- For each apple you eat, you grow 10 pixels.
- The game is over if you hit the bottom edge or if the snake hits itself.
- 10 points for each apple eaten.
The source code for the cube can be found on GitHub!
"Can you make it bigger?"
I was really excited after creating the first version of the cube. More people have to see this! In NOVA Consulting Group we had plans for having a stand/display on NDC. NDC is one of the world's largest developer conferences and would probably generate excitement in like-minded individuals like myself. So I suggested the cube as the main attraction. I showed NOVA the prototype and got a consensus to go forward with the idea. "Can we make it bigger?" was the second reaction that I got. This is actually the most frequent question asked in general about the cube. So, of course, I went home and ordered parts that made the cube 8 times bigger.
Making the cube 8 times larger required a more stable frame. Preferably something 3D printed. Luckily, a friend of mine is an expert at 3D printing and I sent the measurements to him. The results were pretty great and I glued my matrices to the frame. Thank you for your help, Eivind :)
Arranging a hackathon
I arranged a small afternoon hackathon to teach my colleagues about development in Raspberry Pi and hopefully make some good functionality. I brought the cube to the office and many got to see the cube for the first time.
I set the following agenda for the hackathon:
- Continue developing the game. Add new features and make the game design better.
- Make the game run in the background on the Raspberry Pi. Before the hackathon, the game was triggered by running it from the command line.
- Countdown before starting the game.
- Sound effects.
- Connect and integrate the gamepad.
- High-score. How do we register the scores?
The format was a free-for-all where everyone got to play around with the cube. Even watching others play the cube was valuable. The whole point of the hackathon wasn't to produce something useful, but to learn something new and have fun doing so. We ended up having a discussion about the registration flow. We first wanted to be able to scan the NDC badges to register, however, we ended up creating a manual form to register scores of finished games overseen by the stand members. Overall a valuable experience and I'll definitely arrange more hackathons and workshops in the future.
To make the game competitive we also needed to make a high-score board and a scoring system. I wanted to bring in other developers to help me create a high-score and registration website. We decided to make a simple Blazor web app in Azure with live updates using SignalR. I want to thank Marius and Sara for the wonderful contributions they made to the website. Also kudos to Tomas G, Tomas R, and Martin for their input during development.
I didn't want the cube to be dark when idle, so I created a screen-saver functionality. The Heller Zeller rpi-rgb-led-matrix library was used to output animated GIFs while the cube is idle. Martin even created an official splash screen animation for the cube! Creating the screen saver is something I thought was going to be easy, but it was something that took longer than expected. It boiled down to careful handling of the processes on the pi. If multiple processes of the matrix renderer ran at the same time the pi would crash. So an efficient canceling of tasks when starting a game or a new animation was triggered. I initially bought Bluetooth controllers and tried connecting them to the pi. After a lot of trial and error, I ended up buying 2.4 GHz WiFi controllers. Bluetooth controllers suck.
Getting my 15 minutes of fame!
Norway has this awesome news site called kode24.no. I was interviewed by them and I got featured on the site a few days before the NDC conference kicked off. You can of course read about it here.
I published a TikTok video of the first cube that got a few likes. Here you can see my awesome soldering skills where I solder over my keyboard without making a mess! That one you can find here.
NDC and a one-hour visit from the demo ghost
Before talking about NDC, we need to understand that the cube had never been tested in the wild before. The ad-hoc testing sessions at the office and at home were a safe haven compared to the massive scale of a tech conference with thousands of people. Naturally, I had to push some final, nerve-racking changes the day before passing the cube along to the good people that were setting up the NOVA stand. I was told to use the NDC open WiFi to connect the cube to the internet. I was skeptical about this but configured the cube to do that. I did some further hardening of the security of the cube as a result of this:
- Updated the distribution
- Created a really hard, Fort Knox password
- Changed the default ssh port
- Installed Fail2Ban in case of brute force attacks
I arrived early at NDC. People were excited to see the stand. As I arrived at the stand, we turned on the power to the cube. The animations started and we were off to a good start. However, when someone tried to play a game the cube crashed. I found out that playing the game required an internet connection and the pi would not connect to the open wifi. I tried every spelling of the SSID, but nothing worked. Since the pi was set up headless I needed to power off the pi and configure the SSID on the SD card. This was tedious and we ended up connecting to one of the stand members, Karoline, mobile hotspot for a while. After that, we were able to make the game work!
Now I could finally enjoy the conference! After coming back from the first round of presentations, I was blown away to see all of the people that wanted to play! All the stand members were on their feet registering scores and talking to guests. The cube really worked as intended. I also need to disclose that the grand prize for the top score was a PlayStation 5. That might also be a reason for the big crowd.
To be independent of Karoline's phone, we decided to go out and buy a 4G router and a paid SIM card. We got that connected and all was good. For a while... We had purchased a SIM card that had 30kr coverage. Which was enough for a few hours of game time. I was notified when I was at home and the day after I brought my own 4G SIM card with unlimited data. After that, there were no issues and the cube was played long into the evening of the second day.
On the third and last day of the conference, a few contenders were pushing the high score to the top and at 13:00 a winner was crowned. The winner had a whopping 420 points, which was 80 points above his next-best score and second place. Third place was 300 points. These are scores that haven't been matched since.
Some stats
- During NDC, 1,297 games were played
- While the cube was functioning, a game was played every 1,5 minute
- The highest score was 420 points
- The average score per game was 58, not counting games that had 0 points
- 211 people registered their scores
Life at the NOVA House
I'm blown away by how much attention the cube got. I'll be sure to make more content for the cube in the future; different game modes, seasonal modes, etc. We do already have a Christmas mode 🎅
After NDC, the cube isn't collecting dust. It's centrally placed in NOVA's new offices in Karl Johans gate in Oslo and is still turned on today. Often played during or after office hours. Perhaps it will travel to other conferences? Perhaps you will see it at next year's NDC?