How to keep track of days in a day-night cycle?

I’ve used this post to get started with making a day-night cycle since I’ve never done one before and I tried to add on to it by keeping tracking of how many days go by (1 day is 10 minutes) and also when it’s night or morning since I have certain game mechanics the rely on that, however, I’d like to get some help on how I could implement better code for actually doing that lol.

local mam
local dayLength = 30 --600 --10 minutes
local timeBetweenUpdates = 1/30
local timeShift = 1440/(dayLength/(timeBetweenUpdates)) --increases the lightings time
local currentDay = 1
local deb = true
local isNight = false

--I added this
Lighting:GetPropertyChangedSignal("ClockTime"):Connect(function()
	if math.floor(Lighting.ClockTime) == 19 and not isNight then
		warn("NIGHT")
		isNight = true
	end
	
	if math.floor(Lighting.ClockTime) == 5 and isNight then
		warn("MORNING")
		isNight = false
	end
end)

coroutine.wrap(function()
	while true do
		mam = game.Lighting:GetMinutesAfterMidnight() + timeShift
		mam = mam/60

        --probably gonna do this on the client at some point
		local tweenInfo = TweenInfo.new(timeBetweenUpdates, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
		local goal = {ClockTime = mam}
		local tween = TweenService:Create(Lighting, tweenInfo, goal)
		tween:Play()

        --I also added this
		if math.floor(mam) == 0 then
			if deb then
				deb = false 
				currentDay += 1
				warn("DAY: "..currentDay)			
			end
		else 
			deb = true
		end

		wait(timeBetweenUpdates)
	end	
end)()

you could just check how many times the clock has passed 24:00

I tried removing unnecessary code and cleaning parts of your script, it should now work as expected:

local TweenService = game:GetService("TweenService") 
local Lighting = game:GetService("Lighting") 

local dayLength = 30 --600 = 10 minutes
local timeBetweenUpdates = 1/30
local timeShift = 1440*timeBetweenUpdates/dayLength --increases the lightings time(simplified the equation) 
local currentDay = 1

--debounces
local isNight = false
local dayChanged = true

--coroutine wasn't needed, although if you run code under the loop you should add it back
while true do
	local mam = Lighting:GetMinutesAfterMidnight() + timeShift
	local hour = mam/60

	--move the tween code to the client, it will probably cause unnecessary lag to the server
	local tweenInfo = TweenInfo.new(timeBetweenUpdates, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
	local goal = {ClockTime = hour}
	local tween = TweenService:Create(Lighting, tweenInfo, goal)
	tween:Play()
		
	if hour >= 19 and not isNight then 
		isNight = true 
		dayChanged = false 
		warn("NIGHT") 
	elseif hour >= 5 and hour <= 19 and isNight then 
		isNight = false 
		warn("MORNING")
	elseif hour >= 0 and not dayChanged then 
		dayChanged = true 
		currentDay += 1
		warn("DAY: "..currentDay)
	end

	task.wait(timeBetweenUpdates)
end	
2 Likes

This part seems to be incorrect(?)

	elseif hour >= 0 and not dayChanged then 
		dayChanged = true 
		currentDay += 1
		warn("DAY: "..currentDay)
	end

It seems to increase the day as soon as it turns night so I just changed to math.floor(hour) == 0. Also, the coroutine was needed because I have this code in a module.

Anyways this seems a lot cleaner thanks for the help.

1 Like