# `Cauldron2D.Tuning`
[🔗](https://github.com/jaman/cauldron/blob/v0.1.3/cauldron_2d/lib/cauldron_2d/tuning.ex#L1)

Every number that decides how a game plays, in one value the game carries in its
state and a settings page can show and change.

    spec = [
      ball_speed: [default: 10.0, limits: {4.0, 24.0}, doc: "tiles a second"],
      drop_chance: [default: 7],
      widths: [default: %{narrow: 2.0, wide: 5.5}]
    ]

    tuning = Cauldron2D.Tuning.new(spec, ball_speed: 14.0)
    Cauldron2D.Tuning.get(tuning, :ball_speed)
    Cauldron2D.Tuning.put(tuning, :ball_speed, 99.0)   # 24.0, the top of its range

A setting with `:limits` is clamped by `put/3` and moved by `step/3` in twentieths of
its range; one without takes any value. `describe/1` lists the settings in the order
declared, for a settings page.

# `key`

```elixir
@type key() :: atom()
```

# `spec`

```elixir
@type spec() :: [{key(), keyword()}]
```

# `t`

```elixir
@type t() :: %Cauldron2D.Tuning{spec: spec(), values: %{required(key()) =&gt; term()}}
```

# `describe`

```elixir
@spec describe(t()) :: [
  %{
    key: key(),
    value: term(),
    limits: {number(), number()} | nil,
    doc: String.t() | nil
  }
]
```

Every setting as `%{key, value, limits, doc}`, in the order declared.

# `get`

```elixir
@spec get(t(), key()) :: term()
```

The value of `key`; raises `KeyError` for a key not in the spec.

# `keys`

```elixir
@spec keys(t()) :: [key()]
```

The setting keys, in the order declared.

# `limits`

```elixir
@spec limits(t(), key()) :: {number(), number()} | nil
```

The `{low, high}` `put/3` clamps `key` to, or `nil` for a setting without limits.

# `new`

```elixir
@spec new(spec(), keyword() | map()) :: t()
```

A tuning from `spec` with `overrides` over the defaults; an override for a key not in the spec raises `KeyError`.

# `put`

```elixir
@spec put(t(), key(), term()) :: t()
```

Change `key` to `value`, clamped into its limits when it has them; raises `KeyError` for a key not in the spec.

# `step`

```elixir
@spec step(t(), key(), integer()) :: t()
```

Move `key` by `steps` twentieths of its range, or by `steps` itself when it has no limits.

---

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