You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I want to make the save system work and display the button. -
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()