Hello! I have an error that says, "Players.CreatorOfNothing12.PlayerGui.ShopGui.ShopClient:34: attempt to index nil with ‘Stars’'. And also here is the line of code that is giving me issues.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))
local GetDataFunc = ReplicatedStorage:WaitForChild("GetData")
local InteractItemFunc = ReplicatedStorage:WaitForChild("InteractItem")
local gui = script.Parent
local exit = gui.Container.Exit
local stars = gui.Container.Stars1
local limit = gui.Container.Limit
local itemsFrame = gui.Container.Items
local playerData = {}
local function GetItemStatus(itemName)
if table.find(playerData.SelectedTowers, itemName) then
return "Equipped"
elseif table.find(playerData.OwnedTowers, itemName) then
return "Owned"
else
return "For Sale"
end
end
local function interactItem(itemName)
local data = InteractItemFunc:InvokeServer(itemName)
if data then
playerData = data
updateItems()
end
end
function updateItems()
stars.Text = "★"..playerData.Stars
limit.Text = #playerData.SelectedTowers .. "/3"
for i, tower in pairs(towers) do
local oldButton = itemsFrame:FindFirstChild(tower.Name)
if oldButton then
oldButton:Destroy()
end
local newButton = itemsFrame.TemplateButton:Clone()
newButton.Name = tower.Name
newButton.TowerName.Text = tower.Name
newButton.Image = tower.ImageAsset
newButton.Visible = true
newButton.LayoutOrder = tower.Price
newButton.Parent = itemsFrame
local status = GetItemStatus(tower.Name)
if status == "For Sale" then
newButton.Status.Text = "★"..tower.Price
elseif status == "Equipped" then
local UIStroke = Instance.new("UIStroke")
UIStroke.Color = Color3.new(0,0,0)
UIStroke.Thickness = 3
newButton.Status.Text = "✅".." Equipped"
newButton.Status.TextColor3 = Color3.new(1,1,1)
newButton.BackgroundColor3 = Color3.new(0,0,0)
else
newButton.Status.Text = ""
end
newButton.Activated:Connect(function()
interactItem(tower.Name)
end)
end
end
local function toggleShop()
gui.Container.Visible = not gui.Container.Visible
if gui.Container.Visible then
playerData = GetDataFunc:InvokeServer()
updateItems()
end
end
local function SetupShop()
local prompt = Instance.new("ProximityPrompt")
prompt.RequiresLineOfSight = false
prompt.ActionText = "Shop"
prompt.Parent = workspace:WaitForChild("Prox")
prompt.Triggered:Connect(toggleShop)
exit.Activated:Connect(toggleShop)
end
SetupShop()
Assuming what the stars variable is equal to is spelled correctly, and by the fact it doesn’t error saying it is nil upon loading (meaning it is spelled correctly), I assume it didn’t have enough time to load in when you are running the function.
Replace all of the following variables with this (and make sure the new one I added is there), and tell me if it works or not after. Hopefully it does:
local container = gui:WaitForChild("Container")
local exit = container:WaitForChild("Exit")
local stars = container:WaitForChild("Stars1")
local limit = container:WaitForChild("Limit")
local itemsFrame = container:WaitForChild("Items")
I just added the WaitForChild on the original code, so that was probably your issue to begin with. If the GuiObject is named “Stars” exactly, then yes, it will. And that also explains why it didn’t work the first time.
I think it could be from the playerData instead of the TextLabel now because it should be working with that. Right above the first line in the updateItems function, print the playerData and show me what it prints in the output, please.
I have not finished the saving system. I am just working on a shop that is supposed to show the towers but is not showing because the game stops when the error happens.
I think I see the issue now. I think, at least. Is stars a value in a table, or is it a value tied to an object (i.e. StringValue, IntValue, NumberValue)?
It would be the exact issue. If you haven’t finished the saving and there is nothing to load, it won’t be in the table. It doesn’t exist in the table, so it can’t be set as the text on the TextLabel. Once you finish the saving (and/or loading).
Also looking in the rest of the script, Stars never even gets added to the table. Probably because you haven’t finished the saving, so you can’t load it.
local DataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local database = DataStoreService:GetDataStore("Database")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))
local MAX_SELECTED_TOWERS = 3
local data = {}
local function LoadData(player)
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return database:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait()
end
until success or attempt == 3
if success then
print("Data saved successfully")
else
warn("Unbable to get data for player", player.UserId)
end
end
players.PlayerAdded:Connect(LoadData)
local function SaveData(player)
if data[player.UserId] then
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return database:UpdateAsync(player.UserId, function()
return data[player.UserId]
end)
end)
attempt += 1
if not success then
warn(playerData)
task.wait()
end
until success or attempt == 3
if success then
print("Connection Success")
if not playerData then
print("New player, giving default data.")
playerData = {
["Stars"] = 50,
["SelectedTowers"] = {"Soilder"},
["OwnedTowers"] = {"Soilder", "Trump"}
}
end
data[player.UserId] = playerData
else
warn("Unbable to get data for player", player.UserId)
player:Kick("There was a problem getting your data.")
end
else
warn("No session data for, "..player.UserId)
end
end
players.PlayerRemoving:Connect(SaveData)
local function GetItemStatus(player, itemName)
local playerData = data[player.UserId]
if table.find(playerData.SelectedTowers, itemName) then
return "Equipped"
elseif table.find(playerData.OwnedTowers, itemName) then
return "Owned"
else
return "For Sale"
end
end
ReplicatedStorage.InteractItem.OnServerInvoke = function(player, itemName)
local shopItem = towers[itemName]
local playerData = data[player.UserId]
if shopItem and playerData then
local status = GetItemStatus(player, itemName)
if status == "For Sale" and shopItem.Price <= playerData.Stars then
playerData.Stars -= shopItem.Price
table.insert(playerData.OwnedTowers, shopItem.Name)
elseif status == "Owned" then
table.insert(playerData.SelectedTowers, shopItem.Name)
if #playerData.SelectedTowers > MAX_SELECTED_TOWERS then
table.remove(playerData.SelectedTowers, 1)
end
elseif status == "Equipped" then
if #playerData.SelectedTowers > 1 then
local towerToRemove = table.find(playerData.SelectedTowers, itemName)
table.remove(playerData.SelectedTowers, towerToRemove)
end
end
return playerData
else
warn("Tower/player data does not exist")
end
return false
end
ReplicatedStorage.GetData.OnServerInvoke = function(player)
return data[player.UserId]
end