This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
nitrogenfingers's profile picture

Turtle Inventory Management & Organization

Started by nitrogenfingers, 12 August 2012 - 04:17 AM
nitrogenfingers #1
Posted 12 August 2012 - 06:17 AM
With the advent of CC 1.4 turtles now have the ability to access and store things in chests, furnaces, storage mine carts and other turtles. This has utterly changed the game- now turtles are not restricted by what they carry, in fact theoretically they have an infinite inventory, limited only by as many chests you can place. But in practice it’s not quite as simple as this; a good understanding of the working and limitations of the turtle’s inventory system, as well as a bit of clever thinking is required to realize their full potential. This tutorial is designed to teach about how to get the most out of turtle inventory management.

The first step, as with understanding anything programmatic is to check the documentation and see what tools we have available. We’ll be using the turtle api exclusively, which you can read here: http://computercraft...le=Turtle_(API)

Below are the pertinent functions we’ll be using as well as a description of what they do:
turtle.select( slotNum ): This chooses which slot in the turtle’s 16 available slots to “select”. The selected slot is where the turtle by default places all items picked up, as well as where he drops and places from. It returns nil.
turtle.compare(): This compares the block directly in front of the turtle with the selected block in his inventory. If they are the same, it returns true, and false otherwise. This also comes in a turtle.compareUp() and turtle.compareDown() variety to perform this operation on the block above and below the turtle respectively.
turtle.compareTo( [slot] ): This compares the selected block in the inventory with a second block, the index of which provided as a parameter. It also returns true if the blocks have the same ID, and false otherwise.
turtle.drop( [count] ): This drops as many items as are passed through in the count parameter directly in front of the turtle. If the number exceeds the number of items in the slot, it just drops everything, so you can empty a slot with turtle.drop(64). This also comes in a turtle.dropUp( [count] ) and turtle.dropDown( [count] ) variety for above and below the turtle respectively. It returns a Boolean- true if the item was successfully dropped and false otherwise (if for example trying to drop into a full chest)
turtle.suck(): The turtle will attempt to collect any items in front of it, much the same way a player does when moving near anything that can be picked up. Sucked items will be placed in the selected slot, or failing that whatever slot closest to 1 is empty. It returns true if anything was picked up, and false otherwise. This also comes in a turtle.suckUp() and turtle.suckDown() variety to suck above and below the turtle respectively.

Looking at that list we can see turtles can easily put and take things out of a chest, but it doesn’t explain to us how. Give it a try- put a turtle in front of a chest, give him a few items and try sucking and dropping them into the chest to see how it works.

What you’ll notice is there’s no way to control what index the turtle places his items into! Instead they will place it into the nearest available slot closest to the top let corner, filling out left to right, top to bottom much as a turtle’s own inventory does. This is the same story for sucking- it will suck the index nearest to the top left from the chest until it is empty. This is actually what we refer to in computer science as a “queue”, much like a queue in real life the first person to step in is the first one to come out- First-in First-out, or FIFO. They are relatively uncommon compared to the more familiar “stack” (I visualize these with a pile of bricks) in which the most recently placed thing is the last to be removed- LIFO. Recognizing this is a big step in understanding how to manage chests with more than one item.

So when a turtle places items in a particular order into the queue how can we know he gets the same order back when he removes them? The answer is to make sure you start and finish removing at the same index- so for example if emptying items 11-16 into a chest when you start sucking again start at index 11 and go through until 16. The code below demonstrates this:


--[[In this example I've used a sequential index- but if your turtle has gaps in his inventory, you'll need to have a list of every entry]]--
local firstItem,lastItem = 2,16
--This will drop everything into a chest
function putAwayInventory()
for i=firstItem,lastItem do
  turtle.select(i)
  turtle.dropDown()
end
end
--And this will pick it up in the same order!
function pickUpInventory()
for i=firstItem,lastItem do
  turtle.select(i)
  turtle.suckDown()
end
end


Of course, if our turtle needs to do more than one dump of stuff we’re in trouble- we can’t access those other items, just the ones that appeared first in the queue- FIFO remember? We can solve this by having multiple chests and only dumping in one at a time, but this is a bit complicated.
A better way is to SORT our inventory as we go- once we collect a series of things we should put them away in a special order so our turtle can conveniently take them back up again. So how can a turtle do this? Well remember that though we can’t identify a block by its ID alone, we can compare it with blocks in our inventory. So the solution is that the turtle carries around the items it needs to be able to sort, and then compares them one by one until it finds it’s match- once it does it can put it away somewhere it can find it again. So we’ll be using our turtle.compareTo() function for this:


--[[A list of every item the turtle recognizes, indexed by the slot it is found in it's inventory]]--
local items = {
[14] = "COAL",
[15] = "IRON",
[16] = "DIAMOND"
}
--[[We pass in any slot, and return the name of whatever it is we found, or "unidentified" if the turtle doesn't know]]--
function identify(selectedSlot)
turtle.select(index)
for slot,name in pairs(items) do
  if turtle.compareTo(slot) then
   return name
  end
end
return "unidentified"
end


I’ve used a simple string as our value here but those who are super clever might want to use a function instead- containing instructions on what to do with the identified item!

We can do this with theoretically 15 items with a single turtle, but the observant of you will realize 2 issues with this
1. There are way more than 15 kinds of blocks in minecraft
2. This leaves only 1 slot for the turtle to pick things up with, minimizing efficiency

In fact, if you have a mining turtle for example he will have to stop every time he digs a block and sort it in case he misses anything useful! Not even close to an idea solution.
So how do we solve this issue? Remember turtles can drop their inventory into chests, furnaces and turtles- turtles which themselves can sort your items for you! There’s no limit to how many turtles you can place- with an array of sorting turtles you can pass items back and forth from your mining turtle to recognize what the item is, and once it’s been identified put it away. If a turtle doesn’t know what it is, you just move onto the next one. Here’s an example of how that code might look:


--[[The code for our Sorting Turtle(s)]]--
function runIdentification()
--Remember turtle.drop() always places in the FIRST slot,
--not the turtle's selected slot- so make sure this is empty.
turtle.select(1)

while true do
  if turtle.getItemCount(1) > 0 then
   --This uses the same method as in code sample 2
   local item = identify(1)
   rednet.open("left")
   rednet.broadcast(item)
   rednet.close("left")
  else
   --We wait patiently until something arrives
   sleep(0.1)
  end
end
end
--[[The code for our Mining Turtle]]--
--[[Although we drop into the first index, we suck into the selected index- so this can be anything we like]]--
function sortItem(itemSlot)
turtle.select(itemSlot)
--For our rednet call
local id, itemName = -1, "unidentified"
while true do
  turtle.drop(64)
  rednet.open("left")
  id, itemName = rednet.receive(5)
  rednet.close("left")
  --If we've found what we're looking for, we can break
  if itemName and itemName ~= "unidentified" then
   break
  else
   --Move to the next sorting turtle in the line
   turtle.turnLeft()
   turtle.forward()
   turtle.turnRight()
  end
end
end

In this example we’ve assumed the turtle starts facing a sorting turtle, and there’s a long line of additional sorting turtles to his left.
Once you’ve identified what you have what do you do with it? Again it’s really up to you. If you need your turtle to retrieve that item again, rather than playing around with queues I’d recommend having a series of dedicated chests- chests designed to hold only one kind of item, that only the turtle has access to, and can retrieve on request. You might want to have someone with access to take stock, but if you’re really clever you could program your robot to keep track of all input and output, and produce reports on how much stock you have! In fact, the sky’s the limit when it comes to what your turtles can do with these items.

I hope this helps you to get an idea of how to best manage your turtle’s inventory- put into practice a turtle’s inventory is, quite literally, infinite- and so are the possibilities. If you want to see this in action, I developed a “turtle butler” system which you can check out here: http://www.computerc...-turtle-butler/


Thanks for reading- comments, questions and feedback are of course welcome and encouraged!
Cloudy #2
Posted 13 August 2012 - 01:12 AM
Very very nice guide!

I will point out one method of sorting - having the turtle suck one item from a chest, and comparing it against all the others in its inventory - and then placing the stack that matches into the chest. That way you can conceivably sort 15 stacks at a time without having to keep them all around in your inventory!

I'll have to finish my script I was making to do that :-)
nitrogenfingers #3
Posted 13 August 2012 - 04:53 AM
I made a factual error in this tutorial- we can consider chests to be queues only if we are removing or adding the entire contents of the chest. If we're partially emptying or partially filling them, they're not queues at all- they're probably most closely related to linear hash maps but you can only access the elements in a linear order.
Anyway point of the matter being chests are a hard structure to organize, and a significant constraint when considering organization of your turtle's inventory. This is why either using chests with extreme consistency (always filling/emptying and not leaving anything in that you're not aware is already there), or not allowing more than one object is important in maintaining consistency in your applications.
Sorry for the error!
brandon7210 #4
Posted 31 August 2012 - 08:53 AM
i love this tutorial. i have followed the steps and it works great except for function identify(selectedSlot). whenever i run the function from the lua prompt it gives me error "turtle:18: Expected number". please explain whats going on here. i know it has do with the "turtle.select(index)" line. just not sure how to solve this properly. thanks.
Steelsouls #5
Posted 04 September 2012 - 07:15 AM
Great guide, thanks for the info!
nitrogenfingers #6
Posted 05 September 2012 - 06:11 AM
i love this tutorial. i have followed the steps and it works great except for function identify(selectedSlot). whenever i run the function from the lua prompt it gives me error "turtle:18: Expected number". please explain whats going on here. i know it has do with the "turtle.select(index)" line. just not sure how to solve this properly. thanks.

Error in typing on my part- replace "index" with "selectedSlot" and that should solve the problem. Thanks for picking that up!
SirDiggalot #7
Posted 20 December 2012 - 11:41 AM
is there a simple way to have the turtle to detect a block id (not comparing) as an input?
Cranium #8
Posted 20 December 2012 - 11:55 AM
is there a simple way to have the turtle to detect a block id (not comparing) as an input?
No, unfortunately CC does not have item id detection. I believe that the Aperture Science Turtles have that ability, but I never used them.
SirDiggalot #9
Posted 21 December 2012 - 04:52 AM
is there a simple way to have the turtle to detect a block id (not comparing) as an input?
No, unfortunately CC does not have item id detection. I believe that the Aperture Science Turtles have that ability, but I never used them.
yeeeeah, but im using ftb, so :/
Bubba #10
Posted 21 December 2012 - 10:13 AM
is there a simple way to have the turtle to detect a block id (not comparing) as an input?
No, unfortunately CC does not have item id detection. I believe that the Aperture Science Turtles have that ability, but I never used them.
yeeeeah, but im using ftb, so :/

You can easily install mods in FTB, although you may need to change item ids in the config file. Just install the mod as you normally would but into the FTB folder rather than your .minecraft folder.
Goof #11
Posted 21 December 2012 - 11:26 AM
ehm sorry if im a bit stupid, but what IS FTB ???

-Thanks :D/>
Bubba #12
Posted 21 December 2012 - 12:12 PM
ehm sorry if im a bit stupid, but what IS FTB ???

-Thanks :D/>

Feed the Beast. A modpack like Tekkit, but easily 100 times better as it is updated to the latest version of Minecraft and is put together by the modders themselves :)/>
Goof #13
Posted 22 December 2012 - 12:30 AM
Thanks :D/> i think i would try that :D/>
immibis #14
Posted 24 December 2012 - 01:49 PM
ehm sorry if im a bit stupid, but what IS FTB ???

-Thanks :D/>/>

Feed the Beast. A modpack like Tekkit, but easily 100 times better as it is updated to the latest version of Minecraft and is put together by the modders themselves :)/>/>
FtB is not put together by the modders themselves.
Doyle3694 #15
Posted 24 December 2012 - 11:30 PM
Not reallly, but most modders where part of the creation, though most of them didn't do very much. Also it has permissions and the author/authors is not like Kakermix, "We don't ask permission, we still don't. The permission has been given to us through various means, usually after people find out that we aren't assholes and that we truly and honestly love the mods and appreciate the creators. The reason we don't bother saying anything about it (usually) is because we don't want to cause drama between the modders themselves if we can help it."(And yes, that is an actual quote, made by Kakermix on IC2 forums, it was pointed against CovertJaguar.)

Anyways, FTB is for another topic, this is a really awesome tutorial about turtle management, and I think that is what we should discuss.