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


  • Content Count

  • Joined

  • Last visited

  • Days Won


mpmxyz last won the day on April 14

mpmxyz had the most liked content!

1 Follower

About mpmxyz

  • Rank
    Junior Member

Profile Information

  • Gender
    Not Telling

Contact Methods

  • GitHub

Recent Profile Visitors

1345 profile views
  1. Content Introduction Reproducing an Error Error Messages Debug Output Appendix List of Error Messages Using a Debugger Ad alert: cbrowse Introduction Writing code is one thing, making it work is a completely different story. More often than not something is not working as intended and sometimes your program just crashes the instant you run it. This can be fun and inspiring but most often it is just frustrating. This guide is meant to introduce you to several useful debugging techniques with the primary focus being OpenComputers and Lua. I could use your help to improve this guide. If you spot an error or miss some content: Please tell me! Reproducing an Error Even with maxed out debugging skills you are going to have a hard time fixing a bug if you can't see it. So step one in debugging is finding a way to reproduce the bug. This is something that does not necessarily require programming. You can even do that as a user! It is very good manners to add a step by step instruction to your bug report: Write down every step of what you did to reach the bug. Test this instruction yourself and try to find ways to make it as short as possible. Maybe the work you did before opening *this* file did not have anything to do with your bug. Also try some variations to find out if this bug needs a specific setup or if it happens in a more general use case. If the program had no trouble on a T3 screen but crashes on a T1 screen there might be something involving the resolution or color depth. Does it work with a T2 screen? This makes it very easy to see the bug in action. Even if it is just 1 in 10 times. It helps. Beware of the Heisenbug which only appears when you are not watching it! ;-) Error Messages Debug Output Appendix List of error messages Syntax Error: detected when loading code syntax error near 'x' 'x' expected near 'y' 'a' expected (to close 'b' at line c) near 'c' Most of the time it's just a missing 'end' or bracket. That's easy to see if you use indentation. Sometimes it is a bit harder to find, but b()=2 clearly is not correct. <eof> means the end of file Runtime Error: detected when the code is executed Runtime errors aren't as easy. They can hide in rarely used code and there is a variety of them: bad argument #1 to 'func' ('type' expected, got 'wrongType') You called a function but one of the parameters you've given has the wrong type. You should check the functions documentation and compare to how you use it in your program. attempt to index local/global/field 'name' (a 'type' value) attempt to index a 'type' value You tried to access a table field but there actually was no table you could access. (but nil, a number, a function etc.) Check the return value/variable you are using and work backwards to find out where a check has failed, the value has been overwritten or not written. table index is NaN/nil You tried to access a table using an invalid index. Everything is allowed to be an index except nil and NaN. attempt to call local/global/field 'name' (a 'type' value) attempt to call a 'type' value The return value/variable you tried to call as a function hasn't been a function or a value with a __call metamethod. Using a Debugger In other environments it is possible to use an external program to help debugging, a 'debugger'. This would display and modify the values of variables and would allow to stop the program at previously defined breakpoints. After stopping it is possible to step through the program line by line to check what it is doing. Just to be clear: This is possible in normal Lua but OpenComputers already occupies the same feature to limit execution time. Ad Alert: cbrowse You can easily add advanced debug in/output by installing my program cbrowse. The debug interface works by calling this: local a, b, c = 1, "A", {test = true} require"cbrowse".view(a, b, c) Tables can be manipulated. If you want to change the value of a variable you have to temporarily use a table and manually export the result back to the local variable. local a = 1 local _t = {a = a} require"cbrowse".view(_t) a = _t.a But there is one drawback: None of the events happening while cbrowse runs reach your event.pull in your program. Event listeners work though.
  2. I can't help you directly because I don't have OpenSecurity installed and you've already got too much code for me to walk through manually. But here are a few hints: Add debug output! (A lot!) You want to find out the values of important variables throughout your code. Compare the output to what you would expect! You can narrow down the area of the error because it must be somewhere after a correct output and before a wrong output. Move your outputs closer to the error. When you found the error fix it. You can now remove all remaining debug output. In this case this part of your controller is quite interesting: data = crypt(msg, cryptKey, true) -- print(data) if data == "true" then term.write("Access granted\n") A printout of msg, data and cryptKey in server and controller would be interesting. Since cryptKey is a table you can use serialization.serialize(cryptKey, true) to get a neat output. On a side note, here is how you shouldn't do debug output: for i = 1, 10 do print(i) local a = i * 2 local b = i * a + 2 print(a) a = a + 2 print(a) print(b) end It is okay if you just check the value of one variable but it can confuse you a lot if you have long loops and many variables. (Which value belongs to which variable?) It is much better if you add names and descriptions to your output: for i = 1, 10 do print("new iteration i=",i) local a = i * 2 local b = i * a + 2 print("1 a=", a) a = a + 2 print("2 a=", a) print("3 b=", b) end This way it is much easier to know which variable is being displayed and where the output comes from.
  3. Update (13.04.17) -added --address option to specify used tape drive
  4. Update 13.04.17: -fixed a bug which was caused by filesystem.list returning file names without sorting in newer OC versions -added crunch to oppm I decided not to add a 'self extracting archive' option because that deserves to be another program. The output of that program could be compressed though. My next target will be full Lua 5.3 support. I have to check memory requirements after that though. (lots of new operators) Update 16.04.17: -Added Lua 5.3 Support (Operators were missing.) Memory requirement didn't increase noticeably. But the parsing table grew by 12KiB. So there is some increase.
  5. It's actually a good idea to keep using this part as it allows for easier extension using options: local args, options = shell.parse(...) --"prog arg1 -ab --option --value=2 arg2 arg3" will result in: args = {"arg1", "arg2", "arg3"} options = { a = true, b = true, option = true, value = "2", } But this needs further processing because the received arguments are strings and the functions expect number values corresponding to a light number and a color: local shell = require("shell") local colors = require("colors") local args, options = shell.parse(...) (...) --You can access a table using "yourTable[yourIndex]". --'tonumber' converts a string value to a number. 0xABCD00 is just a hexadecimal number. ColorSet(tonumber(args[1]), tonumber(args[2]))
  6. If you have installed an internet card in your computer you can access the "real world" internet. One example on what you could do: wget 'https://raw.githubusercontent.com/mpmxyz/ocprograms/master/home/bin/tar.lua' This will download the file tar.lua. It is a small program I wrote to interact with real world *.tar archives. Note: On some OpenComputers versions you had to install internet related programs separately using an "internet disk".
  7. Disclaimer: I haven't thought through everything; it's just a quick idea. You'd have to hack into the component system and add a "virtual" gpu bound to a "virtual" screen. Both virtual components should be set to be the primary one. It involves a lot of writing code to support the basic functions of gpu and screen. Events have to be modified, too.
  8. Isn't there something like a speed upgrade for MAs in AE2? http://ae-mod.info/Acceleration-Card/ If you want to forward a crafting request to OC you can use an AE2 interface to a buffer robot. You could have one pair for compressing tasks and another pair for uncompressing tasks. I could imagine having two columns of robots. The rear column is distributing the items and the front column is doing the crafting. The two robot columns would be controlled by broadcast wireless signals. The two (or more) input buffers would limit themselves to something like 1000 crafting actions and would give way to the next buffer to avoid one crafting request to block the other. This system is limited by the item transfer rate of a single robot though.
  9. Sometimes it is helpful to write a small tool. To give you an example - it requires you to remove the blocks adding components and rebuilding them in the right order: pastebin get LCXQ9JH1 factory_companion.lua factory_companion test.cfg [enter number of different components] [enter a field name for every component type, can be nested (i.e. "inventory", "furnace.right" or even an empty string to add a list to the root table)] [add the stated component to the network; the program listens to "component_added" signals] [press enter to save config file] cat test.cfg It's just a quick and dirty program. It could have been nicer. You can take it as an example for a tool of your own.
  10. Can you show the part of your code that does all that? That might help replicating the error.
  11. Did you use the given command? It works fine for me. What is your error message? (Does your OC computer have an internet card?)
  12. Finally a place to brag with my current project. It still needs some fine tuning but it is almost done. If you read the output carefully you get some hints about the features:
  13. You haven't seen the part about slavery, did you? For me it looks like a parody of real license agreements. PS: Nice UI, but I wished that it was fully translated... I just formatted the disk because I don't understand Russian at all. xD Do you already use a localization library? A well made one should make your live easier.
  14. Your program is nice. Processing the component documentation to make it more readable is a nice idea. I read through your code and noticed one thing: string.find(methodDoc, "[--]") When writing this you probably thought that this matches the two minus signs within a documentation string. But the square brackets indicate a set of possibilities for one character only. "%-%-" matches two minus signs. Since you adjusted the indices in the following string.sub calls there is no noticeable effect on your program. (So if you "correct" that string.find, you have to change the indices again.) What about a generic documentation for libraries? debug.getinfo can get you a lot of useful information. (Another reason to use good parameter names when writing your library. ;-)) PS: Have you tried my component/library program? While it is able to display unmodified method documentation via tostring(method), it has a much larger focus on working with/trying out things. A split screen with both programs running in parallel would be perfect. (A multi-term-implementation is coming soon but built-in multitasking is still missing.)
  15. Introduction Are you creating the secret underground base? A pyramid maze with all kinds of traps? Or just your high security door lock? Then it's very likely that you are using redstone. More complex designs require bigger circuits or computers. (redstone computers?) Programming with redstone cards or blocks is quite straightforward, but it can be quite annoying to always repeat yourself: local component = require("component") local sides = require("sides") local colors = require("colors") local rs = component.redstone rs.setBundledOutput(sides.north, colors.blue, true) --close entrance os.sleep(1) rs.setBundledOutput(sides.north, colors.green, false) --open exit os.sleep(10) rs.setBundledOutput(sides.north, colors.green, true) --close exit os.sleep(1) rs.setBundledOutput(sides.north, colors.blue, false) --open entrance This library makes things easier and your code more expressive: local component = require("component") local rstools = require("mpm.rstools") local rs = component.redstone --inverted to make true == open local entrance = rstools.digital("output", rs, "north", "blue").inverted local exit = rstools.digital("output", rs, "north", "green").inverted entrance(false) --close entrance os.sleep(1) exit:pulse(10, true, false) --open exit for 10 seconds os.sleep(1) entrance(true) --open entrance Documentation Depencencies Software OpenOS Hardware Redstone Component Installation Download the file and save it as the library "mpm.rstools". Download (last update: 29.01.16) github mkdir /home/lib/mpm cd /home/lib/mpm wget 'https://raw.githubusercontent.com/mpmxyz/ocprograms/master/home/lib/mpm/rstools.lua' Known Issues None.
  • Create New...

Important Information

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