I tried to make an inventory system but it says tower.Name is nil? This is the code
for i, tower in pairs(playerData.OwnedTowers) do
print(playerData.OwnedTowers)
print(tower)
--find any old buttons
--creating new button
print(tower.Name)
print(tower.Rarity)
local newButton = template:Clone()
newButton.Name = tower.Name
For some reason it seems to be treating the whole dictionary as nonexistant, displaying the access key in an array but nothing else. There may be other code affecting it. Are you able to provide any more code that could be affecting it?
Heres some more content, this is the whole inventoryClient code:
local replicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local badgeService = game:GetService("BadgeService")
local getDataFunc = replicatedStorage:WaitForChild("GetData")
local interactItemFunc = replicatedStorage:WaitForChild("InteractItem")
local players = game:GetService("Players")
local player = players.LocalPlayer
local gui = script.Parent
local inventoryFrame = gui.InventoryFrame
local template = inventoryFrame.Template
local playerData = {}
local function getItemStatus(itemName)
if table.find(playerData.SelectedTowers, itemName) then
return "Equipped"
elseif table.find(playerData.OwnedTowers, itemName) then
return "Owned"
end
end
local function interactItem(itemName)
local data = interactItemFunc:InvokeServer(itemName)
if data then
playerData = data
updateItems()
end
end
function updateItems()
for i, tower in pairs(playerData.OwnedTowers) do
print(playerData.OwnedTowers)
print(tower)
--find any old buttons
--creating new button
print(tower.Name)
print(tower.Rarity)
local newButton = template:Clone()
newButton.Name = tower.Name
newButton.Image = tower.ImageAsset
newButton.Parent = inventoryFrame
local status = getItemStatus(tower.Name)
if status == "Equipped" then
print(newButton.Name.." is equipped!")
else
print(newButton.Name.." is owned!")
end
newButton.Activated:Connect(function()
interactItem(tower.Name)
end)
end
end
local function toggleShop()
playerData = getDataFunc:InvokeServer()
updateItems()
end
script.Parent.Parent.SidebarGui.SidebarHolder.InventoryButton.Activated:Connect(function()
toggleShop()
end)
Maybe theres something there that could affect it?
What you’re saving is the keys of the dictionary, not the dictionary itself, so to fix it use them to index the actual dictionary:
local towerDictionary = --the dictionary that contains tower data, not the player one
for _, key in pairs(playerData.OwnedTowers) do
local tower = towerDictionary[key]
--rest of the code
end
local TowerShop = --reference to your tower shop dictionary
type tower = {Name: string, ImageAsset: string, Rarity: string}
local function getTowerByKey(key: string): tower?
for _, rarity in pairs(TowerShop) do
if rarity[key] then return rarity[key] end
end
return nil
end
for _, key in pairs(playerData.OwnedTowers) do
local tower = getTowerByKey(key)
--rest of your code
end
It’s used for error detection and auto-completion. This has no impact in the real game even if it detects an error, but it tells you by making the line red. Basically, it tells the interpreter that what the function getTowerByKey returns is a dictionary with exactly 3 properties named Name, ImageAsset and Rarity and are all of type string. The ? next to tower means it can also return nil. So if you try to type tower. for the result it should suggest you those properties, and if you try to set or use any of them as non-string properties, it will make that line red.
Basically, for the simulation, it’s completely useless, but it helps keep code organized and detect logic errors more easily.