Update: LootLocker now has a Unity SDK. Learn more about it here.
Since LootLocker does not have an SDK for Unity yet, we've prepared an example project showing how to integrate LootLocker in your game using our RESTful API.
Let's start with explaining what a RESTful API is, and how LootLocker has implemented it. If you are already familiar with HTTP verbs, headers and know what the request body is, you can skip this section.
A RESTful API is simply a way of using existing HTTP protocol verbs to signal an intent.
When reading the documentation for LootLocker, the verb is the uppercase word you see right after the curl -X
part, and before the URL. Examples are GET
, POST
, PUT
, and DELETE
.
These each signify what action you intend to take on the endpoint.
GET
requests a resource without modifying it, aka reading a resource.POST
creates one or more resources, using the request body for the data.PUT
updates one or more resources, and also uses the request body for the data transfer.DELETE
deletes one or more resources, and can use both the URL and the request body to signify which resources it will act upon.An HTTP request has a header and a body, and so does responses from the server. These follow the same general pattern. If you are interested in learning more about HTTP headers, Mozilla has a great article on it.
The header is a structured key-value list, with standardized fields such as Content-Type
to let the server or client know what type of data to expect in the body. LootLocker deals mostly in JSON, and as such the value for that header is application/json
.
While the header fields have a standardized list of headers, you can also send custom headers, which LootLocker uses for authentication, with the key x-session-token
.
A request body is simply a string sent along with the request, in the body of the request. For LootLocker this is almost always in a JSON format, the one exception is the authentication request, which is a form request. Unity has support for both and this guide shows how to use both. The request body is handled the same way for all of POST
, PUT
and DELETE
. A request body sent along with a GET
request is invalid and ignored.
When working with remote servers such as LootLocker, it is important to run HTTP requests in the background.
This is because they are very slow compared to what game developers are used to dealing with. While we strive to respond as quickly as possible, and generally do so in a few hundred milliseconds, some requests can take several seconds if there is a lot of data to transfer, or a heavy operation for the servers to handle.
We took the Unity 2D Platformer template and modified it so the character would change colors based on a value saved in the player storage for the player. The game also updates this color with a new random one every 15 seconds, and uses the response to alter the character's color just like the initial color change is handled.
The example includes authentication, as well as reading from and writing to the player storage.
You can download the example project (123 MB zip file) if you want to see the full code and how it's integrated with the engine.
This project is an example, and should not be used in a production setting.
The following code snippets are taken from the LootLocker.cs
class, and as such are not the complete code necessary for getting up and running with LootLocker, but the full class is also available here.
Hopefully this example is good enough to serve as a starting point for your own integration. We are of course always available to help, over on our Discord server.
Create a new file, and give it a descriptive name. I chose LootLocker.cs
, but you might want to spread your integration over multiple files, choosing names accordingly.
The thing to notice here is that we wait for the loginDone
variable to be true
before we continue on to do the other requests, as we need the session token from the login response to be able to perform authenticated calls.
After we've set up the basics, it's time to authenticate the player with LootLocker. This is done by calling the authentication endpoint, with the games API key, the players identifier and a few other bits of information.
It's important to note that this example does not use the Player Verification
endpoint, which ensures that the player is actually who they say they are. This endpoint must be used in any real world integrations, and the Authentication endpoint will normally reject non-verified players. The documentation covers that endpoint here.
Also note the public class PlayerInfoResponse
which is necessary for Unity to parse the response from LootLocker and turn it into native C# data structures. Any public fields in this class will be mapped from the JSON response by the JsonUtilitiy.FromJson
call. Very similarly, we have a public class LoginPayload
which we initialize and set data on.
With all that out of the way, let's have a look at the Login
function.
We start by creating our login payload, and then we serialize it to a JSON string, which we attach to the request using an UploadHandler
. We then send the request using UnityWebRequest.Post
and await a response.
If the request fails, we set the state variables as such, and take no further action. In a real world scenario you would want to retry the authentication or show an error to the player depending on what the error is.
If the request is successful, we parse the response and set the state variables accordingly. The most important part here is that we set the this.sessionToken
variable to the session token returned.
After we've successfully authenticated the player, we are ready to perform the actions we want. In this case, we want to read the player storage (a general purpose key-value store that each player profile has).
We'll be getting all entries in the player storage, but we could also fetch the specific key we're interested in. This is done by using a GET
request, the simplest request.
We created a utility function for handling the response from reading the player storage, since the response we will later get from updating the player storage is the same format.
This utility function handles parsing of the response, and also directly changes the color of the character, based on the data returned by LootLocker. It does this by looping through all the player storage items returned, and once it finds the characterColor
key, it uses the value of that key to update the characters SpriteRenderer.color
.
We also have two classes to handle the parsing of the response. This is because the payload
property on the response is an array, which we save into a List
. The PlayerStorageItem
class also have a ToJSON
method, which will be used when we update the player storage.
If you think (or look) back to the first code snippet in this article, you'll remember that we set up a call to RunUpdatePlayerStorage
every 15 seconds. What this call will do is select a random color and save it to the player storage under the key characterColor
. Once we get the response back, we will parse it and set the characters color to the one we just saved to player storage. Just to demonstrate that we can send multiple keys at once, we also set another key.
Do note that the request requires an order
property on each entry we send. This is to allow for games to send multiple of the same key. For example if a property changes often and the update is on a timer, the game can just queue all the keys with an incrementing order
property and LootLocker will automatically de-duplicate the keys and only save the one with the highest order
value.
We start out by initiating the POST
request to the player storage endpoint, setting the x-session-token
and Content-Type
headers accordingly. Next we generate a random color, and turn it into a comma delimited string we can save in LootLocker.
Because JsonUtility doesn't yet support root level arrays in JSON, we have to manually create some of the structure. That's what the string payload = "[";
is. We then create two objects in this array, one with our random color, and an extra one to show that we can send multiple objects at the same time. These are then immediately turned into JSON strings, using the ToJson
method.
Next we create an UploadHandler
to handle the sending of the request body. We then send the request and wait for an answer. Once we get an answer, we call the same HandlePlayerStorageResponse
method from before.
I hope this example has helped you getting started using LootLocker with Unity. If you have any suggestions, questions or feedback, please do reach out over on our Discord server. We're always happy to hear feedback, discuss implementations and help in any way we can!
Thank you for reading!
Update: LootLocker now has a Unity SDK. Learn more about it here.