Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Search the Community

Showing results for tags 'tutorial'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • OpenComputers
    • Announcements
    • Feedback
    • IRC
  • Code Central
    • Support
    • Showcase
    • Tutorials
  • Addons & More
    • Addons Mods
    • Architectures
    • OpenEngineering Task Force
  • General
    • Lounge
    • Forum Games
    • Showcase
    • Servers
  • Archives
    • Public Archives

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start





Website URL








Fediverse ID



Found 9 results

  1. How to Write an OpenComputers Operating System This is the kind of guide I wish I had had 9 months ago when I started developing operating systems for OpenComputers. It will walk you through writing a very basic OpenComputers operating system. EDIT: The guide I followed (the only one I found) is here: WARNINGS: -- This post assumes basic knowledge of programming, such as: what a string is, what a table or list is, what a function is, what a variable is, etc. I am NOT attempting to teach you Lua-- see warning #3 -- This operating system is not intended to have many features (nor is it fast!), but more so to teach new programmers. I will try to keep my code well-organized and well-commented, but no guarantees! -- If you're new to Lua, go read the PIL (https://lua.org/pil/1.html), and keep the Lua reference manual (https://lua.org/manual/5.3/manual.html) open in case you need to reference it. (I also recommend having the OpenComputers wiki [https://ocdoc.cil.li] open.) -- Note that the component, unicode, and computer APIs, plus checkArg, are unique to OpenComputers, and that io and package (plus require, loadfile, and dofile) must be defined by the user. -- This OS is structured in a way that is meant to be easy-to-follow, though you can lay your own out however you like. All source code is available at https://github.com/ocawesome101/basic-oc-os under no license in particular. 1. Init.lua init.lua is the file that most BIOSes expect to load. Most operating systems, this one included, simply use init.lua to load their kernel. This is an example of an init.lua file: -- The path to our kernel. Note that it is advisable to use the 'local' keyword in front of your variables unless you want them to be accessible from everywhere. local KERNEL_PATH = "/mini/kern.lua" -- Get the computer's boot address local address = computer.getBootAddress() -- Open the kernel file for reading local handle, err = component.invoke(address, "open", KERNEL_PATH) if not handle then -- The kernel is probably not present! error(err) end -- Read all the data from the kernel file local kernelData = "" repeat local chunk = component.invoke(address, "read", handle, math.huge) kernelData = kernelData .. (chunk or "") -- (chunk or "") protects against errors until not chunk -- End Of File -- Close the kernel file handle component.invoke(address, "close", handle) -- Try to turn the data we read into a function we can call local ok, err = load( kernelData, -- the data (or "chunk") "=" .. KERNEL_PATH, -- what name to use for the loaded chunk, prefixed with an "=" "bt", -- the mode with which to load the chunk. "bt" should be generally fine _G ) if not ok then -- There was probably a syntax error or some such thing error(err) end ok() -- Execute the kernel -- an idle loop in case the kernel exits. Could be replaced with computer.shutdown() while true do computer.pullSignal() end The comments should explain fairly well what is happening. init.lua should be placed in the root of your drive. 2. The Kernel The kernel is the heart of your operating system. In more advanced operating systems, the kernel usually contains some basic hardware management, a scheduler (relatively complex beasts involving coroutines and signal timeouts), and possibly drivers, leaving the rest of system initialization to the init process. For the sake of this tutorial, we will jump straight from a basic kernel to the shell. In my case, the kernel is at /mini/kern.lua, though yours can be almost anywhere. For compatibility's sake, it is usually a good idea to start by defining _OSVERSION like so: _G._OSVERSION = "mini 0.1.0" Next, you should find installed GPU and screen components- at least one of each. local gpu = component.list("gpu")() local screen = component.list("screen")() There are two ways to interact with components: component.invoke and through a proxy. For extended usage, a proxy is generally the better choice, but for one or two operations component.invoke is fine. An example of component.invoke usage: component.invoke( gpu, -- The component address, a string "bind", -- The method you want to invoke. Must be valid, and must be a string. screen -- Any additional arguments are interpreted as parameters ) It is probably a good idea to create proxies for the GPU and boot filesystem, since we're going to be using these things a lot. local gpuProxy = component.proxy(gpu) _G.fs = component.proxy(computer.getBootAddress()) -- computer.getBootAddress() is defined by most BIOSes Optionally, you can set up basic onscreen boot logging. This is especially useful for debugging, and it can give some insight into what your OS is doing when it boots. I set up my logging like this. Note that my code is somewhat over-commented for the sake of this tutorial. local line = 1 -- What line are we on? local width, height = gpuProxy.maxResolution() -- get the maximum resolution of the GPU and screen. These values are the minimum of the two. gpuProxy.setResolution(width, height) -- ensure that the screen resolution is properly set gpuProxy.fill( -- Fill a box on-screen with a single character 1, -- The top-left X coordinate 1, -- The top-left Y coordinate width, -- How wide the box should be height, -- How tall the box should be " " -- The character the box should be made of ) local function log(message) -- checkArg is a very useful function, used for argument checking. checkArg( 1, -- the argument number message, -- the argument itself "string" -- one or more types that are allowed for the argument, in the form of separate strings. ) -- Set the line at gpuProxy.set( -- Set a line (or part of a line) onscreen to a string 1, -- The X coordinate of the string line, -- The Y coordinate of the string message -- The string ) if line == height then -- We can't go down or we'll be off the screen, so scroll down a line gpuProxy.copy( -- Copy one screen area to another 1, -- The top-left X coordinate 1, -- The top-left Y coordinate width, -- The width height, -- The height 0, -- The relative X to copy to -1 -- The relative Y to copy to ) gpuProxy.fill(1, height, width, 1, " ") else line = line + 1 -- Move one line down end end -- Crash the system in a slightly prettier fashion. Not necessary, but nice to have. local function crash(reason) checkArg(1, reason, "string", "nil") -- This is an example of checkArg's ability to check multiple types -- Here, reason is already local; there is no need to specify it so reason = reason or "No reason given" log("==== crash " .. os.date() .. " ====") -- Log the crash header, ex. "==== crash 24/04/20 18:52:34 ====" log("crash reason: " .. reason) -- Log the crash reason. ".." is Lua's string concatenation operator. local traceback = debug.traceback() -- Tracebacks are usually useful for debugging traceback = traceback:gsub("\t", " ") -- Replace the tab character (not printable) with spaces (printable) for line in traceback:gmatch("[^\n]+") --[[ :gmatch("[^\n]+") splits the string on the \n (newline) character using Lua's basic regular expressions ]] do log(line) end log("==== end crash message ====") while true do -- Freeze the system computer.pullSignal() end end For sanity's sake (and ease-of-use) you should define loadfile(), dofile(), and require(). If you set up module caching in require, you can do some neat things that otherwise would be difficult, such as library persistence across programs. loadfile() is probably the most complex of the three: function _G.loadfile(file, mode, env) checkArg(1, file, "string") checkArg(2, mode, "string", "nil") checkArg(3, env, "table", "nil") -- Make sure mode and env are set mode = mode or "bt" env = env or _G -- env can be used for sandboxing. Quite useful. local handle, err = fs.open(file, "r") if not handle then return nil, err end local data = "" repeat local fileChunk = fs.read(handle, math.huge) data = data .. (fileChunk or "") until not fileChunk fs.close(handle) -- Always close your file handles, kids return load(data, "=" .. file, mode, env) end Then dofile: function _G.dofile(file) checkArg(1, file, "string") local ok, err = loadfile(file) if not ok then return nil, err end return ok() end Basic library caching can be setup very quickly with: local loaded = { ["gpu"] = gpuProxy } -- Libraries that have already been loaded Next, you should implement some sort of require() function. Ideally we'd do this with a fully fledged package library, but that's much more complex. First, you'll need paths of some kind to search. I did mine this way: local libPaths = { -- The path(s) to search for libraries "/mini/lib/?.lua", "/ext/lib/?.lua" } The standard Lua package.path is "/usr/share/lua/5.3/?.lua;/usr/share/lua/5.3/?/init.lua;/usr/lib/lua/5.3/?.lua;/usr/lib/lua/5.3/?/init.lua;./?.lua;./?/init.lua" but the above is considerably easier to parse. To disable package caching, useful for development, you can comment out the lines suffixed with "--". function _G.require(lib) checkArg(1, lib, "string") if loaded[lib] then -- return loaded[lib] -- else -- -- It wasn't already loaded, so search all the paths for i=1, #libPaths, 1 do component.proxy(component.list("sandbox")()).log(libPaths[i]:gsub("%?", lib)) if fs.exists( libPaths[i] -- The current path :gsub( -- Replace a character or characters in a string with another string "%?", -- The string to replace. "%" is necessary because string.gsub, string.gmatch, and string.match interpret "?", along with a few other patterns, as a form of regex (DuckDuckGo regular expressions if you don't know what regex is). lib -- The string with which to replace "?" ) ) then local ok, err = dofile(string.gsub(libPaths[i], "%?", lib)) -- string.gsub("stringToGSUB", ...) is the same as ("stringToGSUB"):gsub(...) if not ok then error(err) end loaded[lib] = ok -- return ok end end end -- end Once this is all done, I load my shell with a simple while true do local ok, err = dofile("/mini/shell.lua") -- Run the shell if not ok then crash(err) end end Note that mine is encased in a while loop so that if the shell exits it will restart. We aren't done yet though, as we still need to program the shell. 3. The shell For simplicity's sake, my shell is just a basic Lua interpreter. It doesn't seem to function properly in ocvm, unfortunately (pcall results are strange, I'll have to test in-game) but here it is, in all its glory: _G.term = require("term") _G.gpu = require("gpu") -- This is where the loaded = { ["gpu"] = gpu } line comes in term.clear() function _G.print(...) local args = {...} for k, v in pairs(args) do term.write(tostring(v) .. " ") end term.write("\n") end local currentDirectory = "/" -- self explanatory local function drawPrompt() gpu.setForeground(0x00FF00) -- Colors are stored as 24-bit hexadecimal values. (Look up "hexadecimal color"). 0x00FF00 is bright green. term.write("\n" .. currentDirectory .. " > ") gpu.setForeground(0xFFFFFF) end local function printError(err) gpu.setForeground(0xFF0000) term.write(err .. "\n") gpu.setForeground(0xFFFFFF) end local function execute(command) local ok, err = load(command, "=lua") if not ok then ok, err = load("=" .. command, "=lua") if not ok then return nil, err end end local result = {pcall(ok)} -- pcall, or protected call, captures errors. Very useful function. if not result[1] and result[2] then return printError(result[2]) end for i=#result, 1, -1 do print(result[i]) end end while true do drawPrompt() local command = term.read() if command ~= "\n" then execute(command) end end What is this shell doing? First, it defines a few utility functions (print(), drawPrompt, printError, and execute), and then it runs the shell's main loop. But wait! What about the top line? Where is the term API? It's in /mini/lib/term. I implemented term.getCursorPosition, term.setCursorPosition, term.scroll, term.clear, term.write, and term.read, but you can implement more fairly easily. Internally, there are two functions (showCursor and hideCursor) that I call after and before every operation, respectively. For example, when you call term.setCursorPosition(2, 2), the term API executes this code: function term.setCursorPosition(newX, newY) checkArg(1, newX, "number") checkArg(2, newY, "number") hideCursor() cursorX, cursorY = newX, newY showCursor() end cursorX and cursorY, as well as width and height, are used internally for purposes you can probably guess based on their names. If you need it, here's my term.read function (text input is always particularly tricky to get right): -- Fairly basic text imput function function term.read() local read = "" local enter = 13 local backspace = 8 local startX, startY = term.getCursorPosition() local function redraw() term.setCursorPosition(startX, startY) term.write(read) --.. " ") -- the extra space ensures that chars are properly deleted end while true do redraw() local signal, _, charID, keycode = computer.pullSignal() -- signal is the signal ID, charID is the ASCII code of the pressed character, and keycode is the physical keyboard code. Note that these are keypress-specific!! if signal == "key_down" then -- A key has been pressed if charID > 31 and charID < 127 then -- If the character is printable, i.e. 0-9, a-z, A-Z, `~!@#$%^&*()_+-=[]{}\|;':",./<>? read = read .. string.char(charID) elseif charID == backspace then -- The character is backspace read = read:sub(1, -2) -- Remove a character from the end of our read string elseif charID == enter then -- my god Kate's syntax detection is crap read = read .. "\n" redraw() return read end end end end That should be all! Feel free to comment if you need help (be sure to provide error messages and the relevant bits of your code) and I'll do my best to respond. My results with this code (I can enter Lua statements and they will be run): Next Steps: -- Expand on this OS with a more advanced shell, io and package libraries, and the like -- Write your own OS with a task scheduler using coroutines -- Be sure you give events to all processes! My first scheduler very much did not do that.
  2. Hey, it's me Gangsir. I figured I'd try my hand at writing a tutorial on one of the coolest things (in my opinion) in lua. They say that the best way to learn and understand something is to teach it. This is what I aim to do with this hopefully easily accessible tutorial. What? Let me start off by explaining what a coroutine is, for those that don't know. A coroutine is basically a background function. It allows functions to be run without stopping the main thread. By rapidly stepping through background functions, we can achieve multi-tasking. Think of it like sending out your friend to buy a steak while you set the table. Instead of having you do everything, the final result can be achieved faster. Lua.org defines a coroutine as follows: As OC implements them, coroutines work like actual lua coroutines, as in that only one may run at once. As far as I’m aware, OpenOS does not support true multitasking, by having several coroutines run at literally the same time. (I.e. Threads) By quickly stepping through them, however, something close can be achieved. Whenever I refer to "threads" in this tutorial, I mean official lua's coroutines. How? Coroutines have three states. Coroutines can be running, suspended or dead. When coroutines are initially created, they start off in suspended mode. This means that they are paused and waiting for a resume. When in the running state, they are of course, running. And finally, when dead, they have returned. To change between states, there are a few functions you can use that come with the coroutine library that is standard to lua. These are coroutine.create(), coroutine.yield(), coroutine.resume(), and return. Status of a coroutine can be checked with coroutine.status(). First of all, you have coroutine.create(). When coroutine.create() is called, you pass it a function. This is usually done via a nameless function, although you can use an existing named function. For example: co = coroutine.create(function () print("Hi") end) --or, use an existing named function: local function hello() print("Hello!") end co = coroutine.create(hello) This loads up a new coroutine and assigns it to the variable co. If you try to print co, you'll get something like: thread: 0x8071d98 The number on the right will differ. Basically, this means that co is a thread. (A coroutine! It works!) Then, when you want to run the coroutine, call coroutine.resume(co). This will for our example, print "Hi", then kill and return the coroutine. (If no return inside the function is provided, lua assumes a return with no values.) If you then check the status of the co coroutine, you'll get "dead". Example: --">>" means what's printed to console coroutine.resume(co) >>Hi print(coroutine.status(co)) >>dead --if you then try to resume a dead coroutine, you'll get an error. No coroutine necromancy! coroutine.resume(co) >>(error, cannot resume dead coroutine, yada yada stack trace) And finally, where all the magic happens. coroutine.yield(). Call it inside of a coroutine's function, and it will pause(suspend) the coroutine, and return control to the main thread. The main thread can then resume another coroutine, and so on and so forth. Caution, and this is very important, because of how OC handles things, if a coroutine does not yield after a certain amount of time (usually a few seconds), OC will forcefully kill the program it came from, crashing your code. Make sure that you yield coroutines on a common basis. This is to prevent large amounts of coroutines taking up processing power on the real-world server. Example of code that would make OC mad at you: cor = coroutine.create(function() while true do --tryna lag dis server end end) coroutine.resume(cor) --Code would then crash after a few seconds, with a too long without yielding error. Bad coder. Bad! When you call coroutine.yield(), you can specify arguments that will be returned when resume is called on the coroutine. This allows for coroutines to keep a level of communication with the main thread open at all times instead of waiting for the coroutine to return, if ever. coroutine.resume() will return nil or any arguments specified in .yield(). For example: function foo() print("foo", 1) coroutine.yield() print("fooAfterYield", 2) end coro = coroutine.create(foo) coroutine.resume(coro) >>foo 1 --notice that it prints the foo and 1, which is right before the yield! --Then, if we resume it again, coroutine.resume(coro) >>fooAfterYield 2 --Notice how the print changed to the one after the yield? Why? Of course, if you think like me, you likely still fail to see how this is better than just directly calling the function. Say you have a program that needs to do many things at once. You can use coroutines and a dispatcher function to step through them. This allows for multitasking, by placing each function into it's own thread. The yielding function allows for control to return to the main thread when the coroutine has a good stopping point. It's kind of like writing an essay. You have a page written, and it's concise and meets the requirements as it stands. You can yield and put the essay back into your backpack, or keep running and writing, or return and turn the essay into the professor. You can't mess with it once you turn it in, so if you want to keep making edits, it's better to yield and put it back inside your backpack. Keep in mind that while it's in it's own thread, if a thread has a fatal crash, the whole script will likely crash. Make sure to do error handling to ensure the whole tree isn't lost if a leaf falls off. Further questions? Let me know below in the replies. Have a correction? By all means, tell me. I'm trying to fully understand coroutines as well. Like my tutorial? Give me a like and show your programmer buddies. Fun Fact: The word "Coroutine" or some variant has been used 63 times in this post, as of 10/2/15.
  3. for OpenComputers 1.51 on Minecraft 1.7.10 Black Hole Tutorial 05- Pretty Pretty Program "If builders built buildings the way programmers write programs, then the first woodpecker that came along would destroy civilization." - Gerald Weinberg Before we got into writing anything useful, I wanted to go over some commonly preferred practices to be used when writing your programs. This is purely selfish on my part, since I would like to be able to read that elegent bit of code that took you a week. These practices should also make things easier on you. Writing your Program 1) Write the documentation first. As in the last tutorial, knowing exactly what you want done makes writing code easier. Start by writing the .man page first. edit /usr/man/programName.man NAME - name of your program SYNOPSIS - how your program is started, what arguments are used DESCRIPTION - What does your program do? Any options available? EXAMPLES - examples of your program in use, how arguments affect the outcome With documentation done first, you might be able to throw out ideas you at first thought to be great without writing a line of code. Once done, your docs will guide and help keep your focus during coding. If you do choose to do the documentation later, you will have less reason to do a good job (I know how it works, that's good enough!) and will know the program too well, probably leaving out things new readers should know. 2) Write from comments to code. Determine the flow of your program before actual code. Start at general ideas of how you want it (put wood in furnace) and break it down. This makes it easier to see additional requirements, what is missing or backwards, etc. put wood in furnace move to top of furnace - drop wood in top move back, up, back - select slot with wood - dropDown 8 at a time - return to home t.back() t.up() t.back() - t.select(woodSlot) - while t.count() >= 8 do t.dropDown(8) end - t.forward() t.down() t.forward() - select previous slot OK, you get the idea (and I learned a new button!) 3) Start small, test often. Write a prototype with the most miminimal imaginable functionality (like our treeMuncher program from the last tutorial). Gradually add features one at a time (planting a sapling, checking for a grown tree, etc) after making sure the program is currently working. When debugging you will know any problems must be in the recently added code. This is better then spending four hours writing out every part of a complicated program and then over six hours the next two days debugging it. (I would have been better starting over.) 4) Do the easy thing first. This gives your subconscious time to break down the difficult parts. Trying to tackle the most difficult bits first will make Reddit or Netflix look like a good alternative (Still haven't seen Game of Thrones, maybe just the first episode). You want to do it all eventually, so ease into it. On the other hand, stay away from easy low-priority work that does not really need doing (get the furnace interaction working before playing with the soundtrack). If you're stuck, go to bed and let your brain stew on it for a while. 5) Read (and use) other people's code. There is always someone who is better then you, learn from them. Look at programs similiar to what you want done. If you find something useful, thank them and write it down in your notebook (If you do not have one by now, I REALLY SUGGEST getting something. A text file, wiki, pen and paper, whatever. Pale ink (or pixels) beats a bright mind.) Formatting your Program "Code is read much more often than it is written." - Guido van Rossum The following is a style guide of how to make your code look, based upon available Lua style guides online and some personal preferences. Consistency Consistency means to do things the same way most every time. There will be times when doing it differently makes it easier to read, the art is knowing when. Even if you don't intend anybody to read your code but you, then think of the you twelve months from now (you are going to be amazed how bad you were back then). Comments Comments that contradict the code are worse than no comments at all. Keep comments up-to-date with code changes. Use block comments (--[[ and --]]) for long comments and important notes. Use line comments (-- ) for short, unimportant and temporary comments. Keep a space between the -- and your comments. Inline Comments An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. Inline comments are unnecessary and in fact distracting if they state the obvious. Tell us why, not what. Example: xMax = x + 1 -- Increment x Leave room for window frame Indentation I indent two spaces, though I've seen three and four used as well. Spaces are the preferred indentation method. Tab sizes can vary by user and editor. This helps to keep code easy to follow by eye, find missing closures, etc. Bad Example: if next(idx) == nil then print this and that show some examples else for i,v in pairs(idx) do all of this and that end end Good Example: if next(idx) == nil then print this and that show some examples else for i,v in pairs(idx) do all of this and that end end Naming It's a general rule that variable names with larger scope (seen by more of the program) should be more descriptive than those with smaller scope. For example, 'x' is probably a poor choice for a global variable in a large program (better would be 'homeCoordX'), but it's fine as a counter in a small loop. Constants: Constants, particularly ones that are simple values, are often given in ALL_CAPS, with words optionally separated by underscores. Example: CONNECT_RETRY_FOR = 300 -- in seconds Lua internal variables: Names starting with an underscore followed by uppercase letters are reserved for internal global variables used by Lua. Example: _VERSION Variables: should start with a lower case letter with each embedded word capitalised. Examples: maxTreeLevel, moveToTarget, HTTPAddress (while not consistent it is easier to read, so a good exception to the rule) Functions: Functions follow similar rules as variables. A function name consisting of multiple words may run together (getmetatable), as done in the standard Lua functions, though you may choose to use underscores (get_metatable) or like variables (getMetaTable). Booleans: It can be helpful to prefix variables that contain or functions that return only boolean values with 'is' Example: isChickenDone = false Names to Avoid: Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single character variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use 'l', use 'L' instead. Code Compartmentalize your program Always start with a comment header, then keep similar parts of your program together: required libraries, variable and constants definitions, etc. Keep functions close to where they are called from. Use local variables rather than globals whenever possible. When you type anything that requires closure, do it now and move back. This way you are done and have no need to remember to do it later. Examples: ( ), " ", [ ], --[[ --]] function() end if then end -- Ooh, triple word score (might be tired) When unsure, parenthesize. While the order of operations is correct for our needs, parentheses will ensure future readability. Even if you are absolutely sure it doesn't need them, consider the next person who uses the code without you there, who will probably put parentheses in the wrong place. Editor While editing a program in the Robot works fine for simple programs and bug hunting, you'll eventually find yourself wanting to use a proper IDE(Integrated Development Environment). An IDE will use color to highlight key parts, hide function bodies you don't need to be looking at, have multiple files open or the same program open at different points, auto-completion of variable or function names and much more. Just try one and then go back, I dare ya. If you want to be editing your programs while Minecraft is running, you need to open /config/opencomputers.cfg and change bufferChanges to false. These are some free IDEs I have tested. Been some time since I used Windows, but I remember Notepad++ being my primary choice for an editor. Currently I am running Kubuntu, so Kate is available. Works fine for my simple stuff and what I use most often. Zerobrane Studio: This is the one I would recommend, the interface is fairly intuitive and I like the amount of documentation. Available for Linux, Mac and Windows. jEdit:I have spent the least amount of time with this one, so I can't say much other than it works. Liscense Only because this is a silly world we live in. If you worry about how others might use your programs, I suggest learning about the GNU General Public License, here is how to use it. Least Signifigant Bits OK, I lied. This is actually for me. I get ideas popping and then get messy and then have to start over. You can use it if you want. In the next tutorial we are playing with computers and cards! If you are having problems, post it on the Support Sub-Forum. Additional information, constructive critism or praise of this tutorial should be posted below. End of Line.
  4. OpenComputers 1.51 for Minecraft 1.7.10 Black Hole Tutorial 04- So You Want to Write a Program So you have an understanding of Computers, Robots and OpenOS and how everything fits together. Time to get them finally doing something. This tutorial is here to help you learn to design and write a simple program for a robot. The Language of Lua If you know little to nothing about Lua, start here: Lua 5.2 Reference Manual. Read what Lua is capable of. Have lua running on a computer and try out some of the example code provided. OpenComputers mostly follows along with the above, read the wiki to see the differences. There are many tutorials on Lua available, these are some I have used: TutorialsPoint, Lua- Really for Beginners, Lua-Users Wiki. I am going to assume at this point that you have at least a basic knowledge of Lua. This should include: Comments Variables Conditional Stuctures - if, then, else, ... Loops - for, while, repeat, ... Functions Tables Can you name at least six commands you can give a robot? If not, you need to learn more about how to control it. Look at the APIs available on the wiki, especially the Robot API. In the Lua interpreter l="" for k,v in pairs(robot) do l=l..k.." " end print(l) l=nil, will print a list of commands available for the Robot API. change 'robot' to other api's names to see what they have. I remember a command that gives us a string of documentation, but can't find it now. This is why you take lots of notes. I thought for our first program, we should start by doing what everybody does when starting Minecraft: punch some wood. -Plan Our Work- The more specific you can be in your desired outcome, the easier it will be to translate that into software. These questions are not really necessary for such a simple program, but it is better to start thinking this way now. Q: What do we want done? Chop down a tree. Q: What do we have to work with? Lots of 1x1 trees. Q: What else do we need for this to work? A way to recharge the robot, eventually. Q: What machine will best/can we afford to do this job? We want it to move, so a Robot or Drone. We want it to grab a a treeful of wood, so a Drone could work if I knew how to program an EEPROM. I don't yet, so we will use a Robot. We will need at least one Inventory Upgrade to hold the wood we are chopping. We aren't asking for much, so a minimal Tier 1 Robot should be able to do this. Tier 1 Case Tier 1 CPU Tier 1.5 Memory Tier 1 GPU Tier 1 Hard Drive with OpenOS already installed on it Tier 1 Screen Keyboard Inventory Upgrade You could install a Tier 2 Upgrade Card as well. That would let you use a Generator or Solar Panel to help with our power requirements. -Work Our Plan- start a new file where you want, I suggest /usr/bin: mkdir /usr/bin edit /usr/bin/treeMuncher.lua Some notes on what it was intended for, who wrote it and when are nice to have. Especially six months down the road when you won't even remember writing this program and have no idea what it does. --[[ Tree Muncher v0.1 for OpenComputers v1.51 Written by Me on 2015Mar03 Purpose: To collect the trunk of a 1x1 tree and return to starting location. How to use: Put robot at the base of a 1x1 tree, facing the tree before starting program. Needed: minimum Tier 1 Robot --]] Save and Quit for now, we'll come back. We need to think of and test our program. - Break it Down - "This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface." - Doug McIlroy “Make it run, then make it right, then make it fast” - Kent Beck Just like ye programmers of olde, you are working with machines of limited capablility. The above ideals are what was learned from that time and are just as valuable today. The Wikipedia page on UNIX Philosophy is a quick read and a great way to think about your programs. For a much longer read, The Art of Unix Programming is available. Let us break down our program into 'dig into the tree, chop up tree, come back down' 1) Dig into the Tree Cool thing: just like you, a robot does not need an axe to chop a tree down. Put your robot down facing a tree and turn it on. Enter the lua interpreter with lua and try robot.swing() Cool, we got a block. You may have noticed a delay after getting the block. That is there to simulate the time it normally would have taken to chop down that block. Put that log back in the tree and put an axe into the tool slot (Bottom-left corner of Robot's inventory with a wrench icon). Press the up arrow to show the last command you entered and enter to do it again. Was the delay less using the axe? Look at the axe, you are indeed using it. Durability of your tools is something you have to take into account in future programs. To make it worse, the only way to change tools is with the Tier 2 Inventory Controller Upgrade. And if we wanted the Robot to craft it's own axes, that requires a Crafting Upgrade. At this point, we need a Tier 2 Robot. 2) Chop Up Tree We got a block, now we want a tree. Let 's use Beck's above quote and show how that idea can translate into reality. "Make it run" We can move and swing, that should be enough to make it work. Trees are usually less then 10 blocks tall, so robot.swing() robot.forward() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() robot.swingUp() robot.up() will work. It is also very wasteful of space and hard to read. Also I noticed during testing the trees I chop are never more then 8 blocks tall. "then make it right" robot.swing() robot.forward() for i=1,7 -- seven because we already took the bottom block do robot.swingUp() robot.up() end is much easier to understand. I can think of one more change, though. robot.swing() robot.forward() while robot.swingUp() do robot.up() end Small, simple and easy to read. Good code can be a thing of beauty. This has the added benefit of stopping when there is nothing more to chop. "then make it fast" This program is so simple, we can't really do much to make it faster. Maybe a diamond axe? 3) Come Back Down If you have been testing these programs as we go along (good for you!), you noticed the robot has done the job we want: the tree is chopped. Of course, it is now more than a few blocks up in the air. One last step before we are done: have our robot come back to where it started. This is not just for an easily retrieval. By returning to its original coordinates and facing, this makes it easier for us to keep track of where the robot is in your program and in the world. Once your robot is working on several projects, having a home base (usually next to a Charger) makes things simpler. Simple is good. Let's finish this: robot.swing() -- make a hole in the base of the tree robot.forward() -- move into the tree while robot.swingUp() do robot.up() end -- while we get a block swinging up, keep moving up while not robot.detectDown() do robot.down() end -- until we see a block belows us, keep moving down robot.back() -- back to start location Try these commands in lua and make sure they work, Testing is good. Then exit the interpreter and get back to your tree muncher program. edit /usr/bin/treeMuncher.lua after the comment header, add local r = require("robot") to have access to the Robot API. (I use a single letter for the variable name because I will have to type it a lot and is easy to remember. Saves a little space on your file system as well. Changing 'r' to 'robot' or 'rbt' or even 'GrrlPower' works as well, if a bit silly.) and then our program above: r.swing() r.forward() while r.swingUp() do r.up() end while not r.detectDown() do r.down() end r.back() and that's that, your first simple program. Check for mistakes in typing, Save and Quit. We'll be back later to make this program more useful. Actually, almost done. Do you have a way to recharge your robot? If your robot sits for long periods of time waiting, a Solar Panel Upgrade would make sense. Since we are collecting lots of wood, we could burn some small portion in a Generator Upgrade. Bonus: Auto-Chop At the shell, type cp /usr/bin/treeMuncher.lua /autorun.lua Now take your robot to the base of another tree and turn it on. Robot Chop! After booting the robot, OpenOS will automatically run autorun or autorun.lua in the root directory if available. Least Signfigant Bits Your turn: Can you add to this program to plant a seedling and wait until a new tree is grown before cutting down again? If you are having problems, post it on the Support Sub-Forum. Additional information, constructive critism or praise of this tutorial should be posted below End of Line.
  5. OpenComputers 1.51 for Minecraft 1.70 Black Hole Tutorial 03- Roots and Shells and File Systems v1.1 I was going to write a basic programming tutorial when I realized there is one more maze we really should go through: OpenOS itself. Make a superflat map in creative mode or use the one from last time. Turn on a computer you have installed OpenOS onto. After the booting process is done, what you are looking at is an input prompt for a program called the shell. It is the main interface to your files. (At the prompt, type in man sh for more information.) Type in ls and see what we start with. bin boot etc lib mnt tmp usr init.lua Unless you changed something, you are looking at a list of directory and file names. Do you know why all these directories are here, what they store and how they are meant to be used? It All Starts at / What you are seeing is based on the Filesystem Hierarchy Standard. It hasn't changed much since the early days of UNIX, over 40 years ago. Basically it is a definition of what kinds of files belong where. / - Root Every file and directory starts from the root directory, sometimes called the trunk (like a tree). When you turn on the computer, this is where you start at. This is similar to C:\ under Windows. Notice that the rest of these start with '/', meaning they are branching off from root. This is different to what Windows uses ('\'). /bin - System programs that come with OpenOS. /boot - contains files required to boot OpenOS. Look but do not touch. /etc - used to store config files. Like the Registry in Windows. /etc/rc.d - run control directory. It controls what programs you want to start after booting (I think). /lib - Libraries contains the shared libraries used by OpenOS. /mnt - Mount where external file systems (floppies, Hard Drives, RAIDs, etc.) are attached (mounted) to root /tmp - Temporary Used to store files until the computer is shut down or rebooted. At that time everything in this directory is erased. /usr - User Programs, libraries, documentation, etc. for all user-related programs. /usr/man This is where the text files used by the man command are stored. Have you tried the 'man' program? Type in man cat. Now type cat /usr/man/cat to see the same text. Side Note: You can and should write a man page for your programs, if not for others than yourself. /usr/misc - For miscellaneous files, I suppose. While not necessary, but I would suggest adding these to help keep things organized: /usr/bin - non-system programs. (think stuff like Firefox, VLC, XTree, etc. Programs used by everyone on a computer beyond the system basics.) Windows equivalent is C:\Program Files. /usr/lib - non-system libraries/APIs /var - stands for variable files. All files that change frequently are traditionally kept in a subdirectory of /var. /var/log - log files (written records of what your programs have been doing, useful for debugging) /var/lib - packages and database files /home - user personal files (Optional, but traditional) /home/bin - personal programs (you are probably seeing a pattern by now) If you have multiple people using the same computer, give each person their own directory under /home (i.e. /home/max, /home/vincent). This way everyone has a place put their ocNotes.txt or TreeMuncher.lua. Windows equivalent is C:\users\max\. Please remember, what I am saying above are just suggestions. Try different things and find out what works best for you. You could dump everything in root and probably be okay. All these directories do not have to be on your boot drive. You can mount other filesystems and connect them to your root file structure where you please. More on that later in this tutorial. All these directories may not make much sense for OpenComputers since it has no permission system. Under Linux/UNIX, everyone has an account to log into. Each account is set up to allow access to only the parts of the system that user needs, hopefully keeping any damage they can do to a minimum. The 'root' account has access to everything, just like you do now. Tread lightly, my friends. If you are working on some large projects, DO make backups onto alternative media and/or other computers, just like you would in the real world. How to Get Around File and directory names are case-sensitive. That means you can have 4 files named AB.txt, Ab.txt, aB.txt and ab.txt (unless you are running Windows, since OpenComputers saves files onto your PC's Hard Drive and Windows is case-insensitive). try LS or Ls or lS and see what happens These are the commands you be be using the most often. There are lots more, but this tutorial is long enough already. ls man ls ls -M shows there should be 2 files in our root directory, but we see only one. where is the other file? ls -a shows all files in the specified directory. ah, a .osprop was hiding! Starting a file with a . tells the OS it is meant to be a hidden file. Under Linux a lot of programs use this to hide their config files in the each user's /home directory. ls /bin If you do not recognize any of these, it is a good time to start learning. We go over the most basic commands below. Use man (try man man to start) on the ones you don't recognize. Not all will work, but most will. cd man cd if you haven't already. current working directory means whatever directory you are currently in. pwd will show you where you are at. The far left of the command line shows the same. mkdir creates a directory mkdir /usr/bin ls /usr rm this will delete files, directories, and unmount filesystems. rm /usr/bin ls /usr Warning: Use with caution, there is no undelete! cat and more Both are used to display files onto your screen. Cat all at once, more is controlled by your input. cat /bin/shutdown.lua more /bin/redstone.lua try arrow down, enter and space bar edit This is how you create, edit and view your files. cd /usr/misc edit happy.txt if /usr/misc/happy.txt does not yet exist, it will be created for you. edit -r /boot/02_os.lua that extra -r tells edit to not let you change anything in the file you loaded (i.e. Read Only). Self Test: After running edit the first time, a config file is written. Can you guess where? (answers at bottom) alias Since most people still use Windows for some reason, you might be more used to dir than ls. alias dir ls now try dir -a alias by itself shows the current list of aliases Command History At the prompt, use the up and down arrow keys. The shell keeps a list of the last ten commands you have entered. Side Note: Shell Variables type in echo $PATH, you will see a list of directories the shell looks in for programs you ask it to run. When you type in ls it looks in the current directory and if not found there, it looks in the first directory in that list. If not there, then the next one and so on. These are the shell variables I could find. Colons are used to separate entries and ends with a period by itself. $PATH = /bin:/usr/bin:/home/bin:. (where to look for programs) $HOME = /home (more useful with multiple users on same machine) $MANPATH = /usr/man:. $PWD = your current working directory $PS1 = $PWD# (what is displayed at the prompt) The reason I bring this up is that it can be useful to change these (adding /home/max/bin to the $PATH, for instance). Thanks to dgelessus, I found out about the 'set' command. (No man page and it was not mentioned in the Linux Shell tutorials I looked at, that's why I missed it. Sorry folks.) Type in set to see a list of the current shell variables, looks like I missed quite a few. SHELL, EDITOR and PAGER point to the programs you want to use for that purpose. HISTSIZE is for the size of the command history. The rest I am not sure about yet. Example: set HISTSIZE='20' to double your Command History. File Systems and your Media Have you tried putting more than one hard drive in a computer? It is a good way to initially expand your long-term storage. Plus if you somehow destroy the OS on your boot hard drive, the data on your second drive is safe. I would suggest to put /home on different media than your boot drive. This makes it easy to upgrade your computer and keep all your important stuff in one place. /var is also recommended if you plan on lots of data collection (think of log files out of control, filling your boot drive to capacity and possible crash). Unlike Windows, there is no D:\, E:\, etc for each new drive added to a computer. Everything is connected to root somewhere, primarily in /mnt, secondarily where you want it. ls /mnt shows the first three characters of the address of file systems mounted and ready for use on this computer. Not that handy. components shows all items connected to this computer and their full addresses, look inside computer to compare. df (Disk Free) to see mounted filesystems, how much room is available and where they are connected to root. So much better. tmpfs (Temporary FileSystem) is a small amount of memory setup as a RAM Drive that will be erased when the computer is turned off. Even if you are running OpenOS off the floppy, it is available. You might not even need a Hard Drive if your programs are small enough and you do not let the power run out. OpenOS is the default label on the hard drive you booted from, openos is the floppy disk. Small difference but important. Time for an upgrade! Type shutdown at the prompt to turn off computer. add another hard drive, look at its address (mine starts with a7f, replace with the first three characters of your hard drive), turn computer on component and df again to see what has changed cd /mnt/a7f and ls to see it is a blank drive. Let's give it a label in addition to an address. label -a a7f data Type df again and find "data" in the list. Go look at new label on the Hard Drive in the Computer. With all this potential, we have to put something on this new drive. make sure you are still in /mnt/a7f and create a directory mkdir doc cd doc start a new file edit ocNotes.txt take a few notes on what you have learned so far, save and exit. Self Test: Mount a floppy, Copy all of /usr onto it. Label it 'UsrBackup'. Look in /bin and figure out how to unmount the floppy. Use man pages for help. Now constantly going to /mnt/??? is not the best way to access other filesystems. We are going to attach this Hard Drive to root at /home. mount a7f /home or mount data /home ls /home to see if it worked This is cool, but we have a problem. If we reboot the computer, it will not remember that we mounted 'data' at /home. Note: Next part paraphrased from http://ocdoc.cil.li/tutorial:oc3_hard_drives We need to add a program that mounts the disk at /home for us when it is inserted. Every hard drive can have such an autorun script. It has to be named autorun or autorun.lua and must be in the root directory of the hard drive we want mounted, in this case 'data'. This script is automatically executed when the computer mounts our hard drive. So before we reboot: cd /home or cd /mnt/a7f edit autorun.lua Paste or type the next four lines: -- Mount this Hard Drive to /home local fs = require("filesystem") local proxy = ... fs.mount(proxy, "/home") Save and Quit Lastly, reboot ls should show us /home is available. Bonus: Not Enough Room! You want a geological database, projected to be just over 10MB in size. You could try to portion it out to 24 floppy disks, swap out hard drives, or set up a RAID (Redundant Array of Independant Drives) of Tier 3 Hard Drives wired up or next to your computer. It turns three Hard Drives into a single drive, but at a cost. Any Hard Drives added to a RAID will be wiped. If you take out any of the Hard Drives in a RAID all data on all drives are lost. Works like a Disk Drive with a LOT more room. (If you want to learn more, look up 'RAID Level 0'.) Least Signifigant Bits Ctrl-Alt-C to exit a running program Ctrl-C to restart computer while at the command line (think warm boot) One more directory: /net - where entire remote file systems are mounted. WIll be very useful later on. Look in minecraft/save/(world name)/opencomputers. You will find all the file systems in there sorted by component address. The edit.cfg is in /etc If you are having problems, post it on the Support Sub-Forum. Additional information, constructive critism or praise of this tutorial should be posted below. End of Line. Edit v1.1: Added dgelessus's comments into the tutorial, Command History. Spelling Errors.
  6. OpenComputers v 1.45 for Minecraft 1.7.10 Black Hole Tutorial 01- Learning the Chips v1.2 You can skip this: I promised if I got help getting this mod to work I would write a tutorial. The best way to learn something is to do it yourself, so consider it more of a walkthrough. Mods I consider NEI (Not Enough Items) essential, both for playing modded Minecraft and learning OpenComputers. Tinker's Contruct is nice for the Gold and Iron Oreberry Bushes. The Oreberries are equivalent to nuggets for crafting and they make a lot of berries. I use EnderIO for conduits (pipes) to transfer power to the computers. MAYBE IC2 wire, Buildcraft pipes work as well? Buildcraft, Electriacal Age, IndustrialCraft 2 Exp, Mekanism, Thermal Expansion are compatible for power needs. Since Extra Utilities outputs RF, it should work as well. STARTUP Make a superflat map in creative mode. We are going to look at and hopefully understand the basic components of the computers. Spawn in one of each of the Computer Cases (Tier 1-3 plus Creative) with at least 2 spaces between them all. Also a copy of the OpenComputers Manual, which is fantastic and makes this tutorial mostly redundant. Really, read the book and come back. I'll wait. Before we go any further, we need power of some form (unless you have no powergen mods, then you get a warning and computers with no need for power). I am using a Creative Energy Cell from Thermal Expansion behind each case, except for the Creative Case,which powers itself. If you have WAILA installed, it will show you the power held in each case when you look at it. (Power requirements can be adjusted or turned off in /config/opencomputers.cfg in your minecraft directory. If you screw up the file, delete it and a new one will be made.) Look inside the Tier 3 Case. Nice! Lots of room for the best stuff, but oh so expensive. In each slot in the Case you will see a Roman I,II or III (Equivalent to 1, 2 and 3) in the lower right corner. This indicates the maximum Tier Item that will fit into that slot. Example: Tier 1 Hard Drive will go in any Hard Drive slot, being the lowest Tier. Tier 2 Hard Drive will not go into Tier 1 slot, but will go into a Tier 3.Look inside the other three cases now. I bet Tier 1 feels less then adequate. That Creative Case is a thing of fantasy, but yours to play with if you want. All have different abilities in increasing amounts (Tier 3 and Creative Cases have an internal Disk Drive in the lower right corner, more on that later.) Filling the slots Spawn these items into your inventory: Disk Drive - Used to Read/Write Floppy Disks Tier 1, 2 and 3 Screens - Visual interface Keyboard - Tactile Input Tier 1, 2 and 3 Central Processing Units (CPUs) - Ties everything together Tier 1, 2 and 3 Graphics Cards - Writes to Screens Tier 1, 2 and 3 Hard Disk Drives - Long Term storage of your data Tier 1, 2 and 3 Memory Sticks - Short Term Storage of your data (gone when power is off) Three Floppy Disks with openos Right-Click on the Tier 1 Case. In the NEI search bar at the bottom of the screen type in openc to show just the items and blocks from this mod. Hover over the top left slot in the Tier 1 Case. Leave your mouse there and look over at NEI. You should see some items highlighted, scroll down in NEI for more. These are cards that will fit into that slot. Hover over some of the other slots and look at NEI and your inventory, same thing. (Hover over the top center slot to see what CPUs can fit in there.) This subtle highlighting is a bright idea and will be useful to you learning what goes where. Mouse over the Tier 1 Graphics Card in your inventory. Now Shift-Click it into the Tier 1 Case. Bam, right were it belongs. Try the same with a Tier 2 CPU and nothing. Just a kindly developer trying to help you out. While we are at it, take a look at the label on the Tier 2 CPU. Notice the letters are Gold(Yellow) in color. Look at the Tier 1 CPU and see an Iron(White) Color. Can you guess what color Tier 3 labels are? (Hint: diamond) Put into each Case the same Tier CPU, Graphics Card, Hard Drive, and Memory. We are using the bare essentials, no other items are needed. You do not have to fill all the slots for any particular item (i.e. memory). The case is okay partially empty as well. You can always put in more memory, larger hard drive or an additional card later. Modularity is a good thing. You can delete the Creative Case now or fill it, your choice. (Graphics Cards are actually optional, as long as you do not mind not being able to see anything. Usually called a headless computer. Yes, there are uses for this to be talked about elsewhere.) Put on top of each Case a Screen (using Shift-Right-Click) of the same Tier, and put a Keyboard on the back of each Screen. (The Keyboard is what lets you type when looking at the screen. It can be on any side of the monitor. It also works if you put the keyboard in the space next to the Screen pointing at the Screen.) Put a Disk Drive next to each Case. (Yes, the Tier 3 doesn't need one, but bear with me.) The computer will want to find an OS which it currently does not have. Put one OpenOS Floppy Disk into each Disk Drive (Shift-Right-Click on the drive with the floppy to insert, Shift-Right-Click with an empty hand to pull it out.) Zhu Li, Do the Thing! Once each Case has a Graphics Card, CPU, Memory ,and Hard Drive it is time to turn a computer on (Press the green and gray power button to the left of the slots or Shift-Right-Click the Case). BEEP-BEEP What? Try again. BEEP-BEEP Ah, crud what went wrong? Time to spawn in the Analyser. This handy tool will give you a lot of information, but what we want is the last error from that case. Shift-Right-Click the Case with the Analyzer and look at the top of the list. no bios found; install a configured EEPROM Looks like we need a Lua BIOS. Great, now where do we get that. In Survivial, you have make an EEPROM then put that with a book in a crafting table to get your Lua BIOS EEPROM. Spawn or craft one and shift-click it into the Case. It should have gone into the slot left of the power button. This contains the program that gets the computer started and looking for something to run. Do the same for the other cases. (Small note: you can write your own. Why you would want to do this is a topic for later.) Not that Thing, the other Thing! Now try that power button one more time. If no beeps are heard, click on the screen. Welcome to your first computer! Now do the same to the other Cases. If there is a problem, try using the Analyzer on it. Look at each screen (right-click to pull up a window). You might notice a few differences between them. Each Graphics Card supports a better resolution and more colors (if the Screen can handle them). The Tier 2 and 3 monitors support a touch interface (clicking on the screen) if no keyboard is attached. Also of import is the amount of memory remaining for your programs to use, displayed at the top of the boot screen. Type install and Enter, then 1 and Enter to copy the OS onto the only Hard Drive available. Kind of like installing Linux or Windows from a DVD. (Your Tier 1 computer will run out of memory, that is intentional. Ask why somewhere else. Add another Tier 1 Memory to the Case, reboot and it will work.) After it is done rebooting, you can take out the OpenOS Floppy Disk and put it somewhere safe. You might make a mess and have to reinstall. This is a small but very functional Virtual Machine running in Minecraft. Most things you can do with your really old PC at home, you can do here (Networks, File Servers, Games, Security, Automate all the things, etc). All it takes is a lot of study, experimentation and writing down what you have learned. Also more than a little iron, gold, emerald, diamond, redstone, coal, paper, time and swearing. Time now for you to do the same thing in your survival world. If you find the recipes too simple they can be changed to Hard Mode in /config/opencomputers.cfg, along with a lot of other details about this mod. It is worth your time to take a quick scan of the possibilities. QUESTIONS: Q: I have a computer running, now what do I do with it? A: This is where your programs come into play. Computers excel at collecting, sorting and displaying data. They are a good place to write software for your robots and drones. With additional components, a lot more is possible. They are best at doing exactly what you tell them to (especially if you didn't mean for them to do it that way). Q: What about the rest of these cards? A: This tutorial was just to get you a computer that runs. Usage of other cards would be in future tutorials. Q: This is great and all, but I just wanted a robot. A: Robots use the same base parts and OS as a computer, plus upgrades to enhance their natural player-like abilities. Here's a link to the Robot Overview Tutorial. Least Signifigant Bits, I Promise Almost forgot, right-click on any Case in NEI. You should find an in-game manual. Nice! API commands, if used, can be found by clicking on the top right arrow. Try this with other items. When building these, anything to help you with auto-crafting is a godsend (Super Crafting Frame, Applied Energisitics 2, Assembly Halo from Botania, etc) When I learn more, I will be writing it down in these forums as a tutorial. (What have you taken note of?) If you are having problems, post it on the Support Sub-Forum. Constructive critism or praise of this tutorial should be posted below. End of Line. Edit v1.1: Added proper list of powergen mods. Link to 2nd Tutorial. Minor formatting. Edit v1.2: Added OpenComputers Manual.
  7. Getting Started A Open Computer's Tutorial By PotatoTrumpet Introduction A mod like Open Computers (OC) can be confusing to new users. Some people need a little guidance to get started. If you need more in-depth help, check out the wiki. It is recommended that you know the basics of the language that we will be programing in, know as Lua. It is recommended to read the Lua 5.2 Reference Manual to get the basics of Lua down. Components and Modules Assuming you know the crafting recipes for the parts required, here is what you will need for this tutorial: 1x Power Converter 1x Capacitor 1x Computer Case (Tutorial uses Tier 1) 1x Monitor (Tutorial uses Tier 1) 1x Keyboard 1x CPU (Tutorial uses Tier 1) 1x Memory (Tutorial uses Tier 1) 1x Graphics Card (Tutorial uses Tier 1) 1x Hard Disk Drive Tutorial uses Tier 1) 1x Disk Drive 1x Blank Floppy Disk Version Dependent: If you are using version 1.3.0 Beta 1 or Higher, you will also need a floppy disk with Open OS on it. Part 1 : Power Unless it is disabled in the config, Computers require power. For this tutorial, I have already set up a power supply. Once you have your power supply set up, you need to make it usable! Hook up the power to the Power Converter as shown. ​Next, You need a way to store the power. Place the Capacitor as shown. Part 2: Building Blocks Now, its time to start building the Computer. Start by putting the Computer Case as show, then a monitor on top. Next, we need a place to put the floppy disks, plop the Disk Drive down to the right or left of the Computer Case. As basic logic assumes, you need a keyboard to interact with the computer. Place a keyboard on the left, right, or back of the monitor. No matter where you place it on the monitor, if you click the monitor, it will open up. Part 3: The Inner Workings All that you have now is a Case, Monitor, and Disk Drive. For the computer to function, it will need the following: a CPU, a Graphics Card, some Memory, and a Hard Disk Drive. To install these devices, you need to right click on the Computer Case. When the GUI opens up, you will see slots for different items. The easiest way to put the items in the correct slots is to Shift-Click them in. Once everything is installed, you are ready for the next part. Part 4: Starting Up ------------------------------------------------ IF YOU ARE NOT USING 1.3.0 OR HIGHER, YOU ARE DONE ------------------------------------------------ Now, the computer needs something to boot. Put the floppy disk labeled "openos" in the Disk Drive. Now, go to the Case and click the Giant Green Power Button. The computer is now usable! Now, you need to install the OS. To do this, Right click on the Monitor. A GUI should appear, this is called the 'Terminal'. Type 'install' into it. It should ask you to press 1 to install it to the "Hard Disk Drive". Press 1 then enter. It will then ask you if you want to reboot. I suggest rebooting so that it boots off the HDD. At this time, you should remove the floppy from the disk drive. You can now use your computer. Tutorial Version Written on 6/12/14 at 1:05 PM CDT (Chicago)
  8. So, you want to know what this `require` thingy does? Or maybe you installed a library you can't load? You want to write your own library? Then we are here to help you. In this tutorial, we are going to explain how the `require` function and the `package` library works. So, lets get started! Loading Libraries In order to load a library, you can use the function `require`. But what does `require` do? Where does it pull these libraries from? `require` needs the name of the library you want to load, but not the path to that file, so it needs to search the file system somehow. This is done by looking at the string in `package.path`. You can open up a lua prompt and try to print it now. The default value of `package.path` is `"/lib/?.lua;/usr/lib/?.lua;/home/lib/?.lua;./?.lua"`. Each string between the `;` is seen as a path and the name you provide is used to replace the `?`. Then require tries all the paths and sees if the file exists. If it exists, it is executed and the return value is stored and returned to the caller. The vaule is stored so `require` does not have to load the same library twice. This improves loading times and minimizes RAM usage! So, lets say you installed a library in `/usr/local/lib` and `require` can't seem to find it. How do you tell `require` where it needs to look? This can be done by changing `package.path` to include the installation location of your new library. So you need to encode your new directory in the path. First you need to make the path to the new folder recognisable to `require`. First you need the path to the directory (`/usr/local/lib/`). This needs to be followed by the `?.lua` to do the substitution with the name. Then we get the following path: `/usr/local/lib/?.lua`. So now require knows where to find your library! Writing Libraries So, now you know how to load a library, but not how to write one, so that is what we are going to do now. The library will not do propererror checking, that is left as an exercise to the reader. So, what will our library do? It will be a wrapper around the movement functions of the `robot` api, but it will move the robot multiple times. So `movebot.forward(10)` will try to move the robot ten times. So open a file called movebot.lua and we can start! First we need to require the robot api. We can do this like you would do it in any other file, with `local robot = require 'robot'`. Now we get to the fun part. At the end of the file, we need to return a table which will hold all the functions. I find it easiest to create this table beforehand, but you can also create it at the end. If you do, don't forget to localise your variables! So, lets create this table! local movebot = {} Now we can install our functions into it! As said before, these functions wil have no error checking, this is left as an exercise to the reader. The functions will get a number and need to call the respective function from the robot library that many times. function movebot.forward(x) x = x or 1 for i = 1, x do robot.forward() end end function movebot.back(x) x = x or 1 for i = 1, x do robot.back() end end function movebot.up(x) x = x or 1 for i = 1, x do robot.up() end end function movebot.down(x) x = x or 1 for i = 1, x do robot.down() end end Now we only need to return the table we just created and we are done! return movebot The whole file should now look like this: local robot = require 'robot' local movebot = {} function movebot.forward(x) x = x or 1 for i = 1, x do robot.forward() end end function movebot.back(x) x = x or 1 for i = 1, x do robot.back() end end function movebot.up(x) x = x or 1 for i = 1, x do robot.up() end end function movebot.down(x) x = x or 1 for i = 1, x do robot.down() end end return movebot Now, save the file and you are ready to require the file! In fact, you can try it out from the lua prompt. If it errors, make sure you try to `require` the right file and that it is in your `package.path`. And Now? Now you should be ready to install and write your own libraries and make changes to the libraries of others. If you still have questions, feel free to ask them here!
  9. Hello everyone! I made a tutorial for my server mates and myself, showing to them how to craft a basic Tier 2 Computer with all the necessary and recommended components in hard recipe mode. I did that because this recipe mode contains a lot of crafting steps, so I derived the most efficient way of crafting all the parts you need (with as few steps as possible). Also, the tutorial also shows all the basic materials required to get the Computer, so you know exactly when you are ready to craft it. Now I am posting this tutorial here in case anyone wants to use it. It might also be useful as an example for the difficulty involved in the hard recipe mode. The tutorial consists of two parts, the first part shows how to craft a basic Computer, the second one covers specifically crafting the Internet Card (also including material list and all the crafting steps). You can find the tutorial here. I hope someone will find this tutorial useful. I would appreciate feedback on this, I might do more of these (for other recipe modes as well). Sincerely, Vexatos
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.