Lifecycle and cleanup
Re-running your script, tearing a window down, and disconnecting everything cleanly.
Re-running replaces, it does not stack#
By default, running your script again closes the previous window and opens a fresh one:
local win = Ember.new({ Title = "My Script" })That is deliberate. While you are working you run the same loadstring over and over, and without this every run leaves another live window behind — each with its own keybind, its own tile pool and its own dissolve. Pressing the toggle key then plays every one of them at once, which feels like the UI getting slower each time you execute.
To have two windows on screen together:
local win = Ember.new({ Title = "My Script", ReplaceExisting = false })Only the newest window answers the keybind
Even with several windows open, the toggle key belongs to the most recently created one. Otherwise a single press would fire every window's animation simultaneously.
Destroying a window#
win:Destroy()This disconnects every event Ember made, stops every running animation, clears its tile pool and removes the GUI. After it, the window is gone and nothing of it is still running.
Cleaning up your own work#
Your script has connections Ember knows nothing about. Register them and they are torn down with the window:
win:OnDestroy(function()
heartbeat:Disconnect()
myEspFolder:Destroy()
end)You can register as many as you like; they run in order when the window is destroyed.
For a connection you want managed entirely by the window, Track takes it
directly:
win:Track(game.Players.PlayerAdded:Connect(onPlayerAdded))Tracked connections are disconnected on destroy without you writing any cleanup at all.
A complete, well-behaved script#
local Ember = loadstring(game:HttpGet('https://rbx.lol/ember.lua'))()
local win = Ember.new({ Title = "My Script", Subtitle = "v1.0" })
local main = win:Section("Main", "house")
local running = true
-- Managed by the window: gone when it is.
win:Track(game:GetService("RunService").Heartbeat:Connect(function()
if not running then return end
-- per-frame work
end))
main:Toggle({
Text = "Enabled",
Default = true,
Callback = function(on) running = on end,
})
main:Button({
Text = "Close",
ButtonText = "Exit",
Danger = true,
Callback = function() win:Destroy() end,
})
win:OnDestroy(function()
running = false
print("cleaned up")
end)What survives a destroy#
Saved settings. They are on disk, not in the window, so destroying a window and
running the script again restores everything with a Save key — including the
window's own size and position if you set SaveLayout = true.
To wipe them:
Ember.Store.clear("godmode") -- one keyChecking whether a window is still alive#
Every window is registered while it exists:
local live = getgenv().__EMBER_LIVE -- array of live windows
print(#live)This is what ReplaceExisting reads to find the previous window. You rarely
need it directly, but it is the honest answer to "is my old window still
there".