Hi there, I am commonly running into a small problem when trying to optimize my code. I would like to use a single variable for the pathway of another variable’s children / properties, but I do not know how. I have tried looking for a solution in documentation and surrounding the variable in brackets, but to no avail.
In AutoHotKey, this can be accomplished by surrounding the variable in percentage signs:
variableTable := [“This should not appear”]
variablePathway := variableTable[1]
%variablePathway% := “This should appear”
Msgbox, % variableTable[1] ; “This should appear” is shown. How can I do the same thing in Lua?
-- (Example One)
local variableOne = "I Dont Want This To Print"
local function functionExample(variablePathwayToChange)
variablePathwayToChange = "I Want This To Print"
end
functionExample(variableOne)
print(variableOne)
-- (Example Two)
local tableVariable = {"I Don't Want This To Print"}
local targetIndex = tableVariable[1]
targetIndex = "I Want This To Print"
print(tableVariable)
-- (Example Three)
local targetProperty = script.Name
targetProperty = "I Want The Script's Name To Change To This"
wait(3)
targetProperty = "Then, It Should Change To This"
This is close to what I am looking for and it is what I have been using in my scripts but I would like to have the whole pathway inside of a single variable so that I do not have to redefine it a bunch of time later on. Sorry, for I am having trouble explaining my problem. I will try with a practical example.
-- below data works, but how can I condense it so that playerConfiguration.Walkspeed is its own variable?
if (playerConfiguration.WalkSpeed > 3) then -- should be able to condense
playerConfiguration.WalkSpeed = 14 -- should be able to condense
playerConfiguration.JumpPower = 0
end
-- I would like for it to look like:
local playerSpeedProperty = playerConfiguration.WalkSpeed
if (playerSpeedProperty > 3) then
playerSpeedProperty = 14 -- however, this just replaces the content of the variable and does not actually set the humanoid's walkspeed to 14
playerConfiguration.JumpPower = 0
end
Ok well no other way then to make a table and function so like:
function getObjectFromTable(tbl)
local path = game
for _, prop in pairs(tbl) do
path = path[prop]
end
return path
end
local pathVar = {"Workspace", "Baseplate", "Position"}
local playePosition = getObjectFromTable(pathVar)
I thought that what I would like to do could be done by surrounding it in brackets like:
local tableVariable = {{{"This should get replaced"}}}
local pathwayVariable = tableVariable[1][1][1]
[pathwayVariable] = "This should replace it" -- this does not work like how I would expect it to
print(tableVariable)
wait(3)
[pathwayVariable] = "Then it should be replaced by this" -- but, if there is a way to do this, I would not have to redefine the location again by using this method.
print(tableVariable)
There is no way to create a reference to a specific value in Lua. You can only create a reference to tables (and userdata I believe), otherwise it just clones the value and stores it separately.
local a = 1 --set "a" to 1
local b = a --set "b" to the value of "a"
a = 2 --set "a" to 2
print(a, b) --> 2, 1
local a = {} --declare a new table assigned to "a"
local b = a --declare a new reference to table "a"
b[1] = 1 --set the value of table "a" to 1
print(a[1]) --> 1
local a = {1} --declare a new table with a value assigned to "a"
local b = a --declare a new reference to table "a"
local a = nil --remove the old reference of the table
--the table doesn't get deleted by gc as it still possesses an active reference
print(b[1]) --> 1
Note: This disables lua optimizations!! (To get the context certain optimizations can’t be used or else it would break. This is why some script optimizations are disabled).
You can do this:
local __ = getfenv(); --To shorten it
local myVar = 1;
local myPathway = "myVar";
__[myPathway] = 2;
print(myVar);
I am pretty sure you can also index functions to getfenv since it is a table. If so you can use __index and __newindex.
For instance you can never do something like this:
local myVar.Hello.One = 1;
You can take advantage of this by doing a methamethod called “__newindex”. You can make it so it breaks apart the name, so it actually replaces this:
local myVar = {
Hello = {
One = 1
}
}
--Instead of this
local myVar.Hello.One
And index should return the value. If you do that then you can do something like this:
You really have 2 options, the function I gave you, which is more secure (probably) or the getfenv method that @STORMGAMESYT7IP gave (which is probably less secure because, well, it’s getfenv)
local variableTable = {"I Dont Want This To Print"}
local function functionExample(tableToChange, tablePathway)
tableToChange[tablePathway] = "I Want This To Print"
end
functionExample(variableTable, 1)
print(variableTable)
does work. I am just trying to find out how to condense the two variables into one basically.
here are all of your examples with the principle I gave
-- (Example One)
local variableOne = "I Dont Want This To Print"
local function functionExample(variablePathwayToChange)
variableOne = "I Want This To Print"
end
functionExample(variableOne)
print(variableOne)
-- (Example Two)
local tableVariable = {"I Don't Want This To Print"}
tableVariable[1] = "I Want This To Print"
print(tableVariable)
-- (Example Three)
script.Name = "I Want The Script's Name To Change To This"
wait(3)
script.Name = "Then, It Should Change To This"
It’s not really necessary to do that anyway, plus it can open type confusion attacks
If an exploiter gets to that function, they can change any variable in the game to whatever
functionExample(playerToKick,“Name”)
This could work with simple functions, but I need to do so for a table with an ever-changing number of players and their respective data. Also, I make sure that all inputs from client to server are non exploitable. Here is a simplified version of the code that prompted me to ask this question:
local playerAbode = {{"Player1", 1, 1}, {"Player2", 2, 6}, {"Player3", 9,0}} -- can be infinitely large
local function BulletCollision()
-- bunch of code that does stuff that isn't important for this example.
local playerIndex = SomeUnrelatedFunction()-- gets index through another function
local playerData = playerAbode[playerIndex]
local alreadyRagdolling = playerData[2]
if (alreadyRagdolling ~= 2) then
RagdollEntity(playerData[1], alreadyRagdolling)
end
end
local function RagdollEntity(playerInstance, alreadyRagdolling)
if (alreadyRagdolling = 1) then -- these alreadyRagdolling variables should stay inside the function so that I do not have to write it multiple times
alreadyRagdolling = 2 -- I need this to use a pathway variable.
else
alreadyRagdolling = 1 -- This also needs to use the pathway.
wait(5) -- approximate time it takes to complete ragdoll
alreadyRagdolling = nil -- and this too...
end
end
This function can occur multiple times before the first ragdoll occurrence completes, and, as such must change the variable for the whole script to read instead of just changing it locally. In order to do this, I can theoretically just pass the pathway into the function. getfenv() seems to be the most efficient solution, if I can learn how to get it to work.