Change of day-night cycle

I wrote a working script for changing the day and night cycle. I know that it is very poorly written, I am interested in how it can be improved so that it works better. Your suggestions

local player=game:GetService("Players")
local lightService=game:GetService("Lighting")

local timeClockSpeed=1

local function updateCycle()
	for time=10,15,.03 do
		lightService.ClockTime=time
		task.wait(timeClockSpeed)
	end
end

player.PlayerAdded:Connect(function(player)
	while true do
		updateCycle()
	end
end)
5 Likes

Well if it’s a server-sided script then you could just do

local speed = 1

game:GetService("RunService").Heartbeat:Connect(function(dt)
	game.Lighting.ClockTime = time()*speed
end)
2 Likes

That’s not bad, but your script is not looping.

3 Likes

What?? Did you even read the code? The RunService.Heartbeat event is fired every frame, so yes, it will be looping once tested. Did you test it to see?

3 Likes

I want to ask you the same thing. Have you tested it? If so, you should have noticed that this script only loops twice because the time() function returns the time in seconds since the epoch (January 1, 1970). This value is constantly increasing, and when it is multiplied by speed, it becomes a very large number. As a result, the value of game.Lighting.ClockTime quickly goes through all 24 hours (from 0 to 24), which causes a rapid change of day and night. Since speed is set to 1, this happens twice per time cycle, which causes a double change of day and night.

This is what a cyclic script should be like:

local speed = 1

game:GetService("RunService").Heartbeat:Connect(function(dt)
	game.Lighting.ClockTime = (time() * speed) % 24
end)
5 Likes

Ohh, okay., my bad. I immediately assumed that because it was a Heartbeat event that it would be looping. Thanks for the info, lol. I also can’t test it because my studio currently isn’t working for me. Otherwise, I would have tested it to see.

2 Likes

I was confused when I saw this at first but this is genious

if t < 24 then CT = t
if t > 24 then CT = t % 24
if t = 24 then CT = 0

…which then goes into a loop since the first condition will be met again, the second condition will be met, and then the third.

example : [10 % 24] → {10}, [24 % 24] → {0}, [25 % 24] → {1}

2 Likes

What would you do to make a set time while having the loop not break?

My implementation of your question, if that’s what you’re asking:

local speed=.005
local startTime=6
local startTimeOffset=startTime/24

game["Run Service"].Heartbeat:Connect(function()
	local currentTime=(time()*speed+startTimeOffset)%1*24
	game.Lighting.ClockTime=currentTime
end)

P.S. Using game[“Run Service”] is not a good practice, better to just use game:GetService(“”).

2 Likes

why are you dividing the startTimeOffset by 24, and why are you using the modulo operator on everything before it and then multiplying that by 24?

To limit the cycle of day and night, in my case I needed this.

So if I was to remove those to part, and leave it as (0(1) + 8) % 24 , would this be able to achieve the same thing?

0 → time
1 → speed
8 → startTime / beginningOfTheDay

Your suggested expression (0(1) + 8) % 24 can be used to achieve the same result as in my script. However, keep in mind that 8 here refers to the start time at 8am, while my script uses startTime for the start at 6am. If you need the start time at 8am, you can use your suggestion. The speed must remain the same as in my script if you want to keep the current flow of time.

Did I understand your question correctly?

2 Likes

Yeah, that answered it correctly, thanks!

But one last question,

is it possible to set the base time to eight, then have the day-night cycle play out without immedietly setting the time back to zero? Because although it does give me my desired results, adding eight basically made the new “Morning” eight instead of zero, due to the fact that the clocktime does an entire twenty four hours due to the fact that theres a full 24 hours after eight, which can just be simplified by 8 + 24 → 32 % 24 = 8 . It’s a bit nitpicky, but I prefer the clocktime resetting to zero rather than eight.

If you want to set the base time to 8am and have a day/night cycle without the time resetting to zero, you can make a small change to the script. Your approach of adding 8 to the current time and then taking the remainder of dividing by 24 (currentTime = (time() * speed + 8) % 24) is really good for this purpose. It will allow you to start a new day at 8am without resetting the time to zero.

I find it’s most pleasant to use TweenService for day-night cycles, due to all of the headaches surrounding floating point imprecision. TweenInfo has a RepeatCount property, which can be set to -1 to create a looping tween; and Lighting.ClockTime resets to zero once it hits 24. So it’s as simple as creating a tween over Lighting.ClockTime, using TweenInfo.Time to specify how many seconds are in a day, and then playing it. A preliminary tween can be used to get on cycle, for a specified arbitrary start time.

I don’t think using TweenService for this specific purpose is a good idea. It will work, the only problem is that TweenService is very poorly optimized and it is possible that in a large game where there are already a lot of scripts and other things, this can cause additional lags. In my opinion, in this example it is better to use math with RunService.

I don’t understand why it should be any less performant. We’re talking about a single Tween, which linearly interpolates a single number value in lighting. Any difference in cost between this approach, and your current, should be entirely negligible—the comparable complexity, likewise independent of your game’s size, as lighting would still be updating at the same rate regardless. What exactly is the concern here?

No; actually, you are saying that. Your entire last post was to tell me that TweenService was “very poorly optimized”; and that it’s possible it might “cause additional lags”. When you write this, you are—on no apparent basis, making the definitive claim that my approach jeopardizes performance. And this simply isn’t true. Any way you slice it, you are not making any considerable optimizations by preferring your current method. If you just like the way it looks, that’s fine. But that’s a very different takeaway from what you were just implying.

I’m not saying you can’t do it this way, the difference may be minor. I like my way better than using TweenService.