#Issues with metatable

1 messages · Page 1 of 1 (latest)

fallen dove
#

I would like to know why does the metatable not work when indexing

local FoldersMT = {
    __index = function(self, key)
        local instance = rawget(self, key)
        if instance then
            return instance.Value
        end
        return nil
    end,
    __newindex = function(self, key, value)
        local instance = rawget(self, key)
        if instance then
            instance.Value = value
        end
    end,
}```

the error part
```lua
local function StatsThread(playerData: PlayerDataClass.PlayerDataType, AliveHumanoid: Humanoid)
    while task.wait(0.5) do
        -- Posture regeneration
        if playerData.CharacterData["Posture"] > 0 then
            if playerData.Combat.InCombat then
                playerData.CharacterData["Posture"] -= StatsValuesCombat["PostureRegen"].Value
            else
                playerData.CharacterData["Posture"] -= StatsValues["PostureRegen"].Value
            end

            if playerData.CharacterData["Posture"] < 0 then
                playerData.CharacterData["Posture"] = 0
            end
        end
-- rest of script

the object creation function

function PlayerData.new(Player : Player) : PlayerDataType
    local self = setmetatable({}, PlayerData) :: PlayerDataType

    self.__dataFolder = DefaultAliveData.Player:Clone()
    self.__dataFolder.Parent = AliveData
    self.__dataFolder.Name = Player.Name

    self.Player = Player
    self.Character = Player.Character or Player.CharacterAdded:Wait()

    self.CharacterData = setmetatable(__toDictionary(self.__dataFolder:FindFirstChild("CharacterData"):GetChildren()), FoldersMT)

    self.Combat = setmetatable(__toDictionary(self.__dataFolder:FindFirstChild("Combat"):GetChildren()), FoldersMT)

    self.Movement = setmetatable(__toDictionary(self.__dataFolder:FindFirstChild("Movement"):GetChildren()), FoldersMT)

    

    return self
end```
opaque barn
fallen dove
whole kettle
opaque barn
fallen dove
fallen dove
#

ok i found a workaround by creating a proxy that will always run the metamethods

local function createValueProxy(instances)
    local mt = {
        __index = function(self, key)
            local instance = instances[key]
            if instance and instance:IsA("ValueBase") then
                return instance.Value
            end
            return instance
        end,
        __newindex = function(self, key, value)
            local instance = instances[key]
            if instance and instance:IsA("ValueBase") then
                instance.Value = value
            end
        end
    }
    -- Return empty table with metatable, not the instances table
    return setmetatable({}, mt)
end```

```lua
function PlayerData.new(Player : Player)
    local self = setmetatable({}, PlayerData)

    self.__dataFolder = DefaultAliveData.Player:Clone()
    self.__dataFolder.Parent = AliveData
    self.__dataFolder.Name = Player.Name

    self.Player = Player
    self.Character = Player.Character or Player.CharacterAdded:Wait()

    -- Store instances in internal tables
    self._characterDataInstances = __toDictionary(self.__dataFolder:FindFirstChild("CharacterData"):GetChildren())
    self._combatInstances = __toDictionary(self.__dataFolder:FindFirstChild("Combat"):GetChildren())
    self._movementInstances = __toDictionary(self.__dataFolder:FindFirstChild("Movement"):GetChildren())

    -- Create empty proxy tables with metatables
    self.CharacterData = createValueProxy(self._characterDataInstances)
    self.Combat = createValueProxy(self._combatInstances)
    self.Movement = createValueProxy(self._movementInstances)

    return self
end```