WinnerScript colour randomiser causing issues

I’ve been sitting on this question for months, waiting to be granted membership. Please be gentle as this is my first topic. I apologise if I break any forum etiquette in where / how I ask for help.

  1. What do you want to achieve? Keep it simple and clear!
    I have a script that creates a pop up screen with sound effect when a player has a certain gamepass. This occurs on purchase, and at each subsequent spawn.

  2. What is the issue? Include screenshots / videos if possible!
    While the script ostensibly seems to work, I am worried it may be causing performance issues (I’m new to Dev, don’t know how to phrase it … I feel phrases like ‘memory leaks’, ‘loops not getting closed’, ‘things getting duplicated’ might be close to describing the problems I don’t have the vocabulary to express). I think they may tie in to my main issue:

I have written a loop that randomisers the colour of the text in the pop up. Although the script works as intended currently, I feel there must be an error as I am unable to place any further code following this loop inside the ‘local function’ which is responsible for creating and closing this pop up.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have constructed a ‘working’ iteration of the script through searches on Dev hub and other resources, but I am looking ways to resolve the issues mentioned above.

I’ve included the script below, it’s really hacked together from various tutorials, so I apologise if it is rough. Any general suggestions to improve polish would be of course also welcome.

Summary
-- NOTE: Change this to the Game Pass ID found in your web browser
local GAMEPASS_ID = 10128546

local player = script:FindFirstAncestorWhichIsA("Player")

local function closewindow ()
	print("close window")
end
 
-- Gives the player an effect whenever they buy that game pass
local function enableGamePassEffect()

	
	-- Insert effects for the game pass here
	local winnerscreen, text, sound, button = Instance.new('ScreenGui'), Instance.new('TextLabel'), Instance.new ('Sound'), Instance.new ('TextButton')
	winnerscreen.Parent = player.PlayerGui
	sound.Parent = player.PlayerGui
	sound.SoundId= ("rbxassetid://"..12222253)
	sound.Playing = true
	text.Parent = winnerscreen
	text.BackgroundTransparency = (1)
	text.BorderSizePixel= (0)
	text.Text = ('You Win!')
	text.TextScaled = true
	text.Position = UDim2.new(.4,0,.40,0)
	text.Size = UDim2.new(.2, 0, .2, 0)
	button.Parent = text
	button.BackgroundTransparency = (1)
	button.BorderSizePixel= (1)
	button.Text =('X')
	button.TextScaled = true
	button.Position =UDim2.new (.99,0,0,0)
	button.Size = UDim2.new (.1,0,.1,.0)
	button.SizeConstraint = Enum.SizeConstraint.RelativeXX
	button.TextColor3 = Color3.new (1,0,0)
		local function closewindow ()
		winnerscreen:Destroy()
		end
	button.MouseButton1Click:Connect(closewindow)
		while true do --random color generator adding script to the enableGamePassEffect function after here gets glitchy
			local r = math.random()
			local g = math.random()
			local b = math.random()
			text.TextColor3 = Color3.new (r, g ,b)
			wait (.1)
		end

end


--================DO NOT EDIT UNDER HERE ===============================
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local HasGamepassChecker = require(ReplicatedStorage:FindFirstChild("HasGamepassChecker"))
local MarketplaceService = game:GetService("MarketplaceService")
 
-- Checks if the player has the game pass when the game starts. 
if HasGamepassChecker:getPlayerHasPass(player.UserId, GAMEPASS_ID) then
	print("player has pass")
	enableGamePassEffect()

else
	print("player either doesn't have pass or there was an error and player didn't want to retry")
end
 
-- Checks if the player purchases the game pass during the game
local function onPromptGamePassPurchaseFinished(player, purchasedPassID, purchaseSuccess)
	if purchaseSuccess == true and purchasedPassID == GAMEPASS_ID then
		print("player has pass")
		enableGamePassEffect()
	else
		print("player either doesn't have pass or there was an error and player didn't want to retry")
	end
end
 
MarketplaceService.PromptGamePassPurchaseFinished:Connect(onPromptGamePassPurchaseFinished)


Yeah, your problem is the while true do loop. You might be able to tell that it never ends. Thus, any code that you write under it in the same thread will not execute since your loop is still running.

So you’ll need to run that loop in a separate thread. spawn is not usually recommended but you’ll be okay using it for now. You can search for spawn on this page to read more about it. Essentially, you can run yielding code (like an infinite loop) at the same time as your other code.

Here’s a hint for what you’ll need to do:

spawn(function()
    while true do
        print("okay!")
    end
end)
print("ahh!")
1 Like

FYI: You don’t need to always put the while loop in a separate thread here, infact you only need to once.

See where it’s called here:

It’s blocking the rest of the code but this can be quickly averted by using a coroutine. Preferably, I like to use wrap:

coroutine.wrap(enableGamePassEffect)();

Now it’s separately running in its own thread, not blocking anything.

Later on where the function is called in the connected function, that’s in its own separate thread as well anywho since its internally called.


Like to know more on coroutines? See here:

1 Like

Thank you for your suggestions, good people.

I shall play around with each to work out which is the most expedient solution.

For the time being I removed the lines ‘while true do’ and ‘end’, so each time the screen it is presented it is in a random font colour, rather than flashing random colours.

I look forward to testing your solutions to return the end user display to it’s intended flashy function.

Is it a problem that the code loop never ends? Especially if the script has already completed it’s purpose, and there isn’t any further code after it which would need to be executed?

Is there a way to check if this loop continues to run or gets duplicated each time the player spawns? It is located in StarterGui in case that is relevant.

Would I really need to make a coroutine for the entire gamepass effect? Surely that won’t solve the problem of adding extra code to the effect underneath the color randomiser?

Surely only the color randomise loop part of the gamepass effect would need to be wrapped up in its own coroutine?

Eitherall works, as long as the while loop runs in a separate thread. I would preferably wrap the entire function though.