Save system not working and shop button not showing

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to make the save system work and display the button.

  2. What is the issue? Include screenshots / videos if possible!


    robloxapp-20240221-2018213.wmv (1.2 MB)

    ↑View of Explorer

When I run the script below, the message above is output.
3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I asked chatGPT and looked for videos on youtube.

This is a shop server script.

local DataStoreServis = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local database = DataStoreServis:GetDataStore("database")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))

local MAX_SELECTED_TOWERS = 5

local data = {}

-- Load the players data
local function LoadData(player)
	local success = nil
	local playerData = nil
	local attempt = 1
	
	repeat
		success, playerData = pcall(function()
			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 retrieved")
		if not playerData then
			print("New player, giving default date")
			playerData = {
				["Coins"] = math.huge,
				["SelectedTowers"] = {"SlingerBacon"},
				["OwnedTowers"] = {"SlingerBacon"}
			}
		end
		data[player.UserId] = playerData
	else
		warn("Unble to get data for player", player.UserId)
	end
end
Players.ChildAdded:Connect(LoadData)
-- Save the players data
local function SaveData(player)
	if data[player.UserId] then
		local success = nil
		local playerData = nil
		local attempt = 1

		repeat
			success, playerData = pcall(function()
				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("Data saved successfully")
		else
			warn("Unble to save 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
	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]
	local status = getItemStatus(playerData, itemName)

	if status == "For Sale" and shopItem.Price <= playerData.Coins then

		playerData.Coins = playerData.Coins - 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
    
		local towerToRemoveIndex = table.find(playerData.SelectedTowers, itemName)
		if towerToRemoveIndex then
			table.remove(playerData.SelectedTowers, towerToRemoveIndex)
		end
	end

	return playerData
end

ReplicatedStorage.GetData.OnServerInvoke = function(player)
	return data[player.UserId]
end

This is the client script.


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.Coins
local limit = gui.Container.Limits
local itemFrame = gui.Container.ItemFrame

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
		updateItem()
	end
end


function updateItem()
	stars.Text = playerData.Coins .. "Coin"
	limit.Text = #playerData.SelectedTowers .. "/5"
	
	for i, tower  in pairs(towers) do
		-- Find any old buttons
		local oldButton = itemFrame:FindFirstChild(tower.Name)
		if oldButton then
			oldButton:Destroy()
		end
		
		-- Creating new button
		local newButton = itemFrame.TemplateButton:Clone()
		newButton.Name = tower.Name
		newButton.TowerName.Text = tower.Name
		newButton.Image = tower.ImageAsset
		newButton.Visible = true
		newButton.LayoutOrder = tower.Price
		newButton.Parent = itemFrame
		
		local status = getItemStatus(tower.Name)
		
		if status == "For Sale" then
			newButton.Status.Text = tower.Price .. "Coins"
		elseif status == "Equipped" then
			newButton.Status.Text = "✅ Equpped"
			newButton.Status.TextColor3 = Color3.new(0, 1, 0)
			newButton.BackgroundColor3 = Color3.new(0.333333, 1, 0.498039)
		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()
		updateItem()
	end
end

local function setupShop()
	local promt = Instance.new("ProximityPrompt")
	promt.RequiresLineOfSight = false
	promt.ActionText = "Shop"
	promt.Parent = workspace:WaitForChild("ShopPart")
	
	promt.Triggered:Connect(toggleShop)
	exit.Activated:Connect(toggleShop)
end

setupShop()

DataStore saving and getting requires a Key and you forgot to return the database in GetAsync()

	return database:GetAsync(tostring(player.UserId).. "-data")
database:UpdateAsync(tostring(player.UserId).. "-data", function()
					return data[player.UserId]
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.