Struct CharacterResourcesBroadcast
Carries a character's resources to everyone observing it.
public struct CharacterResourcesBroadcast : IBroadcast
- Implements
-
IBroadcast
- Inherited Members
Remarks
Observers learn a peer's health from the reconcile stream, and that stream reaches them only
while state forwarding is on. Once forwarding is disabled — which is what makes 100-200
players per scene affordable — a peer's CharacterAttributeController would never be
updated on anyone else's client, and UITKTarget reads exactly that to draw a target's
health bar. This is the replacement path.
Rate limited and change gated by the sender, so an idle character at full health costs nothing and a fight costs a handful of updates a second rather than thirty. The gate is split: health and the maxima on one schedule, mana and stamina on a far coarser one, because no observer-facing readout draws a peer's mana or stamina at all. See ObservedResourcePushScheduler.
Field gated as well as change gated. Mask names which of the six values
this message actually carries; the rest are absent from the wire and the receiver leaves its
own copy alone. The three maxima move on an equip, a buff or a level and at no other time, so
before the mask existed roughly forty per cent of every push was a number the observer had
held since the spawn payload. This is the same redundancy the reconcile path solved for the
same struct in CharacterAttributeResourceStateSerializer.WriteDelta.
Fields
CharacterObjectID
NetworkObject id of the character these resources belong to.
public int CharacterObjectID
Field Value
Remarks
Required because a broadcast is not addressed to a NetworkBehaviour the way an RPC is — the handler is registered once per client and has to be told which character it is about.
Health
Current health, in whole units. Present when Health is set.
public int Health
Field Value
Remarks
Integers rather than floats, for all three current values. An observer renders a bar at whole-unit precision — the sender's change gate already compares at whole units, so nothing finer was ever visible — and FishNet packs an int to one or two bytes where a float is always four.
The whole-unit form is also what makes the mask exact. The sender sets a bit when the ROUNDED value differs from the rounded value it last sent, which is precisely what the receiver is holding, so an omitted field can never drift.
Mana
Current mana, in whole units. Present when Mana is set.
public int Mana
Field Value
Mask
Which of the six values below are present on the wire; see CharacterResourcesMask.
public byte Mask
Field Value
Remarks
A field whose bit is clear is absent from the message entirely and its value in this struct is meaningless — the receiver must leave its own copy untouched rather than applying a default. Zero is a legal mask (a confirmation of nothing is never sent, but a corrupt or future-shaped stream can produce one) and means "apply nothing".
Every present field is an ABSOLUTE value, never a difference. That is the whole reason a mask is safe on an unreliable channel: the message is self-describing for what it carries, so a receiver that missed the previous push still applies these fields exactly right. What a loss can cost is an omitted field staying at its old value, and Confirm — which sets every bit and rides the reliable channel — is what bounds that.
MaxHealth
Maximum health. Present when MaxHealth is set.
public int MaxHealth
Field Value
MaxMana
Maximum mana. Present when MaxMana is set.
public int MaxMana
Field Value
MaxStamina
Maximum stamina. Present when MaxStamina is set.
public int MaxStamina
Field Value
Sequence
Monotonic per-character counter, incremented on every send.
public ushort Sequence
Field Value
Remarks
The stream is unreliable, so it is also UNORDERED: two updates sent a few ticks apart can arrive the wrong way round, and the receiver applies whichever landed last. During a fight that means a health bar that jumps back up after a hit, and at the end of one it meant a corpse still showing health — the reorder is most likely exactly when updates are most frequent. The receiver drops anything not newer than what it already applied.
Compared with wrapping arithmetic, so the counter may roll over freely. It is per character and reset with the rest of the observed state when a pooled object is reused.
Stamina
Current stamina, in whole units. Present when Stamina is set.
public int Stamina