Table of Contents

Class GatheringNode

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Gathering node interactable that grants items from a loot table when gathered. Tracks remaining uses and despawns when depleted. Configured via a GatheringNodeTemplate ScriptableObject asset.

[RequireComponent(typeof(SceneObjectNamer))]
public class GatheringNode : Interactable, ISpawnable, IGatheringNode, IInteractable, ISceneObject
Inheritance
Object
Component
Behaviour
MonoBehaviour
NetworkBehaviour
GatheringNode
Implements
Inherited Members
NetworkBehaviour.IsSpawned
NetworkBehaviour.ComponentIndex
NetworkBehaviour.NetworkObject
NetworkBehaviour.MAXIMUM_NETWORKBEHAVIOURS
NetworkBehaviour.UNSET_NETWORKBEHAVIOUR_ID
NetworkBehaviour.ToString()
NetworkBehaviour.Reset()
NetworkBehaviour.OnValidate()
NetworkBehaviour.IsBehaviourReconciling
NetworkBehaviour.ClearReplicateCache()
NetworkBehaviour.CreateReconcile()
NetworkBehaviour.Reconcile_Reader<T>(PooledReader, ref T)
NetworkBehaviour.OnStartServerCalled
NetworkBehaviour.OnStartClientCalled
NetworkBehaviour.OnStartNetwork()
NetworkBehaviour.OnStopNetwork()
NetworkBehaviour.OnStopServer()
NetworkBehaviour.OnOwnershipServer(NetworkConnection)
NetworkBehaviour.OnSpawnServer(NetworkConnection)
NetworkBehaviour.OnDespawnServer(NetworkConnection)
NetworkBehaviour.OnStartClient()
NetworkBehaviour.OnStopClient()
NetworkBehaviour.OnOwnershipClient(NetworkConnection)
NetworkBehaviour.ClearBuffedRpcs()
NetworkBehaviour.ExcludeOwnerFromUnbufferedObserversRpcs
NetworkBehaviour.IsClientOnly
NetworkBehaviour.IsServerOnly
NetworkBehaviour.IsHost
NetworkBehaviour.IsClient
NetworkBehaviour.IsServer
NetworkBehaviour.IsDeinitializing
NetworkBehaviour.NetworkManager
NetworkBehaviour.ServerManager
NetworkBehaviour.ClientManager
NetworkBehaviour.ObserverManager
NetworkBehaviour.TransportManager
NetworkBehaviour.TimeManager
NetworkBehaviour.SceneManager
NetworkBehaviour.PredictionManager
NetworkBehaviour.RollbackManager
NetworkBehaviour.NetworkObserver
NetworkBehaviour.IsClientInitialized
NetworkBehaviour.IsClientStarted
NetworkBehaviour.IsClientOnlyInitialized
NetworkBehaviour.IsClientOnlyStarted
NetworkBehaviour.IsServerInitialized
NetworkBehaviour.IsServerStarted
NetworkBehaviour.IsServerOnlyInitialized
NetworkBehaviour.IsServerOnlyStarted
NetworkBehaviour.IsHostInitialized
NetworkBehaviour.IsHostStarted
NetworkBehaviour.IsOffline
NetworkBehaviour.IsNetworked
NetworkBehaviour.GetIsNetworked()
NetworkBehaviour.IsManagerReconciling
NetworkBehaviour.Observers
NetworkBehaviour.IsOwner
NetworkBehaviour.IsController
NetworkBehaviour.HasAuthority
NetworkBehaviour.Owner
NetworkBehaviour.OwnerId
NetworkBehaviour.ObjectId
NetworkBehaviour.LocalConnection
NetworkBehaviour.OwnerMatches(NetworkConnection)
NetworkBehaviour.Despawn(GameObject, DespawnType?)
NetworkBehaviour.Despawn(NetworkObject, DespawnType?)
NetworkBehaviour.Despawn(DespawnType?)
NetworkBehaviour.Spawn(GameObject, NetworkConnection, Scene)
NetworkBehaviour.Spawn(NetworkObject, NetworkConnection, Scene)
NetworkBehaviour.RemoveOwnership()
NetworkBehaviour.GiveOwnership(NetworkConnection)
NetworkBehaviour.GetInstance<T>()
NetworkBehaviour.TryRegisterInstance<T>(T)
NetworkBehaviour.UnregisterInstance<T>()
NetworkBehaviour.CanLog(LoggingType)
MonoBehaviour.IsInvoking()
MonoBehaviour.CancelInvoke()
MonoBehaviour.StopCoroutine(Coroutine)
MonoBehaviour.StopAllCoroutines()
MonoBehaviour.destroyCancellationToken
MonoBehaviour.useGUILayout
MonoBehaviour.didStart
MonoBehaviour.didAwake
MonoBehaviour.runInEditMode
Behaviour.enabled
Behaviour.isActiveAndEnabled
Component.GetComponent<T>()
Component.TryGetComponent<T>(out T)
Component.GetComponentInChildren<T>()
Component.GetComponentsInChildren<T>()
Component.GetComponentInParent<T>()
Component.GetComponentsInParent<T>()
Component.GetComponents<T>()
Component.GetComponentIndex()
Component.CompareTag(TagHandle)
Component.transform
Component.transformHandle
Component.gameObject
Component.tag
Object.GetEntityId()
Object.GetInstanceID()
Object.GetHashCode()
Object.InstantiateAsync<T>(T)
Object.InstantiateAsync<T>(T, Transform)
Object.InstantiateAsync<T>(T, Vector3, Quaternion)
Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion, Transform)
Object.Instantiate(Object)
Object.Instantiate(Object, Scene)
Object.Instantiate<T>(T, InstantiateParameters)
Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)
Object.Instantiate(Object, Transform)
Object.Instantiate<T>(T)
Object.Instantiate<T>(T, Vector3, Quaternion)
Object.Instantiate<T>(T, Vector3, Quaternion, Transform)
Object.Instantiate<T>(T, Transform)
Object.Destroy(Object)
Object.DestroyImmediate(Object)
Object.DontDestroyOnLoad(Object)
Object.DestroyObject(Object)
Object.FindObjectsOfType<T>()
Object.FindObjectsByType<T>(FindObjectsSortMode)
Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)
Object.FindObjectOfType<T>()
Object.FindFirstObjectByType<T>()
Object.FindAnyObjectByType<T>()
Object.FindFirstObjectByType<T>(FindObjectsInactive)
Object.FindAnyObjectByType<T>(FindObjectsInactive)
Object.FindObjectsByType<T>()
Object.FindObjectsByType<T>(FindObjectsInactive)
Object.name
Object.hideFlags

Fields

AchievementTemplate

Achievement to increment when a player gathers from this node.

public AchievementTemplate AchievementTemplate

Field Value

AchievementTemplate

Template

Template defining the drop table and gather parameters.

public GatheringNodeTemplate Template

Field Value

GatheringNodeTemplate

Properties

RemainingUses

Remaining uses before the node is depleted. Initialized from MaxUses on awake.

public int RemainingUses { get; set; }

Property Value

int

Remarks

Server state, and deliberately not on the wire. It used to ride the spawn payload — four bytes per node per observer — to answer a question a client cannot ask honestly: nothing refreshes it after the payload, so partial depletion was invisible to anyone already watching, and the only client use was a "> 0" test whose answer is implied by the node still existing (GatheringNodeAction despawns it on reaching zero). See AllowsGathering(int, bool).

Title

Display title shown above the gathering node.

public override string Title { get; }

Property Value

string

TitleColor

Title color for the gathering node UI label.

public override Color TitleColor { get; }

Property Value

Color

Methods

AllowsGathering(int, bool)

The charge half of the gathering rule, as a pure function so it can be reasoned about and tested without a NetworkManager.

public static bool AllowsGathering(int remainingUses, bool chargesAreAuthoritative)

Parameters

remainingUses int

The node's remaining charges.

chargesAreAuthoritative bool

True when this peer owns the charge count.

Returns

bool

Remarks

Truth table:

  • not authoritative, any count → true (the server answers)
  • authoritative, count > 0 → true
  • authoritative, count <= 0 → false

A peer that does not own the count does not get to answer with it. The count is not replicated — it moves whenever anyone gathers, and there is no message that carries the new value — so a client asking it would be asking a number frozen at whatever it held when the node was spawned.

CanInteract(IPlayerCharacter)

Returns true if the specified player character may interact with this object.

public override bool CanInteract(IPlayerCharacter character)

Parameters

character IPlayerCharacter

The player character attempting to interact.

Returns

bool

True if interaction is allowed, false otherwise.

Remarks

A pure question with no side effects. It used to stamp the character's interact rate-limit as part of answering, which made it unusable as a check: the scene server, the quest system and the client's input handler all call it, and each call silently consumed a limiter meant for one of the others. A quest accepted within the limiter's window of the interaction that opened the dialogue was refused by a debounce nobody intended to spend, and the refusal path sends nothing back — so the player saw a dead keypress. Spend the limiter explicitly with TryConsumeInteractRateLimit(IPlayerCharacter).

OnAwake()

Called when the object is awakened. Override to implement custom initialization logic.

public override void OnAwake()

ResetState(bool)

Restores the node's charges when this instance returns to the pool.

public override void ResetState(bool asServer)

Parameters

asServer bool

True when the reset is for the server instance.

Remarks

OnAwake() is where RemainingUses is seeded, and Unity calls Awake once per instance — not once per spawn. A pooled node therefore came back out of the pool with the zero its previous life ended on, and CanInteract(IPlayerCharacter) refuses a node with no uses left: every gathering node in a scene became permanently depleted the first time it was exhausted, for the remaining life of the server process.