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 itsviewmodelforclientis the player; otherwise, with noviewmodelforclient, its effects haveEF_NODEPTHTEST(8192), itspvsflagslow 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/2at the player's eye and at itsview2), the entity at the end of itstag_entitychain (up to ten long) standing in for it, which passes as the player and fails as another player'sviewmodelforclient; - its
nodrawtoclientis not the player, and itsdrawonlytoclientis none or the player; - the player's
dimension_seeshares a bit with itsdimension_seenordimension_ghost, unless it is the player or the player'sview2. Undeclared,dimension_seeanddimension_seenread as 255.
Summary
Functions
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.
The entities player viewer has been sent and still has, in order.
Start keeping entity bits for player viewer.
Types
@type update() :: {:update, pos_integer(), binary()} | {:remove, pos_integer()}
An entity sent to a player, or taken away.
Functions
@spec frame(QuakeServer.Server.t(), [non_neg_integer()]) :: {%{required(non_neg_integer()) => [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.
@spec held(QuakeServer.Server.t(), non_neg_integer()) :: [pos_integer()]
The entities player viewer has been sent and still has, in order.
@spec watch(QuakeServer.Server.t(), non_neg_integer()) :: QuakeServer.Server.t()
Start keeping entity bits for player viewer.