Here is some feedback I have on your code. Keep in mind this is the nicest, most elegant set of APIs I have seen on here in a while, and I am really straining myself in order to provide you with some feedback. :P/>/>
Aware: I really like how you structured most of your functions. The modposition wrapper is very elegant, and the moveto() is a great solution for general movement. I don't understand why you have move in front of most of your functions… it makes them more verbose, and makes it harder to make Aware a drop-in replacement for the default turtle api (eg find all "turtle" and replace with "aware" in a file). Also, I really like the idea of the "shaft" flag, but I feel it could be done a tad better. Instead of a flag, give the turtle 3 modes: move, dig, and shaft. In move mode, it just tries to move. In dig mode, it digs in the direction it is trying to move, and once done, moves in that direction. In shaft mode, it does the same thing as dig mode, it also digs above itself. This would eliminate the need for the digging functions, and would make it simple to reuse code for each scenario, and would remove the bug where it digs forward into squares that in does not plan to move into when in shaft mode.
Biodesign and biobuild are amazing. Pure and simple. The way it only moves to blocks that actually need to be built is a neat optimization. In some cases, I imagine it would be nice if you could clear the are you are building in, or start at a different location. For example, a building with a basement. You could tell the turtle to build something, and WHERE it should start. The turtle goes to that location (digging down if it needs to) and then just goes through the entire area (possibly as a toggleable flag) clearing all the existing blocks and adding its own. As for the size limitation, instead of biobuild being artificially limited to 20*50, you should make it able to build any size, even manually created designs, as long as they follow the right basic structure. This has one major difficulty: you would have to store the ranges of x and y in your matrix for each layer, so it can be arbitrarily large. Ill get to this in a second. A feature request for buibuild would be to make it possible to "scroll" around, and make layers up to hundreds of squares in size, and possibly paste around objects within a layer to other coordinates, but that is a LOT of work. As an alternative: a simple tool that converts a layer expressed as a plaintext file into a layer, so you can manually design things using text editors.
Feature ideas: take a design, and split it into parts, send the parts to multiple turtles, and have them each do one part. Now you can make giganting floating castles in the sky in no time at all!
About the matrix program… I feel like yours does not add quite enough features over just doing it manually (array[x..":"..y]=3 seems just as easy as matrix.set(array, x, y), but that might just be me). I have decided to hack up a fully compatible, more universally useful version, which allows any number of dimentions. I'll post it as soon as I am done.
Good work!
Thanks for all the feedback! Glad to see someone's looking :-)
The verbosity was done on purpose early on so that i wouldn't accidentally confuse my own moves with turtle.'s, then when i added more later it got.. well.. verbose. The shaftmode was an afterthought to the mining app that i haven't posted yet. The extra blocks in front weren't an accident, it's supposed to dig 2-tall so i can walk, and 2-wide so i can have a ladder down to mining level, 1 block adjacent to the starting position.
The movement functions in general i'd like to clean up as those are some of the first lua functions I ever did, but haven't touched them because they just work (though i did go back and do the modposition thing when i changed how location was stored). I'll revisit them when i'm feeling masochistic :-)
Biobuild actually does build relative to itself, but the program itself doesn't determine movement. You could accomplish this by just using the little goto app and say "goto x y z o" then "build shack" - not quite as automatic as you're suggesting but i guess i could add in some command line arguments to automagically call goto? I'll have to think about the clearing flag - that shouldn't be too hard, but i'm not positive about that.
The copy/paste is doable, and i
think i know how it will work.
The scrolling itself should be possible, but i'm not so sure about storing and traversing the data once the size is no longer known. I kinda cheated on that and now it's going to bite me.
That being said, I'm
really not happy with the matrix format and i want to nix it altogether, ideally. The problem is multidimensional array init in lua - i haven't really figured out how to tackle that yet since they're really just nested tables, but you have to initialize a table before you can index it.
array = {}
array
= {}
array[j] = 3
is very verbose, but you can't shortcut as far as i can tell. And I can't try to index uninitialized tables, so unless I give some arbitrary size limit to the layer size and just initialize a big empty nested 2d array to then come back and write values into, i'm not sure how to tackle it. I wrote matrix because i was bashing my head against 'attempt to index nil' errors when trying to manipulate layer tables.
I could avoid these problems for the time being if i limited structures to… say… 64x64xN - big enough?
I suppose turtles could work in tandem if they split up x/y areas instead of truly working in tandem. A program to parse and split a design file might accomplish this, i'll think on that.
All the solutions i came up with in the past would require the entire turtle work on some sort of action queue allowing it to listen for rednet signals and keep a running list of other turtle positions - but that won't work for non-wireless turtles and that annoys me.
Action queue is the same solution I came to. I wrote my existing code (that does similar things to your aware api, plus minimal pathfinding), then realized I wanted to make it work with swarms, so I am basically starting over and planning to do exactly that. It is difficult for sure, but it seems like the ultimate possible goal, so hey, why not.
I dont exactly understand your avoidance of rednet… it seems fine to me. Also, correct me if I am wrong, but couldn't turtles use the wired rednet api to communicate when in contact? It might be a little slow though…
The fact that turtles aren't multithreaded is what gets me. I don't really want to write an application the way i would need to in order to accomplish that. EVERY program would have to submit to some sort of queue, and that's just no fun in my opinion.
My latest idea, however, is when i do my detect() before movement and it comes back true, i can check to see if a peripheral exists in that block, and if so - attempt to get it's computer ID. Then do something where if my ID is less than theirs, i have seniority. Then the one with the higher ID sends a redstone signal to indicate they're moving out of the way, move, then the older one resumes. If the older one doesn't get a redstone signal in some time frame, they assume it's inactive or a computer and attempt to move around it.
That would work on all turtles regardless of wireless status. But i haven't tested to make sure there won't be a race condition where they go all thunderdome on each other =)