Is it possible to tell if you can destroy an object?

So I was looking around, but I couldnt figure it out so I have come with a simple question.

Is it possible to tell if you can destroy a certain object?
For instance services in roblox cant be destroyed, there might be other things but those are the only I know.

Thanks in advanced!

2 Likes

You can only destroy an object if it exists otherwise it will throw a warning or an error depending on if you used wait for child, neutral, or find first child

local part = workspace.Part --This will error if the object doesn't exist at the time of creating this variable

if part then
part:Destroy()
end

local part = workspace:FindFirstChild("Part") --This will not error

if part then --but the object will not be destroyed if it doesn't exist when running this check
part:Destroy()
end

local part = workspace:WaitForChild("Part") --No errors, waits until the object exists, then destroys it

if part then
part:Destroy()
end

1 Like

Thanks but this isnt exactly what Im looking for, what I’m trying to tell if a certain object like can actually be destroyed.

Of course a part that doesnt exist cant be destroyed, but if it did exist it can be destroyed.
So like types of instances that no matter what cannot be destroyed. For instance, the workspace, or game itself. That sort of thing.

Thanks nonetheless!

2 Likes

As far as I know, it’s only services that can’t be destroyed. By this logic, you can use ServiceProvider.FindService on the classname and see if it returns the service - if it does, it’s a service!

if (not pcall(game:FindService(instance.ClassName))) then
    instance:Destroy()
end
1 Like

Use:

--
local archivable = part.Archivable
if not archivable then part.Archivable = true end
local clone = part:Clone()
part.Archivable = archivable
--
local canBeDestroyed,_ = pcall(function()
clone:Destroy()
end)
--
print(canBeDestroyed)
--

This is something I was considering, but I noticed it doesnt account for StarterChacterScripts and StarterPlayerScripts, I will def use this for part of it, but what about these two? Theres also the ClientReplicator inside of NetworkClient.

Why couldnt roblox just have given them a property or something :sob:

The only issue with this is it’d most likely cause a lot of lag in the long run. Especially when I have to call this on the workspace, which would then load all of its many children, which probably wouldnt be too great, but it would certainly work, just not sure if its worth the performance hit (cause I assume there will probably be one)

You cant really tell becouse all of services do inherit this instance class: Instance | Documentation - Roblox Creator Hub
So no you cant BUT BUT
You can do some weird shenanigan to check if its a service or not

type(select(2,pcall(game.FindService,game,InstanceYouWantToCheck.ClassName)))=="userdata"

!!! WHAT TO DESTROY!!!

1. Dynamic Instances

What: Part, ScreenGui, Sound, etc.
How:

local part = Instance.new("Part")
part.Parent = workspace
part:Destroy()

2. Event Connections

What: .Touched, .Changed, .MouseClick, etc.
How:

local conn = part.Touched:Connect(function()
	print("Touched")
end)
conn:Disconnect()

3. Coroutines / Loops / Tasks

What: task.spawn, while, loops
How:

local running = true
task.spawn(function()
	while running do
		task.wait(1)
	end
end)
running = false

4. Cloned Models / Tools

What: Cloned parts, NPCs, tools
How:

local clone = template:Clone()
clone.Parent = workspace
clone:Destroy()

5. Temporary Effects or Sounds

What: Explosion, Sound, ParticleEmitter
How:

local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://123"
sound.Parent = workspace
sound:Play()
sound.Ended:Connect(function()
	sound:Destroy()
end)

6. Temporary UI

What: Notifications, prompts, dialog boxes
How:

local gui = Instance.new("ScreenGui")
gui.Parent = player:WaitForChild("PlayerGui")
gui:Destroy()

7. Temporary Values

What: BoolValue, IntValue, etc.
How:

local flag = Instance.new("BoolValue")
flag.Value = true
flag:Destroy()

!!! WHAT YOU SHOULD NOT DESTROY !!!

Type Example Why
Services game:GetService("Players") Core system services; destroying will break game
Static Assets Assets in ReplicatedStorage, ServerStorage, StarterGui, etc. Shared across sessions, used for cloning
Starter Scripts Scripts inside StarterGui, StarterPack, StarterPlayerScripts Needed for player respawn and setup
Player Characters player.Character Managed by the engine on spawn/death
Scripts (usually) Script, LocalScript, ModuleScript Not typically destroyed directly; use carefully

this suffers the same issue that mine does, because things like StarterPlayerScripts are not services but are also not destroyable.

you’d also be better off with an if statement because userdatas are truthy values anyway.

I don’t really like “truthy” values and i hope roblox will allow compiled code to do actual checks instead of having “truthy” values.

most programming languages have truthy values, it’s just value that is treated as true for an if statement.

Luau bytecode can’t really do that because of type safety. in languages like C++, absolute type safety and inference is required for the code to even compile, but Luau is type-safe, meaning the type might not actually be known until runtime. Off the top of my head, Luau bytecode relies on the runtime environment to evaluate truthiness, but don’t quote me on that.

well, considering ServiceProvider.FindService requires a pcall for this anyway, you might as well just have a go at changing the parent and seeing if it errors.

local canChangeParent = pcall(function()
    local p = inst.Parent
    inst.Parent = nil
    inst.Parent = p
end)

but ofc this will fire signals like ChildAdded, ChildRemoved, etc etc. Although it seems a like a workaround, I’d probably say your best bet is storing a table of the classnames that aren’t services but still have the property locked, and checking that table for the classname too.

you’re right, it could all be fixed if Roblox just exposed a readonly property…

1 Like

No
Im talking about --!native mode

truthy and falsy values don’t exist in machine code, and roblox’s native codegen (native mode) compiles Luau code to machine code. It sits somewhere between JIT compilation and AOT compilation.

For example, if you write something like:

if var then

and the compiler correctly inferred var as a boolean,
it might look like this in asm:

cmp rdi, 1                ;if var is stored in the rdi register
je .Lif_true              ;this would resolve to a runtime address

but if your code is not type safe, the compiler might infer extra runtime checks, or execution might even fallback to interpreted if the compiler cannot evaluate types accurately or “confidently”.

so truthy values don’t actually exist in native codegen, they are expanded to full expressions.

some things like the thing under networkclient cant be destroyed too

1 Like

yep frodev mentioned that too which sadly means we cant use findservice on it
i think the next best thing without even more pcalls would probably be a lookup table of the small amount of classnames that arent services and cant be destroyed as i mentioned here

That literally what i have been saying
You seem probably misunderstood me.

you’re basically saying compiled Luau has truthy values…
please explain where you said that native code doesnt have truthy/falsy values

local part = workspace.Part
local success, result = pcall(function() return part.Destroy end)
print(result) --memory address of function (if the instance has a destroy method)