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

Why does my class method become nil?

Asked by
alibix123 175
4 years ago

I have an "Item" object. It's defined here:

local Item = {}
Item.__index = Item

function Item.new(itemClass, name, value, rarity)
    local newItem = {}
    setmetatable(newItem, Item)

    newItem.ItemClass = itemClass
    newItem.Name = name
    newItem.Value = value
    newItem.Rarity = rarity

    return newItem
end

function Item:ToString()
    print("Type: " .. self.ItemClass .. ", Name: " .. self.Name .. ", Value: " .. self.Value .. ", Rarity: " .. self.Rarity .. " ")
end


return Item

I have a server script that gives each player and "inventory" (a table) - and in this table, I'm putting "Item" objects.

local InventoryModule = require(game.ServerStorage.InvData)
local players = game:GetService("Players")
local Item = require(game.ServerStorage.ItemClass)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage:WaitForChild("DataEvent", 30)

local inventory = {Item.new("Resource", "Wood", 10, "Common"), Item.new("Food", "Rainbow Trout", 35, "Uncommon")}  -- defining the inventory with two "items"

function PlayerJoined(player)
    InventoryModule.addPlayer(player, inventory)
end
[...] -- code continues but this is the part that matters

And finally, I have a local script that fires the server for the inventory data, which I subsequently print:

local Player = game.Players.LocalPlayer

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage:WaitForChild("DataEvent", 30)

local invData

function setupInv()
    Event:FireServer()

    wait(invData)

    print(Player.Name .. "'s Items:")
    for i, item in ipairs(invData)do
        item:ToString()
    end
end

function updateInv(newInv)
    invData = newInv
end

Event.OnClientEvent:Connect(updateInv)

setupInv()

I would expect to see the output of each item in the player's inventory but instead, I get:

PlayerScripts.LocalScript:15: attempt to call method 'ToString' (a nil value) 20:17:24.314 - Stack Begin

If I do item.Name, or item.Rarity it works fine - this only happens when I try to call the item's print method. Why is this? The class definitely has a ToString() method! And I know it works because if I use it in where I am defining the inventory in the server script - it works fine.

I'm totally stumped

1 answer

Log in to vote
2
Answered by 4 years ago

You're sending a table with a metatable over a remote, which is then lost.

"If a table has a metatable, all of the metatable information will be lost in the transfer."

Refer to this wiki article for more information: https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events

0
Is there anyway around this for implementing my inventory system? alibix123 175 — 4y
0
I mean, there's nothing stopping you from just using regular ol' tables and setting the metatable after receiving them in the client. Jahaziel_VanDerHas 238 — 4y
0
Sorry, I don't understand, how do you mean? alibix123 175 — 4y
0
I mean, sending a list of the items and their data from the server, then giving them a new metatable on the client, or something to that effect. Jahaziel_VanDerHas 238 — 4y
1
Ah, I get it. Thanks! alibix123 175 — 4y
Ad

Answer this question