Subscription script running only once

  1. What do you want to achieve? Keep it simple and clear!
    I am modifying the Roblox-provided script on the subscriptions wiki page to replace a game pass with a subscription. Originally, the game pass unlocked access to a room with all the tools but I’m redesigning it so the player spawns with all the tools in their inventory with the speed and health bonuses automatically applied.

  2. What is the issue? Include screenshots / videos if possible!
    Upon joining the game, the subscription’s effects do not work. When I reset my avatar, everything works as intended. However, if my character dies again, it completely breaks after that. There are no errors.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    There doesn’t appear to be any similar problems I could find online. I’ve tried rewriting this script many times but to no avail.

This is the server script located in ServerScriptService

-- Run this code on the server
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local toolNames = {"Assault Rifle", "BoomBox", "Medkit", "Minigun", "Thief Knife"}
local ReplicatedStorage = game:GetService("ReplicatedStorage")


local LEGACY_GAME_PASS_ID = hidden -- Replace with the ID of the game pass being replaced by a subscription
local SUBSCRIPTION_ID = "hidden" -- Replace with your subscription ID

local function awardBenefit(player: Player)
	-- You should award the subscription here
	local character = player.Character or player.CharacterAdded:Wait()
	local superthiefitems = ReplicatedStorage:WaitForChild("SuperThiefItems")
	---
	player.CharacterAdded:Wait()
	player.Character:WaitForChild("Humanoid")
	player.Character.Humanoid.WalkSpeed = 40
	player.Character.Humanoid.MaxHealth = 150
	player.Character.Humanoid.Health = 150
	---
	for i = 1, #toolNames do
		local tool = superthiefitems:FindFirstChild(toolNames[i])
		if tool then
			print(tool.Name.." has been distributed to "..player.Name)
			local clone = tool:Clone()
			clone.Parent = player.Backpack
		end
	end
	---
end

local function revokeBenefitIfGranted(player: Player)
	-- This method is called for every player who does _not_ have the subscription
	-- If your code saves subscriptions to Data Stores or provides some benefit that needs to be 'revoked'
	-- you should use this method to handle the revocation
end

local function checkSubscriptionStatus(player: Player)
	local success, result = pcall(function()
		return MarketplaceService:GetUserSubscriptionStatusAsync(player, SUBSCRIPTION_ID)
	end)

	if not success then
		print(`Error fetching subscription status: {result}`)
		return
	end

	if result.IsSubscribed then
		if player.Character and player.Character:FindFirstChild("Humanoid") then
			player.Character.Humanoid.WalkSpeed = 40
			player.Character.Humanoid.MaxHealth = 150
			player.Character.Humanoid.Health = 150
			awardBenefit(player)
		else
			player.CharacterAdded:Wait()
			player.Character:WaitForChild("Humanoid")
			player.Character.Humanoid.WalkSpeed = 40
			player.Character.Humanoid.MaxHealth = 150
			player.Character.Humanoid.Health = 150
			awardBenefit(player)
		end
	else
		revokeBenefitIfGranted(player)
	end
end

local function onPlayerAdded(player: Player)
	local success, result = pcall(function()
		return MarketplaceService:UserOwnsGamePassAsync(player.UserId, LEGACY_GAME_PASS_ID)
	end)

	if not success then
		print(`Error fetching game pass status: {result}`)
		return
	end

	if result then
		-- If the player has purchased the legacy game pass, we do not need to look up their subscription status
		-- as they have the benefit granted for life
		if player.Character and player.Character:FindFirstChild("Humanoid") then
			player.Character.Humanoid.WalkSpeed = 40
			player.Character.Humanoid.MaxHealth = 150
			player.Character.Humanoid.Health = 150
			awardBenefit(player)
		else
			player.CharacterAdded:Wait()
			player.Character:WaitForChild("Humanoid")
			player.Character.Humanoid.WalkSpeed = 40
			player.Character.Humanoid.MaxHealth = 150
			player.Character.Humanoid.Health = 150
			awardBenefit(player)
		end
		return
	end
	
	checkSubscriptionStatus(player)
end

local function onUserSubscriptionStatusChanged(player: Player, subscriptionId: string)
	if subscriptionId == SUBSCRIPTION_ID then
		checkSubscriptionStatus(player)
	end
end


local function onPromptGamePassPurchaseFinished(player: Player, purchasedPassID: number, purchaseSuccess: boolean)
	if purchaseSuccess and purchasedPassID == LEGACY_GAME_PASS_ID then
		awardBenefit(player)
	end
end

game.Players.PlayerAdded:Connect(function(player)
	checkSubscriptionStatus(player)
	player.CharacterAdded:Connect(function(character)
		checkSubscriptionStatus(game.Players:GetPlayerFromCharacter(character))
	end)
end)



Players.PlayerAdded:Connect(onPlayerAdded)
Players.UserSubscriptionStatusChanged:Connect(onUserSubscriptionStatusChanged)
-- We will continue to listen for in-game game pass purchases in case the game pass is still on sale
MarketplaceService.PromptGamePassPurchaseFinished:Connect(onPromptGamePassPurchaseFinished)

Any help would be greatly appreciated. Thank you!

3 Likes

:Wait() Yields until the function is running, remove the second second CharacterAdded, this is how it should look like

local function awardBenefit(player: Player)
	-- You should award the subscription here
	local character = player.Character or player.CharacterAdded:Wait()
	local superthiefitems = ReplicatedStorage:WaitForChild("SuperThiefItems")
	---
	player.Character:WaitForChild("Humanoid")
	player.Character.Humanoid.WalkSpeed = 40
	player.Character.Humanoid.MaxHealth = 150
	player.Character.Humanoid.Health = 150
	---
	for i = 1, #toolNames do
		local tool = superthiefitems:FindFirstChild(toolNames[i])
		if tool then
			print(tool.Name.." has been distributed to "..player.Name)
			local clone = tool:Clone()
			clone.Parent = player.Backpack
		end
	end
	---
end
1 Like

It works when I join but when I die, it stops working after that

You have multiple lines of CharacterAdded:Wait(), remove them

I now get this error at line 86

ServerScriptService.SuperThief:86: attempt to index nil with ‘WaitForChild’

What Line is the error occuring? (Like the code)

Line 86. I am assuming this is happening because the humanoid does not exist, or does not exist yet

Then please just make it different on how you get the character

local function awardBenefit(player: Player)
	-- You should award the subscription here
	local character = player.Character or player.CharacterAdded:Wait()
	local superthiefitems = ReplicatedStorage:WaitForChild("SuperThiefItems")
	---
	local Humanoid = character:WaitForChild("Humanoid")
	Humanoid.WalkSpeed = 40
	Humanoid.MaxHealth = 150
	Humanoid.Health = 150
	---
	for i = 1, #toolNames do
		local tool = superthiefitems:FindFirstChild(toolNames[i])
		if tool then
			print(tool.Name.." has been distributed to "..player.Name)
			local clone = tool:Clone()
			clone.Parent = player.Backpack
		end
	end
	---
end


local function checkSubscriptionStatus(player: Player)
	local Character = player.Character or player.CharacterAdded:Wait()
	local Humanoid = Character:WaitForChild("Humanoid")
	local success, result = pcall(function()
		return MarketplaceService:GetUserSubscriptionStatusAsync(player, SUBSCRIPTION_ID)
	end)

	if not success then
		print(`Error fetching subscription status: {result}`)
		return
	end

	if result.IsSubscribed then
		player.Character.Humanoid.WalkSpeed = 40
		player.Character.Humanoid.MaxHealth = 150
		player.Character.Humanoid.Health = 150
		awardBenefit(player)
	else
		revokeBenefitIfGranted(player)
	end
end

local function onPlayerAdded(player: Player)
	local Character = player.Character or player.CharacterAdded:Wait()
	local Humanoid = Character:WaitForChild("Humanoid")
	local success, result = pcall(function()
		return MarketplaceService:UserOwnsGamePassAsync(player.UserId, LEGACY_GAME_PASS_ID)
	end)

	if not success then
		print(`Error fetching game pass status: {result}`)
		return
	end

	if result then
		-- If the player has purchased the legacy game pass, we do not need to look up their subscription status
		-- as they have the benefit granted for life
		Humanoid.WalkSpeed = 40
		Humanoid.MaxHealth = 150
		Humanoid.Health = 150
		awardBenefit(player)
		return
	end
	
	checkSubscriptionStatus(player)
end

Really no hate but your code is kind of messy, make variables when you use many iterations to get a single variable. I’ve cleaned it up for you

I don’t know how to make it different, that’s the problem. I’m new to scripting so it’s not going to be perfect and clean.

It’s alright, everybody can start out, just make sure that you can keep track of certain things, replace the functions I sent with the functions you currently have and it should work

Alright. I’ve done that, tested it and there’s no errors but it’s back to only working on the first life again. Very bizarre

Solved on my own, using a seperate script and a boolean value to identify subscribers in a seperate script to handle speed and health bonuses.

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