Cauldron2D.World (Cauldron2D v0.1.3)

Copy Markdown View Source

Runs a Cauldron2D.Game at a fixed tick and keeps its players supplied with views.

{:ok, world} = Cauldron2D.World.start_link(game: MyGame, game_opts: [seed: 1], hz: 50)

Players join from their own processes with Cauldron2D.Player.join/3; each tick the world applies the input they sent, steps the game once per due step, and sends every player {:cauldron_frame, %{tick: n, view: view, events: events}}. A player whose process exits is removed. Every join and leave is told to the subscribers of Cauldron2D.World.Presence, and each tick's events to those of Cauldron2D.World.Events. stats/1 says how the world is keeping up.

A world started with tick: :on_input has no clock: it runs one step, with dt of 1 / hz, each time a player's input arrives, and sends views after it. That is the world for a turn-based game. pause/1 stops a clocked world stepping until resume/1; time paused is not owed afterwards, and input sent meanwhile is applied on resume.

Options

  • :game — the module implementing Cauldron2D.Game. Required
  • :game_opts — passed to its init/1. Default []
  • :state — a game state to start from instead of calling init/1, as snapshot/1 returned it. Default none
  • :hz — ticks per second, and the dt of a step. Default 50
  • :tick:fixed, stepping on the clock, or :on_input. Default :fixed
  • :record — keep a Cauldron2D.Replay of joins, leaves and input. Default false
  • :name — a GenServer name. Default none

Summary

Types

How the world is keeping up: the players present, the ticks a second it is set to, the steps run so far, and over the last 256 ticks that ran a step — how many they were, the microseconds a tick took (stepping and sending every view) as a mean, a 95th percentile and the longest, and behind, how many of them had more than one step due.

Functions

Returns a specification to start this module under a supervisor.

The game module the world runs.

Send player id's current input, applied before the next tick.

Add the calling process as player id. {:error, reason} is the game's refusal.

Remove player id.

Stop stepping until resume/1. Nothing for a world stepping on input.

Whether the world is paused.

The ids of the players present.

The replay recorded so far, or nil when the world was not started with record: true.

Step again, from now.

The game's current state.

Start a world; see the module documentation for the options.

How the world is keeping up; see stats/0.

Types

player_id()

@type player_id() :: term()

stats()

@type stats() :: %{
  players: non_neg_integer(),
  hz: number(),
  steps: non_neg_integer(),
  ticks: non_neg_integer(),
  tick_us: %{
    mean: non_neg_integer(),
    p95: non_neg_integer(),
    max: non_neg_integer()
  },
  behind: non_neg_integer()
}

How the world is keeping up: the players present, the ticks a second it is set to, the steps run so far, and over the last 256 ticks that ran a step — how many they were, the microseconds a tick took (stepping and sending every view) as a mean, a 95th percentile and the longest, and behind, how many of them had more than one step due.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

game(world)

@spec game(GenServer.server()) :: module()

The game module the world runs.

input(world, id, input)

@spec input(GenServer.server(), player_id(), Cauldron2D.Input.state()) :: :ok

Send player id's current input, applied before the next tick.

join(world, id, props)

@spec join(GenServer.server(), player_id(), map()) :: :ok | {:error, term()}

Add the calling process as player id. {:error, reason} is the game's refusal.

leave(world, id)

@spec leave(GenServer.server(), player_id()) :: :ok

Remove player id.

pause(world)

@spec pause(GenServer.server()) :: :ok

Stop stepping until resume/1. Nothing for a world stepping on input.

paused?(world)

@spec paused?(GenServer.server()) :: boolean()

Whether the world is paused.

players(world)

@spec players(GenServer.server()) :: [player_id()]

The ids of the players present.

replay(world)

@spec replay(GenServer.server()) :: Cauldron2D.Replay.t() | nil

The replay recorded so far, or nil when the world was not started with record: true.

resume(world)

@spec resume(GenServer.server()) :: :ok

Step again, from now.

snapshot(world)

@spec snapshot(GenServer.server()) :: term()

The game's current state.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Start a world; see the module documentation for the options.

stats(world)

@spec stats(GenServer.server()) :: stats()

How the world is keeping up; see stats/0.