2

I'm trying to change the behavior of a Lua function, by adding code to the start or end of it. Because this is a mod for a game, I can't edit the function directly, so I have to override it instead. I accomplish this by storing a reference to the original function in a local variable, then redefining the function with my own, which calls the original one along with any prefix or postfix code I need to add, like so:

local base_exampleFunction = ExampleBaseGameClass.exampleFunction

function ExampleBaseGameClass.exampleFunction(param1, param2)

    --Prefix code goes here

    base_exampleFunction(param1, param2);

    --Postfix code goes here
    
end

This works fine for functions defined with the ClassName.functionName syntax, but some functions use ClassName:functionName instead, which from what I understand, are functions that pass a reference to the class instance as the first parameter. I can't figure out how to prefix/postfix these functions, as I get the following error when declaring a variable to hold the original function if I try the same approach:

attempted index: exampleFunction of non-table: null

Is there a way to make this work?

1 Answer 1

4

: functions are just scary ways of saying "the first argument is self".

So, ExampleBaseGameClass:exampleFunction(param2) is equivelent to ExampleBaseGameClass.exampleFunction(ExampleBaseGameClass, param2)! It's just got self at the beginning, and functions declared with : will have an invisible self variable appear out of nowhere.

local a = {}
function a.b(self)
    print(self)
end
function a:c()
    print(self)
end

-- a.c(a) == a:c()
-- a:b() == a.b(a)
-- a:b() == a:c()

Using this idea, we can simply prepend an argument (it does not have to be called "self", it just has to be the first argument).

This should work, unless there is a part of your Lua environment (eg, funky metatables) which would prevent such a thing:

local base_exampleFunction = ExampleBaseGameClass.exampleFunction

function ExampleBaseGameClass.exampleFunction(self, param1, param2)

    --Prefix code goes here

    base_exampleFunction(self, param1, param2);

    --Postfix code goes here
    
end

The lua library takes advantage of the first argument being the calling object for it's string library. Notice how ("hello"):gsub() works--by passing the string itself as the first argument!

Sign up to request clarification or add additional context in comments.

4 Comments

The error I'm getting (attempted index: exampleFunction of non-table: null) happens right on the first line where the local variable is defined, so adding self to the overridden function doesn't solve the problem, though I assume that's also necessary given your explanation. Is there anything I need to change in the local variable declaration?
Are you sure that ExampleBaseGameClass's equivalent in your scenario actually exists? Check for typos, as the error implies that ExampleBaseGameClass does not exist, instead of exampleFunction.
@PM4 then ExampleBaseGameClass is null at the point where you are running this code. This has nothing to do with : functions
Thanks! You're both right, the base game class is only initializing in server context, not client, whereas my override was running in both contexts, hence the error when launching the client.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.