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
| Piece | Home |
|---|---|
| The map | A Tiled file in games/<game>/assets/, an entry of the scene's loader catalogue. |
| A cell changed while the game runs | One key of the tilemap row's edits. |
| Where a seat starts | A start actor per slot: { "is": "start", "slot": 0, "pos": [...] }. |
| Doors, chests, monsters | actors entries in the scene file, or in assets/<scene>.actors.json. |
| The level's fixed numbers | Fields of the scene's world. |
| A level several scenes are played on | A <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
- Make the map in Tiled and save it as JSON,
assets/<scene>.tmj, orthogonal or isometric, with its tileset as a.tsjbeside it or embedded. Each tile layer is drawn on the render2d layer of the same name. - 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.
- In
<scene>.scene.json, catalogue the map as atilemapentry withpreload, name it inworld.tilemap.file, and giveworld.render2dagroundthat matches the tiles. List tilemap before render2d. - Change the game's numbers to the level's units: positions in cells, speeds in cells a second, sizes as a radius in cells.
- Have the mover's rule ask the map:
slidefor a circle,sweepfor a box that falls,clearfor whether a spot is free. - Place a
startfor each slot and anactorsentry for each thing on the level.
"world": {
"loader": { "assets": {
"<scene>": { "type": "tilemap", "url": "/games/<game>/assets/<scene>.tmj", "preload": true, "nearest": true }
} },
"tilemap": { "file": "<scene>" },
"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
- Make each level a scene:
<level>.scene.jsonwith its own map and actors,<level>.sim.tshanding out the sim of the scene it shares its kinds with, and an entry in the manager'sscenes. A level that gives its ownworld.loadergives its whole catalogue, the definitions' entry too. - 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.
- Move a seat on by calling
goon the scenemanager row from the rule of an exit or a door.
A generated level
- Write a recipe file in
assets/with its size, layers, algorithm (rooms,cavesorhalls), stairs, actors and itsseed. - Make a theme tileset whose tiles'
typeis the role they draw. - Run mapgen's
buildon the recipe before the game boots, and write what it hands back as<level>.tmjand<level>.actors.json. The same seed makes the same files. - Name both in the scene as for a level drawn by hand.
Checking it
- Test that every start stands
clearof the walls for the player's radius. - Test with nav's
fieldthat every open cell is reachable from every start. - Open the game's
index.htmlas in Starting a game, and walk into every wall.