Tool now inherits from Model

Yes, unfortunately there are other ways out there you could write code but they aren’t common patterns. So far I’m only aware of 3 cases of breakage.

We analyzed the top 10,000 marketplace models and of the handful of instances of :IsA("Tool") none of them were broken by the change. That among other other sources of info were used to build confidence that we could limit the number of place breakages to a very low number.

It’s probably better to use class name checks anyways due to other unwanted inheritance issues.

Seems like this change is causing weird jank with Humanoid.EquipTool and tools created on the client :frowning_face: The tool weld isn’t created unless EquipTool is called 1 heartbeat after the tool is created. This is probably a weird edge case, but this only started happening after Tool:IsA(“Model”) returned true.

1 Like

Do you have a test case file demonstrating what used to work but doesn’t? I can look into it.

Here is a test file demonstrating the bug. For some reason the fix I mentioned earlier isn’t working anymore. Make sure you click the button on the right a few times.

toolbug.rbxl (51.6 KB)

I have been having problems with my tools ever since this update - didn’t know what it was till someone sent me this way. Sometimes players get the tool - however when manually forced to give the tool and once they die it disappears for good. The scripts use IsA(“Model”) and tried IsA(“Tool”) and it made no difference.

Could you try to make a minimal place that reproduces the issue? It’s not clear exactly what circumstances you’re talking about and it would probably be easiest to just show me an example that doesn’t work.

For some reason a roblox update that occured a few weeks ago (I think this one) broke the cooking system of a game that I worked on, now the tool falls out of the hand of the player and falls through the map

More background Information, I’m doing lots of manipulation of the Tools on ServerSide and ClientSide

It has worked perfectly fine a few weeks ago, I didn’t touch anything for a year.
But now a bug occurs, and it is not always occuring but sometimes.

I’m using Manipulations

Such as:

		Tool.GripForward = Vector3.new(-0, 1, -0.002)
		Tool.GripPos = Vector3.new(0, -0.09, -0.057)
		Tool.GripRight = Vector3.new(1,0,0)
		Tool.GripUp = Vector3.new(-0,0.002,1)

and:

		local GripForward = Tool:GetAttribute("GripForward")
	
		local GripPos = Tool:GetAttribute("GripPos")
		local GripRight = Tool:GetAttribute("GripRight")
		local GripUp = Tool:GetAttribute("GripUp")
		Tool:SetAttribute("Done",true)
		if GripForward then
			
			SimpleTween(Tool,0.5,"Quad","InOut",{GripForward = GripForward})
		end
		if GripPos then
			
			SimpleTween(Tool,0.5,"Quad","InOut",{GripPos = GripPos})
		end
		if GripRight then	
		
			SimpleTween(Tool,0.5,"Quad","InOut",{GripRight = GripRight})
				end
		if GripUp then
			
				SimpleTween(Tool,0.5,"Quad","InOut",{GripUp = GripUp})
				end

The tool simply falls out of the map while Tweening (not always)
or when unequipping and equipping the tool or when handing it to someone by parenting it so someone elses Backpack and the person equipping it. (not always)

It is happening fairly often.

1 Like

Here is footage of the bug occuring (Also in one case without attachment manipulation):
I’ve also attached one of the food tools where the bug occurs




One Dish.rbxm (32.0 KB)

I’ll look into it, thanks for the detailed info.

I just noticed this change because it affected one of the tools in my game while I was running tests for the next update.

local RandomTool = game.ServerStorage:GetChildren()[math.random(1, #game.ServerStorage:GetChildren())]:Clone()
if RandomTool:IsA("Model") then
	print("model")
	script.Parent.NaughtySound.PlayOnRemove = true
	local coal = Instance.new("Part")
	coal.Size = Vector3.new(2,2,2)
	local coalmesh = Instance.new("SpecialMesh")
	coalmesh.MeshId = "rbxassetid://1290033"
	coalmesh.TextureId = "rbxassetid://16807569"
	coalmesh.Parent = coal
	coal.Parent = game.Workspace
	coal.Position = script.Parent.Position
else
	if not RandomTool:FindFirstChildWhichIsA("BasePart") then
		print("nohandle")
		script.Parent.NaughtySound.PlayOnRemove = true
		local coal = Instance.new("Part")
		coal.Size = Vector3.new(2,2,2)
		local coalmesh = Instance.new("SpecialMesh")
		coalmesh.MeshId = "rbxassetid://1290033"
		coalmesh.TextureId = "rbxassetid://16807569"
		coalmesh.Parent = coal
		coal.Parent = game.Workspace
		coal.Position = script.Parent.Position
	else
		print("success")
		script.Parent.SantaSound.PlayOnRemove = true
		RandomTool.Parent = game.Workspace
		RandomTool.Handle.Position = script.Parent.Position
	end
end

This line of code will pull a copy of a random descendant from the ServerStorage and put it into the Workspace, I told the script to ignore any unwanted Models and only allow any Tool that has a Handle. But because of this ridiculous update the script now thinks that Tools have their ClassName set to Model even though in the properties the ClassName still says it’s a tool. So no matter what the script picks whether it’s a Tool or Model, it’s always going to assume that it’s a Model even if it picks a Tool. I tried using FindFirstAncestorOfClass(“Model”) but that doesn’t seem to do anything. I guess there is no longer a way to distinguish a Tool from a Model anymore…

Three things you could do:

  • You can check the exact class using ClassName: if thing.ClassName == "Model"
  • Use two IsA calls: if thing:IsA("Model") and not thing:IsA("Tool")
  • Alternatively store the stuff in different containers to avoid the problem entirely
1 Like

That actually worked, and I was wasting so much time when I could have just used a double IsA call. I’m going to fix up the game right now!

How would I fix this? It now clones Tools aswell and tries to make that the Player’s Character

local module = {}

local ServerStorage = game:GetService("ServerStorage")
local CharactersFolder = ServerStorage.Characters

module.FindMorph = function (Plr,MorphName)
	for i,v in pairs(CharactersFolder:GetDescendants()) do
		if v.Name == MorphName then
			for _,MorphItems in pairs(v:GetChildren()) do
				if MorphItems:IsA("Model") then
					Plr.MorphName.Value = MorphItems.Parent.Name
					module.MorphPlayer(Plr,MorphItems)
				end
			end

			for _,Tools in pairs(v:GetChildren()) do
				if Tools:IsA("Tool") then
					local Clone =  Tools:Clone()
					Clone.Parent = Plr.Backpack
				end
			end

			return
		end
	end
end

module.MorphPlayer = function (Plr,Morph)
	repeat task.wait() until Plr.Character
	local plrRoot = Plr.Character:FindFirstChild("HumanoidRootPart") or Plr.Character:FindFirstChild("Torso")
	local Animate = game.ReplicatedStorage:FindFirstChild("Animate"):Clone()
	local foot = game.ReplicatedStorage:FindFirstChild("ACS_Client"):Clone()


	local charClone = Morph:Clone()
	charClone.Name = Plr.Name
	Animate.Parent = charClone
	foot.Parent = charClone
	Plr.Character = charClone
	charClone.Animate.Disabled = false

	local rootPart = charClone:FindFirstChild("HumanoidRootPart") or charClone:FindFirstChild("Torso")

	if rootPart and plrRoot then
		rootPart.CFrame = plrRoot.CFrame
	end
	
	Plr.GotCharacter.Value = true
	
	charClone.Parent = workspace
end

return module```

Just change the if MorphItems:IsA("Model") then line → if MorphItems.ClassName == "Model" then

I tried that, it still clones them to workspace.
image

1 Like

Hello, I’d like to give more data about my bug report to the new tool system @tnavarts did you receive my follow up message? I also included a place file that I don’t want to share publicly

the fork is attached to the other hand (see place file below)

the bug happens with no tool and with tools in inventory

I also work with animations and “freezing” the player, I have a test script in serverscriptservice, where I experimented with it, but got no results

It happens in a place with StreamingEnabled and a place without StreamingEnabled

The bug is reproduced in live game and in studio, but it is not happening every time, lots of different people reported it and it started around the same time as the new tool update got released

I can recreate this bug in 1 in 5 tries or so

I’ve also managed to copy my character while the bug occurs, and the very weird thing is that when you reparent the character, the food automatically repositions itself, sometimes to the hand and sometimes randomly in the air, I also uploaded it as a rbxm file. Here the character to drag:
PlayerBuggedTool.rbxm (148.6 KB)

Here is some more footage of the bug recreated in a place file, sometimes it happens the first time you get the tool, and sometimes after unequipping and equipping again, and if you REQUIP and EQUIP while it falls it sometimes it gets fixed I suppose, as you can see it in one video:


Sounds like it’s being treated as an accessory or welded part? Never heard of this happen before, but it sounds interesting. Do you have code that welds the tool?

Hey there! I’ve tested a bit and extracted the minimum code required to replicate the bug and wrapped it into a place that I’m confident to share to the public.

You have to unequip and equip the tool a few times you can do it after the animation is done or before and sometimes the tool falls out of the map for no apparent reason.

You can try it out in the place unless it has been fixed. I basically create a tool on the serverside then flip the tool around and save the normal position and then tween the tool from the flipped to the default position, all done on the server. This seems to break the tool for some reason, either the tool falls immediately out of the map or only after a few unequips or equips, even after parenting it to another player. The weird thing it’s not always happening.

This has never been a thing before “the tool model behavior” update, as I got dozens of reports from people shortly after this update and it is affecting hundreds of players every day in a game that I work on. A fix would probably be custom grip attachments, but I will wait and see if it will be patched.

ToolBugNew.rbxl (97.1 KB)