Introduction
main.cpp
Wait a second, maybe I'm jumping the gun here. How about this:
Main.java
public class Main {
public static void main(final String[] args) {
System.out.println("Hello world!");
}
}
A little wordy, don't you think? What about:
main.py
That's certainly more concise than the Java version. Easier on the eyes than the C++ version as well. I'm still moving too fast though. Let's take another step back. What am I even making? Who is my target audience? What platforms am I targeting?
I'll be honest, I didn't actually create these files on my computer. This code was in my head until I started writing it down here. Choosing which language to use is important, but it's not the first question to ask. There are a lot of things that I need to decide on first, and my language of choice will differ based on those decisions. So let's go back to square one...
Who am I?
That's a little bit of a deeper question than I really want to get into, but I feel it will provide some appropriate context for the reader. With this context in mind, my motivations might become more clear, and my decision-making might make more sense.
Professionally, I am a software engineer with post-undergrad experience just shy of a decade. Depending on who you ask, my skill level is somewhere between a well-established "Senior Software Engineer" and an early "Software Architect". I have worked at Fortune-500 companies and startups alike. I am currently working in the video games industry, though I do not work on video games directly. At least not professionally.
Personally, I am a husband and step-father above all else. In my free time, I tend to fixate on my hobbies, which include programming and music production. I love video games, and have great nostalgia for the "greats" of my generation, including Pokemon, Zelda, and World of Warcraft. While I still play games occasionally, my play-time is far less these days than it was in my earlier life.
My passion for computers and technology reaches back to my days in elementary school. My family was not fortunate enough to own a computer until the early-2000's, but I had some wonderful teachers who introduced me to computer architecture and programming, igniting that passion. Through my middle and high school years, that passion would evolve from stylizing my Neopets shop and Myspace profile with CSS, to installing Linux on an iPod, to working in a computer repair shop and automating as many processes as I could get my hands on.
My college years were spent repairing more computers to pay rent, and learning new programming languages. In the early days of smart phones, I released my first application, Ventriloid - a Ventrilo client for Android devices - so that I could stay in touch with my World of Warcraft guild when I was unable to log in from a computer. I did not have the foresight at that age to realize how impactful the development of that application would be for my future career.
I met the woman who would become my wife, Allison, toward the tail-end of my college career in 2012. I graduated from Georgia Southern University in 2013 with a B.S. in Information Technology, and a minor in Computer Science. Allison and her daughter, Renea, moved in with me in 2016, and we officially became one family in 2018.
I spend a lot of my time learning about new things - new programming languages, how to make a programming language, video game development, game engine development, processor architecture, cryptocurrencies, market analysis, and much more. I was a terrible student, and a classroom is not an environment in which I excel (though I am happy that I stuck it out and finished my degree).
To this day, Ventriloid is the only solo project that I actually released and maintained. Even so, it was little more than a pretty user interface on top of an open-source library that I modified for my needs. I crave the feeling of success that comes from releasing a project on your own, and so that is what I intend to do.
I consider my life up to this point a great success story, but the story is far from over.
What is this book, exactly?
This book is an attempt to follow along with the development process of an application from its conception all the way to its initial release, and perhaps a short while thereafter. I intend to write out my thoughts and problem-solving process in detail, such that the reader can truly understand the reasoning behind every line of code and every architectural decision. Many technology books glance over the complexities of the development process, instead opting for a more definitive approach, and declaring the "right" way to do things. The reality of software development is that things are rarely so simplistic, and compromises must be made.
Consider this book an extension to a source control repository's commit history - providing additional insight into the development process as it is happening. I intend for it to read more like a story than a textbook.
Who is this book for?
If any of the above has peaked your interest, then you'll probably enjoy this book, or at least be mildly entertained by it. I assume the reader has a passing understanding of programming using C-like programming constructs such as variables and functions, but it's not a strict requirement. Throughout this book, I will be telling stories of past experiences, diving into the deep end of the code, and then coming back up for air with more anecdotes. I don't intend for this book to contain every line of code, but I do intend to keep the project open source for anyone to dig into if they are interested in doing so.
So what should I make?
I've had a lot of side projects, and nearly all of them were abandoned because of one of two factors (sometimes both): the project was overly ambitious for a single developer, or the project just couldn't keep me interested. Don't get me wrong, the amount that I've learned from those projects is invaluable, and has greatly contributed to the success of my professional career. However, if I want to finish this book, then perhaps I should keep the scope of the project small.
On the other hand, too small of a project would be easy to implement, and would therefore have no interesting problems and solutions with which to keep my interest or fill this book! Therein lies my conundrum.
So let's find some middle ground. Here's a list of things that I find interesting or fun:
- Video games
- RPGs and co-ops are my favorites
- Not a fan of mindless games, like infinite runners
- C.L.E.A.N. code (more on that later)
- Low-level systems
- Networking
- Simple graphics and physics
- Entity / dependency management
- Music
- I play guitar and drums
- I specifically enjoy performing and recording my own music
And here's a list of things that I find boring or tedious:
- Content creation
- 3D art
- Any art resembling a human
- Story / narrative
- Background music / sound effects
- Web APIs / "CRUD" applications
It took me over a decade to learn this much about myself.
Some Historical Success
I didn't know it at the time, but Ventriloid was the perfect application for me to work on. I was able to learn Java, how to integrate a Java application with a native library written in C, and how to transmit voice data over UDP. I was also able to avoid dealing with any REST APIs or databases, and the only "content" I had to develop was the icon for the app.
Some Historical Failure
I've attempted to develop video games on my own on multiple occasions. I've dabbled with Unity and Unreal Engine 4, and I've tried my hand at developing a custom engine several times, in several different languages. I've tried to develop RPGs, multiplayer shooters, platformers, and more. Each time, I find that I have a lot of momentum as I'm working through the low-level systems in order to build the underlying platform of the game (entity system, render engine, etc), but once it's time to fill the game with actual content (world-building, characters, narrative, balancing), my interest rapidly declines. I've looked into procedural generation as a means of reducing the amount of manual content generation required, but that generally only takes care of the "world-building" part. I've looked into using pre-built assets from community-driven libraries like Unity's Asset Store, but I feel a lack of attachment to the game, having utilized someone else's creative vision.
Motivational issues can be tricky. You don't often find programming books that talk about "just not wanting to" and how to "get over it". It's incredibly common in this industry, and people don't like to address it. I don't claim to know the answer either, but I do recognize it as a potential roadblock on the path to releasing a product, and as such, I'd like to minimize my chances of failure by choosing a project that will retain my interest for as long as possible.
Some Other Ideas
Music / Digital Signal Processing
I've mostly tried to keep my interest in music separate from my programming. I don't really have any good reason for this, other than a fear of music becoming my "job". Doing so allows me to make music at my own pace, on my own terms, with no pressure or obligation.
I suppose it could be possible to make some software that is less focused on the creation of music, and more focused on utility. The first thing that comes to my head is an iPhone app that can serve as an effects processor for a guitar.
The latest iPad Pro (as of this writing) contains Apple's custom M1 CPU, which is the same CPU found in their latest iMac and Mac Mini desktops. It's a truly impressive piece of engineering, and certainly capable of performing some realtime digital signal processing.
A big obstacle comes to mind: how would you insert the phone/tablet between the guitar and amplifier like a traditional effects pedal? Apple has mostly discontinued the inclusion of headphone jacks on their mobile devices. Without taking sides on that debate, it still complicates my plans.
Furthermore, iPhones and iPads currently use separate interfaces for attaching external devices (iPhones use "Lightning" ports, while iPads have moved onto USB-C/"Thunderbolt" ports). Even if I were to produce custom hardware, I'd have to support both interfaces.
Another option comes to mind: Bluetooth. The guitar could output its signal into a Bluetooth device, which in turn would send the signal to the mobile device. The mobile device would process the signal, and then pass the output to yet another Bluetooth device, which would be plugged directly into the amplifier.
While the idea is really cool, I am not particularly interested in creating the hardware required to pull this off. There would also be large amount of latency involved, between multiple Bluetooth connections and the time it takes to actually process the signal on the CPU. I've also done exactly zero market research, and I wouldn't be surprised if someone has already released something very similar. Competition is good for the market, but as a solo developer, I have to remain practical.
I must acknowledge that I've only put thought into one possible idea in this space. I might revisit it later, but for now, I'm going to maintain my separation of hobbies.
Yet Another Video Game
The video game market is absolutely saturated these days, and yet, indie developers still manage to stand out from the crowd with unique mechanics or other clever ideas. Some games exist for years before they gain massive amounts of players seemingly out of nowhere (Among Us was initially released in 2018, but gained newfound popularity in 2020).
The current state of the mobile market is intriguing. There are a ton of games that are exactly what you would expect to be on mobile devices: infinite runners, Bejeweled clones, and many others that minimize the amount of user input required. Minimizing user input makes sense on a device in which the only input method is a touchscreen. Not only is it difficult to be precise (mouse clicks are pixel-perfect, fingertips are relatively fat), but your finger (and the hand attached to it) covers up the screen every time you have to touch the screen! Interactivity is the very basis of what differentiates a video game from other forms of media - if the user did not interact with it at all, then it's just a video. And yet, minimizing the amount of interaction required on these devices makes perfect sense.
As mobile devices become more and more powerful, many companies have started to release mobile versions of their IP. Shooters, racing games, MMOs - all traditionally known for their quick reaction time requirements or large amounts of inputs - now have a large presence on mobile devices. These types of games are generally produced by large teams, and their level of polish is hard to compete with. I have absolutely no intention of building a game of that scale, but I mention them to emphasize the difficulty of standing out in a crowded market full of high quality products.
The console market is similarly flooded with highly polished products from companies with large budgets. However, the gatekeepers of console libraries are noticeably allowing more and more indie games onto their platforms. Still though, the games they do allow are still no small feat. A "small indie game" that you encounter on the Nintendo Game Store likely took several years of development, even using an out-of-the-box game engine like Unity or UE4.
The desktop market is even more saturated than any of the other markets, due to the ease of publishing a game to Steam or itch.io. It makes me incredibly happy to see so many people building their own games and making them available to others - but at the same time, the sheer amount of competition incites a heavy feeling of hopelessness. For indie gamedevs to gain any traction in this crowded market, developers must spend massive amounts of time and energy making themselves known through social media, advertising, "devlogs", or numerous other methods.
Suffice it to say that making a video game of any sort is no small task, and trying to do so again while writing a book about it may be biting off a bit more than I can chew. Does writing a book about it fall into the "numerous other methods" category?
Still though, the sheer breadth of technical expertise required to build a game from scratch is incredibly enticing, if I can manage to keep my scope small...
A Social Network
Social networks are the bread and butter of modern society, like it or not. From the friend-ranking roots of Myspace arose more of the beasts, filling every niche imaginable. Facebook gained popularity due to its exclusivity. Dating websites are plentiful thanks to our always-connected digital world. Short-form-factor media such as Twitter and TikTok have taken off because of our short attention spans.
Attention is a commodity in a world full of advertisements, monthly subscriptions, and data collection. The more a company can get you to pay attention to their product, the more money they bring in. You don't even have to give them any money directly, because your data is all they need in order to profit off of you. And the more you use their product, the more data they have from you. It really is that simple.
So how can I comment on our short attention spans, and them immediately turn around and say that we pay too much attention to social media? Because they pretty much have us figured out. Social networks provide short bits of moderately entertaining media (be it text, a video clip, or even a GIF), not enough to fulfil your craving for entertainment, but just enough to make you want to scroll down for more. The key word is "want". These networks don't make you do anything you don't already want to do. And because of that, your attention will shift from one small post to another within the same website for long periods of time.
I know that sounds like some "tin-foil hat"-level of paranoia, but it's good to be mindful of how these companies operate. A company doesn't charge for a service, and yet is worth billions of dollars. There's a reason for that.
If you can't tell, I'm not interested in building a social network, but I do want to acknowledge the technical requirements of building a service of that scale. Scalability is hard. With the development of cloud computing, we started to see a lot more horizontal scalability all across the internet, which meant that more people could be doing more things at the same time without bogging down the "one true server". On the other hand, distributing work leads to data contention when multiple servers try to operate on the same data at the same time. A lot of people smarter than me realized that there were patterns that could be taken advantage of in order to reduce data contention while continuing to scale horizontally: partitioning! Every single user of your website doesn't have to operate against the same database, as long as you know which database to go to for any given user.
Google's Borg deployment system was developed internally to handle their massive amounts of traffic, but was the basis of what would become Kubernetes, which allowed much smaller companies to achieve the high scalability required to achieve success.
While web APIs and databases are pretty boring to me, coming up with a solid deployment strategy to support high scalability is actually pretty fun.
The Verdict
I've been sitting here staring at a blinking cursor for quite some time. I'd like to think of more ideas to add to the list. It's certainly not an exhaustive list, and I've asked a few friends for more ideas, but I think the items on the list are already vague enough to cover quite a large surface area. I've had something negative to say about each one of them (some more than others), but I really am drawing a blank here.
At some point, I need to get the meaty part of this book underway, so I really just need to pick something and run with it. On the other hand, I would really like to pick a project in which I have the most chances of success - I would like really like to finish this book.
So let's break these ideas down into a list of pros and cons.
Mobile Guitar Effects App
Pros: * Music is cool and fun. * I've never done any digital signal processing before - learning is good!
Cons: * Music is a hobby, I'd hate to turn it into work. * I've never done any digital signal processing before - risk is bad! * Custom hardware would be required, making both development and releasability difficult. * I finally Google'd it. This has totally been done. Tonebridge Guitar Effects looks great - I need to try it out.
Video Game Attempt Number... I've lost count
Pros: * Video game development can be as simple or complex as you make it. * Game engines are complex systems that are very interesting to learn about. * Game development is a fairly popular topic - it might draw in readers of this book.
Cons: * Hyper-saturated market. Unlikely to find success, but we haven't really defined "success" yet. * I've failed a lot of attempts to build games in the past due to untamed scope.
The Next Social Pandemic (not a great choice of words, these days)
Pros: * Highest likelihood of working with new technologies.
Cons: * While the market isn't as highly saturated as video games, it is still very difficult to break into. * Mostly centered around web APIs and databases, which I don't enjoy working with. * I really don't want to.
I think it's fairly clear which one I'm leaning toward here. I've burned myself so many times, but maybe I'm just a masochist. I admit that I crave some closure - I'd like to release a game and call it my own. If at first you don't succeed...
To that point, let's talk about how we define "success".
The Many Faces of Success
Let's tackle the cons that I listed out for building a video game.
Yes, the market is incredibly saturated, but because of the popularity of game development, it's incredibly easy to release a game. Whether or not your game does well is a different story, but releasing a game is easy... if you can finish building it.
It's good to acknowledge failure and learn from it. In the "agile" methodology of software development, we routinely have retrospective meetings to go over the successes and failures of each sprint. After particularly disastrous events, we have post-mortem meetings to point out the mistakes or events that lead up to the major event. In both cases, the discussions should remain blameless, and participants should leave the meetings with an understanding of how the failures could have been avoided.
I'm going to be honest, I've rarely been in one of those meetings without someone feeling like a complete piece of garbage. As much as management tries to ensure that it remains a "blameless" environment, we have been conditioned to feel ashamed of our failures - to hide from them and cover them up. I agree with the underlying motives of the "agile" way, but I'm not sure that it fits neatly into our highly competitive society. But I digress...
My failures were my own. No one else worked on those projects. I've had a lot of time to reflect on why those projects fizzled out, and I've stated some of those reasons earlier. Learning from those failures is a success in its own right.
So let's define what success means for this project.
Let's release a game on some platform. Let's keep it scoped to one platform for now. If the game sees some popularity on that platform, then we can talk about porting to other platforms later - but that's a pretty big "if", and popularity is not a requirement for success. In order to release the game, we need to finish building it, and in order to finish it, we need to avoid genres that require a lot of content. That rules out RPGs, platformers, shooters, roguelikes, and lots more. I'm sure there are some clever ways to make those types of games with minimal content, but I'd rather commit to something that doesn't tempt me with possibilities of beautiful artwork and expansive levels.
Let's release this book. This book should include my thoughts during the release process of the game itself, so it goes without saying that releasing the book will come after releasing the game. It will be difficult to write my thoughts on releasing the book, since the book must be completed before I can release it. In any case, I need to list completion of the book as a criterion for success, or else I will completely neglect to continue writing it.
Let's get started.