Best way to identify players and NPCs uniquely

I have made a task system where players and NPCs alike can go to a task center to pick up an task, such as “feed the cat” or “clean the kitchen”.

Later when the player or NPC arrives at the task location (cat’s food bowl or kitchen) they can “perform” the task for points.

In this system I need to uniquely identify the agent , either player or NPC.

What would be the best way of uniquely identifying the NPC/players?

If I was only caring about human players, I would probably use Player.UserId, but since there is no Player object for NPCs, what would be another good way to identify agents?

EDIT: To clarify, I don’t care if the agent in question is a player or an NPC. The whole point is that agents should be interchangeable. But I still need to know that agent X is agent X when she arrives at the task center, regardless of wether she is an NPC or human player.


if you retrieve the player’s character model, PlayersService:GetPlayerByCharacter(characterModel) returns the player of the character model.

Yes, but what about NPCs? I need ID for both players and NPCs.

well… if getplayerforcharacter returns nothing then it’s a npc

Why don’t you use booleans in the player and NPC character models? When the player joins the game, you could add a bool value saying that they’re a player, and set it to false for NPCs.

1 Like

I would use tag manager, its a roblox that allows you to add tags to parts and models then your able to identify with scripts what tag it has or none.

I’ve used it for npcs

1 Like

OK, so now I know it is an NPC. My game has 10 NPCs and 10 human players. How do I uniquely identify them?

use getplayerbycharacter aswell…

i mean getplayerbycharacter

The question is not to determine if an agent is a player or an NPC, the question is how can I tell agents apart, regardless of wether they are human players or NPCs.

Name them different things. You can give them all or some actual names like ‘John’ or simply name them based on something like ‘winterworldNPC1’ or just ‘NPC3’.

You could set up a folder under workspace for all NPCs, or, if you have level/world systems, you could set up a folder called ‘NPCs’ for that specific world/level.

Do something like game.Workspace.NPCsFolder.JohnTheTutorialNPC

1 Like

I like this idea, but there is one problem, when testing in studio, many players will have the same name. Also, how can I guarantee that all the names I give are unique?

1 Like

Make the NPCs only based on names alone. For players specifically, you should use their userid.

You would need to run a loop check on join and exclude all current players’ names that are used when picking a random word in your sense.

There were many good answers here, but in the end I solved this in a different way, and so I decided to share my result in case it could be useful to sameone else.

Basically I made a module script “AgentId” that is usable from both client and server (put it under ReplicatedStorage):

local module={}

local HttpService = game:GetService("HttpService")

function module.uuid()
	return HttpService:GenerateGUID(false)	

function module.getInstanceId(instance:Instance)
	if not instance then
	local id = instance:GetAttribute("uuid")
	if not id then
		id = module.uuid()
		instance:SetAttribute("uuid", id)
	return id

return module

At first glance this might seem a bit strange but please let me explain.

Attributes can be attached to any instance and are replicated. Whenever I ask for the ID of an NPC or player object with the getInstanceId() function it will return a UUID string that it generates on the fly if it is missing. This will automatically handle all sorts of problems which is kind of neat.

Things that it handles;

  • It supports ANY object, be it Parts, Models, Folders, Players, Characters, Humananoids or whatever else you need to identify.
  • It only stores ID when you need it, and so you don’t have to carefully manage when IDs are assigned. They are assigned at the first time they are needed.
  • It replicates automatically (given that ID is created on sever which is best practice anyways).
  • IDs are based on UUID which makes them globally unique, making chance of collision practically inexistent.
  • It uses Service to generate UUID which means it is probably fast (hopefully? I did not test this) .

Things that it does not handle;

  • IDs are not persisted in any way. Usually I find this is not necessary, and if it is, I can just use the same attribute and it will magically work with the rest.

I hope this was helpful.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.