Hello! Please choose your
desired language:
Dismiss

Player data

Track player position and rotation

The Camera object exposes information about the player’s point of view in your scene.

  • camera.position returns a 3D vector with the player’s coordinates relative to the scene.
  • camera.rotation returns a quaternion with the player’s rotation.

Tip: You can also obtain the player’s rotation expressed in Euler angles (as an x, y and z vector) by writing camera.rotation.eulerAngles.

const camera = Camera.instance

class CameraTrackSystem {
  update() {
    log(camera.position)
    log(camera.rotation.eulerAngles)
  }
}

The example above logs the player’s position and rotation on each frame.

const camera = Camera.instance

class SomeSystem implements ISystem {
  entity: Entity
  constructor(entity: Entity) {
    this.entity = entity
  }

  update() {
    const transform = this.entity.getComponent(Transform)
    transform.rotation = camera.rotation
  }
}

const cube = new Entity()
const shape = new BoxShape()
const transform = new Transform()
transform.position.set(5, 1, 5)
cube.addComponent(shape)
cube.addComponent(transform)

engine.addEntity(cube)
engine.addSystem(new SomeSystem(cube))

The example above uses the player’s rotation to set that of a cube in the scene.

Get player’s public Ethereum key

You can obtain a player’s public Ethereum key by using getUserPublicKey(). You can then use this information to send payments to the player, or as a way to recognize players.

The example below imports the Identity library and runs getUserPublicKey() to get the public key of the player’s Ethereum account and log it to console. The player must be logged into their Metamask account on their browser for this to work.

import { getUserPublicKey } from "@decentraland/Identity"

const publicKeyRequest = executeTask(async () => {
  const publicKey = await getUserPublicKey()
  log(publicKey)
  return publicKey
})

Note that we’re using an async function to run the getUserPublicKey() function, as it might take some time to retrieve this data. We’re then handling the data in a system, to be able to use it whenever it’s ready.

Get the essential player data

You can obtain a player’s display name and public Ethereum key by using getUserData().

The example below imports the Identity library and runs getUserData().

import { getUserData } from "@decentraland/Identity"

const userData = executeTask(async () => {
  const data = await getUserData()
  log(data.displayName)
  return data.displayName
})

NOTE: This won’t work when running a local preview, since you’re not authenticated while running a preview. But once the scene is deployed to Decentraland, the player’s data will be readable by this code.

Here we’re using an async function to run the getUserData() function, as it might take some time to retrieve this data. We’re then handling the data in a system, to be able to use it whenever it’s ready.

The getUserData() function returns the following information:

  • displayName: (string) The player’s user name, as others see in-world
  • userId: (string) A UUID string that identifies the player. If the player has a public key, this field will have the same value as the public key.
  • publicKey: (string) The public key of the player’s Ethereum wallet. If the player has no linked wallet, this field will be null.
  • hasConnectedWeb3: (boolean) Indicates if the player has a public key. True if the player has one.

Note: For any Ethereum transactions with the player, always use the publicKey field, instead of the userId.

Get player realm data

Players in decentraland exist in many separate realms. Players in different relms cant see each other, interact or chat with each other, even if they’re standing on the same parcels. Dividing players like this allows Decentraland to handle an unlimited ammount of players without running into any limitations. It also pairs players that are in close regions, to ensure that ping times between players that interact are acceptable.

If your scene sends data to a 3rd party server to sync changes between players in real time, then it’s important that changes are only synced between players that are on the same realm. You should handle all changes that belong to one realm as separate from those on a different realm. Otherwise, players will see things change in a spooky way, without anyone making the change.

import { getCurrentRealm } from "@decentraland/EnvironmentAPI"

const playerRealm = executeTask(async () => {
  let realm = await getCurrentRealm()
  log(`You are in the realm: ${JSON.stringify(realm.displayName)}`)
  return realm
})

Decentraland handles its communications between players (including player positions, chat, messageBus messages and smart item state changes) through a decentralized network of communication servers. Each one of these servers can support multiple separate layers, each with a different set of players. Each one of these layers in a server is a separate realm.

The getCurrentRealm() function returns the following information:

  • displayName: (string) The full address of the relm, composed of the server + the layer
  • domain: (string) The URL of the server
  • serverName: (string) The name of the server
  • layer: (string) The name of the layer

Fetch more player data

Make a REST API call to the following URL, to obtain info about the player from the content server. Besides obtaining the player name, and wallet (which you can also obtain through userData) you can also find a full list of all the wearables that the player owns and all the wearables that the player is currently wearing. You can also find the player’s base body shape (male of female avatar), and snapshots of the avatar’s face and body in .jpg format.

This feature could be used, for example, to only allow players that are wearing a special wearable item into a place.

This information is exposed in the following URL, appending the player’s user id to the url parameter.

https://peer.decentraland.org/lambdas/profile/<player user id>

Tip: Try the URL out in a browser to see how the response is structured.

To get more real time data about the player, you can query that same information but directly from the same server that the player is currently on. For example, if the player changes clothes, this information will be available instantly in the player’s server, but will take a couple of minutes to propagate to the peer.decentraland.org server.

https://<player server>/lambdas/profile/<player user id>

Tip: You can obtain the player’s server by doing getCurrentRealm().domain.

This example combines getUserData() and getCurrentRealm() to obtain the player’s data directly from the server that the player is on:

import { getUserData } from "@decentraland/Identity"
import { getCurrentRealm } from "@decentraland/EnvironmentAPI"

async fetchPlayerData() {
    const userData = await getUserData()
    const playerRealm = await getCurrentRealm()

    let url = `{playerRealm.domain}/lambdas/profile/{userData.userId}`.toString()
	log('using URL: ', url)

      try {
		let response = await fetch(url)
		let json = await response.json()
		
		log('full response: ', json)
		log('player is wearing :', json[0].metadata.avatars[0].avatar.wearables )
		log('player owns :', json[0].metadata.avatars[0].inventory)

	  }
	  catch {
		log("an error occurred while reaching for player data")
	  }
}

fetchPlayerData()

Get detailed info about all wearables

Make a REST API call to the following URL, to obtain a full updated list of all wearables that are currently usable, with details about each.

https://dcl-wearables-dev.now.sh/expected.json

This feature could be used together with fetching info about the player, to for example only allow players to enter a place if they are wearing any wearable from the halloween collection, or any wearable that is of legendary rarity.

Tip: Try the URL out in a browser to see how the response is structured.

fetchWearablesData() {
    let url = `https://dcl-wearables-dev.now.sh/expected.json`

    executeTask(async () => {
      try {
        let response = await fetch(url)
        let json = await response.json()
        log('full response: ', json)
	  }
	  catch {
		log("an error occurred while reaching for wearables data")
	  }
	})

fetchPlayerData()