Skip to content

Instantly share code, notes, and snippets.

@umnikos
Last active March 22, 2026 00:58
Show Gist options
  • Select an option

  • Save umnikos/3ec51ee981496f2721e387e3896d6730 to your computer and use it in GitHub Desktop.

Select an option

Save umnikos/3ec51ee981496f2721e387e3896d6730 to your computer and use it in GitHub Desktop.
Introduction to ComputerCraft

Introduction to Programming with ComputerCraft

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.

image

Then right click on the turtle to open its UI.

image

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:

image

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.

Basics of Lua

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:

image

Specifically this mines the block in front of the turtle, there's also turtle.digDown() and turtle.digUp() for the other two directions:

image

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.

image

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:

image

Let's now try moving the turtle. Moving forward is done via turtle.forward():

image

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.

image

And after that we can call turtle.refuel()

image

Now we should be able to move forward with turtle.forward():

image

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():

image

Getting loopy

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:

image

And with that I'd like to congratulate you on making a fully working cobblestone generator.

image

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:

image

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.

image

There's a slight problem though, when it runs out of blocks it keeps going...

image

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:

image image

Promising. Now, what we need is a true/false statement and not a number, but we can easily fix that with some math:

image image

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".

Saving our programs

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()

image

From here we'll now open a text editor in which we can write our program. Type edit bridge.lua and press enter:

image image

Welcome to the built-in text editor. It's very barebones but it'll do the trick. Write down your program.

image

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:

image

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:

image

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...

image

...then press enter to save the file...

image

...then press control to open the menu again...

image

...then right arrow twice (or once on a non-advanced turtle) to navigate to "exit"...

image

...then press enter to exit the editor.

image

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:

image

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:

image

Exercise #1: Concrete maker

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: image
while true do
  turtle.place()
  turtle.dig()
end

This definitely works and would earn you full points. Another solution is the following setup with two turtles and two programs:

image
while true do
  turtle.place()
end
while true do
  turtle.dig()
end

While 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.

Checkpoint

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.

Interlude: Startup file

Sometimes when you leave a turtle to do something and then come back you can catch it slacking on the job:

image

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:

image image image image

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:

image

Getting iffy

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...
end

Again 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.

Lights controlled by the time of day.

Lamps activated by inverted daylight detectors are a classic.

image

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:

image

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
  ......
end

We 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()
end

Of 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:

image

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)
end

We're done... right? This sure is code at least, so let's run it.

image

...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
end

Testing this program it seems to work!... For about 10 seconds. Then it errors.

image

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)
end

Finally, some working code.

image

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)
end

This 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.

Interlude: Comments

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
end

How 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment