Spending long, frustrating hours writing complex graphics code and then finally seeing the results of your work come to life in front of you is the second best feeling in the world. The best feeling is, of course, admiring the flashy accidental art that happens when the code doesn’t quite work correctly. After every “mainline” post I’ll be sharing the wildest bugs I managed to capture around the same time as the events of the post. Enjoy! (Consider all videos of this series to have an epilepsy warning.)
Ever since my code started producing pretty cool bugs and glitches, I have been repeatedly asked to start documenting my misadventures in computer graphics. And finally, here it as – a freshly deployed blog, a blank slate, yet to be filled with the broken hopes and dashed dreams of software development. How exciting.
The plan is to produce a write-up of every interesting topic that I research while working on the Minote project. If I keep at it, hopefully I will catch up to the present before it runs too far ahead again. So, without further ado, let’s start with the part that all things start with.
Minote was initially created with one specific goal in mind: reimplement the arcade game Tetris: The Grand Master with an easily accessible coat of modern UX design and attractive graphics. TGM is a videogame which should absolutely not be overlooked by anyone with interest in game design, as it’s one that could legitimately be called a sequel to Tetris. The purity and elegance of the original ruleset is preserved, while refining the controls with frame-precision and expanding it with movement features that, past a certain speed, transform the classic puzzle into a fresh new challenge that extends all the way to human limits and beyond. If at any point in your life you, through no action of your own, find yourself with a copy of MAME and the ROM of the game, make sure to check it out. A community-produced version called Shiromino is also a great option.
The community around the game was quite small – it’s hard to get people to play a game which is not only notoriously difficult, but requires non-trivial effort to even start playing. Even after dropping a few plays, it can be discouraging to hit the initial wall of rapidly rising gravity. As is standard for any arcade game, no guidance is ever provided to help the player advance further. Instead, players are expected to talk among themselves to find the techniques and strategies that allow one to eventually reach the end. This seemed to me like a problem, a fixable one – we just needed a version of the game which makes it easy to get started, and provides the encouragement and progress tracking which is expected by players of modern games. The core of the game is timeless, and only needed an updated presentation. With this in mind, I opened my IDE for the first time in years.
At that time I’ve done a small bit of hobbyist programming, but had next to no knowledge about modern graphics, and the game absolutely needed to make use of full power of the hardware to have the visuals that would interest a casual gamer. I chose to go with OpenGL, mostly because of this brilliant tutorial, which explains not only the API but the basic graphics programming techniques and the theory behind them. After a few weeks, which extended into months, a prototype was ready.
By the end the game was a nearly frame-perfect recreation of the original, with a slick presentation, particles, and glorious bloom. The road seemed clear to add more features, polish it up, and prepare for full release. If you like what you’re seeing, feel free to give it a try!
So why not?
Around this time, it started feeling like the project was taking a bit too much effort for a game that’s just a copy of something someone else made. TGM is very well designed but not perfect, and during hours of testing (and not just playing it repeatedly because it’s so addictive,) I came up with many ideas for potential changes which could make the game more intuitive, or at the very least shake things up a little. Implementing them would bring the game out of the questionably legal territory of being a clone. Considering The Tetris Company’s history of being litigation-happy and sending takedown requests to fan projects, this was not a comfortable position to be in. A new version was released which implemented some of these changes, like a unique randomizer, more intuitive and symmetrical rotation system, and further improved animations and effects. Some of the more outlandish ideas however would require changing the game on a very fundamental level.
Another source of issues was from the technical side. OpenGL is an API with very long history, and despite best efforts to keep it updated with changes to GPU hardware, it still has a lot of ambiguity in the API specification which results in code producing different results on different graphics drivers. Cross-vendor testing, and fixing all the bugs caused by a loose API specification and GLSL miscompilations, was starting to eat up a lot of development time. Something had to change, or I would never get out of bugfixing hell.
2nd attempt (ongoing) (actually 4th)
I’m no stranger to rewrites, and I realized they’re never as rosy as they appear. Old problems go out, new problems come in. Instead of throwing out all code, I decided to replace the renderer first, with one that could handle all the wild ideas of marrying visuals and gameplay. A properly modern one, in Vulkan, with PBR stuff and GPU-driven. It turned out that I quite enjoy graphics programming, perhaps more than I ever enjoyed making the game… It’s been almost 2 years, and the renderer is still in progress, and so many weird and interesting things came out of it. Friends in the wonderful Graphics Programming community, finding out which C++ features aren’t all that bad, computer locking up with colorful stripes flashing on the screen. Modern graphics programming feels like the comeback of writing ultra optimized code to extract the full potential of the raw hardware; there is minimal OS supervision, just you versus the GPU, a horrifying beast which can unleash incredible power should you manage to tame it. A completely different paradigm of thinking about problems, where even basic constructs like the “if” statement are executed differently on a fundamental level. It’s fascinating, it changes your thinking, and it made me rediscover the joy of programming.
But I’m rambling, and you don’t care about this. Minote is a work-in-progress renderer with some unique goals of fully procedural shading (no textures), having no visible artifacts that we typically associate with the “videogame” look of CG, and handling very high instance counts; to be eventually used for videogame and digital art projects. Now that I think about it, I could’ve started with that and spared you the barely relevant leadup. Well, I hope you like reading about tetris.