Table of Contents

Class AbilityObserverBroadcastSerializers

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Hand written wire format for AbilityActivatedBroadcast.

public static class AbilityObserverBroadcastSerializers
Inheritance
AbilityObserverBroadcastSerializers
Inherited Members

Remarks

A cast broadcast goes to every observer of the caster, and a channelled ability sends one per tick it is held, so its size is paid far more often than its field count suggests. The generated serializer wrote all eleven fields unconditionally — three world vectors, a quaternion and two full ticks — for every mode, about 65-73 bytes. Most of that is dead weight in any given mode.

Two observations shape this format:

  • A Camera spawn pose is a pure function of the aim origin, the aim direction and the ability's range — all of which the observer either receives or reads off the template. So Camera carries aim (12 + up to 5 bytes) and omits the pose; every other mode carries the pose (12 + 8 bytes) and omits the aim, because those poses come off transforms the observer holds interpolated and cannot reproduce.
  • SpawnTick and ServerTick are close together in practice — identical for a server driven NPC, and a fraction of a second apart for a player, whose replicate tick runs a buffer ahead of the server's. The spawn tick therefore travels as a signed 16-bit offset, with a full width fallback for the case where the two domains are genuinely far apart (a client that has just resynchronised, or an unset tick).

The mode and the two shape flags share one byte. Everything else uses FishNet's packed encoding, which is already variable width for the ids.

Discovered by FishNet's codegen through the Write*/Read* naming convention and applied across assemblies because the struct carries [UseGlobalCustomSerializer].

Fields

MAX_LEARNED_EVENTS

Hard cap on the crafted event ids carried by one AbilityLearnedObserverBroadcast.

public const int MAX_LEARNED_EVENTS = 64

Field Value

int

Remarks

An ability's event count is bounded by its template's AdditionalEventSlots plus the events baked into the template, which is a handful. The cap exists so the count fits one byte and so a malformed or hostile message cannot make the reader allocate an arbitrarily large array before the stream runs out.

Methods

ReadAbilityActivatedBroadcast(Reader)

Reads an AbilityActivatedBroadcast written by the method above.

public static AbilityActivatedBroadcast ReadAbilityActivatedBroadcast(this Reader reader)

Parameters

reader Reader

Returns

AbilityActivatedBroadcast

Remarks

Fields that a given mode does not carry come back at their defaults — Vector3.zero, Quaternion.identity, and -1 for an absent target — which is exactly what the receiving side expects: the handler branches on SpawnMode and only reads the fields that mode carries.

ReadAbilityLearnedObserverBroadcast(Reader)

Reads an AbilityLearnedObserverBroadcast written by the method above.

public static AbilityLearnedObserverBroadcast ReadAbilityLearnedObserverBroadcast(this Reader reader)

Parameters

reader Reader

Returns

AbilityLearnedObserverBroadcast

WriteAbilityActivatedBroadcast(Writer, AbilityActivatedBroadcast)

Writes an AbilityActivatedBroadcast in its mode-shaped form.

public static void WriteAbilityActivatedBroadcast(this Writer writer, AbilityActivatedBroadcast value)

Parameters

writer Writer
value AbilityActivatedBroadcast

WriteAbilityLearnedObserverBroadcast(Writer, AbilityLearnedObserverBroadcast)

public static void WriteAbilityLearnedObserverBroadcast(this Writer writer, AbilityLearnedObserverBroadcast value)

Parameters

writer Writer
value AbilityLearnedObserverBroadcast

Remarks

Hand written for the event-id count: FishNet's generated array serializer writes a four-byte length and a null sentinel, where this message's count never exceeds MAX_LEARNED_EVENTS and a null list is simply an empty one.