Decentraland Coding Challenge

Decentraland is an open-source virtual world owned by its users, where they can create and experience content in the metaverse.

The Decentraland community is looking for top-tier developers to tackle the implementation of a new World Explorer in Bevy, opening the gates of the platform to global participation in the process.

The new Explorer will be built from the ground up, inspired by the current implementation but not tied to it, and aim to solve some of the known problems with it.

If you’re excited about the project and want to participate, this is the place too start. We give you a warm welcome and would love to see what you build!

Participation

Your mission, should you choose to accept it, will involve facing 2 challenges. You must successfully complete each one to qualify for the next.

Winners will be compensated for their time. The project will assign a total of 5.000 USD in prizes for those that advance through the challenges.

To join in (and maybe become the candidate we’re looking for), you must fill this form before February 5th, 2023.

First Challenge

While moving through the world of Decentraland, users enter and leave scenes which control objects and their behavior in a certain area. The script of each scene is executed by the World Explorer in a sandboxed environment to ensure the security and stability of the experience.

In this first stage, you will create a proof-of-concept runtime environment similar in nature to the one that runs Decentraland scenes.

You must push your solution to a GitHub repository before midnight on February 5th, and send an email to challenge@decentraland.org including the URL. We’ll know who you are based on your original form submission.

Since we can’t anticipate the number of participants, we can’t guarantee responses to every email we receive, but all solutions will be put to the test.

Goal

Write a program that embeds a JavaScript runtime to execute a script in a sandboxed environment, providing access to functionality outside the sandbox. The code you will run, and the objects you will provide, are a simplified version of a minimal Decentraland scene runtime.

Requirements

Ensure that your program is in line with these requirements:

  • Language: it must be written in Rust.
  • Compliance: it must produce the exact specified output (see below).
  • Code quality: the code must be readable, well-organized and well-architectured.
  • Running script: it must run with a specific script (see below).
  • License: it must include an Apache License 2.0 file, as the Decentraland source.
  • Functionality:
    1. Create a JavaScript sandbox that provides a number of global objects (see below).
    2. Load the test file in the sandboxed environment (see below).
    3. Call and await the module.exports.onStart() method (simulating initialization).
    4. Call and await the module.exports.onUpdate(deltaTime) method three times, with the deltaTime sequence 1, 2, 3 (simulating 1 tick per second).
    5. Handle messages sent from inside the sandbox during the simulation.

Global Objects

The sandboxed environment must make the following globals available to the scene. In pseudocode resembling TypeScript:

type EngineModule = {
  async sendMessage(message: string): void // send data outside the environment, in order to log it
}

type Console = {
  log(text: string): void // *immediately* write text to stdout
}

declare const console: Console

declare function require(moduleName: "~engine"): EngineModule
declare function require(moduleName: string): any // throw an error

In more detail, the require implementation provided to the sandboxed script must be compatible with this example JavaScript one (but running outside the sandbox in the language of choice):

function require(moduleName) {
  if (moduleName !== '~engine') {
    throw new Error('Unknown module')
  }

  return {
    async sendMessage(message) {
      console.log("EngineModule: sendMessage: " + message)
    }
  }
}

Sandboxed Code

Inside the sandboxed environment, the following code must run:

const engine = require("~engine")

module.exports.onStart = async function() {
  console.log("Scene: onStart")
}

module.exports.onUpdate = async function(dt) {
  console.log("Scene: onUpdate: begin: " + dt)
  
  console.log("Scene: onUpdate: sendMessage: " + dt)
  await engine.sendMessage("" + dt)

  console.log("Scene: onUpdate: end: " + dt)
}

Expected Execution and Output

Your program must run as follows, from the root of your project:

$ ./bin/run

Ensure that the run script takes care of any preparations your submission needs.

The project will run in a Unix shell environment with cargo installed.

During the course of the execution, your program must write the following verbatim output (and nothing else) to stdout:

Scene: onStart
Scene: onUpdate: begin: 1
Scene: onUpdate: sendMessage: 1
EngineModule: sendMessage: 1
Scene: onUpdate: end: 1
Scene: onUpdate: begin: 2
Scene: onUpdate: sendMessage: 2
EngineModule: sendMessage: 2
Scene: onUpdate: end: 2
Scene: onUpdate: begin: 3
Scene: onUpdate: sendMessage: 3
EngineModule: sendMessage: 3
Scene: onUpdate: end: 3

Ready?

We hope to hear from you and see what you build!

» Start Here «