Update a Player’s Display Name #

The Account Plugin can be used to add custom behavior during the account lifecycle. This includes handling any updates to a player’s account information based on updates from a third party provider such as Steam.

This guide provides a walkthrough of the steps required to update a player’s Pragma Account display name using the Account Plugin. We’ll go through two scenarios when you might want to enable Pragma Account display name updates. Choose which option works best for your needs:

Core Concepts:
Check out our concept doc for an intro to the Account Plugin. For more information on the default behavior of Pragma Account display names, see Display Name.

Prerequisites:

  • Pragma Engine, Postman, and IntelliJ must be installed.

Updating Display Name with Steam #

In this section, we’ll create a custom Account Plugin that updates a player’s Pragma Account display name when a player updates their display name on Steam.

Prerequisites: You’ll need to have authenticated with Steam. See tutorials Unreal: Authenticate with Steam or Unity: Authenticate with Steam for details.


Get started #

Run the following command in the terminal from the platform directory to build the engine: ./pragma build all --skipTests

1. Create a custom Account Plugin #

Goal

Create a custom Account Plugin with logic to update a player’s Pragma Account display name when they update their name on Steam.

Steps

  1. Create a new directory at pragma-engine/platform/PROJECT/PROJECT-lib/src/main/kotlin/accounttutorial.
  2. Create a new Kotlin file in that directory called AccountTutorialSteamAccountPlugin.kt.
  3. Copy the following code into the AccountTutorialSteamAccountPlugin.kt file. This defines a class that implements the Account Plugin interface:
package accounttutorial

import pragma.PragmaError
import pragma.PragmaException
import pragma.account.AccountPlugin
import pragma.account.AccountRpc
import pragma.account.PragmaAccount
import pragma.auth.IdProviderAccount
import pragma.content.ContentDataNodeService
import pragma.services.Service

@Suppress("unused")
class AccountTutorialSteamAccountPlugin(
    val service: Service,
    val contentDataNodeService: ContentDataNodeService,
) : AccountPlugin {

    override suspend fun onAccountCreate(idProviderAccount: IdProviderAccount): PragmaAccount {
        return PragmaAccount(idProviderAccount.displayName)
    }

    override suspend fun onAccountCreated(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountLogin(pragmaAccount: PragmaAccount) {
        val steamIdProvider =
            pragmaAccount.getSocialIdentity()?.providerAccounts?.find {
                it.idProvider ==  AccountRpc.IdProvider.STEAM_VALUE
            }
        if (steamIdProvider != null && steamIdProvider.displayName !=
            pragmaAccount.getDisplayName()) {
            pragmaAccount.setDisplayName(steamIdProvider.displayName)
        }
    }

    override suspend fun onAccountUpdate(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountDelete(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountDeleted(pragmaAccount: PragmaAccount) { }

    override suspend fun updateDisplayName(requestedDisplayName: String, pragmaAccount: PragmaAccount) {
        /**
         * We are disabling the ability for players to manually update their display name
         */
        throw PragmaException(
            PragmaError.AccountService_DisplayNameUpdateNotAllowed,
            "Display name updating is not allowed"
        )
    }
}
Method overview

The onAccountCreate method defines the logic that executes when a player’s account is first created. It always needs to return a Pragma Account representing the player’s new account that will be created. This is how you define the player’s initial account parameters like their display name. If you want to customize how the player’s account is created you can do that in this method.

The onAccountLogin method defines the logic that executes when a player logs in. This is where we will insert the logic needed to update a Pragma Account display name when a player has updated their name on Steam. The next time the player logs into the Player Social backend, Pragma checks for any Steam display name changes. If the Steam display name is different from the player’s current display name, the Pragma Account display name will be updated with their new Steam name accordingly. The Pragma Account display name is only updated with the Steam display name when the player logs into the Social Player Portal or your game client with their Steam account using the Steam identity provider.

The following onAccountCreated, onAccountUpdate, updateDisplayName, onAccountDelete, and onAccountDeleted methods are other account events that you could add additional logic to but for the purpose of our implementation they can be left empty. These methods need to be included to adhere to the Account Plugin interface even if they are not being used.

After saving the new file, run the following command in the terminal from the platform directory to build the platform: ./pragma build --skipTests

2. Configure the plugin #

Goal

Register your custom Account Plugin in Pragma Engine.

Steps

Plugins must be configured in YAML configuration files before they can be utilized by Pragma Engine. We’ll configure the plugin to run in your local Pragma Engine.

  1. Open [project]/config/local-dev.yml.
  2. Register the AccountTutorialSteamAccountPlugin by ensuring the social section of the config file matches the following:
social:
  pluginConfigs:
    AccountService.accountPlugin:
      class: "ext.accounttutorial.AccountTutorialSteamAccountPlugin"

Test the plugin #

In this section we’ll test if your Account Plugin updates your Pragma Account display name when you change your name on Steam.

Start Pragma Engine #

Run Pragma Engine via one of the following methods.

Running via Command Line
From your pragma-engine/platform working directory, run ./pragma run to start the platform.
Running in IntelliJ
Run Pragma from the IDE by selecting the ‘Run Pragma’ run configuration from the dropdown in the upper right.

Once the engine has started successfully, it prints the message INFO main - Pragma server startup complete.

Update your display name #

You’ll need to have completed either the Unreal: Authenticate with Steam or Unity: Authenticate with Steam tutorial.

The following are two options for testing:

Option 1: Testing with Steam
  1. Log in with Steam.
  2. Change your Steam display name.
  3. Log into your game client with Steam.
    • Your Pragma Account display name should be updated to your new Steam display name.
Option 2: Testing with the Social Operator Portal
  1. Log in with Steam as a player in your game client.
  2. Go to the Social Operator Portal and login as the Operator account test01.
  3. Search for the account you used to log into Steam.
  4. Change your display name by clicking Edit Account.
  5. Log in to the game client with Steam again.
  6. Confirm your Pragma Account display name has changed back to match the Steam display name.

Updating Display Name with Social Player Portal #

In this section, we’ll create a custom Account Plugin that updates a player’s Pragma Account display name when a player updates their display name in the Social Player Portal. We’ll also go through how to add time throttling to limit how often a player can update their display name.

Prerequisites: You’ll need to have authenticated with Steam. See tutorials Unreal: Authenticate with Steam or Unity: Authenticate with Steam for details.


Get started #

Run the following command in the terminal from the platform directory to build the engine: ./pragma build all --skipTests

1. Create a custom Account Plugin #

Goal

Create a custom Account Plugin with logic to update a player’s Pragma Account display name when they update their name in the Social Player Portal.

Steps

  1. Create a new directory at [project]/ext/src/main/kotlin/ext/accounttutorial.
  2. Create a new Kotlin file in that directory called AccountTutorialManualUpdateAccountPlugin.kt.
  3. Copy the following code into the AccountTutorialManualUpdateAccountPlugin.kt file. This defines a class that implements the Account Plugin interface:
package ext.accounttutorial

import pragma.PragmaError
import pragma.PragmaException
import pragma.account.AccountPlugin
import pragma.account.PragmaAccount
import pragma.account.TimeSpanner
import pragma.auth.IdProviderAccount
import pragma.config.ConfigBackendModeFactory
import pragma.config.PluginConfig
import pragma.content.ContentDataNodeService
import pragma.plugins.ConfigurablePlugin
import pragma.services.Service
import pragma.settings.BackendType

@Suppress("unused")
class AccountTutorialManualUpdateAccountPlugin(
    override val service: Service,
    override val contentDataNodeService: ContentDataNodeService,
) : ConfigurablePlugin<AccountTutorialManualUpdateAccountPlugin.Config>, AccountPlugin {
    class Config private constructor(type: BackendType) : PluginConfig<Config>(type) {
        override val description = "Account plugin configuration."

        var waitingPeriodInDays by types.long("The number of days between name changes.")

        companion object : ConfigBackendModeFactory<Config> {
            override fun getFor(type: BackendType): Config {
                return Config(type).apply {
                    waitingPeriodInDays = 30L
                }
            }
        }
    }

    private lateinit var config: Config
    private val timeSpanner: TimeSpanner = TimeSpanner()

    override suspend fun onAccountCreate(idProviderAccount: IdProviderAccount): PragmaAccount {
        return PragmaAccount(idProviderAccount.displayName)
    }

    override suspend fun onAccountCreated(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountLogin(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountUpdate(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountDelete(pragmaAccount: PragmaAccount) { }

    override suspend fun onAccountDeleted(pragmaAccount: PragmaAccount) { }

    override suspend fun updateDisplayName(requestedDisplayName: String, pragmaAccount: PragmaAccount) {
        if (!timeSpanner.enoughTimeHasElapsedSince(pragmaAccount.getDisplayNameLastUpdated())) {
            throw PragmaException(
                PragmaError.AccountService_BadRequest,
                "Players are only allowed to update display name every ${config.waitingPeriodInDays} days"
            )
        }
        pragmaAccount.setDisplayName(requestedDisplayName)
    }

    override suspend fun onConfigChanged(config: Config) {
        this.config = config
        timeSpanner.setWaitingPeriodDays(this.config.waitingPeriodInDays)
    }
}
Method overview

We will make this plugin a ConfigurablePlugin which means we can update its behavior by YML config without making a code change. To do this we created a Config class to add the new config setting waitingPeriodInDays.This is so you can easily configure the throttle time for display name updates.

The onAccountCreate method defines the logic that executes when a player’s account is first created. It always needs to return a Pragma Account representing the player’s new account that will be created. This is how you define the player’s initial account parameters like their display name. If you want to customize how the player’s account is created you can do that in this method.

The onAccountLogin method defines the logic that executes when a player logs in.

The updateDisplayName method defines the logic that executes every time a player attempts to update their own display name manually. In this implementation, we first check the timestamp for the last time the display name was updated. There are two possible scenarios dependent on if enough time has elapsed since the update:

  • If enough time has elapsed, the player’s Pragma Account display name will update.
  • If not enough time has elapsed, an exception is thrown and the display name will not be updated.

The onConfigChanged method will apply your updates to the throttle time without needing to redeploy your Pragma Engine. See Dynamic configuration for more information.

The following onAccountCreated, onAccountUpdate, updateDisplayName, onAccountDelete, and onAccountDeleted methods are other account events that you could add additional logic to but for the purpose of our implementation they can be left empty. These methods need to be included to adhere to the Account Plugin interface even if they are not being used.

After saving the new file, run the following command in the terminal from the platform directory to build the platform: ./pragma build --skipTests

2. Configure the plugin #

Goal

Register your custom Account Plugin in Pragma Engine.

Steps

Plugins must be configured in YAML configuration files before they can be utilized by Pragma Engine. Here we will configure the plugin to run in your local Pragma Engine

  1. Open [project]/config/local-dev.yml.
  2. Register the AccountTutorialManualUpdateAccountPlugin by ensuring the social section of the config file matches the following:
social:
  pluginConfigs:
    AccountService.accountPlugin:
      class: "ext.accounttutorial.AccountTutorialManualUpdateAccountPlugin"

Optional config #

The Account Plugin contains an optional config waitingPeriodInDays that defaults to 30 days. This value can be overridden by setting the value in the config:

social:
  pluginConfigs:
    AccountService.accountPlugin:
      class: "ext.accounttutorial.AccountTutorialManualUpdateAccountPlugin"
      config:
        waitingPeriodInDays: 10

3. Enable the Social Player Portal overlay #

Goal

Enable the overlay so that players can update their Pragma Account display name in the Social Player Portal.

Steps

Enable the Social Player Portal overlay to allow users to update their display name.

  1. Open [project]/portal/src/config/default.js.
  2. Under player-social add accountTutorialPlayerExtension.
module.exports = {
  builds: {
    'player-social': {
      common: { 'app.extensions': ['accountTutorialPlayerExtension.js'] }
    },
  }
}
  1. In [project]/portal/src/extensions/ create a new file called accountTutorialPlayerExtension.js.
  2. Add the following code:
const { DisplayNameEdit } = pragma.ext.player.ui.components

export default {
  swappableComponents: {
    "Player.Account.Settings.DisplayName": DisplayNameEdit
  },
};

4. Package Social Player Portal #

Goal

Update the Social Player Portal for players to see the update display name input box.

Steps

To package the Social Player Portal run the following command: ./pragma portal package

Test the plugin #

In this section we’ll test if your Pragma Account display name updates when updated from the Social Player Portal.

Start Pragma Engine #

Run Pragma Engine via one of the following methods.

Running via Command Line
From your pragma-engine/platform working directory, run ./pragma run to start the platform.
Running in IntelliJ
Run Pragma from the IDE by selecting the ‘Run Pragma’ run configuration from the dropdown in the upper right.

Once the engine has started successfully, it prints the message INFO main - Pragma server startup complete.

Update your display name #

The following are two options for testing:

Option 1: Testing in Social Player Portal
  1. Go to: http://localhost:11000/.
  2. Select Sign in with Pragma Unsafe. Log into the Social Player Portal as test01.
  3. Click on the Settings tab.
  4. Update your display name.
    • This will update your display name instantly. If you attempt to update your display name immediately again it’ll fail, because there is a default of 30 days before you can update.
Option 2: Testing with Postman

Simulate a player updating their display name in Social Player Portal.

  1. Send the Pragma Dev > Scenario Logins > login with test01 request.
  2. Update the display name by using the call PragmaDev > Social > RPC - Player > Account > UpdateDisplayNameV1.
  3. Confirm the display name has been updated by using the call PragmaDev > Social > RPC - Player > Account > GetAccountV1.
  4. Send the PragmaDev > Social > RPC - Player > Account > UpdateDisplayNameV1 request.
    • This request should fail because not enough time has elapsed since the last update.