Appearance
Release 16
December 22nd, 2021
Appearance
December 22nd, 2021
New feature: Game config compression reduces the download size of game configs by approximately 80-85%. The feature will be automatically enabled.
New feature: Player developer privileges allow giving developers extra privileges in the production environment. Developer players can log in during maintenance mode, can execute [DevelopmentOnlyAction]s, and perform sandbox purchases on iOS. See Working with Developer Players for more information.
New feature: Analytics event custom labels allow games to add custom data to server-side analytics events. Check out Implementing Analytics Events in Game Logic on how to add your first custom label, and see Streaming Analytics Events to External Storage for details on how these labels are written out to the external storage.
New feature: Debug-forcing of activables is a development-time feature for bypassing the configured scheduling and targeting of activables (such as in-game events) to test their various phases. See section Force-Activating Events During Development in Implementing Config-Driven Game Events for how to access this feature.
New feature: Player segment combinations. It is now possible to target broadcasts, notifications, and experiments to players that match multiple segment conditions. This effectively means that in addition to being able to target players who match any of the listed segments, you can now match players who only match against all.
An example use case might be to send a broadcast to anyone that is over level 20, was last logged in from the US, and has made purchases in the game. Previously this was only possible by declaring a separate combination segment, now the combination can be declared as part of the targeting parameters.
Streamlined feature: Banning players now prevents them from starting a game session and reports a new dedicated error code, which makes handling banned players easier on both the server and the client. No need to remember to inspect IsBanned again. See Player Banning for tips and tricks.
INFO
Comment on log4j (CVE-2021-44228 and CVE-2021-45046): We are aware of the recently disclosed issues in log4j. Metaplay backends do not utilize log4j and are not susceptible to the issues described in the CVEs. We have additionally reviewed the underlying AWS services that are being used in conjunction with our infrastructure setups and our current understanding, based on our own review and AWS's comments, is that there are no current vulnerabilities in the infrastructure services related to the CVEs either.
Please note that if you have deployed any non-Metaplay software as part of your backend, you should review whether components you may have inserted yourself are vulnerable and patch and update accordingly!
LogicVersion to force a synchronized client/server update.npm install in the dashboard project folder to refresh your local development environment before launching the dashboard project.Options.base.yaml using Clustering.ShardingTopologies. The old Helm values-based definitions are deprecated and no longer used. Options.base.yaml.experimental.gameserverIpv6Enabled parameter with service.ipv6Enabled and set it to true by default. experimental.publicApiEndpoints block with publicApiEndpoints. admin.auth block with auth. This object can be used to configure Auth0 or more general OIDC authentication setups. When used for configuring Auth0 authentication, these values will be configured across all relevant chart-managed resources (e.g. LiveOps dashboard, Grafana, etc.) and will not require duplicating the same information across multiple configuration blocks. auth.eas, but the defaults should work for most of the cases.EntityKinds are now separate to various registries based on owner and visibility. Game Entities are defined in EntityKindGame for client-and-server-visible Entities, and EntityKindCloudGame for server-only-visible Entities. Similarly, builtin Metaplay Entities are now defined in in EntityKindCore for client-and-server-visible Entities and EntityKindCloudCore for server-only-visible Entities. MetaDefines has been removed and has been replaced by GlobalOptions. This mainly affects updating the current LogicVersion ranges, which must now be updated in GlobalOptions.cs instead. externalDns configuration block. api configuration block. New timeline-based view of events to improve workflows for CS agents when dealing with event streams such as player events and audit logs.
This new component replaces event and audit log lists in many dashboard pages:

A new dedicated event timeline page shows event streams in even greater detail:

The Compare Game Config Versions page now allows you to quickly and easily select any two game configs for comparison. In the main view of this page, individual difference chunks can now be collapsed to reduce noise.
[PersistedEntityActor] and [EphemeralEntityActor] attributes into a EntityActorRegistry. The registry is used for storing metadata such as schema versions and the types are used to persist objects into the database.[EntityMaintenanceRefreshJob] registers a refresh database scan job for the entity (triggerable from the dashboard).[EntityMaintenanceSchemaMigratorJob] registers a schema migrator database scan job for the entity type (triggerable from the dashboard).[EntityMaintenanceJob(..)] registers a custom maintenance database scan job for the entity type (triggerable from the dashboard).[EntityArchiveImporterExporter(..)] registers entity archive import/export functionality for the entity type. These are invoked by the export and overwrite player state buttons in the dashboard.[PrimaryKey] member. It is now possible to do re-sharding again. The operation can still take a lot of time with big databases, so please talk to us if you want to do a re-sharding operation in production.apply. This will minimize the required maintenance break when updating the infrastructure (updating EKS can be done while the rest of the game backend remains up).Infrastructure and Helm chart compatibilities for this release:
infra-modules version v0.1.3 or later for infrastructuremetaplay-gameserver Helm chart version 0.2.0 or later for deploymentinfra-modules version v0.1.7 or later for infrastructuremetaplay-gameserver Helm chart version 0.3.0 or later for deploymentEntityActorRegistry which keeps metadata about all EntityActors and can be used to query it.[JsonSerializeNullCollectionAsEmpty] attribute to allow serializing null arrays and dictionaries as [] and {} in JSON.TerminalError.PlayerIsBanned error if attempting to log in with a player that is banned. Ongoing sessions are terminated with a new SessionForceTerminateReason.PlayerBanned reason. In LifecycleDelegate both are exposed as ConnectionLostReason.PlayerIsBanned.IAPManager for managing the flow of IAPs between the game, Metaplay, and Unity IAP. Previously, IAPManager existed in the Idler reference project.PersistedEntityActors using the [EntityMaintenanceJob(..)] attribute.ContentDelivery Runtime Option.[Index] attribute for the database index definitions.GameDbContext into MetaDbContext<TPersistedPlayer, TPersistedGuild>.PersistedPlayerSearch into core where it belongs.PersistedPlayer to PersistedPlayerBase.ServerMain into SDK core class ServerMainBase.PlayerActor.CreatePlayerStateResponse() as it's no longer needed.PersistedPlayers or PersistedGuilds.CreateDataResolver() methods -- use the relevant ISharedGameConfig instead.PlayerActor.RegisterPlayerAsActive() into PlayerActorBase.PlayerActor.CreatePersisted() for creating the game-specific PersistedPlayer object.EntityActor types must now have either [PersistedEntityActor] or [EphemeralEntityActor] attribute.PersistedEntityActor schema version is now defined via [PersistedEntityAttribute(..)].Connection.Reconnect() emits DisconnectedFromServer and processes its handler synchronously before starting to open the new connection.ClusteringOptions.ShardingTopologies and TopologyId.GameDbContext and remove DatabaseBackendXyz dependency on GameDbContext.EntityRefresherUtil and EntitySchemaMigratorUtil now query EntityActorRegistry instead of including metadata about EntityKinds.[EntityArchiveImporterExporter] for Actor. Player and Guild Actor are eligible automatically with the default Import & Export handlers.ImportEntityHandler into (Player|Guild|*)Model.RemapEntityIdsAsync.GamePermissions must now have [AdminApiPermissionRegistry].MetaDefines by a MetaplayCoreOptions which the SDK discovers by reflection at initialization time.[EntityMaintenanceRefreshJob] and [EntityMaintenanceSchemaMigratorJob] for Actor. Player and Guild Actor are eligible automatically.[EntityMaintenanceJob("Delete", typeof(ScheduledPlayerDeletionJobSpec))].SessionActor to SessionActorBase.PlayerActor.OnNewOwnerSubscriber and OnOwnerSubscriberLost to OnNewOwnerSession and OnOwnerSessionEnded. OnOwnerSessionEnded is now also called when session ends due to player being kicked.GuildActor.ValidateGuildCreationAsync and replaced it with overridable PlayerActor.ValidateGuildCreationAsync.ServerAction into UnsynchronizedServerAction to better describe its behavior.ConfigArchiveEntry.Bytes is now accessed via ConfigArchiveEntry.Uncompress().IJournalModelAdapter (and the game-side implementations like PlayerAdapter) has been removed and its responsibilities refactored to various places.GuildModelBase<...> now implements IGuildModelBase and some of its methods. Accordingly, various methods in GuildModel are now defined as overrides instead of direct interface method implementations.ProtocolStatus.InMaintenance.[Consumes("application/json")] is now applied on per-endpoint basis as ASP.NET 6 no longer matched any of the routes without explicit specifying the 'Content-Type: application/json' header, even where no content exists.MetaRefs: Ignore indexers and getterless properties in the object tree traversal.SHA256.Create() etc., and RandomNumberGenerator.GetBytes().EventDescription property getter.[PrimaryKey].HttpClient when generator network diagnostics reports, to reduce the chances of exceptions in its Dispose() method (caused by a known bug in Mono version used by Unity, should be innocuous).