# `Cauldron2D.Drafter.Client.Settings`
[🔗](https://github.com/jaman/cauldron/blob/v0.1.3/cauldron_2d_drafter/lib/cauldron_2d/drafter/client/settings.ex#L1)

A player's settings: which keys do what, whether the pointer steers, how loud things
are, how the arena is drawn.

Kept per kind of client — the terminal, a desktop, a browser, a phone: a kind is any
atom, `:terminal` the default — on disk under
`$XDG_CONFIG_HOME/<game>/<player>.settings` for the terminal and
`<player>.<kind>.settings` for another kind, `<game>` being the game's title in lower
case with runs of other characters as `_` (or under `~/.config`), and, when the
player has an account, in its props as well: `settings` for the terminal,
`settings_<kind>` for another kind. `load/4` reads the file over any account props;
`save/5` writes both.

    settings = Cauldron2D.Drafter.Client.Settings.load(MyGame.Client, "alice", account_props)
    settings.bindings[:launch]
    Cauldron2D.Drafter.Client.Settings.load(MyGame.Client, "alice", account_props, kind: :desktop)

# `display`

```elixir
@type display() :: :auto | :braille | :glyphs
```

How the arena is drawn: pixels where the terminal has them, else glyphs; braille; or glyphs.

# `fps`

```elixir
@type fps() :: :auto | pos_integer()
```

Frames per second, or `:auto` for the terminal's best.

# `item`

```elixir
@type item() ::
  :preset
  | {:action, Cauldron2D.Input.action()}
  | :pointer
  | :sfx
  | :music
  | :display
  | :fps
```

One line of the settings screen: the preset, an action's binding, or a switch or level.

# `t`

```elixir
@type t() :: %Cauldron2D.Drafter.Client.Settings{
  bindings: Cauldron2D.Input.keymap(),
  display: display(),
  fps: fps(),
  music: float(),
  pointer: boolean(),
  preset: atom(),
  sfx: float()
}
```

# `bind`

```elixir
@spec bind(t(), Cauldron2D.Input.action(), Cauldron2D.Input.key_spec()) :: t()
```

Add `key` to what `action` is bound to, after the keys it has; a key already there is not added twice.

# `choose_preset`

```elixir
@spec choose_preset(t(), module(), atom()) :: t()
```

Switch to `preset` of `game`, dropping individual rebindings.

# `frame_rate`

```elixir
@spec frame_rate(t(), atom() | nil | :unprobed) :: pos_integer()
```

The frame rate to draw at: the setting, or for `:auto` the terminal's best — 15 where
every frame is a full image (iTerm2, sixel), 30 elsewhere.

# `frame_rates`

```elixir
@spec frame_rates(module()) :: [fps()]
```

The frame rates the settings screen offers: the game's `frame_rates/0`, else `:auto`, 15, 30, 50 and 60.

# `items`

```elixir
@spec items(module()) :: [item()]
```

The settings screen's items for `game`, top to bottom.

# `keys_text`

```elixir
@spec keys_text(t(), Cauldron2D.Input.action()) :: String.t()
```

The keys bound to `action`, as text for a screen.

# `load`

```elixir
@spec load(module(), String.t(), map(), keyword()) :: t()
```

Settings for `player` of `game` on a `:kind` of client (default `:terminal`): the file on disk over `account_props` over the defaults.

# `new`

```elixir
@spec new(module(), map()) :: t()
```

Settings for `game` with `overrides` applied over the game's first preset.

# `nudge`

```elixir
@spec nudge(t(), :sfx | :music, number()) :: t()
```

Move a 0.0–1.0 level by `delta`, clamped.

# `path`

```elixir
@spec path(module(), String.t(), atom()) :: Path.t()
```

Where `player`'s settings for `game` live, for a kind of client (default `:terminal`).

# `presets`

```elixir
@spec presets(module()) :: [atom()]
```

The presets in the order the settings screen offers them: the game's `keymaps/0` order for a keyword list, by name for a map.

# `prop_key`

```elixir
@spec prop_key(atom()) :: atom()
```

The account prop a kind's settings are kept under: `:settings` for the terminal, `:settings_<kind>` for another.

# `rebind`

```elixir
@spec rebind(t(), Cauldron2D.Input.action(), Cauldron2D.Input.key_spec()) :: t()
```

Bind `action` to `key` alone, in place of whatever it had.

# `save`

```elixir
@spec save(t(), module(), String.t(), GenServer.server() | nil, keyword()) :: :ok
```

Write the settings to disk, and to the account when `accounts` is given, for a `:kind` of client (default `:terminal`).

# `step_display`

```elixir
@spec step_display(t(), -1 | 1) :: t()
```

The next or previous display choice, in the order auto, braille, glyphs, wrapping.

# `step_fps`

```elixir
@spec step_fps(t(), module(), -1 | 1) :: t()
```

The next or previous frame rate choice of `game`'s `frame_rates/1`, wrapping.

# `surface_mode`

```elixir
@spec surface_mode(t()) :: nil | :braille | :text
```

The surface mode for the display setting: `nil` lets the terminal decide.

# `to_props`

```elixir
@spec to_props(t()) :: map()
```

The map kept in account props and on disk.

# `unbind_last`

```elixir
@spec unbind_last(t(), Cauldron2D.Input.action()) :: t()
```

Drop the last key `action` is bound to; an action with no keys is unchanged.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
