Unique Idenifier for instances

Is there any unique idenifiers for instances?

1 Like

Instance API Reference (roblox.com)

Instance is the base class for all classes in the Roblox class hierarchy.

There may be a unique identifier for the Objects that you are trying to work with, but an Instance can be literally anything. What type of object do you need to identify using a unique key?

To answer your question, the Instance class does not have an attribute that can uniquely identify any instance.

1 Like

you can use tostring(instance) to get the instance’s memory address,
the memory address is a unique identifier of that instance

actually what’s an instance I don’t even know.
it’s just the base class of every other class, an abstract class if you would
it’s not an independent object that can be constructed, only the derived class can be constructed that is an instance
and tostring(instance) prints the Instance.Name not the memory address
but if you can somehow get the memory address than you have the unique identifier

tostring() works with tables

2 Likes

While the memory address may be unique, it will not be the same each time the game is loaded. The memory address is a value that allows the game engine to find where the Instance is stored in RAM. You might be able to use the memory address of the Instance for some debugging purpose, but the memory address is not useful if you need to uniquely identify an Instance programmatically.

Is it stable however
does it ever change?

Memory addresses never change.
you could do something like

local address = {[1] = YourInstance}
tostring(address) -- == the mock memory address unique to 'YourInstance'
-- or if you can get the actual memory address of the instance, even better
--or, as a dictionary
local address = { Instance = YourInstance }
tostring(address)
-- then, when you're trying to use it
address.Instance
--or, you could even store it as an indice;
local address = { Instance = YourInstance }
address["Identifier"] = tostring(address)
print(address.Identifier)

-- but if you add another indice into address, than the mock address would refer to 
-- both of the indices, so each instance would have to have their own table.
-- that's remedied by getting the actual memory address of the instance
-- however i don't know how
1 Like

This is not true, memory addresses DO change and WILL change unpredictably. Memory addresses are used to temporarily store data for programs. A memory address is basically an identifier for a “slot” in your device’s physical RAM where data can be stored. Printing the memory address will essentially show a pointer to what address the Instance is currently stored at.

Memory Address - Wikipedia

3 Likes

Where does it say that memory addresses change in that wiki you listed?
I can’t be expected to read that entire document looking for a needle in a haystack.

Well, according to roblox’s wiki references to instances are never weak,
so the memory address wouldn’t change until garbage collected.
according to:

https://developer.roblox.com/en-us/articles/Metatables
-- __mode	
-- Used in weak tables, declaring whether the keys and/or values of a table are weak.
-- **NOTE: References to Roblox instances are never weak. Tables that hold such references will never be garbage collected**.
1 Like

This does not mean that the memory address will always be the same. You can assume that the memory address of any Instance will change every time you run the game and will be different on each device.
Memory addresses should not be used in your scripts to identify Instances, and there is likely a better way to identify any Object that you need to access in code.

1 Like

Yeah for sure.
The instance would be stored in a different heap allocation every time the applications runs, unless you know you’re using like C++ stackalloc, malloc, or using fixed *bytes in C#.

If you create an instance on the server and it’s replicated to the client, it’ll have a different address.
If you close the client and re-open the game, it’ll have a different address.
If you destroy the instance and recreate it from the same function, it’ll have a different address.
If the instance is replicated to any other clients from a client, it’ll have a different address.

The address isn’t getting physically marshaled anywhere else, so it’s unique to the local environment.

On the other hand, if your goal is to have a transferrable unique identifier
than you could use HttpService:GenerateGuid() and pass that value between local environments

local datum = {}
local address = { 
    Instance = YourInstance, 
    Identifier = { Passable = HttpService:GenerateGuid(), Local = '' },
}
address.Identifier.Local = tostring(address)
table.insert(datum, address)
local function lookup(value, returntype: string)
    for i = 1, #datum do
       if typeof(value) == "string" and value == datum[i].Identifier.Passable then
          print("Matched "..tostring(value).." within datum at index "..tostring(i))
          break
       end
       if typeof(value) == "Instance" and value == datum[i].Instance then
           print("Matched "..tostring(value).." within datum at index "..tostring(i))
           break
       end
    end
end

On the other hand, if your goal was to have a static address between sessions,
than you’d have to store that in a DataStore and retrieve the value from there,
and it’s only transferrable between experiences sharing that datastore.

Whichever way though, the notable reminder here is if you’re referencing the instance in a table, according to Roblox, it’ll never be collected even if you Destroy() the instance, the table’s reference needs to be nil’ed before the garbage collector handles the nil instance. I don’t know how you’d do it, but, you’d have to nil the table reference prior to or following :Destroy() the instance

maybe at the end of the lookup function you’d want to iterate over the datum and check if any Instance.Parent is nil and remove that index, or something.

3 Likes

What are you trying to do? There is certainly a way around needing unique identifiers, usually by just passing instances by reference. Remote events accept Instances as parameters as long as the Instances are present on the Server.

Was wondering if this existed or not

as long as they are ‘parented to workspace’ on the server

I know this is a stale thread, but I did want to report something I have found which may or may not help in answering this question.

Btw, this thread came up as the first result on google when searching for “roblox get unique id for instance”. So I figure this is a good place to try and answer this question.

Personally, I was trying to create a system that would track instances that were given certain tags at runtime. So that I could then also execute code for those instances (models/parts) when they eventually entered the workspace. This is just an experimental system I am testing out, though.
And the main motivation for this system is to prevent code being ran for objects that only exist inside the ReplicatedStorage, or located in some other temporary location before being brought back to workspace.
(come to think of it, I feel like this is a bit pointless now, heh. Either way)

So I was breakpoint debugging this code for the system I was experimenting with.
And I noticed that if I used the object itself as the key to the table. When I looked at the key value, it showed a value which I assume is an memory address. Which should be perisistent for the lifetime of the program. The object isn’t going to randomly get a new address unless there is somthing going on with the garbage collecter that may alter it. But that may be a different address.

Either way, because I am using the object itself as the key to the table, getting the address really isn’t necesary. If I want to know if the object is in the table, you do table[object] and if the result is not-nil, then it’s there.


Final remark:
The reason I started second guessing the system I was experimenting with is because, I am trying to prevent certain things from happening when the object is no longer in the workspace. But that might not be a major issue anyway.
Like, if you have to use a RunService event for a tagged object. But you don’t want it to run of the object gets moved outside the workspace temporarily. But maybe there are better ways to handle that. Like in the loop itself, you just check if the ancestor is moved elsewhere, or somthing.