Class InteractableSystem
- Namespace
- FishMMO.Server.Implementation.World.SceneServer.Interactable
- Assembly
- FishMMO.Server.dll
Server-authoritative dialogue session management. Tracks active dialogue sessions per character, validates client choices, evaluates ECA conditions/actions, and maintains per-character choice bitmasks. All dictionaries are bounded to prevent unbounded memory growth.
[CreateAssetMenu(fileName = "InteractableSystem", menuName = "FishMMO/Server/SceneServer/Interactable System", order = 1)]
[RequiresDataContainer(typeof(InteractableSystemMainThreadQueueData))]
[RequiresDataContainer(typeof(InteractableSystemRuntimeData))]
[RequiresDataContainer(typeof(AsyncWorkerData))]
public class InteractableSystem : ServerBehaviour, IServerBehaviour<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>, IServerComponent<INetworkManagerWrapper, ServerManager, NetworkConnection, IServerBehaviour>, IInteractableSystem, IServerBehaviour, IServerComponent
- Inheritance
-
ObjectScriptableObjectInteractableSystem
- Implements
- Inherited Members
-
ScriptableObject.SetDirty()ScriptableObject.CreateInstance<T>()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.ToString()Object.nameObject.hideFlags
Remarks
The corpse is the authority throughout. The client sends a scene object ID and a slot index and nothing else — never an item ID, a template, or an amount — so the worst a forged request can do is name a slot that is empty or a corpse it has no rights to, both of which are refused here.
Fields
DialogueLeaveChoiceIndex
Choice index meaning "leave the conversation" rather than "take choice N".
public const int DialogueLeaveChoiceIndex = -1
Field Value
Remarks
A dialogue node whose choices are all filtered out — every one already taken, or every one's conditions unmet — leaves the client with no buttons at all, and the panel has no close of its own. Escaping out of it left the session open on the server, so the next interaction with anything was validated against a node the player had walked away from. This gives the client a way to say so. It reuses DialogueChoiceBroadcast rather than adding a message, because everything the leave path needs to validate — the session, the node, the range — is already carried on it.
Methods
EndDialogueSession(IPlayerCharacter)
Ends the dialogue session for the specified character without sending a broadcast.
public void EndDialogueSession(IPlayerCharacter character)
Parameters
characterIPlayerCharacterThe player character whose session to end.
InitializeOnce()
Initializes the InteractableSystem: validates dependencies, registers all network broadcast handlers, subscribes to dialogue events, and clamps configuration values.
public override ServerComponentInitializationStatus InitializeOnce()
Returns
- ServerComponentInitializationStatus
Initialization status indicating success or failure.
LearnAbility(IAbilityController, AbilityTemplate, List<int>)
Creates and learns a new crafted ability, then schedules asynchronous persistence.
public Ability LearnAbility(IAbilityController abilityController, AbilityTemplate abilityTemplate, List<int> abilityEvents)
Parameters
abilityControllerIAbilityControllerAbility controller receiving the new ability.
abilityTemplateAbilityTemplateBase ability template used for creation.
abilityEventsList<int>Selected ability event identifiers to attach.
Returns
- Ability
The created ability instance.
LearnAbilityEvent<T>(NetworkConnection, IPlayerCharacter, T)
Learns an ability event template and synchronizes the result to the client.
public void LearnAbilityEvent<T>(NetworkConnection conn, IPlayerCharacter character, T template) where T : AbilityEvent
Parameters
connNetworkConnectionClient connection to notify.
characterIPlayerCharacterCharacter learning the ability event.
templateTAbility event template to learn.
Type Parameters
TConcrete ability event type.
LearnAbilityTemplate<T>(NetworkConnection, IPlayerCharacter, T)
Learns a base ability template and synchronizes the result to the client.
public void LearnAbilityTemplate<T>(NetworkConnection conn, IPlayerCharacter character, T template) where T : BaseAbilityTemplate
Parameters
connNetworkConnectionClient connection to notify.
characterIPlayerCharacterCharacter learning the ability.
templateTAbility template to learn.
Type Parameters
TConcrete base ability template type.
OnDeinitialize()
Deinitializes the InteractableSystem: drains queued actions, clears ingress guards, unregisters network broadcast handlers, unsubscribes from dialogue events, and clears dialogue session state.
public override void OnDeinitialize()
OnInteractNPC(IPlayerCharacter, IInteractable)
Updates an NPC to face the interacting character and enter idle state.
public void OnInteractNPC(IPlayerCharacter character, IInteractable interactable)
Parameters
characterIPlayerCharacterInteracting player character.
interactableIInteractableInteracted NPC object.
OnServerAbilityCraftBroadcastReceived(NetworkConnection, AbilityCraftBroadcast, Channel)
Handles an incoming ability crafting request and validates cost, ownership, and selected events.
public void OnServerAbilityCraftBroadcastReceived(NetworkConnection conn, AbilityCraftBroadcast msg, Channel channel)
Parameters
connNetworkConnectionRequesting client connection.
msgAbilityCraftBroadcastAbility crafting request payload.
channelChannelTransport channel used by FishNet.
OnServerDungeonFinderCreateBroadcastReceived(NetworkConnection, DungeonFinderCreateBroadcast, Channel)
Handles a request to open a new instance of a dungeon.
public void OnServerDungeonFinderCreateBroadcastReceived(NetworkConnection conn, DungeonFinderCreateBroadcast msg, Channel channel)
Parameters
connNetworkConnectionRequesting client connection.
msgDungeonFinderCreateBroadcastWhich entrance, which difficulty, and whether to list it.
channelChannelTransport channel used by FishNet.
OnServerDungeonFinderJoinBroadcastReceived(NetworkConnection, DungeonFinderJoinBroadcast, Channel)
Handles a request to join an instance somebody else has opened.
public void OnServerDungeonFinderJoinBroadcastReceived(NetworkConnection conn, DungeonFinderJoinBroadcast msg, Channel channel)
Parameters
connNetworkConnectionRequesting client connection.
msgDungeonFinderJoinBroadcastWhich entrance and which instance.
channelChannelTransport channel used by FishNet.
OnServerDungeonFinderListBroadcastReceived(NetworkConnection, DungeonFinderListBroadcast, Channel)
Answers a client browsing the instances joinable at one difficulty.
public void OnServerDungeonFinderListBroadcastReceived(NetworkConnection conn, DungeonFinderListBroadcast msg, Channel channel)
Parameters
connNetworkConnectionRequesting client connection.
msgDungeonFinderListBroadcastWhich entrance and which difficulty.
channelChannelTransport channel used by FishNet.
Remarks
Every exit sends a DungeonFinderListResultBroadcast, including the refusals and the empty lists. The panel disables its list and its Refresh button while a request is outstanding — the guard that stops the button being held down — so a handler that returned silently would leave the panel inert for the rest of its life.
Not gated on character state. Reading a list is not a move, and a player in combat who cannot see the list can see it by walking ten metres away; refusing would hide information rather than prevent an action.
OnUpdate(float)
Called every frame. Drains a bounded number of queued main-thread actions and sweeps stale debounce entries.
protected override void OnUpdate(float deltaTime)
Parameters
deltaTimefloatTime elapsed since the last frame.
SendNewItemBroadcast<T>(T, ICharacter, IInventoryController, Item)
Attempts to add items to a characters inventory controller and broadcasts the update to the client. DB persistence is fire-and-forget async.
public bool SendNewItemBroadcast<T>(T conn, ICharacter character, IInventoryController inventoryController, Item newItem)
Parameters
connTcharacterICharacterinventoryControllerIInventoryControllernewItemItem
Returns
Type Parameters
T
StartDialogueSession(IPlayerCharacter, ISceneObject, IDialogueInteractable)
Starts a new dialogue session for the character from an interactable interaction. Evaluates the start node's conditions and sends DialogueStartBroadcast to the client.
public void StartDialogueSession(IPlayerCharacter character, ISceneObject sceneObject, IDialogueInteractable dialogue)
Parameters
characterIPlayerCharacterThe player character starting the dialogue.
sceneObjectISceneObjectThe scene object hosting the interactable.
dialogueIDialogueInteractableThe dialogue interactable.
StartECADialogueSession(IPlayerCharacter, DialogueTemplate, IInteractable)
Starts a new dialogue session triggered by an ECA action.
public void StartECADialogueSession(IPlayerCharacter character, DialogueTemplate template, IInteractable interactable = null)
Parameters
characterIPlayerCharacterThe player character starting the dialogue.
templateDialogueTemplateThe dialogue template to use.
interactableIInteractableThe interactable the dialogue is anchored to, or null.
Remarks
interactable is what anchors the conversation to a place in the
world. Every dialogue in the game reaches the server through this method — the
interactable-typed StartDialogueSession(IPlayerCharacter, ISceneObject, IDialogueInteractable) overload has no callers — so when
this passed a hard-coded 0 for the scene object ID, every session was
unanchored and the choice handler's range check was dead code for all of them. A player
could open a conversation, walk to the far side of the zone, and keep taking choices —
including any that hand out items or currency.