Introducing "Local NPCs"!

I am currently designing a game where the player has to collect cassettes to see certain cutscenes. Specifically cutscenes that require multiple humanoids (NPCs) to move. There’s one problem though… It runs on the server which also means it runs on every single client. If one person is viewing a cutscene, the NPC might be in another place.

You might also ask yourself, couldn’t he just put it inside CurrentCamera? Yes, but it’s produces more lag on the client side. That’s why I introduce a new module. Local NPCs.

How does this module work?

This works by cloning a NPC on the server’s side and sending a remote event to every other player to make the NPC transparent. You can create and remove one at any time. This won’t minimalize memory and will reduce lag on the client side. You need to know how it works in order to use it.

To create a NPC, you would want to call the module like a function and put an original NPC you want to clone on the player’s side as the first argument and the player you want to view as the second argument.

local Lib = require(game.ReplicatedStorage.NPCHandler)
local NPC = Lib(workspace.NPC_1, player)

Let’s say that A is the cloned NPC and B is the original NPC.

This does nothing except make a clone on the player’s side and makes B transparent. Everyone else can see B unmoved. You could run a RemoteEvent to the client and inside the function you could make A move to a certain spot.

Note: A and B do not collide with each other, but all the players can collide with both A and B.

To Remove A (or a local NPC), you would have to index the module as a dictionary. You would want to put the player inside the brackets. Here’s where people get messed up.

The first argument is for the cloned NPC. You would have to run this code on the server. You can also change the first argument to nil if you want every single cloned NPC on the player’s side to be removed. (and yes, you can have multiple NPCs.) The second argument is the state of the NPC(s). Changing it to nil will allow the NPC(s) to delete. I will add more soon, just hold on.

Lib[player] = {NPC, nil} -- This will allow the selected NPC to be removed.
Lib[player] = {nil, nil} -- This will allow all the NPCs on the player to be removed.

If you essentially want A and B to touch, you would have to disable the variable just by doing:

Lib.NonCollisions = false

When an NPC is cloned, it automatically turns this true.

And finally, if you want a random NPC to go through both A and B, you would make a code like this, but putting a replica of B as the first argument and a boolean on the second argument. Set it to true will allow the replica to go through A and B.

Lib:SetNPCCollision(workspace.NPC_2, false)

Version 1.02.1
Reset on/off command won’t break the script

there might be bugs, just message me :slight_smile:

Also for those who keep saying, “You can just clone the model locally”, yes it’s equivalent to this module (if we were saying lag and memory based) but animations are less harder to control.


Im just gonna say, you explained that so well

Could you maybe give footage
If thats impossible, never mind

Good tool, I might use it later


Sure. I did this test running two windows and an extra server window. You can see one of the players can see the zombie moving to the dot, but the rest are unable to see it. If you want to see my code, it’s right here:

--// Variables
local Lib = require(game.ReplicatedStorage.NPCHandler)
local debounce = false -- prevents two clones

--// Functions
	if debounce == false then
		debounce = true
		local NPC = Lib(workspace.NPC_1, player)
		Lib[player] = {NPC, nil} -- first value: npc {set to nil if every NPC} second value: set to {nil to destroy}



why would you want this though? It would be easier to have the server handle movement of the ai let alone exploiters probably abusing this depending on context.

1 Like

There’s only one reason on the top of my head why this was a good idea [back a months ago], and that is that there can be a “local” NPC, or in other words, an NPC that can be only seen from one screen. A year ago I had a problem with the animations attempting to clone the NPC to the client. Sure, depending on the context, the exploiters will abuse it, but that’s only on their client, and it wouldn’t matter unless it’s for some game reward. TL;DR: Use it if you want local npcs with good animation, I guess

I personally have never had that issue but its not like you cant have a local script handling animation loading etc that only matters to the client really. but I get what you mean.

1 Like