Category Archives: Release History

Custom Entity GetEntityPage Improvement

The Challenge

Last week we became aware of a potential issue when using GetEntityPage() with owned entities.

The issue is related to how brainCloud handles ACL permissions. As you may or may not know, all entities in brainCloud support ACL permissions – and you can set the global accessibility of an object by setting the acl.other permission to one of the following:

  • 0 = no access
  • 1 = read-only access
  • 2 = read + write access

In loose terms, any object with acl.other != 0 is shared with (or accessible by) all users of the app.

This has large implications when dealing with Owned Custom Entities and the GetEntityPage() call – because by the previous default – the call would look for all entities that meet the search criteria that:

  • Are owned by the current user
  • Are accessible by the current user

Owned is simple – we simply add “ownerId”: <profileId> to the query provided by the developer.

Accessible is not so simple – the database must look at all of the objects that the player doesn’t own, and specifically examine each objects ACL to see if acl.other != 0 !!! This is incredibly slow, and exponentially so! Especially since 99.9% of the time, a developer is only looking for the entities owned by the current user!

Information

Note – this issue does not affect Unowned Custom Entities, Sys calls (which ignore permissions), or the Singleton API (which assumes objects must be owned by the current user). It only affects GetEntityPage() and GetEntityPageOffset().


The Solution

To address this issue, we are changing to the default behaviour of `GetEntityPage() so that it no longer considers shared entities (by default) for Owned Custom Entities.

Thus, a query with the following criteria will now only return objects that are owned by the current user:

{
  "pagination": {
    "rowsPerPage": 50,
    "pageNumber": 1
  },
  "searchCriteria": {
    "data.position": "defense"
  },
  "sortCriteria": {
  }
}

Going forward, if an app wants to modify this default behaviour to include accessible (i.e. shared) objects that are owned by other users – they can add the new ownedOnly: false option. For example:

{
  "pagination": {
    "rowsPerPage": 50,
    "pageNumber": 1
  },
  "searchCriteria": {
    "data.position": "defense"
  },
  "sortCriteria": {
  },
  {
  "options": {
    "ownedOnly": false
  }
}

Advice

Note also that your CustomEntity should include Custom Indexes that include the acl.other field for efficient queries where ownedOnly: false.


Compatibility Flag

Because this is a change to the previous brainCloud behaviour, we have introduced a new compatibility flag. When enabled, the following flag preserves the old functionality – where both objects owned and accessible by the user will be returned.

The new compatibility flag can be found in the Design | Core App Info | Advanced Settings page:

[ x ] Include shared objects in Owned Custom Entity GetEntityPage queries (warning: can be slow). Can be overwritten by specifying ‘ownedOnly’ in query context ‘options’.

When enabled, the default for ownedOnly is false – and when disabled, the default for ownedOnly is true.

Advice

Note that this compatibility flag, like all compatibility flags, is automatically enabled for existing apps (for backwards compatibility), and disabled for new apps.


We believe strongly that this new-and-improved GetEntityPage behaviour is the better + safer default – and thus highly recommend that all developers whose owned queries are only expecting objects owned by the current user go to this compatibility flag and immediately “uncheck” it to enable the new behaviour!

Remember – this option does not affect queries for Un-owned Custom Entities. It also does not affect Sys calls. So both of those scenarios will continue to return objects not owned by the current user – regardless of the compatibility setting.

If you have any questions – please reach out to the support team.

Cheers!

Reminder: Plus Plan restrictions

Advice

Note that basic RTT features are still available in the free Development plan. As before, Dev+ is only required for hosting and deep data features during development.

These changes apply to apps using Plus Plan features from the non-plus paid plans (i.e. Standard / Lite / Business).

A quick reminder that usage of the following features have always required activation of a Plus Plan for live apps:

  • RTT – used for Chat, Lobbies, Presence, etc
  • Hosting – spinning up custom Room and Relay Servers
  • Deep Data – used for Custom Entities and Messaging

In 4.9.5 (and earlier) there were scenarios where these restrictions were not being enforced.

We have addressed those scenarios in 4.10 – and as noted in the 4.10 release notes – we will enable the feature flag to begin properly enforcing these restrictions tomorrow – April 5th, 2022 – at approximately 9am Eastern.

Starting tomorrow, developers can expect that attempting to access these features (like enabling RTT, creating a custom entity, connecting to a chat channel, sending a message, etc.) without an active Plus Plan, will result in a run-time licensing error.

To quickly update your app to a plus plan, simply:

  • Navigate to Team | Manage | Apps
  • Select Change Plan from the action menu associated with the app
  • Click on the Plus Plans tab
  • Choose the plan to switch to
  • And click [Choose Plan]

brainCloud will then swap your app to the new plan.

Note that your charges will be adjusted automatically, with the first few days of April charged to the old plan, and the rest of the month charged to the new plan – with the live fees pro-rated accordingly.

If you have questions or issues, feel free to reach out via the support widget.

Release 4.10 is live!

brainCloud 4.10 adds new Security Options, an upgraded Cloud Code Engine, new Advanced Authentication calls, and more.

Compatibility

As always, brainCloud 4.10 aims to be 100% backwards compatible with previous releases. There are some changes/fixes that could affect existing apps:

Plus Plan Exclusive Feature Enforcement – We have discovered that in some scenarios, Plus Plan Features (i.e. RTT, Chat, Messaging, Custom Entities, etc.), can be accessed by live apps that are not on an appropriate plan. Release 4.10 addresses this issue. We will be enabling proper enforcement of Plus Plan restrictions starting Tuesday, April 5th. Please double-check that your app is on the correct plan before then!

Rhino 1.7.14 – there is a known breaking change in the new engine. It involves using the java-based (i.e. not javascript-based) java.util.HashMap()class from within a cloud code script. Our production searches indicate that no developers are using this class in production – and thus we are disabling support for that feature. But just in case – we are still noting it here.

Group and Group Entity ACL changes – there are fixes to how Groups and Group Entities handle ACL permissions, which may affect existing applications. To be safe, we have added a compatibility flag, “[x] Preserve legacy GroupEntity / Group ACL defect behaviour”, that preserves the old behaviour for existing apps by default.

Release Highlights

TLS Security Enforcement

We are hardening the security of our Public BaaS environment to enforce TLS 1.2 for all APIs.

Background

Up until now, we have accepted TLS 1.0 and 1.1 for API calls to ensure maximum compatibility for older apps. TLS 1.2 is well established now though, and we risk more by allowing 1.0 and 1.1 than we gain in backwards compatibility keeping them. Apologies to those devs that may be affected – but we must all march forward!

To facilitate a manageable transition – we have added an additional API endpoint to our public BaaS. So our public BaaS now supports:

  • api.braincloudservers.com – our new API endpoint that supports TLS 1.2 only… (we will further upgrade it to support TLS 1.3 as well when AWS supports it)
  • sharedprod.braincloudservers.com – this is our legacy endpoint that currently supports TLS 1.0, 1.1 and 1.2. This URL will be re-targeted to the same endpoint as api.braincloudservers.com starting June 7, 2022 ← approximately 90 days from now.

Note that other than the version of TLS enforced, these two endpoints function exactly the same. Your apps and players will not see any difference!

Our 4.10 client libraries have all been updated to use api.braincloudservers.com as the new default serverUrl for API calls. If you are using an older library, you can simply specify "https://api.braincloudservers.com/dispatcherv2" for the serverUrl parameter of the wrapper Initialize() call – see API Reference.

Once your app is calling the new endpoint, you can then go to the new Design | Core App Info | Security page, and set the minimum API TLS to 1.2. Careful though – this will mean that any calls to the older API endpoint (sharedprod.braincloudservers.com) will be rejected! ← because brainCloud cannot otherwise ensure that they were at least TLS 1.2.

Note that our RTT websocket endpoint is already enforcing a minimum TLS of 1.2. The raw TCP version of RTT however, which is used only for clients that cannot support WebSockets, is not encrypted. Setting Minimum RTT TLS Version to 1.2 thus disables the raw TCP connection option for your app. Note that both Unity and Unreal clients use the encrypted websocket implementation by default – so removing this option does not affect 99% of apps.

Information

Note – S2S and Builder APIs are also available via the new api.braincloudservers.com endpoint. It is recommended that all devs move to these endpoints at their earliest convenience.

Warning

Older libraries – Our tests indicate that our older libraries should support TLS 1.2 – but we haven’t been able to exhaustively test across all client platforms. As always, it is recommended that developers keep pace with the latest brainCloud libraries for maximum performance and reliability.

Migration options

In summary, brainCloud 4.10 allows developers to bump up the minimum level of TLS for client APIs. Developers have two options on how they would like to migrate:

  1. Do nothing – If you do nothing, your app will automatically be upgraded to TLS 1.2 starting on June 7, 2022 when sharedprod.braincloudservers.com merges with api.braincloudservers.com and begins enforcing a minimum TLS of 1.2.
  2. Migrate early – For developers wanting to improve their app security now, the new API and security settings provide the means to de-risk and accelerate the migration – which is definitely convenient for devs maybe going through Facebook’s Privacy Checklists for example. The recommended approach is:
    1. Reconfigure your app to talk to api.braincloudservers.com – either by updating to the 4.10 libs – or overriding the serverUrl parameter in wrapper Initialize().
    2. Confirm that your app works just fine
    3. Release the updated build of your app – so that you can get the majority of your player base migrated over
    4. Set the minimum client version of your app to force upgrades for any stragglers.
    5. Adjust the TLS settings of your app to require TLS 1.2. You are done!

Pro-tip

One final note – the api.braincloudservers.com endpoint is actually ready now – before the official 4.10 release. So you don’t have to wait to start migrating your apps to the more secure endpoint. Start today!

Cloud Code Engine Upgrade

We have upgraded the Mozilla Rhino Engine from 1.7.13 → 1.7.14.

This brings with it support for the following Javascript features:

  • Template Literals!
  • Promise Support (Requires app to be set to ES6)
  • Error stack traces!

And more!

For the full details, see the Rhino 1.7.14 Release Notes.

Advanced Authentication

Developers of certain categories of apps have long asked for the ability to register a new user, and set default attributes, etc. for that user during the initial Authentication call. This is not possible with the existing Authentication calls – so we have added a new set of calls to satisfy this use case. 

The new AuthenticateAdvanced() call allows the developer to include an extraJson payload with the authentication call, which can then be picked up by pre- or post- API hooks for additional processing as the account is created.

Note that for simplicity, all authentication types are handled by the single AuthenticateAdvanced() call – similar to how the API Explorer works… Corresponding Merge() and Detach() calls have been added to the Identity service as well.

Group and Group Entity Enhancements

We have done a full review of our Group and Group Entity code, and found some areas that warranted improvements. The following changes/fixes have been made:

  • Improved handling of ACL permissions – In particular, some GroupEntity operations were being gated via the Group ACL instead of the Group Entity ACL! Note that there is a compatibility flag to preserve the old behaviour.
  • Improved concurrency handling – we have improved the locking of several key methods – including managing group membership.
  • Added missing Group “Sys” API call – Added Sys implementation for SysRemoveGroupMember()
  • New SysGetRandomGroupsMatching() call – this is a more useful implementation of the GetRandomGroupsMatching() call – which is hampered by ACL permissions not allowing the API to return full details of groups that the user is not a member of. We would recommend that in most use cases, it is more correct to use SysGetRandomGroupsMatching() than GetRandomGroupsMatching() – though like all Sys calls, SysGetRandomGroupsMatching() is not available directly via the client API – so you’ll need to call it via a cloud code script.
  • Updated ReadGroupMembers() and SysReadGroupMembers() calls to return a user’s summaryFriendData

Additional Features

  • Unreal Relay communications – we have completely re-written Unreal relay communications for this release. In addition, we have created an Unreal-based Relay Tester app to demonstrate the usage of the relay server APIs.
  • Improved credential checks – we have added improved versions of getProfileInfoForCredential() and getProfileInfoForExternalAuth() that don’t unnecessarily log an error if the credential isn’t found. This is handy for use cases where a credential not being found is normal – and isn’t worth flagging as an error in the logs. The new methods are:  getProfileInfoForCredentialIfExists() and getProfileInfoForExternalAuthIfExists()
  • Faster file deployments – brainCloud will now copy multiple files in parallel during app deployments. This should have a noticeable reduction in deployment times for some apps.
  • Ultra authentication – brainCloud APIs now support user authentication for apps on the Ultra.io platform. 
  • Unity Chat – a new Unity Chat example app has been created. You can find the source for it here:
    https://github.com/getbraincloud/examples-unity/tree/develop/BC-Chat
  • Unreal Relay Test – a new Unreal Relay Test example app has been created. You can find the source for it here:
    https://github.com/getbraincloud/examples-unreal/tree/master/RelayTestApp

Plus 4.9.5 Patch items

The following additions were technically included in 4.9.5 patches – but are described here for completeness:

  • Illegal file types – Developers are no longer allowed to upload certain file types. Currently disallowed extensions are: html,htm,jsp,php,bat,cmd,exe,js,pif,ps1,scr,vb,vbe,vbs
  • SysUpdateEntityFieldSharded() call – added new SysUpdateEntityFieldSharded() call for use with sharded Custom Entity Collections. This is because the existing SysUpdateEntityField() will not work for owned custom entities once sharded.
  • Improved Room and Relay Servers – improved handling for long-lived lobbies with join-in-progress servers.
  • Improved RTT connection handling – improved handling of RTT connection disconnects. 

Portal Changes

We have made the following portal changes:

Design 

  • Core App Info | Advanced Settings
    • Added a new compatibility flag to preserve the old (and incorrect) GroupEntity / Group ACL behaviour. By default this flag is enabled for existing apps – but it is recommended that devs review their apps and clear this flag when possible.
  • Core App Info | Security
    • This new screen allows devs to customize the security settings of their apps. For more information, see the TLS Security Enhancements section above.

Monitoring

  • Global Monitoring | Custom Entities
    • Improved performance when showing all entities for a custom entity collection with tons of entities.
  • Global Monitoring | Recent Errors
    • Fixed an issue that would cause logs to show the wrong relative date in certain timezone situations.

Reports

  • Reporting | Analytics
    • The Dormant Users statistics table has been updated.
  • Reporting | API Usage
    • Fixed an issue displaying usage stats for games with > 2.1 Billion game sessions.

General

  • Unlocking apps – Unlocking a live app (via the Live Lock Banner) now requires the developer to type the name of the app, not the developer’s password. This is more in tune with the original design intent for the banner (which was to ensure the developer is aware of which particular version of their app (production, development, etc.) is being changed) – and interacts better with the PortalSSO integrations of private licensee’s brainCloud instances.

API Changes

The following changes/additions have affected the brainCloud API:

  • Authentication
    • New AuthenticateAdvanced() call that allows extraJson payload to be included with player authentication / registration
    • New AuthenticateUltra() call allows apps to authenticate with the Ultra.io platform
  • Custom Entity
    • New methods UpdateEntityFieldsSharded() and SysUpdateEntityFieldsSharded() are sharding-safe implementations of the older UpdateEntityFields() and SysUpdateEntityFields() methods. The non-sharded versions of these methods are now recommended only for custom entity collections that you know you will never want to shard in the future (i.e. small, probably static collections).
  • Friend
    • The new getProfileInfoForCredentialIfExists() and getProfileInfoForExternalAuthIfExists() methods behave just like getProfileInfoForCredential() and getProfileInfoForExternalAuth() respectively – except that they don’t log errors if the credentials don’t exist. Handy and cleaner for many use cases.
  • Group
    • New SysGetRandomGroupsMatching() call is a more convenient version of GetRandomGroupsMatching() – which eliminates the need to give read-only access to “other” users.
    • Added new S2S + cloud code only method: SysRemoveGroupMember()
    • Updated ReadGroupMembers() and SysReadGroupMembers() to return a user’s summaryFriendData
    • Improved concurrency handling
    • Improved handling of ACL permissions; behaviour changes are gated by a new compatibility flag.
  • Group Entity
    • Improved concurrency handling
    • Improved handling of ACL permissions; behaviour changes are gated by a new compatibility flag..
  • Identity
    • New cloud code only GetIdentityData() call allows apps to retrieve additional information regarding a specific player identity. Currently only supported for the new Ultra authentication.
    • New Advanced identity methods: AttachAdvancedIdentity(), DetachAdvancedIdentity(), MergeAdvancedIdentity()
    • New Ultra identity methods: AttachUltraIdentity(), DetachUltraIdentity(), MergeUltraIdentity()
  • RTT
    • EnableRTT() now fails if the app’s plan does not support RTT. Note that this is a server-side check, and is not limited to the 4.10 client library.

We have attached warnings in the API docs to the following methods:

  • Custom Entity
    • UpdateEntityFields() and SysUpdateEntityFields() – These methods are not sharding safe – and thus are not recommended for custom entities that you may want to shard for greater performance and scalability in the future. Consider using UpdateEntityFieldsSharded() and SysUpdateEntityFieldsSharded() instead.

Miscellaneous Changes / Fixes

  • Updated libraries
    • All libraries have been updated with the new serverUrl and the latest APIs. Go get ’em!
  • Documentation updates
    • API reference has been updated with the latest API changes.
  • Important Fixes
    • [BCLOUD-1508] Fix for broken RTT disconnects
    • [BCLOUD-1508] Fix for broken RTT disconnects
    • [BCLOUD-1565] Dormant User Analytics changes: Users now only considered dormant if inactive > 365 days
    • [BCLOUD-1534] [Fixed] Can’t turn off Facebook Limited Login Friends once turned on
    • [BCLOUD-1530] [Fixed] Design Portal Error log entry displayed date is not accurate
    • [BCLOUD-1378] Add missing API Hooks for RedemptionCode service
    • [BCLOUD-266] [Fixed] RTT DISCONNECT message not passed to the user
    • [BCLOUD-35] [Fixed] Relay C++ UDP ping sent before CONNECT
    • [BCLOUD-1535] Add missing Sys Group API (SysRemoveGroupMember)
    • [BCLOUD-1525] ItemCatalog service missing some cloud code SYS calls
    • [BCLOUD-1298] [BuilderAPI] Fixed NPE when request does not contain a content-type
    • [BCLOUD-1531] Improved error message (and logic) for launching hosted servers when a region is not supported
    • [BCLOUD-1515] [Fixed] Apps with billing plans with RTT disabled should not be able to send chat messages or make rtt connections
    • [BCLOUD-1587] [Fixed] Group has two members having role of OWNER
    • [BCLOUD-1387] [Fixed] User Monitoring – Login as User should set user’s languageCode and countryCode on created PlayerSession
    • [BCLOUD-1394] Return Catalog Item Definition name and/or description in app’s default language if none for user’s language for User Item with metadata flagged true
    • [BCLOUD-1393] Added missing support for getRunningOrQueuedCloudScripts Sys API on ScriptS2SServiceProxy
    • [BCLOUD-1331] Group APIs for Group Entity should enforce Group Entity ACL, not Group ACL
    • [BCLOUD-1331] Speed up SysIncrementGroupEntityData and SysUpdateGroupEntityData calls by avoiding Group lookup (only required for the equivalent non-Sys calls)
    • [BCLOUD-1402] [Fixed] Messaging Sys APIs not allowing version -1 for any version
  • Plus miscellaneous fixes and performance enhancements…

brainCloud Atlas migration – Feb 22-23, 2022

Warning

tl;dr Developers will be unable to deploy or import/export application changes from Feb 22, 2022 at 11am Eastern until Feb 23, 2022 at 11am Eastern.

See remainder of announcement for additional restrictions.

Background

On February 22nd and 23rd, we will be migrating brainCloud’s core database cluster from VM-hosted MongoDB instances to MongoDB’s Atlas service.

This is a live migration – intended to accomplish the migration of all app and player data – with minimal service interruption.

Player-visible Service Impacts

Depending upon the features your app uses, the following service impacts may be noticeable by your players:

  • Lobbies and Hosted Servers delays – lobby processing and launching of hosted servers will experience some performance delays during the cut-over period. We hope to keep this period of reduced performance to ~10-20 minutes — between the hours of 05:00 and 07:00 Eastern on Feb 23, 2022.
  • Delayed Push notifications – new push notification jobs started during the cut-over period may experience delays
  • Scheduled Jobs – scheduled cloud code jobs may experience small delays during the initial cut-over period.
  • Stale Segments – The nightly Segment Refresh job will not run the night of Feb 22, 2022. This could mean that a player that newly qualifies for a segment wouldn’t be considered part of it – for a segment targeted Push Notification run, for example. Note that an individual player’s segments will still refresh when they log in — so any Store pricing shown to players will still accurately reflect any applicable promotions.

Temporary Restrictions

For data integrity reasons, we cannot allow any changes to the database schema (i.e. new/removed collections or indexes) during the migration period – so certain brainCloud features will be disabled. We also need to disable (i.e. temporarily remove) all TTL (Time To Live) indexes — so certain objects will stick around past their normal expiry periods.

These restrictions translate to the following brainCloud limitations:

  • For safety, we will also be disabling the ability to Deploy or Import/Export apps during the entire migration period.
  • If creating a new app in brainCloud, the leaderboard collection for that app will not be created (until after the migration period)
  • If introducing support for leaderboards in your app for the first time, posting scores will not be supported until after the migration
  • TTL indexes for all core and custom collections (i.e. Custom Entities, Messages, etc.) will be removed. This means that some objects may stick around for up to one day later than they otherwise would
  • Developers will not be able to create new Custom Entity collections.
  • Developers will also not be able to create new Indexes on Custom Entity collections
  • If Messaging is newly enabled for an app, messages cannot be sent until after the migration

Thus, the following screens in the Design Portal will be disabled during the migration period:

  • Design | Core App Info | Admin
  • Design | Cloud Data | Custom Entities

Also – to ease the amount of data changes to migrate, we will be disabling Segment Processing for the night of Feb 22nd only.

Detailed Schedule

The planned schedule for the migration is as follows. Interim times are intentionally conservative. If the migration is proceeding well, some steps will happen earlier than stated here.

  • Feb 22 11:00 Eastern – Start migration prep
    • Notify developers (via banner) that migration is starting
    • Disable collection creation
    • Disable the Admin Tools and Custom Entities design screens
    • Disable Segment Processing
    • Prep the source database cluster (i.e. disable balancer and remove TTL indexes)
  • Feb 22 13:00 Eastern – Start bulk migration
    • The background bulk copy processes will begin
  • Feb 22 22:00 Eastern – Start sync
    • The bulk migration should be complete
    • The system now goes into sync mode – syncing oplog changes in realtime between the old and new clusters. Note that it will take several hours for the new clusters to catch up to the latest changes being applied to the old clusters
  • Feb 23 04:00 Eastern – Validate data + indexes
    • Validate the results of the migration. May involve rebuilding key indexes
  • Feb 23 06:00 Eastern – Start cut-over
    • Cut-over the brainCloud servers from the old database to the new database.
    • Certain background processes will be scaled down during the cut-over. This will delay the processing of certain background tasks, like scheduled jobs, push notifications, etc. Those jobs will be processed once the servers spin back up on the new cluster.
  • Feb 23 09:00 – Finalize migration
    • Validate health of all processes
    • Disable sync process
    • Re-enable balancer and re-add TTL Indexes
  • Feb 23 11:00 – Migration complete
    • Re-enable collection creation
    • Re-enable brainCloud screens
    • Re-enable Segment processing
    • Remove banner

FAQ (Frequenty Asked Questions)

Why is brainCloud moving to MongoDB Atlas?

Moving to Atlas will offload the low-level server and software maintenance responsibilities from brainCloud DevOps personnel. It means less work keeping the servers secure, up-to-date and running properly – but also means that performing common operations like software upgrades, vertical and horizontal scaleouts, etc. are all handled automatically.

There are also benefits to monitoring the performance of the database — and a recommendations engine that brainCloud is considering leveraging for future Custom Entity enhancements.

Will my players or developers notice any changes once the system is running on Atlas?

No.

Will my players or developers notice any changes during the migration to Atlas?

Potentially. See the Player Visible Service Impacts section above.

What if something goes massively wrong during migration?

If the migration appears compromised in any way, we will abort. The database will remain on the existing servers – and we will reschedule the migration for a future date.

Information

If you have further questions or concerns, please reach out to brainCloud Support via the chat widget.

brainCloud and log4shell (CVE-2021-44228)

As you are likely aware, a serious vulnerability has been discovered in Apache Log4J 2, a very popular logging library for Java services. This attack is informally referred to as log4shell, presumably due to the way it allows an attacker to make privileged JNDI calls via the logging of simple input data from an API or web form.

We are pleased to report that brainCloud’s Production Services are unaffected by this vulnerability – and that we have further patched our services to completely eliminate any future risk of attack.

More specifically:

  • brainCloud’s API and Portal services do not use Log4J 2 – and are thus not affected by log4shell.
  • Some secondary Datastream and RTT services do use Log4J 2 – but these services do not log raw input data in our Production configuration – and thus, once again – are not affected by log4shell.
  • To completely eliminate any future risk of exposure, we have now patched all services that use Log4J 2 to version 2.16.0, which disables the compromisable functionality.

The security of your apps and user data is of utmost importance to us. Thank you for trusting your business to brainCloud!

brainCloud 4.9.5 is live!

brainCloud 4.9.5 is the last release of 2021, and targets a few key customer requests and performance and reliability improvements.

Release Highlights

Profanity Check Improvements

We have improved the built-in filtering of our WebPurify integration – so that devs can now choose to filter a user’s chat messages, and updates to their name, by their own language only (instead of against all configured languages).

You will find the new options:

  • on the Design | Integration | Manage Integrations screen for the player name settings
  • on the Design | Messaging | Chat screen for the chat message settings

Additional improvements

  • Async Match improvements – Deleting a player will now automatically abandon any asynchronous matches that they have in progress
  • Entity call improvements – added a new _serverTime field to the JSON responses of most get entity calls – as a convenience to client devs
  • Friend service improvements – more reliable retrieval of friend data across multiple social platforms ← a failure to retrieve friends from one service will no longer abort retrieving from the remaining services.
  • Leaderboard rotation improvements – Improvements to concurrency handling during Leaderboard rotations and Tournament processing
  • Lobby matchmaking – improved matchmaking performance under heavy loads
  • User batch processing – improved handling of larger data bundles during batch processing

Portal Changes

We’ve made the following portal improvements:

Design Section

  • Integrations | Manage Integrations
    • WebPurify – Added new options for improved targeting of languages for name profanity checks
  • Multiplayer | Chat
    • Added new options for improved targeting of languages during chat profanity checks
  • General
    • Adjusted the line-height of several components used in some log screens to address issue with low-hanging font characters being cut off

API Changes

The following changes/additions have affected the brainCloud API:

  • CustomEntity service
    • Added a _serverTime field to the ReadEntity(), ReadSingleton(), SysReadEntity(), GetEntityPage(), GetEntityPageOffset(), and GetRandomEntitiesMatching() responses
  • [User] Entity service
    • Added a _serverTime field to the GetEntitiesByType(), GetEntity(), GetList(), GetPage(), GetPageOffset(), GetSharedEntitiesForProfileId(), GetSharedEntitiesListForProfileId(), GetSharedEntityForProfileId(), GetSingleton() responses
  • GlobalEntity service
    • Added a _serverTime field to the GetList(), GetListByIndexedId(), GetPage(), GetPageOffset(), GetRandomEntitiesMatching(), GetSystemEntityList(), GetSystemEntityPage(), GetSystemEntityPageOffset(), ReadEntity(), ReadSystemEntity() responses
  • Group service
    • Added a _serverTime field to the ReadGroupEntitiesPage(), ReadGroupEntitiesPageByOffset(), ReadGroupEntity(), SysReadGroupEntitiesPage(), SysReadGroupEntitiesPageByOffset(), SysReadGroupEntity() responses

Miscellaneous Changes / Fixes

  • Updated libraries
    • There are no new client APIs in this release.
    • There have been several client lib patches over the past month though – so be sure that you are using the latest!
  • Plus miscellaneous fixes and performance enhancements…

brainCloud 4.9 is live!

brainCloud 4.9 is a massive update with a hat-trick of new Multiplayer / Hosting Features – plus Unity Compression and some highly requested Marketplace and Management APIs. We hope you like it!

Warning

This release features an update to path handling for the bridge.callScript() method to ensure that called script paths are treated as relative to the calling scripts paths. This aligns with the path handling of the bridge.include() import mechanism – and makes for more maintainable and portal script modules. See Updated Script Path Handling for more information.

Release Highlights

Amazon GameLift Support!

We are pleased to announce that brainCloud now supports Amazon GameLift.

This means that you can enjoy all the benefits of brainCloud multiplayer – with our online matchmaking and lobby services – but with the flexibility of running and hosting your own server fleets in GameLift.

This is especially helpful in scenarios where:

  • You already have game servers running in GameLift
  • Your game needs the performance boost provided by GameLift’s non-containerized architecture 
  • You want to lower costs with GameLift’s ability to utilize AWS Spot Instances

The best part is that once you configure it – there are almost no changes to your client code. The only difference is that the connectData information returned to the client will specify a protocol type of gamelift.

JSON

Information

Note that GameLift hosting is priced differently than standard brainCloud hosting. brainCloud will charge the equivalent of 5 API Calls per player added to your GameLift servers.

This is independent of the costs that Amazon will charge you directly, of course.

Join in progress!

Speaking of brainCloud lobbies and matchmaking – brainCloud 4.9 adds support for backfilling of matches – which means that new/replacement players can finally be added to matches in progress!

Note that the room server should use the SysGetLobbyMember() call to validate the legitimacy of any players attempting to join the Room Server after the match starts.

Retrieve List of Lobbies

To complete our multiplayer hat-trick, developers can now query the list of active lobbies in a game. This is useful for games providing a more classic multiplayer experience.

Simply pair the new GetLobbyInstances() and GetLobbyInstancesWithPingData() calls with the existing GetLobbyData() and JoinLobby() calls to implement your own old-school lobby system!

AppStore Item Purchases

At long last, Marketplace Products can now include Inventory Items. This means users will be able to acquire your game’s “Magic Wand of Silly Walks” directly through an in-app purchase!

Unity Client Compression

The Unity Client now officially supports compressing of client ↔︎ server messages.

Sending large API requests/responses takes time – especially under mobile conditions. With a pair of flags, you can enable compression for faster processing of brainCloud requests. This can also reduce the occurrence of network timeouts that can happen when sending/receiving larger requests.

brainCloud’s compression support is intelligent – and only kicks in if the message bundle to be transmitted is greater than a size threshold – which defaults to 50Kb. Any messages sent/received above that threshold will be compressed (and uncompressed) automatically and transparently to your app.

Note that compression is disabled in the 4.9 Unity Client by default.

To enable compression of both requests and responses, call:

C#

Updated Script Path Handling

We have updated brainCloud’s handling of paths for the bridge.callScript() method to make it more consistent with industry standards (and our own bridge.include() method).

Before this change, if brainCloud were running script /subFolder/myScript.ccjs – the following two calls would look for their files in different directories:

  • bridge.include("myImportFile.ccjs") ← would look for myImportFile.ccsj in the current directory of the calling script – i.e. “/subFolder” ✅
  • bridge.callScript("myUtilityScript.ccjs", {}) <- would look for myUtilityScript.ccjs in the root! ❌

With this change, the two calls use the same algorithm to determine the referenced script.

As you would expect, we have introduced a new compatibility flag that controls this improved behavior. The new [x] Use legacy script path handling flag, if enabled, preserves the old functionality. This flag is enabled by default for all existing apps, and disabled by default for newly created apps.

Information

Important – this change does not affect the functioning of ScriptServiceProxy.runScript(). As that method mimics the Client API call – it always assumes that it is running from the root. We highly recommend that devs use bridge.callScript() instead of ScriptServiceProxy.runScript() from within scripts.

Tournament Management APIs

We have expanded our Sys APIs to support Tournament Management.

This includes new cloud-code only APIs for:

  • Managing Tournament Templates
  • Enabling Tournaments for a Leaderboard Config
  • Editing Tournament details for current and future periods

In addition, we have added new methods for more efficiently retrieving the list of leaderboards, and retrieving leaderboard details. See the API Changes section for more details.

Additional Improvements

This release also includes the following:

  • $text query support
    • the query syntax for Custom Entities has been extended to support MongoDB $text queries.
  • Improved RTT connection id handling
    • The Relay Server Protocol protocol (and the Relay Server and Client Libraries that implement it) have been enhanced for more consistent usage of RTT connection IDs – basically, the protocol now uses profileIdCx ids instead of just profileId
    • There is a new compatibility flag, [x] Include legacy lobby owner field in API output, that when enabled ensures that this new behavior still works with old clients. This flag is enabled by default for all existing apps, and disabled for newly created apps.
  • Additions / Improvements to the Builder API
    • Support for API Hook management
    • Support for basic Team Member management
  • Improvements to Async Match APIs
    • We are now returning handy summaryFriendData for players in more of the AsyncMatch calls – including FindMatches(), FindCompleteMatches() and ReadMatch()
  • Additional HTTP Client methods
    • Support for HTTP PATCH, DELETE, and HEAD commands
  • External Authentication enhancements
    • Ability to return additional information with authentication results
    • For more info – see the new authPayload and extraErrorJson fields documents in the API Docs.

Portal Changes

Design

  • Core App Info | Advanced Settings
    • Added new compatibility flag: [x] Include legacy lobby owner field in API output. Enabled for existing apps by default. See Improved RTT Connection ID handling for more information.
    • Added new compatibility flag: [x] Use legacy script path handling. Enabled for existing apps by default. See Updated Script Path Handling for more information.
  • Cloud Code | My Servers
    • The new GameLift Room Server option has been added.
  • Cloud Code | Scripts
    • When dealing with live apps, the Script Editor will no longer allow portal users to start editing a script before unlocking the app — instead of just refusing to save the changes! A small but useful improvement!
  • Custom Config | Legacy Files
    • The old Files page has been fittingly renamed to Legacy Files.
  • Integrations | Manage Integrations
    • A new AWS GameLift Integration section has been added.
  • Leaderboards | Leaderboard Configs
    • We have added a search box for filtering the list of leaderboards. Super useful for those apps with tons of leaderboards!
  • Marketplace | Products
    • Added the ability to add Items as reward items for in-app purchase products.
  • Multiplayer | Lobbies
    • Added new options to the Rules page for lobbies:
      • Disband on start (default) – lobbies will be terminated when the game starts. This flag is enabled by default for existing apps.
      • Allow join in progress – allows players to join games that are already in progress (i.e. backfilling)

Team

  • Manage | Apps
    • We’ve added an app’s appId (in parenthesis) to the list for easy reference
    • We’ve also added a new Last Updated field – so it is easier to see which apps have been edited recently. Note that we have also updated how some of our nightly processes work with the updatedAt field of the game record – so that going forward, apps are not considered to be “updated” when our back-end billing processes run.

API Changes

The following changes/additions have affected the brainCloud API:

  • AsyncMatch Service
    • We have added user summary data to the results returned by CreateMatch(), SubmitTurn(), FindMatches(), FindCompleteMatches(), ReadMatch() and UpdateMatchSummaryData().
  • Client Service (Unity Only)
    • Call the new EnableCompressedRequests()and EnableCompressedResponses() methods to enable compression.
  • Global App Service
    • New ReadSelectedProperties() and ReadPropertiesInCategories() methods allow the app to retrieve a subset of the app’s global properties instead of all of them.
    • We have also added new S2S and cloud-code only methods for creating properties: SysCreatePropertyString() and SysCreatePropertyJson()
  • Group Service
    • New cloud-code only SysIsGroupMember() call for testing group membership.
  • HTTPClient
    • Added support for HTTP PATCH: PatchJsonResponseJson() and PatchTextResponseText()
    • Added support for HTTP DELETE: DeleteJsonResponseJson() and Delete()
    • Added support for HTTP HEAD: HeadRequest()
  • Leaderboard Service
    • New PostScoreToDynamicGroupLeaderboardDaysUTC() call allows for the dynamic creation of group leaderboards with a DAYS rotation.
    • New SysCreateLeaderboardConfig() and SysEditLeaderboardConfig() methods are updated versions of the older SysCreateLeaderboard() and SysEditLeaderboard() methods – with the ability to edit tournament settings. The old methods continue to be available (they are not deprecated).
    • New SysListLeaderboardConfigs() and SysGetLeaderboardConfig() methods for more efficient retrieval of summary information vs. leaderboard details, respectively.
    • New APIs for editing tournament period settings on leaderboards: SysEditTournamentSettingsForFuturePeriodsOnly() and SysEditTournamentSettingsIncludingCurrentPeriod(). Note that you would usually only edit future periods – because you don’t want to change the rules of a tournament that is already underway – that seems unfair! :slight_smile:
    • New APIs for editing adhoc tournament periods – SysCreateAdhocTournamentPeriod(), SysEditAdhocTournamentPeriod(), and SysDeleteAdhocTournamentPeriod()
  • Lobby Service
    • Added new GetLobbyInstances() and GetLobbyInstancesWithPingData() calls to return the list of available lobbies. Pair with the existing GetLobbyData() and JoinLobby() calls to implement your own old-school lobby system!
  • Tournament Service
    • New management calls – SysListTournamentTemplates(), SysCreateTournamentTemplate(), SysEditTournamentTemplate(), SysReadTournamentTemplate() and SysDeleteTournamentTemplate().
  • User Service
    • A number of Sys methods that were missing from the S2S proxy have been added

Miscellaneous Changes / Fixes

  • Updated libraries
    • All libraries have been updated with the latest API changes. Go get ’em!
  • Documentation updates
    • All of the new API calls have been added to the API Reference
  • Important Fixes
    • BCLOUD-792 – JS S2S Heartbeat doesn’t work – fixed.
    • BCLOUD-799 – User Batch Script processing issue with PlayerSession API version causing Leaderboard API errors
    • BCLOUD-945 – REDIS lag causes issues when scripts are moved between folders
    • BCLOUD-980 – Scripts in the root folder are not being cleared when restored to checkpoint
    • BCLOUD-981 – Add protection for PlayerStatistics experience points from going negative
    • BCLOUD-982 – Add more input validation for Tournament rewards input for GlobalGameStatistics and/or PlayerStatistics stat names
    • BCLOUD-998 – Add support for $text operator text query document fields
    • BCLOUD-1057 – Locks with no player session context not unlocking properly
  • Plus miscellaneous fixes and performance enhancements…

GameSparks to brainCloud migration notes

brainCloud is an excellent option for developers looking to migrate their app and players before GameSparks shuts down on September 30, 2022.

GameSparks developers will find that the brainCloud feature set and technology platform align well with what they are already used to.

Major advantages of migrating to brainCloud include:

  • Cloud code – brainCloud’s cloud code system utilized JavaScript, is based on Mozilla Rhino, uses JSON parameters, and allows synchronous access to the full brainCloud API.
  • Cloud data – brainCloud uses NoSQL MongoDB for persistent data storage.
  • Chat & Messaging – brainCloud’s RTT (Real-time Tech) service provides support for Chat (both Global and Group channels) and player-to-player Messaging
  • Downloadables – brainCloud supports Downloadables and Uploadables, with built-in CloudFront CDN support
  • Email – brainCloud provides a SendGrid integration for email
  • Leaderboards – brainCloud rich leaderboard system directly supports everything but leaderboards partitions – and partitions can be emulated via separate, dynamically created leaderboards.
  • Multiplayer – brainCloud provides support for hosted Room and Relay Servers, and beginning in 4.9 supports Amazon GameLift as well!
  • Teams – brainCloud’s Group service provides support for teams – including team chat and leaderboards
  • Virtual Currencies and Virtual Goods – brainCloud supports them both, along with purchasing both from the AppStores.
  • And much, much more!

This document provides instructions and tips for migrating your app from GameSparks to brainCloud.

Click on the collapsable table-of-contents to jump to a section.

Achievements

brainCloud supports standard achievement functionality: short name (id), title, description, and platform-specific achievement IDs. Devs can also attach a collection of key+value pairs for additional metadata.

In brainCloud, Achievements are cosmetic – they do not deliver additional rewards (such as Virtual CurrenciesPlayer XPUser StatisticsVirtual Goods, etc.).

brainCloud does provide a Milestone system, however, that can be used to trigger such awards – including Achievements themselves. Milestones are configured to watch User Statistics and trigger automatically when specified thresholds are exceeded. Milestones can award AchievementsVirtual CurrenciesPlayer XPUser Statistics, and Global Statistics

Milestones do not currently award Product Items; that feature is coming in an upcoming release. This functionality can however be easily achieved with custom code by attaching the product item id to the Achievement’s metadata.

brainCloud does not have Leaderboard Triggers – but you can attach a custom Cloud Code script to any API Call via the API Hooks feature. So for example, a PostSuccess API Hook on the PostScoreToLeaderboard() call can achieve a similar result.


Authentication Basics

brainCloud supports a rich set of authentication types (also called Identity Types).

The equivalent of GameSpark’s Device Authentication is brainCloud’s Anonymous ID. This is a generated GUID that is stored on the player’s device.

Authenticating anonymously is as simple as calling the brainCloud Wrapper’s AuthenticateAnonymous() call. 

bool forceCreate = true; // Creates the account if it doesn't already exist
SuccessCallback successCallback = (response, cbObject) =>
{
    // Continue with launching the app
    // ...
};
FailureCallback failureCallback = (status, code, error, cbObject) =>
{
    // An error occurred
    // Pop up a dialog for the user to retry?
};

_bc.AuthenticationService.AuthenticateAnonymous(forceCreate, successCallback, failureCallback);

Registration

brainCloud also supports both Univeral Identity (username + password) and Email Identity (email address + password) authentication.

To register their account, the app simply attaches the desired identity type to the player’s account. For example, the following code attaches a Universal Identity to the account.

bc.IdentityService.AttachUniversalIdentity( 
    userId,
    password,
    SuccessCallback, FailureCallback);

Authentication

Once a higher form of identity has been attached to the account, the app can login using that identity via the appropriate authentication calls. For example, to login via the Universal Identity:

_bc.AuthenticationService.AuthenticateUniversal(
    userId, 
    password, 
    forceCreate, 
    successCallback, 
    failureCallback);

Authentication (3rd Party)

brainCloud supports Sign in With Apple, Facebook Login, Google Play, Google OpenId, Oculus, and more.

From a code perspective, all work basically the same:

  • The app uses the appropriate Platform / 3rd Party SDK to authentication the user
  • The app then passes the authentication information returned from the SDK to brainCloud (via the appropriate authentication mechanism
  • brainCloud validates the authentication is legit – and then looks up the user’s account and/or creates a new account as directed (according to the “forceCreateoption)

For example, the call for Sign in with Apple is:

_bc.AuthenticationService.AuthenticateApple(
    appleUserId, 
    identityToken, 
    forceCreate, 
    SuccessCallback, 
    FailureCallback);

Tutorials for configuring brainCloud and the 3rd party system can be found here:


Chat & Messaging

brainCloud supports both Chat and Messaging as part of its RTT (Real-time Tech) offering. RTT enhances brainCloud’s standard request+response API with an additional WebSocket connection to the server for bi-directional real-time communications.

Chat

In brainCloud, Chat messages are directed to channels, not users. Channels have an ID and a rolling history. Active listeners of a channel are notified in real-time when new messages are posted.

brainCloud supports Global, Group (i.e. Clans or Teams) and Dynamic Channels. brainCloud also supports Lobby Chat – though technically that is achieved through a separate, lobby event API.

To participate in Chat or Messaging, the client app must first enable RTT:

eRTTConnectionType rttConnectionType = eRTTConnectionType.WEBSOCKET;
_bc.RTTService.EnableRTT(rttConnectionType, successCallback, failureCallback);

And register for the chat callback:

RTTCallback rttCallback = response =>
{
   Debug.Log(response);
   // do something! :)
};
_bc.RTTService.RegisterRTTChatCallback(rttCallback);

Next, the app connects to the desired chat channel:

string channelId = "22817:gl:CHAT_TRADE"; // APP_ID:CHANNEL_TYPE:CHANNEL_ID
_bc.ChatService.ChannelConnect(
    channelId, 
    maxReturn, 
    successCallback, 
    failureCallback);

And finally to post a message:

_bc.ChatService.PostChatMessageSimple(
    channelId, 
    chatMessage, 
    true, 
    successCallback,
    failureCallback);

Note that brainCloud chat supports both simple text and rich JSON payloads – and integrates with WebPurify for profanity filtering.

Messaging

In brainCloud, Messaging messages differ from Chat messages in that they are directed at players, not channels. Messaging can be thought of as a simple local email system for your app.

Each player has an inbox and an outbox.

Note – because Messaging is RTT-enabled, online players will be alerted in real-time (via a callback) when a new Message arrives. 

brainCloud Messaging supports both simple text messages and complex JSON payloads. The following method delivers a simple text message to the players at the specified profileIds.

_bc.MessagingService.SendMessageSimple(
  toProfileIds, 
  text, 
  successCallback, 
  failureCallback);

Cloud Code

brainCloud’s Cloud Code system is very similar to the model employed by GameSparks:

In brainCloud:

  • Cloud code Scripts are written in JavaScript, and run upon an embedded Rhino engine
  • Scripts can include other scripts and call other scripts.
  • Scripts are passed JSON parameters when they are called
  • Scripts have access to the full brainCloud API – including the ability to Get/Set Player Data (like player statistics, attributes, User Entities, Owned Custom Entities, etc.) and Get Static Game Data – MetaCollections (like Global Properties, Global Entities, Un-owned Custom Entities, etc.)
  • API calls made from Cloud Code Scripts run synchronously for simplicity!
  • Scripts have access to the brainCloud HttpClient service – which can be used to Send HTTP requests to external services
  • Scripts can be registered to be called from webhooks – which are useful for Receiving HTTP Requests from external services. (Note – brainCloud also supports a custom S2S API for more flexibility)
  • brainCloud supports User Batch Jobs – so you can trigger a script to be run on a select batch of users (or all users). 
  • brainCloud supports Scheduling scripts to be run in the future. Although there isn’t the concept of “run every hour” or “run every day” – it is very simple to have a script reschedule itself to achieve the same result.
  • brainCloud scripts can be attached to API calls via API Hooks. API Hooks can be configured to run custom scripts before and/or after the API call. This can be useful for modifying a game’s behavior without the need to redeploy a new client.

brainCloud Data

brainCloud offers a rich set of data APIs for storing player and game data. An overview of the different data APIs can be found here – as well as a discussion of the benefits of Custom Entities vs. the older User and Global Entity mechanisms here.

MetaCollections

Developers should use brainCloud’s Unowned Custom Entities in place of MetaCollections. Custom Entities are JSON objects with a rich API for storage and retrieval. For more information, see the Custom Entity API reference.

System-Scripts

brainCloud provides a mechanism called API Hooks that allows you to attach custom scripts to API Calls and other events in brainCloud.

API Hooks can be configured as either Pre- or Post- hooks – meaning that they will run either before or after the API calls they are enhancing. 

Post-hooks are useful for cases where you want to enhance the results of an API call with additional data – for example, attaching the user’s campaign state to the Authenticate call results.

Pre-hooks can be used to add additional checks to allow/disallow API calls – and alternatively re-route the calls themselves. They are an easy way to re-route cheaters to alternate leaderboards, for example.

Bulk-Jobs

brainCloud offers a Batch User Script feature for scheduling a script to be run all or a subset of users.

Like GameSparks, the workload is spread across all players and executed as background jobs to not impact server performance. brainCloud also offers the ability to trigger a completion script when all users have been processed.

For more information, check out the RunBatchUserScriptAndCompletionScript() API call.

Schedulers

brainCloud offers APIs for scheduling a script to run at a specified time in the future. Although not the same as the every-hour, every-day scripts supported by GameSparks – the same sort of functionality can be achieved by having the script re-schedule itself to run again. An example of such a script can be found in brainCloud’s Cloud Code Central repository.

Transitioning MetaCollections

The brainCloud Portal offers the ability to import data from JSON files – this is supported for both Custom Entities and Global Entities. This is suitable when important static reference data – like level data, tuning files, etc.

Information

The allowed size of import files is limited – if you receive an error during the import, message our support and we may be able to adjust the limit for you.

Note that brainCloud also supports an S2S API, which may be helpful if you need a more custom approach for migrating your app’s reference data.

GameSparks API Wrappers

If you decide to create wrappers for GameSparks key APIs, you can easily include them in your scripts using the bridge.include() operation.

Using this approach may allow you to better take advantage of the similarities between the brainCloud and GameSparks cloud code systems.

Asynchronous APIs

Happily, brainCloud cloud code scripts use synchronous calls, just like GameSparks.

Performance Bottlenecks

The brainCloud Cloud Code Editor and API Usage pages can help you to find performance bottlenecks:

  • The Cloud Code Editor returns the execution time for each test run of your script. It also returns information on what API calls we made by the script – to help better understand where time may have been spent
  • The Reports | API Usage page displays the average execution times of each of your API calls, including cloud code scripts. Any commonly called scripts taking longer than 200ms should be examined for possible optimizations.

Data Transition Guide

Reference data

The brainCloud Portal offers the ability to import data from JSON files – this is supported for both Custom Entities and Global Entities.

This is suitable when importing static reference data – like level data, tuning files, etc.

Information

The allowed size of import files is limited – if you receive an error during the import, message our support and we may be able to adjust the limit for you.

Note that brainCloud also supports an S2S API, which may be helpful if you need a more custom approach for migrating your app’s reference data.

User accounts

For dynamic user data, it is highly recommended that new users be migrated over during initial login to brainCloud.

This has a number of benefits:

  • Simpler – Importing a single user is simpler than importing all of them
  • Scalable – It spreads the work of importing out, creating less load on both brainCloud and GameSparks
  • Efficient – it ensures that only active player data is migrated over to brainCloud. If your game is more than two years old, it’s likely that less than 25% of your stored player accounts are still active.

The recommended approach is to leverage the following brainCloud features:

  • External Authentication – which allows brainCloud users to be authenticated via an external source – like your Gamesparks app
  • API Post-Hook – which can be used after successful authentication, to trigger a script to retrieve the user’s GameSparks data
  • HTTPClient service – used to make HTTP calls to external services (i.e. GameSparks)

More information on this sort of approach can be found in this article.


Downloadables

brainCloud supports a Global Files service that allows developers to upload files to be downloaded by client apps. These files are automatically distributed to AWS CloudFront CDN for fast downloads.

Uploading of files to brainCloud is normally done via the Design Portal. It is also possible to upload a file as a User File via a Client Library, and then convert it to a Global File via an API Call.

(We will be adding the ability to upload Global Files directly in a future version of our APIs.)


Emails (SendGrid)

brainCloud provides a SendGrid integration for sending emails.

To utilize brainCloud’s SendGrid functionality, simply:

  • Configure the SendGrid settings on the Design | Integrations | Manage Integrations page, SendGrid section of the design portal
  • Modify your scripts and/or client to use brainCloud’s Mail service APIs
  • Optionally customize the system templates to be used for password resets and such on the Design | Authentication | Email Authentication page.

Leaderboard Basics

brainCloud provides a rich leaderboard system – with support for both player and group leaderboards, scoring types, rotation types, supplemental data, history, etc.

Leaderboards are normally pre-defined in the Portal on the Design | Leaderboards | Leaderboard Configs page. Leaderboards can also be dynamically created using the PostScoreToDynamicLeaderboardUTC() call.

Leaderboard scores can be viewed on the Monitoring | Global Monitoring | Leaderboards page of the Portal.

brainCloud of provides a rich API for returning leaderboard results, including social and global leaderboard results – as well as an advanced API for retrieving high scores across multiple leaderboards for social maps.

A player’s own score can be retrieved via the GetPlayerScore() api.

Advice

Pro-tip: To retrieve a player’s rank as well as score, use the GetGlobalLeaderboardView() call, specifying 0 for the beforeCount and afterCount.


Leaderboard Partitions

brainCloud does not support Partitioned Leaderboards – but something similar can be achieved using multiple leaderboards.

To keep setup as simple as possible, we would recommend that the additional partitions (for example, country-specific versions of the leaderboard) be created programmatically with a descriptive suffix (i.e. “_<countrycode>”. This can be done via a simple cloud code script and/or cloud code hook.


Leaderboard Resetting

brainCloud directly supports the following automatic rotation types:

  • NEVER – the leaderboard never resets
  • DAILY – the leaderboard resets daily
  • DAYS – the leaderboard resets after <x> days
  • WEEKLY – the leaderboard resets weekly
  • MONTHLY – the leaderboard resets monthly
  • YEARLY – the leaderboard resets yearly

brainCloud leaderboards also have a “retained count” – that determines how many old copies of the leaderboard are retained before deletion. This can be useful for rewarding players for their performance in the previous rotation.

Note that developers can also directly control rotation by configuring a NEVER leaderboard and resetting it manually via the SysResetNeverLeaderboard() call.


Manage Screens

brainCloud has a feature-rich Design Portal that provides access to game, group, and player data – including entities, statistics, leaderboards, etc. All of this data is viewable and editable by development and support personnel (given appropriate permissions).

The data is all accessible via the Monitoring portion of the portal. Monitoring is broken into the following sub-sections:

  • Global Monitoring – for viewing/editing global data – like global/custom entities, leaderboards, global statistics, job queues, and more
  • Group Monitoring – for viewing/editing of groups and group data
  • User Monitoring – for viewing/editing of users and their data

brainCloud also provides an S2S API that can be used to implement a custom management tool that manages your brainCloud-based apps.

More information on the S2S API can be found here.


Matchmaking

brainCloud provides two different matchmaking systems.

The MatchMaking service is primarily for use by games that are using brainCloud’s Async Match and One-way Match APIs. Games of these types are often played offline – and thus this matchmaking service only selects offline players.

Online games should use the brainCloud Lobby service for matchmaking. Lobby Matchmaking identifies groups of suitable players for online play.

Lobby Matchmaking is highly configurable, with support for:

  • skill level matching
  • min / max players (by team)
  • geo matching <- prioritizing players that are close together
  • filter scripts

For more information, see the brainCloud Lobby service.


Player Manager

Player Management is accomplished via the Monitoring | User Monitoring section of the portal. Subsections for viewing and editing player data include:

  • User Summary – a summary of the user’s info, including name, xp, identities, currency balances, etc.
  • Achievements – displays the user’s achievement status
  • Attributes – displays any attributes attached to the user. Supported creating and editing of attributes
  • Custom Entities – allows for view/edit of a user’s owned Custom Entities
  • Friends – view the player’s friends (both 3rd party and locally managed)
  • Groups – view the Groups the user is a member of
  • Inventory – view the items owned by the player
  • Milestones & Quests – view the user’s completion status for milestones and quests
  • One-way MP – view the status of recent one-way multiplayer matches
  • Pricing – view the store prices for this player – including any promotions that may be being applied
  • Statistics – view/edit the user’s statistics
  • Transactions – view any purchases the player may have made
  • Turn-by-Turn MP – view any async match games currently in progress
  • User Entities – view/edit the player’s User Entities
  • User Files – view the files that this user has uploaded
  • Virtual Currency – view/edit the user’s current balances
  • Logs – logs of the user’s recent interactions with the brainCloud API <- super useful for debugging!

brainCloud also offers an S2S API that can be useful for building custom management tools.


Scheduled Events

brainCloud offers a Scheduled Promotions feature that can be used to configure sale prices for all users and/or specific segments of users.

The list of active promotions can also be queried via the RefreshPromotions() call – and could be used by the client to configure additional custom functionality.


Teams

brainCloud’s term for Team is Group.

Groups are designed as follows:

  • Groups consist of a collection of members (users)
  • Groups have a name, a type, an id, and custom data
  • Members are each assigned a role-based permission level: “OWNER”, “ADMIN”, or “MEMBER”
  • Groups have one (and only one) “OWNER”. The OWNER of a group can add/remove members, and delete the group
  • Groups can have multiple “ADMIN”s. ADMINs are like OWNERs, except that they cannot delete the group.
  • Any “MEMBER” can edit group data
  • MEMBERs of a group can have custom attributes associated with them (can be used for custom application roles, etc.)
  • Users can be members of more than one group
  • Users can be the owner of more than one group
  • Groups can also have associated Entities (i.e. GroupEntity)

Team Chat & Notifications

brainCloud supports text-based Team Chat via RTT’s Chat Service. The Chat service supports special “group channels” for communications between the members of a group.

brainCloud also supports sending push notifications to the members of a group via the SendRawPushNotificationToGroup() call.

Team Leaderboards

brainCloud supports group leaderboards – which are leaderboards where the group entries, instead of player entries.

brainCloud also supports group social leaderboard calls – where the results of the player leaderboard call are filtered to just the members of the specified group.

Team Data

brainCloud supports two forms of team data:

  • Group Data – which is custom JSON attached to a group
  • Group Entities – which are JSON entity objects owned by a group

Both types of data are serviced via the Group Service API.


Virtual Currency

brainCloud provides a VirtualCurrency service for managing a player’s currency balances. Developers can define as many currencies as they like – and these currencies can be automatically awarded from XP level-ups, Milestones, Quests, and Tournaments — and of course, be purchased via in-app purchase Products.

To configure a sign-up bonus for players, simply add the desired currency amount as a reward for the initial XP level. Note that this technique works even if your game doesn’t otherwise use the brainCloud XP system.


Virtual Goods Basics

brainCloud provides support for virtual goods via:

  • ItemCatalog service – which defines the set of items (i.e. virtual goods) that are available for purchase by the user
  • UserItems service – which manages the player’s inventory of said items, including purchases and trading

Standard item properties include: id, name (localizable), category (user-defined), description (localizable), resource ids, pricing (in virtual currency), tags, and custom JSON data.

Additional properties enable behaviors like stackable, consumable, activatable, and tradable.

User items also have a publishing state (DRAFT, PUBLISHED, RETIRED, REVOKED) to help control their life cycle.

Note that brainCloud does not currently support bundles – though this can be worked around using the custom JSON data and a bit of cloud code.

Virtual Goods (3rd Party)

brainCloud directly supports in-app purchases on iOS, Google, Facebook, Steam, and more.

Purchases are enabled by defining Products in the Design | Marketplace | Products screen of the Design Portal. Products are generally used to purchase Virtual Currency bundles, but in brainCloud 4.9 we add support for purchasing User Items (i.e. Virtual Goods) as well.

Products in brainCloud can be defined with multiple price points – which are convenient for scheduling sales using the Promotions service.

To configure Products in brainCloud for purchase, developers must first:

  • Configures the necessary platform integration settings. See tutorial examples for iOS and Google to start.
  • Configure the products to be purchased in the Design | Marketplace | Products page of the portal. The products should be configured to award Virtual Currencies, items from the Item Catalog, and/or custom rewards via attached JSON (and custom cloud code scripts)
  • Configure the pricing of the products – matching up the appStore IDs with the definitions in the platform stores

At purchase time, the app will:

  • Retrieve a list of the products available for sale (and their corresponding platform store ids) via brainCloud’s AppStore service’s GetSalesInventory() call.
  • Call the Platform SDK to retrieve the localized prices for the items to display
  • Display the list of products to the user in your custom storefront
  • When a user selects purchase, the app will initiate a purchase transaction using the Platform SDK
  • The SDK will return receipt data, which the app will forward to brainCloud using the AppStore VerifyPurchase() call
  • brainCloud makes a server-to-server call to the Platform to verify the receipt data (as well as performs a few additional checks of our own)
  • If the purchase is valid, the player is awarded the contents of the Product – and the results are returned to the client app

For more information, see the brainCloud AppStore APIs.

Release 4.8

This is an early summer release with a few timely features – plus a bunch of under-the-hood improvements to support future updates.

Release Highlights

Search Cloud Code Scripts

Got a lot of scripts? Getting hard to find the one you want? You can now search for cloud code scripts by name – across all your folders. 

Just type a few letters, and then click on the script name to jump to it!

Facebook Limited Login Friends

Facebook has enhanced their new Limited Login Mode to support retrieval of the logged-in user’s friends (https://developers.facebook.com/blog/post/2021/04/12/announcing-expanded-functionality-limited-login/) – and thus we have extended brainCloud to support friend retrieval as well!

Facebook only allows apps to retrieve the user’s friends during the initial authentication operation. Since brainCloud Friend and Social Leaderboard APIs can be called anytime (during the current or subsequent play sessions) – we need to store a copy of the Facebook friends in the internal brainCloud friend list. If this feature is enabled, when a user logs in via the AuthenticateFacebookLimited() call, brainCloud will retrieve the user’s Facebook friends and add them to the internal friend list for that user. Note – all friends in brainCloud are bi-directional – so their friend’s friend lists get updated as well.

To enable this feature, go to the Design | Core App Info | Application IDs page, choose the Facebook tab, and set the Facebook Limited Login (Retrieve friends) drop-down to “Retrieve and add to internal friends (add only).”

Advice

For our customers that are using 3rd party authentication services: If you are getting a list of Facebook friends from another service, you can use the new AddFriendsFromPlatform() call to add those friends to the internal list all at once.

Account Migration Support

The brainCloud community has long been interested in being able to migrate player accounts on-demand from one instance to another.

This is useful when:

  • migrating to brainCloud from another service
  • beta-testing a new release in a separate brainCloud app (or server) instance

brainCloud’s security and privacy frameworks can make this very challenging (as they should!). In brainCloud 4.8 we’ve added some new features + APIs, that when used together, can make this use case achievable.

The new features / APIs are:

  • Authentication postFail – you can now attach a custom script to an Authentication failure. This allows your custom script to perform some work (like account retrieval and creation) when an authenticate operation fails. The script then returns a special status (199) to tell the dispatcher to re-try the authentication from the beginning.
  • GetSessionForValidatedCredential() – a new S2S method that allows a client authentication to be performed via an S2S script. Once authenticated, the script can then retrieve and return select data from the user account. 
  • SysGetUserExport() – a new cloud-code only method that allows a script to retrieve an export of the data associated with a user.

By putting these features together, a developer can:

  • Write an authentication postFail script for the target app, that will catch authentication failures and attempt to retrieve the missing user account
  • Write an account retrieval script for the source app, that can be called via S2S to retrieve the data from a user account if the supplied credentials are valid

Information

For full instructions on these use cases, see the brainCloud Knowledgebase.

Edit User Email Identities

The brainCloud Design Portal has been updated to provide a simple way for Support personnel to update the Email Identity + Contact Emails of users.

Simply navigate to the Credentials section of the User Summary page in User Monitoring, and click the pen icon next to the user’s email identity.

Note that if you only want to edit a user’s Contact Email – we have added an edit feature (via another pen icon) near that field as well.

Miscellaneous

In addition, the following new changes have been added to the platform:

  • Division improvements – we have adjusted the Division Set algorithms to allow players to post scores for rounds that started before the Division instance was created. This is important because some apps have their user’s join divisions just-in-time as they are posting their first score – and thus if the user is the first player in the division, their play round would have begun before the division tournament itself had been created! (And thus it was rejected by brainCloud). The new algorithm will dynamically adjust the start time of the division if a player attempts to record a score from before the Division was created. Note that the start time of the round must be within 2 X the Buffer time defined for the tournament.
  • Authentication Pre- and PostFail- hooks – we have added both pre- and postFail- hook support for the Authentication services. This work was done in association with the Account Migration feature (above) – but they will undoubtedly will be useful in their own right!
  • Lobby + Relay Server protocol improvements – we have tightened up the data structures and IDs commonly used between Lobby Services and Relay Services to be more consistent. This is in preparation for new Multiplayer features coming in the near future. The biggest impact of this is the replacement of the owner field in the Lobby data with the proper ownerCxId field. To help migrate to the new structure, a new compatibility flag has been introduced, which when enabled, causes both the owner and ownerCxId fields to be present in Lobby data messages. (This flag is currently forced to enabled for both new and existing apps.)
  • New Client Library calls – we have added a few calls that were introduced in recent releases as cloud-code only, to the 4.8 client libs:
    • AppStore – the RefreshPromotions() call has been added
    • Events – the DeleteIncomingEvents()DeleteIncomingEventsOlderThan() and DeleteIncomingEventsByTypeOlderThan() calls have been added
    • User Files – we have added the UploadFileFromMemory() call to the JavaScript library, and likewise improved the Unity implementation of the call.
  • Audit Logging
    • Added additional tracking for changes to Team information
  • Cloud-code Script Performance
    • Updated Rhino engine from 1.7.12 to 1.7.13
    • We have enhanced the API Server bootup strategy to pre-load and cache both scripts and leaderboard configurations for active apps – resulting in faster launch performance for cold servers
    • Added big message support to user batch script operations
  • Group & GroupEntity Performance Improvements
    • We have adjusted the indexes and sharding strategies for Groups and Group Entities to improve performance.
  • Scheduled / S2S Scripts
    • Improved error logging for Scheduled and S2S Scripts

Portal Changes

We have made the following portal improvements:

Design

  • Core App Info | Application IDs
    • New option to retrieve friends when using Facebook Limited Login added to the Facebook tab
  • Core App Info | Advanced Settings
    • New compatibility feature: Include legacy lobby ‘owner’ field in API output. Note – the new code + features that use this flag aren’t completely ready yet – so changing the flag is disabled. The flag will be set to true (enabled) for both new and existing apps.
  • Cloud Code | Scripts
    • There is a new search box on the cloud code scripts page. Just type a few letters, and click on the name of the script you want to view/edit!
  • Leaderboards | Leaderboard Configs
    • The Leaderboard Configs page has been refactored to better support apps with thousands of leaderboards
  • General
    • Privileges + Permissions handling – We have re-worked the underlying permissions and privilege caching and enforcement code to be more consistent

Monitoring

  • User Monitoring | User Summary
    • You can now change a user’s email identity credentials by clicking on the pen icon next to their email identity in the Credentials section of the page. When editing the user’s email identity, you are also given the option to change the user’s contact email as well.
    • You can also change the user’s contact email directly via the pen icon by the Contact Email field in the Account Information section. 

Warning

Note that changing a user’s contact email alone does not change their email identity (which is the email address used to log into your app).


API Changes

The following changes/additions have affected the brainCloud API:

  • Bridge
    • New Sleep( <millis> ) call added to facilitate waiting before retry operations. Can only be called from cloud-code. Note – the max sleep time is restricted to the timeout setting of the script.
    • New GetSessionForValidatedCredential() allows an S2S script to acquire a client session for the account associated with the provided user credentials, after first confirming that the credentials are valid, of course
  • Friend
    • New AddFriendsFromPlatform() call allows devs to add multiple friends to the internal brainCloud friends list, specifying the platform-specific external IDs, instead of brainCloud profileIds. ← saving multiple lookup calls.
  • Global App
    • New SysGetAppSecret() method returns the secret for the current session. Useful for apps using the Shared Accounts feature (between Parent and Child apps), and that don’t want to package the secrets of all child apps in the client binary.
  • Global Files V3
    • New cloud-code only methods for confirming files exist: CheckFilenameExists() and CheckFullpathFilenameExists().
  • Identity
    • New cloud-code only SysChangeEmailIdentity() method allows the email address associated with a user to be changed without having the user’s password. This is of course a dangerous method not suitable for client usage – so it is cloud-code only.
  • Leaderboard
    • New SysCreateLeaderboard() call allows for the programmatic creation of Group as well as Player leaderboard. The old call, CreateLeaderboard(), only supported the creation of Player leaderboards – and has been deprecated.
    • New SysEditLeaderboard() call likewise allows the editing of group leaderboards.
  • Lobby
    • We have added 3 new methods in preparation for our upcoming Join-in-progress and Long-lived Lobbies features: SysRoomStopped()SysMemberLeft(), and SysGetLobbyMember(). Stay tuned!
  • User
    • New cloud-code only SysGetUserExport() call allows a script to retrieve an export of the specified user’s data.

We have also deprecated the following methods:

  • Leaderboard
    • CreateLeaderboard() – replaced with SysCreateLeaderboard() method (see above)
    • EditLeaderboard() – replaced with SysEditLeaderboard() method (see above)

Miscellaneous Changes / Fixes

  • Updated libraries
    • All supported libraries have been updated with the latest API enhancements. Go get ’em!
  • Documentation updates
    • Updates to tutorials and API References to match the new features/APIs in this release
  • Important Fixes
    • BCLOUD-29 – LobbyService joinLobby() is broken in some circumstances
    • BCLOUD-56 – [PROD] Tournament rewards with only “custom” rewards cannot be claimed
    • BCLOUD-68 – Logging performance improvement
    • BCLOUD-519 – User Monitoring / Logs – Fix handling of mismatched request/response data for displayed packets.
    • BCLOUD-575 – Add packetId as a field in requestResponse logs
    • BCLOUD-634 – ErrorLogEntry timestamps are slightly off
    • BCLOUD-698 – Handle “duplicate key” exception on Leaderboard Service – Post Dynamic (player or group score)
    • BCLOUD-707 – Allow Tournament Scores to be posted to Division Set Instance for round started before joined tournament
    • BCLOUD-710 – ACE Editor: when copying and pasting content sometimes that pasted content is missing from the submitted data.
    • BCLOUD-793 – Defect in memcached lock handling for temporary sessions
    • And fixed issue with “edit leaderboard” APIs potentially resetting pacer settings
  • Plus miscellaneous fixes and performance enhancements…

Release 4.7.5

Release 4.7.5 is a surgical release to improve brainCloud support in a few key feature areas (mostly Purchases + Promotions). We hope you dig it! 

Release Highlights

Promotions

This release addresses some limitations of the existing promotions system and introduces a few cool new tricks.

The improvements, in no particular order, are:

  • Added new Purchase Rewards Hook – a new API Hook that allows apps to override the configured reward amounts for product purchases. This is useful for companies that like double the rewards of a promotional item, instead of offering the same items for less $. You can find a script example here.
  • Added max # of purchases for Automated Promotions – you can now configure Automated Promotions to expire early if a user makes a purchase – limiting that special deal to the first <x> purchases they make.
  • Added max # of re-triggers for Automated Promotions – you can now configure Automated Promotions to re-trigger a finite number of times
  • New AppStore RefreshPromotions() call refreshes the Segments and Promotions of the current user. Useful for apps that want to check if a promotion became active during the play session. Note – cloud-code only for now.

In addition, we have addressed a limitation where Automated Promotions targeting existing Segments would not trigger for users already in that Segment. Those users (in existing segments) will now have the promotion applied by a new job that kicks off when the Automated Promotion is enabled.

Purchases

We have also made improvements to the saved purchase transaction data – as viewed via the User Monitoring | Transactions page. For new purchases, you can now see:

  • Any rewards associated with the purchase
  • Where the purchase was made during a promotion
  • And whether the purchase has been refunded. Note – for purposes of brainCloud, chargebacks also appear as refunds. Also, note that these states only apply to Facebook purchases.

Miscellaneous

  • Builder API – Our “official official” beta release of Builder API begins now. Our planned 4.7.0 roll-out was delayed while we put in some finishing touches. Note – still for private licensees and approved BaaS customers only.
  • Cloud-code Script Hook – we have added a cloud code script pre-hook. This can be helpful when re-organizing scripts into folders (using our new Cloud Code Folders feature). This hook can allow you to rework your script organization, while still supporting existing clients attempting to run scripts from their old locations. See this article for an example of how to use it.
  • Events – we have added more flexible ways of deleting incoming events for a user. See the API Changes section for more details…
  • Room & Relay Servers – we have reworked our room/relay server mechanisms to be more efficient. You may notice more responsive cleaning-up of server resources.
  • RTT – Improved clean-up (server-side) of stale client connections.

Portal Changes

We’ve made the following portal changes:

Design

  • Cloud Code | API Hooks
    • Added new AppStore PurchaseRewardHook – configure it as a “Post” hook to dynamically override the default awards of an item.
    • Added the ScriptService to the list of services that support API Hooks. So for example you can now add a Pre-hook to “RunScript” that adjusts the name/path of a script before running it. Useful when migrating to Cloud Code folders while still maintaining compatibility with existing clients.
  • Cloud Code | Scripts
    • We have updated the Scripts screen to default to showing up to 100 scripts per page. You are welcome! 🙂
  • Promotions | Automated
    • You can now set the max # purchases and max # re-triggers for automated promotions. Leave the value blank for unlimited – which is the default.

Monitoring

  • Global Monitoring | Recent Errors
    • Updated the source of legacy servicemix errors to the more up-to-date cron and datastream sources
  • User Monitoring | Transactions
    • We have beefed up the Transactions page to show rewardspromotions and refund status of transactions. There is also more transactional info shown via the Transaction Action menu for Facebook purchases. 
    • Steam pending transactions are no longer shown (by default). There is a new toggle button to toggle viewing pending transactions. 

API Changes

The following changes/additions have affected the brainCloud API:

  • AppStore
    • The GetEligiblePromotions() method (and other promotions methods) now include the new num purchases and retriggers counts in the responses when appropriate.
    • Added a cloud code method, RefreshPromotions(), that refreshes the segments and promotions associated with a user. Note that a user’s segments and promotions are automatically refreshed when they authenticate. Calling this method allows apps to periodically refresh the segment + promotion data for the user during the play session. Note that this is an expensive call – calling it is equates to 2 API counts (technically 1 API + 10 bulk API) – so use it sparingly!
  • Events
    • New event deletion methods – DeleteIncomingEvents()DeleteIncomingEventsOlderThan() and DeleteIncomingEventsByTypeOlderThan()

Note that all of the new methods are cloud-code only for now – but will be added to the client libraries for brainCloud 4.8.


Miscellaneous Changes / Fixes

  • Updated libraries
    • No changes to the Client Libraries for 4.7.5.
  • Documentation updates
    • Updated API Reference docs and examples
  • Important Fixes
    • BCLD-7072 – Automated Promotion job to run when promotion created or new target segment added
    • BCLD-7095 – Failure to extend the TTL of an RTT cx should result in the termination of the socket connection
    • BCLD-7201 – Product pricing lookups should be specific to store type
  • Plus miscellaneous fixes and performance enhancements…