Posted On: 2019-07-01
This blog post has taken something of a 180 in the middle of working on it. Originally, I had intended to explore how game development generally deals more with mathematical challenges and less with what I would call "technical" programming challenges.* As I worked through the argument, however, I came to realize this was a bit shortsighted: as I am still in the prototyping stage, I necessarily am more involved in gameplay code, and gameplay is generally very mathematical. My original belief, that technical challenges were rare in game programming, was colored by the fact that I am simply not far enough along for the language implementation to matter for what I am working on. In hindsight, this should have been obvious (optimization is highly technical) but for whatever reason I was focused on abstraction-based and object typing-based challenges, rather than recognizing the obvious counter-examples.
While this post doesn't have a neat or tidy way of wrapping up everything, I still think it explores interesting territory. I personally find technical challenges fascinating, as they throw our understanding of the programming world into conflict with itself: languages, frameworks, and operating systems were made to simplify our work, so why then are they the source of so many technical problems?
"Technical" is a broad term - the Merriam Webster dictionary defines it: "relating to a particular subject, art, or craft, or its techniques." While one could take this to mean the entire domain of programming, doing so would render it largely useless as a way to categorize challenges. Instead, I prefer to consider technical challenges to be problems wherein the solution directly benefits from the depth of a person's understanding of the supporting systems it is built on top of (frameworks, languages, operating systems, etc.) Thus, I am considering challenges like calculating jump height, Inverse Kinematics, or calculating physics forces to not be "technical challenges": all of these benefit much more from a background in geometry than a knowledge of underlying systems. Instead, I am considering challenges like adjusting Unity's script execution order and accounting for the effect of scope on variable hoisting to be technical.
I touched on this briefly in the opening, but generally games have a lot of mathematical and geometric challenges that must be solved up-front. Many of these fall into the domain of Game Design (good "game feel" and progression systems to achieve a certain pacing) but they are by no means exclusive: shaders and animation systems also use plenty of mathematics (for example, the curve defining a visually pleasing ease-in-ease-out animation.) Technical issues do occur, even at the early stage, but while a game is rapidly changing it is much more likely to have mathematical challenges than technical ones. Importantly, when a project enters into polish and porting phases, I expect that this relationship will be inverted. In particular, porting is very likely to introduce plenty of non-mathematical design challenges (gamepad vs touch vs mouse) as well as mountains of technical challenges.*
There are two main reasons that I think this important. Firstly (and this is a rather personal reason) I am generally more experienced at dealing with technical challenges compared to mathematical challenges. As a senior level full-stack web developer, I was often involved in troubleshooting the intersection of systems that did not behave as expected. Conversely, full-stack web development seldom overlaps with mathematical software challenges - generally we worked with the organization and aggregation of information, rather than actual calculation. As such, I personally find challenges like avoiding race conditions to be quite simple, yet I have to manually work through even simple force calculations.
The second reason why this is important is (imho) applicable to just about anyone starting out game development. Effectively working with a system requires learning its nuances and limitations, and the more technical challenges you overcome the better you will become at understanding what is going on "under the hood." While it is wonderful to be able to start right away solving domain-specific challenges (making the game) this unfortunately means that a lot of this is done without an understanding of the systems it is built upon. Since the technical challenges are more concentrated late in the development cycle, there is a significant risk of the challenges seeming insurmountable, as the developer may only have marginal knowledge of the underlying systems. Even as someone with a significant background in technical challenges, I expect that I will have problems: my knowledge of .Net internals is often tested and stretched by the way it intersects with Unity (which is more akin to a C++ application that exposes a C# scripting API, rather an actual C# application.) Even if I have the skills to rise to the challenges as they occur, the fact that I am building my application atop a system that I don't fully understand means I will likely make poor design and/or architecture choices early on, based on a flawed understanding of what's occurring "under the hood."
Hopefully this jaunt through what is a "technical challenge" in software, and why it matters, is useful for you. As mentioned in the opening, I don't necessarily have a great takeaway from all of this, but I have found the process of unwrapping it all to be fascinating, and I hope that it's been interesting to you as well. As always, if you have any thoughts or feedback about this, please let me know.