Marbles: The Beginning

25/04/2025

So, I've got my dream project. Well, I do know what it's going to be. And I also know how fast I'll make it. It won't take me more than two weeks. It's just a simple game, and there are plenty of tutorials. The plan is clear, I'm taking vacation from work, and in exactly 14 days, I'll be a proud solo developer with my own creation on Google Play. Nothing could possibly go wrong, right?

Yes, I really did take two weeks off work, and yes, I really believed I'd finish within that time. The game was supposed to be simple. The player's task was just to control a marble along a narrow track without falling off, aiming to get as far as possible. Plus, I decided I'd mainly focus on programming, while UI elements would be purchased from the Unity Asset Store. Music would also be solved by buying it or begging a friend. Easy-peasy!

Game design document? Pfft, why bother.

If you ever read anything about game project management, you'll probably come across the recommendation to create a so-called Game Design Document (GDD) right at the start. It's supposed to serve as the single source of truth. It describes all the key ideas defining your project. What your game will be, what it will look like, who your target audience is, which technologies you'll use, and maybe even when it will be finished. Just for fun, here's how the original Diablo's GDD looked back in 1994.

Well... I kinda skipped that part. Firstly, I figured a two-week project meant just to learn new stuff didn't really require it. I had no experience with it, and it felt like it would be a huge waste of time. Plus, I decided to record my project ideas differently. Using a mind map. It just suits me better, and honestly, it's more fun.

Speaking of mind maps, I tried several tools. Something bothered me about each one. I ended up with an application called Coggle, which felt pretty good. Lately, however, I've been thinking of trying something else, like FigJam, Miro, or something similar.

So, I had my main written down. In my head, I already imagined epic scenes of coding the game logic at night, assembling the UI, and popping champagne after 14 days. Essentially, I was done already. Just had to actually do it. So all that was left was opening Unity, creating a new project, and… hey, wait a minute!

To versioning or not to versioning? That's the question.

Everywhere you look, people say, "Don't overthink it at the start, just dive in." That's how startups work. That's how agile projects succeed. That's how you shape the world. Yet, there were two things I wanted to have covered right from the start.

The first was the Version Control System (VCS). And I wanted to have it set up right from the beginning so I could develop without fear of messing things up. Or losing work. I also wanted a complete history of all changes. And nowadays, I also consider this essential for any serious software project.

So the question wasn't if I'd use a version control system, but rather, which one. For me, it was always clear. Git. Yes, I know it's not the best choice for versioning binary files. Yes, I've read many articles recommending avoiding Git for game development. And yes, I know that Unity itself has its Unity Version Control (formerly PlasticSCM). Despite that, it was still the best choice for me.

It was best for me because I've known it for years and use it almost daily. I know exactly what to expect and how to solve potential problems. At this stage, my goal was to learn game development, not a new version control system.

For the same reasons, I chose GitLab as the repository storage. Again, I've known it for quite some time, and it always seemed more appealing to me than GitHub. I also use it daily at work and for other projects. At this stage, I had a clear idea of how I wanted to set up my workflow, and GitLab's Issues, Milestones, and basic Issue Board fit perfectly for planning also. As a bonus, I'd use its Snippets to share code snippets here on the website.

But since I'm not a masochist, I didn't want to handle Git from the command line. I started looking for a GUI client to make the task a bit more pleasant. I also didn't want to use Git integration in Visual Studio. It also felt tedious to open an IDE just for commit changes from, say, Blender. So, I searched for a small, preferably free app. Initially, I chose Gitahead, but some issues started bothering me, and its development eventually stopped. Over time, I found a replacement in GitHub's desktop client, which I still use happily today.

To test or not to test? ... umm?!

So, I had my version control system set. I created a new project in GitLab, cloned the repository locally, and installed a new Unity project in it. And hurray, into development! Now nothing could stop me!

Well, not exactly. There was still one more thing I decided to do before diving into code. Setting up a testing environment. Another thing that tutorials rarely mention. Unless you specifically search for testing tutorials. I know people often prefer postponing tests, but I thought it was better to handle this right away. Because if I didn't test, it would be like writing it in JavaScript. Just hoping it does what you intended.

Sure, I could have manually tested everything initially, probably enjoying each successful result. But from past experience, I've found it much more satisfying to watch automated tests run rather than repeatedly clicking through the same scenarios thousands of times.

For testing to really be useful, it needed to be automated somehow. So I wouldn't have to run the tests manually every time. Because one thing is to set up tests in Unity, but another is to ensure I don't forget about them. In reality, I've been running them manually since the beginning, and still do, before I send changes to Git. But automation is good insurance. Like a safety brake on a train.

GitLab CI/CD

Fortunately, this was something I didn't have to invent myself. Because someone else had already solved it. Like most things. I decided to use GameCI, a community project focused exactly on these things. GameCI provides settings for GitLab to automate testing and building games for various platforms.

Configuring and running it for the first time required some extra steps directly in GitLab. Probably to make it not too simple. After obtaining the Unity license (yes, even the free version has a license) and entering it into GitLab, everything worked beautifully and brought only joy. Plus, the whole process was very well documented.

However, after configuration, I made some minor adjustments. In .gitattributes, I ensured all graphical and multimedia files were stored in Git Large File Storage (LFS). Git is great for source code. For images, not so much. I also adjusted .gitignore to match my project structure and avoid unnecessary files, like Blender backup files.

Most importantly, I customized the GitLab CI pipelines settings significantly. I deleted all parts related to builds for various platforms. At this stage, I only needed automatic testing after every push to GitLab. Nothing more, nothing less. And so I left nothing else there, planning to expand it later. My .gitlab-ci.yaml looked like this:

Unity Test Framework

So GitLab was set up. But it had nothing to run. Yet! The next step was to set up tests directly in Unity. I activated the Test Framework package and got started.

The project was still in its default state, so I first cleaned out unnecessary files. I created a new scene and named it Tests. Then I structured the folders for testing. Inside Assets, I created a new folder Tests. Then two subfolders, but this time I created them using the Create -> Testing -> Tests Assembly folder option from the context menu. I named them EditMode and PlayMode.

These folders correspond to the two types of tests Unity Test Framework offers. Comparing them to the standard testing pyramid, I would place Edit Mode tests at the unit test level. Play Mode tests, on the other hand, I would align with integration tests.

By creating folders using the Tests Assembly folder context option, I achieved that so-called Assembly definitions were immediately created in the folders. This is a mighty fine thing. In the default state, all scripts in Unity project are in one big pile. Assembly definitions allow this pile to be divided into smaller parts, or if you will, smaller piles.

This then has its advantages, such as not all scripts have to be recompiled when you modify a single script. Only those in the same pile. With each update, it can then reduce the impact of changes. Of course, it also has its disadvantages, such as scripts in one pile don't know about scripts in other piles. But my future self will have to deal with that.

Done. At least, the initial setup.

With that, I was prepared! For the time being. The project was created. Essential things were configured. After sending changes to GitLab, it showed successful tests. Sure, there were no actual tests yet. But who cares? Everything worked exactly as planned. The rest will be a breeze. I felt like a champion, just like when I cleared the first floor of the dungeon beneath Tristram cathedral 28 years ago. Blissfully unaware of the Butcher lurking ahead.

So far it only took a moment, about 4 hours, and everything went according to plan. I still had 14 days of vacation ahead of me and believed with unshakable confidence that everything would go smoothly. So I merged the commit into the main branch and started developing. I created the first prototype of the player, started writing the first scripts, created the first game objects, prefabs, etc. But, about that I'll write some other time.

And how about you? How did you start your first project? Do you use game design documents or mind maps? Do you versioning and testing right from the start? Could you work without it? Which tools do you prefer? Feel free to share in the comments on my socials, I'd love to chat!