Pragma Engine 0.0.90
January 13, 2023
Changes from 0.0.89 have been integrated into this release.
Features #
The updated Matchmaking service is live! #
Description: Our new version of the Matchmaking service currently supports the same features as the previous iteration, but with easier ways to write core matchmaking logic in the plugin, and improved implementation for custom games and other game types that don’t require matching with incoming parties. We’ll continue to add new functionality to this service.
Related note: See Docs note on the new Matchmaking page.
You can now send an idempotency key on the Apply Inventory Operations endpoints to ensure the data operations are applied only once. #
Description: These Apply Inventory Operations endpoints include:
InventoryRpc.ApplyInventoryOperationsOperatorV1Request
InventoryRpc.ApplyInventoryOperationsPartnerV1Request
InventoryRpc.ApplyInventoryOperationsServiceV1Request
If you assign an idempotency key, all Apply Inventory Operations’ requests withDataOperations
will only be applied to the player one time. All following requests with the same idempotency key will do nothing and return an empty response.
You can now return a null ExtInstancedItem
in the InstancedItemPluginResult
.
#
Description: The update to InstancedItemPluginResult
now allows you to return a null on the ExtInstancedItem
field. This allows for a lot more flexibility and control of instanced item creation and updating.
You can now set a time window on limited grants. #
Description: This allows you to define a limited grant that will only be granted to a player within a specified time window.
Related note: See related Docs note on the Limited Grant tutorial.
Game client inventory is now updated automatically when player inventory is changed. #
Description: Game client inventory is now updated automatically when player inventory is changed using Operator, Partner, or Service inventory endpoints. The existing Pragma Engine InventoryService.OnInventoryUpdated
notifications on both Unreal and Unity SDKs are broadcast when updates are received.
Added a new Service endpoint for deleting a player’s inventory. #
Description: Services can now delete player inventories by using the new endpoint DeletePlayerInventoryServiceV1Request
. Note that this functionality already existed as a Player endpoint, and is now additionally available as a Service endpoint.
Added a new annotate
command to output fully resolved Pragma Engine configurations.
#
Description: A new annotate command has been added to the pragma.jar
to enable viewing the fully resolved configuration.
For more information, run the following command:
java -jar 5-ext/target/pragma.jar config annotate --help
Example: The following command returns a full output of the configurations annotated with the source file that the values originated from.
java -jar 5-ext/target/pragma.jar config annotate --backend-type game --configuration-filepaths config/dev-defaults.yml,5-ext/config/dev.yml,5-ext/config/common.yml,5-ext/config/local-dev.yml
SDKs: You can now specify Partner Session Authentication Tokens via an SDK’s command line. #
Description: Specifying Partner Session Authentication Tokens for game servers can now be done during your SDK app startup. Before this feature, users had to put Partner tokens into a config file. Users can now specify those tokens via the SDK command line.
PragmaPartnerSessionSocialAuthToken="<social token>"
PragmaPartnerSessionGameAuthToken="<game token>"
Jobs in the Dependent Job Incoming Queue Length graph in Grafana are now split into subsets of jobs. #
Description: In the Dependent Job Incoming Queue Length graph in Grafana, jobs are now split into subsets of jobs specified by a group identifier. This new group argument can be added to pragma.jobs.runAsDependentJobs
; existing usages can be updated to use this feature.
SDKs: You can now reuse a game server for multiple matches by releasing the capacity of the MatchCapacityService
after match completion.
#
Description: When calling ReleaseCapacity
, the MatchCapacity
service sets the used capacity to 0
, which is then reported to Pragma Engine in the ReportCapacity
poll. To reuse this game server state, pass in the OnComplete
handler that was used in the StartReportCapacityPolling
call.
void UPragmaMatchCapacityService::ReleaseCapacity(const FMatchAllocatedDelegate& OnComplete)
TFuture<TPragmaResult<FPragma_MatchLifecycle_MatchDataV2>> UPragmaMatchCapacityService::ReleaseCapacity()
public void ReleaseCapacity(MatchAllocatedDelegate onComplete)
public void ReleaseCapacity(MatchAllocatedDelegate onComplete)
Unreal SDK: You can now override Pragma.ini
’s location via the Unreal SDK’s command line.
#
Description: The Pragma.ini
configuration file can now be specified in a command line instead of hardcoded to its specific destination. Make sure that you specify a filename and include the .ini
extension when changing the file’s location.
PragmaIni="path/to/pragma.ini"
Unreal SDK: Added future
version to the StartReportCapacityPolling
function.
#
Description: To maintain consistency with SDKs having both callback and future versions of async functions, we’ve added a version of the StartReportCapacityPolling
function that returns a future
alongside the existing version of the function that takes in a callback.
Example:
UPragmaMatchCapacityService
:
TFuture<TPragmaResult<FPragma_MatchLifecycle_MatchDataV2>> UPragmaMatchCapacityService::StartReportCapacityPolling(FString ServerId, FString GameVersion, FString GameServerZone, float Timeout)
Unreal SDK: New HasSession()
method added to Pragma Subsystems
.
#
Description: You can now check if Pragma Engine has been initialized without needing to hit the assert
inside GetSession()
. Use the new HasSession()
method on Pragma LocalPlayer
and GameServer
Subsystems
instead.
Unreal SDK: Program
type Unreal apps can now be used without an engine dependency.
#
Description: The PragmaSDK
module no longer has an engine module dependency, which means it can be built by Unreal apps that don’t depend on it. Engine-dependent functionality is now in PragmaSDKAux
, so if you’re using Subsystems or are planning on future engine-dependent code, you’ll need to include that module in your dependency list.
Related note: See related Integration note about the PragmaSDKAux
dependency.
Portal: Added Tree
view alongside Rich
and Raw
views in Content Catalogs.
#
Description: We’ve added a structured JSON editor under the Tree
tab on the Content Catalogs page. This editor includes several formatting tools, such as sort, transform, and duplicate.
Portal: Content Catalogs Editor now enabled by default. #
Description: The Content Catalogs Editor portlet is now enabled by default. Adding 4: null
to your config will disable this portlet.
game:
pluginConfigs:
GameOperatorGatewayNodeService.portalPlugin:
class: "pragma.gateway.FilePortalModulePlugin"
config:
modules:
4: null
Deprecations #
Replace GrantItemsPartnerV1
, DestroyItemsPartnerV1
, DestroyItemsServiceV1
, and GetInventoryPartnerV1
with their newer versions.
#
Description: The GrantItemsPartnerV1
, DestroyItemsPartnerV1
, DestroyItemsServiceV1
, and GetInventoryPartnerV1
endpoints weren’t filtering content into hidden vs player-facing inventory items, which meant game servers could be sent hidden inventory. The responses for these endpoints are now filtered into a ServiceUpdateItemsResponse
with two UpdateItemsResponse
s, one for hidden inventory and one for player-visible items.
Replace the request and response calls for the following endpoints with their newer versions by release 0.0.90. Note that you can use the separate updates.hidden
and updates.player
to access filtered data.
original | replacement | removal release |
---|---|---|
GrantItemsPartnerV1 | GrantItemsPartnerV2 | 0.0.91 |
DestroyItemsPartnerV1 | DestroyItemsPartnerV2 | 0.0.91 |
DestroyItemsServiceV1 | DestroyItemsServiceV2 | 0.0.91 |
GetInventoryPartnerV1 | GetInventoryPartnerV2 | 0.0.91 |
Unity SDK: Switch to using the cached inventory returned by InventoryService.GetInventory
.
#
Description: Unity SDK developers need to switch to using cached inventory returned by InventoryService.GetInventory
, or force the cache to update and use the result returned to the callback provided to the new InventoryServiceForceGetInventory
. To find stackable and instanced inventory within this data, you can subscribe an event handler to InventoryService.OnInventoryUpdated
.
Replace usages of InventoryService.GetInventoryV2
with InventoryService.GetInventory
. If you require the client to forcibly refresh itself, you can use InventoryService.ForceGetInventory
.
original | replacement | removal release |
---|---|---|
InventoryService.GetInventoryV2 | InventoryService.GetInventory | 0.0.91 |
Integrations #
Update unit tests to be compatible with the JUnit upgrade. #
Description: We’ve upgraded JUnit from version 5.6.2 to 5.9.1 to take advantage of some new test parallelization features. As a result, you may need to make changes to some of your unit tests.
Integration steps:
- Remove the
private
modifier from@BeforeEach
/@AfterEach
/@BeforeAll
/@AfterAll
methods in your unit tests. - If you’re using
@BeforeEach
/@AfterEach
/@BeforeAll
/@AfterAll
methods with inheritance, you may need to make some changes to preserve intended behavior due to a bugfix.
Update unit tests because they now run in parallel. #
Description: Tests now run in parallel by default in order to shorten build times. This affects tests running via make
/mvn
and IntelliJ.
Integration steps: Some tests may not be compatible with parallelization.
- Use
@ResourceLock
to prevent multiple tests from using a particular resource simultaneously.- Example: Tests that use Ktor’s
withTestApplication
do not interact well with parallelization and should use a@ResourceLock(Resources.KTOR_TEST)
annotation to ensure only one is run at a time.
- Example: Tests that use Ktor’s
- Use
@Isolated
to ensure a test runs entirely alone.- Example: Any tests that use
mockkStatic
should use@Isolated
.
- Example: Any tests that use
- Using delays in integration tests is more dangerous with parallelization. Use the new
TestUtils.repeatUntilSuccess
function instead of hardcoded sleeps to make your tests more robust. maven-surefire-plugin
often reports incorrect numbers of tests run in each class (this is a known issue).
Update your usage of the PartyTestFactory
.
#
Description: The party()
and partyWithPlayers()
methods have been combined. The new method is named party()
and preserves the functionality of both methods.
Integration steps:
- Replace usages of
partyWithPlayers()
withparty()
. - If you’re using
party()
and want a party with zero players, pass innumPlayers = 0
.
Copy your Social node’s configuration for TokenSignerConfig
into the Game node configuration.
#
Description: Pragma Engine can now send Partner game tokens to Nomad game servers on startup. To enable this, Game node configurations now require a TokenSignerConfig
.
Integration step: Copy the existing configuration from social.serviceConfigs.TokenSignerConfig
and create a new entry at game.serviceConfigs.TokenSignerConfig
.
game:
serviceConfigs:
TokenSignerConfig:
jwtPrivateKey: "myPrivateKey"
If you’re using Nomad as a capacity provider, the config for the PragmaNomadCapacityProvider
needs to be updated to use jobDatacenter
instead of jobName
.
#
Description: To support the Nomad changes that improve the capacity provider flow, you need to update the config as we move towards a simpler pattern for spawning jobs.
Integration step: If you’re using Nomad as a capacity provider, the config for the matchcapacity.PragmaNomadCapacityProvider
needs to be updated to use jobDatacenter
instead of jobName
. You’ll also need to remove -exec
from the config value.
Self-hosted customers will need to upgrade their environments using the following Terraform module: internal-shard-with-nomad-v5
. Managed customers should reach out to Pragma for support for this change.
#
Description: Partner tokens no longer need to be encoded into Nomad game binaries, because the Nomad capacity provider now sends them automatically on addCapacity
calls–this change requires an update to the Nomad infrastructure. The game server shell invocation script is invoked by Nomad with the following command line parameters: PragmaPartnerSessionSocialAuthToken
and PragmaPartnerSessionGameAuthToken
. The SDK prioritizes these over values set in Pragma.ini
files.
Integration step: Terraform environments must be upgraded using the following shared Terraform module: internal-shard-with-nomad-v5
. You won’t be able to use your Nomad provider until this integration is complete. Managed customers should reach out to their Pragma support team to have this work completed.
If you’re using the token refresh feature for the Discord ID provider, reach out to your support representative. #
Description: To simplify the extra features on supported ID providers, we’ve removed the following endpoints: /v1/account/discord-token-refresh
& discordTokenRefreshV1
.
Integration step: If you’re using the token refresh feature for the Discord ID provider, reach out to your support representative.
If your game is integrated with the Inventory service, you need to assign a value to InventoryCacheConfig
.
#
Description: The Inventory service now runs a sweep of the cache in the background to help with the eviction logic for the Inventory service cache. We have added configurations around the frequency and requirements to evict.
Integration steps:
- Assign an
InventoryCacheConfig
underInventoryServiceConfig
for all deployed environments. The following parameters must be assigned values:sizeBeforeExpirationEnforced,
maxTimeBetweenAccessMillis
, andsweepIntervalMillis
. We have provided local/dev defaults underpragma-engine/platform/config/dev-defaults.yml
, but must be manually set for all other environments. - We recommend using the values in the example below. If you’re currently integrated with the Inventory service and running playtests with over 10,000 players, please reach out to Pragma for support.
Example: Config under game
:
InventoryServiceConfig:
inventoryCacheConfig:
sizeBeforeExpirationEnforced: 10000
maxTimeBetweenAccessMillis: 720000
sweepIntervalMillis: 900000
If you’re returning instancedItemGrants
from InventoryOperationsPlugin.InventoryOperations
, you need to update server type.
#
Description: The return result from InventoryOperationsPlugin.getInventoryOperationsFromMatchEnd()
no longer has a field for InstancedItemGrants
.
Integration step: Convert from InstancedItemGrant
to InstancedItemServerGrant
in your plugin implementation.
If you’re not using Pragma Engine’s SDK’s game servers and you’re using the Keep Alive feature, you must configure the Keep Alive interval. #
Description: The Keep Alive feature is now enabled by default, so a Keep Alive interval must be set. Game servers using Pragma Engine’s SDKs will do this automatically.
Integration step: If MatchReadyV2Response.enable_keep_alive
is set to true
, a MatchKeepAliveV1Request
must be sent from the game server on an interval defined by MatchReadyV2Response.keep_alive_interval_millis
.
Related note: See Docs note on the Keep Alive feature.
If you want to use match reconnect, you must set SessionConfig.enableMatchReconnect
to true
.
#
Description: To simplify the basic match loop setup, the default value for enableMatchReconnect
has been changed to false
. If you had match connect implemented already, you will need to reenable it in the config.
**Integration step:**To enable match reconnect, make sure match reconnect SDK handlers are implemented, and then enable match reconnect functionality in your configuration for that environment.
game:
core:
session:
enableMatchReconnect: true
If you’re using the version
properties endpoint in /v1/info
, you’ll need to update it to platformVersion
.
#
Description: We’ve added version
properties to /v1/info
for each artifact type (platformVersion
, portalVersion
, contentVersion
, and configVersion
).
Integration step: If you’re using the version
properties endpoint in /v1/info
, you need to update it to platformVersion
.
original | replacement |
---|---|
version | platformVersion |
Unreal SDK: If you use the ErrorCode
result of the LogIn
method, you’ll need to update your code to reference enum errors instead of the previous strings.
#
Description: The LogIn
method was originally written before the SDK began using enum errors, and therefore used arbitrary strings. With this change, UAccountService::LogIn
uses EPragma_SdkError
enum values like Unauthorized
, PlatformUnavailable
, and AlreadyLoggedIn
instead of those strings.
Integration step: If you use the ErrorCode
result of UAccountService::LogIn
, the string value has changed. See the EPragma_SdkError enum
for possible errors–UAccountService::LoginError_*
strings have been removed.
New strings will look like: EPragma_SdkError::PlatformUnavailable
. You can also use the enum itself by using Result.Error()
instead of Result.ErrorCode()
.
Unreal SDK: Update references to PartyService.ResetParty
to expect a return value of void
instead of a boolean.
#
Description: The ResetParty
function no longer returns a boolean indicating whether the function actually reset the party. This change was made to simplify some internal code around changing party state. The function still guarantees that the party state is reset every time it is called. Note that the corresponding ForceReset
function was changed to return void instead of a boolean, but this was for internal code and should not cause errors, so please let us know if this change impacts you.
Integration step: Update references to PartyService.ResetParty
to expect a return value of void
instead of a boolean.
Unreal SDK: Update references to the listed renamed Inventory service calls. See included table for details. #
Description: We’ve renamed/removed several Inventory service calls for clarity.
Integration step: Update references to the listed renamed Inventory service calls.
original | replacement |
---|---|
UPragmaInventoryService::GetInstancedItemsV1 UPragmaInventoryService::GetStackableItemsV1 | UPragmaInventoryService::GetInventory : You can see the instanced and stackable items within the response of this call. |
UPragmaInventoryService::GetInventoryV1 | UPragmaInventoryService::GetInventory |
UPragmaInventoryService::DeletePlayerInventoryV2 | UPragmaInventoryService::DeletePlayerInventory |
Unreal SDK: Add the PragmaSDKAux
dependency to any [ProjectName].Build.cs files
that depend on PragmaSDK.
#
Description: The Unreal SDK has been split into two modules so you will need to add the new module to project dependencies.
Integration step: Add the PragmaSDKAux
dependency to any [ProjectName].Build.cs
files that depend on PragmaSDK.
Example:
- Before:
PrivateDependencyModuleNames.AddRange(new string[] { "PragmaSDK"});
- After:
PrivateDependencyModuleNames.AddRange(new string[] { "PragmaSDK", "PragmaSDKAux" });
Related note: See related Feature note about Program type apps.
Portal: Add the previously hard-coded authentication config values into your YAML file. #
Description: The Portal plugin FilePortalModulePlugin
previously used hard-coded Pragma-specific app information used by Portal for authentication, for the Google, Discord, and Twitch client IDs. These have been moved to dev-defaults.yml
. This means anyone running Pragma Engine locally will still be able to authenticate to the Portal using Pragma Engine apps, but production environments will need to separately specify these config values.
Integration step:
Add in the proper config values for authentication in your shard-
or common.yml
files. An example can be found below or in the platform/config/dev-defaults.yml
file.
If you’re using your own app credentials for Portal authentication, you should be unaffected.
Example:
game:
pluginConfigs:
GameOperatorGatewayNodeService.portalPlugin:
class: "pragma.gateway.FilePortalModulePlugin"
config:
authenticationIdProviders:
1: UNSAFE
discordClientId: ""
googleClientId: ""
twitchClientId: ""
...
social:
pluginConfigs:
SocialOperatorGatewayNodeService.portalPlugin:
class: "pragma.gateway.FilePortalModulePlugin"
config:
authenticationIdProviders:
1: UNSAFE
discordClientId: ""
googleClientId: ""
twitchClientId: ""
...
Bugs and Fixes #
Stopped
onComplete
callbacks for various functions being executed before inventory update events are fired in the Inventory SDK.Unreal SDK: Fixed a bug where the
Disconnect
event would not be fired when both sockets were consideredDegraded
and the full disconnect timer had elapsed.
Docs #
[Updated Concepts Section] The Monetization section has been updated with a new Overview and new pages on Provider Entitlement and the Payment service.
[New Concepts Guide] Added a new page on Viewing and Editing Content in the Portal section.
[New Concepts Guide] Added a new page on Grants and Entitlements in the Player Data section.
[Updated Concepts Guide] The Matchmaking guide has been completely rewritten! This new page contains detailed and comprehensive information on our updated matchmaking service.
[Updated Concepts Guide] Updated the Match End guide to capture the Match Keep Alive Heartbeats default being changed to
true
.[Updated Concepts Guides] The Match Lifecycle and Match End pages under Game Flow have been edited for clarity and accuracy.
[Updated Tutorial] Updated the Limited Grants tutorial to include information on time windows.
[New Tutorial] Added a new Tutorial on creating a Battlepass.
[Updated SDK Guide] The Unreal SDK guide has been updated to be clearer and more accurate.
[New Tech Blog Video] A new video on Creating a Crafting System Using Stores has been posted.
[New Tech Blog Article] The Instanced Item series is now live! Learn how to create instanced items, custom content, and plugins.