Making a game

Scene flow

More than one scene: titles, menus, levels, cutscenes and game over.

A game of more than one scene: a title, levels, a game over, and moving seats between them with the scenemanager.

How it is laid out

  • The manager scene, <game>.scene.json, names every scene in its scenemanager prefab: scenes (a name to { file, suspend, enter? }) and entry, the scene every connection enters first.
  • A child scene's prefabs and world are the manager's with its own over them, key by key.
  • Scenes played on one place, a skirmish and its missions or a level by day and by night, share a partial, <name>.partial_scene.json, which is never a scene of its own and is not in scenes.
  • A suspend: true scene nobody is in does not step. A scene is booted once and keeps its rows when seats leave.

Steps

  1. Write the scene: <scene>.scene.json and <scene>.sim.ts beside the manager's, with scenemanager in its plugins, and an entry in the manager's scenes. A second level hands out the sim of the scene it shares its kinds with, export { sim } from './main.sim.ts'; a title or a game-over screen has a sim of its own.
  2. For scenes on one place, put the ground, the world and the actors every one of them places alike in the partial, and have each scene name it as "extends" and hold only what makes it different. A row two scenes place differently, such as each scene's start with its own loadout, is an actor of each scene. A new variation is a new scene file naming the partial.
  3. Name the scene's own kind after no scene: a title scene shows a titlecard.
  4. Move world.defs and world.loader into the manager's world, so every scene inherits them.
  5. Set entry in the manager's prefab.
  6. Make a title or game-over screen a scene with "plugins": ["loader", "scenemanager", "ui"] and no player. Its button sends the seat on with plugins.scenemanager.go(name, ...args).
  7. Move a seat from a rule with w.call(w.find('scenemanager'), 'go', seat, name, ...args). seat is the seat number an act was handed, not the slot.
  8. Carry a score or lives as go's args. They arrive on the next scene's player row as the act arrive, which checks each value's type and range.
  9. Keep every scene name in a definition or the level's world, never in code.
  10. Rewrite <game>.sim.test.ts to start from the new entry.
"prefabs": {
  "scenemanager": {
    "entry": "title",
    "scenes": {
      "title": { "file": "title.scene.json", "suspend": true },
      "main": { "file": "main.scene.json", "suspend": true }
    }
  }
}

Starting a level over

A level a seat returns to is as it was left. Name an enter: { kind, act } in its scenes entry; the act runs for each seat that enters and can spawn the cast again from w.world.scenemanager.actors.

What crosses a move

CrossesDoes not cross
The page's store: volume, rebound keys.The seat's player row and its fields.
go's args, as arrive, into a scene that lists player.The page's actors, plugins, keys and open panels.
The scene left behind, with its rows.Anything past the process; that is persist.

A cutscene

A cutscene with go in its cue file sends the kinds world.cutscene.kinds names on at its end. It plays once per scene.

Checking it

  1. In <game>.sim.test.ts, connect a seat, check it enters the entry, send go, and read the next scene's rows.
  2. A test that reads a scene file to know what to expect loads it with the scenemanager's child, never by importing <scene>.scene.json, which holds only the scene's own part when it extends a partial.
  3. Enter a scene directly from dev.html with file.prefabs.scenemanager.entry = '<scene>'.
  4. Open the game's index.html as in Starting a game, and play from the entry through each scene, and back.