Skip to content

Cloud Data

ChilliConnect's Cloud Data feature provides you with the ability to save persistent data from your game in the cloud and share that data between players. Cloud Data comes in two types, Collection Data and Player Data, that satisfy different types of data storage requirements.

Player Data is primarily suited for data that is tied to a specific player and does not need to be searched for or updated by other players. Use cases for player data include:

  • Save game state
  • Player preferences

Collection Data is best suited for data that is global to your game, should be visible to all players and can potentially be updated by multiple players. Here are some of features you can implement with Collection Data:

  • Content sharing
  • Turn based multiplayer
  • Challenges
  • Teams and clans
  • Social quests
  • Tournaments and competitions

Collection Data

Collection Data is a fast, scalable, cloud based data store for your games that provides all the flexibility you would get from writing your own server but with none of the hassle. Collection Data can be used to store JSON data and then query and share that data with other player using an intuitive query language.

Collection Data is fully Cloud Code compatible, making it easy to add to Client or Server Authoritative games. See our tutorial on implementing a simple in-game marketplace using Collection Data and Cloud Code for a detailed example.

Creating Collections

Collections are created from the ChilliConnect Dashboard, using the Add Collection button from the Collections page:

The following information can be supplied for each collection:

Name Descriptive name for the Collection
Key The Key used to identify the Collection in API calls from your game
Fields

A list of fields that that describe the properties of Objects in your Collection. Each field contains a descriptive Name, a field Type and can be optionally defined as an Index. Fields that are going to be queried in your collection should always be defined as an index. Indexed fields can also be specified as Unique, meaning that the value of the field must be unique within the Collection. All fields in a Collection are treated as optional. Collections can have up to 15 fields and 5 indexes.

Supported field types are described below:

Type Description Example Input
String Value A text string that represents a specific value. This should typically be used for strings that will be one of known set, and will be searched for. For string values that represent free text, the String Full Text type should be used. String Values can be up to 180 characters in length. { "MapSize" : "LARGE" }
String Full Text

A text string that represents a body of text. Free-form strings such as comments or descriptions are a good fit. String Full Text fields can be upto 10,000 characters in length.

Note: Collection Queries cannot sort on Full Text fields.

{ "Comment" : "This is a great map!" }
Boolean Boolean values true or false. A Boolean field will accept and transform 1, "1" to true, and 0, "0" to false. { "IsDeleted" : true }
DateTime An ISO8601 date formatted string. Time is required. { "EndDate" : "2015-01-01T12:10:30" }
Float A double-precision 64-bit IEEE 754 floating point number. { "Rating" : 1.234 }
Integer A signed 64-bit integer. { "Counter" : 27 }
JSON

A JSON value. When querying Collections, values inside a JSON Object field cannot be searched. If you wish to search using a specific field, make sure that it is defined as a top-level field rather than nested within a JSON Object.

{
 "Transaction" : {
 "Date" : "2015-01-01T12:10:30",
 "Status" : "Complete"
 "Item" : {
  "Name" : "Gems",
  "Quantity" : 7 }
 }
}

When editing a Collection, existing fields cannot be renamed, but they can be removed. Removed fields are no longer visible in returned query results and can no longer be populated when adding or updating Collection objects. However, the data is not deleted, and restoring the field will cause existing any previous information to become visible in search results again.

Adding Objects

Objects can be added to a Collection using the AddCollectionObject method, specifying the Key of the Collection and a JSON Value. The maximum size of the Object is 400kb. The method will return the ObjectID, a unique identifier assigned to the stored object that can later be used to update or delete the object using the UpdateCollectionObject and DeleteCollectionObject methods. For more details on updating and deleting objects, see the Modifying Objects section.

When stored in the Collection, the Value provided will be wrapped in an outer object that contains meta-data associated with the item, including the player that created the object and the date the object was last modified. For example, calling AddCollectionObject with the below JSON Value:

{
  "Type" : "jungle",
  "Size" : "Large",
  "Name" : "SodaJungle",
  "PlayersMax" : 32
}

Will result in the following object being stored in the Collection:

{
    "ObjectID": "56413f2a-c1f5-11e6-b05f-0a3391dcf55d",
    "CreatedBy": "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateCreated": "2016-12-14T12:03:33",
    "ModifiedBy": null,
    "DateModified": null,
    "Value": {
        "Type" : "jungle",
        "Size" : "Large",
        "Name" : "SodaJungle",
        "PlayersMax" : 32
    }
}

This is important to remember when querying collections. To query the Type field, we would specify Value.Type as the field name. To query a top level item, such as DateCreated no prefix is required. ChilliConnect will also update the ModifiedBy and DateModified values automatically whenever the object is changed.

Viewing Objects

Collections and their objects can be viewed from the "Collections" menu option in the Dashboard. Selecting a specific Collection will show a paged list of Objects stored in the Collection, with the first 6 fields displayed.

Selecting an individual Object shows a detailed view for that specific Object, including all fields as well as the ChilliConnect player to create and last update the object.

Querying Collections

Objects in a Collection can be searched using the QueryCollection method. The QueryCollection method takes the Key of the Collection to be searched and optional Query string and Sort parameters.

The format of the Query string is a series of clauses on the fields of the object that can be optionally be combined together to perform more complex queries. For example, to search for objects where a Name field is equal to ChilliConnect, the query string is simply Value.Name = "ChilliConnect". For more examples of queries and available operators, see below.

Results can be randomized. By setting the Randomize parameter in the request the QueryCollection call will return a random set of 20 results that match your query criteria. If sort parameters are supplied they will be applied to the randomised set of results once the objects have been selected. Supplying a Page parameter with the randomize flag has no effect.

Example Queries

Assume that we have a Collection to store player created maps that can be searched and played by other players. Each object contains fields to store the map type, the size, name and the maximum number of players that the map can support. An example of an object sorted in this collection is below:

{
    "ObjectID": "56413f2a-c1f5-11e6-b05f-0a3391dcf55d",
    "CreatedBy": : "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateCreated": "2016-12-14T12:03:33",
    "ModifiedBy": null,
    "DateModified": null,
    "Value": {
        "Type" : "jungle",
        "Size" : "Large",
        "Name" : "SodaJungle",
        "PlayersMax" : 32
    }
}

Here are some of the types of queries we could run on this Collection:

  • Find all maps of Type "jungle"
Value.Type = "jungle"
  • Find all maps of Type "jungle" that support more than 16 players
Value.Type = "jungle" AND Value.PlayersMax > 16
  • Find all maps of Type "jungle" or type "desert"
Value.Type = "jungle" OR Value.Type = "desert"
  • Find all maps created by a specific player
CreatedBy = "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW"
  • Find all maps that are either of type "jungle" or type "desert" and are size "Large"
Value.Type = "jungle" OR ( Value.Type = "desert" AND Value.Size = "Large" )

Query results are returned in a paged format, with the CreatedBy and ModifiedBy attributes expanded to also include the player's UserName and DisplayName:

{
    "Total": 1,
    "Page": 1,
    "PageSize": 20,
    "Objects": [
        {
            "ObjectID": "82c77206-bcac-11e6-aca5-08002739d0fc",
            "CreatedBy": {
                "ChilliConnectID": "dLH3DVBq2laMECfQ8CxO8YmpXdQo5lbF",
                "UserName": "SomeUsername",
                "DisplayName": "SomeDisplayName"
            },
            "CreatedBy": {
                "ChilliConnectID": "4gfaOaVBq2laha21Q8CxO8YmpXkasFe2",
                "UserName": "AnotherUser",
                "DisplayName": "AnotherDisplayName"
            },
            "Value": {
                "Type" : "jungle",
                "Size" : "Large",
                "Name" : "SodaJungle",
                "PlayersMax" : 32
            },
            "WriteLock": "1"
        }
    ]
}

Queries can be nested several levels deep and can operate on any number of fields. These examples show just some of the queries you can run against Collections. For a full list of available operators see the section below.

Query Operators

Collection Data provides a wide range of operators that can be used to search and filter data. The table below describes each operator as well as usage examples.

Operator Description Example
=

Matches objects where the specified field is equal to the provided value. Date values must be provided in ISO8601 format. Compatible with String Full Text, String Value, Boolean, DateTime, Integer, Float.

Value.Name = "ChilliConnect"
DateCreated = "2017-01-04T12:23:12"
!= Negation of =, matches objects where the specified field does not equal the provided value. Value.Name != "ChilliConnect"
>

Matches objects where the specified field is greater than the provided value. For use on Boolean fields, true is equivalent to 1, and false to 0. Can be used with String Values for lexicographic comparison. DateTime values must be provided as ISO8601 strings. Partial dates can also be used.

Compatible with String Full Text, String Value, Boolean, DateTime, Integer, Float.
Value.Age > 21
Value.Name > "B"
Value.LastPlayed > "2016-12-14T00:00:00"
Value.LastPlayed > "2016-12-14"
<

Opposite of >, matches objects where the specified field is less than the provided value.

Value.Age < 21
Value.Name < "E"
Value.LastPlayed < "2016-12-14T00:00:00"
Value.LastPlayed < "2016-12-14"
IN

Matches objects where the specified field equals one of the provided values. The values should be supplied in list format.

Compatible with String Full Text, String Value, Boolean, DateTime, Integer, Float.
Value.Name IN ("ChilliConnect", "ChilliSource")
NOT IN

Negation of IN, objects where the specified field does not equal any of the provided values.

Compatible with String Full Text, String Value, Boolean, DateTime, Integer, Float.
Value.Name NOT IN ("ChilliConnect", "ChilliSource")
IS NOT NULL

Matches objects where the specified field has been defined and is not null. Unlike other operators, IS NULL does not require a value.

Compatible with String Full Text, String Value, Boolean, DateTime, Integer, Float.
Value.Description IS NOT NULL
IS NULL Negation of IS NOT NULL, matches objects where the specified has not been defined or is null. Value.Description IS NOT NULL

Modifying Objects

An Object can be updated using the UpdateCollectionObject method, specifying the Key of the Collection, the Object's ObjectID, and the JSON Value. For example, supplying the Value:

{
    "Type" : "jungle",
    "Size" : "Medium",
    "Name" : "SodaJungle",
    "PlayersMax" : 16
}

Will result in the following being stored in the Collection:

{
    "ObjectID": "56413f2a-c1f5-11e6-b05f-0a3391dcf55d",
    "CreatedBy": "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateCreated": "2016-12-14T12:03:33",
    "ModifiedBy": "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateModified": "2016-12-14T12:21:45",
    "Value": {
        "Type" : "jungle",
        "Size" : "Medium",
        "Name" : "SodaJungle",
        "PlayersMax" : 16
    }
}

Partial Updates

In addition to full updates in the example above it is possible to modify just part of an Object. For example, providing the object Value as:

{
    "Size" : "Small",
    "PlayersMax" : 8
}

Will result in the following being stored in the Collection:

{
    "ObjectID": "56413f2a-c1f5-11e6-b05f-0a3391dcf55d",
    "CreatedBy": "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateCreated": "2016-12-14T12:03:33",
    "ModifiedBy": "xe7FuRxEHeEqjVF6xG8Ux7GWmP3SCbZW",
    "DateModified": "2016-12-14T12:32:07",
    "Value": {
        "Type" : "jungle",
        "Size" : "Small",
        "Name" : "SodaJungle",
        "PlayersMax" : 8
    }
}

As you can see only the Size and PlayersMax fields were updated, and the other fields remain and are unchanged.

Deletes

An object can be removed from a Collection by calling the DeleteCollectionObject method, specifying the Key of the Collection, and the Object's ObjectID. When a deletion has been successful an empty response is returned.

WriteLock

In order to better support offline play on multiple devices, Collection Data also provides the ability to detect potential conflicts when attempting to save new data. When data for an Object is retrieved, ChilliConnect will return a WriteLock value for that Object. The WriteLock represents an identifier to the current version of the data that has been read. In order to implement conflict checking, simply supply the WriteLock when next attempting to update or delete that Object.

If the currently stored WriteLock differs from the WriteLock supplied (meaning that the device attempting to update the Key does not have the latest version), then an error will be returned. The data property of the error will include details of the currently stored data so that you can either resolve the conflict programmatically, or present the data to the player and allow them to select the correct version.

See the full documentation for the UpdateCollectionObject method for more details on how to use the WriteLock for conflict checking.

Permissions

The ability to read or modify objects in Collections can be controlled through permissions, accessible from the "Permission" tab on the Collection view.

Permissions allow you to control what collection objects players can read and modify (add, update or delete) from both the public API and from Cloud Code scripts. For example, for a server authoritative game, you may want all players to be able to read objects from a Collection through the public API, but only allow modifications from Cloud Code. In some cases, you might want to treat a Collection as completely private, with all access controlled through Cloud Code scripts.

The available permission levels are:

None No players can perform this action from this source.
Creator Only the player that initially created the Object can perform the action from this source.
Everyone All players can perform this action on any object from this source.

Player Data

Player Data is allows you to save bespoke data against a ChilliConnect player. You can save any kind of data you want - for example, game progression and player preferences are good examples of the type of data that can be saved in Cloud Data. Saved data is persisted on the ChilliConnect servers and can be retrieved on any device, allowing your game to easily support cross platform play.

Saving Data

All data saved in Player Data is attached to a specific Key that describes the Data. For example, PlayerProgress or Level are examples of good Player Data names. Data is saved using the SetPlayerData method.

Up to 10 Keys can be stored against a single player. Keys can be up to 50 characters in length, with values up to 7kb, and an Attachment which is a string up to 2mb in size. If you attempt to save a new Key when the player already has 10 Keys stored, an error will be returned. Existing Keys can also be removed with the DeletePlayerData method.

Retrieving Data

Data stored against the currently logged in player is retrieved through the GetPlayerData method. You can provide a list of Keys to return specific data, or omit the Keys to retrieve all stored Keys for the player.

Player Data also allows you to retrieve a specific Key for the currently logged in player's facebook friends via the GetPlayerDataForFacebookFriends method. This makes it easy to share read only information such as game progression or last level played for example between Facebook friends.

Similarly, GetPlayerDataForChilliConnectIds can be used to retrieve a specific Key for a list of ChilliConnectIDs. This can be used in combination with the ChilliConnectIds returned from a GetScores request, for example, to retrieve additional read only information on other ChilliConnect players when displaying Leaderboard scores in your game.

Conflict Checking

In order to better support offline play on multiple devices, Player Data also provides the ability to detect potential conflicts when attempting to save new data. When data for a particular Key or set of Keys is retrieved, ChilliConnect will return a WriteLock value for that Key. The WriteLock represents an identifier to the current version of the data that has been read. In order to implement conflict checking, simply supply the WriteLock when next attempting to save data to that particular key.

If the currently stored WriteLock differs from the WriteLock supplied (meaning that the device attempting to update the Key does not have the latest version), then an error will be returned. The data property of the error will include the currently stored data as well as date and time the data was last modified so that you can either resolve the conflict programmatically, or present the data to the player and allow them to select the correct version.

See the full documentation for the SetPlayerData method for more details on how to use the WriteLock for conflict checking.

Attachments

Additionally each Player Data Key can store an Attachment. An Attachment is a string up to 2mb in length - serialise binary, zip or other structured data to a string format such as base64 encoding. Attachments are used for larger pieces of data such as saved game state. For performance Attachment data is not sent with the GetPlayerData response, but accessed individually from either the GetPlayerDataAttachment or GetPlayerDataAttachmentForChilliConnectID methods.

Viewing Player Keys

Keys saved against against a particular player are also viewable through the ChilliConnect Dashboard. From the player screen, simply select the "Player Data" tab: