Gui not popping up after first time?

Hello!

I made a script where it makes the game go day and night. When it’s night, it fires a remote event that makes a gui visible. It works the first time, appearing when the day goes to night. However, when the day goes to night again, the gui dosen’t appear. I don’t know what’s even wrong with it. I searched the forums, but couldn’t find anything. I’ve put print statements, but they never printed anything, as if it was never called in the 1st place. (I’m not good at explaining, sorry).

Day and night script (It’s in ServerScriptService)

local minutesAfterMidnight = 14 * 60
local RepStorage = game:GetService("ReplicatedStorage")
local NightEvent = RepStorage:WaitForChild("NightEvent")
local prompt = game.Workspace.Sled2.SledPrompt.ProximityPrompt
local ClearEvent = RepStorage:WaitForChild("ClearEvent")

while true do
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	minutesAfterMidnight = minutesAfterMidnight + .2 -- .2
	wait(.1)
	
	if game.Lighting:GetMinutesAfterMidnight() == 6 * 60 then
		if prompt.Enabled == true then
			prompt.Enabled = false
		end
	end
	
	if game.Lighting:GetMinutesAfterMidnight() == 18.38 * 60 then
		NightEvent:FireAllClients(minutesAfterMidnight)
		ClearEvent:FireAllClients(minutesAfterMidnight)
		if prompt.Enabled == false then
			prompt.Enabled = true
		end
	end
end

NightEvent script (In a localscript where the gui is)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local NightEvent = ReplicatedStorage:WaitForChild("NightEvent")

NightEvent.OnClientEvent:Connect(function(minutesAfterMidnight)
	if gui.Visible == false then
		gui.Visible = true
	end
end)

Just as a general rule, don’t try to compare numbers that have decimal parts directly like this. You won’t always get consistent results.

Also, not sure why you’re firing the ClearEvent and the NightEvent in the second if block.

To fix, try to keep track of when it switches from night to day, not when the hour is some exact number.

I would either:

  1. Split your time changing into two discrete loops (i.e. day loop and night loop) and just call the events between the two loops, or
  2. Instead of comparing numbers directly, you can check if its nighttime every iteration and just fire events when the state changes.

Here’s a rough draft of (2), but (1) is honestly probably a better way:

local RepStorage = game:GetService("ReplicatedStorage")
local NightEvent = RepStorage:WaitForChild("NightEvent")
local prompt = game.Workspace.Sled2.SledPrompt.ProximityPrompt
local ClearEvent = RepStorage:WaitForChild("ClearEvent")

local DAY_START = 6 * 60
local DAY_END = 18.38 * 60
local GAME_TIME_AT_START = 14 * 60

local SECONDS_PER_GAME_HOUR = 60 -- one minute = one hour in game

-- little initialization outside of the loop
game.Lighting:SetMinutesAfterMidnight(GAME_TIME_AT_START)
local mins = game.Lighting:GetMinutesAfterMidnight()
local isNight = mins < DAY_START or mins > DAY_END

while true do
	local mins = game.Lighting:GetMinutesAfterMidnight()
	local isNightNow = mins < DAY_START or mins > DAY_END

	if (!isNight and isNightNow) then
		-- it changed from day -> night
		NightEvent:FireAllClients(mins)
		prompt.Enabled = true
	elseif (isNight and !isNightNow) then
		-- changed from night -> day
		ClearEvent:FireAllClients(mins)
		prompt.Enabled = false
	end

	isNight = isNightNow

	-- using the actual time waited to calculate the number of minutes to advance
	local timeWaited = wait(0.5)
	local amount = timeWaited / SECONDS_PER_GAME_HOUR * 60 -- pretty sure that math's right but idk
	game.Lighting:SetMinutesAfterMidnight(mins + amount)
end

It works, but I only want the GUI to appear only ONCE a night, how do I do that?

I also borrowed the original script from the Roblox Developer Hub Article: Day and Night Article

Fixed it, what I did is divide 5 multiple times to the point where it’s identical to the original day and night movement, and changed 18.38 to 19.