Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Gamepass script not working?

I made a gamepass that lets you edit your walkspeed. I also made another way to get the pass, through perks I select through values. I put a model in replicatedstorage and put in stringvalues named "perkers" and the value would have their names. I tested out an alt account who had their name in one of the string values. But it didn't work! Can someone help me out with this?

local passid = 236050258 -- The ID of the gamepass goes here
local GamePassService = game:GetService('GamePassService')
local player = script.Parent.Parent.Parent.Parent.Parent

while true do
	wait(1)
	for i,v in pairs(game.ReplicatedStorage.Perkers:GetChildren()) do
	if GamePassService:PlayerHasPass(player, passid) then
		player:FindFirstChild("PlayerGui").WalkSpeedPass.Frame.Visible = true
	elseif player.Name == v.Value then
		warn("Watchme naeynaey")
		player:FindFirstChild("PlayerGui").WalkSpeedPass.Frame.Visible = true
else
	player:FindFirstChild("PlayerGui").WalkSpeedPass.Frame.Visible = false
	script.Disabled = true
		end
	end
end

By the way this is only part of the script, I'm only pasting in part of the script that's have errors.

1 answer

✓ Accepted answer

Style

It's easier to deal with good code, and good code has mistakes more obvious.

Tab your code correctly.


:FindFirstChild("Obj") and .Obj both return the object with the given name. The reason why you use :FindFirstChild is in case the object doesn't exist, you get nil instead of an error.

However, if you have code like this:

player:FindFirstChild("PlayerGui").WalkSpeedPass

that benefit is destroyed, because (nil).WalkSpeedPass will result in an error.

If you use :FindFirstChild, you should explicitly deal with nil. If you aren't, then you shouldn't use :FindFirstChild, you should use just use .PlayerGui, or you could use :WaitForChild("PlayerGui").

You also repeat that line three times. Save it ahead of time in a variable.

local frame = player:WaitForChild("PlayerGui").WalkSpeedPass.Frame

You shouldn't use Disabled to control the current script. Just stop working if you want to! break in this case will clean that up.


Use consistent quoting, either ' or ", not both -- it just makes things more complicated than necessary.


Pick good variable names! You don't use i, so just call it _. You should pick a better name than v, maybe perker since it's from a list of Perkers?


Cleaned up

Your code now looks like this:

local passid = 236050258 -- The ID of the gamepass goes here
local GamePassService = game:GetService("GamePassService")
local player = script.Parent.Parent.Parent.Parent.Parent

local frame = player:WaitForChild("PlayerGui").WalkSpeedPass.Frame
while true do
	wait(1)
	for _, perker in pairs(game.ReplicatedStorage.Perkers:GetChildren()) do
		if GamePassService:PlayerHasPass(player, passid) then
			frame.Visible = true
		elseif player.Name == perker.Value then
			warn("Watchme naeynaey")
			frame.Visible = true
		else
			frame.Visible = false
			break
		end
	end
end

Fixing Problems

There's something suspicious here: the for loop has an if with an else. That means you will always take action based on just the first perker. That's probably not what you want.

When any single perker doesn't match, then you don't have to do anything. Just default with the frame invisible.

local passid = 236050258 -- The ID of the gamepass goes here
local GamePassService = game:GetService("GamePassService")
local player = script.Parent.Parent.Parent.Parent.Parent

local frame = player:WaitForChild("PlayerGui").WalkSpeedPass.Frame
while true do
	wait(1)
	frame.Visible = false -- Start hidden
	for _, perker in pairs(game.ReplicatedStorage.Perkers:GetChildren()) do
		if GamePassService:PlayerHasPass(player, passid) then
			frame.Visible = true
		elseif player.Name == perker.Value then
			warn("Watchme naeynaey")
			frame.Visible = true
		end
	end
end

You should probably break when it becomes visible, rather than not. Otherwise there's no reason for the while loop.

Unless you plan on people buying the gamepass while this is running, there's no reason for the while loop at all.

The first if doesn't actually use the perker, so it probably doesn't belong in the for loop. This could be a lot cleaner looking if you used functions:

local passid = 236050258 -- The ID of the gamepass goes here
local GamePassService = game:GetService("GamePassService")
local player = script.Parent.Parent.Parent.Parent.Parent

function hasGamePass()
	return GamePassService:PlayerHasPass(player, passid)
end

function isPerker()
	for _, perker in pairs(game.ReplicatedStorage.Perkers:GetChildren()) do
		if perker.Value == player.Name then
			return true
		end
	end
	return false
end

local frame = player:WaitForChild("PlayerGui").WalkSpeedPass.Frame
while true do
	wait(1)
	frame.Visible = false -- Start hidden
	if isPerker() or hasGamePass() then
		frame.Visible = true
	end
end

The if is actually unnecessary now, since frame.Visible is just going to be the same as the condition.

local passid = 236050258 -- The ID of the gamepass goes here
local GamePassService = game:GetService("GamePassService")
local player = script.Parent.Parent.Parent.Parent.Parent

function hasGamePass()
	return GamePassService:PlayerHasPass(player, passid)
end

functoin isPerker()
	for _, perker in pairs(game.ReplicatedStorage.Perkers:GetChildren()) do
		if perker.Value == player.Name then
			return true
		end
	end
	return false
end

local frame = player:WaitForChild("PlayerGui").WalkSpeedPass.Frame
while true do
	frame.Visible = isPerker() or hasGamePass()
	wait(1)
end

This discussion is preserved as it was. New answers, comments, and votes are closed.