Buying an in-game item with Datastore2

Hi, whenever a player purchases something in-game using the coins they have, it automatically jumps to the end of the script saying the skin/trap doesn’t exist. here is my code:

game.ReplicatedStorage.BuyItem.OnServerInvoke = function(player, itemName, itemType)
	
	local DataStore2 = require(game.ServerScriptService.DataStore2)
	local MarketplaceService = game:GetService("MarketplaceService")
	
	local defaultCashValue = 0
	
	
	game.Players.PlayerAdded:Connect(function(plr)
		local coinsDataStore = DataStore2("Coins", player)
		
	
		
		local cash = Instance.new("StringValue")
		cash.Name = "Cash"
		
		local function coinsUpdated(updatedValue)
			cash.Value = coinsDataStore:Get(updatedValue)
			game.ReplicatedStorage.UpdateClientCurrency:FireClient(plr, coinsDataStore:Get(defaultCashValue))
	
		end
		
		coinsUpdated(defaultCashValue)
		
		coinsDataStore:OnUpdate(coinsUpdated)
		
		
	end)
	
	local item
	local inInventory
	
	if itemType == "skin" then
		item = game.ReplicatedStorage.Skins:FindFirstChild(itemName)
		
		if player.SkinInventory:FindFirstChild(itemName) then
			inInventory = true
		end
	elseif itemType == "trap" then
		item = game.ReplicatedStorage.Traps:FindFirstChild(itemName)
		if player.TrapInventory:FindFirstChild(itemName) then
			inInventory = true
		end
	end
	
	if item then
		local coinsDataStore = DataStore2("Coins", player)
		if item:FindFirstChild("Cost") then
			if not inInventory then
				if item.Cost.Value <=  coinsDataStore then
					print("Player can buy this")
					coinsDataStore:Increment(-item.Cost.Value)
					
					local stringValue = Instance.new("StringValue")
					stringValue.Name = item.Name
					
					if itemType == "skin" then
						stringValue.Parent = player.SkinInventory
					elseif itemType == "trap" then
						stringValue.Parent = player.TrapInventory
					end
					
					return "bought"
				else
					return "failed"
				end
			else
				print("Player already owns the item")
				
				if itemType == "skin" then
					player.EquippedSkin.Value = itemName
				elseif itemType == "trap" then
					player.EquippedTrap.Value = itemName  
				end
				return "equipped"
			end
		end
	else
		print("No skin/trap found")
		return "failed"
	end
end

I can’t make many assumptions here without more information. I’d recommend ensuring that

game.ReplicatedStorage.Traps

It contains the trap in question as well as skin. Your conditional

if item then

It seems to be what is tripping your script up.

Here are the folders:

local trapInventory = Instance.new("Folder")
	trapInventory.Name = "TrapInventory"
	trapInventory.Parent = player
	
	local skinInventory = Instance.new("Folder")
	skinInventory.Name = "SkinInventory"
	skinInventory.Parent = player
	
	local equppedTrap = Instance.new("StringValue")
	equppedTrap.Name = "EquippedTrap"
	equppedTrap.Parent = player

	local equppedSkin = Instance.new("StringValue")
	equppedSkin.Name = "EquippedSkin"
	equppedSkin.Parent = player
1 Like

Here is the ClientShop script:

local shop = script.Parent

local skins = shop:WaitForChild("Skins")
local traps = shop:WaitForChild("Traps")

local skinsBtn = shop:WaitForChild("SkinsButton")
local trapsBtn = shop:WaitForChild("TrapsButton")

local itemTemplate = script:WaitForChild("Template")

skinsBtn.MouseButton1Click:Connect(function()
	traps.Visible = false
	skins.Visible = true
end)

trapsBtn.MouseButton1Click:Connect(function()
	skins.Visible = false

	traps.Visible = true
end)

local skinsData = game.ReplicatedStorage.Skins:GetChildren()
local trapsData = game.ReplicatedStorage.Traps:GetChildren()

function createFrame(name, cost, object, parent)
	local frame = itemTemplate:Clone()
	frame.Name = name
	frame.Title.Text = name
	frame.Cost.Text = cost
	
	frame.Parent = parent
	
	return frame
end

function addSkins(data)
	for i, v in pairs(data) do
		local frame = createFrame(v.Name, v.Cost.Value, v, skins.Folder)
		
		frame.Button.MouseButton1Click:Connect(function()
			local result = game.ReplicatedStorage.BuyItem:InvokeServer(v.Name)
			print(result)
		end)
	end
end


wait(5)

addSkins(skinsData)

Eventhandling script:

local keyModule = require(script.Parent:WaitForChild("Game Logic").KeyModule)
local roundModule = require(script.Parent:WaitForChild("Game Logic").RoundModule)

game.Players.PlayerAdded:Connect(function(player)
	
	local trapInventory = Instance.new("Folder")
	trapInventory.Name = "TrapInventory"
	trapInventory.Parent = player
	
	local skinInventory = Instance.new("Folder")
	skinInventory.Name = "SkinInventory"
	skinInventory.Parent = player
	
	local equippedTrap = Instance.new("StringValue")
	equippedTrap.Name = "EquippedTrap"
	equippedTrap.Parent = player

	local equippedSkin = Instance.new("StringValue")
	equippedSkin.Name = "EquippedSkin"
	equippedSkin.Parent = player
	
	local inMenu = Instance.new("BoolValue")
	inMenu.Name = "inMenu"
	inMenu.Parent = player
	
	player.CharacterAdded:Connect(function(char)
		char.Humanoid.Died:Connect(function()
			
			if char:FindFirstChild("HumanoidRootPart") then
				keyModule.DropTools(player, game.Workspace.Map, char.HumanoidRootPart.Position)
				print("Tools dropped")
			end 
			
			if player:FindFirstChild("Contestant") then
				player.Contestant:Destroy()
			elseif player:FindFirstChild("Piggy") then
				player.Piggy:Destroy( )
			end
				
		end)
	end)
end)

local trapDebounce = false

game.ReplicatedStorage.PlaceTrap.OnServerEvent:Connect(function(player)
	if player:FindFirstChild("Piggy") then
		if player:FindFirstChild("TrapCount") then
			if not trapDebounce then
				trapDebounce = true
				
				if player.TrapCount.Value > 0 then
					if game.Workspace:FindFirstChild("Map") then
						player.TrapCount.Value = player.TrapCount.Value - 1
						
						local trap = game.ServerStorage.Bear_Trap:Clone()
						
						trap.CFrame = player.Character.HumanoidRootPart.CFrame - Vector3.new(0,3.5,0)
						trap.Parent = game.Workspace:FindFirstChild("Map")
					end
				end
				
				wait(5)
				trapDebounce = false
			end
		end
	end
end)
	
game.ReplicatedStorage.MenuPlay.OnServerEvent:Connect(function(player)
	if player:FindFirstChild("inMenu") then
		player.inMenu:Destroy()
	end
	
	if game.ServerStorage.GameValues.GameInProgress.Value == true then
		local contestant = Instance.new("BoolValue")
		contestant.Name = "Contestant"
		contestant.Parent = player
		
		game.ReplicatedStorage.ToggleCrouch:FireClient(player, true)
		
		roundModule.TeleportPlayers({player},game.Workspace:FindFirstChild("Map").PlayerSpawns:GetChildren())
	end
	
end)

game.ReplicatedStorage.BuyItem.OnServerInvoke = function(player, itemName, itemType)
	
	local DataStore2 = require(game.ServerScriptService.DataStore2)
	local MarketplaceService = game:GetService("MarketplaceService")
	
	local defaultCashValue = 0
	
	
	game.Players.PlayerAdded:Connect(function(plr)
		local coinsDataStore = DataStore2("Coins", player)
		
	
		
		local cash = Instance.new("StringValue")
		cash.Name = "Cash"
		
		local function coinsUpdated(updatedValue)
			cash.Value = coinsDataStore:Get(updatedValue)
			game.ReplicatedStorage.UpdateClientCurrency:FireClient(plr, coinsDataStore:Get(defaultCashValue))
	
		end
		
		coinsUpdated(defaultCashValue)
		
		coinsDataStore:OnUpdate(coinsUpdated)
		
		
	end)
	
	local item
	local inInventory
	
	if itemType == "skin" then
		item = game.ReplicatedStorage.Skins:FindFirstChild(itemName)
		
		if player.SkinInventory:FindFirstChild(itemName) then
			inInventory = true
		end
	elseif itemType == "trap" then
		item = game.ReplicatedStorage.Traps:FindFirstChild(itemName)
		if player.TrapInventory:FindFirstChild(itemName) then
			inInventory = true
		end
	end
	
	if item then
		local coinsDataStore = DataStore2("Coins", player)
		if item:FindFirstChild("Cost") then
			if not inInventory then
				print("Not in player's inventory")
				if item.Cost.Value <=  coinsDataStore then
					print("Player can buy this")
					coinsDataStore:Increment(-item.Cost.Value)
					
					local stringValue = Instance.new("StringValue")
					stringValue.Name = item.Name
					
					if itemType == "skin" then
						stringValue.Parent = player.SkinInventory
					elseif itemType == "trap" then
						stringValue.Parent = player.TrapInventory
					end
					
					return "bought"
				else
					return "failed"
				end
			else
				print("Player already owns the item")
				
				if itemType == "skin" then
					player.equippedSkin.Value = itemName
				elseif itemType == "trap" then
					player.equippedTrap.Value = itemName  
				end
				return "equipped"
			end
		end
	else
		print("No skin/trap found")
		return "failed"
	end
end

The reason why this

print("No skin/trap found")
		return "failed"

is ran is because thet conditional

if item then

is not meant. You need to make sure there is an item inside your folders in your game explorer. The location in question, according to your script, is in game.ReplicatedSotrage.Traps.

There are items in the explorer

I found out what the issue was, minor naming mistake. However I receive this error:

ServerScriptService.EventHandling:143: attempt to compare number and table

has to do with this line:

				if item.Cost.Value <=  coinsDataStore then

I don’t know how’d I get the value of the coins the player has

This should be a useful link: API - DataStore2

Try:

coinsDataStore:Get() 

to get the number of coins the player has.

1 Like

I looked through the API earlier and saw that, should’ve added it at the start. Thank you!

1 Like