Hello! Please choose your
desired language:
Dismiss

The 6.0 Beta release of the Decentraland SDK includes some changes that may break your scenes’ existing code. These changes are not as drastic as the changes introduced in version 5.0, but they do still affect all scenes built using previous versions of the SDK.

So, we’ve written a migration guide to help you transition to the new SDK as quickly and smoothly as possible. If you continue to have problems with your migration after working through this guide, please reach out for help in Decentraland’s Developers channel.

Creating a scene in the SDK 6.0 beta

To create a new scene that uses the SDK 6.0 beta, make sure you have the latest version of the CLI installed, and create a new project, with dcl init.

To make sure you have the latest version of the CLI, run:

npm install -g decentraland

Migrate an existing project to the SDK 6.0 beta

To migrate an existing project, follow these steps:

  • Delete the bin and the node_modules folders of the project you want to migrate.
  • Delete the package-lock.json file.
  • Make sure that in the package.json file, the decentraland-ecs field is set to latest.
  • Run npm install on your project’s folder.
  • Make the syntax changes in your code according to the rest of this migration guide.

General syntax changes

The following commands for handling components have been renamed for better clarity and to make it more obvious just what they do. Your scene probably uses at least a couple of these, so it’s worth double checking your code and making sure that you update any obsolete commands.

Old Command New Command
add addComponent
set addComponentOrReplace
get getComponent
getOrNull getComponentOrNull
getOrCreate getComponentOrCreate
remove removeComponent
has hasComponent

Old code:

const ent = new Entity()
ent.add(new GLTFShape('models/Environment.glb'))
ent.add(new Transform({
 position: new Vector3(5, 0, 5)
}))
engine.addEntity(ent)

New code:

const ent = new Entity()
ent.addComponent(new GLTFShape('models/Environment.glb'))
ent.addComponent(new Transform({
 position: new Vector3(5, 0, 5)
}))
engine.addEntity(ent)

Tip: We recommend running a “find and replace” command over your entire project to make sure you’re using the most recent commands and terms. If you do, remember that the set command could also refer to the command used to set a specific position, rotation, or scale, which hasn’t changed. So be careful not to replace any commands that have not changed. For example: myTransformComponent.position.set(5, 0, 5).

Larger parcels

Each parcel in Decentraland now measures 16 meters x 16 meters (as opposed to the previous 10 x 10 format). As a result, you now have far more space to host content in your scene! Please note that the limits of polygons in your scene are based on the number of parcels that make up your scene, not the surface area, so these limits haven’t changed.

Since single parcel scenes now measure 16 x 16, the center of each scene has moved to (8, 0, 8). Depending on the content of your scene, you might want to scale all of your entities up by a factor of 1.6 to fill the entire space. Otherwise, you may need to add new content to fill in the gaps.

3D model rotation

We changed how the SDK internally sets the rotation of all 3D models in a scene so that it follows standards that are consistent with most other platforms. This means that any 3D models in your scene will now be rendered facing backwards, rotated 180 degrees along the Y axis. You may have to reposition or rotate your entities to compensate for this new rotation.

If you used the lookAt function to set the rotation of an entity, keep in mind that what used to be the front of the entity is now its back. In these cases, our recommendation is that you edit the 3D model in an external tool like Blender so that it faces the opposite direction on the Y axis.

Animations

3D model animations are now handled by a separate Animator component, instead of the GLTFModel component.

Also, we’ve renamed the AnimationClip object to AnimationState to help avoid any confusion with the actual animation clip in the glTF file.

Old code:

let shark = new Entity()
shark.add(new GLTFShape("models/shark.gltf"))
let clipSwim = shark.get(GLTFShape).getClip("swim")
clipSwim.play()
engine.addEntity(shark)

New code:

let shark = new Entity()
shark.addComponent(new GLTFShape("models/shark.gltf"))
const animator = new Animator()
shark.addComponent(animator)
let clipSwim = new AnimationState("swim")
animator.addClip(clipSwim)
clipSwim.play()
engine.addEntity(shark)

Read more about this in the documentation or look at an example scene that uses this feature.

Audio

Audio is now handled by a SoundSource component that must be added to an entity. You don’t need to use the executeTask function anymore.

Old code:

executeTask(async () => {
 try {
   await playSound("sounds/Vexento.ogg", {
     loop: true,
     volume: 75,
   })
 } catch {
   log('failed to play sound')
 }
})

New code:

const ent = new Entity()
const audioClip = new AudioClip("sounds/Vexento.ogg")
const audioSource = new AudioSource(audioClip)
ent.addComponent(audioSource)
audioSource.playing = true
engine.addEntity(ent)

Read more about this in the documentation or look at an example scene that uses this feature.

Billboard mode

Billboard is now a separate component, instead of a setting applied to shape components.

Old code:

let ent = new Entity()
ent.add(new BoxShape())
ent.get(BoxShape).billboard = BillboardMode.BILLBOARDMODE_ALL
engine.addEntity(ent)

New code:

let ent = new Entity()
ent.addComponent(new BoxShape())
ent.addComponent(new Billboard())
engine.addEntity(ent)

Read more about this in the documentation.

Textures

To add a texture, you now have to create a Texture component, and add this component to a Material or BasicMaterial component. The Texture component exposes a few new parameters you can set for evern greater control over how things look.

The Material and BasicMaterial components no longer support paths to image files on any of their fields, instead these must point to Texture components.

Old code:

const woodMaterial = new Material()
woodMaterial.albedoTexture = "materials/wood.png"

let ent = new Entity()
ent.add(new PlaneShape())
ent.add(woodMaterial)
engine.addEntity(ent)

New code:

const woodTexture = new Texture("materials/wood.png")
const woodMaterial = new Material()
woodMaterial.albedoTexture = woodTexture

let ent = new Entity()
ent.addComponent(new PlaneShape())
ent.addComponent(woodMaterial)
engine.addEntity(ent)

Read more about this in the documentation.

Click events

We’ve renamed the BUTTON_A_DOWN and BUTTON_A_UP events to simply BUTTON_DOWN and BUTTON_UP. Information about which button was pressed will now be passed as one of the fields inside the event.

Old code:

input.subscribe("BUTTON_A_DOWN", e => {
 log("button Down", e)
})

New code:

input.subscribe("BUTTON_DOWN", e => {
 log("button Down", e)
})

Optional click enhancement

Version 6.0 includes a new OnPointerDown component, which is often a better option than OnClick. OnClick is only triggered when both the pressing and releasing of the button occurs while pointing at the same entity. OnPointerDown is triggered with just the pressing of the button.

The OnClick component will remain supported, but it’s the least versatile option. The event handled by the OnPointerDown component exposes more data, including ray distance, position of the player, and the id of the specific mesh in the 3D model that was clicked.

Old code:

ent.add(
 new OnClick(e => {
   log("event data: " + e)
 })
)

New recommended code:

ent.addComponent(
 new OnPointerDown(e => {
   log("event data: " + e)
 })
)

Other

Removing entities

The engine.removeEntity() used to have a second optional argument, a boolean that determined if child entities should also be removed.

On 6.0 we determined that the default behavior should be to remove all child entities every time.

Old code:

engine.removeEntity(cube, true)

New recommended code:

engine.removeEntity(cube)

Tip: If you don’t want to remove children, you can make them children of another entity before you remove the parent.

Text component alignment

The TextShape component used to have two properties named hAlign and vAlign. These have been renamed to hTextAlign and vTextAlign.

Old code:

let text = new TextShape("Hello world!")
text.hAlign = 'center'

New recommended code:

let text = new TextShape("Hello world!")
text.hTextAlign = 'center'

Entity type renamed

If your scene has function definitions that take entities as inputs, the Entity type now needs to be renamed to IEntity.

Old code:

export function myFunction(
    myNumber: number,
    myEntity: Entity
  ) {
	  log("Entity: " , myEntity)
  }

New recommended code:

export function myFunction(
    myNumber: number,
    myEntity: IEntity
  ) {
	  log("Entity: " , myEntity)
  }