Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Object method coming out nil after getting the object through Invoke?

Asked by
xPolarium 1388 Moderation Voter
5 years ago
Edited 5 years ago

So this could be something going right over my head or my lack of experience with multi-script/modular systems and BindableFunctions:

So I have a basic OOP class setup (In a module) that a 'Main' script creates a "Fighter" object for a player that joins the server. This has methods in it that involve managing fighter attributes that have no problems at all. After a new object is created, it's placed into a table.

Looks like this in the Main script in a simple form:

local FighterModule = require(ServerStorage.FighterModule)

local fightersInServer = {} --stores fighter objects

function onPlayerJoin(player)
    local NewFighter = FighterModule:Create(player)

    table.insert(fightersInServer, NewFighter)
end

game.Players.PlayerAdded:Connect(onPlayerJoin)

Now in my second server script, the purpose of it is to handle fighter abilities after the client calls for an ability. My issue then lies inside of the function that connects to my RemoteEvent. I wanted to use a BindableFunction to get the fighter from the table inside of my Main script, but it's giving out an error when I want to fire a method from my object.

Output Error: attempt to call method 'DoAbility' (a nil value)

What confuses me is that I can get a property from my fighter object like fighter.Name but not one of the method, fighter:SomeMethod().

This is my second server script with it invoking to the Main script:

local requestFighterFunction = ServerStorage.BindableFunction

function onAbility(player, arg1, arg2) --I have some args passed by the client
    local fighter = requestFighterFunction:Invoke(player)

    print(fighter.Name) --does print the name of the fighter

    fighter:DoAbility() --attempt to call method error
end

RemoteEvent.OnServerEvent:Connect(onAbility)

Now to finish off what I'm doing in my Main script is the listener to the BindableFunction which is supposed to return the fighter from the table of fighters:

local FighterModule = require(ServerStorage.FighterModule)
local requestFighterFunction = ServerStorage.BindableFunction

local fightersInServer = {} --stores fighter objects


--This function is also used by this same script to save typing and works
function getFighter(player)
    local found;

    for _, fighter in pairs(fighters) do
        if fighter.Name == player.Name then
            found = fighter
        end
    end

    return found
end

function onPlayerJoin(player)
    local NewFighter = FighterModule:Create(player)

    table.insert(fightersInServer, NewFighter)
end

game.Players.PlayerAdded:Connect(onPlayerJoin)

requestFighterFunction.OnInvoke = getFighter

Not sure what I'm doing wrong or the fix to this. The other way to fixing it would be putting the entire scripts into one but I do want to keep them apart since they server different purposes.

Another thing I want to ask are better alternatives to what I'm doing if any. This is my first game project that I want to have a modular system for so the help is appreciated.

Let me know if I missed something you would like to know.

edit:

If I wasn't clear of what :DoAbility() is, it's a method in my class module that will do something. It's only a getter type of method right now.

ModuleScript:

local fighter = {}
fighter.__index = fighter

function fighter:Create(player)
    local self = setmetatable(fighter, {})

    self.Name = player.Name

    --other stuff in here

    return self
end

--function in question.
function fighter:DoAbility()
    --does stuff

    return self.SomeProperty
end

return fighter

Just typed this out right now and not in studio but should be a simpler version to my OOP class setup. Let me know if this is set up properly.

0
I don't see the DoAbility function anywhere? User#19524 175 — 5y
0
DoAbility is a method inside of my module script. It's a method for my class. xPolarium 1388 — 5y
0
Edited question to include fighter class module. xPolarium 1388 — 5y
0
You're setting fighter's metatable to a blank table. Maybe you want to swap the two? User#19524 175 — 5y

1 answer

Log in to vote
1
Answered by
Amiaa16 3227 Moderation Voter Community Moderator
5 years ago

When you pass a table via a BindableFunction, a copy of it is returned, not the actual table. Therefor it may not function properly if you applied metamethods to it, as the metatable is stripped from the copy of the table.

What you should do instead is either a) Make it a function placed in a ModuleScript rather than a BindableFunction or b) Pass the value via a global table, such as _G or shared (less recommended)

Ad

Answer this question