Making a Day/Night Cycle

This is an easy tutorial This is an easy tutorial. < Creating a Script Lighting Parts on Fire > This tutorial is part of a series on scripting. Return to tutorial index

In the previous tutorial we learned how to add a script to a game so we could run code when the game starts. In this tutorial, we will add a script to a game that will cycle the time of day in the game using loops and a streetlight that turns on and off at the appropriate times using conditionals.

Changing Time of Day[edit]

By default ROBLOX does not have a day/night cycle, but we can add one ourselves with a script. First, lets look at how to change the time of day. We will use a function called SetMinutesAfterMidnight:

game.Lighting:SetMinutesAfterMidnight(5 * 60)

Functions, as mentioned in earlier tutorials, are special instructions we can use in code. print is a function we have been using quite often. print is a global function, meaning we can call it whenever we like. Other functions, such as SetMinutesAfterMidnight, are associated with specific types of instances, in this case Lighting. This means if we want to use the function, we have to specify which instance we want to use the function with. This is done similarly to how we change a property of an instance. The only difference is that we separate an instance and a function with at colon : instead of a dot ..

SetMinutesAfterMidnight is pretty straightforward as far as functions go. We simply put a number between the two parenthesis after the number to indicate how many minutes after midnight we want to set the world to. The above code would set the time to 5AM (as 5 times 60 minutes is 5 hours).

We can change the time of day several times in a row:

game.Lighting:SetMinutesAfterMidnight(5 * 60)
game.Lighting:SetMinutesAfterMidnight(6 * 60)
game.Lighting:SetMinutesAfterMidnight(7 * 60)
game.Lighting:SetMinutesAfterMidnight(8 * 60)
game.Lighting:SetMinutesAfterMidnight(9 * 60)

The above code changes the time from 5AM, then 6AM, then 7AM, and so on. But there is a problem. If we run the game right now, the time will instantly change to 9AM. Why does this happen? Why didn't we see the other changes?

It turns out that the game did change the time of day several times as we instructed, it just did it so fast we couldn't see. When a game runs a script, it runs it as fast as it can. Most instructions will only take a mere fraction of a second, far too quick for us to notice. In order to see the changes take place over a time span we can actually see, we need to make the script pause between each change. To do that, we will use a global function called wait:

game.Lighting:SetMinutesAfterMidnight(5 * 60)
wait(1)
game.Lighting:SetMinutesAfterMidnight(6 * 60)
wait(1)
game.Lighting:SetMinutesAfterMidnight(7 * 60)
wait(1)
game.Lighting:SetMinutesAfterMidnight(8 * 60)
wait(1)
game.Lighting:SetMinutesAfterMidnight(9 * 60)

Whenever we call wait in a script, we are giving the script the instruction to pause for the amount of time we specified (in seconds). In the above code, the script will pause for one second between each time change, which gives us enough time to notice the day progressing.

Looping[edit]

The above code work fine over a very short period of time, but what if we wanted the time of day to keep changing for minutes? Hours? We would need to write thousands of lines of code. There is fortunately a very simple alternative that we can use to avoid this called looping.

A loop is a segment of code that repeats itself over and over until a certain condition is met; Some loops can even run indefinitely until the game stops. One loop that can loop indefinitely is a while loop. Take a look at the following example:

number = 0
while true do
	number = number + 1
	print(number)
	wait(1)
end

The first line of the script simply makes a variable called number and stores the value 0 in it. The second line sets up a loop: while is the type of loop and true is the condition for the loop to repeat. Since we don't want the loop to ever end, we can just say true here and the loop will continue forever (we will go over stopping a loop in a future tutorial). The code in between do and end is all the code we want to repeat. In this case, 1 will be added to the value inside of number, and that sum will be stored back into number. We then print out number and tell the script to wait for one second. After that, the loop will repeat itself starting with adding 1 to number.

Loops, like the one above, that repeat themselves indefinitely are called infinite loops. They can be very useful, but you have to be careful when you use them. Anytime you have an infinite loop in your game like the one above, you must include a wait function call somewhere in the code that gets repeated. If you do not, your game will crash.
Notice how the code inside of the while loop above is shifted to the right. This is called indenting, which is a common convention in coding. Indentation doesn't change how the code runs, it is just a way of formatting your code to make it easier to read. Whenever you have a block of code inside of something like a loop, conditional, or function, indent it like above so it is easier for you and others to understand what you wrote. You can indent using the Tab ⇆ key.

Let's see how we can use a loop like above to cycle the day and night.

minutesAfterMidnight = 0
while true do
	minutesAfterMidnight = minutesAfterMidnight + 1
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	wait(.1)
end

In this code we keep track of the time with the variable minutesAfterMidnight. In every cycle of the loop we increase the value in minutesAfterMidnight by 1 and then update the time using SetMinutesAfterMidnight. We then wait 1/10th of a second to make the script pause before repeating the loop. If you let the game run for a bit now you will see the day gradually change from night to day.

You can make the day/night cycle faster or slower in the above code by changing the number added to minutesAfterMidnight. If you want the day to cycle faster, simply add a bigger number. If you want the day to take longer, add a smaller number.

Adding a Streetlight[edit]

Let's add a streetlight to our game. This light will turn on at night and off during the day. First construct the light:

Scripting4Lamp.png

Make sure the part we want to illuminate is named LightPart. This part should have the neon material so it appears to glow. Also insert a PointLight into the part so that it emits light on the parts around it. Feel free to play with the Color, Brightness, and Range of the PointLight so it creates the effect you want.

Scripting4LampExplorer.png

Now, let's modify our script above to turn off the light during the day. Specifically, we will turn the light off at 6AM. We will also speed up the time of day cycle so we can quickly test the code.

lightPart = game.Workspace.LightPart
minutesAfterMidnight = 0
while true do
	minutesAfterMidnight = minutesAfterMidnight + 10
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
 
	if game.Lighting:GetMinutesAfterMidnight() == 6 * 60 then
		lightPart.Material = Enum.Material.Plastic
		lightPart.PointLight.Enabled = false
	end
 
	wait(0.1)
end

We start by making a variable for the LightPart. In our loop we add something called an if statement. An if statement runs code only if a certain condition has been met. In this case, we want to check it the time of day is 6AM. To check if two things are equal in Lua, we use two equal signs ==. The code between then and else will run only if the number of minutes after midnight is exactly the same as 6 * 60 (= 6 hours). If we run the code now we will see the light will become plastic and the PointLight inside will stop shining.

To turn the light on again at the end of the day, we can simply follow up with another if statement:

lightPart = game.Workspace.LightPart
minutesAfterMidnight = 0
 
while true do
	minutesAfterMidnight = minutesAfterMidnight + 10
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	wait(0.1)
 
	if game.Lighting:GetMinutesAfterMidnight() == 6 * 60 then		-- checks for 6AM
		lightPart.Material = Enum.Material.Plastic
		lightPart.PointLight.Enabled = false
	end
	if game.Lighting:GetMinutesAfterMidnight() == 18 * 60 then		-- checks for 6PM
		lightPart.Material = Enum.Material.Neon
		lightPart.PointLight.Enabled = true
	end
end

Our game can now cycle through the day and night, and we have a light that automatically turns itself on and off! In the next tutorial we will cover how to use events to light parts on fire and then douse them.

This is an easy tutorial This is an easy tutorial. < Creating a Script Lighting Parts on Fire > This tutorial is part of a series on scripting. Return to tutorial index