Integrations and Deprecations 0.4.x #
This topic includes integrations and deprecations for Pragma Version 0.4.0.
Behavioral integrations #
This section describes changes in behavior due to new/updated functionality. Extra care should be taken when implementing changes to avoid unexpected behaviors or regressions.
Process change for engine pom.xml files #
If you modify pom files in the engine, you must make the mod in the pom.xml.template file and run an engine build. Changes made directly to pom.xml files will be overwritten by the generated template file and lost.
Run ./pragma build engine -s -m buildplan:list to test your pom file validity without waiting for an entire pragma engine build.
Syntax integrations #
This section describes changes in naming, file locations, and other syntactical updates.
New CLI #
This integration guide includes using the new tool to identify your 5-ext project and automatically configure itself. The integration steps below include regenerating your project pom files to adopt the new, simpler, Maven structure.
All instructions are run in git-bash from the platform dir:
cd pragma-engine/platform
Init pragma cli #
The following command will generate a project config file and update Maven pom files to the new structure:
./pragma update init-5-ext
Run the update script #
The following command will run a script specific to perform some integration steps automatically, such as generating new ext proto messages:
./pragma update 0-4-0
Reconcile 5-ext Maven files #
After initializing the CLI, your 5-ext pom files will be overwritten with the updated structure. Use a diff tool to compare your 5-ext pom files, keeping the new changes while restoring any intended modifications your team has made, such as additional lib dependencies or additional maven projects you’ve added.
We suggest adding engine mod start/end markers to your pom changes to help make future pom updates easier to reconcile.
Note: Do not restore any test-jar dependencies pointed at proto projects; these have been removed intentionally and will cause your build to fail if added.
Reconcile removed engine-settings.xml file #
If you modified the engine-setings.xml file, migrate your modifications to the top-level platform/pom.xml.template file.
Run ./pragma build engine-code -s to regenerate the pom.xml from the template and confirm the engine builds successfully.
Update custom/additional Maven projects #
If you have custom/additional Maven projects within your 5-ext project, follow these steps to update your project pom.xml files to the new structure:
Update parent xml block in your
pom.xmlfiles:Old:
<parent> <groupId>[company]</groupId> <artifactId>5-ext</artifactId> <version>${revision}</version> </parent>New:
<parent> <groupId>[company_lower]</groupId> <artifactId>5-ext</artifactId> <version>[COMPANY_UPPER]-LOCAL-SNAPSHOT</version> </parent>Old:
<version>DEFAULT-LOCAL-SNAPSHOT</version>New:
<version>[COMPANY_UPPER]-LOCAL-SNAPSHOT</version>Add Maven profile files.
The new structure relies on a named text file to trigger the correct build profile.
Copy
mvn-profile-enginefrom5-ext/ext-serverinto your custom Maven project directories (next to thepom.xmlfor that project).
Complete the rest of your integration #
Once your project structure has been updated, proceed with the rest of your platform-side integrations. Once integration notes are complete, return here and follow the remaining steps to build and run.
Build your project to confirm changes #
Run these build steps in order to confirm all pom upgrades have been completed successfully
./pragma build engine-protos./pragma build engine-code -s./pragma build project-protos./pragma build project-codeNote: Use .
/pragma buildto rebuild your project on an ongoing basis. Use./pragma build engine -sonly when engine sources change.After successfully building on the command line, reload all Maven projects within Intellij and build the project within Intellij.
Make sure the
pragma-cli.inifile and updated pom files are checked in once the integration steps have been completed.
Adjust update-pragma-sdk.sh #
Make the following edits to your copy of the update-pragma-sdk.sh file:
Unreal:
Replace make gen-sdk-types-unreal4 with ./pragma sdk generate
Unity:
Replace make gen-sdk-types-unity with ./pragma sdk generate
Multiplayer integrations #
[Multiplayer ] Update NewGameInstance construction
#
To support creating a game instance directly from backend services, the NewGameInstance constructor now includes a ExtBackendCreateRequest parameter.
See the Migrate ExtGameInstance section of this deprecation note for instructions on migrating data from ExtGameInstance to the new ExtBackendCreateRequest.
If you do not want to migrate to the newExtBackendCreateRequestyet, you can continue to provide theExtGameInstancein theNewGameInstanceconstructor with a defaultExtBackendCreateRequest, however this flow is deprecated and will be unavailable in a future release.
[Multiplayer ] Migrate ExtGameParty data to the player and game instance data stores
#
To support adding players to a game instance directly, we removed the ExtGameParty ext. Instead, define the data directly on the player and game instance data store.
In gameInstanceExt.proto:
- Move data from
ExtGamePartytoExtData, which defines data store information for game instances and their players - For
ExtGamePartydata created during matchmaking, put that data in the newExtBackendCreateRequestandExtBackendAddPlayerexts, as well as onExtData. - Remove
ExtGameParty
In your matchmaking plugin:
- When creating a NewGameInstance or GameInstanceUpdate use the
requestExtconstructor parameter (ExtBackendCreateRequest), or thesetExtForPlayer()method withExtBackendAddPlayer. See the Matchmaking tasks for instructions and examples. - Remove calls to
setExtGameParty()
In your game instance plugin:
- Add data from
ExtBackendCreateRequestandExtBackendAddPlayerto the game instance and/or player data store. See the Create ExtData task for instructions and examples.
Before in gameInstanceExt.proto:
message ExtGameParty {
int32 mmr_average = 1;
}
After in gameInstanceExt.proto:
message ExtData {
oneof data {
Map<Fixed128, int32> party_mmr_averages = 1;
}
}
message ExtBackendCreateRequest {
Map<Fixed128, int32> party_mmr_averages = 1;
}
You can also choose to temporarily move data fromExtGamePartytoExtGamePlayerandExtGameInstance, however these exts have been deprecated and will be removed in a future release.
[Multiplayer ] Migrate ExtMatchmakingGameParty data to player or game instance exts
#
To support adding players to a game instance directly, we removed the ExtMatchmakingGameParty ext. Instead, define the data on ExtMatchmakingGamePlayer or ExtMatchmakingGameInstance.
Move
ExtMatchmakingGamePartydata to another ext:- Move player-specific data to
ExtMatchmakingGamePlayer - Move game instance data to
ExtMatchmakingGameInstance - Remove
ExtMatchmakingGamePartyfrom yourmatchmakingExt.protofile
- Move player-specific data to
Update ext build and set methods:
- Move player-specific data to
buildExtMatchmakingGamePlayer() - Move game instance data to
buildExtMatchmakingGameInstance() - Remove
ExtMatchmakingGamePartyfrom yourmatchmakingExt.protofile - Remove implementations of
GameInstanceMatchmakingPlugin.buildExtMatchmakingGameParty() - Update
buildExtMatchmakingGamePlayer(), as it no longer takes aGameInstance.GameParty parameter. Use the newGameInstance.getPlayersByPartyId()method to organize data by party ID.
- Move player-specific data to
[Multiplayer ] Update references for new way of getting party information from game instances
#
We removed the GameParty object from the GameInstance and Matchmaking interfaces. You can now access a list of players organized by party ID using the getPlayersByPartyId() method on the GameInstance and Matchmaking interfaces.
| Before | After |
|---|---|
In your GameInstancePlugin:GameInstance.parties | GameInstance.getPlayersByPartyId() |
In your MatchmakingPlugin:MatchmakingGameInstance.parties | MatchmakingGameInstance.getPlayersByPartyId() |
[Multiplayer ] Update service configs
#
To account for game instance allocation improvements, do the following:
Replace references to
GameInstanceServiceConfig.gameReadyTimeoutMilliswithGameInstanceServiceConfig.gameServerAllocationTimeoutMillis(default: 3 minutes).Replace references to
GameInstanceServiceConfig.reconnectwithGameInstanceServiceConfig.removePlayersOnDisconnectand provide a boolean value (defaultfalse) instead of a GameInstanceReconnect enum.- If previously using
reconnect = GameInstanceReconnect.OFF, useremovePlayersOnDisconnect = true - If previously using
reconnect = GameInstanceReconnect.REQUIRED, useremovePlayersOnDisconnect = false - If previously using
reconnect = GameInstanceReconnect.OPTIONAL, useremovePlayersOnDisconnect = falseand continue using the deprecated client SDK GameInstanceApi.DeclineReconnect() method.
- If previously using
Optionally, override the default for
GameInstanceServiceConfig.connectPlayersTimeoutMillis(default: 30 seconds)
[Multiplayer ] Do not use GameServerPlayer SDK class to retrieve display names and social IDs
#
To support adding players to a game instance directly, we removed the DisplayName, SocialId, and ClientVersion properties from the GameServerPlayer classes in the SDKs for Unreal and Unity, as fetching these values could become cumbersome.
To retrieve display names and social IDs, use PragmaAccountPartnerServiceRaw.GetPlayerIdentitiesPartnerV1() with the corresponding player IDs and shard ID.
[Multiplayer ] Update references to renamed Matchmaking methods
#
The following Matchmaking methods were renamed:
| Previous method | New method |
|---|---|
Matchmaking.Matchable.findPlayer() | Matchmaking.Matchable.getPlayer() |
Matchmaking.GameInstance.findPlayer() | Matchmaking.GameInstance.getPlayer() |
[Multiplayer ] Update metrics
#
- New GameInstance and PartyCache graphs were added to the Grafana Multiplayer dashboard.
- The PartyCache metric uses a standard cashing system with built-in metrics, so the PartyCount method is no longer required.
- The session lifespan metric type was changed from a distributed summary to a timer to better reflect the information being observed. In custom Grafana graphs change reference to
pragma_session_lifespanOnTermination_buckettopragma_session_lifespanOnTermination_seconds_bucket.
Reach out to Pragma to update your infrastructure to the latest version so you can receive the new graphs.
[Multiplayer ] Add new multiplayer ext messages
#
Define the following new protos in your gameInstanceExt.proto file:
/**
* Create payload for a game instance. Populated by game servers and/or backend services and used in
* [GameInstancePlugin.handleBackendCreateRequest].
*/
message ExtBackendCreateRequest {
}
/**
* Request payload when creating a game instance. Populated by game clients and used in [GameInstancePlugin.handlePlayerCreateRequest].
*/
message ExtPlayerCreateRequest {
}
/**
* Request payload when adding players to a game instance. Populated when using the [GameInstanceApi] and used in
* [GameInstancePlugin.handleBackendAddPlayersRequest].
*/
message ExtBackendAddPlayersRequest {
}
/**
* Payload for a specific player sent on a request to add players to a game instance. Populated when using the [GameInstanceApi] and used
* in the [GameInstancePlugin].
*/
message ExtBackendAddPlayer {
}
/**
* Request payload when joining a game instance. Populated by game clients and used in [GameInstancePlugin.handlePlayerJoinRequest].
*/
message ExtPlayerJoinGameInstanceRequest {
}
/**
* Request payload when removing players from a game instance. Populated by game servers or when using the [GameInstanceApi] and used in
* [GameInstancePlugin.handleBackendRemovePlayersRequest].
*/
message ExtBackendRemovePlayersRequest {
}
/**
* Payload for a specific player sent on a request to remove players from a game instance. Populated by game servers or when using the
* [GameInstanceApi] and used in the [GameInstancePlugin].
*/
message ExtBackendRemovePlayer {
}
/**
* Request payload when leaving a game instance. Populated by game clients and used in [GameInstancePlugin.handlePlayerLeaveRequest].
*/
message ExtPlayerLeaveRequest {
}
Define the following new protos in your partyRpcExt.proto file:
/**
* Update payload for a party. Populated when using the [PartyApi] and used in [PartyPlugin.handleBackendUpdateRequest].
*/
message ExtBackendUpdatePartyRequest {
}
Social integrations #
[Social ] Change game server and backend presence calls to update rich presence by player ID
#
We updated the MatchApi.SetRichPresence() and backend PresenceApi.SetRichPresence() methods to accept a player’s PlayerId instead of the SocialId.
Before MatchApi SDK
void SetRichPresence(
const FString& SocialId,
const FPragma_Presence_ExtRichPresenceBackendRequest& RichPresenceRequest,
const FOnCompleteDelegate& OnComplete);
After MatchApi SDK
void SetRichPresence(
const FString& PlayerId,
const FPragma_Presence_ExtRichPresenceBackendRequest& RichPresenceRequest,
const FOnCompleteDelegate& OnComplete);
Before PresenceApi.kt
class PresenceApi(
private val service: Service,
) {
suspend fun setRichPresence(
socialId: SocialId,
richPresenceRequest: ExtRichPresenceBackendRequest
)
}
After PresenceApi.kt
class PresenceApi(
private val service: Service,
) {
suspend fun setRichPresence(
playerId: PlayerId,
richPresenceRequest: ExtRichPresenceBackendRequest
)
}
Update references accordingly.
Engine integrations #
[Engine ] Update any usages of PragmaClient’s APIs
#
We have simplified PragmaClient’s APIs with the following version:
| Original | New |
|---|---|
makeGameRequest and gameRequest | gameRequestV2: PragmaResult<Response, GeneratedMessageV3> |
makeSocialRequest and socialRequest | socialRequestV2: PragmaResult<Response, GeneratedMessageV3> |
Patch integrations #
This section describes integrations necessary for specific patches.
[0.4.3 ] Update handleBackendCreateRequest() and handleBackendAddPlayersRequest() to use new PlayerToAdd data class
#
To provide the plugins with additional context about the new player being added, we created the PlayerToAdd data class.
Integration steps:
Update the following methods to use the updated playersToAdd parameter:
Originals
handleBackendCreateRequest(
gameInstanceSnapshot:
GameInstance.GameInstance,
requestExt:
ExtBackendCreateRequest,
playersToAdd: Map<PlayerId,
ExtBackendAddPlayer>
)
handleBackendAddPlayersRequest(
gameInstanceSnapshot:
GameInstance.GameInstance,
requestExt:
ExtBackendAddPlayersRequest,
playersToAdd: Map<PlayerId,
ExtBackendAddPlayer>
)
Replacements
handleBackendCreateRequest(
gameInstanceSnapshot:
GameInstance.GameInstance,
requestExt:
ExtBackendCreateRequest,
playersToAdd: List<PlayerToAdd>
)
handleBackendAddPlayersRequest(
gameInstanceSnapshot:
GameInstance.GameInstance,
requestExt:
ExtBackendAddPlayersRequest,
playersToAdd: List<PlayerToAdd>
)
Deprecations #
[Multiplayer ] Migrate game instance and player data to data stores
#
To streamline and consolidate game instance and game player data, we are deprecating the following exts in favor of using the data stores:
ExtAddedToGameExtGameInstanceExtGamePlayer
Migrate ExtAddedToGame data:
Move data from
ExtAddedToGameto theGameInstance.GamePlayer’s data storeBefore:
message ExtAddedToGame { string current_game_phase = 1; }After:
message ExtData { oneof data { string current_game_phase = 1; } }Populate the player’s data store using a Game Instance Plugin method, depending on how the player is entering the game instance.
For example, instead of using the
buildExtAddedToGame()method, set the relevant data on the game instanceExtDatawhen creating the game instance from a the backend:CustomGameInstancePlugin.kt override suspend fun handleBackendCreateRequest( gameInstanceSnapshot: GameInstance.GameInstance, requestExt: ExtBackendCreateRequest, playersToAdd: Map<PlayerId, ExtBackendAddPlayer> ) { val startingGamePhaseExtData = ExtData.newBuilder().setGamePhase( "loading" ).build() val startingPlayerPointsExtData = ExtData.newBuilder().setPlayerPoints( 0 ).build() gameInstanceSnapshot.dataStore.create( "gamePhase", startingGamePhaseExtData, PlayerSync.Public ) playersToAdd.forEach { it.dataStore.create( "playerPoints", startingPlayerPointsExtData, PlayerSync.Player(it.playerId) ) } //... }Remove your GameInstancePlugin’s
buildExtAddedToGame()implementation.
Migrate ExtGameInstance data:
Previously, you populated ExtGameInstance in matchmaking and then Pragma Engine automatically stored it on the newly created game instance. Now, do the following:
- Send game instance data from matchmaking to a new game instance via the
ExtBackendCreateRequestwhen constructing a NewGameInstance. - Store data that should persist for the life of the game instance on the game instance’s data store by defining the data in the
ExtDataproto.
For example, when creating a NewGameInstance from the matchmaking plugin:
val newGameInstance = NewGameInstance(
requestExt = ExtBackendCreateRequest.getDefaultInstance(),
gameServerZone = "North America"
)
The deprecated ext is still the first argument of the NewGameInstance constructor. Make sure you name your parameters to ensure you’re correctly providing the ExtBackendCreateRequest.See also: Match parties
Migrate ExtGamePlayer data:
Previously, you populated ExtGamePlayer in matchmaking and then Pragma Engine automatically stored it on the newly created game instance. Now, do the following:
- Send game player data from matchmaking to a game instance via
ExtBackendAddPlayerwhen adding a player to a game instance. - Store data that should persist for the duration of the player’s time in the game instance on the player’s data store by defining the data in the
ExtDataproto.
For example, when adding a player to a game instance from the matchmaking plugin:
val newGameInstance = NewGameInstance(...)
newGameInstance.addParties(anchor.parties)
for (player in anchor.players) {
newGameInstance.setExtForPlayer(player, ExtBackendAddPlayer.newBuilder().build)
}
[Multiplayer ] Use the new PartyApi.update() method instead of the Party plugin returnFromGameInstance() method to update party data from a game instance
#
To streamline updating party data, you can now use the new PartyApi.kt class update() method. The Party plugin returnFromGameInstance() method, which was used to update party data when a game instance ends, has been deprecated. Now, to update end-of-game-instance data, have the GameInstancePlugin.onEndGame() method invoke the PartyApi.update() method with the ExtBackendUpdatePartyRequest payload.
Integration steps:
- Define
ExtBackendUpdatePartyRequestto include information previously present in thereturnFromGameInstance()call. - Remove the
PartyPlugin.returnFromGameInstance()override and migrate functionality toPartyPlugin.handleBackendUpdateRequest(). - Change
GameInstancePlugin.onEndGame()to callPartyApi.update()with theExtBackendUpdatePartyRequest.
The returnFromGameInstance() method is expected to be removed in version 0.6.0.
[Multiplayer ] Replace decline reconnect methods and listeners
#
To better reflect actions taken, we’ve deprecated the following methods and events related to declining reconnections:
- The server SDK
OnPlayerDeclinedReconnectevent has been deprecated in favor ofOnPlayersRemove - The client SDK
GameInstanceApi.DeclineReconnect()method has been deprecated in favor ofGameInstanceApi.Leave()
Updating to the new event and method should be done in sync to avoid duplicated events.
[Multiplayer ] Replace OnAddPlayers listeners with OnPlayersAdded
#
We deprecated the Match API OnAddPlayers event and replaced it with the OnPlayersAdded event to maintain consistent naming across events. We recommend you replace occurrences of OnAddPlayers with OnPlayersAdded in your code.
The OnAddPlayers event is expected to be removed in version 0.5.0.
[Multiplayer ] Update use of Match API RemovePlayers() and Game Instance Plugin onRemovePlayers()
#
To streamline and standardize removing players from a game instance, we made the following changes:
Deprecated
ExtRemovePlayerin favor ofExtBackendRemovePlayerDeprecated
ExtRemovePlayersRequestin favor ofExtBackendRemovePlayersRequestDeprecated the
MatchApi.RemovePlayers()method that accepts theExtRemovePlayersRequestpayload in favor of aRemovePlayers()method that accepts theExtBackendRemovePlayersRequestpayload:Deprecated MatchApi.RemovePlayers():
public void RemovePlayers( PragmaId gameInstanceId, IEnumerable<PlayerToRemove> players, ExtRemovePlayersRequest ext, CompleteDelegate onComplete)New MatchApi.RemovePlayers():
public void RemovePlayers( PragmaId gameInstanceId, IEnumerable<BackendPlayerToRemove> players, ExtBackendRemovePlayersRequest ext, CompleteDelegate onComplete)Deprecated the
GameInstancePlugin.onRemovePlayers()method in favor ofhandleBackendRemovePlayersRequest(), which is now invoked byMatchApi.RemovePlayers()andGameInstanceApi.removePlayers()
Integration steps:
- Migrate ext data from
ExtRemovePlayerintoExtBackendRemovePlayer - Migrate ext data from
ExtRemovePlayersRequestintoExtBackendRemovePlayersRequest - Migrate logic in
GameInstancePlugin.onRemovePlayers()toGameInstancePlugin.handleBackendRemovePlayersRequest() - Update calls to
MatchApi.RemovePlayers()to use the newRemovePlayers()signature - If your current implementation of
GameInstancePlugin.onRemovePlayers()returns any values, instead invokegameInstanceSnapshot.removePlayer(playerId, ExtRemovedFromGame)within thehandlBackendRemovePlayersRequest()for each of those values. By default, the handle method removes all requested players with no additional process or ext content.
[Social ] Update references of methods in the SocialBackendPartnerClientNodeService class
#
The request RPC methods in the SocialBackendPartnerClientNodeService class are being deprecated in favor of two new methods with clearer naming and method signatures. The new methods perform the same request to the social backend as the old methods.
| Original | New |
|---|---|
requestRpc | makeSocialRequest |
requestRpcV2 | makeSocialRequestV2 |
[Portal ] Portal component library version updated to latest major version
#
We are upgrading the ant-design-vue library version 3.2.6 to the latest major version 4.2.1 for improved styling and customization options.
Integration steps:
Run the following command in the terminal from the platform directory to install new required packages:
./pragma portal setupAny custom Pragma Portlets or custom components that use Ant Design components may need to be updated. Reference the Ant Design version 4 migration guide for more details.
Use LESS variables instead of CSS variables.
Before (CSS variable) color: var(–primary);
After (LESS variable) color: @colorPrimary;
- If you are currently using .css files for styling of custom components change the file extension to .less. Pragma will automatically compile the file into CSS as part of the build process.
- CSS variables are scheduled to be removed in Pragma Version 0.5.0.