# `Cauldron2D.States`
[🔗](https://github.com/jaman/cauldron/blob/v0.2.2/cauldron_2d/lib/cauldron_2d/states.ex#L1)

State tables: an actor's animation and behaviour as data, each state a picture shown for
a number of ticks, an action run on entering it, and the state that follows.

    table = %{
      stand: %{picture: {"TROO", 0}, tics: 10, action: :look, next: :stand_b},
      stand_b: %{picture: {"TROO", 1}, tics: 10, action: :look, next: :stand},
      die: %{picture: {"TROO", 8}, tics: 8, action: :scream, next: :dead},
      dead: %{picture: {"TROO", 12}, tics: -1, action: nil, next: nil}
    }

    actor = Cauldron2D.States.enter(actor, table, :stand, &MyGame.act/2)
    actor = Cauldron2D.States.tick(actor, table, &MyGame.act/2)

An actor is a map; entering a state sets its `:state`, `:tics` and `:picture` and then
runs `act.(actor, action)` with the state's action, which returns the actor and may
itself `enter/4` another state. A state of zero ticks is passed straight through to the
next. A state of `-1` ticks lasts until something enters another. Entering `nil`, or a
`next` of `nil`, sets `:state` to `nil`: the actor is finished and the caller removes it.

`picture` and `action` are the game's terms; the table only orders them. `tick/3`
counts a state down by one tick and enters the next when it runs out.

# `actor`

```elixir
@type actor() :: %{
  optional(:state) =&gt; name() | nil,
  optional(:tics) =&gt; integer(),
  optional(atom()) =&gt; term()
}
```

# `name`

```elixir
@type name() :: term()
```

# `state`

```elixir
@type state() :: %{
  picture: term(),
  tics: integer(),
  action: term(),
  next: name() | nil
}
```

# `table`

```elixir
@type table() :: %{required(name()) =&gt; state()}
```

# `enter`

```elixir
@spec enter(actor(), table(), name() | nil, (actor(), term() -&gt; actor())) :: actor()
```

Enter state `name`, running actions and passing through zero-tick states.

# `tick`

```elixir
@spec tick(actor(), table(), (actor(), term() -&gt; actor())) :: actor()
```

One tick: count the state down and enter the next when it runs out.

---

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