Pragma Engine Architecture Overview #

Logical Architecture #

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 #

Pragma nodes operate in two operating modes, “Social” or “Game”. The Social node runs Accounts, Friends, and Presence services. The Accounts service is responsible for cross-platform accounts, platform authentication, and signing Pragma session tokens for both Game and Social gateways. Multiple Game Titles can be registered with the Accounts service for multi-title studios and publishers.

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.

Gateways and Session #

Player, Operator, Partner, Service

Tech stack #

Pragma bucks common trends in our extreme commitment to preserving a simple architecture. We rely on boring, 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.