The Evolution of Our LiveOps Dashboard: The In-House System Behind Every Live Event

In casual mobile games, live game operations have become incredibly important within the last decade. Prototyping, developing and launching a game is just the first step. The big task is keeping players engaged long-term, and this is where LiveOps come into play.

As a game developer, it became increasingly more evident and important to Tactile to have a unified place from which we can configure our games. And so, over time, we have developed an entire suite of tools that empower our teams to take full control of their games. We call it our LiveOps dashboard. It allows our teams to control exactly what players see and experience in a game.

On top of this, the dashboard enables us to stay true to our core values (such as validating all of our results with data) and to keep the promises we’ve made to our players (like 24/7 user support). The LiveOps dashboard can therefore be used for a variety of purposes – to schedule live events and tournaments, run A/B tests so that we can see what features are most impactful, to send engagement rewards and in general support users when they experience issues in a game, as well as to create curated player journeys for new or specific user groups.

We could have used a variety of 3rd party tools available on the market to do this, but having our own internal solution enables us to have all these different tools in one. Completely interconnected and managed by our Core tech team.

A sneak peak of our LiveOps Dahsboard

Taking a walk down memory lane

We tried to dig out the first line of code we ever committed to GitHub for the LiveOps dashboard project, but we were not even using Git back then yet 😂. And so, we asked our CTO, Morten, to fill in the gaps.

“The LiveOps Dashboard started out as a reporting dashboard, similar to how we use Looker today,” he starts, “It allowed us to see all of our revenue and data, mainly for our first big game called Skyline Skaters. We used it to track a variety of metrics such as ad revenue, impressions and clicks.”

At some point, the team wanted to be able to configure Skyline Skaters remotely. This was when they built a remote configuration tool within the reporting dashboard, which still exists in our current set-up. “Though it has evolved many times since then,” Morten adds. This initial version of the tool was a way for us to safely edit a JSON file that would get downloaded by a game, which allowed us to configure whatever we wanted in the game, completely remotely.

“The first version of the dashboard was built in pure JavaScript with AngularJS for the front-end, along with MongoDB and Redis, both of which we still use today,” he explains. As part of the remote configuration system, the team also built an ad mediation tool, which enabled us to control the waterfall of ad providers we worked with, as well as an additional support for remotely downloading asset bundles. This was a way for us to remotely distribute assets, such as allowing players to download a new city in Skyline Skaters to skate in.

Around that time, live operations in mobile games started growing drastically. Morten explains that they noticed some of our big competitors running events and features on a scheduled basis. “And so we introduced live events and scheduled features to the dashboard,” he says, “We basically built a tool that enabled us to remotely configure and schedule events within a game.”

From that followed the A/B testing feature, to ensure we’re making data driven decisions when releasing new features and… the rest is history.

From an old Angular project to automated game set-ups

This is where Tyler and Vera, our LiveOps Backend Engineers, come in.

Meet Tyler and Vera 👋

When Vera joined Tactile in 2020, the LiveOps dashboard was a, well … cluttered AngularJS project. By then, AngularJS was already quite old and it was painful to add new features and functionalities to the dashboard. On top of this, updating it to a newer version turned out to be really difficult.

“We were stuck,” Vera says, “Either way we had to re-build the entire front-end from scratch, either in Angular or in a brand new framework.” After some discussion within the team, they decided to switch to React, which would allow them to build a much more modern dashboard UI.

The challenge was that the developers on our Core team at the time were primarily backend experts, but they had to take care of the entire stack. This meant that all of our front-end was built by backenders, without a product designer, which caused some UX challenges. When we started transitioning the dashboard to React, we decided to do so step by step, page by page.

As the first step, we decided to do a little trick. We made a basic React page, but displayed our old AngularJS version within an iFrame. “This allowed us to be quick, instead of having to build an entire new version of the dashboard, which would have taken a long time before being able to release it to our users,” explains Vera. Building it page by page allowed them to show the new UI whenever it was ready, and then remove the old AngularJS in iFrame display.

At the same time, we also hired our very first Product Designer, who came up with a brand new dashboard design, and soon after also our first ‘proper’ frontend focused engineer, who worked on integrating it in React. Our Product Designer spent a solid amount of time with the teams who use our LiveOps dashboard to really understand what they do and come up with a design that serves their needs as best as possible.

During this transition process, the team discovered that the back-end, just like the front-end, was outdated and hard to manage. “This is why we started experimenting with Dependency Injection,” explains Vera, “Everything that we build new is built using dependency injection (DI) and the old code is being refactored along the way.”

Tyler, who joined the team in 2024, joined the dashboard project several years post migration. He shares his thoughts on the state of the current dashboard codebase: “We are an extremely opinionated team, but also very democratic and flexible. We adhere to guidelines, but are open to changing them when there is a strong argument for it and when it makes sense. When there is a pattern in the code, it’s easy to see what is happening, so I can really feel the impact of the transition to DI.”

Future plans

Post-migration to React, the dashboard kept growing and expanding with new features and tools to enable our teams to work even faster and more efficiently.

One of the most significant additions in the last few years was the Player Journeys tool – designed by our Solutions Architect in close collaboration with the LiveOps and Product teams, and built from the ground-up in-house. This tool allows us to segment players and give them completely tailored experiences based on what live actions they take within the game. As our games are picked up by a wide variety of players – from experienced match-3 players to those who have opened a mobile game app for the very first time – it’s important to recognize their unique playing styles and tailor their player journey based on that.

Another big system we’re currently working on will enable us to empower new game teams to set-up their own projects on the LiveOps dashboard. At the moment, we have a manually maintained list of games. However, as our new company strategy is to ship (ship ship) more games, we have started building faster and more often. This created a lot of additional work on the Core team’s side, having to set-up and calibrate all the new projects for individual game teams. “We want to hand over the building power to the teams,” says Tyler, “This will remove us from the equation and empower the teams to start new projects themselves and to choose the modules they need to start building live game operations.”

But… Why build it and not just buy it?

“There is no one single tool on the market that offers what our LiveOps Dashboard does,” explains Tyler. Building this huge tool happened very organically for us. It started small, but over time we started adding more features to it, as we found a need for them. Vera adds: “We have built this tool with the user perspective in mind, which has allowed us to both get and act on feedback from our users very quickly.” Another aspect is that building it ourselves has given us the flexibility to make it exactly as we want it to be. “We can do whatever we want with our dashboard. It’s already very dynamic and we are still implementing more things to it,” she says.

By saying we can do what we want, Vera means that we can optimize workflows for specific roles in the company. For example, our User Support page includes a lot of game-specific data. Instead of using an external tool to display this and forcing the user to switch between several platforms, our LiveOps dashboard automatically enables this connection for them. “This makes their workflow faster and less tedious,” explains Tyler.

The requirements for building new features come from different sources, but most often it’s from the teams themselves. Recently, we added a Scheduled Feature Importer tool because Morten (our CTO) found a pain-point when working directly with the LiveOps team. This was great because the users don’t always know how to make their workflows better or that there are ways to automate them.

Building it well and building it for the future

We have already talked about the team applying dependency injection to the codebase and switching from Angular to React. This idea, like most others, originated from their book club. All of our Core programmers regularly meet to read and discuss technical books. This stems from their culture of wanting to improve as developers, but also to make continuous improvements to the code base. None of the big changes happened as a ‘light bulb moment’ or an ‘order from above’. Instead, they spawned from the team democratically and developed through a gradual iteration process.

“It’s important to note that we do not look at the books we read as Bibles,” laughs Vera, “We use our common sense to take ideas from them that make sense for our team.” On top of the book club, they also meet weekly to discuss different ways to improve things. The main purpose of these meetings is to create a common mindset about coding best practices, as well as to ensure a common vocabulary within the team when talking about different software engineering patterns and strategies.

Their team meets weekly to discuss improvement

“One thing that has had a huge impact on upholding our coding practices have been code reviews (PRs),” says Vera. “And we have a culture of being very picky in them,” Tyler chimes in. The aim is not to bring someone down and mark their code as bad, but rather to leave small comments and/or suggestions for improvement, which do not necessarily need to be applied. It’s usually things like: “You could rename this…” or “Have you thought about doing it this way instead?” “We always want to make the best code possible,” he explains. Vera adds that we always try to make changes in iteration and therefore keep PRs small so that they’re easy to review and understand.

Unit testing, CI/CD and DDD

All of our code is covered in unit and integration tests. On top of this, we have a QA team within our Core team responsible for testing what the programmers produce.

We also have daily automated deployments and can deploy manually at any time. There are basically no barriers to what can be deployed, which is enabled by the PRs and our amazing QA team. This continuous cycle allows us to build and deploy quickly, but it also enables us to react quickly if something isn’t working as it should be. Tyler explains that if their daily release does not go out, then it becomes their immediate #1 priority – having longer release cycles is not an option for the team.

Vera & Tyler work closely with our QA Engineers

Whilst things on the surface of our LiveOps dashboard might appear ‘simple’, the logic underneath is actually very complex. This is mainly due to this tool being extremely domain-heavy. For the team this means keeping as much as possible focused within one single domain and building ubiquitous language in collaboration with other teams.

“During my onboarding, the most challenging part was navigating all the complexity and figuring out how everything ties together,” Tyler remembers. There are a lot of things happening within our games – there’s the user experience, engagement and monetisation aspects – and we want things to keep happening. The games need to run and we also need to be able to collect data at the same time. For Vera the challenge is managing it all on the LiveOps side and that’s what makes her work so meaningful.

Our news

DSC00738
Tactilers

Bridging creative vision and player experience as a…

More
DSC00460
Copenhagen

Stories of building a life in Denmark

More
DSC00651
Tactilers

Making complexity approachable – Building internal tools as…

More
DSC00362 (1)
Tactilers

Empowering teams to make an impact as a…

More
DSC09890
Life at Tactile

Tactile Bootcamp – We did it again!

More
DSC00075
Tactilers

Designing and delivering meaningful content to players as…

More
DSC09465
Product

Level-up your data skills with Game Analytics

More
PF_SouthAfrica
Copenhagen

Introducing our official Relocation Guide

More
DSC09390
Tactilers

Crafting fun experiences for players as an Animator

More
DSC09314
Tactilers

Blending UI and AI as a Game Artist

More