Source code is available on GitHub
One of the benefits of being neither a professional software designer or woodworker is that I never get tired of making mistakes doing either. So after many learning experiences, I ended up building this from the ground up:
and peals of laughter echoed through the halls
This started as an idle thought during some down time in an electronics factory in Shanghai. What exactly does building something "from scratch" really mean these days? Even the most aggressively old-fashioned luthier probably isn't growing and felling their own trees or slaughtering sheep for authentic gut strings. In this highly mechanized and productive world, even making something as simple as an aluminum beverage can involves mining operations in Jamaica and Guinea, international shipping conglomerates headquartered in the US and China, and domestic processing and manufacturing plants around the globe. So maybe making anything from scratch is a stretch nowadays. But at this point I wanted to build something without the aid of a factory line, and had drafted up some vague dimensions for an arcade machine in my notebook.
Let's define the project then:
- Designing and assembling the enclosing cabinet
- Selecting and integrating the electrical hardware
- Architecting and writing the game software
Which was how a buddy and I ended up in my workshop a few weeks later:
But I'm getting ahead of myself.
Let's start at the beginning!
Disclaimer: I'm far from a carpenter
Probably my main motivation in this project was learning more about woodworking. Wood is a great material to work with — relatively easy to shape, and it exists on a spectrum of quality allowing for cheap prototyping and the crafting of sturdy luxury goods. To get an idea of what the woodcraft would entail, I sketched out my ideas on paper and translated them into my old friend TinkerCAD:
This is inspired by the large cabinets found in any arcade, but reduced in height for a desk or table because my apartment is in San Francisco and therefore tiny. The dimensions are hand-wavy, my main thought was that I wanted enough room for two players and that would require ~8" per control set + some buffer between and at the ends.
If this sounds disturbingly cavalier towards hard measurements, it was and is. Most of this pre-work was done in my spare time on a business trip, but with powerful CAD tools and a small amount of foresight, I ended up with fairly complete looking model. Particularly important is the sizing of the display window, matched in height and width to a cheap old monitor at a classic 4:3 aspect ratio I found on Craigslist. The rest of the porting, such as holes for the buttons and joysticks, were left to be drilled by hand once I determined what exactly would be needed.
After mocking up the pieces digitally together, the next step was separating each area into flat files for laser cutting (which I decided was the best way to cut these because it uses lasers):
I reached out to a local workshop and got two sets cut from \( ^1/_4 \)" birch veneer plywood for $140. As a general rule, it's a good idea to buy spares as experimentation is destructive and long lead times for replacement parts will kill a project's momentum.
They came in looking pretty good, and with the help of some L brackets it fit together quite nicely.
The screen fit perfectly, and the next task was deciding the configuration of buttons. With simplicity in mind, I opted to omit coin slots and unnecessary controls and go for a straightforward 6-button + joystick approach using some parts bought off of Amazon.
Extracting a bit of geometry from the gaskets, we sketched out a configuration.
After the measurements were done, we used a Dremel with cutting and sanding bits to cut the holes — it didn't need to be perfect as the flanging on plastics covered up any small mistakes.
Finally, with the holes cut and drilled into place, we can do a fit check to see how it looks when assembled. But don't forget to label the buttons first!
This might just actually work
Looking pretty good! This is a fairly pretty cut of ply, but in general untreated wood this thin runs the risk of significant warpage due to changes in humidity and temperature — so I decided apply a stain and lacquer. The first step here is sanding it down a bit (but carefully, the ply veneer is thin).
With a more classic look in mind, I used two passes of a dark walnut color and then a matte finish:
Not bad. Giving the other pieces the same treatment, it's time to get started on the next aspect of the design.
In order to be true to the spirit of old-fashioned arcade machines, I wanted to make sure I wasn't just building a beautiful case for a high-end gaming computer. To this end, it meant picking hardware that was sufficient to run a 2D game at the classic CRT 4:3 aspect ratio, but not the latest AAA games. To minimize on cost and power consumption, I ended up selecting the Raspberry Pi v3:
tha new OG hobbyist kit
The Raspberry Pi is arguably the most popular single-board computer available today. Capable of running a small version of Windows and a few flavors of Linux, it should have everything I need to run a simple game and costs only $35. While this is typically the computer used for retro arcade machine builds, other folks tend to use the operating system RetroPie which allows the use of various emulators to play classic games — because I'm writing mine from scratch, I decided to use the more fleshed-out operating system Raspbian.
Though it is a more flexible and arguably more powerful OS, the additional tools come burdened with a cost of setup complexity and increased opportunities for hardware failures. The Raspberry Pi uses an SD card as its main non-volatile system memory, which means it's susceptible to corruption when subjected to high frequencies of read/writes and improper handling of power states. Simply put, this means "try not to hammer at the SD card, and make sure to shut it down before turning off power."
With that in mind, we can finish our list of electrical parts:
- 1x Raspberry Pi v3
- 1x 4:3 VGA Monitor
- 1x HDMI/VGA Adapter
- 2x Computer Speakers
- 2x Set of 6 Arcade Buttons + Joystick
- 1x Power Strip
- 1x Powered USB Hub
- 1x Electrical Switch (for Power On/Off)
This should have everything we need — computer, display, audio, and power. After mocking it up in a very rough sketch, it looked like so:
Picasso also played fast and loose with perspective
Here we get to the brains of the project. Typically I've seen folks set up home-made arcade machines with emulators to run all sorts of retro games — but I want it to run something I've developed.
Choosing the Game
It's like Geometry Wars, but worse!
The premise of the game is that the player controls a cargo ship in deep space, surrounded by hostile enemies with various degrees of firepower. Because the player controlled ship is merely a cargo vessel, most of the gameplay revolves around redirecting enemy fire into the enemy spacecraft with careful piloting and the occasional powerup.
It's sort of a running joke among my buddies that I keep resurrecting this ancient code from my childhood, so I decided to do so once again and bring Squid to life inside the arcade cabinet.
Choosing the Software Stack
I was mistaken.
One of the most popular platforms for writing cross-platform applications is Xamarin which runs on their open source .NET implementation, Mono. Curiously enough they revived the XNA framework redubbing it Monogame, and kept it syntactically almost identical to its predecessor.
Because I wanted my development environment to be as similar as possible to the final platform, I spun up a Linux virtual machine to do the bulk of my coding. This was my first mistake. Because software development is generally a dumpster fire, Monogame requires Monodevelop 6 but Xamarin has stopped updating their per-distro packages at version 5.9, so at the time of my writing this it is impossible to follow their installation instructions and actually code anything. Luckily as is usually case in the Linux community, one brave soul (shoutout to cra0zy) developed a kinda hacky workaround to get people like me moving.
Once Monodevelop actually started without crashing, I was finally able to observe all the ways my code wouldn't run. Beyond the more prosaic syntax errors and embarassingly deprecated API calls, there was plenty of core functionality that straight-up wasn't going to fly in Mono — guess it isn't as complete a port as I thought. Well, nothing good comes easy, so I got to work debugging and freshening up the stale code.
Eventually, things started coming together:
you usually need to pay good money for this kinda validation
Putting It All Together
Now that we have the constituent pieces laid out, it's time to start putting things together. I've heard it said the last 10% of a project is 50% of the work, and this is no different — the difficult unknowns that I've as of yet to address are now the only tasks remaining. Namely:
- How am I going to affix this massive, heavy monitor inside of the cabinet?
- How do I organize all of these gross electronics?
- How do I safely turn the game on and off?
Luckily, the first one has a simple solution: Liquid Nails
I drank one of these and am now also tough as nails
A liberal application of the above construction caulk, and you can be damn sure that the weakest part of your design is now the strongest thing you've ever built.
Letting this sit for 24 hours, we have time to start addressing the next few points. For organizing the cables and mounting the electronics, I decided to affix everything down using gear ties and command strips:
I'd build a house out of gear ties and command strips if you'd let me
As for safely turning the console on and off? Finally, a hotrod red racing switch:
which is then tied to a General Purpose Input Output (GPIO) pin on the Raspberry PI can safely keep the unit asleep in one position, and up and active in the other.
Conclusion & Parting Thoughts
When all was said and done, she struck a cutting figure in the ol' hardware lab.
Embarassingly, this little project actually took over a year to put together! As usual for me, the biggest difficulty of all was finding the wherewithal to continue after the novel joy of starting something wore off — setting aside the time to fail and learn, debugging intractable and unfun software issues (like ARM/x86 library incompatabilities holy cow), moving the equipment to a new pad in LA, staining and treating wood and then having to wait days at a time before putting everything together, and so many more tiny impediments proved to be the biggest obstacles that kill a project's momentum.
And for what? A stupid arcade machine? What a waste of time.
Well, then, I guess it isn't really about the finished project. There's something deeply meditative losing yourself in a new skill or hobby, especially when you reach proficiency and can really get lost in the now.
It's been a fun ride, let me know if you want a 1v1 grudge match on the home-grown Squidcade.