So a while back I created two modules that wrapped the TweenService and Debris. You just use them in place of the direct service itself and it adds some additional functionality. I’ve been using them for a while so I figured why not just post them to the devforum to anyone that needs to use them so here you go.
--example on how to use it (debris)
local Debris = game:GetService("Debris")
local part = workspace.Part
Debris:AddItem(part, 10) --this is the only function of debris afaik
--now with the wrapper:
local Debris = require(path_to_module) --instead of getservice you just require the module, duh
local part = workspace.Part --whatever instance
Debris:AddItem(part, 10) --scheduled to be destroyed in 10 seconds
Debris:PauseItem(part) --indefinitely pauses
Debris:UnpauseItem(part)
Debris:PauseItemForDuration(part, 2) --pauses for 2 seconds (just adds two seconds to its lifetime, can be used to shorten lifetime), extendlifetime may be a better name
Debris:IsAlive(part) --returns 1: whether or not the item is alive (true for still in queue, false for has been destroyed, or nil for the item not being in queue), and 2: the item's remaining lifetime (-1 for has been destroyed and nil for not in queue)
Debris:RemoveItem(part) --hallelujah!
Otherwise, for the tweenservice wrapper, it functions (and is used) identically to the regular tweenservice without any additional functionalities. It simply destroys the tweens once they have completed. The original reason I created this module was because I read somewhere that tweens aren’t necessarily gc’d correctly, or something of the sort. However, after a 2 second dive through a few devforum posts, this appears to be unnecessary since it isn’t actually true from what I’ve once again read. This module is definitely unnecessary, however I’ve included it anyways just for the hell of it. Please don’t pester me about it.
Debris Source
local Queue: {[Instance]: number} = {}
local Debris = game:GetService("Debris")
game:GetService("RunService").Heartbeat:Connect(function(dt)
for item, lifespan in pairs(Queue) do
if item and item.Parent and lifespan > 0 then
if lifespan - dt <= 0 then
Queue[item] = nil
item:Destroy()
else
Queue[item] -= dt
end
end
end
end)
return setmetatable(
{
AddItem = function(self: any, item: Instance, lifetime: number?)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
Queue[item] = lifetime ~= nil and lifetime < 1 / 60 and 1 / 60 or lifetime ~= nil and lifetime or 10
end,
addItem = function(self: any, item: Instance, lifetime: number?)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
Queue[item] = lifetime ~= nil and lifetime < 1 / 60 and 1 / 60 or lifetime ~= nil and lifetime or 10
end,
RemoveItem = function(self: any, item: Instance)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
if not Queue[item] then warn(item.ClassName..' "'..item.Name..'" could not be found in debris.') return end
Queue[item] = nil
end,
PauseItem = function(self: any, item: Instance)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
if not Queue[item] then warn(item.ClassName..' "'..item.Name..'" could not be found in debris.') return end
Queue[item] = -math.abs(Queue[item])
end,
UnpauseItem = function(self: any, item: Instance)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
if not Queue[item] then warn(item.ClassName..' "'..item.Name..'" could not be found in debris.') return end
Queue[item] = math.abs(Queue[item])
end,
PauseItemForDuration = function(self: any, item: Instance, duration: number)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
if not Queue[item] then warn(item.ClassName..' "'..item.Name..'" could not be found in debris.') return end
Queue[item] += Queue[item] / math.abs(Queue[item]) * duration
end,
IsAlive = function(self: any, item: Instance): (boolean?, number?)
assert(typeof(item) == "Instance", "Unable to cast value to Object")
return Queue[item] and true or item.Parent ~= nil and nil, Queue[item] or not item.Parent and -1 or nil
end
},
{
__index = Debris,
__newindex = Debris,
}
) :: {
AddItem: (self: any, item: Instance, lifetime: number?) -> (),
addItem: (self: any, item: Instance, lifetime: number?) -> (),
RemoveItem: (self: any, item: Instance) -> (),
PauseItem: (self: any, item: Instance) -> (),
UnpauseItem: (self: any, item: Instance) -> (),
PauseItemForDuration: (self: any, item: Instance, duration: number) -> (),
IsAlive: (self: any, item: Instance) -> (boolean?, number?)
} & Debris
TweenService Source
local TweenService = game:GetService("TweenService")
return setmetatable(
{
Create = function(self, ...)
local Tween = TweenService:Create(...)
Tween.Completed:Once(function()
Tween:Destroy()
end)
return Tween
end
}, {
__index = TweenService,
__newindex = TweenService,
}
) :: TweenService
This was my first community resources post so thank you for reading. If you have any optimizations (I’m more specifically thinking about the runservice loop in the debris module), please let me know. Enjoy!