Debris MaxItems still in effect despite being deprecated

True. A custom debris function is the way now.

1 Like

We are likely going to deprecate Debris entirely as it has numerous implementation problems and is not more efficient (in fact, far less efficient) than the equivalent Lua code:

task.delay(lengthOfTime, function()
    instance:Destroy()
end)

We recommend using this from now on instead.

6 Likes

Couldn’t you just make Debris:AddItem use that internally rather than whatever it currently uses? If Debris:AddItem switched to using task.delay(length, Instance.Destroy, Instance) it would also patch AddItem being affected by MaxItems.

6 Likes

This seems pretty easy to do and would maintain lots of backwards compatability for older games, whilst also boosting their performance.

1 Like

A lot of thought has to go into updating endpoints, so its a lot more work than it seems.

Just use DebrisGobbler for now

2 Likes

I have a quick question. One of the advantages with using Debris:AddItem is that it doesn’t error if the given object has already been destroyed after the elapsed time. Wouldn’t this script with task.delay lose that advantage? I find it useful for despawning bullets and things like that. I know you could manually check, but it is nice that Debris:AddItem could take care of that on its own.

1 Like

You can prevent the error by checking if the Instance still exists. Here is an example:

task.delay(lengthOfTime, function()
	if instance then
		instance:Destroy()
	end
end)

I will miss Debris:AddItem only taking up one line of code and making it all look prettier. Perhaps it should be updated to use this new formula like the others have suggested rather than being deprecated.

Thanks

3 Likes

If you want it to only take one line of code, you can always turn it into a function, and call the function instead. If you will be using it across your entire project, you can also put the function in a module. I think soft deprecation of the service is fair, since it doesn’t provide much value to justify being a service.

A function or a module will never be at the same level as a service

I have used debris a couple of times. It isn’t the most useful service but I don’t want it gone…
I guess the reality is that improving it is more effort than just deprecating it

1 Like

Why would that be a bad thing? Why does that matter in this case?

Simply for tidiness. Services are integrated within Roblox which makes them the default option when you want to achieve something, and so “cleaner”, in a way
With modules you have to integrate them in every game where you need it. It’s not a lot of work, but it’s not the same as a service

1 Like

you can do

task.delay( time_, game.Destroy, instance )

or

task.delay( time_, instance.Destroy, instance )

I don’t actually think the code the staff provided does error if the instance has already been destroyed–only if the instance was set to nil.

2 Likes

Wow, thank you, it seems like this is working perfectly.

It looks like you’re correct. Does Destroy() never give errors when you call it on something that has already been destroyed? I just assumed it would error in that circumstance.

Yep, you can destroy something as much as you want.

That’s useful information to know.

I’ve noticed another potential issue with replacing Debris:AddItem with the task.delay function. If the script running the task.delay gets destroyed, the delayed event won’t fire. This isn’t the case with using Debris:AddItem, which will remove the specified item even if the script it was called in is gone.

For example, Roblox’s Linked Sword model uses Debris:AddItem to clear the “Creator_Tag”, used to track kills on the leaderboard, after two seconds. Say you use the new task.delay system instead of Debris in this script, damage a player, then respawn before those two seconds expire, would the creator tag not then become “stuck”, since the script that ran the task.delay was destroyed upon your respawning?

1 Like

The documentation appears to state the exact opposite. Which of these statements is true?

Also, it would be best if MaxItems was not enforced regardless of whether Debris is less efficient, I have been using this service entirely unknowingly about this behaviour and I can only assume many other developers have too, Debris is a nice fast solution for scheduling part deletions.

1 Like

This is not equivalent to Debris:AddItem. Scripters have always been enabled to simply pop open a new thread; that’s not why Debris service has historically had so much utility.

The crucial difference with Debris, is that the cleanup gets done, regardless of whether or not the calling script lives long enough to see it. Your solution won’t work in cases where the host is prematurely terminated; as happens frequently, when scripts are externally disabled, or otherwise parented outside of a container where they can run (destroyed).

Here’s a little demo I just threw together for anyone curious to see this pitfall in action:

5 Likes

No. instance:Destroy() does not error either if the instance is already destroyed.

The documentation here is a little overkill–it’s checking also that the projectile isn’t nil and isn’t parented, but you don’t need to check either of these. The new thread shouldn’t have any noticeable impact on performance either. The motions to deprecate Debris are not finalized yet, but I would defer to my statements.

1 Like

For anyone interested, I’ve come up with a pretty elegant workaround to the problem I pointed out.

Since modules are effectively initialized as a unique script, we can leverage a ModuleScript to be a generator of external threads like so:

return task.spawn(function()
	while true do
		task.delay(coroutine.yield())
	end
end)

Then this generator can be resumed, to schedule new threads unassociated with the requiring script:

local ExternalThread = require(Module)
coroutine.resume(ExternalThread, LifeTime, Object.Destroy, Object)
-- Or alternatively
task.spawn(ExternalThread, LifeTime, Object.Destroy, Object)
1 Like