# `QuakeServer.Network`
[🔗](https://github.com/jaman/quake_server/blob/v0.1.0/lib/quake_server/network.ex#L1)

FTE's delivery of the entities a program sends itself (`SendEntity`) to the client
programs of the players watching (`sv_ents.c`).

    server = QuakeServer.Network.watch(server, 1)
    {%{1 => updates}, server} = QuakeServer.Network.frame(server, [1])
    updates #=> [{:update, 37, <<...>>}, {:remove, 40}]

`frame/2` runs once a server frame (`SV_SendClientMessages`). First every watching
player keeps the bits of each live entity's `SendFlags` (`SV_ProcessSendFlags`). Then
each player being sent a packet is first given the sounds and particle effects it lacks
(`QuakeServer.Precaches`), then its updates (`SV_EmitCSQCUpdate`): for each
entity with a `SendEntity` the player may see, in order, that function runs with `self`
the entity and as parameters the player and the kept bits in three 24-bit pieces (an
entity the player does not have gets every bit), and what it writes to `MSG_ENTITY` is
the update when it returns true. An entity the player has is removed when its function
returns false, or when it is no longer among those the player may see, either unless
its `pvsflags` has bit 128 (`PVSF_NOREMOVE`); one the player has whose bits are
unchanged is passed over. Last `SendFlags` is cleared (`SV_CleanupEnts`) up to the
highest entity that had some, and an entity whose `Version` differs from the count the
server keeps for it (`QuakeServer.Edicts.free/2` counts it up) gets `SendFlags` -1.
Nothing is kept until a player watches.

The player may see an entity (`SV_Snapshot_BuildQ1`) when it is live, its
`customizeentityforclient` (run with `self` it and `other` the player) returns true
where it has one, and:

  * it is the player or the player's `view2`, or its `viewmodelforclient` is the
    player; otherwise, with no `viewmodelforclient`, its effects have `EF_NODEPTHTEST`
    (8192), its `pvsflags` low bits are 3 (`PVSF_IGNOREPVS`), or 2 (`PVSF_USEPHS`)
    except on a Quake map with a PHS built (`QuakeServer.Multicast.phs?/1`), where its
    origin must be where the player's origin can be heard
    (`QuakeServer.Visibility.heard/2`); or else it touches a leaf of
    the player's fat PVS (`QuakeServer.Visibility.fat/2` at the player's eye and at
    its `view2`), the entity at the end of its `tag_entity` chain (up to ten long)
    standing in for it, which passes as the player and fails as another player's
    `viewmodelforclient`;
  * its `nodrawtoclient` is not the player, and its `drawonlytoclient` is none or the
    player;
  * the player's `dimension_see` shares a bit with its `dimension_seen` or
    `dimension_ghost`, unless it is the player or the player's `view2`. Undeclared,
    `dimension_see` and `dimension_seen` read as 255.

# `update`

```elixir
@type update() :: {:update, pos_integer(), binary()} | {:remove, pos_integer()}
```

An entity sent to a player, or taken away.

# `frame`

```elixir
@spec frame(QuakeServer.Server.t(), [non_neg_integer()]) ::
  {%{required(non_neg_integer()) =&gt; [update()]}, QuakeServer.Server.t()}
```

Run a server frame's delivery: keep the bits for every watching player, give the
updates for each watching player in `sending`, and clear `SendFlags`.

# `held`

```elixir
@spec held(QuakeServer.Server.t(), non_neg_integer()) :: [pos_integer()]
```

The entities player `viewer` has been sent and still has, in order.

# `watch`

```elixir
@spec watch(QuakeServer.Server.t(), non_neg_integer()) :: QuakeServer.Server.t()
```

Start keeping entity bits for player `viewer`.

---

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