April 13, 2023

Features #

[Game Flow] Active Matches are now live! #

Description: Game servers that are running a match can now request for more players to be matched and added to the game.

The Active Match feature requires the use of WebSockets as the game server protocol.

Details: Check out the Matchmaking page for more information about Active Matches.

[Game Flow] New GetPlayerIdentities and GetSocialIdentities endpoints now available. #

Developers can now retrieve a list of player identities or social identities for a provided list of player IDs or social IDs using the corresponding Partner, Operator, or Service endpoint.

Note that the social identities returned will include information like identity provider account, which may be restricted by a platform, so we recommend using caution when exposing this data.

Details:

Player:

void GetPlayerIdentities(const TArray<FString> PlayerIds, const FGetPlayerIdentitiesDelegate& OnComplete);
TFuture<TPragmaResult<PlayerIdentitiesResponse>> GetPlayerIdentities(const TArray<FString> PlayerIds);

Social:

void GetSocialIdentities(const TArray<FString> SocialIds, const FGetSocialIdentitiesDelegate& OnComplete);
TFuture<TPragmaResult<SocialIdentitiesResponse>> GetSocialIdentities(const TArray<FString> SocialIds);

Player:

public Future<PlayerIdentitiesResponse> GetPlayerIdentities(IEnumerable<PragmaId> playerIds)

Social:

public Future<SocialIdentitiesResponse> GetSocialIdentities(IEnumerable<PragmaId> socialIds)
  • Service:
    • Player: AccountRpc.GetPlayerIdentitiesServiceV1Request
    • Social: AccountRpc.GetSocialIdentitiesServiceV1Request
  • Operator:
    • Player: AccountRpc.GetPlayerIdentitiesOperatorV1Request
    • Social: AccountRpc.GetSocialIdentitiesOperatorV1Request
  • Partner:
    • Player: AccountRpc.GetPlayerIdentitiesPartnerV1Request
    • Social: AccountRpc.GetSocialIdentitiesPartnerV1Request

Related note: See docs note.

[Game Flow] New OnMatchProcessed event triggered when a player’s match end data has been processed. #

Description: The Party service now has an OnMatchProcessed event, which is triggered when a match end is processed for a player. This event already existed in the GameDataServiceRaw file, but is now also available on the Party service and is the recommended way to listen for this event.

Details:

// Fired when a match result is processed.
FMatchProcessedEvent OnMatchProcessed;
// Fired when a match result is processed.
public event Action<MatchProcessedV3Notification> OnMatchProcessed;

Example: This feature can be used to show post-match statistics for a player.

[Game Flow] New OnLeftMatchmaking event triggered when a party leaves matchmaking. #

Description: The Party service now has an OnLeftMatchmaking event, which is triggered when a party leaves matchmaking.

Details:

// Fired when the party has left matchmaking.
FLeftMatchmakingEvent OnLeftMatchmaking;
// Fired when the party has left matchmaking.
public event Action OnLeftMatchmaking;

Example: This feature can be used to show UI changes so non-leader players are aware a party has left matchmaking.

[Game Flow] New OnEnteredMatchmaking event triggered when a party enters matchmaking. #

Description: The Party service now has an OnEnteredMatchmaking event, which is triggered when a party enters matchmaking.

Details:

// Fired when the party has entered matchmaking.
FEnteredMatchmakingEvent OnEnteredMatchmaking;
// Fired when the party has entered matchmaking.
public event Action OnEnteredMatchmaking;

Example: This feature can be used to show UI changes so non-leader players are aware a party has entered matchmaking.

[Game Flow] New OnMatchFound event triggered when a party is matched but the game server isn’t ready yet. #

Description: The Party service now has an OnMatchFound event, which is triggered when a party is matched in matchmaking but before the game server is ready. The event’s data provides the match ID for the match.

Details:

// Fired when a match is found in matchmaking but before a game server is ready.
FMatchFoundEvent OnMatchFound;
// Fired when a match is found in matchmaking but before a game server is ready.
public event Action<PragmaId> OnMatchFound;

Example: This feature can be used to disable a “leave matchmaking” button while waiting for a game server to run a match.

[Game Flow] Matches can now be removed from matchmaking using the LeaveMatchmaking request. #

Description: Game servers can now request that a match is removed from matchmaking using the MatchLifecycleService.LeaveMatchmakingV1Request. This can be used to remove an Active Match from matchmaking if the match will end soon or if it can no longer accept more players.

Details:

void UPragmaMatchLifecycleService::LeaveMatchmaking(const FString MatchId,
UPragmaMatchLifecycleServiceRaw::FLeaveMatchmakingV1Delegate Delegate)
TFuture<TPragmaResult<FPragma_MatchLifecycle_LeaveMatchmakingV1Response>>
UPragmaMatchLifecycleService::LeaveMatchmaking(const FString MatchId)
MatchLifecycleService:
void LeaveMatchmaking(PragmaId matchId, Action<Result<LeaveMatchmakingV1Response>> callback)
Future<LeaveMatchmakingV1Response> LeaveMatchmaking(PragmaId matchId)

[Game Flow] Unreal: New OnPreferredGameServerZonesChanged event added for game flow. #

Description: We’ve added a new OnPreferredGameServerZonesChanged event to the Unreal SDK. Subscribe to this event to be notified when a party leader updates the list of preferred game server zones.

Details:

FPreferredGameServerZonesEvent PragmaPartyService.OnPreferredGameServerZonesChanged;

[Game Flow] Unreal: New GetMatchID() function retrieves match ID value for a party. #

Description: The Party service now has a GetMatchID() function for the Unreal SDK that retrieves the current match ID value. If the party is not in a match, a null value is returned.

Details:

PartyService->GetMatchId()

[Player Data] You can now set up virtual currency entitlements for PlayStation 5 using Pragma Engine’s pre-implemented PS5 plugin. #

Description: Contact your Pragma support representative for further details.

[Player Data] Game servers, game Operators, and custom authored services can now synchronize player entitlements. #

Description: You can now synchronize player entitlements from Service, Operator, and Partner endpoints.

Details:

  • SyncEntitlementsPartnerV1Request has been added to support game servers.
  • SyncEntitlementsOperatorV1Request has been added to support game Operators.
  • SyncEntitlementsServiceV1Request has been added to support custom services within Pragma Engine.

[Player Data] You can now change the rewards of a crafting call based on the contents of a player’s inventory. #

Description: We’ve added the parameter playersInventory to the Crafting Plugin. This enables making decisions about the crafting result item grants based on the player’s current inventory.

Related note: See integration note about the Crafting Plugin.

[Accounts] The Steam Identity Provider Plugin now supports filtering account access by app ownership and Steam ban status. #

Description: Use the new config fields restrictByAppOwnership and restrictByAccountBan on the Steam Identity Provider Plugin. These are optional booleans defaulted to false.

Related note: See docs note about identity providers.

[Accounts] The Google Identity Provider Plugin now supports email domain verification for authentication. #

Description: Use the new config field allowedDomains on the Google Identity Provider Plugin. This is an optional field, and if no list is provided, all email domains will be allowed to authenticate.

Related note: See docs note about identity providers.

[Infra & Tooling] Updated Postman collection in the pragma-engine repo. #

Description: An updated list of request endpoints has been added to the Postman collection.

[SDKs] Custom services now only need to be registered once on the runtime instead of on each session. #

Description: You can now register your custom service on all Player and Server sessions regardless of when they are created.

Details: We recommend you register your custom services in one place early during game startup.

  • Use UPragmaRuntime::RegisterService to register your custom service. We recommend you register your custom services in one place early during game startup. Some examples are:
    • in your GameInstance Init method override
    • in one of your GameInstanceSubsystem Initialize methods
    • directly after you create the Pragma::Runtime (if you don’t use the PragmaGameInstanceSubsystem)
  • Use Pragma.Runtime.RegisterService to register your custom service. We recommend you register your custom services in one place early during game startup immediately after calling Runtime.Get() for the first time such as in an Awake() method.

[SDKs] Unreal: You no longer need to explicitly check for null pointers when using PragmaPtrs. #

Description: PragmaPtrs now have a boolean operator, so you no longer need to explicitly check for null pointers.

originalreplacement
if (Player == nullptr) {
    // handle nullptr
}
else
{
    // do stuff
}
if (Player) {
    // do stuff
}

[Portal] Developers can now view and edit Rewards in Portal. #

Description: You can now use the Portal to view and edit Rewards, Reward Bags, Reward Slots, and Reward Tables. You can also view the rewards chances of rolling on a specific table. To access this functionality, visit Reward Tables in the Content Catalogs section.

Deprecations #

[Game Flow] Replace references to getMatchmakingInfoV1 with getMatchmakingInfoV2. Adjust usages of the result payload from the old dictionary to the new list object. #

originalreplacementremoval release
Unreal
Session()->Party()->GetMatchmakingInfoV1()
Unreal
Session()->Party()->GetMatchmakingInfoV2()
0.0.93
Unity
Player.Party.GetMatchmakingInfoV1()
Unity
Player.Party.GetMatchmakingInfoV2()
0.0.93

[Infra & Tooling] Replace references to configMapOfPrimitiveOf and configMapOfObjectOf with configMapOf. #

originalreplacementremoval release
configMapOfPrimitiveOfconfigMapOf0.0.93
configMapOfObjectOfconfigMapOf0.0.93

Related note: See integration note about ConfigMap.

Integrations #

[Game Flow] Update usages of prepareMatchInfo to use prepareMatch and preparePlayers instead. #

Description: The MatchFoundPlugin.prepareMatchInfo method has been removed. The methods MatchFoundPlugin.prepareMatch and MatchFoundPlugin.preparePlayers should be used instead.

Integration step: Update usages of prepareMatchInfo to use prepareMatch and preparePlayers instead.

originalreplacement
prepareMatchInfoprepareMatch and preparePlayers

[Game Flow] Replace references to enableMatchReconnect with the new matchReconnect configuration property. #

Description: The MatchLifecycleServiceConfig.enableMatchReconnect boolean config has been removed in favor of the MatchLifecycleServiceConfig.matchReconnect enum config. This allows for customization of match reconnect behavior, which can be read about in the Match Reconnect section of the docs.

Integration step: Use the new MatchLifecycleServiceConfig.matchReconnect configuration property by making the following replacements in your config file:

originalreplacement
enableMatchReconnect: truematchReconnect: "REQUIRED"
enableMatchReconnect: falsematchReconnect: "OFF"

[Game Flow] Update references to startMatchmaking and canStartMatchmaking in SDK code to reflect the rename to use enter instead of start, and use the newly renamed enterMatchmaking instead of requestMorePlayers. #

Description: The calls startMatchmaking and requestMorePlayers have been replaced with enterMatchmaking. For consistency, canStartMatchmakingV1 has been replaced with canEnterMatchmaking.

Integration step: Make the following updates in SDK code:

originalreplacement
PartyService.StartMatchmakingV1PartyService.EnterMatchmakingV1
PartyService.CanStartMatchmakingV1PartyService.CanEnterMatchmakingV1
PartyServiceRaw.StartMatchmakingV1PartyServiceRaw.EnterMatchmakingV1
MatchLifecycleService.RequestMorePlayersMatchLifecycleService.EnterMatchmaking
MatchLifecycleServiceRaw.RequestMorePlayersV1MatchLifecycleServiceRaw.EnterMatchmakingV1
MatchLifecycle.RequestMorePlayersV1RequestMatchLifecycle.EnterMatchmakingV1Request
MatchLifecycle.RequestMorePlayersV1ResponseMatchLifecycle.EnterMatchmakingV1Response
originalreplacement
PartyService.StartMatchmakingV1PartyService.EnterMatchmakingV1
PartyService.CanStartMatchmakingV1PartyService.CanEnterMatchmakingV1
PartyServiceRaw.StartMatchmakingPartyServiceRaw.EnterMatchmaking
MatchLifecycleServiceRaw.RequestMorePlayersV1MatchLifecycleServiceRaw.EnterMatchmakingV1
MatchLifecycleService.RequestMorePlayersMatchLifecycleService.EnterMatchmaking
MatchLifecycle.RequestMorePlayersV1RequestMatchLifecycle.EnterMatchmakingV1Request
MatchLifecycle.RequestMorePlayersV1ResponseMatchLifecycle.EnterMatchmakingV1Response

[Game Flow] If your game server implementation in the SDK uses the ConnectMorePlayers call, generate an ExtPlayerMatchDetails object for each player. #

Description: The game server must now send an ExtPlayerMatchDetails in the MatchMorePlayersFound notification for every player sent to the game server, otherwise the ConnectMorePlayers request fails and players are removed from matchmaking after the configured createMatchTimeout time has elapsed. A PragmaError.MatchLifecycleService_MissingPlayerExt error is thrown if there is a missing ExtPlayerMatchDetails.

Integration step: If your game server implementation uses the ConnectMorePlayers call, generate an ExtPlayerMatchDetails object for each player.

[Game Flow] If you’ve implemented the Matchmaking Plugin, update imports of pragma.matchmaking.MatchmakingQueueKey to pragma.matchmaking.MatchmakingRpc.MatchmakingQueueKey. #

Description: The MatchmakingQueueKey has been migrated from being a Kotlin data class to a protobuf object. This change was made to make it easier for queue key responses to be interpreted, so a namespace move was required on several methods on the Matchmaking Plugin.

Integration step: In any implementations of the Matchmaking Plugin–or in subclasses implementing behavior for this plugin–update imports of pragma.matchmaking.MatchmakingQueueKey to pragma.matchmaking.MatchmakingRpc.MatchmakingQueueKey.

originalreplacement
pragma.matchmaking.MatchmakingQueueKeypragma.matchmaking.MatchmakingRpc.MatchmakingQueueKey

[Game Flow] If you’re using an engine-modded custom implementation of the Accounts service, update the getPragmaSocialIdentities and getPragmaSocialIdentityBySocialId methods to their listed renames. #

Description: These public methods in the AccountDaoNodeService have been renamed for clarity.

Integration step: If you’re using an engine-modded implementation of the Accounts service, update the following methods to their renames:

originalreplacement
AccountDaoNodeService.getPragmaSocialIdentitiesAccountDaoNodeService.getSocialIdentitiesWithPersonals
AccountDaoNodeService.getPragmaSocialIdentityBySocialIdAccountDaoNodeService.getSocialIdentityWithPersonalForPragmaSocialId

[Game Flow] If you have integration tests using the BaseServerIT class, rename your GameIT and SocialIT config files to DefaultGameIT and DefaultSocialIT. #

Description: The default Game and Social configs referenced by the BaseServerIT located in test/resources/localDevelopmentShardConfig have been renamed from GameIT and SocialIT to DefaultGameIT and DefaultSocialIT. This rename is for consistency of internal integration tests.

Integration step: If you have integration tests using the BaseServerIT class, complete the following renames. If these config files are automatically generated from templates next time you complete a local build, copy over any custom additions and remove the old config files.

originalreplacement
GameITDefaultGameIT
SocialITDefaultSocialIT

[Player Data] If you’ve implemented the Crafting Plugin, you’ll need to update the craft() and meetsRequirements() methods with the new parameter playersInventory. #

Description: To accommodate the playersInventory feature, you’ll need to complete the integration steps.

Integration steps:

  • Add the new parameter playersInventory to the Crafting Plugin craft() method.
  • Change the parameter name on the meetsRequirements() method from inventoryData to playersInventory. Example:
    override fun craft(
        craftingEntry: CraftingEntryWrapper,
        destroyedInstancedItems: List<InstancedItem>,
        playersInventory: InventoryData,
        inventoryContent: InventoryServiceContent,
        requestExt: ExtCraftRequest
    ) : CraftingPlugin.CraftResult {
    }

    override fun meetsRequirements(
        craftingEntry: CraftingEntryWrapper,
        destroyedInstancedItems: List<InstancedItem>,
        playersInventory: InventoryData,
        ext: ExtCraftRequest
    ): PragmaResult<Unit, List<String>>  {
    }

Related note: See feature note about player inventory.

[Accounts] Update code that references the Accounts RPC protos PragmaPlayerOverview and PragmaAccountOverview, as they have been moved. #

Description: The Accounts RPC protos PragmaPlayerOverview and PragmaAccountOverview have been moved.

Integration steps:

  • Update platform code that references the RPC protos PragmaPlayerOverview and PragmaAccountOverview.
  • Update the imports for these classes in Unreal code to reflect their new location.

[Accounts] If you manually inspect and use fields in the auth token JWTs, update your code to reference refreshInMillis instead of refreshAtMs. #

Description: This change has been made because the refreshAtMs field is subject to a player client’s system time, while refreshInMillis is a duration that can be explicitly and consistently tracked.

Integration step: If you manually inspect and use fields in the auth token JWTs, update your code to reference refreshInMillis instead of refreshAtMs.

[Accounts] If you’ve configured your Discord identity provider to have a map of authorizedRoleIds, you’ll need to migrate the value to allowedRoleIds in the config. #

Description: The authorizedRoleIds config in the DiscordIdProviderConfig has been renamed to the new key allowedRoleIds to maintain consistent naming between similar concepts within the Discord and Google identity providers.

Integration step: If you’ve configured your Discord identity provider to have a map of authorizedRoleIds, you’ll need to migrate the configuration value to the new key allowedRoleIds.

[Accounts] If you’re using the PlayStation identity provider, contact your Pragma support representative for assistance. #

Description: We’ve modified the PlayStation identity provider for usability.

Integration step: Please contact your Pragma support representative if you’re using the PlayStation identity provider.

[Infra & Tooling] Replace any references to the DatabaseConnectionFactory class with DatabaseConfigResource.getSchemalessNonPooledConnection. #

Description: The deprecated DatabaseConnectionFactory class has been removed and any references to the class’s function should be replaced with DatabaseConfigResource.getSchemalessNonPooledConnection.

Integration step: Update any references to the DatabaseConnectionFactory class with DatabaseConfigResource.getSchemalessNonPooledConnection instead.

originalreplacement
DatabaseConnectionFactory classDatabaseConfigResource.getSchemalessNonPooledConnection

[Infra & Tooling] Replace any references to the BackendInfo class’s scheme and wsScheme properties with protocol and webSocketProtocol. #

Description: The BackendInfo class’s scheme and wsScheme properties have been removed and any references to the class’s previous properties should be replaced with protocol and webSocketProtocol. This affects any Kotlin platform code using the deprecated properties, as well as any SDK or website info calling the v1/info endpoint.

Integration step: Replace any references to the scheme and wsScheme properties in the BackendInfo class with protocol and webSocketProtocol instead.

originalreplacement
schemeprotocol
wsSchemewebSocketProtocol

[Infra & Tooling] Replace ConfigMapOfPrimitive and ConfigMapOfObject with ConfigMap for any type declarations in configuration classes. #

Description: ConfigMapOfPrimitive and ConfigMapOfObject types have been consolidated into ConfigMap for code simplification.

Integration step: Replace ConfigMapOfPrimitive and ConfigMapOfObject with ConfigMap for any type declarations in configuration classes.

originalreplacement
ConfigMapOfPrimitiveConfigMap
ConfigMapOfObjectConfigMap

[Infra & Tooling] If you use any functions inside the UUIDUtils file in pragma-engine, update the imports to use the new pragma.utils root package. #

Description: The UUIDUtils file has been migrated to a new package, and no longer belongs to the root package of Pragma Engine. It should now be accessed using pragma.utils.

Integration step: Update imports of any function that uses the UUIDUtils file from pragma.* to pragma.utils.*

[Infra & Tooling] Update references to operatorSession, partnerSession, playerSession, and serviceSession to use the correct imports. #

Description: Session Test Factory functions were removed to address duplication.

Integration step: Update references to operatorSession, partnerSession, playerSession, and serviceSession to use the correct imports.

originalreplacement
import pragma.PragmaCoreTestFactory.operatorSession
import pragma.PragmaCoreTestFactory.partnerSession
import pragma.PragmaCoreTestFactory.playerSession
import pragma.PragmaCoreTestFactory.serviceSession
import pragma.SessionTestFactory.operatorSession
import pragma.SessionTestFactory.partnerSession
import pragma.SessionTestFactory.playerSession
import pragma.SessionTestFactory.serviceSession

[SDKs] Unreal: If you were dependent on OnConnected happening after the LogIn method’s callback OnComplete returning, you’ll need to modify your code. #

Description: UPragmaConnection::OnConnectednow fires before the LogIn method’s callback OnComplete returns. This is consistent with how the LogOut method works and allows systems relying on OnConnected to initialize before the LogIn callback returns.

Integration step: Update any code that relies on the ordering of the OnConnected event relative to the LogIn OnComplete callback.

[SDKs] Unity: Update usages of PartyService.RawPartyService to PartyService.Raw. #

Description: This rename was done to be consistent with established naming conventions.

Integration step: Update usages of PartyService.RawPartyService to PartyService.Raw.

originalreplacement
PartyService.RawPartyServicePartyService.Raw

[Portal] If you’re using the Resource Portal Module Plugin, migrate to the File Portal Module Plugin. #

Description: The Resource Portal Module Plugin has been removed and replaced with the File Portal Module Plugin.

Integration step: In your config file, change the Portal plugin reference from ResourcePortalModulePlugin to FilePortalModulePlugin and update config values as necessary.

Bugs and Fixes #

  • Logging for Postman requests has been improved.
  • The Party parameters OnPartyChanged (Unreal) and OnPartyDataChanged (Unity) are no longer invoked when a party is not yet set.
  • Unreal: The Unreal SDK now parses JWTs encoded with base64url and UTF8 properly.
  • Unreal: Fixed a crash that occurred when receiving a JSON payload greater than one million characters in size with a log level of VERBOSE.
  • Portal: The Unsafe Provider has been set as the default login in the dev-yml file for both Social and Game.

Docs #

  • [Updated Concepts] Updated and reorganized the Party concepts page.
  • [Updated Concepts] Updated the Player Data Overview page with more information on the Inventory service.
  • [Updated Concepts] Added a new section for the Instanced Item Plugin on the Items concepts page.
  • [Updated Concepts] Updated the Limited Grants page with new information and further clarifications.
  • [Updated Concepts] Updated the Identity Provider page in the Accounts section with tables on config values and parameters options.
    • Related note: See features notes about identity providers.
  • [Updated Concepts] Added a new quick guide on viewing batched player and social identities to the Account Data concepts page.
    • Related note: See feature note on player and social identities.
  • [Updated Introduction Guide] Updated the Understanding Pragma Engine Introduction page with a new section on how to access docs for older versions of Pragma Engine.
  • [New Internal Guide] Added a new internal guide on adding a Provider Entitlement for Playstation. Contact us for further information and access.