Hello! Please choose your
desired language:
Dismiss

This series of articles will focus on giving you the tools to be able to create a richer shared experience between players in your scene. Decentraland is a social space and many of the most rewarding things you can do as a player require that your actions are visible to others and are permanent.

For instance, in a previous article about Genesis Plaza, we covered how to use the message bus to send P2P messages between players who are in a scene at the same time. That’s a really useful tool, but it has the limitation that any information passed between players fades away as soon as the players walk away from the scene. (If a tree falls in a scene that only uses the message bus and no one is around to hear it, does it make a sound?). What if you want this conversation to remain so that other players that enter the scene later may see it?

We’ll cover questions and functionalities like these, as well as many of the tools you’ll encounter along the way. We appreciate there are more experienced members of the audience from a development perspective, so we’ll go at a relatively slower pace – explaining concepts where we think it’s important.

There’s a whole world of tools and services that can be used in the metaverse. We’ll do our best to give you a suitable roadmap and get you started on your own journey into these lands.

About APIs

Let’s begin with a simple task: Accessing information from a RESTful API.

API stands for Application Programming Interface, and REST stands for Representational State Transfer. An API is a way for apps to talk to apps via code, and a RESTful API is one that does it by following the REST standard – but all you really need to know about this for now is that HTTP is used to send the info.

You’d be surprised by how many webpages and apps have their own API to expose Stuff As A Service, that you can access just by sending an HTTP request to the right address. Some of these services require registering a key, some even require paying a fee, but a lot of them are free and open and are just waiting for someone to come and play with them.

Check out Programmable Web for a great catalogue of what’s out there. For example, you can call a trivia API, and have the whole backend logic and content of a trivia game already served on a platter, for free. You could also fetch images from Twitter to show on your scene, showing the latest from an account, or the latest that use a certain hashtag. You could also query coin prices from Binance, live data from sports events, and a ton of other things that can imbue Decentraland with the events from the ‘real’ world.

For example, in the Trade Center building of Genesis Plaza (on the south-east corner) we query a number of APIs to display data from the crypto market, including the Binance API, the OpenSea API and the API from our own Marketplace. We also query our Marketplace API to fetch data from wearables on sale on the Wearables building. We also query our Events API to show any events that are currently live on a banner near the central building.

What time is it?

Let’s take a look at a simple API that returns the time. A Decentraland scene can’t access your computer’s clock, since it runs in its own sandbox environment, but you can still fetch this info from the internet if you call an API.

Here’s a simple example scene that uses data from an API to tell the time and start a party at a specific time: github.com/decentraland-scenes/Party-Time

In this scene, we send out a request to an API using the URL https://worldtimeapi.org/api/timezone/etc/gmt+3. Since this is a simple GET request, with no headers or anything special, we can actually see the response we’re getting back from the API if we just paste the URL into another tab in our browser. If you try that, you’ll get a response that looks similar to this one:

{
  "abbreviation": "-03",
  "client_ip": "181.167.208.158",
  "datetime": "2020-06-03T16:34:28.699908-03:00",
  "day_of_week": 3,
  "day_of_year": 155,
  "dst": false,
  "dst_from": null,
  "dst_offset": 0,
  "dst_until": null,
  "raw_offset": -10800,
  "timezone": "Etc/GMT+3",
  "unixtime": 1591212868,
  "utc_datetime": "2020-06-03T19:34:28.699908+00:00",
  "utc_offset": "-03:00",
  "week_number": 23
}

Some other APIs require requests with more fancy elements, like headers or a body, or perhaps use a POST or a PUT method instead of GET. A great tool to send and test those requests is Postman. It’s always a good practice to first test out the requests you want to send before you start writing the code as part of a scene. That way you can be sure of what inputs and outputs you’ll be dealing with.

The following snippet, taken from the same example scene, condenses the most important things in this post. If you have a web development background, it all may look quite familiar to you already, but we’ll explain it in detail for those who don’t. Feel free to skim over this part if you’re well acquainted with the concepts.

async function checkTime() {
  let url = 'https://worldtimeapi.org/api/timezone/etc/gmt+3'
  try {
    let response = await fetch(url)
    let json = await response.json()
    log(json)
  } catch {
    log('error getting time data')
  }
}

Fetch

The fetch() function is a common function in JavaScript and TypeScript that is used to send HTTP requests to a URL. In its simplest form, as you can see above, you just pass it a URL and that produces a GET request – just like if you wrote the URL into a web browser. You can also pass this method HTTP headers, an HTTP body, a different HTTP method, etc.

Read more about the fetch function here: developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Parse a JSON

Most APIs return their responses as a .json file, this file might contain several fields with data you might want to access. The challenge is that what you really receive as a response is a string with all of that information, and your scene won’t know to interpret it as a collection of fields and values. If you want to be able to call out the individual values inside of the JSON structure, you first need to parse it, which you can easily do by running the .json() function on the response.

Once we have our parsed response from the API, we can access the different elements from inside the response JSON. For example we can get json.datetime or json.timezone. If in doubt about what you’ll get on the response JSON, use Postman to send a mock request!

Try & Catch

The execution of this task relies on things that happen far off in a server somewhere. Since we have no control over that, it’s a good practice to always wrap up the code that calls the server in a Try statement. The Catch statement then determines what happens in the event that something in the Try statement fails. So if the server we’re calling is down, or they change their endpoints – or they just block our requests because they have something against us for some reason – our code won’t fail catastrophically. Our scene will just shrug, say “whatever” and move on to what’s in the Catch statement, unshaken. In the example above, our Catch statement is just logging a message, but it could do whatever we need it to do to keep the show running.

Async & Await

As already stated, we’re relying on something that’s executed remotely, and when that’s the case we also need to make use of the Async and Await statements. We don’t know how long it will take our request to reach the server, get processed, and then get back to us. We can’t make our whole execution thread freeze while we wait for that. An async function runs asynchronously on its own thread, it does its own thing and takes as much time as it needs while the rest of the scene keeps moving on. Note that the function defined in our example is marked async. An await statement forces the execution to wait for a response before moving over to the next line of code. await statements can only be used inside an async block of code, since otherwise you’d be freezing the main thread, which is never a good idea. In the example above, we need to add an await to the fetch() function so that we wait for its response before we deal with it. Without the first await, the fetch() function would wait for a response in its own separate thread, and meanwhile we’d be trying to read its response before we even have it. The same goes for the await on response.json(), since the parsing of the message is also something that normally happens in its own thread and might take its time. We’d otherwise be trying to log something before we have it parsed.

Fetch Decentraland Events

Here’s another simple example, taken from something you can find in Genesis Plaza. This scene looks at the Decentraland Events API and displays any events that are currently live on a board, showing their title, location and image. If there are several live events, the board cycles through them. The board can also be clicked to teleport straight into the coordinates of the event.

github.com/decentraland-scenes/Events-API

What’s the weather like?

If you’re looking for an example that’s slightly more advanced, check out the Weather Simulation scene here: github.com/decentraland-scenes/Weather-simulation

This example hits a weather API to get the current weather conditions in a specific location. Depending on the conditions, the scene then emulates those conditions.

That’s enough information for this first instalment. Stay tuned for part two of this series, where we’ll get into creating our own API, so that our scene can not only retrieve information but also write information that can then be accessed by other players!

It may sound scary to some of you, but we’ll be with you every step of the way with examples to illustrate what we mean.