Tornado doing minimal damage

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

The tornado doing more damage
The tornado only sucks up a few parts, and I need it to be a lot more destructive

I didn’t change the script between now and when I attached a billboard gui tornado to my script. I’m not sure what changed, but I looked around to see if I accidentally changed anything, and it all looked normal.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

-- This is an example Lua code block

Screenshot 2025-06-17 101343

Hazard script:

local tor = script.Parent
local debounce = true
local attackrange = 100


local near = coroutine.resume(coroutine.create(function()
	while wait() do
		local region = Region3.new(
			Vector3.new(tor.Position.X - tor.Size.X/2 - attackrange, tor.Position.Y - tor.Size.Y/2 - attackrange, tor.Position.Z - tor.Size.Z/2 - attackrange),
	  		Vector3.new(tor.Position.X + tor.Size.X/2 + attackrange, tor.Position.Y + tor.Size.Y/2 + attackrange, tor.Position.Z + tor.Size.Z/2 + attackrange)
		)
		local parts = workspace:FindPartsInRegion3(region)
		for i,p in pairs(parts) do
			if p:IsA("BasePart") and p.CanCollide == true and p:GetMass() < 1000000 then
				if not p:FindFirstChild("TornadoSuckingForce") then
					-- enssential stuff
					local bp = Instance.new("BodyPosition")
					bp.Name = "TornadoSuckingForce"
					bp.MaxForce = Vector3.new(2000 * p:GetMass(), 2000 * p:GetMass(), 2000 * p:GetMass())
					bp.Parent = p
					-- this will let the parts handle itself, instead of a whole script handling everything to reduce lag
					local torvalue = Instance.new("ObjectValue")
					torvalue.Name = "WhichTornado"
					torvalue.Value = tor
					torvalue.Parent = p
					local scr = script.SuckingScript:Clone()
					scr.Parent = p
					scr.Disabled = false
					-- extra stuff
					local bav = Instance.new("BodyAngularVelocity")
					bav.Name = "SuckingRotation"
					bav.MaxTorque = Vector3.new(4000 * p:GetMass(), 4000 * p:GetMass(), 4000 * p:GetMass())
					bav.AngularVelocity = Vector3.new(math.random(1,25), math.random(1,25), math.random(1,25))
					bav.Parent = p
				end
			end
		end
	end
end))

Sucking script:

local sp = script.Parent
repeat
	wait()
until sp:FindFirstChild("WhichTornado")
local tor = sp:FindFirstChild("WhichTornado").Value
local bp = sp:FindFirstChild("TornadoSuckingForce")
local bav = sp:FindFirstChild("SuckingRotation") -- Assuming you want to keep rotation

sp.Anchored = false
sp:BreakJoints()
game.Debris:AddItem(sp,9999) -- Lifetime of the debris

-- Create BodyForce for upward and outward push

local bf = Instance.new("BodyForce")
bf.Name = "TornadoLaunchForce"
bf.Parent = sp

local height = 0
local maxSuckHeight = 1

repeat
	-- Calculate the relative position to the tornado's center (on the Y axis)
	local relativeY = sp.Position.Y - (tor.Position.Y - tor.Size.Y / 2)

	-- Calculate outward force based on height (further up, more outward)
	local outwardStrength = relativeY / maxSuckHeight * 5 * sp:GetMass() -- Adjust multiplier as needed
	local outwardDirection = (sp.Position - tor.Position) * Vector3.new(1, 0, 1) -- Project onto XZ plane
	if outwardDirection.Magnitude > 0 then
		outwardDirection = outwardDirection.Unit * outwardStrength
	end

	-- Apply upward force (constant or increasing with height)
	local upwardStrength = 200 * sp:GetMass() + (relativeY / maxSuckHeight * 25 * sp:GetMass()) -- Adjust multipliers
	local upwardForce = Vector3.new(0, upwardStrength, 0)

	bf.Force = upwardForce + outwardDirection

	-- Update BodyPosition to guide towards the center with a radial offset
	local radialOffset = tor.Size.X/0.75 + height/75
	local targetPosition = (CFrame.new(tor.Position - Vector3.new(0, tor.Size.Y/2, 0)) * CFrame.Angles(0,math.pi*2*((tick()/5)%1),0) * CFrame.new(radialOffset, height, 0)).Position
	bp.Position = targetPosition

	height = height + (tor.Size.Y/25*0.5) -- aka 2% of it's Y size
	wait()
until height >= maxSuckHeight -- Use >= to ensure it finishes even if height slightly exceeds


bf:Destroy()
bav:Destroy()
bp:Destroy()

If I need to include more, such as how the bbguis are attached, I can.
the locator gui is just a bbgui attached to the part without any scripts, so I can see the tornado if the bbguis glitch out.

1 Like

i mean… you have an attackrange variable.

just increase it?

more range more damage!

1 Like

the attack range variable is already pretty high but its not whats causing it to not destroy things. Something somewhere is limiting the amount of parts it can suck somehow

1 Like

How many parts are you wanting to move? More parts = more load on the server.

How many Unanchored Parts are in your place? Physics gets overloaded if it has to calculate all the objects, even the unmoving ones.

Have you tried setting the NetworkOwnership of the Parts to see if that makes a difference?

1 Like

I want to move around 20 parts at a time, because they quickly exit the tornado, and I plan on building the houses unanchored but welded to an anchored base, with pieces welded together made of meshes that fit together like a puzzle.

currently only around 5, the few ones the tornado managed to unanchor
I thought it was an issue with too many billboard guis, but deleting them didn’t work.

And changing the network owner seemed to make it worse, though I probably did it wrong.

1 Like

What’s the Density of the Parts?
If you make it lower it would be moved more easily.

You could also try setting a variable to p.GetMass() so the script didn’t have to calculate it each time you call GetMass. Something like:

					-- enssential stuff
					local bp = Instance.new("BodyPosition")
                    mass = p.GetMass()

Then just use mass throughout your other calculations.
Try increasing your multiplier values as well. Change the 2000 in your bp.MaxForce line to something like 10000 to test and see if it works better. If it does then fine tune it to the value that works properly for you.

1 Like

I kept increasing it until i got to 99,999,999,999,999, it wasn’t affecting it. I think something must be inhibiting it somehow

1 Like

Some parts might not be able to move because others that are surrounding it might be anchored. Causing a collision issue. Since they “can move” but are stuck in between other parts.

1 Like

Yeah, but the tornado should be pulling a lot more parts, which would unstuck the others (90% of the time)

1 Like

Well based on the code, it has to do with the part ingame. That’s my guess :confused:

1 Like

How are you getting rid of the Welds that hold these Parts down?

Oh your question pointed out an issue.

I’ve been using BreakJoints() but I was looking to make sure it does what I think it does and noticed that its actually been deprecated, so I tried an alternative from a post about it and it, but I noticed the issue is the tornado not sucking up parts at all.

Try checking to see if there is a Weld (or WeldConstraint, whichever one you are using) in the Part you are trying to suck up.
If there is just Destroy() it.