The drafter application that puts a Cauldron2D.World in front of one player.
Runs a game's client module — one implementing Cauldron2D.Client.Game —
through its screens: a title, a lobby listing the arenas, settings, the arena itself,
and a summary when the game's outcome/1 says play is over for this player. It holds the player's input, their audio, and their connection to the world.
An arena whose world is {module, opts} is this player's alone: the client starts
a Cauldron2D.World for it when the player joins and stops it when they leave, and
p pauses and resumes it. A game whose lobby?/0 is false goes from the title
straight into its first arena, and back to the title from it.
Drafter.Server.start_ssh(Cauldron2D.Drafter.Client,
auth: {:accounts, accounts},
tunnel: true,
mount_props: %{game: MyGame.Client, accounts: accounts}
)Mount props
:game— the client module. Required:username— the player's name, set by the ssh transport. Default"player":sink— aTuningFork.Sinkmodule or{module, opts}this player's audio plays through. Default: the game'ssink/1given all the mount props, elseTuningFork.Sink.Speakerwhen that package is present, else silence:settings— the mapCauldron2D.Drafter.Client.Settings.to_props/1produced, from the account props; a settings file for the player overrides it. Default: the game's first preset:accounts— theDrafter.Accountsserver settings are saved to. Default: none:kind— the kind of client this is, the key its settings are kept under (seeCauldron2D.Drafter.Client.Settings). Default:terminal:start— the first screen,:titleor:lobby. Started at the lobby, the client has no title of its own: going back from the lobby (Escorq) stops it, as quitting from the title does. Default:title
Every other mount prop is the game's, read by its sink/1, pages/1 and arenas/1.
Embedding
A game with screens of its own — its own title, a menu, pages that take input —
runs its own Drafter.App and drives this one from it: it keeps the client's state
from mount/1 (with start: :lobby), and hands it its events, messages and timers
through handle_event/2, handle_event/3, on_message/2 and on_ready/1, draws
render/1, and calls unmount/1 when done. A {:stop, reason} from the client
is its wish to end: the game takes its screens back. The game's use Drafter.App
needs the same options this module's has — key_release: true, cell_size: true, frame_pacing: :always — and its refresh_rate/0 should be refresh_rate/0 here.
Tracing
With CAULDRON_TRACE set (see Cauldron2D.Trace), the client writes every key and
mouse event it steers with (key, mouse), every input it sends the world (input,
with the actions held and the aim in tiles) and every frame the world sends back
(frame, with its tick), so mix cauldron.report --from mouse --to frame measures
the way round.
Keys
The client's own keys are default_keys/0, each replaceable or dropped by the game's
client_keys/0; what follows describes the defaults. In the arena t opens a line
to talk to everyone in it — Enter sends, Esc cancels, and no key steers while it
is open. Esc goes back: settings to where it was opened from, arena to lobby, lobby
to title, title out of the program. q quits the arena for the lobby too, and goes
to the title from the lobby. ^Q and ^C quit from anywhere. ? shows the arena's key hints and hides
them again; held, it shows them until released. The fps key, bound only when the
game binds it, shows under the arena how many frames a second the world sends and
hides it again. = (or +) and - zoom the arena in and out through the levels
Cauldron2D.Drafter.Surface.zoom_levels/2 gives for the display in use, the wheel
too (one step for the events a notch sends within 150 ms), and 0 puts the zoom
back; the zoom shows under the world while it is not
native. Watching (joined with w), the arrows and a drag with the left button pan
the view, the wheel zooms about the pointer, and 0 recentres; flying, the view
stays on the ship and the wheel zooms about it. A page the game adds (pages/1)
opens from the title on its key; Esc or q closes it.
Title: Enter plays, s opens settings, h the guide, q quits. Lobby: ↑/↓
pick an arena, t a team where the arena has them, Enter joins, w watches, s
opens settings, c chats and Enter on an empty line leaves the chat. Settings: ↑/↓ move over
the items — preset, each action's binding, pointer steering, effects level, music
level, display (pixels where the terminal has them, braille, or glyphs), frame rate
(auto picks the terminal's best) — ←/→ change the item under the cursor, Enter on a binding then
a key or a mouse button adds it to the binding, Backspace removes the binding's last
key, Esc during a rebind cancels it. Arena: the game's bindings; Tab
opens settings without leaving the ship; the pointer steers only when pointer
steering is on, and a key bound to one of the game's steering/0 actions takes over
from it until the pointer moves again.
Summary
Functions
The game's arenas, from its arenas/1 given the mount props.
The client's keys by action — a key, or a list of keys — before the game's client_keys/0 is applied.
The point the arena is drawn around: the scene's focus moved by the pan.
The state with its pan dropped when the scene's :subject is not the one the pan was taken on; a scene with no subject keeps the pan.
Callback implementation for Drafter.App.on_timer/2.
Whether the player's own world is paused.
The zoom levels this client steps through: Cauldron2D.Drafter.Surface.zoom_levels/2 for the game's atlas and the display in use.
Functions
@spec arenas(map()) :: [Cauldron2D.Client.Game.arena()]
The game's arenas, from its arenas/1 given the mount props.
The client's keys by action — a key, or a list of keys — before the game's client_keys/0 is applied.
@spec focus(map(), Cauldron2D.Client.Game.scene()) :: {number(), number()}
The point the arena is drawn around: the scene's focus moved by the pan.
@spec follow(map(), Cauldron2D.Client.Game.scene()) :: map()
The state with its pan dropped when the scene's :subject is not the one the pan was taken on; a scene with no subject keeps the pan.
Callback implementation for Drafter.App.on_timer/2.
Whether the player's own world is paused.
The zoom levels this client steps through: Cauldron2D.Drafter.Surface.zoom_levels/2 for the game's atlas and the display in use.