Typed API
Use typed Luau methods with predictable cleanup semantics and named scopes.
Roblox Luau lifecycle utility
A typed cleanup scope for Roblox systems. Track connections, instances, promises, tweens, render bindings and temporary resources, then clean them up with one clear lifetime owner.
Install
[dependencies] GarbageMan = "virtualdesign0/garbageman@0.1.4"
Core idea
Roblox systems often create resources that should not live forever. A UI screen has connections and tweens. A weapon has input bindings. An NPC has controllers and events. A projectile has a short lifetime. GarbageMan gives each of those systems a clear owner.
Features
Use typed Luau methods with predictable cleanup semantics and named scopes.
Track instances, connections, functions, threads, promises, tweens and custom objects.
Replace, get, remove or drop resources when only one object should own a tag.
Create nested lifetimes with Extend and Adopt. Parent destruction cleans children.
Use AddTemporary, CleanAfter and DestroyAfter for hitboxes, UI, VFX and projectiles.
Split larger cleanup work across scheduler steps with CleanBatched or DestroyBatched.
Connect, Once, DestroyOnSignal and ReplaceConnection keep event cleanup close.
Inspect summaries, leak warnings, failed cleanup info and optional profiling data.
Clean vs Destroy
Clean removes current resources, but the scope can be used again.
local scope = GarbageMan.new("Round")
scope:Add(connection)
scope:Clean()
scope:Add(newConnection) -- valid
Destroy is final. Mutating methods should not be used afterwards.
local scope = GarbageMan.new("Weapon")
scope:Add(connection)
scope:Destroy("Weapon unequipped")
scope:Add(otherConnection) -- error
Installation
Mount the module into ReplicatedStorage and require the folder directly.
{
"name": "GarbageMan",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"GarbageMan": {
"$path": "src/GarbageMan"
}
}
}
}
Add GarbageMan as a dependency, then install packages.
[dependencies]
GarbageMan = "virtualdesign0/garbageman@0.1.4"
# then
wally install
Download the latest release asset and drag it into ReplicatedStorage.
https://github.com/Virtualdesign0/GarbageMan/releases/latest/download/GarbageMan.rbxm
Examples
local scope = GarbageMan.new("InventoryUI")
local frame = scope:Copy(InventoryTemplate)
frame.Parent = playerGui
scope:DestroyOnSignal(closeButton.Activated, "Inventory closed")
local tween = TweenService:Create(frame, tweenInfo, {
Position = UDim2.fromScale(0.5, 0.5),
})
scope:ReplaceTween("Tween:Open", tween)
tween:Play()
local scope = GarbageMan.new("Hitbox")
local hitbox = Instance.new("Part")
hitbox.Name = "TemporaryHitbox"
hitbox.Anchored = true
hitbox.CanCollide = false
hitbox.Parent = workspace
scope:AddTemporary(hitbox, 0.25)
scope:Connect(hitbox.Touched, function(hit)
print("Touched:", hit.Name)
end)
local projectileScope = GarbageMan.new("Projectile")
projectileScope:DestroyAfter(10, "Projectile expired")
local projectile = projectileScope:Construct(Instance, "Part")
projectile.Name = "Projectile"
projectile.Parent = workspace
projectileScope:Connect(projectile.Touched, function(hit)
projectileScope:Destroy("Projectile hit")
end)
local roundScope = GarbageMan.new("Round")
for _, npc in npcs do
roundScope:Add(npc)
end
roundScope:DestroyBatched("Round ended", 50)
API Preview
| Method | Purpose |
|---|---|
Add() | Track one resource. |
AddMany() | Track multiple default-cleanable resources. |
Replace() | Store one tagged resource and clean the old one. |
Connect() | Connect to a signal and track the connection. |
ReplaceTween() | Replace a tagged tween and cancel the previous one. |
AddTemporary() | Clean one resource after a delay. |
Clean() | Clean current resources while keeping the scope reusable. |
Destroy() | Final cleanup. The scope should not be used afterwards. |
Extend() | Create a child scope owned by the current scope. |
DestroyBatched() | Destroy the scope and split cleanup work into batches. |
Debugging
Use summaries for safer debug panels without printing real object references.
for _, summary in GarbageMan.Debug.getSummary() do
print(
summary.name,
summary.size,
summary.age,
summary.destroyed
)
end
Enable tracebacks, leak warnings or profiling while testing.
GarbageMan.configure({
tracebacks = true,
captureAddTracebacks = true,
leakWarnings = true,
profiling = true,
})
Behavior Notes
Create scopes for real lifetimes like UI screens, weapons, NPCs or projectiles.
Remove cleans the resource. Drop releases it without cleaning.
Tags are useful for replacement cleanup, not for all gameplay state.
If the system is finished for good, prefer Destroy over Clean.
Ready to use
GarbageMan stays light for gameplay code while still covering debugging, child scopes, delayed cleanup and batched shutdown.