Pragma Engine Architecture Overview #

Overview #

Pragma is a web server that exposes multiple gateways for different session types, each assigned to a distinct port. Gateways authenticate users, establish sessions, and routes traffic bi-directionally to and from Pragma services. Services can be horizontally scaled across multiple Pragma nodes independently. Each service may optionally utilize a persistence layer that can also be horizontally scaled independently from the service layer. Service-to-service traffic is managed by a specialized gateway that handles this case directly.

Gateways #

Gateways accept websocket and http traffic, and accept messages encoded via protobuf or json. Pragma utilizes an RPC style approach and provides request/response semantics as well as uni-directional notifications sent via webosocket connections.

Services #

A Pragma node is configured to run one or more services (such as Matchmaking or Accounts), with the gateways routing traffic to and from various services. For production, a multi-node deployment is configured to operate in a typical microservice topology. For local development and internal test environments, a single-node configuration can run all services at once, making dev iteration fast and keeping costs down for internal environments.

Social and Game Shards #

Shards represent a cluster of Pragma nodes that support a specific environment, such as internal playtest environments, staging, loadtest, or a fully scaled production environment. Studios relying on Pragma’s managed services can request an unlimited number of shards for their internal and production use cases.

Pragma nodes run a selection of services. There are two operating modes for a Pragma node, “Social” or “Game”. The Social node is responsible for accounts and social capabilities, while a Game node hosts services responsible for game specific features and workflows.

Social nodes are responsible for managing cross-platform accounts, platform authentication, and signing Pragma session tokens for both Game and Social nodes. Multiple Game Titles can be registered within the Accounts service to support multi-title studios and publishers.

Game nodes run services that focus on game-specific features such as matchmaking, multiplayer flows, game server coordination, inventory, unlocks, meta and progression systems, and related. These services are tailored to the needs of a specific game title.

Authentication #

Game Clients utilize platform SDKs (Steam, Epic, Playstation, Xbox, etc.) to obtain the appropriate game platform token. This platform token is passed to the login step of the Pragma SDK, which performs appropriate server side validation and exchange for a Pragma session token. The Pragma token is then presented to the relevant Pragma Gateway and a session is established. All RPCs are sent to the backend via the Pragma SDK and routed to the appropriate service via the Gateway. A separate connection is maintained for the Social and Game shards, enabling platform indpendent Friends and Presence support in addition to other social features. Game specific features are supported by the Game shard, such as Parties, Matchmaking, Meta-game systems etc.

Custom services and features #

Custom services are authored the same way as all other Pragma services. After registering a new Service or RPC, Pragma’s CLI will regenerate the Pragma SDK and update it in your game codebase. This enables studios to create tailored backend features with exactly the API needed for the game, all within the same unified toolchain that is used for utilizing ready-made Pragma services and features.

Studios utilizing Pragma’s Managed Services will have have access to new backend binaries with their customizations that can then be deployed to various internal test environments and later promoted to staging and prod.

Tech stack #

Pragma bucks common trends in our extreme commitment to preserving a simple architecture. We rely on reliable, proven tech and keep our operational footprint extremely small.

Pragma requires only the JVM and MySQL to run. There are no other dependencies such as key-value stores, distributed caches, message queues, etc.

Pragma services are packaged into a single executable. The entire stack can be run with a single button press, enabling simple local dev environments and low-cost internal test environments. Production environments are configured in a traditional microservice architecture with services running on dedicated nodes, but this complexity is reserved for when it is needed.

We have no additional layers of nested or embedded runtimes. The ‘scripting’ language of Pragma is Kotlin, the same language as the platform itself.

Why Kotlin? #

While Kotlin is not the most commonly used language, we use it because it relies on the same core JVM libraries that power some of the world’s largest games (for example Fortnite and League of Legends). Our team has extensive experience with the stack based on our experience working on these massive game titles. Kotlin provides a more pleasant syntax that is immediately familiar to anyone with experience in c++, c#, or java, therefore we decided it was worth adopting compared to vanilla Java.

Why MySQL? #

Similar to our choice of the JVM, we use MySQL because it powers some of the largest games in the world and we have extensive experience with it. We have many Postgres fans in the studio, but we make decisions based on practical considerations that minimize risk– in this case industry validation and in-house experience.