BoolValue not changing?

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 have a game where there’s an intermission, a round, and then the players get teleported back. This repeats over and over.
  2. What is the issue? Include screenshots / videos if possible!
    The BoolValue “Intermission” does not change when I set it to false. It prints out false, however when I check the status it stills says true. It doesn’t run anything.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’m not sure as to what may be causing this. If anyone has any suggestions please let me know. This is in a ModuleScript by the way.
    After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
local mod = {}

local TeleportTo = game.Workspace.Map.Environment.Stage:FindFirstChild("TeleportTo")
local Arena = game.Workspace.Map.Environment.Stage:FindFirstChild("Arena")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Values = ReplicatedStorage:FindFirstChild("Values")
local Intermission = Values:WaitForChild("Intermission")
local InRound = Values:WaitForChild("InRound")
local Countdown = Values:WaitForChild("Countdown")


mod.RoundInProgress = function(Players, Status)
	while true do
		task.wait()
		if #Players:GetPlayers() >= 3 then
			Intermission.Value = true
			for i = 30, 1, -1 do
				Status.Value = "Intermission: "..tostring(i)
				task.wait(1)
			end
			Intermission.Value = false
			for i, player in pairs(Players:GetPlayers()) do
				local Character = player.Character or player.CharacterAdded:Wait()
				
				if Character then
					local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
					
					if HumanoidRootPart then
						HumanoidRootPart:PivotTo(TeleportTo.CFrame)
					end
				end
			end
			if Arena then
				task.spawn(function()
					while true do
						task.wait(1)
						Arena.BrickColor = BrickColor.random()
					end
				end)
				
				Countdown.Value = true
			end
		end
	end
end


return mod

This is happening because right after you set the Intermission value to false, the next few blocks of code will execute within milliseconds and then the next iteration will begin, which sets the Intermission value to true again.

2 Likes

So, what can I do to solve this? Add a wait?

Your game logic is wrong.

It should go like this:
IntermissionRound StartRound EndIntermissionRound Start → …

In your case right now it’s doing:
IntermissionIntermissionIntermission → …

You should wait for a sign that the round has ended before running the next intermission.

2 Likes

You can set the Intermission value to true in the for loop.

Shouldn’t the for loop run first, and when it finishes it continues.

The thing is the Intermission value will always (~approx) be true. In the code, after setting it to false, the players for loop won’t take much time to finish executing so then the for loop will finish and then the whole while loop executes again, setting the Intermission value to true and waiting 30 seconds until it sets it to false until the player for loop finishes executing.

2 Likes
mod.RoundInProgress = function(Players, Status)
	while true do
		task.wait()
		if #Players:GetPlayers() >= 3 then
			Intermission.Value = true
			for i = 30, 1, -1 do
				Status.Value = "Intermission: "..tostring(i)
				task.wait(1)
			end
			Intermission.Value = false
			for i, player in pairs(Players:GetPlayers()) do
				local Character = player.Character or player.CharacterAdded:Wait()
				
				if Character then
					local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
					
					if HumanoidRootPart then
						HumanoidRootPart:PivotTo(TeleportTo.CFrame)
					end
				end
			end
			if Arena then
				task.spawn(function()
					while true do
						task.wait(1)
						Arena.BrickColor = BrickColor.random()
					end
				end)
				
				Countdown.Value = true
				
				task.wait(1)
				Arena.CanCollide = false
				
				Target.Touched:Connect(function(Hit)
					local Player = Players:GetPlayerFromCharacter(Hit.Parent)
					
					if Player then
						Winner.Value = Player.Name
					end
				end)
				
				if Winner.Value then
					Intermission.Value = true
				end
			end
		end
	end
end

I’m going to restart the whole thing. Cause I’m not sure what to do.

So do I put a wait to fix this or no?

doesnt you have any other scripts that is cahnging the bool?
as I see from description, it will be client server problem

You could add a new BoolValue called RoundEnded and wait for it to be true, once it is true it would begin the next intermission.

Here’s a simple refactor of what I described earlier:

-- Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Values
local Values = ReplicatedStorage.Values :: Folder
local Status = Values.Status :: StringValue
local Intermission = Values.Intermission :: BoolValue

-- Game Module
local Game = {}

Game.Intermission = function()
	-- wait until there's the minimum amount of players
	repeat task.wait() until #Players:GetPlayers() >= 3
	
	-- set the intermission value to true
	Intermission.Value = true
	
	for i = 30, 1, -1 do
		Status.Value = "Intermission: "..tostring(i)
		task.wait(1)
	end
	
	Intermission.Value = false
	
	-- start the round
	Game.RoundStart()
end

Game.RoundStart = function()
	-- do stuff related to the round
	
	
	-- transition to the round end
	Game.RoundEnd()
end

Game.RoundEnd = function()
	
	-- move to intermission
	Game.Intermission()
end

return Game
2 Likes

Thank you for that. I’ve never actually made a round system before.

Of course, if you find this interesting and want to learn more about it, I recommend you to learn about the State Machine model, which is basically what I showed you but in a more simplified/easier manner.

2 Likes

So after that do I just put each function in a loop like this?

while true do
	task.wait(1)
	RoundModule:Intermission(Players, Status, IntermissionLength, Intermission)
end

No, you don’t need a loop. The code I provided you will be looping throughout the game.

Game.Intermission() will call Game.RoundStart()
Game.RoundStart() will call Game.RoundEnd()
Game.RoundEnd() will call Game.Intermission()

It’s a game life-cycle.

2 Likes
function mod:EndRound(Players, Target, Winner)
	Target.Touched:Connect(function(Hit)
		local Player = Players:GetPlayerFromCharacter(Hit.Parent)
		
		if Player then
			Winner.Value = Player.Name
		end
	end)
end

IT WORKS! THANK YOU SO MUCH! I forgot to teleport the players lol! I just need to make a skydiving system now