Table of Contents

Struct CharacterResourcesBroadcast

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

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

int

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

int

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

int

Mask

Which of the six values below are present on the wire; see CharacterResourcesMask.

public byte Mask

Field Value

byte

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

int

MaxMana

Maximum mana. Present when MaxMana is set.

public int MaxMana

Field Value

int

MaxStamina

Maximum stamina. Present when MaxStamina is set.

public int MaxStamina

Field Value

int

Sequence

Monotonic per-character counter, incremented on every send.

public ushort Sequence

Field Value

ushort

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

Field Value

int