Hello, I’m wanting to have this code run each time that a player clicks on the cardslot, and not just one time, but whenever I apply the loop to my code, it ends up running out my timer quickly, and when I try to stop the test session, my studio ends up crashing.
I am a fairly newer scripter, so some of the methods I applied here might not be the best.
For the timer portion of the script, I use a while true do loop that gradually subtracts 1 from a Number value I have in a Values folder as long as there hasn’t been more than 50 balls dropped and the time value is above 0.
The script works just fine otherwise.
I did try searching on the dev forum, but I didn’t see anything that said ways to prevent a loop from crashing outside of applying a wait, although I found that the game runs normally if I put the wait value at 15, although the studio still crashes when I try and stop the test session, and the script doesn’t allow for the machine to be played afterward.
Here is my code below. I would appreciate any help.
---Variables
local CardReader = script.Parent.CardReader
local CardReaderText = CardReader.Cardslot.SurfaceGui.TextLabel
local DeadZone = script.Parent.DeadZone
local Button = script.Parent.Button
local GameboardText = script.Parent.GameBoard.Gameboard.SurfaceGui.TextLabel
local JackpotDisplay = script.Parent.Jackpot.JackpotDisplay.SurfaceGui.TextLabel
local Balls = game.ServerStorage.Balls
local VALUES = script.Parent.Values
local ControlGame = script.Parent.Button.button.ControlGame
local DropZones = script.Parent.RotatingPlatforms.DropZones
local function VictorySequence()
VALUES.LastGameWon.Value = true
GameboardText.Text = "You've hit the jackpot of " .. #VALUES.Jackpot.Value.. " tickets! Congratulations!"
wait(15)
repeat
VALUES.VictorySequenceTime.Value = VALUES.VictorySequenceTime.Value - 1
wait(1)
until VALUES.VictorySequenceTime.Value == 0
repeat
local ballcopy = Balls:Clone()
ballcopy.Parent = game.Workspace
ballcopy.Anchored = false
wait(.2)
until VALUES.VictorySequenceTime.Value == 0
if VALUES.VictorySequenceTime.Value == 0 then
VALUES.JackpotValue.Value = VALUES.DefaultJackpotValue.Value
JackpotDisplay = VALUES.DefaultJackpotValue.Value
VALUES.GameFinished.Value = false
VALUES.VictorySequenceTime.Value = 30
end
end
JackpotDisplay.Text = VALUES.JackpotValue.Value
---Game Code
function StartGame()
while true do
wait(10)
CardReader.Cardslot.ClickDetector.mouseClick:Connect(function(hit)
if VALUES.IsPlaying.Value == false then --- Checks that nobody is playing the machine
CardReaderText.Text = "Enjoy your game!"
wait(2)
CardReaderText.Text = "Game in progress."
VALUES.IsPlaying.Value = true
end
end)
VALUES.IsPlaying.Changed:Connect(function()
if VALUES.IsPlaying.Value == true then
VALUES.AmountDropped.Value = 0 ---Resetting previous game's values
VALUES.TouchedJar.Value = 0
end
VALUES.LastGameWon.Changed:Connect(function()
if VALUES.LastGameWon.Value == true then
VALUES.JackpotValue.Value = VALUES.DefaultJackpotValue.Value
JackpotDisplay = VALUES.JackpotValue.Value
end
end)
GameboardText.Text = "Welcome to Quik Drop!"
wait(4)
GameboardText.Text = "The goal is to drop all 50 balls into the bucket before the time runs out."
wait(4)
GameboardText.Text= "If you drop all 50 balls into the bucket, you will win the Jackpot!"
wait(4)
GameboardText.Text = "Good luck!"
wait(4)
ControlGame.Disabled = false
while VALUES.Timer.Value > 0 and VALUES.AmountDropped.Value < VALUES.MaximumBallCount.Value do
VALUES.Timer.Value = VALUES.Timer.Value - 1
GameboardText.Text = VALUES.Timer.Value
wait(1)
end
if VALUES.AmountDropped.Value >= VALUES.MaximumBallCount.Value or VALUES.Timer.Value == 0 then
ControlGame.Disabled = true
Balls.Parent = game.ServerStorage
VALUES.GameFinished.Value = true
if VALUES.GameFinished.Value == true then
GameboardText.Text = "The game has finished! Let's see how you did!"
wait(4)
if VALUES.TouchedJar.Value < VALUES.BallsNeeded.Value then
GameboardText.Text = "It looks like you did not quite get all 50 balls."
wait(4)
GameboardText.Text = "You got "..VALUES.TouchedJar.Value.. " balls in the bucket."
wait(4)
GameboardText.Text = "Try again next time!"
wait(4)
VALUES.JackpotValue.Value= VALUES.JackpotValue.Value + 5
JackpotDisplay.Text = VALUES.JackpotValue.Value
GameboardText.Text = "Quik Drop"
print (JackpotDisplay)
elseif VALUES.TouchedJar.Value == VALUES.BallsNeeded.Value then
VictorySequence()
end
end
end
end)
end
end
StartGame()
It might be because you’re adding more connections to your events every time you go through a loop, taking up a lot of memory, and also lagging out the game whenever those evens fire. You only need to connect the functions once, not continuously.
I have a feeling that might be caused by the touched events I have in some of my other scripts, which are meant to destroy the balls whenever it comes into contact with a dropzone or a deadzone. I’ll show them under this comment, the only difference between them is that one of them adds to a value if it hit a dropzone. I’ll also go ahead and see if I can get a screenshot of the memory in the dev console.
Balls = game.ServerStorage.Balls
script.Parent.Touched:Connect(function(hit)
if Balls then
wait(.2)
hit:Destroy()
end
end)
local Balls = game.ServerStorage.Balls
local VALUES = script.Parent.Parent.Parent.Parent.Values
local debounce = false
script.parent.Touched:Connect(function(hit)
if not debounce then
debounce = true
wait(.2)
hit:Destroy()
VALUES.TouchedJar.Value = VALUES.TouchedJar.Value + 1
debounce = false
end
end)
Here is what shows up in the memory on the console. it seems to spike up a little bit when I start dropping balls, then it goes down when the game detects that the game is finished and flatlines around 45.275 mb.
The game lasts for 30 seconds and stops when either all 50 balls are dropped or the timer runs out. Here is part of the script I posted before with that section of the code here:
while VALUES.Timer.Value > 0 and VALUES.AmountDropped.Value < VALUES.MaximumBallCount.Value do
VALUES.Timer.Value = VALUES.Timer.Value - 1
GameboardText.Text = VALUES.Timer.Value
wait(1)
end
if VALUES.AmountDropped.Value >= VALUES.MaximumBallCount.Value or VALUES.Timer.Value == 0 then
ControlGame.Disabled = true
Balls.Parent = game.ServerStorage
VALUES.GameFinished.Value = true
Nothing seems wrong with this code either, except that the if statement is redundant, as the while loop only breaks when the if statement is true.
Back to the first code, in StartGame, why exactly do you need the first while true do? It doesn’t seem to be doing anything except reconnecting events that were already connected.
I had put the while true do loop there in an attempt to see if that would allow for the player to play the machine more than once, since atm it only works once and doesn’t trigger again even after clicking the cardslot. Like I said in my OP, I am fairly newer to scripting, so there could be something I’m missing here that I don’t realize yet.
when you connect a function to an event,
(e.g.
CardReader.Cardslot.ClickDetector.mouseClick:Connect(function(hit)
…
end)
)
The connection doesn’t go away when the event is triggered. Instead, every time the event is triggered, it’ll run the same code. by constantly connecting the events every 10 seconds, you’re telling the game to run the code multiple times when the event is triggered, which can really ruin a lot of stuff, let alone the fact that more connections means more memory usage, and continuously adding connections without removing old ones can cause memory leak.
The connection doesn’t go away when the event is triggered. Instead, every time the event is triggered, it’ll run the same code. by constantly connecting the events every 10 seconds, you’re telling the game to run the code multiple times when the event is triggered
Is this true when you have 2 scripts that take the same input to activate an event? I just tried applying a debounce to both the cardslot code and the game control code, and it did reduce the memory usage to the range of 41-43 mb on a few test sessions, and it didn’t crash, but still didn’t loop.
The game doesn’t loop because nowhere in your code do you set IsPlaying.Value back to false, so when the player clicks on the cardslot again, it sees that IsPlaying.Value == true and does nothing,
I want to point something out that’ll give you problems in a minute, your connection to IsPlaying.Changed that actually starts the game takes into account when the game was being started or stopped only for resetting values, and not for actually starting the game. This means that when you do set IsPlaying.Value back to false, it’ll start the game as if you set it to true. I recommend putting this at the start of the function you’re connecting to stop it from running when the game is stopped:
if VALUES.IsPlaying.Value == false then
return
end
Yeah, I was about to apply that before I saw your response, thanks for the help, although I feel dumb for missing something that was so simple as forgetting to set a value back to false. I still have a learning curve to follow
Don’t worry about forgetting stuff, I forgot that return is for functions and break is for loops when writing that response. Anyways, you might also want to connect LastGameWon.Changed outside of IsPlaying.Changed, as it’ll reconnect every time the game starts and lead to memory leak.
Anyways, you might also want to connect LastGameWon.Changed outside of IsPlaying.Changed, as it’ll reconnect every time the game starts and lead to memory leak.
I don’t know why that didn’t work, but I guess you can also try putting the part of the function that starts the game inside the if statement that checks if the value is true, you would only start the game if the game is being set to being played. You can also add print statements nearby to probe the code to see which parts run and which parts don’t.
Ok, so I tried adding a check that requires a bool value to be true along with the IsPlaying bool value and now it doesn’t trigger the intro sequence, and no errors in output. The value I added is changed though.
CardReader.Cardslot.ClickDetector.mouseClick:Connect(function(hit)
if VALUES.IsPlaying.Value == false then --- Checks that nobody is playing the machine
CardReaderText.Text = "Enjoy your game!"
wait(2)
CardReaderText.Text = "Game in progress."
VALUES.IsPlaying.Value = true
VALUES.PassedCardReader.Value = true
end
end)
VALUES.LastGameWon.Changed:Connect(function()
if VALUES.LastGameWon.Value == true then
VALUES.JackpotValue.Value = VALUES.DefaultJackpotValue.Value
JackpotDisplay = VALUES.JackpotValue.Value
end
end)
end
if VALUES.IsPlaying.Value and VALUES.PassedCardReader.Value == true then
VALUES.AmountDropped.Value = 0 ---Resetting previous game's values
VALUES.TouchedJar.Value = 0