Making a game

Building a level

The place a game is played in: maps, ground, walls and where things start.

A level is its environment and its actors. The environment is the map, the ground and the collision, held in a data file the scene names; the actors are everything that has a row.

Where a level's pieces go

PieceHome
The mapA Tiled file in games/<game>/assets/, an entry of the scene's loader catalogue.
A cell changed while the game runsOne key of the tilemap row's edits.
Where a seat startsA start actor per slot: { "is": "start", "slot": 0, "pos": [...] }.
Doors, chests, monstersactors entries in the scene file, or in assets/<scene>.actors.json.
The level's fixed numbersFields of the scene's world.
A level several scenes are played onA <name>.partial_scene.json with its ground, its world and the actors every scene places alike, which each scene names as "extends".

A tilemap level

  1. Make the map in Tiled and save it as JSON, assets/<scene>.tmj, orthogonal or isometric, with its tileset as a .tsj beside it or embedded. Each tile layer is drawn on the render2d layer of the same name.
  2. Give tiles their collision in the tileset. A cell with no tile on any layer blocks a mover that walks cell by cell, so paint the floor.
  3. In <scene>.scene.json, catalogue the map as a tilemap entry with preload, name it in world.tilemap.file, and give world.render2d a ground that matches the tiles. List tilemap before render2d.
  4. Change the game's numbers to the level's units: positions in cells, speeds in cells a second, sizes as a radius in cells.
  5. Have the mover's rule ask the map: slide for a circle, sweep for a box that falls, clear for whether a spot is free.
  6. Place a start for each slot and an actors entry for each thing on the level.
"world": {
  "loader": { "assets": {
    "&lt;scene&gt;": { "type": "tilemap", "url": "/games/&lt;game&gt;/assets/&lt;scene&gt;.tmj", "preload": true, "nearest": true }
  } },
  "tilemap": { "file": "&lt;scene&gt;" },
  "render2d": { "ground": [[32, 0], [0, 32]], "up": [0, -32], "zoom": 1, "look": [15, 8],
                "layers": ["ground", { "name": "things", "sort": true }] }
},
"prefabs": { "tilemap": { "edits": {} } },
"actors": [
  { "is": "tilemap" },
  { "is": "start", "slot": 0, "pos": [2.5, 2.5] }
]

Other ground

  • grid for a map whose every cell changes while the game runs.
  • terrain3d for 3D ground, with scatter3d for trees and rocks and solids for still models.
  • roomcamera for a level cut into rooms.

Many levels

  1. Make each level a scene: <level>.scene.json with its own map and actors, <level>.sim.ts handing out the sim of the scene it shares its kinds with, and an entry in the manager's scenes. A level that gives its own world.loader gives its whole catalogue, the definitions' entry too.
  2. Several scenes played on one level, by day and by night say, share one partial of the level and hold only what is their own, as Scene flow sets out. Never copy the level into each scene file.
  3. Move a seat on by calling go on the scenemanager row from the rule of an exit or a door.

A generated level

  1. Write a recipe file in assets/ with its size, layers, algorithm (rooms, caves or halls), stairs, actors and its seed.
  2. Make a theme tileset whose tiles' type is the role they draw.
  3. Run mapgen's build on the recipe before the game boots, and write what it hands back as <level>.tmj and <level>.actors.json. The same seed makes the same files.
  4. Name both in the scene as for a level drawn by hand.

Checking it

  1. Test that every start stands clear of the walls for the player's radius.
  2. Test with nav's field that every open cell is reachable from every start.
  3. Open the game's index.html as in Starting a game, and walk into every wall.