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.xml
files: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-engine
from5-ext/ext-server
into your custom Maven project directories (next to thepom.xml
for 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-code
Note: Use .
/pragma build
to rebuild your project on an ongoing basis. Use./pragma build engine -s
only 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.ini
file 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 newExtBackendCreateRequest
yet, you can continue to provide theExtGameInstance
in theNewGameInstance
constructor 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
ExtGameParty
toExtData
, which defines data store information for game instances and their players - For
ExtGameParty
data created during matchmaking, put that data in the newExtBackendCreateRequest
andExtBackendAddPlayer
exts, as well as onExtData
. - Remove
ExtGameParty
In your matchmaking plugin:
- When creating a NewGameInstance or GameInstanceUpdate use the
requestExt
constructor 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
ExtBackendCreateRequest
andExtBackendAddPlayer
to 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 fromExtGameParty
toExtGamePlayer
andExtGameInstance
, 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
ExtMatchmakingGameParty
data to another ext:- Move player-specific data to
ExtMatchmakingGamePlayer
- Move game instance data to
ExtMatchmakingGameInstance
- Remove
ExtMatchmakingGameParty
from yourmatchmakingExt.proto
file
- Move player-specific data to
Update ext build and set methods:
- Move player-specific data to
buildExtMatchmakingGamePlayer()
- Move game instance data to
buildExtMatchmakingGameInstance()
- Remove
ExtMatchmakingGameParty
from yourmatchmakingExt.proto
file - 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.gameReadyTimeoutMillis
withGameInstanceServiceConfig.gameServerAllocationTimeoutMillis
(default: 3 minutes).Replace references to
GameInstanceServiceConfig.reconnect
withGameInstanceServiceConfig.removePlayersOnDisconnect
and provide a boolean value (defaultfalse
) instead of a GameInstanceReconnect enum.- If previously using
reconnect = GameInstanceReconnect.OFF
, useremovePlayersOnDisconnect = true
- If previously using
reconnect = GameInstanceReconnect.ON
, useremovePlayersOnDisconnect = false
- If previously using
reconnect = GameInstanceReconnect.OPTIONAL
, useremovePlayersOnDisconnect = false
and 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_bucket
topragma_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:
ExtAddedToGame
ExtGameInstance
ExtGamePlayer
Migrate ExtAddedToGame data:
Move data from
ExtAddedToGame
to 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 instanceExtData
when creating the game instance from matchmaking:Before:
CustomGameInstancePlugin.kt override suspend fun buildExtAddedToGame( gameInstanceSnapshot: GameInstance.GameInstance, player: GamePlayer ): ExtAddedToGame { val ext: ExtGameInstance = gameInstanceSnapshot.ext return ExtAddedToGame.newBuilder() .setCurrentGamePhase(ext.gamePhase) .build() }
After:
CustomGameInstancePlugin.kt override suspend fun handleBackendCreateByMatchmakingRequest( gameInstanceSnapshot: GameInstance.GameInstance, ) { val phaseExtData = ExtData.newBuilder() .setCurrentGamePhase(BEGIN_GAME_PHASE).build() gameInstanceSnapshot.dataStore .create("game_phase", phaseExtData , PlayerSync.Public) }
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
ExtBackendCreateRequest
when 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
ExtData
proto.
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
ExtBackendAddPlayer
when 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
ExtData
proto.
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
ExtBackendUpdatePartyRequest
to 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
OnPlayerDeclinedReconnect
event 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() method to use new ext
#
We deprecated the MatchApi.RemovePlayers()
method that accepts the ExtRemovePlayersRequest
payload in favor of a RemovePlayers()
method that accepts the ExtBackendRemovePlayersRequest
payload. This decision was made to better align the Match API method with the backend APIs that accept the ExtBackendRemovePlayersRequest
.
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)
[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 setup
Any 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.