Having issues using bindable function with module

  1. What do you want to achieve? Keep it simple and clear!
    I’m trying to use a bindable function to get/set property values within specific instances of a module/class.

  2. What is the issue? Include screenshots / videos if possible!
    Its hard to explain but, the bindable event doesn’t seem to work on unique instances, when the property values are changed the changes aren’t happening for unique instances.

  3. What solutions have you tried so far?
    I have tried embedding the bindable function within the unique properties of each instance and I have tried using the function outside of the instance and calling a method of an instance.
    Either way the property values aren’t being updated for a specific instance. I know I’m not explaining this well, please ask questions for clarification.

Example Module Script:

local module = {}

module.__index = module
module.InstanceCounter = 0

function module.New(model)
    local new = {}
    setmetatable(new, module)

    module.InstanceCounter = module.InstanceCounter + 1

    new.Player = nil
    new.Character = nil
    new.Model = model

    new.FavColor = "Blue"

    new.ColorFunc = game:GetService("ServerStorage"):WaitForChild("ColorFunction")

    new.ColorFunc.OnInvoke = function(...) return new:Color(...) end
    
    new.InstanceID = module.InstanceCounter

    return new
end

function module:Color(newColor)
    if(self.InstanceID)then
        Print(self.InstanceID)
    end

    if(newColor ~= nil)then
        self.FavColor = newColor
    end
    return self.FavColor
end

When run, the instance ID is returned as 6 when I expect Instance ID 1 or even all the instance IDs and when I try to access self.FavColor in other methods the color remains blue it does not seem to be changed. Within the method, even though the self.Player values have been updated by other methods previous, their values are still nil.

Bindable Function Called from different script using:
local newColor = colorFunc.:Invoke("Red")

the string “Red” is returned…

1 Like

The problem here is that a BindableFunction can only have one invocation function at a time, so when calling it, it’ll only call the function of the latest instance. The solution is to create a new BindableFunction for each instance.

Also, you reference a color variable in this part of the code, but the actual argument being passed through is newColor. You might want to change that.

    if(color ~= nil)then
        self.FavColor = color
    end

Ah, okay. If I create a new bindable function for each instance how can I call that function then? Basically I’m using a tool that calls the bindable function to both get and set values for a specific model and that model is controlled using the module. Outside of the module I would have no access to the bindable function correct?

If the BindableFunction was parented to nil, it wouldn’t be accessible by anything else unless you established a way to access it (i.e. storing it as a variable within the metatable).

1 Like

Yeah, this is something you’re going to want to create a new BindableFunction for. Just be wary that you’ll need to hold on to it somewhere. On the other hand, you can use one BindableFunction if you use your id system to your advantage.

local ColorFunction = game:GetService("ServerStorage"):WaitForChild("ColorFunction")
local ObjectList = {}

local class = {}
class.__index = class

local id = 0

function class.new(model)
    id = id + 1

    local new = setmetatable({
        Player = nil,
        Character = nil,
        Model = model,

        FavColor = "Blue",
        InstanceId = id
    }, class)

    ObjectList[id] = new

    return new
end

function class:Color(newColor)
    print(self.InstanceId)

    self.FavColor = newColor or self.FavColor

    return self.FavColor
end

ColorFunction.OnServerInvoke = function(id, ...)
    if id and ObjectList[id] then
        return ObjectList[id]:Color(...)
    end
    return nil
end
1 Like