Making a game
Writing the look
How a game looks in 2D or 3D: renderers, sky, light, sea and particles.
How a game appears is set by the plugins its scene lists and by the <kind>.client.ts of each kind it draws. Every colour, size, light and camera number goes in the scene file or in a data file the scene's catalogue names, never in code.
Choose a renderer
- List one renderer in the scene's
plugins: render2d for a PixiJS stage, or render3d for a three.js scene with points in metres, y up. - Under render2d with a
world.render2d, give every size on a definition in the world's units and draw it scaled byrender2d.ground().
Switch a scene to 3D
- In
<scene>.scene.json, putrender3din place ofrender2dand give it acamera,shadowsand tone mapping. - Add the light and sky, and the ground (below).
- Change every
posto[x, y, z]in metres, and the definitions' speeds and sizes to metres. - Redraw every kind's
.client.tsagainst render3d.
Draw a kind
- A kind drawn from a sheet, a rigged model, still solids or particles is listed in that plugin's table and needs no look file.
- Otherwise write
games/<game>/<kind>.client.tswithsetup,tickandremove, reading sizes and colours off the definition. - Pass every 3D material through
render3d.dress, so rain, snow and cloud shadow reach it, and setcastShadowandreceiveShadowon each mesh. - Set a turn whole, as a quaternion:
mesh.quaternion.setFromAxisAngle(up, row.data.turn), orquaternion.fromArrayfor a row that carries one. One Euler angle set alone,mesh.rotation.y = turn, turns the long way round every frame once the turn passes 90°. - When a look puts its object somewhere new rather than along its way, a door to elsewhere or a respawn, raise its
userData.teleporton that frame, as Smooth gameplay sets out. - Read the camera and the store in
tick, notsetup.
Sky, ground and the rest
- Sky, sun, weather and fog: skydome3d, a row with one
{ "is": "skydome3d" }actor and its weathers file in the catalogue. For fixed lights and a flat floor, use environment3d instead. - Ground: terrain3d, its colours and detail in its field file.
- Sea: ocean3d, a row with the prefab
{ "t": 0 }. - Trees and rocks: scatter3d.
- Particles: particle3d or particle2d, a ledger row and an effects file.
- Darkness and lights in 2D: light2d, its layer the last of
world.render2d.layers.
List skydome3d, terrain3d, ocean3d and scatter3d before render3d, and sprite2d before render2d; listed after, they draw one frame behind.
Connect them with mods
One plugin uses another's knowledge through a mod named in its world.<p>.mods:
world.skydome3d.mods.land: "terrain3d"stands rain splashes on the land.world.ocean3d.mods:lightandwindfromskydome3d,landfromterrain3dfor a seabed.world.scatter3d.mods:landandgroundfromterrain3d.
"plugins": ["loader", "scenemanager", "player", "terrain3d", "skydome3d", "render3d"]
Checking it
- Give the camera a
farpast the sky dome's radius, or the sky draws black. - Test each look in
<kind>.client.test.ts: size and colour from the definition, standing on the row'spos, dressed, and disposed when the row ends. - Open the game's
index.htmlas in Starting a game, and look at the sky, the ground and each thing up close from several angles. - For a thing that judders, flips or turns the long way, record what is drawn for it every frame with render3d's
drew(f), beside the row's value it came from and the step. The frame where the drawn value leaves the row's is the fault, and a single Euler angle set alone is the first thing to look for.