island coast
World Tree

The goal of World Tree is to provide a low barrier to creating a world for a game to take place in. This is achieved in mulitple ways:
- Very few sprites are required to build a world, and the generated world automatically becomes more visually complex with the greater number of sprites and flags provided.
- The world geometry is defined just by a 2D value of numbers, known as a height map.
- Commonly used camera controls are provided by the engine.
- The engine also provides a simple way to add characters and tracks their movements, automatically performing collision detection.
- An event system is employed as an asynchronous way for the user defined elements to perform actions, interacting with the world and each other.

map generated with single block
Small map generated with a single sprite.
map generated with two blocks
Small map generated with two sprites.
map generated with three blocks
Small map generated with three sprites.
island generated with 7 sprites.
Small island generated with seven sprites.
Adding the graphics
Using the two-sprite map as an example, we'll want to add two tile sprites: one for the floor and one for the walls. 2D sprites are created by cutting up a SpriteSheet into a 2D grid. The engine currently only supports PNG files for the spritesheet and the layout of the sprite sheet is described by our terrainSpriteDescriptor. This object is a part of the worldDescriptor object, which also holds the layout of our little 5x5 world.

import * as WT from "../../../dist/world-tree.mjs";

const worldDescriptor = {
  canvasName: "demoCanvas",
  projection: "TwoByOneIsometric",
  numTerraces: 1,
  heightMap: [ [ 1, 1, 0, 1, 1 ],
               [ 1, 0, 0, 0, 1 ],
               [ 1, 0, 0, 0, 1 ],
               [ 0, 0, 0, 0, 1 ],
               [ 0, 0, 1, 1, 1 ],
  floor: WT.TerrainType.Inside,
  wall: WT.TerrainType.Inside,
  terrainSpriteDescriptor: {
    spriteSheetName: "graphics/png/basic-dungeon",
    spriteWidth: 322,
    spriteHeight: 270,
    tileRowTypes: [
    tileColumnShapes: [
We then pass the worldDescriptor object to the engine and wait for it to finish building the world. We can then add a mouse-click controlled camera and enter the animation loop.

window.onload = async (event) => {
  const context = await WT.createWorld(worldDescriptor);
  const canvas = document.getElementById("demoCanvas");
  const camera = new WT.MouseCamera(

  const update = function() {
    if (document.hasFocus()) {
The code is running in the canva below (if your screen is large enough), so use mouse click to move the camera around.