Struct ObservedResourcePushScheduler
Decides, tick by tick, whether a character's resources go out to its observers.
public struct ObservedResourcePushScheduler
- Inherited Members
Remarks
The observer resource stream is unreliable and change gated: a value is sent when it changes and then never again. Lose that one packet and every observer holds a stale bar until the next change — which for a creature that has just died, or has just been topped up to full, may be never. This schedules a single confirmation re-send of the last pushed state ConfirmDelayTicks later, provided the state is still what was pushed. One confirmation is pending at most; a new change replaces it rather than stacking.
Pure state machine with no network dependency so the schedule is unit tested. The owner of this struct decides what "changed" means (whole units, for a bar) and passes it in.
Fields
ConfirmDelayTicks
Ticks after a push before its confirmation re-send. 15 at tick rate 30 is half a second.
public const uint ConfirmDelayTicks = 15
Field Value
ConfirmPending
True while a confirmation re-send is scheduled for ConfirmTick.
public bool ConfirmPending
Field Value
ConfirmTick
Tick the pending confirmation is due on.
public uint ConfirmTick
Field Value
HasPushed
False until the first push, which always happens regardless of change.
public bool HasPushed
Field Value
LastPushed
The state most recently sent.
public CharacterAttributeResourceState LastPushed
Field Value
NextPushTick
Earliest tick the next change push may occur on.
public uint NextPushTick
Field Value
Methods
AllowImmediatePush(uint)
Drops the outstanding rate limit so the next CHANGE is sent on the tick it happens.
public void AllowImmediatePush(uint tick)
Parameters
tickuintThe current server tick; the deadline is moved back to it.
Remarks
NextPushTick is an absolute deadline stamped from the interval in force at the last push. A caller that widens its interval while a character is idle therefore leaves a deadline behind that outlives the reason for it — and the event that matters most (the first hit of a fight) is exactly the one that arrives while it is still pending. This clears the deadline without pushing anything: nothing is sent unless the state has actually changed.
Deliberately does NOT touch LastPushed, HasPushed or the pending confirmation. Clearing those would resend a value the observers already hold and would drop the loss repair for the previous push.
Evaluate(uint, in CharacterAttributeResourceState, uint)
Evaluates one tick.
public ObservedResourcePushScheduler.Decision Evaluate(uint tick, in CharacterAttributeResourceState state, uint pushInterval)
Parameters
tickuintThe current server tick.
stateCharacterAttributeResourceStateThe current resource state, with fields observers do not use zeroed.
pushIntervaluintMinimum ticks between change pushes.
Returns
- ObservedResourcePushScheduler.Decision
What, if anything, to send. On Push, LastPushed is now
state.
Reset()
Forgets everything, so the next evaluation pushes unconditionally.
public void Reset()
ResourcesDifferForObservers(in CharacterAttributeResourceState, in CharacterAttributeResourceState)
True when two resource states differ by enough for an observer to notice.
public static bool ResourcesDifferForObservers(in CharacterAttributeResourceState a, in CharacterAttributeResourceState b)
Parameters
Returns
Remarks
Compared at whole units because that is what a health bar renders. Sub-unit regeneration drift would otherwise mark every interval dirty and push continuously.