For roughly eighteen months, I led the complete rebuild of a tool connected to Star Citizen servers. Game developers used it locally, while Game Masters and support teams used it in production. It had to bring many data sources together and remain straightforward to extend.
A tool connected to the game
Live Tools was an internal tool connected directly to the game servers. Star Citizen developers used it locally to confirm that expected events and data appeared correctly. In production, Game Masters and support teams used it to understand a situation and act on player data.
The interface followed the selected context. A player identifier shown in a table could open a new window with the profile, related data, and available actions. Several windows and panes could stay visible while navigating between a player, group, lobby, or another entity.
Rethinking both foundations and usage
The rebuild had to replace the existing application with a foundation that was easier to understand and extend. The game backend exposed many gRPC services and streams, while each frontend screen needed a coherent view of the data relevant to its context.
Adding a data source or component also had to avoid another bespoke integration. The new version needed to absorb that variety into one system while remaining useful for local debugging and production operations.
My lead scope
I was the lead developer and managed two frontend developers. I handled code reviews, set the technical direction, and took part in product prioritization and interface design decisions.
I owned the architecture of the rebuild: a monorepo, micro-frontends with Module Federation, a GraphQL BFF, UI and Data packages, Apollo hook generation, and the declarative module system. It was a new version, then its rollout was secured progressively through QA and local deployments used by game developers.
An architecture driven by context
Aggregate gRPC behind a GraphQL BFF
The game backend remained organized around gRPC services. I implemented a GraphQL gateway that aggregated their streams and gave the frontend a contract suited to its screens. The Data package centralized Apollo, types, and automatic hook generation.
Declare a module instead of rewiring an interface
The module system linked a data source, context, and component through a declarative layer. A team could add a new datasource and its interface without reproducing all the plumbing needed to connect them.
Make context part of navigation
Windows and panes shared the selected context. Clicking data such as player_id opened the views and actions available for that player. Relationships between data could therefore be explored directly from the tool.
One delivery for real operating conditions
Developers could verify expected events and data locally. In production, Game Masters and support teams could open views linked to a player in the same tool to handle a situation.
Adding a source or module went through a declaration connecting a context, a data stream, and a component instead of another bespoke integration.
What the next team inherited
The most durable part of the work was turning very different needs into explicit extension rules. The next team could add a source or an action without rebuilding the screen.
