Either you need to use UserOwnsGamePassAsync() to load the attribute, or use DataStores which makes it even more complex, not for me though, but maybe OP.
How, attributes are literally marked the best solution by roblox themselves. They highly recommend you to use them along with collectionservice due to how versatile both services are.
Can you clarify the cases in which Roblox talked about it ? I didnât told in general, itâs not pretty good in this specific caseâŚ
I asked to clarify in the case of gamepass.
it is leagues better than spamming api calls, especially if that api call is happening each time a player is pressing a gamepass button
What sounds better to you?
Ping Roblox once on player join, setting the value, and being set
Pinging Roblox every single time that button is pushed (let me remind you, you can just keep jumping off and on to this same button)
Ok, but if you have alot of gamepasses, you need alot of code maybe. But ok, attributes are good. I recommend OP to use attributes then.
can easily be done with a table and the ids, keeping it quite small and compact
To create an auto collector gamepass, you can modify your existing code to automatically collect cash for players without them needing to click the CashButton. Hereâs an example code:
-- Configuration
local CASH_COLLECT_INTERVAL = 5 -- The interval (in seconds) at which cash is automatically collected
-- Function to give a player cash
local function giveCash(player, amount)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
end
local cash = leaderstats:FindFirstChild("Cash")
if not cash then
cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Value = 0
cash.Parent = leaderstats
end
cash.Value = cash.Value + amount
end
-- Function to automatically collect cash for players with the gamepass
local function autoCollectCash()
for _, player in ipairs(game.Players:GetPlayers()) do
if player:FindFirstChild("AutoCollector") then -- Check if player has gamepass
local humanoid = player.Character and player.Character:FindFirstChild("Humanoid")
if humanoid and humanoid.SeatPart then -- Check if player is seated
giveCash(player, Values.CashValue.Value)
Values.CashValue.Value = 0
end
end
end
end
-- Connect the autoCollectCash function to run at the specified interval
while wait(CASH_COLLECT_INTERVAL) do
autoCollectCash()
end
To create a 2x cash gamepass, you can modify your existing code to multiply the amount of cash players receive. Hereâs an example code:
-- Configuration
local CASH_MULTIPLIER = 2 -- The amount to multiply cash by for players with the gamepass
-- Function to give a player cash
local function giveCash(player, amount)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
end
local cash = leaderstats:FindFirstChild("Cash")
if not cash then
cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Value = 0
cash.Parent = leaderstats
end
cash.Value = cash.Value + amount
end
-- Function to handle player collecting cash
local function onPlayerCollectCash(player)
if player:FindFirstChild("DoubleCash") then -- Check if player has gamepass
giveCash(player, Values.CashValue.Value * CASH_MULTIPLIER)
else
giveCash(player, Values.CashValue.Value)
end
Values.CashValue.Value = 0
end
-- Connect the onPlayerCollectCash function to the CashButton's Touched event
Mainitems.CashButton.ButtonPart.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Values.OwnerValue.Value == player then
onPlayerCollectCash(player)
end
end
end)
Note that in both examples, you will need to create gamepasses in the Roblox Studio marketplace and add them to your game in order for players to purchase them.
How are you gonna check if the player has gamepass ? Where you used MarketplaceService ? If youâre just checking if a player has a value, that isnât the best way as @Wertyhappy27 already proved, it would be messy having so much values.
I tried that already. That will multiply even if you dont own the gamepass.
- Set up gamepasses for the game
- Have a variable âserver sideâ stating if the player owns the gamepass (can be an attribute)
- Have the collector or the 2x check for the variable in step 2, each time to see if needed to auto collect or 2x the value
- When a gamepass is purchased, set the variable in step 2 to true (purchase verification on server)
- When a character logs in or resets, check marketplace service to set variable in step 2
- Optional⌠If you are doing the check on step 3, on the client, every so often, ask the server to verify that the gamepass is owned, if there is a difference, such as the server says it is not, and the client says it is, recheck from marketplace service, and reset the clients variable, or kick them for hacking
local Debounce = false
local MPS = game:GetService("MarketplaceService")
local plr
Mainitems.CashButton.ButtonPart.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
plr = player
if Values.OwnerValue.Value == player then
if Debounce == false then
Debounce = true
if MPS:UserOwnsGamePassAsync(player.UserId, gamepassidhere) then
player:WaitForChild("leaderstats").Tix.Value += Values.CashValue.Value * 2
wait()
Values.CashValue.Value = 0
wait(1)
Debounce = false
else
player:WaitForChild("leaderstats").Tix.Value += Values.CashValue.Value
wait()
Values.CashValue.Value = 0
wait(1)
Debounce = false
end
end
end
end
end)
Value.Changed:Connect(function(value)
if MPS:UserOwnsGamePassAsync(player.UserId, gamepassidhere) then
Mainitems.CashButton.ScreenPart.SurfaceGui.TextLabel.Text = value * 2
else
Mainitems.CashButton.ScreenPart.SurfaceGui.TextLabel.Text = value
end
end)
Also, I recommend you to learn basics of scripting or on whatever level you are, because it seems like youâre struggling with adding if and else statements, like there are some things you can easily add but still youâre asking people about every simple thing.
Still doesnt solve the SurfaceGui displaying the correct amount.
Whatâs your full code then ? Please tell that. And we also donât know what is your setup. We just gave you some basic scripts, but we donât know what actually are you doing and whatâs wrong. Maybe you did something wrong or any other script is doing something. So please show your scripts.
This includes all functions.
local TycoonModel = script.Parent.Parent
local items = {}
local Boughtitems = TycoonModel:FindFirstChild("Boughtitems")
local Buttons = TycoonModel:FindFirstChild("Buttons")
local DropperParts = TycoonModel:FindFirstChild("DropperParts")
local Mainitems = TycoonModel:FindFirstChild("Mainitems")
local Scripts = TycoonModel:FindFirstChild("Scripts")
local Values = TycoonModel:FindFirstChild("Values")
--Tycoon Clone--
local TycoonClone = TycoonModel:Clone()
TycoonClone.Parent = game.ReplicatedStorage
--- Owner Functions ---
Mainitems.OwnerDoor.MainDoor.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") and Values.OwnerValue.Value == nil then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if player:FindFirstChild("OwnsTycoon").Value == false then
Values.OwnerValue.Value = player
player:FindFirstChild("OwnsTycoon").Value = true
while wait() do
Mainitems.OwnerDoor.MainDoor.SurfaceGui.TextLabel.Text = tostring(Values.OwnerValue.Value).."'s Tycoon"
end
end
end
end)
--Buying Functions--
for i, v in pairs(Buttons:GetChildren()) do
local NewItem = Boughtitems:FindFirstChild(v.Item.Value)
if NewItem ~= nil then
items[NewItem.Name] = NewItem:Clone()
NewItem:Destroy()
else
v.ButtonPart.Transparency = 1
v.ButtonPart.CanCollide = false
v.ButtonPart.BillboardGui.Frame.Visible = false
end
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function()
v.ButtonPart.Transparency = 1
v.ButtonPart.CanCollide = false
v.ButtonPart.BillboardGui.Frame.Visible = false
if Boughtitems:WaitForChild(v.Dependency.Value, 1000000) then
v.ButtonPart.Transparency = 0
v.ButtonPart.CanCollide = true
v.ButtonPart.BillboardGui.Frame.Visible = true
end
end))
end
v.ButtonPart. Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Values.OwnerValue.Value == player then
if v.ButtonPart.CanCollide == true and v.ButtonPart.Transparency == 0 then
if player:WaitForChild("leaderstats").Tix.Value >= v.Price.Value then
player.leaderstats.Tix.Value -= v.Price.Value
items[v.Item.Value].Parent = Boughtitems
v:Destroy()
end
end
end
end
end)
end
--Cash Function--
local Debounce = false
local MPS = game:GetService("MarketplaceService")
local plr
Mainitems.CashButton.ButtonPart.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
plr = player
if Values.OwnerValue.Value == player then
if Debounce == false then
Debounce = true
if MPS:UserOwnsGamePassAsync(player.UserId, 144417242) then
player:WaitForChild("leaderstats").Tix.Value += Values.CashValue.Value * 2
wait()
Values.CashValue.Value = 0
wait(1)
Debounce = false
else
player:WaitForChild("leaderstats").Tix.Value += Values.CashValue.Value
wait()
Values.CashValue.Value = 0
wait(1)
Debounce = false
end
end
end
end
end)
Value.Changed:Connect(function(value)
if MPS:UserOwnsGamePassAsync(player.UserId, 144417242) then
Mainitems.CashButton.ScreenPart.SurfaceGui.TextLabel.Text = value * 2
else
Mainitems.CashButton.ScreenPart.SurfaceGui.TextLabel.Text = value
end
end)
all basic functions are above.
This seems fine, can you show an image or video of whatâs happening exactly ?
This is the leaderstats code
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder" , player)
leaderstats.Name = "leaderstats"
local Cash = Instance.new("NumberValue", leaderstats)
Cash.Name = "Tix"
Cash.Value = 0
local OwnsTycoon = Instance.new("BoolValue",player)
OwnsTycoon.Name = "OwnsTycoon"
OwnsTycoon.Value = false
end)