Help with hat shop system

Hey there,
Im trying to make a hat shop system for my game but ive run into a few issues. Whoever can help me get it working ill give 1000 Robux for your services.

  1. The hats arent saving
  2. when I buy a hat both hats appear in the inventory

Scripts:

Shop:

local plr = game.Players.LocalPlayer
local sframe = script.Parent.ShopFrame
local hats = game.ReplicatedStorage.Hats
local hatinfo = game.ReplicatedStorage.HatInfo
local owned = plr.Owned
local ownedColor = game.ReplicatedStorage.owned.Color
local BuyColor = game.ReplicatedStorage.buy.Color
local buy = sframe.Buy

local VioletValkWeb = game.ReplicatedStorage.Webhooks.VioValkWeb
local DomPraeWeb = game.ReplicatedStorage.Webhooks.DomPraeWeb


local hat1 = sframe.Hat1
local hat2 = sframe.Hat2
local hat3 = sframe.Hat3
local hat4 = sframe.Hat4
local hat5 = sframe.Hat5
local hat6 = sframe.Hat6

--Violet Valk
hat1.Image = hatinfo.VioletValk.Image.Value
hat1.MouseButton1Click:Connect(function()
	if owned.VioletValk.Value == true then sframe.Buy.Text = "Already Owned!"
		sframe.Buy.TextButton_Roundify_12px.UIGradient.Color = ownedColor
	elsesframe.Buy.Text = "Buy hat!" 
		sframe.Buy.TextButton_Roundify_12px.UIGradient.Color = BuyColor
	end
	sframe.Show.Image = hatinfo.VioletValk.Image.Value
	sframe.description.Text = hatinfo.VioletValk.Desc.Value
	sframe.Cost.Text = "Cost: $"..hatinfo.VioletValk.Price.Value
	buy.MouseButton1Click:Connect(function()
		if owned.VioletValk.Value == true then
			print("You already own this lol")
		end
		if plr.leaderstats.Crowns.Value ~= 800 then print("ur too broke lolol")
		end
		if owned.VioletValk.Value == false and plr.leaderstats.Crowns.Value >= 800 then
			owned.VioletValk.Value = true
			plr.leaderstats.Crowns.Value = plr.leaderstats.Crowns.Value - 800
            VioletValkWeb:FireServer()
	    end
	end)
end)

--Dominus Prae
hat2.Image = hatinfo.DominusPraefectus.Image.Value
hat2.MouseButton1Click:Connect(function()
	if owned.DomPrae.Value == true then sframe.Buy.Text = "Already Owned!"
		sframe.Buy.TextButton_Roundify_12px.UIGradient.Color = ownedColor
	else sframe.Buy.Text = "Buy hat!" 
		sframe.Buy.TextButton_Roundify_12px.UIGradient.Color = BuyColor
	end
	sframe.Show.Image = hatinfo.DominusPraefectus.Image.Value
	sframe.description.Text = hatinfo.DominusPraefectus.Desc.Value
	sframe.Cost.Text = "Cost: $"..hatinfo.DominusPraefectus.Price.Value
	buy.MouseButton1Click:Connect(function()
		if owned.DomPrae.Value == true then
			print("You already own this lol")
		end
		if plr.leaderstats.Crowns.Value ~= 1200 then print("ur too broke lolol")
		end
		if owned.DomPrae.Value == false and plr.leaderstats.Crowns.Value >= 1200 then
			owned.DomPrae.Value = true
			plr.leaderstats.Crowns.Value = plr.leaderstats.Crowns.Value - 1200
			DomPraeWeb:FireServer()
		end
	end)
end)

Inventory:

local plr = game.Players.LocalPlayer
local inv = script.Parent.InvFrame
local owned = plr.Owned
local template = inv.ScrollingFrame.Template
local hatinfo = game.ReplicatedStorage.HatInfo

--CLONES

--VioletValk
local workVV = true
while workVV == true do
	wait(0.1)
if owned.VioletValk.Value == true then
	local VioValkClone = template:Clone()
	VioValkClone.Parent = inv.ScrollingFrame
	VioValkClone.Visible = true
		VioValkClone.Image = hatinfo.VioletValk.Image.Value
		workVV = false
	end
end

--DomPrae
local workDP = true
while workDP == true do
	wait(0.1)
	if owned.DomPrae.Value == true then
		local DomPraeClone = template:Clone()
		DomPraeClone.Parent = inv.ScrollingFrame
		DomPraeClone.Visible = true
		DomPraeClone.Image = hatinfo.DominusPraefectus.Image.Value
		workDP = false
	end
end

Owned Hats:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("HatStats")

game.Players.PlayerAdded:Connect(function(Player)
	local Owned = Instance.new("Folder", Player)
	Owned.Name = "Owned"
	local VioletValk= Instance.new("BoolValue", Owned)
	VioletValk.Name = "VioletValk"
	VioletValk.Value = 0
	local DomPrae= Instance.new("BoolValue", Owned)
	DomPrae.Name = "DomPrae"
	DomPrae.Value = 0

	local Data = DataStore:GetAsync(Player.UserId)
	if Data then
		VioletValk.Value = Data.VioletValk
		DomPrae.Value = Data.DomPrae
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	DataStore:SetAsync(Player.UserId, {
		["VioletValk"] = Player.Owned.VioletValk.Value;
		["DomPrae"] = Player.Owned.DomPrae.Value; 
	})
end)

Unfortunately, i do not use DS. But DS2 makes things alot easier. Why not using Data Store 2 instead?

1 Like

Does it print any errors? Also, this script could get very unnecessary long with more than 5 hats. I recommend you use owned:GetChildren() and then loop through all the items the player owns.

1 Like

yeah I just dont know how to make a new frame in the inventory for each hat like that

Never tried to use it, I should probably learn though

Sorry that this is a bit off topic but I wouldn’t recommend using DataStore2 module because all features are now built-in Roblox natively (DataStore 2.0). I would recommned to use ProfileService instead - you don’t need to worry about saving, it’s really simple to use and respects rate limits

1 Like

Instead of cloning the template you could try to put the GuiObject inside of player.Owned.Hat

You would only need to set the parent of the GuiObject from/to the PlayerGui and use Owned.Hat:FindFirstChildOfClass(”ImageButton”).Parent = player.PlayerGui.ScreenGui

1 Like

oh yeah that’s a really good idea

1 Like

Also you could try to learn it but it’s not very necessary

Does it print any errors in the output?

1 Like

nope
30

1 Like

Try the method and then come back if it still gives you both hats