# ExPilot v0.1.1 - Table of Contents

> An XPilot for the terminal, over ssh, in the browser and on the desktop, on Cauldron.

## Pages

- [ExPilot](readme.md)
- [ExPilot, technically](technical.md)

## Modules

- [ExPilot.Arenas](ExPilot.Arenas.md): ExPilot's arenas on `Cauldron2D.Arenas`: a map each, its world an `ExPilot.Game`,
its robots (`ExPilot.Robot`) and its ledger recorder seated beside it.
- [ExPilot.Art](ExPilot.Art.md): Every picture ExPilot draws, as a `Cauldron2D.Atlas` named `:ex_pilot`.
- [ExPilot.Ball](ExPilot.Ball.md): Treasures and the balls in them, for capture the flag.
- [ExPilot.Client](ExPilot.Client.md): What every client — the terminal's, the browser's, the desktop's — needs from ExPilot,
as `Cauldron2D.Client.Game` asks for it: the title, the keys, the arenas, how a view
is drawn, and the sound and music.
- [ExPilot.Client.LeadersPage](ExPilot.Client.LeadersPage.md): The terminal client's leaders page: today, this week and all time side by side, the
top ten by kills with their kills a death and rounds won, from `ExPilot.Ledger`.
- [ExPilot.Client.SoundPage](ExPilot.Client.SoundPage.md): The "No sound?" page of a served ssh session: the player's sound port on the server,
the player program to run on their machine for each operating system, and the ssh
line whose reverse tunnel carries the sound.
- [ExPilot.Duels](ExPilot.Duels.md): Challenges between two pilots: each is an arena of its own on a map both know, no
robots, the two of them the only ones who may fly (anyone may watch), the first to a
number of kills the winner; the arena closes ten seconds after. The challenged may
decline and the challenger withdraw (`cancel/2`), and a duel nobody has flown for ten
minutes expires; either way the arena goes.
- [ExPilot.Duels.Remote](ExPilot.Duels.Remote.md): A challenge sent to another ExPilot server over its API (`POST <url>/duel`), and a
duel there declined or withdrawn (`POST <url>/duel/cancel`).
- [ExPilot.Game](ExPilot.Game.md): The rules of ExPilot as one pure value, run by `Cauldron2D.World`.
- [ExPilot.Gear](ExPilot.Gear.md): What a ship's items do when their keys are pressed or held, and while their effects
last.
- [ExPilot.Guide](ExPilot.Guide.md): What everything in the arena is: the things on the map, the weapons, and every item
with the key that uses it, in sections of entries with the art the atlas draws them
with. The terminal shows it from the title and the lobby, the browser on its guide page.
- [ExPilot.Items](ExPilot.Items.md): XPilot's items: what they are, where they appear, and what picking one up does.
- [ExPilot.Ledger](ExPilot.Ledger.md): ExPilot's results in `Cauldron2D.Ledger`, kept at
`$XDG_DATA_HOME/expilot/ledger.dets` beside the accounts, with the metrics its boards
rank by: kills, kills a death, rounds won, the best streak of kills without dying,
the longest contact (seconds alive with an enemy within thirty tiles) and laps.
- [ExPilot.Map](ExPilot.Map.md): A classic XPilot map read for play: the block legend, the features on it, and the
options ExPilot honours.
- [ExPilot.Mode](ExPilot.Mode.md): The kinds of arena `ExPilot.Game.mode/1` tells apart, in words and in colour, for every
client's lobby.
- [ExPilot.Music](ExPilot.Music.md): ExPilot's music: pieces written in Strudel, one per mood and kind of arena, each in
four layers — `:drums`, `:bass`, `:pad`, `:lead` — for `Cauldron2D.Audio.Music`.
- [ExPilot.Music.Ctf](ExPilot.Music.Ctf.md): The pieces for a ctf arena, as `ExPilot.Music` lists them: `{name, bpm, %{section => {bars, layers}}}`.
- [ExPilot.Music.Instruments](ExPilot.Music.Instruments.md): The recorded instruments the pieces play beside the synthesised ones, registered with
`TuningFork.Sfz` when the application starts: FreePats' fingered and picked electric
bass and Karoryfer Samples' meatbass, all CC0, fetched from where they are published.

- [ExPilot.Music.Race](ExPilot.Music.Race.md): The pieces for a race arena, as `ExPilot.Music` lists them: `{name, bpm, %{section => {bars, layers}}}`.
- [ExPilot.Music.Score](ExPilot.Music.Score.md): Helpers for writing a piece's Strudel chains.
- [ExPilot.Music.Static](ExPilot.Music.Static.md): The songs a static stage loops, one a kind of arena, as `ExPilot.Music` lists them:
`{name, bpm, %{song: {bars, layers}}}`. Each is a piece of the concert repertoire
played from its score — a MIDI engraving under `priv/scores`, read at compile time
through `ExPilot.Music.Score.part/2` — on the Salamander grand (`piano`, a recorded
Yamaha C5, CC BY 3.0) with a recorded bass (`ExPilot.Music.Instruments`' `fingerbass`
and `pickbass` from FreePats, `meatbass`, a plucked double bass, from Karoryfer Samples,
all CC0), a drum kit and a doubling instrument arranged under it, in four layers,
written to be heard round and round: the last bar leads back to the first and nothing
changes with the fight.
- [ExPilot.Music.Team](ExPilot.Music.Team.md): The pieces for a team arena, as `ExPilot.Music` lists them: `{name, bpm, %{section => {bars, layers}}}`.
- [ExPilot.Race](ExPilot.Race.md): Race mode: the map's checkpoints `A`–`Z` taken in order, a lap at a time.
- [ExPilot.Radar](ExPilot.Radar.md): XPilot's radar on `Cauldron2D.Minimap`: the whole arena in a few rows of braille,
walls in blue, bases grey, the player's ship yellow, teammates blue and enemies red.
With `radar.players?` false in the view (the map's `playersonradar`), only the
player's own ship is marked.
- [ExPilot.Robot](ExPilot.Robot.md): A robot's brain for `Cauldron2D.Robot`: a robot joins a world as `{:robot, n}` and
flies by its view, deciding every few frames here.
- [ExPilot.Server](ExPilot.Server.md): Serve ExPilot: its maps as arenas, over ssh and to browsers, through
`Cauldron2D.Drafter.Server`.
- [ExPilot.Ship](ExPilot.Ship.md): One player's ship: its body, fuel, shield, lives and score, and what it is doing.
- [ExPilot.Shipshape](ExPilot.Shipshape.md): XPilot ship shapes, as players wrote them.
- [ExPilot.Sound](ExPilot.Sound.md): The sound each game event makes.
- [ExPilot.Targets](ExPilot.Targets.md): Targets: the `!` tiles a team defends. Each belongs to the team of the nearest base,
takes three hits from anything but its own team, and comes back a minute after it is
destroyed. Destroying one scores for the shooter's team.
- [ExPilot.Terminal](ExPilot.Terminal.md): ExPilot in a terminal, with the desktop's flow: a title of its own, play here, connect
to a node or a server, host a server, the leaders — the arenas, settings and play
themselves being `Cauldron2D.Drafter.Client` started at its lobby and driven from
here.
- [ExPilot.Weapons](ExPilot.Weapons.md): What a ship can throw besides its cannon shot: torpedoes, smart and heat missiles,
mines, and the laser.
- [ExPilot.Web.ApiController](ExPilot.Web.ApiController.md): ExPilot's own API beside `Cauldron2D.Net.Api` (which serves the token, the arenas,
the stats and the leaders under `/api`): the duels (`GET /api/duels`; `POST
/api/duel` with a `token`, `to`, `arena` and `first_to` to challenge someone; `POST
/api/duel/cancel` with a `token` and the duel's `id` to decline or withdraw it).

- [ExPilot.Web.ArenaChannel](ExPilot.Web.ArenaChannel.md): A browser player in an ExPilot arena, its sound at 44 100 Hz stereo unless the browser asks otherwise (a phone asks for 22 050 Hz mono); see `Cauldron2D.Net.Channel`.
- [ExPilot.Web.ArenaLive](ExPilot.Web.ArenaLive.md): The arena: the canvas the browser draws the world on, the hud beside it, and the
round's end. On a coarse pointer (a phone or a tablet; `?touch=1` or `?touch=0`
forces it, kept in the browser) the page is the game alone — no top bar, no key
hints, nothing to scroll: the canvas fills the screen, a thumbstick steers and,
pushed past the ring at half its travel, thrusts — the harder the push, the more
thrust (`strength` in the input, from a third of full at the ring); buttons fire, shield, fire a missile
and thrust (next ship when watching); the fuel, score and status ride over the
world; `≡` opens the rest of the hud over it, `−`/`+` and a pinch zoom the view out
to the whole arena and back, `⇄` swaps the stick and the buttons between hands (kept
in the browser), `♪` switches the music off and on (kept in the browser, the effects
stay), `⤢` goes full screen and `✕` leaves for the arenas. The sound comes
as 22 050 Hz mono there, a quarter of the desktop's bytes. With a keyboard `+`, `−`
and the wheel zoom and `0` puts the view back, and `♪` in the bar switches the music;
watching, the arrows or a drag (the mouse, a finger) pan the view, the wheel and a
pinch zoom about the pointer or the fingers, and `0` recentres it.

- [ExPilot.Web.Auth](ExPilot.Web.Auth.md): Who a browser player is: login against the server's `Drafter.Accounts`, the signed
token a page hands its socket, and the sound levels kept in the account.
- [ExPilot.Web.Components](ExPilot.Web.Components.md): The pieces ExPilot's pages share: the shell with its top bar (a tab bar along the
bottom on a phone or a tablet, where the top bar is hidden), the badge naming an
arena's kind, and a sprite cut from the sheet.

- [ExPilot.Web.Endpoint](ExPilot.Web.Endpoint.md): The HTTP side of an ExPilot server: the pages, the player socket, the sprite sheet
and the scripts, on the port `ExPilot.Server.start/1` is given as `:http`.

- [ExPilot.Web.GuideLive](ExPilot.Web.GuideLive.md): The guide: what everything in the arena is, with its picture.
- [ExPilot.Web.LeadersLive](ExPilot.Web.LeadersLive.md): The boards: the pilots of today, this week and all time, by kills, kills a death, rounds
won, longest streak, longest contact and laps, over every arena or one of them, from
`ExPilot.Ledger`.

- [ExPilot.Web.LobbyLive](ExPilot.Web.LobbyLive.md): The arenas, who is in them, the way in, and the duels: a challenge to another pilot on an arena, first to a number of kills.
- [ExPilot.Web.LoginLive](ExPilot.Web.LoginLive.md): Log in, or make an account, against the server's accounts.
- [ExPilot.Web.SessionController](ExPilot.Web.SessionController.md): Turns a login token into the browser session cookie, and clears it on logout.
- [ExPilot.Web.SettingsLive](ExPilot.Web.SettingsLive.md): The sound levels of this kind of client — the browser, or a phone or tablet
(`:touch`, told by the page) — kept in the account under their own key, and the
nickname every client plays under.

- [ExPilot.Web.SheetController](ExPilot.Web.SheetController.md): Serves the sprite sheet the browser draws the arena from.
- [ExPilot.Web.UserSocket](ExPilot.Web.UserSocket.md): The player socket: a browser connects with the token its page was given at login and
the kind of client it is (`web` or `touch`), and its channels carry the player's name
and that kind's sound levels.

- [ExPilot.Wx](ExPilot.Wx.md): ExPilot in a window, played with the keys or the mouse: the title, the lobby, the
arena, the summary, the settings, a connect screen and a serve screen, every one
drawn on the same canvas (`ExPilot.Wx.Screens` on `Cauldron2D.Wx.Text`), the arena on
`Cauldron2D.Wx.View`.
- [ExPilot.Wx.Keys](ExPilot.Wx.Keys.md): The desktop's keys: wx key codes and mouse buttons to ExPilot's actions, the same
bindings the browser has.
- [ExPilot.Wx.Screens](ExPilot.Wx.Screens.md): What the desktop's screens look like, as items `Cauldron2D.Wx.Text` draws: the title,
the connect form, the lobby, the settings, the leaders, the summary and the serve form
(the start or stop first, the settings under it), from the window's state.

## Mix Tasks

- [mix ex_pilot.desktop](Mix.Tasks.ExPilot.Desktop.md): Open the desktop client: a wx window that joins a server by URL, a node, or the
arenas this app serves itself from its Server page.
- [mix ex_pilot.ledger](Mix.Tasks.ExPilot.Ledger.md): Open the ledger at `$XDG_DATA_HOME/expilot/ledger.dets` and forget the results of every
name matching a pattern, `*` standing for any run of characters. The load tool's
accounts are `load_1`, `load_2` and so on.
- [mix ex_pilot.listen](Mix.Tasks.ExPilot.Listen.md): Play the sound of an ExPilot session served elsewhere through this machine's speaker:
run it here, then connect with `ssh -R <your port>:127.0.0.1:4713 …`.
- [mix ex_pilot.load](Mix.Tasks.ExPilot.Load.md): Run `Cauldron2D.Net.Load` against an ExPilot server started elsewhere
(`mix ex_pilot.serve` in another terminal, or another machine), with the players
holding ExPilot's own actions: a report every few seconds, a summary at the end, and
every report and the summary written as JSON lines to a file as the run goes.
`Enter` ends the run early with the summary of what was measured; `Ctrl-C` kills
the run, and the file has every report up to it.
- [mix ex_pilot.maps](Mix.Tasks.ExPilot.Maps.md): Fetch the 131 classic XPilot maps from SourceForge into `priv/maps`.
- [mix ex_pilot.play](Mix.Tasks.ExPilot.Play.md): Offer every map under `priv/maps` (or `--maps`) as an arena and run the client in this
terminal, with sound through this machine's speaker. An arena's world starts when it is
joined.
- [mix ex_pilot.serve](Mix.Tasks.ExPilot.Serve.md): Start the ExPilot ssh server and keep it running.
- [mix ex_pilot.terminal](Mix.Tasks.ExPilot.Terminal.md): Run `ExPilot.Terminal`: the desktop's flow in a terminal — play the arenas this
program carries, connect to a node or a server, host a server for others, see the
leaders.

