Fabamaq


This is a big one, so here is a summary of my main achievements at FABAMAQ:

All Tech used: C#, C++, Godot, CMake, SCons, OpenGL, RenderDoc, Linux, Git, GitLab CI/CD, JIRA

In more detail below:


Right after finishing college I started working on a 3D game engine to learn and build a portfolio piece, with the hopes of landing a job in game development.

After a few months of tinkering and failing, I felt like I was still nowhere near the point I wanted to be, but too much time had passed and I kinda needed to find a job.

I got a referral from a friend who heard I was looking for a C++ job and got an interview at FABAMAQ. I received a simple C++ take home and from there had some more interviews which were successful, and eventually joined them!

FABAMAQ is a casino game company, their focus is mainly land-based games (think those machines on casino floors with slot games etc), but they also have a newer online division. We mainly used our own in-house engine, both for land-based and online.

I joined a team that was separate from these, Research & Development. Our job was to research new ways we could develop our games as well as new mechanics which we would prototype and test to see if they had any viability.

As I joined, the team was close to shipping 3 games that were part of the same set. These games had been made in Godot, an open-source game engine that had never been used at the company, quite the different approach from the proprietary tech approach they had used in the past.

I started out by just reading the codebases my colleagues had written in Godot and learning the engine, soon starting to build my own prototype for a new game with a new mechanic.

It was a really cool, challenging and very iterative process. Loved working so close to people in other disciplines such as artists and musicians.

It really pushed my understanding of what it takes to finish those last 20% of a project.

I had started in January and by March, in my mind the game was done.

But it was nowhere near the professional standard that would be expected from an actual game you’d play. The next 2-3 months were then spent on polishing and making the experience as best as possible.

Lots of iteration, reviews, etc.

Around the stage where I was finishing that game, my colleagues were getting ready to start the process of shipping their 3 games.

However, there was an issue, in that their performance was lackluster on mobile platforms. The games ran on the browser through WASM which Godot can compile to.

On a PC or laptop they played fine, even a modern Iphone could handle them well, but anything below that would suffer from choppy framerates, and the battery would drain fast.

The games averaged between 200-400 draw calls, honestly an outrageous amount for a visually simple 2D game.

During all this time, I had kept working on my game engine whenever I could. Before and after going to work and on the weekends. It was really an integral part of my continuous learning experience, in the hopes of a day joining a AAA.

I saw an opportunity to help and share some of the knowledge I had picked in order to optimize the games as much as possible so they could be in a playble state and be shipped.

By this point I still had little experience with Godot, and was not too sure how the scene tree and its nodes would translate to draw calls and rendering time. What actions were the most costly etc.

I started out by introducing RenderDoc to the team, and analyzing the game at its key moments, trying to identify the problems. I also explained the anatomy of a draw call, the stateful nature of OpenGL, and other rendering principles.

There were essentially 3 problems with the games: No use of texture atlases, poor scene tree structure, and fonts.

Every single texture in the game was its own file, leading to every sprite to require a SetTexture, adding another drawcall to the bunch.

The scene tree was also poorly optimized, but to be honest, Godot was not as benevolent as say, Unity, with this. I felt like with Unity I could get away with more by not paying to much atention to my hierarchy where as with Godot, specifically the 3.5 version, it mattered way more.

Lastly there were the fonts. They had lots of overdraw some special effects.

Eventually, after some experimentation and trial and error, the games were optimized to a comfortable 10-40 draw calls, the higher number being on key moments of the game with lots of animations. There was still some performance to be squeezed, but the games were in a good state where they could be shipped.

We would take these lessons onto the future games of the team, where they would rarely go above 10 draw calls and have great performance at all times.

Later on I would also introduce these concepts to the online team so their games could be as optimized as possible.

At this time the game I was working on also came to its conclusion and was passed to another team.

For a few weeks I helped out with other project such as a VR one, but then came time for a new project.

Before I had come along, the team was experimenting with building a new engine to have another alternative to the already existing one. The plan was to use Godot and write some c++ modules to extend its behaviour for our own land-based games.

We were tasked with taking a critical look at that code, and think of possibilities of what this new tool could look like, in terms of technology workflow, etc. It was going to be using Godot in some manner.

One of the requirements was communication with C++ libraries, because the games depended on those to communicate with the machine on the casino floor.

At this time we also experimented with compiling our own versions of Godot, where I learned yet a new build system, SCons.

We toyed around some more with the C++, wrote some CMake and some modules to interact with our shared libraries, but the whole process was a bit cumbersome and would not offer much over what we already had on the land-based department.

We were taking this route because GDScript, Godot’s scripting language which was what we had used so far, had no way to interact with external C++ libs.

But then we took notice that Godot also supported C# through Mono, and C# does have mechanisms to interact with C++. After some days of tinkering, we managed to connect to these libs somewhat gracefully and write something that was working, and felt good to work with.

We decided to fully embrace that C# route and kept on building.

My colleagues eventually moved to other projects and I kept working on TurboDot alone.

The project started out as an experiment but its goal became more clear the coming weeks. Verify if Godot could handle our needs for a land-based game, and if so, build a framework that would allow us to do so, in a better fashion.

Faster (both in runtime performance and dev speed), more ambitious, etc.

The project was progressing at a satisfying pace and eventually the team made 2 more hires, who would help me out on the project.

I was responsible for integrating them into the team and the project.

I was a bit out of my depth here but I think I handled it well and they where quickly contributing to the project!

Months passed and we kept at it, developing the framework and a game on top of it, so we would keep pushing with the requirements. At this point we were presenting our results to other teams every other month. This was important as ideally this framework would try and bridge some of the gap between programmers and creative teams, and their feedback was vital.

By the time I left it was pretty self suficient and could produce a game that would be “production ready” and offered significant improvements over what came before.

The frameworks features could be summed as:

Tackling such a big project and owning a massive codebase was pretty intimidating at first and definitely a huge challenge. I am immensely grateful for the opportunity to have such a responsability. It felt rewarding and vindicating in the end. Picked up a lot of new skills along the way.

Grateful for my time at FABAMAQ and my colleagues who pushed me to be better!