Getfenv() question

i hear it gets the environment of something, but what exactly is a environment and what is it used for?

3 Likes

Environments hold the variables. Each function has a different environment (afaik).
If you create a variable

local thing = {}

You can get the value via indexing by doing

getfenv().thing

Lua stores global variables in the environment. The environment is a table of all the global variables. getfenv can get the environment of a function or of a stack.

With the exception that it doesn’t hold local variables, getfenv().thing is nil unless you delete the local

1 Like

You’re right. Stacks are definitely extremely confusing. I rarely use getfenv() so I don’t know in detail how it works.

Dont judge me on anything I say here. But i’m pretty sure i’ll try and explain it.

getfenv stands for getting the functions environment.
And environment is the enclosure the script is being ran in. By default we have globals and what not. Such as os, script, game, workspace. what not.

There is one global in there which is unique. And thats the script variable. I’ll talk about this more later.
Anyway, So when a lua script is executed. It’s given these globals so that the script can work. You can edit these globals too with the getfenv function.

Now. getfenv also allowes you to retrieved stacked information. So you can process the environment of a function that called this function.

local function b()
    local BFunctionEnviroment = getfenv(2) -- If we did 1 it would return A enviroment

   return BFunctionEnviroment.VariableName
end

local function a()
   VariableName = "Hello, World!"

   return b()
   --this environment is 2nd now.
   -- b environment is first.
end

print(a()) -- "Hello, World!"

Now. Lets go onto how and what an environment can be used and manipulated for.

Well first we can actually set custom globals. I’ll show you an example now.

local function b()
    print(CustomVariableThatDoesntExist) -- Hello, World!
end

setfenv(b, {CustomVariableThatDoesntExist = "Hello, World!"}) -- An environment
-- is an table. And ofc if you wanted you could attach metatables. Allowing you
-- to do quite alot.

Now. Lets talk about that script variable. As we already know. All these globals like shared, _G game, workspace are shared bewteen every script. So including them into the environment is a waste. But having a Unique thing like a script. Because each script is different is important.

So if you were to grab the environment of a function and print it. You’ll see only “script” comes up. And thats because everything else is naturally there. Ofc you can manually set your own globals. Rewriting them but it’s not advised as it’s a little bit important to connect it to the game.

Either way. You’ll see environment exploitation being used in sandboxes and stuff.

6 Likes

Biiiiiiiiig wooooords. Sorry if I didn’t explain it to a good extent. I’m tired and its 1:30 in the day.

1 Like

As my knowledge it returns global variable(s) from the current script

here’s an example from Roblox Developers Hub

myVariable = "Hello, environments" -- Note: a global variable (non-local)
local env = getfenv()
print(env["myVariable"])  -- Hello, environment

this doesn’t actually work, when you do setfenv() you override everything including the print() function so instead it just gives the error “attempt to call a nil value”

Whoah… two years? It’s really been that long… :eyes:

As for this yeah what you could do is set the metatable to index the environment your in at the time;

setfenv(something, setmetatable({ abc = 123 }, { __index = getfenv() } )
2 Likes