i have 0 knowledge on how to program this thing where to start and what to do — You, probably
Open Minecraft, go into a singleplayer creative world, then place down an "Advanced Mining Turtle". A turtle is essentially a robot that can move around, break and place blocks, and a couple of other things depending on what tools you give it.
Then right click on the turtle to open its UI.
Welcome to the shell, also known as the command prompt. It looks way scarier than it is.
The only thing you can do from the shell is run programs by typing the program's name and hitting enter.
Computers come with a couple dozen pre-written programs, but soon we'll be writing our own and the shell is also where we'll be running them from.
For now the only program we care about is lua so let's run that:
Welcome to the lua repl. This is a place where we can directly write and immediately run lua code. It's useful for experimentation as we can run individual lines of code one by one to see what they do, and later once we've figured out what we want the turtle to be doing we can write an entire program.
In Lua every capability of the computer is represented as a function. Functions have names and can be called in order to do their corresponding action. The words "calling", "executing" and "running" are all essentially synonyms.
The syntax for calling a function in lua is the following: functionName(argument1, argument2, argument3, etc...)
In the above functionName stands for the name of the function we'll be calling. After that follows an opening parenthesis, and then any number of arguments.
Arguments (also known as parameters) are additional information we can give to the function with which we can specify exactly what it should be doing.
A lot of functions don't accept any arguments, in which case the syntax would just be functionName().
Fearing that the above might be too much text, let's start writing some code.
What turtle.dig() does should be pretty clear from the name of the function:
Specifically this mines the block in front of the turtle, there's also turtle.digDown() and turtle.digUp() for the other two directions:
Similarly we have turtle.place(), turtle.placeDown() and turtle.placeUp() to place blocks.
The block placed is whatever block the turtle currently has selected from its inventory.
Changing what item the turtle currently has selected is done with turtle.select, and this is our first example of a function that takes an argument, that being the number of the slot we want to select:
Let's now try moving the turtle. Moving forward is done via turtle.forward():
Uhhh... Right. This failed and it tells us why: turtles need fuel to move. Let's put some fuel in the turtle's currently selected slot.
And after that we can call turtle.refuel()
Now we should be able to move forward with turtle.forward():
There's also turtle.back(), turtle.up() and turtle.down() to move the turtle in other directions. To turn the turtle we can use turtle.turnLeft() and turtle.turnRight():
Typing turtle.dig() into a terminal to mine a block is no easier than just mining it yourself.
In general the power of computers comes not from doing things once but doing them over and over again on repeat.
This is what's usually called automation.
The first construct I will show you is just an infinite loop.
The code while true do ...... end will run whatever program we write in place of the dots over and over forever.
Let's automate digging blocks via while true do turtle.dig() end:
And with that I'd like to congratulate you on making a fully working cobblestone generator.
With infinite loops comes the danger of getting stuck. You can always end the current program's execution by either holding Ctrl+T or by pressing the terminate button ⦸ on the top left:
Time for something more complicated. Instead of just placing one function call in the loop we can place multiple and they'll each run in sequence.
Another simple program we can make with that is while true do turtle.forward() turtle.placeDown() end. This is a program for creating a bridge! Very useful for exploring the nether.
There's a slight problem though, when it runs out of blocks it keeps going...
Ideally after it runs out of blocks we'd like for it to stop. This is done by making our infinite loop finite.
Instead of doing while true do ...... end we can do while someCondition do ...... end, where someCondition stands for any expression that can be true or false.
Before each iteration of the loop the condition will be computed and the loop will continue only if it is true, if it is false the loop will immediately end.
Going back to the lua repl, we want the loop to end when we run out of blocks, so let's try to write some lua code that checks if the turtle has blocks.
After reading the documentation we find the function turtle.getItemCount(), let's see what it does:
Promising. Now, what we need is a true/false statement and not a number, but we can easily fix that with some math:
We have our condition, and slotting it into our previous program we get while turtle.getItemCount() > 0 do turtle.forward() turtle.placeDown() end.
Almost reads like english, "while you have items go forward and place them down".
The last program we just wrote is very useful, but it's kind of starting to get long. Instead of typing it all out every time we want to bridge in the nether it'd be way more convenient to have it saved in some way. Thankfully we can do exactly that by writing it down in a file.
First, quit the lua repl to go back to the shell by running exit()
From here we'll now open a text editor in which we can write our program. Type edit bridge.lua and press enter:
Welcome to the built-in text editor. It's very barebones but it'll do the trick. Write down your program.
Now, so far we've been writing our programs on a single line, but even a relatively simple program like this one is getting unwieldy to manage when it's written out on a single line. Let's split it up into multiple by hitting enter in a couple of places:
Now the whole thing fits neatly on the screen. Another nice thing we can do is indent the lines that are inside the loop by two spaces:
Our program is now functional and beautiful. Let's save it. The built-in editor is a bit weird when it comes to that. You have to first press control on your keyboard, then that opens a menu which you can navigate with left and right arrow keys, and you then have to press enter to do the selected thing. So first press control on your keyboard to open the menu...
...then press enter to save the file...
...then press control to open the menu again...
...then right arrow twice (or once on a non-advanced turtle) to navigate to "exit"...
...then press enter to exit the editor.
You can check that you saved it correctly by running the ls program (short for "list", it lists all of the files we have).
This is what you should be seeing:
Time to run our program. The name of the file is the name of our program, so give the turtle some blocks and then run bridge:
Create a program that turns a stack of concrete powder into a stack of concrete. Similarly to the cobblestone generator you'll need to construct a setup around the turtle for this to be possible.
After you've made something that works read the solution below.
Solution
One solution to the problem is the following setup and code:
while true do
turtle.place()
turtle.dig()
endThis definitely works and would earn you full points. Another solution is the following setup with two turtles and two programs:
while true do
turtle.place()
endwhile true do
turtle.dig()
endWhile this requires 2 turtles it is correspondingly 2x faster while only requiring one of the two turtles to have a pickaxe. This solution would again earn you full points.
Congratulations, you're a wizard now. What we've done together is test things out in the lua repl, written a complete program, saved it to a file, then ran it and it (hopefully) worked. Throughout the rest of this tutorial this is what we'll keep doing over and over, with the only difference each time being that our programs will get increasingly more sophisticated in order to solve increasingly more complicated problems. There is much more for you to learn, but in the business of wizardry the learning never stops. On that note, let's continue the learning.
Sometimes when you leave a turtle to do something and then come back you can catch it slacking on the job:
That is because when a computercraft computer of any kind gets rebooted it completely forgets what it was doing.
When you go away the chunks with the computer get unloaded and the computer shuts down, then when you come back the computer gets booted up again but no longer knows what it is supposed to be doing.
The solution to this is writing a file called startup.lua. This name is special because when a computer boots up it looks for a program called like that and if there is one it runs it.
So in our case if we put our cobblestone mining program in a file called startup.lua the turtle will resume mining cobblestone even after rebooting.
This is another opportunity to practice writing code into files with edit:
Now if you did it correctly when you reboot the turtle manually it should start digging. You can do that either via the red power button ⏻ at the top left or by typing reboot:
We talked about while loops, let's now talk about if statements. If while loops are a way to execute code multiple times, if statements are a way to not execute it at all. The basic structure is like this:
if someCondition then
...ifTrue...
else
...ifFalse...
endAgain we have some kind of condition (aka. something that's either true or false), but this time there's two blocks of code inside. If the condition is true the first block is ran and the second one is ignored, if the condition is false the first block is ignored and the second one is ran.
On their own if statements don't have much use, it's only when we combine them with other things like while loops that they becomes useful. Let's do that.
Lamps activated by inverted daylight detectors are a classic.
But with this simple setup we don't have control over what time exactly the light is on. If we instead have a computer control the light we can tell it exactly when it should turn on and off, and we could even have complicated schemes like turning it on and off multiple times in a single day. Let's do that!
I've made the following build where a regular computer is hidden under trapdoors. You can probably build something prettier than this but for this example it will do:
There's two things we don't know yet, and that's how to tell the time and how to turn the lamp on and off. Looking through the documentation we can find the redstone api, and from it redstone.setOutput seems to be what we want. As for the current time there's os.time() which returns the current hour of the day in a 24-hour format (0 is midnight, 12 is noon, 13 is 1pm, 19 is 7pm, etc.). With those two things out of the way we can start writing code.
I just told you about if statements so it's fair to say we'll probably need them. Let's just write one down.
if someCondition then
......
else
......
endWe want the lamp to be on when it's night and off when it's not, so let's write that down.
if isNight() then
turnOnLamp()
else
turnOffLamp()
endOf course these three functions don't exist, but we can start replacing them one by one with actual code. turnOnLamp and turnOffLamp can both be done with redstone.setOutput like so:
if isNight() then
redstone.setOutput("top", true)
else
redstone.setOutput("top", false)
end...I actually forgot to tell you what arguments redstone.setOutput takes. Here:
This is a screenshot of the relevant bit of documentation. The first line is the signature of the function. It tells us the name, then the number of arguments and gives a name to each argument. The first argument is called "side" and the second argument is called "on". Below that is a description of what the function does, and below the general description is a description of what each argument is supposed to be. The argument called "side" is supposed to be a string, which is programming jargon for "text" (and in lua we write text between "quotation marks", otherwise the text will be interpreted as code). The argument called "on" is supposed to be a boolean, which is programming jargon for "true or false". With that context it should now be pretty clear what each of the two lines I just wrote do.
Now time to replace isNight(). From messing around with /time set it seems the sun sets at 19 and rises at 5.5 (aka. 5:30).
This means if the time is over 19 or less than 5.5 it's night.
if os.time() > 19 or os.time() < 5.5 then
redstone.setOutput("top", true)
else
redstone.setOutput("top", false)
endWe're done... right? This sure is code at least, so let's run it.
...It immediately finishes. Yeah that makes sense, there's no loop in here. The code as-is only checks the time once, sets the lamp accordingly, then stops. What we want is for it to keep checking the time and keep setting the lamp, so what we have to do is take all of this and put it in an infinite loop:
while true do
if os.time() > 19 or os.time() < 5.5 then
redstone.setOutput("top", true)
else
redstone.setOutput("top", false)
end
endTesting this program it seems to work!... For about 10 seconds. Then it errors.
I won't go into detail about what "yielding" is, but the cause of this error is that our loop has nowhere for the computer to "take a break" per se. We've told it to keep checking the time and updating the lamp as fast and as often as it can, and that's usually not a good thing to have on a multiplayer server where the computer is consuming the server's resources to do these checks. The sleep() function comes to the rescue. It accepts as an argument some number of seconds and all it does is tell the computer to do nothing for that amount of seconds. Let's insert a sleep at the end of our loop such that the computer will only check the current time once per second.:
while true do
if os.time() > 19 or os.time() < 5.5 then
redstone.setOutput("top", true)
else
redstone.setOutput("top", false)
end
sleep(1)
endFinally, some working code.
For your purposes you can adjust the two numbers as you see fit. If you modify the condition of the if statement you can even have it turn on and off multiple times per day, for example like so:
while true do
if (os.time() > 19 and os.time() < 21) or (os.time() > 5.5 and os.time() < 7.5) then
redstone.setOutput("top", true)
else
redstone.setOutput("top", false)
end
sleep(1)
endThis lamp will be on from 7pm to 9pm as well as from 5:30am to 7:30am. Could be useful for automating the lights in your house, perhaps?
If you do end up using this in your world make sure to name the program file startup.lua so that it keeps working.
A -- followed by any text is a comment. Comments are parts of the code that are completely ignored by the computer and therefore do absolutely nothing. The primary use for comments is to explain the rest of the code as you can write text freely in them. Here's the previous program with some comments added:
while true do
-- check if it's dark outside but not bed time
if (os.time() > 19 and os.time() < 21) or (os.time() > 5.5 and os.time() < 7.5) then
redstone.setOutput("top", true) -- turn on lamp
else
redstone.setOutput("top", false) -- turn off lamp
end
sleep(1) -- fix "too long without yielding" error
endHow you use comments is completely up to you. A perfect program wouldn't need any comments because it would be completely self-explanatory, but I don't write perfect programs so I find comments very useful for explaining non-obvious parts of my code. You will be seeing me use comments a lot from now on.
Comments are useful not only for explaining your code to other people but also for explaining your code to future you. After writing a program it can take as little as a week for you to completely forget why you wrote something the way you did, so comments exist as a message in a bottle for your future self to be able to pick up from where you left off.