March 2, 2023
Features #
[Game Flow] New Matchmaking Plugin method endLoop
allows for custom code to be injected after each matchmaking loop.
#
Description: The new Matchmaking Plugin method endLoop
is now invoked after each matchmaking loop. This makes it possible to add custom logic, such as the functionality to start a Potential Match early even if it fails to make an ideal match.
Related note: See docs note on endLoop
.
[Game Flow] Leaving a party or kicking a player from a party removes the entire party from matchmaking. #
Description: This change was made to keep matchmaking and party player membership in sync.
[Game Flow] Match reconnect can now be set as optional for players. #
Description: Operators can now configure game flows to allow for optional match reconnect. If configured, game clients can invoke DeclineReconnect
to leave the existing match when they disconnect.
Details:
New Player endpoint:
DeclineReconnectV1
bool UPragmaPartyService::CanDeclineReconnectV1() const bool UPragmaPartyService::CanDeclineReconnectV1(FPragmaError& OutError) const TFuture<TPragmaResult<>> UPragmaPartyService::DeclineReconnectV1() void UPragmaPartyService::DeclineReconnectV1(const FOnCompleteDelegate& OnComplete)
public bool CanDeclineReconnectV1() public bool CanDeclineReconnectV1(out Error? error) public Future DeclineReconnectV1() public void DeclineReconnectV1(CompleteDelegate onComplete)
New Partner notification that can be subscripted via engine-specific events:
PlayerDeclinedReconnectV1Notification
FPlayerDeclinedReconnectEvent UPragmaMatchLifecycleService.OnPlayerDeclinedReconnectEvent;
public event Action<PragmaId, PragmaId> MatchLifecycleService.OnPlayerDeclinedReconnect;
New Match Lifecycle service configuration option:
matchReconnect
can have the valuesOFF
,OPTIONAL
, orREQUIRED
.
[Player Data] UpdateEntryId
is now an optional field when making instanced item update calls.
#
Description: You can now call instanced item update without needing a placeholder for the update entry. ServerInstancedItemUpdate
and InstancedItemUpdate
no longer require you to assign an UpdateEntryId
.
Examples: The following are examples of instanced item update calls without UpdateEntryId
:
FPragma_Inventory_InstancedItemUpdate{*InstanceId}
var instancedItemUpdate = new InstancedItemUpdate {InstanceId = instancedId}};
"payload": {
"itemUpdate": {
"instanced":
{
"instanceId": "<items-instance-id>"
}
}
}
[Player Data] Items that do not correspond to a valid catalogId
will no longer show up in a player’s inventory.
#
Description: The Inventory service now filters out items that do not have a corresponding catalogId
defined by instanced and stackable content specs. This filtering prevents runtime errors that occurred on retrieval when a catalogId check was happening.
If you want to load items in the database with invalid catalogId
, assign and set legacyItemLoadBehavior: true
in the Inventory service config, though this may result in runtime errors.
[Player Data] The Instanced Item Plugin’s newInstanced()
and update()
functions can now access a player’s inventory before and during an RPC call.
#
Description: The Instanced Item Plugin’s functions have been updated with one new and one renamed parameter. This enables player inventory access for instanced item modifications before the call runs, as well as a view into the item logic that would be committed to the database once the engine processes the call’s request.
Related note: See integration note to update the Instanced Item Plugin.
[Infra & Tooling] New configuration validation process checks configs and outputs errors. #
Description: Pragma Engine now validates configuration files and provides detailed explanations of any issues. This new config validation process means the engine will catch issues, prevent bad configs from being used, and provide meaningful guidance for resolving errors. This validation runs both when you build, and when you dynamically change a config for an actively running backend.
Related note: See integration note for config validation.
[Infra & Tooling] Version information on all gateways can now be viewed using the new /v1/healthcheck
.
#
Description: /v1/healthcheck
can be used to monitor nodes that don’t necessarily run frontend gateways. The following are /v1/healthcheck
responses and their associated JSON payloads:
- 200: Health of node is ideal.
{"isHealthy":true,"version":"DEFAULT-0.0.91-WIP-a5bb265-dirty","platformVersion":"local-dev","portalVersion":"local-dev","contentVersion":"local-dev","configVersion":"local-dev"}
- 503: Health of node is not ideal. Note that
"isHealthy": false
is currently used during startup to indicate that not all services are running yet.
{"isHealthy":false,"version":"DEFAULT-0.0.91-WIP-a5bb265-dirty","platformVersion":"local-dev","portalVersion":"local-dev","contentVersion":"local-dev","configVersion":"local-dev"}
Related note: See integration note about /v1/info
.
[SDKs] Added rich bindings for PlayerLeave
.
#
Description: The rich Match Lifecycle service on the PragmaSession
now has PlayerLeave
functions for both Unity and Unreal.
[SDKs] SDK code generation now supports the proto3 optional
field attribute.
#
Description: The proto3 optional
field is now supported. This allows the SDK to support messages that recursively reference themselves. You can also now check for the existence of optional
fields.
Example:
// Given a MyData field called "Data"
bool b = Data.SomeInt.HasValue(); // Check that the field has a value set.
Int x = Data.SomeInt.Value(); // Get the value.
Data.SomeInt.SetValue(42); // Set the value.
// Given a MyData field called "Data"
bool b = Data.SomeInt.HasSomeInt; // Check that the field has a value set.
int x = Data.SomeInt; // Get the value. Note this will return default if not set.
Data.SomeInt = 42; // Set the value.
message MyData {
optional int32 some_int = 1;
}
[SDKs] SDK code generation now supports messages that recursively reference themselves. #
Description: Messages can reference themselves in their own fields or in sub-message fields. Fields involved in cyclic references must be marked optional
or repeated
.
Example: The following code block shows message A referencing itself both in its own field and in message B, which is a sub-message of A.
message A {
optional A = 1;
optional B = 2;
}
message B {
repeated A = 1;
}
[SDKs] BackendAddress
and ProtocolType
can now be specified separately for client and server.
#
Description: Pragma SDK running on a game server now uses the new config fields PartnerBackendAddress
and PartnerProtocolType
. These fields can be overridden via command line parameters: -PragmaPartnerBackendAddress="http://127.0.0.1:10100" -PragmaPartnerProtocolType="Http"
. If the PartnerBackendAddress
field is empty, BackendAddress
will be used instead.
[SDKs] The Inventory service now supports item lookups by catalogId
and instanceId
.
#
Description: You can now look up items by catalogId
and instanceId
instead of iterating through the list on InventoryResults.InventoryFull
using the two new functions GetInstancedItemsByCatalogId
and GetStackableItemsByCatalsogId
.
Example: The following are the two new item lookup functions in PragmaInventory.Service
:
var itemsWithCatalogIdLookup = PragmaInventory.Service.GetInstancedItemsByCatalogId("<<catalog-id>>");
var itemWithInstanceIdLookup = PragmaInventory.Service.GetInstancedItemByInstanceId("<<instance-id>>");
[SDKs] Game servers now connect to Pragma Engine over WebSocket by default. #
Description: The default PartnerProtocolType
for Pragma SDKs is now WebSocket instead of HTTP. If you prefer HTTP, you can override this behavior with the command line parameter -PragmaPartnerProtocolType="Http"
or via the config field PartnerProtocolType
according to your engine.
[Portal] The new Portal is now available! #
Description: The new Portal has better extensibility, clearer separation of customer data, and a simplified configuration. New capabilities include:
- Update and extend existing pages and portlets with components, pages, and actions.
- Use flags to toggle features with the
featureToggles
option. - Define custom rendering components for ext data in content and inventory.
- Use the
<Icon />
component to access 400+ new icons and add custom icons. - Leverage the new Less support across the entire Portal; all
.less
files are loaded and compiled automatically.
Related note: See integration note about custom content in Portal.
[Portal] Portal shows how much time remains before an event begins or ends. #
Description: You can now see the amount of time remaining before events start or end when viewing scheduled events in the Portal. This information is shown in a new Status
column.
The Events
table can be seen in the Social Portal → Services menu → Game Title Management → Shards → Select a shard, then scroll down to the Events
table.
Deprecations #
[Game Flow] The MatchLifecycleServiceConfig.enableMatchReconnect
boolean config has been deprecated in favor of the MatchLifecycleServiceConfig.matchReconnect
enum config.
#
Description: The MatchLifecycleServiceConfig.matchReconnect
config will support an upcoming feature. The existing enableMatchReconnect
config is scheduled to be removed in Pragma Engine release 0.0.92. To migrate early, make the following replacement in your config file:
original | replacement | removal release |
---|---|---|
enableMatchReconnect: true | matchReconnect: "REQUIRED" | 0.0.92 |
enableMatchReconnect: false | matchReconnect: "OFF" | 0.0.92 |
[SDKs] Sessions are changing. #
Description: PragmaSession
has been split into Player and Server objects that provide a more relevant subset of the API based on their respective use cases.
- See the Unreal and Unity SDK API v2 migration guide in the shared Google Drive for more details.
- The existing implementation of
PragmaSession
is now deprecated and will be removed in a future release.
Integrations #
[Game Flow] Move the Match Reconnect config to its new location in the MatchLifecycleServiceConfig
.
#
Description: Match Reconnect now handles connections that were forcibly disconnected on the client side. The configuration for turning on Match Reconnect has been moved to the MatchLifecycleServiceConfig
.
Integration step: Move the Match Reconnect config to its new location. Be sure to remove it from the existing location.
- Before:
game:
core:
session:
enableMatchReconnect: true
- After:
game:
serviceConfigs:
MatchLifecycleServiceConfig:
enableMatchReconnect: true
Related note: See bugfix note on client reconnects.
[Game Flow] Replace usages of the partyStartMatch
Test Factory method with startMatch
.
#
Description: This helper has been removed as part of the post-Lobby service cleanup.
Integration step: Replace usages of the following Test Factory method in Game Loop.
original | replacement |
---|---|
matchCapacity_partyStartMatchV1Request | matchCapacity_startMatchV1Request() |
[Game Flow] If you’re using the listed MatchLifecycleServiceConfig
properties, you’ll need to update references to reflect their renames.
#
Description: We’ve renamed several config properties for the Match Lifecycle service to be more clear. Note that these are optional properties, so if you’re not using them, no action is required.
Integration step: Update references to the following renamed config properties.
original | replacement |
---|---|
enableInProgressMatchTimeout | enableMatchAbsoluteTimeout |
inProgressMatchTimeoutMillis | matchAbsoluteTimeoutMillis |
missedKeepAlivesBeforeCleanup | keepAliveMissesLimit |
Example: Below is an example of the new Match Lifecycle service config using all the new property names.
game:
serviceConfigs:
MatchLifecycleServiceConfig:
enableMatchAbsoluteTimeout: true
matchAbsoluteTimeoutMillis: 10000000
enableKeepAlive: true
keepAliveIntervalMillis: 30000
keepAliveMissesLimit: 3
[Game Flow] If you have custom code referencing SessionServicePB
or Session
, update them to their new names.
#
Description: To improve the structure of Pragma Engine and to keep components understandable, we’ve renamed a few Session-related protos and services.
Integration step: After rebuilding protos
and sdk-types
, check custom code for references to the following Session calls and update them to their replacements:
original | replacement |
---|---|
SessionServicePB | PlayerSessionRpc |
Session | SessionCommon |
[Game Flow] If your game server implementation uses the MatchReady
call, generate an ExtPlayerMatchDetails
object for each player.
#
Description: Game server implementations that use the MatchReady
call must provide ExtPlayerMatchDetails
for each player. This change was made to detect missing ExtPlayerMatchDetails
. If the game server provides fewer ExtPlayerMatchDetails
than the required number of players as defined by the ReportCapacity response, it will throw a MatchLifecycle_MissingPlayerExt
error.
Integration step: In your game server’s response handling for MatchCapacity::StartReportCapacityPolling
, while creating the MatchReady
request, an ExtPlayerMatchDetails
object must be generated with the playerId
for each player. These objects must then be put on the MatchReady
request before calling MatchLifecycle.MatchReadyV2
.
[Game Flow] If you’re using the listed Party service helper functions, update them to their new names. #
Description: We’ve renamed the getParty
and getBroadcastParty
proto helpers on the Party service to be more accurate.
Integration step:
original | replacement |
---|---|
Party.getParty | Party.getPartyProto |
Party.getBroadcastParty | Party.getBroadcastPartyProto |
[Game Flow] If you have a custom implementation of the Matchmaking Plugin, update references to PotentialMatch
, ActiveMatch
, and MatchableParties
to be consistent with new locations and names.
#
Description: Studios using custom implementations of the Matchmaking Plugin will need to update the class references, as the interface for the plugin has been changed with new types. These changes were made to be more readable and prevent the usage of restricted properties and functions. Changes have been made to the locations of ActiveMatch
and PotentialMatch
, and to the name of MatchableParties
.
Integration steps: If you have a custom implementation of the Matchmaking Plugin, you will need to complete the following steps.
- Change the
MatchableParties
type toMatchable
, and update any related imports as necessary. - Update any references to
PotentialMatch
andActiveMatch
, as they’ve been moved into a new folder. - If you were using a function or property that is now unavailable, reach out to your Pragma support representative to find alternate strategies using approved functions.
[Player Data] If you’re using the Instanced Item Plugin, update newInstanced()
’s and update()
’s parameters.
#
Description: We’ve added in a new parameter called pendingInventory
and renamed an existing parameter initialInventory
in the Instanced Item Plugin’s newInstanced()
and update()
functions.
Integration steps:
- Add the parameter
pendingInventory
to bothnewInstanced()
andupdate()
. - Rename the parameter
initialInventory
withstartingInventory
to bothnewInstanced()
andupdate()
.
Example: Below is an example of the Instanced Item Plugin with the updated parameters:
interface InstancedItemPlugin {
fun newInstanced(
instancedSpec: InventoryContent.InstancedSpec,
inventoryContent: InventoryServiceContent,
startingInventory: InventoryData, // RENAMED from initialInventory
pendingInventory: InventoryData, // NEW parameter
clientRequestExt: ExtPurchaseRequest?,
serverRequestExt: ExtInstancedItemServerGrant?
): InstancedItemPluginResult
fun update(
initialInstancedItem: InstancedItem,
instancedSpec: InventoryContent.InstancedSpec,
updateEntry: InventoryContent.UpdateEntry,
inventoryContent: InventoryServiceContent,
startingInventory: InventoryData, // RENAMED from initialInventory
pendingInventory: InventoryData, // NEW parameter
clientRequestExt: ExtInstancedItemUpdate?,
serverRequestExt: ExtInstancedItemServerUpdate?
): InstancedItemPluginResult
}
Related note: See feature note on updates to the Instanced Item Plugin.
[Infra & Tooling] Replace usages of /v1/info
version information with /v1/healthcheck
.
#
Description: Version information is no longer available on /v1/info
, as it has been moved to the new /v1/healthcheck
.
Integration step: Replace any dependency on /v1/info
version data with /v1/healthcheck
.
[Infra & Tooling] You may need to check your config files for stale or unused configs to successfully pass the new config validation step. #
Description: As part of the new config validation feature, stale or broken configs that were previously ignored will now cause the engine to prevent startup and generate an error.
Integration step: Check your config files for stale, unused configurations from before Pragma Engine began validating. These will need to be removed.
Related note: See feature note on config validation.
[Infra & Tooling] If you’re using the SystemProxy
class, reimplement it as it’s been deleted.
#
Description: The old SystemProxy
class is no longer in use by Pragma Engine and has been deleted. If you’re using this class in custom code, you’ll need to reimplement it.
Integration step: Please contact us for support for reimplementing the SystemProxy
class.
[SDKs] Unreal: If you had manual HTTP implementations for game servers in any custom services, replace these with the new macros. #
Description: The Unreal game server now supports WebSocket connections. Any custom service that previously utilized manually created functions for the Http()
handler can now make use of the prebuilt macros.
Integration steps:
- Locate custom service code that directly invokes HTTP connections to Pragma.
- Replace code with usage of an appropriate binding of the correct
IMPL_PRAGMA_[BACKEND]_METHOD
macro, where[BACKEND]
should be replaced withSOCIAL
orGAME
.
Example:
- Before:
void UPragmaMatchLifecycleServiceRaw::MatchReadyV2(
const FPragma_MatchLifecycle_MatchReadyV2Request& Request,
TUniqueFunction<void(TPragmaResult<FPragma_MatchLifecycle_MatchReadyV2Response>, const FPragmaMessageMetadata&)>
Callback) const
{
Connection().Http(EPragmaBackendType::Game).SendMessage(Request, MoveTemp(Callback));
}
- After:
IMPL_PRAGMA_GAME_METHOD(UPragmaMatchLifecycleServiceRaw, MatchReadyV2, FPragma_MatchLifecycle_MatchReadyV2Request,
FPragma_MatchLifecycle_MatchReadyV2Response, FMatchReadyDelegate);
[SDKs] Unreal: Rename the listed types. #
Description: As part of Core SDK cleanup, some type names have changed.
Integration step: Find and rename the following types:
original | replacement |
---|---|
UPragmaConnection::FConnectionError | FPragmaConnectionError |
EProtocolError | EPragmaProtocolError |
[SDKs] Unreal: Update your Init
method in custom services to take new parameters.
#
Description: As part of Core SDK cleanup, the Init
method of custom services now takes new parameters.
Integration step: Make the following replacement:
original | replacement |
---|---|
Init(UPragmaSession* InSession) | Init(IPragmaShimSession* InSession, IPragmaShimConnection* InConnection) |
[SDKs] Unreal: Complete the listed integration steps to enable a workaround for packaging standalone Unreal game builds. #
Description: To enable packaging standalone Unreal game builds, you must complete the integration steps.
Integration steps:
- Open the
pragma-engine/sdk
folder. - Find
PragmaInventoryCache.cpp
and remove#include "BehaviorTree/BTCompositeNode.h"
. - Find
PragmaCore.cpp
and comment outPRAGMA_LOG(Error, "Failed to load Pragma Core shared library.");
. - Run the
update-pragma-sdk.sh
script. - Rebuild your Unreal game project to enable packaging projects from Unreal Editor.
[SDKs] Unity: Update your Init method in custom services to take new parameters. #
Description: As part of Core SDK cleanup, the Init
method of custom services now takes new parameters.
Integration step: Make the following replacement:
original | replacement |
---|---|
Init(PragmaSession session) | Init(ISession session, IConnection connection) |
[Portal] All customers must complete the provided Portal integration guide to prevent CI from breaking. #
Description: To support the new Portal workflow, you’ll need to upgrade portlets and deployment systems so they work properly with the new Portal.
Integration step: Check out the Portal Integration Guide in the shared Google Drive for integration steps and a changelist.
Related note: See feature note about the new Portal.
Bugs and Fixes #
[Game Flow] Pragma Engine now properly clears party and matchmaking states when a client crashes and restarts.
Description: New client connections are treated as fresh sessions, unless
enableMatchReconnect
is configured, in which case the players are automatically reconnected to the match.Related note: See integration note on Match Reconnect.
[Game Flow] We’ve fixed an issue where sessions would prematurely time out if connected with HTTP and WebSocket.
Docs #
[Updated Docs] Updated SDK docs across the site to reflect the API V2 changes.
[Updated Concepts] Added a new section on Keep Alive Heartbeats in the Match End page, which explains the behavior regarding the Match Lifecycle service.
[Updated Concepts] Added new information on disabling Unsafe Providers and the related config to the Identity Providers page.
[Updated Concepts] Updated the Provider Entitlement page with new information and clarification.
[Updated Concepts] Added new information on match reconnect on the Match Lifecycle page.
- Related note: See feature note about match reconnect.
[Updated Concepts] Added a new section Add Custom Behavior After Complete Loop to the Matchmaking page.
- Related note: See feature note on the new Matchmaking Plugin method
endLoop
.
- Related note: See feature note on the new Matchmaking Plugin method
[Updated Concepts] Added a new section on Configuring Protocols for HTTP and WebSocket connection on the Game Server Management page.
[Tech Blog] The Tech Blog has migrated from the docs site to Pragma’s main site, with a new landing page which includes new locations for articles.
[New Tech Blog Articles] Two new Content Data articles are live! Learn about the Content Data system with Part 1 and Part 2 of the Content Data article series.