Unsure About Remotes Communicating Between Player, Server, and NPC

So far, my script for raycasting for NPC characters is going fine. However, I’m starting to get a bit confused about how I will go about this. I have a remote for when the player interaction with the npc succeeds (by having a raycast look for the npc’s humanoid), and it runs when the npc does get detected.
This is where I’m getting confused because I can’t figure out how to get the code to run on the NPC within severscript when the remote is triggered without using another separate remote or extremely tedious code. I have the code stored inside the NPC that I may be able to migrate to serverscript.

Please note I am trying to only to do this for ONE NPC because I will sort the rest on my own later

It sounds like you’re on the right path with your raycasting and remote setup! You have a remote event that triggers when the player successfully interacts with the NPC by detecting the NPC’s humanoid. Now, it seems like you’re facing the challenge of running code on the NPC through the server once this remote event is triggered.

To clarify, let’s go over what’s happening in your setup:

  1. Player Interaction: The player successfully detects the NPC using raycasting and triggers a remote event.
  2. Server Triggering Logic: The server needs to run some code on that specific NPC when this remote is triggered.

Here are a few ways you can proceed without needing additional remotes or an excessive amount of code:

Approach 1: Use Remote Event with NPC Identification

When triggering the remote event from the client, you can include an identifier for the specific NPC. For instance, if each NPC has a unique Name or an ID property, pass that along with the remote event trigger. Here’s how you might go about it:

  • On the Client: Send the NPC’s unique identifier as part of the remote event.
  • On the Server: When the server receives the event, it can use this identifier to locate the specific NPC and execute the code you want.

For example:

  • If each NPC has a unique Name or an ID property, use game.Workspace:FindFirstChild(npcID) to locate the NPC in the workspace.
  • Once found, you can then run the NPC-specific code.

This avoids duplicating remotes and centralizes your logic.

Approach 2: Store NPC Code in ServerScriptService

Instead of keeping the code directly in the NPC instance, consider organizing it in ServerScriptService so it’s easier to maintain and access. You can organize your NPCs by adding them to a table or dictionary, indexed by each NPC’s unique identifier. This way:

  • The server code can easily locate the NPC based on the ID received from the client.
  • You centralize your NPC-related logic, so managing multiple NPCs later on will be much simpler.

Here’s an example of the structure for your server-side logic:

-- In ServerScriptService
local NPCManager = {}

NPCManager.NPCs = {
    ["UniqueNPCID1"] = function(npc)
        -- Code for NPC interaction
    end,
    -- Add more NPCs as needed
}

local function onRemoteTriggered(player, npcID)
    local npc = game.Workspace:FindFirstChild(npcID)
    if npc and NPCManager.NPCs[npcID] then
        NPCManager.NPCs[npcID](npc)
    end
end

remoteEvent.OnServerEvent:Connect(onRemoteTriggered)

In this setup, the NPCManager dictionary stores the functions specific to each NPC, which will be executed when the remote event fires.

Approach 3: Modules for NPC Behavior

If you anticipate complex behaviors, consider using ModuleScripts. Each NPC can have a module with specific behavior, and when the server receives the event, it can call the appropriate module function based on the NPC’s ID.


I hope this helps. Let me know for any clarification or if my response isn’t what you’re looking for.

Thanks, approach 1 and 2 seems to be just what I need.

I’ll report back if there is something wrong.

I have run into another problem: the solution will clash with my “wander” script for the NPC’s.

For context, I am using method 2 that you stated since there will be two types of NPC’s that the player can interact with currently.

here is the wander script (legacy, inside the character):
(I know I should optimize my code but I’ll do it later lol)

while humanoid.Health > 1 do
	task.wait(waitTime)
	waitTime = ranInterval()
	if not beingAsked then
		if not Moving then
		Wander(humanoid)
		Moving = true
		while humanoid.MoveDirection.Magnitude > 0 do
			wait()
		end
		Moving = false
	end
	wait()
	end
end

It sounds like you’ve made good progress with the approach of handling NPC interaction, but now there’s a conflict between the interaction logic and the existing wandering behavior. It seems like you need a way to coordinate these two scripts, so that the NPC stops wandering when a player interacts with it.

Here’s a possible strategy for integrating these behaviors without causing conflicts:

  1. Use a “State” Variable

Introduce a state variable, like isInteracting, to track whether the NPC is currently interacting with a player or just wandering. This variable could be stored in a ModuleScript shared across scripts, or it could be a property in each NPC object if each NPC manages its own state.
• In the wander script: Check the isInteracting variable before initiating wandering behavior. If isInteracting is true, the NPC should pause its wandering.
• In the interaction script: Set isInteracting to true when the player starts an interaction. Once the interaction ends, set isInteracting back to false.

  1. Modify the Wander Script to Check isInteracting

Add checks within the wander loop so it only executes if isInteracting is false. This ensures that the NPC won’t start wandering again until the interaction is complete.

For example, your modified wander script might look something like:

while humanoid.Health > 1 do
    task.wait(waitTime)
    waitTime = ranInterval()

    if not beingAsked and not isInteracting then  -- only wander if not interacting
        if not Moving then
            Wander(humanoid)
            Moving = true
            while humanoid.MoveDirection.Magnitude > 0 do
                wait()
            end
            Moving = false
        end
    end
    wait()
end
  1. Update isInteracting on Interaction

In your interaction handling code, make sure to set isInteracting to true when the player triggers the interaction and set it back to false when the interaction ends.

For example:

local function onRemoteTriggered(player, npcID)
    local npc = game.Workspace:FindFirstChild(npcID)
    if npc and NPCManager.NPCs[npcID] then
        npc.isInteracting = true  -- stop wandering
        NPCManager.NPCs[npcID](npc)  -- handle interaction
        npc.isInteracting = false  -- allow wandering again after interaction
    end
end

This approach lets you control the NPC’s wandering based on whether it’s in an interaction state, keeping both behaviors from clashing.

let me know if this works or if you have abymore questions.

What resources would you recommend for learning to use modules (other than the documentations)? I’m still learning and this is currently my second project.
(haha accidentally clicked solution when editing this)

One more problem: the if statement check doesn’t work

specifically:

if npc and NPCManager.NPCs[npcID] then

it doesn’t seem to run at all when I sent the raycast result’s parent as instance, which should work in theory but it just doesn’t work. The event does get triggered, though.

Edit: the script seems to be running fine now, I don’t know how but it just did. However, it says that there’s a nil value?

Solved this on my own, but my raycast suddenly starts detecting player accessories :smiling_face_with_tear:

(solved again)