I’m afraid this isn’t possible, and it’s because how Luau as a language manages memory.
first of all, it’s very important to note that Luau is a memory safe language. This means it has its own garbage collector, which I will explain more about in a minute.
The Roblox engine is written in C++, and one of the reasons Luau is the scripting language is because it can be directly embedded and run from C++ code. Lua, the language Luau is derived from, also supports this. You can actually see this by running debug.info(_, "s")
(where _
is a built-in function), to retrieve the function source. You’ll notice it returns [C]
.
There are two main memory structures: the stack and the heap.
The stack is a structure where local variables and function call data is stored. Imagine a stack of plates - one is added on top and one is removed. This is where temporary data is held, and it’s accessible from both C++ and Luau.
The heap is an unordered area of memory, and this is where the garbage collector acts. Data is stored here for long-term use; things like your baseplate you talked about before. The garbage collector detects when items in your script are no longer referenced and clears the memory associated with them. This prevents memory leaks and keeps unnecessary memory free for when it’s next needed.
Let’s take an example function of C++ to further explain this. Imagine you have this very basic function to multiply a number by 2.
int multiplyNumber(lua_State* L) { //L is a pointer to the lua stack manager
int num = lua_tointeger(L, -1); //this retrieves the top item from the stack and converts it to an integer
int result = num * 2; //this is the logic for multiplying by 2
lua_pushinteger(L, result); //this pushes the result back onto the stack
return 1; //telling lua how many values the function left on the stack
}
//would then go on to register this function to Lua
Your Lua code would then receive this integer and carry on like normal.
local val = multiplyNumber(3)
The same thing is happening to your baseplate, really. When you initialise the variable a
, you are giving it a reference to the baseplate in the workspace. When you destroy the baseplate, it doesn’t get cleared from memory; all destroy does is set the parent to nil, lock the parent, and call destroy on all descendants. This means you can’t reference it again without the variable.
When your code finishes executing, the garbage collector notices a
isn’t used anymore. Hence, it frees the memory location a
was at. This is why when you output a
after destroying it, it still prints the baseplate, because a
isn’t out of scope yet, so it still exists in memory. After all code referencing the baseplate goes out of scope, then that too will be freed from memory.
I hope this clears things up, please ask if you have any questions, i appreciate this is quite a lengthy explanation.
Note: Although I said the C++ stack is accessible from both C++ and Luau, it can only be manipulated manually through C++. You can’t access it in Luau.
TL;DR: You can’t access the Luau stack or heap!
*note to anyone who is concerned about this: yes, you can actually access the Luau stack but with limited access - you can only read from it, and specific values at that. debug.info
with the f
option and a stack level (e.g. debug.info(2, "f")
would return the function at stack level 2 should it exist.