Is it more optimized to give objects a “type” parameter that a script can easily access through:
- Attributes
- StringValue Instances
- Storing them in Tables
- The Tag Editor?
- Or something else?
Is it more optimized to give objects a “type” parameter that a script can easily access through:
You can test things like this by timing each type of operation for each thing.
Storing them in tables is probably the most efficient overall.
Generally though it’s not very important to optimize things like this since it’s usually pretty inconsequential unless you’re store huge amounts of data.
I thought about it more and what if I want to know if I hit a certain object? If I loop through the object table, it would probably start lagging the game. There’s gonna be a lot of stuff considered “objects” so the table approach probably won’t work.
StringValue, and as such most other Value instances are borderline deprecated for most use-cases through the introduction of attributes, so just don’t use those if you can avoid them.
Tables are definitely the fastest / “most optimized”, however attributes are generally more intuitive to use and easier to organize, even more so for non-programmers. At some point of complexity tho, using attributes becomes cumbersome and overwhelming.
I haven’t tested this so don’t quote me on it, but I believe tags are effectively the same as attributes performance wise (at least compared to tables).
Could you elaborate a bit more on what exactly you are trying to do? I don’t exactly understand what you mean with your question.
There’s hit detection for my game, but with some objects I want it to do different things. I wanted to make it organized and manageable, so I am settling on tables, or attributes to make it work.
The table index / attribute would make it so that when hit detection was used elsewhere it could validate (through one of the three) what type of object it was and then do the specific action that I wanted to perform for it.
An example of this is a brick wall that has 50 health.
Which would be better?
Tables (Lua Variables)
~0.02–0.05 µs
Fastest because everything stays in pure Luau memory.
Attributes
~0.3–1.0 µs
Stored natively on Instances, lightweight, typed, and faster than value objects.
Tag Editor / CollectionService Tags
~1–3 µs (checking/adding/removing tags)
Good for marking/filtering objects; slightly slower than Attributes due to hashing + tag lookup layers.
StringValue (or other ValueBase instances)
~3–10 µs
Slowest because each value requires an Instance, property lookups, replication cost, and garbage-collectable objects.
“Something else?”
If you’re a confident scripter, go with number 1. Attributes are a more modern system and run pretty quickly, too. The performance overhead is hardly anything unless you’re querying tens of thousands of objects like every frame in a shitty way.
Still a little confused on what you’re describing with the table approach, but here’s how I’d likely do it.
I’d make a table something like this:
local objects = { -- Table containing all objects and their data
[1] = { -- This is the first object
Model = modelOfTheObject, -- This'd be your reference to the actual 3D object
Health = 50, -- And this is your health stat
}
}
Then, once you’ve got your brick wall that you hit, you can just do this:
local hitObject = objects[hitIndex] -- Or however you get the table representing the brick wall
if hitObject.Health then
hitObject.Health -= 5
end
This kind of approach would be “better” performance wise, but, unless you’re going to have hundreds or thousands of objects which are getting accessed constantly, the difference would be negligible.
I believe I will have hundreds to thousands of objects since I plan to make a bunch of walls for my game. It’s destruction-based so again, I’d like to find the best way to manage it.
Also I realized tags wouldn’t work for what I’m trying to do so they’re out of the question.
What about it?
But as the scale of my game increases it’s possible that it’ll end up around that amount, so I think I’ll opt for that. I just need to wrap my head around module scripts because more than one seperate module script will be asking to create and edit objects.
Actually, reading it again I think I understood what you meant. Once again tho, using tables will ultimately be faster.
This would be one expensive table query! Use attributes for this system.
Tags would technically work but are basically the predecessor to attributes
Simply HitObject:GetAttribute(“Type”) == x
No, really, just use attributes. A table in this system would put you in a completely unnecessary optimization hell. If we’re talking this many objects.
I thought so. I just imagined how long it’d take for the game to loop through a table of hundreds of objects, and compared to attributes where all that’s required is a simple if statement, it sounds wayyyy more optimized.
Good call. you can close this topic now. The only possible way to make a table with this number of objects is splitting it somehow (octrees, for example) which would then mean we can’t directly index the obect id (partList[actualInstace].Type == xx), which, at that point, would still run slower I imagine.
mark ts correct ![]()
'kay nevermind I still don’t quite understand as it seems. Why would you have to loop through all the objects just to get that one object’s type? Tho, if you’ve only got your 3D hit object at hand and all you need from it is it’s type, then in that single particular case, yes, attributes would likely be practically faster than locating that object’s data in the table.
No it isn’t.
If you have a key-value pair table (known as a map or dictionary in other languages), the inner code doesn’t iterate over the entire table to find that specific pair. It only iterates through < 20 “pairs” in 99.999% of cases (more formally O(log N) complexity).
If the table is an array (as in indicies from 1 to N), then the inner code quite literally immediately gets the value for that index. It doesn’t have to check any other ones.
Attributes are quite literally key-value pairs themselves, which also have the same complexity as a key-value table, but they are less optimized than accessing a key-value table in code.
No, it absolutely isn’t. Well yes, techinally you can hand-craft an example where every single key has the exact same hash value (which will practically never happen in real cases). But that only applies for string keys and in that case it’d be the exact same result for the attributes as well. Assuming number keys for the objects, that will never happen.
Once again, no. That’s the entire point of maps/dictionaries. No matter where the index is, the worst case scenario is gonna be log N queries. For example, if the table has a million items, then accessing the very last one is gonna take maximally 20 queries in total. It’s practically always the same for string key dictionaries as well.
This is in fact common knowledge that any intermediate programmer should know.
No not the type, but check each object in the table so I can get its position and size and then check through an if statement if the object is in the radius of the hitbox.
Does this make more sense?
Well in that case you’re looping through all of them anyway. With the amount of objects you are planning to have, I’d still recommend using tables to store the data. Then you can just do
for idx, object in objects do
if object is in radius then
if object.Health then
object.Health -= damage
end
end
end
(Optionally with less nesting)
rather than
for idx, object in objects:GetChildren() do
if object is in radius then
if object:GetAttribute("Health") then
object:SetAttribute("Health", object:GetAttribute("Health") - damage)
end
end
end
no, attributes and tables aren’t supposed to be used hand-in-hand. I was asking if it’d be more optimized and manageable to loop through each object in the table or js check for the health attribute and then damage the object.
I’m still yet to understand how these two otions are supposed to be related, but, of the two, a single attribute check will be faster.