Account Plugin #

The Account Plugin can be used to add custom behavior during the account lifecycle. The following are methods to manage account data:

MethodDescription
onAccountCreateCalled before an account has been created.
onAccountCreatedCalled after account creation.
onAccountLoginCalled after an account has signed in.
onAccountUpdateCalled when account information has changed.
onAccountDeleteCalled before an account is deleted.
onAccountDeletedCalled after account deletion.

Flow Overview #

In this section we’ll demonstrate the Account Plugin’s flow by going through an example use case. Consider a scenario where a player creates an account for an early development game.

onAccountCreate: Creates an account following specified requirements.

Example: Player A creates an account

Player A does not meet name requirements (minimum character length) and account creation is prevented by throwing an exception. Once the requirements are met, an account is successfully created.

override suspend fun onAccountCreate(
    idProviderAccount: IdProviderAccount
  ): PragmaAccount {
        if (idProviderAccount.displayName.length < 3) {
              throw PragmaException(
                  PragmaError.AccountService_Unauthorized,
                  "The display name is too short."
              )
        }
        if (idProviderAccount.displayName.length > 32) {
              throw PragmaException(
                  PragmaError.AccountService_Unauthorized,
                  "The display name is too long."
              )
        }
    return PragmaAccount(idProviderAccount.displayName)
}

onAccountCreated: Triggers after an account has been successfully created.

Example: Player A is automatically added to the playtest

Player A creates an account and is automatically added to the beta access group so that they are allowed into the game during the testing time window.

override suspend fun onAccountCreated(pragmaAccount: PragmaAccount) {
    val betaAccessGroupId = UUID.fromString("6a7f81ec-42d2-4874-9a8e-092dd79c2627")
    pragmaAccount.addGroup(betaAccessGroupId)
}

onAccountLogin: Allows or prevents players to log in based on restrictions.

Example: Player A logs in

Player A successfully logs into the game.

Player B who has a tag on their account for suspicious activity is denied login by throwing an exception.

override suspend fun onAccountLogin(pragmaAccount: PragmaAccount) {
    if (pragmaAccount.getTags().any { it.tag == "suspicious-activity" }) {
        throw PragmaException(
            PragmaError.AccountService_Unauthorized,
            "This account is flagged for suspicious activity."
        )
    }
}

onAccountUpdate: Makes updates to player account information following specified requirements.

Example: Player A updates their account name

Player A requests for a name change. Their new name meets requirements and their account information is updated to reflect the name change.

Player B requests for a name change. Their new name exceeds the 32 character limit so their name is truncated.

override suspend fun onAccountUpdate(pragmaAccount: PragmaAccount) {
    if (pragmaAccount.getDisplayName().length > 32) {
        pragmaAccount.setDisplayName(pragmaAccount.getDisplayName().substring(0, 32))
    }
}

onAccountDelete: Pragma Engine removes all standard player information. You’ll need to remove any additional stored custom player data.

Example: Player A requests for account deletion

Player A requests for their account to be deleted. This method can be used to define the logic to remove Player A from the game’s custom leaderboard, any groups or guilds they were in, and all accompanying PII.

override suspend fun onAccountDelete(pragmaAccount: PragmaAccount) {
    val leaderboardGameShardId = UUID.fromString(
        "9c9efd2e-a7bd-4374-85b2-4a37d48db7b8"
    )
    val socialIdentity = pragmaAccount.getSocialIdentity() ?: return
    val playerGameIdentity = socialIdentity
        .gameIdentities
        .firstOrNull { it.gameShardId == leaderboardGameShardId }
        ?: return
    val result = service.requestRpc(
        LeaderboardRpc.DeletePlayerDataServiceV1Request.newBuilder()
            .setPlayerId(playerGameIdentity.pragmaPlayerId.toFixed128())
            .build(),
        LeaderboardRpc.DeletePlayerDataServiceV1Response::class)
    // ...
}

onAccountDeleted: Triggers after an account has been successfully deleted.

Example: Transfer guild ownership
Player A who was a guild leader has deleted their account. This method can be used to define logic to transfer custom guild ownership rights to another player.

Create an account #

The onAccountCreate function is called after account authentication, but before creation of a Pragma Social account. When onAccountCreate returns a PragmaAccount object, an account is created. Account creation can be prevented by throwing an exception.

The IdProviderAccount data class is unique account information from an identity provider:

PropertyTypeDescription
idProviderAccountRPC.IdProviderThe type of the identity provider (Steam, Epic, unsafe). See Identity Providers for more information.
accountIdStringUser ID from the identity provider.
displayNameStringThe player’s registered account name from the identity provider.
discriminatorStringUnique digits added to the end of usernames to identify the player’s account.

Pragma Account Object #

The PragmaAccount is a mutable object that represents the current state of the player’s account information. Any changes made on the PragmaAccount object are saved.

All get requests are lazy loaded.
MethodDescription
getSocialIdentityRetrieve all account information. This includes data on account ID, display name, list of game identities, and identity providers.
getDisplayNameRetrieve the player’s registered account name.
getTagsRetrieve all player tags associated with the player’s account.
getGroupsRetrieve all player groups associated with the player’s account.
setDisplayNameSet a new display name for the player’s Pragma account.
addTagAdd a tag to the player’s account.
addGroupAdds a player to a group by the group’s unique ID.
removeTagRemove a tag from the player’s account by the tag’s unique ID.
removeGroupRemove a player from a group by the group’s unique ID.

Implement the Account Plugin #

To build your custom Account Plugin, you’ll need to implement the AccountPlugin interface:

class DemoAccountPlugin(
  val service: Service, 
  val contentDataNodeService: ContentDataNodeService
) : AccountPlugin {}

Configure the Account Plugin #

To enable your custom Account Plugin, you’ll need to add this config in your yaml:

social:
  pluginConfigs:
    AccountService.accountPlugin:
      class: "demo.account.DemoAccountPlugin"