I want to make a gamepass that gives you money just one time

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

  1. What do you want to achieve? I want to make a gamepass that gives you money just one time when the game detects you have it and I made a boolvalue that if its false then it turns it to true, gives you the money and then saves it in the datastore.

  2. What is the issue? When I rejoin I don’t get again the 5k $ but if the money that I have changes and lets say I get 10k$ or I spend some money then I get again 5k even if I already got the 5k.

  3. What solutions have you tried so far? I tried to fix the script but I can’t figure what’s the problem.

If you find the problem please tell me down below the mistakes I did and the solution.

local stat = "Euro" 
local startamount = 0 


local DataStore = game:GetService("DataStoreService")
local players = game:GetService("Players")
local ds = DataStore:GetDataStore("leaderstats1")

--Don't worry about the rest of the code, except for line 25.
game.Players.PlayerAdded:connect(function(player)
local leader = Instance.new("Folder",player)
	leader.Name = "leaderstats"
local Cash = Instance.new("IntValue",leader)
Cash.Name = stat
	Cash.Value = ds:GetAsync(player.UserId, player.leaderstats.Euro.Value) or startamount
	local awarded = Instance.new("BoolValue", player)
	awarded.Name = "Awarded"
	ds:GetAsync(player.UserId, player.Awarded.Value)
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 148030355) and player.Awarded.Value == false then
		player.Awarded.Value = true
		Cash.Value = Cash.Value + 5000
	end
	
	
	
Cash.Changed:Connect(function()
	ds:SetAsync(player.UserId, Cash.Value)
end)
	
awarded.Changed:Connect(function()
		ds:SetAsync(player.UserId, awarded.Value)
	end)
	end)


game.Players.PlayerRemoving:connect(function(player)
	ds:SetAsync(player.UserId,player.Awarded.Value, player.leaderstats.Euro.Value)
end)

game:BindToClose(function(player)
	for _, player in ipairs(players:GetPlayers()) do
		ds:SetAsync(player.UserId,player.Awarded.Value, player.leaderstats.Euro.Value)
	end
end)

The problem here is that SetAsync has 4 paramaters which is key, value, userIds and options.
So what you are doing wrong is that you are setting the 3rd parameter as the value for the second paramater so you need to combine those two in a table and use JSONEncode to put it into string form and at GetAsync use JSONDecode.

Also at GetAsync you only need to put in the key. So what you can do is decode the text into a table then get index 1 to check if it is awarded and then index 2 for the money.

Well the problem is that I am not a really good scripter so I can’t do that. I’m actually a beginner so I don’t really have any idea how to do that.

Can you help me with the script?

Here is a script with the fix (Aswell as a few improvements like using pcall)

local stat = "Euro" 
local startamount = 0 


local DataStore = game:GetService("DataStoreService")
local players = game:GetService("Players")
local ds = DataStore:GetDataStore("leaderstats1")
local https = game:GetService("HttpService")

--Don't worry about the rest of the code, except for line 25.
players.PlayerAdded:connect(function(player)
	local data
	local s,r = pcall(function()
		data = https:JSONDecode(ds:GetAsync(player.UserId))
	end)
	if not s then error("Data Failed to load: "..r) end
	local leader = Instance.new("Folder",player)
	leader.Name = "leaderstats"
	local Cash = Instance.new("IntValue",leader)
	Cash.Name = stat
	Cash.Value = data[2] or startamount
	local awarded = Instance.new("BoolValue", player)
	awarded.Name = "Awarded"
	awarded.Value = data[1]
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 148030355) and player.Awarded.Value == false then
		player.Awarded.Value = true
		Cash.Value = Cash.Value + 5000
	end
end)


game.Players.PlayerRemoving:connect(function(player)
	local s,r = pcall(function()
		ds:SetAsync(player.UserId, https:JSONEncode({player.Awarded.Value, player.leaderstats.Euro.Value}))
	end)
	if not s then warn("Error while saving: "..r) end
end)

game:BindToClose(function(player)
	for _, player in ipairs(players:GetPlayers()) do
		local s,r = pcall(function()
			ds:SetAsync(player.UserId, https:JSONEncode({player.Awarded.Value, player.leaderstats.Euro.Value}))
		end)
		if not s then warn("Error while saving: "..r) end
	end
end)

Also I saw that you were setting the key in the datastore everytime those values updated. This is a bad idea as Roblox has a datastore quota.

for some reason it doesn’t work and the data doesn’t get saved and it says attempt to index number with number

On which line does the error happen?

on the line 21 (characters limit))

I think what you’re really looking for is a Developer product. Developer products are like game passes but can be purchased multiple times and are handled differently(so every time a user purchases one the currency is added and they don’t save as game passes do). However if you want to use a game pass instead because the purchase more closely resembles something like a starter pack, then you should save a value to a datastore that tells you if the user has claimed the game pass rewards and adapt your scripts based on that.

Well thats what I am trying to do with this script but it doesn’t work right

Oh, your problem is that your datastore already contains a value which is a number, all you have to do is clear the keys or change the datastore’s name.

Also I found a problem with the script that if new players joined they wont be given stats.
Here is the fixed script for the problem:

local stat = "Euro" 
local startamount = 0 


local DataStore = game:GetService("DataStoreService")
local players = game:GetService("Players")
local ds = DataStore:GetDataStore("leaderstats2") -- I already changed this name for you if you dont want to change the name change it back.
local https = game:GetService("HttpService")

--Don't worry about the rest of the code, except for line 25.
players.PlayerAdded:connect(function(player)
	local data
	local s,r = pcall(function()
		data = https:JSONDecode(ds:GetAsync(player.UserId))
	end)
	if not s then
		if data == nil then data = {} else error("Data Failed to load: "..r) end-- Prevents data returning nil
	end
	
	local leader = Instance.new("Folder",player)
	leader.Name = "leaderstats"
	local Cash = Instance.new("IntValue",leader)
	Cash.Name = stat
	Cash.Value = data[2] or startamount
	local awarded = Instance.new("BoolValue", player)
	awarded.Name = "Awarded"
	awarded.Value = data[1]
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 148030355) and player.Awarded.Value == false then
		player.Awarded.Value = true
		Cash.Value = Cash.Value + 5000
	end
end)


game.Players.PlayerRemoving:connect(function(player)
	local s,r = pcall(function()
		ds:SetAsync(player.UserId, https:JSONEncode({player.Awarded.Value, player.leaderstats.Euro.Value}))
	end)
	if not s then warn("Error while saving: "..r) end
end)

game:BindToClose(function(player)
	for _, player in ipairs(players:GetPlayers()) do
		local s,r = pcall(function()
			ds:SetAsync(player.UserId, https:JSONEncode({player.Awarded.Value, player.leaderstats.Euro.Value}))
		end)
		if not s then warn("Error while saving: "..r) end
	end
end)
1 Like

Okay so I changed the name of the datastore and now it works perfectly and I also put the new script! Thank you very much for helping me!

Ik someone already gave you an answer, but why do you want to set it to the datastore and not the players leaderstat value?

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