Upcoming API change: Tools inherit Models

Completely ignore me.

I am being stupid, everything in Roblox is an instance even models. It just means they will get stuff from models and instances.

I am just not thinking at all today :laughing:

2 Likes

Anything that can exist within game (including the DataModel itself) is a descendant of the Instance class. This includes both models and even tools.

1 Like

To check if a model is a humanoid (npc or character), check if model:FindFirstChildOfClass("Humanoid") exists.

To check if a model is a character, check if game:GetService("Players"):GetPlayerFromCharacter(model) exists.

3 Likes

In most cases you should be able to switch to FindFirstAncestorOfClass("Model") instead

13 Likes

I assumed Roblox would instead introduce something similar to BasePart; (like BaseModel,) given that the Tool is still a tool. Similar to how Parts, MeshParts, and their sisters work…

1 Like

It’s the same thing as BasePart for Parts/MeshParts/Unions just not an abstract class. There isn’t a reason to make an abstract class that is the exact same as a Model.

2 Likes

Because it seems a couple people here are confused and the wording is a bit strange in the post, I’ll help out and clear up some confusion. Here’s what’s happening:

BackpackItem is what Tools currently inherit from. What’s going on here is that BackpackItem will now also inherit from Model, providing the functionality of models at present. Essentially:

local tool = Instance.new("Tool")

tool:IsA("Tool") -- true
tool:IsA("Model") -- true
tool:IsA("BackpackItem") -- true

will be the new behaviour when this API change is finalised. Tools themselves are not becoming models – they are going to maintain their own class type. Only the inheritence tree is changing.

This has a few benefits:

…which will help make your development life easier for multi-part tools and the like. It’s a great update, but as some people have noted it may cause issues with existing code due to FindFirstAncestorWhichIsA("Model") now returning the tool instance if it’s starting from a tool’s child. It’s a bit of a trade-off, but I personally feel it’ll be the best solution in the end once this is finalised and games are updated for compatibility.

That being said, I would like to see this as a beta toggle so we can write code for this change now rather than have everything spontaneously combust. :pray:

7 Likes

I think easiest way would be…

local function GetAncestorWhichIsAModel(obj)
	local ancestor = obj:FindFirstAncestorWhichIsA("Model")
	local isTool = ancestor and ancestor:IsA("Tool")
	return not isTool and ancestor or GetAncestorWhichIsAModel(ancestor)
end

Not sure though, I haven’t tested. If there’s no ancestor, it should return nil.

2 Likes

The original post indicates they are changing the inheritance of the BackpackItem class, not the Tool class directly. So tool:IsA("BackpackItem") should still also return true

2 Likes

This is incorrect. Tools are still BackpackItems, but BackpackItems a subclass of Models.

2 Likes

Can’t you just check for a humanoid inside the character/model?

3 Likes

I did indeed typo and partially misunderstand myself. Thank you for that.

3 Likes

No? Tool still has different properties and events? yes it would inherit everything a Model has and use its stuff just like Part, MeshPart do for BasePart.

This change makes our code less expressive, when I type in :IsA(“Model”) then I mean any instance of the type Model, it being also a Tool is relevant to me and it should not be picked up because it is not just a Model, it is also a Tool.

If I want it to pick anything up that is RELATED to a Model like Tools (now) then I would want to be expressive and use “BaseModel” or something like that similar to “BasePart”… there is no point in them breaking that just to not introduce something new.

2 Likes

No it doesn’t. You just need to use functions properly.

What that means is any Instance that inherites from type Model. Just like how a Model is an Instance, so model:IsA(“Instance”) returns true.

You should say tool.ClassName == "Tool".

1 Like

except i have absolutely no clue of which games i made have those issues

1 Like

Is this not what BackpackItem is already? A base type for instances that go into your backpack?

A model is a container for other instances, not a basis for anything. They just have convenience methods for manipulating the instances within them. A “BaseModel” in this context makes no sense, and in fact it makes more logical sense that tools have Model in their inheritance tree since they have the ability to have multiple parts.

Okay, I see what you’re saying. It is a fair point, but there are already methods for checking if something is actually a Tool rather than just another Model as previously stated. If it doesn’t validate against those checks, then it’s not a Tool and just a standard model.

1 Like

You should be using OfClass here anyway. I don’t think you need the more in-depth IsA check, unless you have your Character Models as Actors, in which case just use FindFirstAncestorOfClass("Actor"). You really only need to use IsA if you need to check a variety of classes like BasePart.

4 Likes

FYI that’s a complete coincidence, the straw that broke the camel’s back was actually package interactions (and another exciting change I’m working on which I can’t share just yet) not the selection highlight, it just happens to solve that one too.

That is exactly what we’re doing! (“Base class becomes” here means it will “inherit”) Sorry if the post did not make this clear.

I did not think of that breakage possibility, thanks for the feedback on that one everyone, that’s what we do these announcements ahead of time to catch!

I’ll add some analytics to see how common that pattern is to see if we have a problem or if there’s few enough devs that I can just tell the affected people to migrate.

15 Likes

My primary problem with this is consistency and how to look at the type “Model” now.

Models, as you said, they are used as containers, usually for other Models or Parts.
A Tool is not a “container”, it is a Tool. BaseModel, Model, and Tool just make much more sense now because Model will always remain the container part of well… “Model” and Tool will retain its valid typing and the fact that it is not a Container but rather a Tool that inherits Container behaviour.

We as programmers want our code to be as expressive as possible and essentially be read as plain English. When I write my code, especially in a team setting, I write it with the mindset of how to make it as maintainable as possible so that even someone who has never touched Lua and is reading my code understands what is going on in the code through function names and other expressive structures (using IsA and being explicit with it, yes “ClassName” exists but to me that creates inconsistencies within my code making it less readable.)

3 Likes

My 2c here is that Models are very much containers, much more so than other similar things like hats and layered clothing: They often have not just a few but even many parts, constraints, scripts, settings, assets to copy for VFX etc, and in that way they are really conventionally a container of arbitrary contents. Furthermore when existing in the world disconnected from any character as a pickup they feel even more like a model.

11 Likes