Appearance
Appearance
Major improvement: State Persistence in Offline Mode has been made more robust and is now enabled by default. This allows testing of more complex scenarios in the offline mode, including player state migrations. The offline mode is still only intended for development purposes only.
Major improvement: WebGL Support now includes networking via WebSockets and state persistence. It is now possible to build WebGL games using Metaplay. A few features are still missing and some manual configuration is required. See Metaplay & WebGL for more details.
Major improvement: LiveOps Dashboard has been upgraded to Vue 2.7 and the project has been restructured to fully enable TypeScript. The new project structure now enables much more advanced customizations without changing the core SDK code. See Developing the LiveOps Dashboard on how to get started with the new project structure.
This release requires a synchronized upgrade of the client and the server due to backward-incompatible changes in the networking protocol.
LogicVersion
and update the game client and server synchronously.The new Liveops Dashboard project structure requires a one-time manual migration of game-specific additions. Additionally, any imports from the core SDK need to be updated.
Entity schema migration has been refactored to be cleaner, more robust, and to work in Offline Mode as well as when importing entities vie the LiveOps Dashboard. The configuration is now applied to the model classes (eg, PlayerModel
) directly instead of the corresponding server-side actor class.
INFO
Note: If you have a Service Contract signed with Metaplay, all the breaking changes have been fixed already in the SDK upgrade pull request of your project. Otherwise, please see CHANGELOG.md
for a full list of changes, along with the HelloWorld and Idler samples for references on how to apply the changes.
StringId
s and MetaRef
s.PlayerModel
) and can be executed without the corresponding PlayerActor
. This enables running them in offline mode, and dry-runs when importing entities via the LiveOps Dashboard. See Entity Schema Versions and Migrations for more information.IPersistedEntity
classes to database tables. The database schema generation now scans for classes implementing IPersistedEntity
and automatically creates database table mappings for them, removing the need for adding entries in the MetaDbContext
derived class. The old method of declaring database table mappings in MetaDbContext
continues to be supported as well for backwards compatibility.GameConfigBuildTemplate
utility for configuring the game config build now provides default building of config entries for which no game-specifc build logic is required. The new GetEntryBuilder(Type configType, string entryName)
API can be used to override the building of individual entries when per-entry customizations are needed. When no build customizations are needed at all, the integration no longer needs to provide a IGameConfigBuild
class in the first place -- the SDK will default to using DefaultGameConfigBuild
.IRewardSource source
to MetaPlayerRewardBase.InvokeConsume()
for communicating information about the reward source to the consume function, when additional data is needed. The contents of the source information are up to the integration and are created by callbacks to the integration class MetaRewardSourceProvider
.Infrastructure and Helm chart compatibilities for this release:
infra-modules
version 0.2.0 or later for infrastructuremetaplay-gameserver
Helm chart version 0.4.0 or later for deploymentinfra-modules
version 0.2.3 or later for infrastructuremetaplay-gameserver
Helm chart version 0.4.1 or later for deploymentGuildModel.Tick
is now GuildModel.OnTick
.CloudCore.csproj
instead of Server.csproj
. PlayerModel
or GlobalState
). [SupportedSchemaVersions(oldestSupportedVersion, currentVersion)]
attribute and the individual migration methods the [[MigrationFromVersion(fromVersion)]
attribute.METAPLAY_ENABLE_JSON
define is removed and JSON support is assumed. METAPLAY_ENABLE_JSON
definitions should be removed.GameJsonContractResolver
is removed. Custom JSON formatters should be registered with the normal [JsonConverter(type-of-converter)]
on the target type.FooProperty
is serialized into fooProperty
) to match with server behavior. JsonSerialization
need to be checked for potential regressions.[IncludeOnlyInJsonSerializationMode(JsonSerializationMode.Default)]
is no longer included into AdminAPI (Dashboard) json serialization. For these cases JsonSerializationMode.AdminApi
should be used instead.PlayerModel.ServerOptions
is now MetaplaySDK.Connection.ServerOptions
.EnableGoogleAuthentication
is now false
by default and IT MUST BE MANUALLY SET TRUE IN PRODUCTION. GooglePlayClientId
is not longer defined directly but instead with GooglePlayOAuth2ClientCredentialsPath
which is a path or secretsmanager url into a OAuth client configuration JSON exported from Google Cloud Console. Additionally, a new option GooglePlayApplicationId
must contain the Google Play Application ID from the Google Play developer console.MetaDbContext
no longer has generics parameters for the persisted player and guild types. The concrete persisted type is automatically discovered from code. MetaDbContext
in GameDbContext
declarations.InitializeDatabase()
function in ServerMain.cs
.Platform
options is split to GooglePlayStore
and AppleStore
and the structure has changed: EnableGoogleAuthentication
is now ´false` by default and IT MUST BE MANUALLY SET TRUE IN PRODUCTION.GooglePlayClientId
is not longer defined directly but instead with GooglePlayOAuth2ClientCredentialsPath
which is a path or secretsmanager url into a OAuth client configuration JSON exported from Google Cloud.GooglePlayApplicationId
must contain the Google Play Application ID from the Google Play developer console.EnableAppleAuthentication
is now ´false` by default and IT MUST BE MANUALLY SET TRUE IN PRODUCTION.GAME_SERVER
define. NETCOREAPP
(or one of the UNITY_xxxx_y_OR_NEWER
) instead if you want to compile some code in client vs cloud projects (server or botclient).[TypeConverter(typeof(StringIdTypeConverter<T>))]
is no longer required or allowed in StringId type definitions, as string conversion is now enabled for all StringId types. IPlayerModelClientListenerCore.InAppPurchaseValidated
which is called when purchase validation completes either with status ValidReceipt or ReceiptAlreadyUsed. IPlayerModelClientListenerCore
, an implementation for this method needs to be added. The implementation can be empty if the game has no use for it.F64.ToString
now uses the normal double
formatting, instead of using the n6
format which produces thousand separators (commas).Config.env.yaml
files must parse without errors and warnings. METAPLAY_OPTIONS
to validate.Config.*.yaml
or other config sources, the last array definition is now chosen in its entirety. Previously all arrays were merged such that for each declared array element, the last element declaration for the array element index was chosen, and the array length was the maximum of all arrays. The resulting by-index merged array was then concatenated into the property's default value. [MetaReservedMembers(...)]
now forbids using member tagIds that haven't been reserved. This can be relaxed to the old behavior with [MetaAllowNonReservedMembers]
. [MetaAllowNonReservedMembers]
, or remove all [MetaReservedMembers(...)]
attributes from the type, as appropriate.InAppPurchaseEvent
's methods Clone
and CloneForHistory
now take a IGameConfigDataResolver
parameter, which should be the resolver in the containing PlayerModel
.MetaOfferGroupInfoBase
and MetaOfferInfoBase
now provide convenience constructors for populating data from the corresponding source config item base types. Integrations that customize the source types should now derive from MetaOfferGroupSourceConfigItemBase
and MetaOfferSourceConfigItemBase
rather than from the "Default" types.$type
fields in Dashboard no longer carry Assembly information. $backendApi
deprecated -> migrate to gameServerApi
module.this.root
was removed and other potential issues in customer code -> test well.$backendApi
deprecated -> migrate to gameServerApi
module.auth-tooltip
component renamed to meta-auth-tooltip
-> refactor imports.mainStore
renamed to coreStore
for consistency with the other modules -> refactor imports.<project>/Backend/Dashboard> npm run serve
instead of <project>/MetaplaySDK/Backend/Dashboard> npm run serve
meta-generated-view
has been refactored completetly and split into meta-generated-content
, meta-generated-card
and meta-generated-section
. Most related APIs have changed.makeVModelForm
helper method is no longer available.int[][]
or List<int[]>[]
).PlayerActorBase
and GuildActorBase
that default the corresponding persisted type to the SDK type. This allows removing some boilerplate in the common case of not needing to customize the persisted type.MetaplayerReward.Consume()
function for analytics purposes.MetaRef
s and StringId
s in generated forms. These will show a dropdown list based on the currently active gameConfig.MessageDirection.ClientInternal
and ServerInternall
) may no longer be in the shared code.Environment:SystemHttpListenHost
. Defaults to '127.0.0.1' when running locally (to only allow access from localhost) and '0.0.0.0' in the cloud (to allow Kubernetes to reach it).PlayerActorBase.ValidatePlayerName
into PlayerRequirementsValidator
.MetaplayOfflineOptions.PersistState
to false in your MetaplayClientOptions
.[MetaSerializable]
.IPersistedItem
classes are now automatically discovered from code, removing the need for declaring entries for the mapped classes in MetaDbContext
(or GameDbContext
for game-specific classes). The old style configuration of DbSet<>
fields in the context class has been preserved for backwards compatibility but will likely be deprecated in the future. Any IPersistedItem
concrete classes that don't have a corresponding old style DbSet<>
entry in the context class need to declare the database table name via a Table
attribute.GameDatabase
class when no custom queries are needed.METAPLAY_ENABLE_GUILDS
is deprecated. The guilds feature is now always built into the SDK assemblies.OrderedDictionary<>
error messages were improved to include the key/value of interest to make debugging easier.PlayerStateRequest/Response
has been replaced with generic InternalEntityStateRequest/Response
.{InitialPlayerModel}
in MetaplayClient.cs
and DefaultOfflineServer.cs
.Configs/Config.yaml
files) no longer tolerate and ignore unrecognized definitions. Unknown properties or subproperties are now a fatal error. Failing to parse a property value to the target datatype is a fatal error.AtomicFileReadWriteUtil
has been renamed to AtomicBlobStore
and includes a WebGL implementation on top of the browser's localStorage. localStorage is used to allow robust persisting of the player state when the tab/browser is being closed.MetaplayCoreOptions.ProjectName
is now included in the IndexedDB database name to reduce the chance of conflicts across multiple projects.ApplicationStateManager.cs
.--backend-dir
now defaults to Backend
rather than Server
, update CI scripts in light of this!MetaplaySystemHttpServer
to use ASP.NET. This fixes the ArgumentNullException
s that System.Net.HttpListener
can throw if requests are made during initialization.MetaRef<>
patterns.SpreadsheetContent.FilterColumns
throwing IndexOutOfRangeErrors on sparse Spreadsheet data.object[param1, param2]
) no longer break JSON serialization. The properties are automatically ignored and no longer need to be manually marked as Ignored.GoogleSheets:GameConfigSheetId
runtime option instead of a hardcoded id mistakenly added in release 19./sse
have been silenced.