Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why does my class method become nil?

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

✓ Accepted answer

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

5 comments

0

Is there anyway around this for implementing my inventory system?

0

I mean, there's nothing stopping you from just using regular ol' tables and setting the metatable after receiving them in the client.

0

Sorry, I don't understand, how do you mean?

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.

1

Ah, I get it. Thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.