Operations Overview #
Operations are a core part of the Player Data service. They allow the developer to author unique API endpoints for their player data features and define the Request and Response payloads. They also allow you to easily organize and maintain your endpoint business logic responsible for updating any type of defined player data. By defining the Operations yourself, you get to perfectly implement your designed player data features the way you want instead of fitting your design into a backend system that doesn’t align with your game.
Operations always belong to a Sub Service’s class, and typically a Sub Service class is organized based on the Operations within it. For example, a Sub Service that handles daily rewards would contain Operations solely for handling daily reward business logic, and a Sub Service for handling Hero or Champion unlocks would only contain Operations solely for unlocking new characters.
Operations are in charge of assigning live data (Entity
) to players. They can also utilize content data in their business logic when handling any type of player’s data. Every Operation always has access to all of a player’s data, and all changes made to a player’s data in an Operation are applied in one database transaction. The Operations you define are generated into the PragmaSDK and belong to their respective Sub Service in the SDK. This means that the way Operations are defined in a Sub Service directly impacts what Operations are available in the Pragma SDK and how you interact with said Operations.
Continue reading for more information about the important classes, functions, and objects associated with Operations.
Sub Service Class #
Sub Service classes are used to house and organize Operation functions. Every Sub Service class is constructed with a parameter for the PlayerDataContentLibrary
, allowing Operations to interact with and utilize content data. All of the Operations belonging to a Sub Service class are generated into the Sub Service’s SDK class.
Learn how to implement this class in the Define a Sub Service task.
Request and Response Classes #
Operations for a Player Data Sub Service are defined as PlayerDataRequest
and PlayerDataResponse
type classes and given business logic inside a Sub Service Operation function. Every Operation class inherits the PlayerDataRequest
and PlayerDataResponse
interfaces so they can interact with Pragma Engine appropriately. Additionally, the Request
and Response
Kotlin classes are used to generate the protobufs that’ll be used between the engine layer and the PragmaSDK.
Learn how to implement these classes in the Create the Request and Response classes task.
Operation Function #
An Operation’s business logic is written inside a Sub Service’s class using a specific Operation function. An Operation function must always have a property for request
and context
. The request
property provides an instance of the Operation’s user-defined Request
class (inheriting the PlayerDataRequest
structure), and context
gains access to other objects and functions for creating and modifying a player’s live data.
Note that an Operation’s functions name cannot overlap with any other Operation functions. The function must also always return the appropriate PlayerDataResponse
type associated with the Operation.
To implement an Operation function, go to the Author an Operation function task for more details.
Context #
context
is an interface that provides useful data, objects, and helper functions for writing business logic in an Operation’s function. Every Operation has context
as a parameter in its respective function which allows you to access context
’s interface.
See the Context reference section for more interface details.
Snapshot #
PlayerDataSnapshot
is a class that contains functions for retrieving, creating, modifying, and deleting Entities and their Components
. These functions edit a data class within PlayerDataSnapshot
called EntityData
, which manages all data changes and processes made to an Entity
. Anytime an Entity
is called from an Operation, even if no change is made, EntityData
runs through its mutableSetOf()
functions to update the database and cache.
If you plan on updating Entities without using the helper functions in Snapshot, you’ll need to update the raw EntityData
class by updating the mutableSetOf()
for the changedEntities
and entitiesToDelete
parameters. Even if no changes occur for an Entity, you still need to update changedEntities
.
Go to the Modify player data task for implementation details and the Snapshot reference section for more class details.
Unreal PragmaSDK #
All Request
and Response
classes, Sub Services, and Operations are generated in the Unreal PragmaSDK. The PragmaSDK has two classes that provide access to a Sub Service’s APIs and Operations:
The
UPragmaPlayerDataService
class provides access to game client Operations and will only contain a Sub Service’s APIs and Operations available on a player session.The
UPragmaPlayerDataPartnerService
class provides access to game server Operations and will only contain a Sub Service’s APIs and Operations available on a partner session.
The Request
and Response
Unreal structs match the Kotlin Request and Response classes, and Every Sub Service’s Operation has a corresponding Unreal method. The Operation method’s parameters always correspond with the Request
struct properties and include an additional parameter for a delegate
. The Operation’s delegate
has one parameter for TOptional
that contains the Response
struct’s properties. Note that if the TOptional
is not set then an error will occur and you’ll need to check logs for more details
Below is an example of accessing the UPragmaPlayerDataService
through a Pragma::FPlayerPtr
:
Player->PlayerDataService().<SUB-SERVICE-CLASS-NAME>SubService().<OPERATION-NAME>(
...
/* Parameters that correspond with the Operation's request properties */
...
/* Delegate contains one parameter for the Operation's response properties */
FOn<SUB-SERVICE-CLASS><OPERATION>Delegate TOptional<OPERATIONS-RESPONSE-STRUCT>
)
The UPragmaPlayerDataService
also comes with a cache for players’ entities. The cache layer helps optimize and limit the transfer of data between the client and Pragma Engine. Anytime the client calls an Operation, the client side cache will get updated. After the cache is updated, the Operation’s delegate
is called. We recommend you always fetch players’ entities through the UPragmaPlayerDataService.GetCache()
method, which returns a pointer to an FPlayerDataCache
instance.
See the Utilize an Operation in the PragmaSDK task and the Player Data Service SDK reference topic for more details.