Help with updating gamepass multiplier loop

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

  1. What do you want to achieve? Keep it simple and clear!

I am making a VIP gamepass give 1.5x coins and xp but am having trouble with figuring out a way to update the loop when a player buys the gamepass in game. It works fine when they rejoin.

  1. What is the issue? Include screenshots / videos if possible!

The issue is that I do not know how to update the multiplier in the loop.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I have looked for solution on the devhub and cannot find anything, I have tried to search things on the devforum and none of them help with my issue. Everything works fine besides when the player buys it in game.

game.Players.PlayerAdded:Connect(function(player)
	
	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')
	
	CoinsVIPMulti = 1
	XPVIPMulti = 1
	
	CoinsPremiumMulti = 0
	XPPremiumMulti = 0
	
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId,27136394) then
		
		CoinsVIPMulti = 1.5
		XPVIPMulti = 1.5
	end	
	
	
	game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)

		if id == 27136394 and purchased then
			
			CoinsVIPMulti.Value = 1.5
			XPVIPMulti.Value = 1.5
		end
	end)
	
	if player.MembershipType == Enum.MembershipType.Premium then
		
		CoinsPremiumMulti = 0.5
		XPPremiumMulti = 0.5
	end
	
	local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	local TotalXPMulti = XPVIPMulti + XPPremiumMulti
	
	while true do
		
		Coins.Value += 5 * TotalCoinsMulti
		XP.Value += 5 * TotalXPMulti
		wait(2)
	end
end)

I think that the PromptGamePassPurchaseFinished is not activating because of the loop. I somewhat new to scripting so thanks for any help in advance.

I think the issue here is that the values aren’t saved in any datastore

You should check this for the default roblox datastores
https://developer.roblox.com/en-us/articles/Data-store

I do recommend using datastore2 which is an open source module that should be more reliable

All of the values are saved in a separate script besides the CoinsVIPMulti, XPVIPMulti, CoinsPremiumMulti, and XPPremiumMulti which are set when the player joins here. Should I save those other values?

yes they should be saved otherwise they will get only the value gotten from when you joined or bought the gamepass

I just retested this. When the player joins, the CoinsVIPMulti and XPVIPMulti is set to 1 so when a player without the gamepass gains coins they still are gaining 5. The premium multipliers then can be set to 0. This means anyone without premium and vip gets 5 coins every 2 secs. If you have premium, you get 7.5 coins and if you own both, you get 10 coins. Everything is working fine besides when the player buys the gamepass and doesn’t leave and rejoin. I am trying to make it so the player doesn’t have to leave and rejoin.

oh I think I understand the issue now that’s because the values are updated only when you join the game you need to constantly update them

Yes, that is problem but I’m not quite sure how to do that.

I think it’s pretty much this

game.Players.PlayerAdded:Connect(function(player)
	
	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')
	
	CoinsVIPMulti = 1
	XPVIPMulti = 1
	
	CoinsPremiumMulti = 0
	XPPremiumMulti = 0
	
	game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)

		if id == 27136394 and purchased then
			
			CoinsVIPMulti.Value = 1.5
			XPVIPMulti.Value = 1.5
		end
	end)
	
	while true do
        if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId,27136394) then
		
		   CoinsVIPMulti = 1.5
		   XPVIPMulti = 1.5
	    end	

        if player.MembershipType == Enum.MembershipType.Premium then
		    CoinsPremiumMulti = 0.5
		    XPPremiumMulti = 0.5
	    end

		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	    local TotalXPMulti = XPVIPMulti + XPPremiumMulti

		Coins.Value += 5 * TotalCoinsMulti
		XP.Value += 5 * TotalXPMulti
		wait(2)
	end
end)

I’m not sure why but this still isn’t working. I’m going to run some tests real quick. Thank you for helping me so far here!

Ok, so the code below will work, I just need to know if it is possible for me to end the doesntHaveVIP() function and start the hasVIP() function.

game.Players.PlayerAdded:Connect(function(player)
	
	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')
	
	CoinsVIPMulti = 1
	XPVIPMulti = 1
	
	CoinsPremiumMulti = 0
	XPPremiumMulti = 0
	
	local function hasVIP()
		
		CoinsVIPMulti = 1.5
		XPVIPMulti = 1.5
		
		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end
		
		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti

		while true do

			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			wait(2)
		end
	end
	
	local function doesntHaveVIP()
		
		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end
		
		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti
		
		while true do

			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			wait(2)
		end		
	end
	
	game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)
		if id == 27136394 and purchased then
			
			--How can I stop the doesntHaveVIP() function and start the hasVIP() function
		end
	end)
	
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId,27136394) then
		
		hasVIP()
	else
		
		doesntHaveVIP()
	end	
end)

Also, I’m assuming that this is probably a bad way of doing this but I couldn’t come up with anything else.

You can use RunService and use the the Heartbeat event which is a event that fires every frame, after the physics simulation has completed, which can act as an infinite loop as well.
Using heartbeat you are able to use a connection that is returned by the event itself and use the Disconnect() method where you want to stop the connection

here the source
Handling Events.

1 Like
local runService = game:GetService("RunService")

local debounce = false

game.Players.PlayerAdded:Connect(function(player)
	
	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')
	
	CoinsVIPMulti = 1
	XPVIPMulti = 1
	
	CoinsPremiumMulti = 0
	XPPremiumMulti = 0

	local connection
	
	local function hasVIP()
		
		CoinsVIPMulti = 1.5
		XPVIPMulti = 1.5
		
		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end
		
		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti

		while true do

			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			wait(2)
		end
	end
	
	local function doesntHaveVIP()
		
		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end
		
		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti
		
		connection = runService.Heartbeat:Connect(function()
			--the reason I'm using a debounce it's because hearbeat is a event that fires each frame
			--that means it will ignore the wait()
			--this event fires 40 times per second so if you don't mind this you can remove the debounce and wait()
			if not debounce then	
				debounce = true
				Coins.Value += 5 * TotalCoinsMulti
				XP.Value += 5 * TotalXPMulti
				wait(2)
				debounce = false
			end
		end)		
	end
	
	game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)
		if id == 27136394 and purchased then
			
			connection:Disconnect()
		end
	end)
	
	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId,27136394) then
		
		hasVIP()
	else
		
		doesntHaveVIP()
	end	
end)

I hope this works, handling events like this can be really handy for the future so I suggest to check this out

1 Like

This works perfectly and was exactly the kind of solution I was looking for! Thank you so very much.

Sorry for bringing this back up. I have ran some extra tests with multiple people there seems to be an issue. When more than one player joins, all of the other players besides them don’t gain coins. Also if someone buys VIP, then everyone starts gaining coins again and gets the benefits. Do you know of anyway to solve this?

Here is the script:

local runService = game:GetService("RunService")

local debounce = false

game.Players.PlayerAdded:Connect(function(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	CoinsVIPMulti = 1
	XPVIPMulti = 1

	CoinsPremiumMulti = 0
	XPPremiumMulti = 0

	local connection

	local function hasVIP()

		CoinsVIPMulti = 1.5
		XPVIPMulti = 1.5

		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end

		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti

		while true do

			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			wait(2)
		end
	end

	local function doesntHaveVIP()

		if player.MembershipType == Enum.MembershipType.Premium then

			CoinsPremiumMulti = 0.5
			XPPremiumMulti = 0.5
		end

		local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
		local TotalXPMulti = XPVIPMulti + XPPremiumMulti

		connection = runService.Heartbeat:Connect(function()

			if not debounce then	
				debounce = true
				Coins.Value += 5 * TotalCoinsMulti
				XP.Value += 5 * TotalXPMulti
				wait(2)
				debounce = false
			end
		end)		
	end

	game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)
		if id == 27136394 and purchased then

			connection:Disconnect()
			hasVIP()
		end
	end)

	if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId,27136394) then

		hasVIP()
	else

		doesntHaveVIP()
	end	
end)

not sure if this will fix this but you shouldn’t put PromptGamePassPurchaseFinished inside playerAdded as it has a player parameter and it will fire eventually without needing to check if the player joined first

local runService = game:GetService("RunService")
local marketplaceService = game:GetService("MarketplaceService")
local players = game:GetService("Players")

local debounce = false

players.PlayerAdded:Connect(function(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	CoinsVIPMulti = 1
	XPVIPMulti = 1

	CoinsPremiumMulti = 0
	XPPremiumMulti = 0

	if marketplaceService:UserOwnsGamePassAsync(player.UserId,27136394) then

		hasVIP(player)
	else

		doesntHaveVIP(player)
	end	
end)

function hasVIP(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	CoinsVIPMulti = 1.5
	XPVIPMulti = 1.5

	if player.MembershipType == Enum.MembershipType.Premium then

		CoinsPremiumMulti = 0.5
		XPPremiumMulti = 0.5
	end

	local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	local TotalXPMulti = XPVIPMulti + XPPremiumMulti

	while true do

		Coins.Value += 5 * TotalCoinsMulti
		XP.Value += 5 * TotalXPMulti
		task.wait(2)
	end
end

local connection

function doesntHaveVIP(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	if player.MembershipType == Enum.MembershipType.Premium then

		CoinsPremiumMulti = 0.5
		XPPremiumMulti = 0.5
	end

	local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	local TotalXPMulti = XPVIPMulti + XPPremiumMulti

	connection = runService.Heartbeat:Connect(function()

		if not debounce then	
			debounce = true
			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			task.wait(2)
			debounce = false
		end
	end)		
end

marketplaceService.PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)
	if id == 27136394 and purchased then

		connection:Disconnect()
		hasVIP(player)
	end
end)

This doesn’t seem to work either :confused:. I changed the position of the PlayerAdded event, because it fires the functions so the functions have to be above it and then in both functions added

CoinsVIPMulti = 1
XPVIPMulti = 1

CoinsPremiumMulti = 0
XPPremiumMulti = 0

There were no errors but the same things still occur. Do you think it has something to do with the connection?

I doubt that causes the issue, as for now I don’t see why this shouldn’t work so you could do a bit of testing using prints or take inspiration of how roblox does it Game Passes – One‑Time Purchases

Actually I have a doubt about the debounce since I’ve put it as a global variable that means every player will overwrite it so try it to put it inside the function

Ok so I have gotten rid of every problem except for one now. The problem is that if one player buys VIP everything works fine but if two players buy VIP the second player doesn’t disconnect from the doesntHaveVIP(player).

Here is my code:

local RunService = game:GetService("RunService")
local MarketPlaceService = game:GetService("MarketplaceService")
local players = game:GetService("Players")

function hasVIP(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	CoinsVIPMulti = 1.5
	XPVIPMulti = 1.5

	CoinsPremiumMulti = 0
	XPPremiumMulti = 0

	if player.MembershipType == Enum.MembershipType.Premium then

		CoinsPremiumMulti = 0.5
		XPPremiumMulti = 0.5
	end

	local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	local TotalXPMulti = XPVIPMulti + XPPremiumMulti

	while true do

		Coins.Value += 5 * TotalCoinsMulti
		XP.Value += 5 * TotalXPMulti
		task.wait(2)
	end
end

local Connection

function doesntHaveVIP(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local XP = PlayerStats:WaitForChild('XP')
	local Coins = PlayerStats:WaitForChild('Coins')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')
	
	local debounce = false
	
	CoinsVIPMulti = 1
	XPVIPMulti = 1

	CoinsPremiumMulti = 0
	XPPremiumMulti = 0

	if player.MembershipType == Enum.MembershipType.Premium then

		CoinsPremiumMulti = 0.5
		XPPremiumMulti = 0.5
	end

	local TotalCoinsMulti = CoinsVIPMulti + CoinsPremiumMulti
	local TotalXPMulti = XPVIPMulti + XPPremiumMulti

	Connection = RunService.Heartbeat:Connect(function()

		if not debounce then	
			debounce = true
			Coins.Value += 5 * TotalCoinsMulti
			XP.Value += 5 * TotalXPMulti
			task.wait(2)
			debounce = false
		end
	end)		
end

players.PlayerAdded:Connect(function(player)

	local PlayerStats = player:WaitForChild('PlayerStats')
	local CoinsVIPMulti = PlayerStats:WaitForChild('CoinsVIPMulti')
	local XPVIPMulti = PlayerStats:WaitForChild('XPVIPMulti')
	local CoinsPremiumMulti = PlayerStats:WaitForChild('CoinsPremiumMulti')
	local XPPremiumMulti = PlayerStats:WaitForChild('XPPremiumMulti')

	if MarketPlaceService:UserOwnsGamePassAsync(player.UserId,27136394) then

		hasVIP(player)
	else

		doesntHaveVIP(player)
	end	
end)

MarketPlaceService.PromptGamePassPurchaseFinished:Connect(function(player, id, purchased)
	if id == 27136394 and purchased then
		
		Connection:Disconnect(player)
		hasVIP(player)
	end
end)