# `Monty.Frameworks.Environments.PositioningProcedures.GetGoodViewFactory`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/frameworks/positioning_procedures/get_good_view_factory.ex#L1)

Builds a `GetGoodView` for whichever object an episode is about.

Mirrors
`tbp/monty/frameworks/environments/positioning_procedures.py::GetGoodViewFactory`.
The target's semantic id is not known until the scene is built, so a config can
only describe the procedure's settings here and ask for the procedure later.

The defaults are Monty's own: half the view, or three centimetres away.

# `t`

```elixir
@type t() :: %Monty.Frameworks.Environments.PositioningProcedures.GetGoodViewFactory{
  agent_id: atom() | String.t(),
  allow_translation: boolean(),
  good_view_distance: float(),
  good_view_percentage: float(),
  max_orientation_attempts: integer(),
  multiple_objects_present: boolean(),
  sensor_id: atom() | String.t()
}
```

# `create`

A procedure for `target_semantic_id`, as the module and state a behaviour is
called through.

`{module, state}` is how this port carries every behaviour implementation: a
struct says what a procedure is, and the module named after it is what knows how
to run it.

# `from_config`

```elixir
@spec from_config(map()) :: {:ok, t()} | {:error, term()}
```

The factory a composed config entry describes, or why it is not one this port
can build.

Every shipped evaluation config lists two of these: a view finder allowed to
walk towards the object, and a patch camera that may only turn —
`allow_translation: false` — because by then the body is where it should be and
only the aim is wrong.

# `new`

```elixir
@spec new(keyword()) :: t()
```

A factory for `:agent_id`'s procedure, with Monty's defaults for the rest.

---

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