The short answer is perseverance, skills and the ability to teach yourself new ones, creative problem solving, learning from mistakes, and a looot of time. That's my take anyway. Read on if you're curious where I'm coming from!
The Rest of the Intro
I recently released Macrocosm which is a mobile game that takes you from atom to galactic empire across seven interconnected stages where making progress in one stage gives you a boost in the next. This post is a deep dive into the (nearly) four years of free time I spent making it. Part catharsis, part brain dump while things are still mostly fresh, but mainly giving back to the game dev community, this post is for anyone currently making an indie game or thinking about it.
First, let's start with a few stats, because who doesn't love those, and it also should give you a better sense of the scope of the project.
By the numbers
- First commit June 2nd 2018.
- 594 Trello cards created to keep track of tasks and bugs
- 677 days worked on
- 2097 commits (so far)
- Most productive days were 2/23/2020 and 9/20/2020 with 13 commits each.
Commits Per Month
Commits Per Weekday
Commits Per Day Hour
Without 3rd party libraries & dependencies:
--------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------
C# 321 8377 2789 39958
HLSL 9 102 5 517
Javascript 1 7 1 44
Bourne Shell 1 8 5 23
JSON 1 0 0 9
--------------------------------------------------------------------
SUM: 333 8494 2800 40551
--------------------------------------------------------------------
With 3rd party code:
--------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------
C# 1031 23359 23148 117836
HLSL 201 1077 280 18038
JSON 26 1 0 10365
Swift 1 65 10 375
Objective C 1 24 7 109
Objective C++ 1 18 5 62
Javascript 1 7 1 44
XML 1 2 0 29
Bourne Shell 1 8 5 23
C/C++ Header 1 1 0 4
--------------------------------------------------------------------
SUM: 1265 24562 23456 146885
--------------------------------------------------------------------
Back of the Napkin Hours Worked
Using the git-hours tool (and having to fix a bug in the repo along the way!) I used an estimate of 30 minutes before first commit in a session to come up with a very back of the napkin estimate of 1,366 hours. This only takes into account the coding time and the art I did myself, not any of the off computer design, testing, organization, etc. If I had to guess I'd tack on another 300 hours or so for all that.
Budget
I tried to be pretty frugal with how much I spent. Both because it's my hobby side project, and because part of success to me was just being able to break even on costs which is easier when you have less of a hole to dig yourself out of :)
Expense | Amount |
3rd Party Assets & Plugins | $264.60 |
Business Costs | $1,089.00 |
Contractors | $3,781.88 |
Web, Email, & LFS Hosting | $162.98 |
Apple Fees | $340.57 |
Unity Cloud Build | $210.32 |
------------------- | --------- |
Total | $5,849.35 |
Early Project Times
After coming to the tough realization I wouldn't be able to finish my previous project Solaria Tactics that I'd been working on for a couple years I took some time off working on side projects. Around that time Universal Paperclips spread through the office and internet like fire and I loved how it kept you on your toes for what would be next and what new gameplay would be unlocked. I still had the drive inside of me wanting to release a game that I could be proud of and actually release to the world, so it didn't take much of a spark to get my brain thinking of game ideas again. Like Universal Paperclips, I wanted to take the player from something humble and small to something gigantic and have a variety of gameplay along the way to keep it all fresh and new.
So I wrote down a few design pillars:
- Variety of gameplay
- Connected stages
- Can focus on your favorite stage, don't let the player get stuck
- Lower stage progression acts as a force multiplier for later stages
then brainstormed some ideas on what the stages would be, then got back to work! :D Two days after the first commit I had this
Which if you can squint hard enough, still forms the basis for stage one today! You can also see my fascination with MASSIVE NUMBERS that was coming from paperclip land. More on that later...
At this point in the process, I was thinking I'd spend about 1-2 months on each of the 7 stages and wrap up the project in about a year. Spoiler alert: that didn't happen lol.
One of the early challenges was figuring out how the stages would work together. At one point I was thinking there would be some linear path where the game would automatically bounce you between stages as you made progress in some sort of Tower of Hanoi-like pattern. This got tricky to design very quickly as I was writing it down, and luckily was convinced by a friend to change it pretty early on and let the player decide when to switch stages.
There was some interview with Chris Taylor about the making of Supreme Commander (still one of my favorite games) I read a long time ago where he was describing that as the game was being made, naturally everyone got better. The art made 10 months ago wasn't as good as the the art being made now. That lead them to working on the game in passes where they would try to make things as good and fleshed out as they can, then go back in another pass and improve everything.
So this is how I thought about working on Macrocosm. I would first make all the seven stages in a first pass rough draft state where they had the basic gameplay I thought would work and very placeholder everything else, then do another pass to refine, and repeat till release! I did follow that model throughout the project and think it worked pretty well for the project overall, especially given the connected nature of it all. I think it did save me from throwing away work and art that otherwise would have gone to waste if I would have tried to polish or finalize things too early.
Stage 2
Less than a month after starting the project I was onto drafting the second stage
Working on the snake movement code was one of those things where it's easy to get the basic version of it working, but surprisingly nuanced and complicated to get it to feel and work exactly like you want it to. I ended up coming back to it a few times over the course of the development to refine. In this first version you see it's doing the approach of having each part of the chain lerp towards it's immediate neighbor each frame. The problem with this approach is that as the snake does a bunch of tight turns the pieces of the chain down the line start to smooth out and follow a straighter line path instead of exactly where the head actually went. The other problem is that it's hard to make the head piece follow a nice curve while turning so you can't immediately turn back on yourself and break the chain which feels bad. I ended up with a sparsely populated circular buffer of points where the head went and then code to figure out which point to go to next. Lemme know if you know a better way :)
Stage 3
The first basic version of stage 3 came along pretty smoothly, though this was my first foray into the world of getting audio syncing up with gameplay. This is another one of those "oh that sounds easy" problems that is very much not. I found these guides that were immensely helpful though. As the rhythm game crash course says:
In rhythm game first you have to get the backing track to line up with the first "note" (what is that depending on your game) and the rest will stay correct UNLESS the game lags or the audio lags. 90% of the time the game lags and audio went ahead of the game since audio is not in the same processing unit with the game anymore after the play command. The lag requires separated resolution and I will not talk about it right now.
Audio in Unity is "fire and forget". When you ask UnityAudioSource
variable
The really tricky part is that your gameplay code only runs ever X milliseconds based on your frame rate, but the music is continuously playing. So between each time the update loop runs there's a different amount of music that has played. It takes some careful math calculations and using
public double MusicTimeElapsed {
get{ return (double)musicSource.timeSamples / musicSource.clip.frequency; }
}
to synchronize gameplay code to spawn things on the beat of the song.
Stage 4
When I was first started thinking about what I'd do for stage four I went down this big rabbit hole thinking of a platformer where you controlled a creature going around collecting DNA points sonic style (or perhaps EVO style) and you could choose which traits to unlock to make your creature hold its breath longer, jump further, or go faster and let you get to other areas of the map like a metroidvania. I went so far as to sketch out a whole map of how it would look before coming to terms with how hard that all would be to implement and play well. Thankfully I made that realization before starting to build any of it and brainstormed other ideas.
I ended up going with a roguelike partially inspired by the Evolution board game that fit my goals for the stage:
- Have unbounded replayability
- Consumes lives naturally
- Have some creature customization
- Balance skill with upgrade power
As usual, I wanted to go crazy with lots of creature adaptations that you could choose from that have gameplay impact, but more on that later. Along the way doing research for the stage I did find this awesome zoomable tree of life that you can find any species in and see how they relate to other species.
Stage 5
I played way too much Desktop Tower Defense in middle school computer class which kickstarted my love for the tower defense genre so I knew I wanted to do my own spin on it for Stage 5 from the beginning.
It didn't take too long to come up with the idea of layering on a resource collection aspect to the tower defense mechanism, and then using your population (lives traditionally in TD) as a necessary resource for upgrading your towers on top of that.
The only notable challenge getting this stage set up initially was getting the pathfinding set up for multiple starting locations with different destinations, and then handling all the cases where you need to update (and block creating new towers when you're putting it on top of an enemy). The Red Blob Games articles on pathfinding were helpful, particularly the one dedicated to tower defense.
Stage 6
Whew, onto stage 6 huh. How many more stages do I have to do again? Only one more? Ok, we can get through this, even though it's already February 2019 and past when I originally thought I'd be done with the whole game. Oh well, time to make a mini civ game!
I'm one of the millions of Civilization fans out there so it was a no brainer for me to base this stage off of it. However I did know that creating a combat system with lots of units to design, and an enemy AI to fight against was going to be way too much for me to do for just this stage. So I decided to focus on my favorite parts of civ like the exploration, city placement & management, and tech upgrades. This nicely danced around the tech intensive problems but also the design problem of "what happens if you lose" in a combat oriented game since I didn't want the player to ever have to restart.
The Catlike Coding hex map tutorials gave me a good boost on getting the initial map set up and world generation going but it still took a good bit of time to customize it and convert it from 3d to 2d.
It predictably took even more time to then write all the actual gameplay stuff on top of that like the first pass at city management, buildings, technology system, scouting, and the first pass at rivers and roads. After 4 months I had this:
Funnily enough, I got stuck on the triangle controls for city management and asked this question on the Mathematics stack exchange site and got a predictably dense math explanation that I couldn't follow and had to work it out myself.
Stage 7
Alright, onto the grand finale of the last stage. Something fun in a galaxy setting should be easy right? Here's what I was thinking of as the constraints for the stage:
Primary Contraints:
- Able to build it in reasonable amount of time
- Tie in stage 6 technology research
- End as a nice capstone for the game
- Primary goal of exploring the galaxy
Secondary Constraints:
- Use mass & energy as resources
- Have gameplay focusing on automating tasks that allow you to spread throughout the galaxy in an exponential fashion
- Work between solar system & galaxy scales
- Potentially have multiple endings/strategies for replayability
- Have nice space visuals so it's not all just UI manipulation
Having come off a long Factorio play through not long before getting to this stage I naturally was caught by the bug to make an automation style game at this point. I was imagining building up your colonies to mine resources, build probes and colony ships that would then colonize other nearby systems and repeat.
I wasn't quite sure how this would all fit together at first though so I started by building the part I was sure I wanted which was procedural galaxy generation and the 3 main zoom levels going between planet, system, and galaxy.
Since the game is science based I wanted the galaxy generation to be grounded in reality even if there were liberties to be taken for the sake of gameplay. I did a fair bit of research on all the nerdy galaxy formation stuff like: stellar classification, types of planets, gas giant classification, solar main sequence, distribution of luminosity classes, some old world building site, and a bunch of others. I settled on using GURPS Space which is a tabletop role playing guide as a starting point. It has a lot of details on galaxy, system, and planet formation with a bunch of probability tables that I could translate into a galaxy generation algorithm and then adapt as needed to fit the gameplay.
Once all that was in a decent state I had to come back to actually making a game out of it which turned out to be harder than I thought. Prototype after prototype just kept feeling tedious, too complex, or just plain boring. This turned out to be the trickiest game design problem of the whole game. Just balancing all the constraints took so much trial and error to come up with a design I liked.
I ended up taking inspiration from Mini Metro with the added layers of mining a small number of resources, combining them into other resources which are used to build and expand your galactic empire. By focusing on a small number of resources each with a theme and then having the combinations follow what you might expect felt like it was pretty approachable and gave a good design space to work with. For example Iron's theme is the base building resource, Xenon's is engines and transportation so naturally the combination of Iron and Xenon is the Thrusters resource used by colony and transport ships.
Once I got Stage 7 in a reasonable state it was time to go back to the beginning and start making content, work on the final art, and just refine everything. And oh yeah, by the way, it's already a year and half in and the game is nowhere near being done :)
A Brief Interlude on Tools
Roughly at this point in the project (really mixed in throughout working on other stuff) I spent a good chunk of timing honing the tools of the project. As a solo dev you don't want to spend too much time just working on tools but being careful with creating custom tools for your project and using the right 3rd party assets really is worth it's time in weeks. I would also advise to be pretty picky about what 3rd party assets you choose to use because integrating them into your project, really learning how they work deeply, and even finding some bugs with them can really sap your time.
One last tidbit of advice is to try to research and decide on core assets and libraries as early as you can to save yourself the hassle of switching to different ones mid or late project. Graphics, object pooling, and tweening packages are all good examples of this.
Here are the notable ones I used with some notes.
- I created my own Save Editor that was worth its weight in gold to be able to manipulate my save file outside of code to test all sorts of different scenarios and flip between different save files that were in different states and see what was going on.
- Around this time I switched from SVG Importer to the Unity vector graphics package to render all the games graphics. SVG Importer wasn't being supported anymore, had some memory leaks, and required different components depending on what you were doing. It took a bit to get everything switched over but I'm happy I did it. The vector graphics package is only around 3/4ths baked and then put on hold as most things are from Unity these days but I was able to get around its limitations. Having 9-sliced svg images would be real nice though.
- I used StrangeIOC from the beginning of the project since I had used it on my previous project. It's nice dependency injection that really helps architect your project in a clean way. The caveats are that I made a couple small modifications to it, there are a couple quirks with how to use it, and don't use the mediator concept (just bind everything in views directly) but being able to inject data models, events, and services into components is reaaally nice.
- Nice Vibrations is a great and easy to use package that does exactly what it says on the tin.
- The Color Palette asset is decent and saved me some trouble but it's nothing too fancy that someone who knows how to create custom editor windows couldn't do without too much trouble.
- I got Unity Flexbox to try to get something that could get me off of the Horizontal and Vertical layout groups which never do what you want and I despise. However, the flexbox asset had some issues of its own I can't remember and I had to modify it anyways and didn't use it everywhere. 5/10
- I started off by integrating the Unity User Reporting package that integrates with their cloud service but their site kept being super slow for me, sometimes would just be down when trying to send it a new report (or very slow as well), showed the screenshot in the wrong aspect ratio, and their retention period is a woefully short 7 days. All of this greatly frustrated the web developer in me and so I just wrote my own. It took me like 3 days to get everything I used from Unity working in my own except it was super fast and had infinite retention. Anyways, I highly recommend having a system in your game to both capture exceptions and report them to a server as well as an in game way for players to send feedback. This was so valuable to have both for debugging issues (and being able to download the save file that caused them) as well as improve the game through player feedback. If you're interested in any of this, send me a message. I should probably turn that into its own post and open source it.
- Object pool simple and effective. Tweaked a very small amount.
- Switched from iTween to LeanTween for performance.
- Shapes is a great asset for any sort of dynamic vector shape rendering. I use it a bunch for lines, progress bars, circles, donuts, and arcs that are all nicely anti-aliased.
Mid Project
So at this point in the project all 7 stages have most of their basic systems and gameplay worked out, the tools and infrastructure of the game are pretty close, but it's all developer art still and everything needs this tricky thing called content. I assume everyone who's made a single-player game before knows how time consuming this actually is, but for a new solo dev I found out it's really easy to grossly underestimate.
The trap I fell into was thinking that once the systems were done content was a matter of adding rules, data, and a few more scripts. In reality though it's doing those things plus then the realization you need a little more variety so the gameplay systems need extending, then play testing, then not being satisfied and tweaking some more, then working through problems with integrating the art, then balancing all the rules and systems, all while fixing a bunch of bugs.
Speaking of art though, it's an amazing feeling to see the first final (or near final) art in the game. The project just seems so much more real after adding it and it's a great morale boost. I highly recommend finding an artist to hire if you're not sure you can pull it off yourself. The look of your game really helps differentiate you amongst the thousands of other games out there to choose from. Being able to create the first versions of the art to experiment and prototype with is really important as well though. It'll save you time and money trying different ideas with placeholder cheap assets before committing to creating the final versions.
Stage 1 Before and After
One thing you might also notice in that before and after is that the big number score got removed. I got so far as to implement it in each of the stages with a nice animation ticker effect whenever you got more points, but that ticker effect combined with getting points all the time meant that the score was allocating memory like crazy constructing new strings constantly. I was starting to look into ways around that when I thought about it more and wasn't really happy with the arbitrary nature of what gave you more score and how much. So I did the simplest thing and just removed it all which I'm happy with. An important skill, especially as a solo dev, is the ability to evaluate your ideas and get rid of the ones that aren't working. Every single idea you have isn't a good one, trust me on that :)
Another example of an idea that needed editing was making the content for the third stage which is the cellular scale with a rhythm tapping and sliding to music theme. I started out by thinking I could randomly or procedurally create all the cells to tap on while each song is playing to save me from having to manually create a beatmap ahead of time. The more I playtested that though the more I realized that procedural wasn't going to work for the amount of time it would take to make it good. There needed to be predicable repeating patterns of cells to tap just like how in a song there's repeating patterns that make up the structure of the song (intro, verse, chorus, etc). If the player fails a song by missing too many beats it should also be the same patterns so you can actually practice getting better. So after the realization that doing that procedurally wasn't easy I just made a simple system that allowed me to create the beatmaps, and then it was just a matter of spending the time to create and test all of them.
There were plenty of other challenges and things to learn along the way while refining each stage and adding content. On the creature stage I had to figure out how to animate the dino's and promptly ran into the limitation of the vector graphics package that doesn't really work with any of Unity's other sprite animation systems. After doing some research on options I landed on using Anima2D for its bones and IK support even though it doesn't seem to be supported or maintained anymore.
Adding support for the notches at the top of phone screens was another unexpected challenge. Luckily there's a nice Notch Solution out there that does most of the hard work. Making sure that all the game UI worked with different aspect ratios and while compressed in with the notches took a lot of bug fixing though.
A good forcing function for keeping the game simple while designing it was adding tutorials for each stage. It became pretty obvious that if I couldn't explain what to do in a few pop up tutorials then I had made the game too complicated. This mainly was an issue on the last two stages building a civilization and a space empire which required a bit of simplification so I could try to explain to the player how they worked. In general though the tutorial system was yet another system that turned out to be more complicated than I originally thought it would need to be. It needs to handle all sorts of events from the game to trigger tutorials, pausing and unpausing the game correctly (don't want to unpause the game if it's already paused while a tutorial is shown), handling multiple tutorials trying to open at once, as well as saving and restoring the tutorial state when the game quits and then reopens.
The last pain in the butt around this time in development was getting automatic builds created every day for both iOS and Android. This was really helpful to be able to test on actual devices and catch bugs that were device specific as soon as possible (usually ones with touch input handling). I did end up paying for Unity Cloud Build since it's obviously made for this exact thing. The build process for mobile apps is way more complicated to set up on your own computer than it should be so you're kinda forced into using a cloud solution. But even with the hosted solution it's not a walk in the park. You have to create custom scripts around accessing the build version inside the game and uploading the builds to the app store. Just setting up the certificates for iOS is an absurd back and forth process.
Finish it
At this point in the project I was feeling like you're probably feeling reading this: "This took way longer I thought and I'm ready to be done with it" :)
But as with any passion project it's hard to release something when you know it could be better and you see all the little flaws. So on goes the polishing, optimizing, tweaking, balancing, play testing, iterating, and bug fixing. I'm curious to know if anyone's tried to quantify development time as a function of game length is but I'd be willing to bet it's more than linear. Full playthroughs take longer and there's just more of everything to test and tweak like you can see here in the before and after of the city management UI.
Stage 6 Before and After
More code also means more places that can be slow which is important to pay attention to on mobile devices. This is another section that could be a whole post of its own but here's my couple Unity optimization tips:
- Get really familiar with the built in profiler, and add lots of custom samples with
UnityEngine.Profiling.Profiler.BeginSample("My Sample");
- Hunt down all the things that are allocating memory every frame. The usual suspects are creating strings, starting coroutines, and dictionaries keyed by enums need equality comparers.
- Know your data structures, use HashSet's instead of array's if you're mainly doing contains checks.
Getting the word about about your game is tough like you might imagine. I'm only barely qualified to talk about it myself so instead of me writing lots more words I'll point you in the direction of Chris Zukowski's how to market a game blog that has lots of useful info. Marketing for mobile games does seem to be a different beast though, some of which seems to involve questionable ethics that I don't want any part of. What you should be part of instead is your local game developer community! It's super helpful to find your peers and participate helping others with their struggles and in turn getting help with your own struggles. There were several talks given by the local group here that opened my eyes to things I hadn't even thought about before.
If you are into marketing and interested in working on commission though definitely feel free to contact me through the email in the sidebar.
So at some point you just need to pick a date to release the damn thing. I gave myself the deadline of releasing the week of Pax East so I could do some guerilla marketing while I was there. I'm glad I picked the date and got it out there but in hindsight it was a little crazy to do with going to the conference then flying across the country to see family the same day. If you can time it to give yourself a bit of free time after releasing to fix the bugs, do all the social things, and monitor all the other things that would be wise.
The only real hiccup with releasing was the Google Play Console having some really awful and confusing UX. There's no way to promote your pre-sale listing to full sale. You have to duplicate the whole store listing. The button that is labeled "Release to Production" actually means "Send the build to our review team that will take 48 hours to review before you can release unless you already did that by turning on this other setting we won't tell you about". So yeah, Android release was delayed...
But in the end it was released and it felt great to finally get it out there after working on it for so long!
Final Lessons Learned and Advice for Aspiring Game Developers
Everyone says this, but I'll say it again 'cause it's true: Start on a small project that's realistic to finish and build up to your bigger dream game you want to make. This was my 3rd serious attempt at making a game, but the first time I actually released one. Even still, I let my ambitions and scope go wild that made everything take way longer and could have easily led to abandoning it. There's so many things you can't possibly know when you're making your first game so starting small and going start to finish will give you the experience to use in the next project.
The games industry is a very competitive space and there's a high likelihood you won't even make minimum wage for the time you put into it on your first game. I certainly haven't yet. Try to find what your passion is for making games and what you want to accomplish. If you're just in it for the money, there are easier ways to make money for your time. I'd advise seeing how far you can get doing game development as a side project to make sure you love doing it and can stick with it before pursuing it as a full time job.
If you can find people to partner with to bring a game to life that would be awesome! I think it can be a bit of a double edged sword though. You'll have to find people that are really on the same page for what the game should be, with complimentary skills, and are realistic about committing to finishing the game given how long it'll take to make. If the collaboration doesn't work out it can easily kill the project.
When you're first thinking about what game you want to make, write all your cool game ideas first. I know you have at least a couple. Then pitch the idea to your friends and family and get their reactions. Do they get the idea? Are they confused? Does it sound like fun? This should help you both refine the idea and get a sense of what it'll be like when it comes time to promote the game. What's the hook, and what's the kicker? Remember that you could be working on this for quite awhile so really make sure this is the right idea that you're super excited about. It's a big commitment! When you're in the thick of development it's hard to push through all the non fun stuff like fixing bugs or just getting the sound to play correctly so you need the spark of the idea to keep you going!
Finally, don't stop dreaming and trying. I know it can all get a little overwhelming both in learning what it takes and actually doing it, but you learn so much along the way. The journey is more important than the destination
Liked this post?
Sign up and be the first to see new posts!
No spam, no nonsense, no guarantees, no rights reserved, probably.