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

Cobblestone-to-Diamond Script Crashes Minecraft and Destroys Saves

Started by rockobonaparte, 01 February 2014 - 04:40 PM
rockobonaparte #1
Posted 01 February 2014 - 05:40 PM
tl;dr is that I have buffed up a script for crafting cobblestone to diamond through a roundabouts way, and it crashes Minecraft hard. Roughly half the time it takes my save with it. It will stop listing that save.

I'm a proficient programmer, but not in Lua, so it has been interesting seeing how this all pans out. I have been using the Never Stop Toasting 1.6.4 modpack, which uses ComputerCraft 1.57. It also generates few diamonds, or at least I haven't been able to get them. They already conceded that, but meanwhile I decided–since I am going automation-crazy now–to try the whole cobblestone-to-diamond pipeline. That involves a Minium stone and a lot of steps, eventually turning 8192 cobblestone into 1 diamond.

I started with a script from these very forums here. It needed a lot of rehabilitation and then I started throwing some aggressive logging on top of it. The logging prints to the turtle as well as to a file on disk, which I can read after-the-fact. It seems to crash in all variety of places inside the core loop. Sometimes it's in the middle of crafting and sometimes it's in the middle of working with a chest.

If I use a chest full of cobblestone without an itemducts feeding it, everything still dies dramatically. My first hunch had been a race condition of some kind, so I had tried it. Also, the fact that it dies during crafting and not chest interaction sealed the deal.

Here's a pastebin for the modified script: http://pastebin.com/pRJwER2v

If we can get it not to wreck the save I want to post it back into that thread because it looks like people had nothing but problems using the script. It could probably be a little more tolerant of where different chests are. I'm not going to knock it though since somebody did that in their free time.

Here's the logging.lua that I am using with it: http://pastebin.com/tAFh8dwV

I noticed that for some reason I can't import that script into the autocrafter immediately; it complains about calling something nil. I have to run logging.lua for whatever reason and then the autocrafter works too. I consider that its own problem that I'd like to address. Also, the crashes happened before I instituted logging. I started logging to try to track down the crash.

It crashes within just a few cycles. Like, it does a little bit of cobblestone, gets to flint, then to clay, and right around there it will die. If I'm a lucky man, I'll get an ingot.

Setup is very tedious with this. I recommend:
1. Dig a block out of the ground
2. Put a chest in the hole
3. Put a Minium Stone in the chest
4. Put a chest above and in front of that chest, close to you.
5. Go around the back of that chest and slap a crafting turtle behind it.
6. Place a chest on top of the turtle.
7. Get all the scripts on the turtle
8. Create a diacraft.config, which the original script needed, with the direction in which you placed the turtle. Like "north," "east," that kind of thing. This is from the original incarnation and I'd like to improve it, when it stops completely corrupting saves. If you start running and it complains about not finding a chest, try the opposite direction.
7. Save your game right here in case it gets all screwed up
8. Load the top chest with cobblestone
9. Running logging.lua – for whatever reason as I mentioned above.
10. Run the autocrafting script

Rough side view of this all:

C	<---- Cobblestone
TC
C	<---- Minium

C = Chest
T = Turtle

Place turtle from left
rockobonaparte #2
Posted 01 February 2014 - 08:18 PM
It's starting to smell more like an actual bug than anything else. I didn't think I'd blow it up so quickly so I went for help first. Using that logging.lua for getting a log, I have taken it down to this concentrated code:


os.loadAPI("logging.lua")
log = Logger.new()
log.SetTraceLevel()

if not peripheral.isPresent("back") then
    print "Missing chest in back of crafting turtle."
    errors = true
end
local item_chest = peripheral.wrap("back")

craftCount = 16

log.Trace("pushing item to slot 2")
item_chest.pushItemIntoSlot("east", 1, craftCount, 2)
log.Trace("pushing item to slot 5")
item_chest.pushItemIntoSlot("east", 1, craftCount, 5)
log.Trace("pushing item to slot 6")
item_chest.pushItemIntoSlot("east", 1, craftCount, 6)
log.Trace("pushing item to slot 9")
item_chest.pushItemIntoSlot("east", 1, craftCount, 9)

log.Trace("Selecting slot 12 for drops")
turtle.select(12)
for i = 1, craftCount do
    log.Trace("Crafting " .. tostring(i))
    turtle.craft()
    log.Trace("Dropping " .. tostring(i))
    turtle.drop()
    log.Trace("Done dropping " .. tostring(i))
end

That is, with the crafter bot facing east, and a chest in front and behind it, put 64 cobblestone in the rear chest. Give it a Minium stone in slot 1. Run the script once and it will be fine. When you run it again, it will die, every time, when it tries to craft the first of 16 items.

I'll see if there's a newer release or something else I can look into meanwhile.
Lyqyd #3
Posted 01 February 2014 - 08:25 PM
Your logging API flushes the file each time it writes, but never actually closes the handle. When you attempt to start another run, it cannot open a second write handle (as the first has not been closed), causing the crash.

Edit: That shouldn't be killing saves, though. It should just be throwing an error or some such.
rockobonaparte #4
Posted 01 February 2014 - 08:41 PM
I decided to skip restarting the script, and instead added an outer loop. When it tries the second iteration of the outer loop, it crashes there instead. That's from a single invocation of the script. It looks like this now:


os.loadAPI("logging.lua")
log = Logger.new()
log.SetTraceLevel()

if not peripheral.isPresent("back") then
    print "Missing chest in back of crafting turtle."
    errors = true
end
local item_chest = peripheral.wrap("back")

craftCount = 16

log.Trace("pushing item to slot 2")
item_chest.pushItemIntoSlot("east", 1, craftCount, 2)
log.Trace("pushing item to slot 5")
item_chest.pushItemIntoSlot("east", 1, craftCount, 5)
log.Trace("pushing item to slot 6")
item_chest.pushItemIntoSlot("east", 1, craftCount, 6)
log.Trace("pushing item to slot 9")
item_chest.pushItemIntoSlot("east", 1, craftCount, 9)

log.Trace("Selecting slot 12 for drops")
turtle.select(12)
for j = 1, 4 do                 -- Outer loop.  It will crash at j = 2, i = 1
    for i = 1, craftCount do
        log.Trace("Crafting " .. tostring(j) .. ", " .. tostring(i))
        turtle.craft()
        log.Trace("Dropping " .. tostring(j) .. ", " .. tostring(i))
        turtle.drop()
        log.Trace("Done dropping " .. tostring(j) .. ", " .. tostring(i))
    end
end

That should bypass the dangling file handle problem. Honestly, shouldn't that get tackled in GC anyways? I'd be in big trouble otherwise, since if I'm logging, it's probably because I expect it to drop dead at some unanticipated moment.

Also note that I am now using ComputerCraft 1.58 here. I got the same kind of crash as before, and then I made these modifications after seeing your response.
Lyqyd #5
Posted 01 February 2014 - 08:47 PM
Hmm. That code suggests that crafting on an empty inventory is causing the crash. That's decidedly odd. Can you reproduce it with just an empty turtle and the craft command?
rockobonaparte #6
Posted 01 February 2014 - 09:02 PM
Hmm. That code suggests that crafting on an empty inventory is causing the crash. That's decidedly odd. Can you reproduce it with just an empty turtle and the craft command?
Ain't that something. Yeap, dead right there.

I made lets_do_this:

turtle.craft()
I didn't entirely do an empty inventory; I had the Minium stone still in there, but I took out the stray cobblestone it had already placed.

I'll take the Minium out and report in a second. I figured you were watching the thread due to the fast turnaround, so I wanted to get back to you quickly. Each time I do this and succeed at a crash, that's one more time I have to start at the Mojang splash screen and wait for the next attempt. :P/>

Just to reiterate, this is running with the Never Stop Toasting 1.6 pack, using the Technic Launcher. I only started doing this mod stuff recently, and I saw all this stuff in the bug report thread about Bukket and other junk, so I wanted to just emphasize the other, potentially hidden, moving parts in my mess.

Update Without the Minium Stone it crashed just the same. I'm going to step away from it for a little bit and do some dishes or something else.
Edited on 01 February 2014 - 08:05 PM
Bomb Bloke #7
Posted 01 February 2014 - 09:30 PM
I'm running Direwolf 1.0.11, which is also MineCraft 1.6.4 with ComputerCraft 1.57 (but otherwise would be quite a different mix of mods - no Equivalent Exchange, for eg).

"turtle.craft()" seems to work fine with an empty inventory (in that it just returns "false" instead of crashing the game), ditto if the turtle's holding items but cannot currently craft with them.

It'd be well worth checking your MineCraft install directory for crash logs.
Edited on 01 February 2014 - 08:31 PM
rockobonaparte #8
Posted 01 February 2014 - 09:48 PM
It'd be well worth checking your MineCraft install directory for crash logs.
I was waiting for that. So with mods and all, I'm not sure how this works anymore. I think I found the crash report in C:\Program Files\Technic\modpacks\never-stop-toasting-16\crash-reports

I'll just throw the whole of it in PasteBin but there's a DIV0 up top in ComputerCraft somewhere that I'll paste here:
http://pastebin.com/YVyvcRAn


---- Minecraft Crash Report ----
// Hey, that tickles! Hehehe!

Time: 2/1/14 8:51 PM
Description: Ticking tile entity

java.lang.ArithmeticException: / by zero
at cubex2.cs2.item.crafting.CSShapedRecipe.func_77569_a(CSShapedRecipe.java:79)
at net.minecraft.item.crafting.CraftingManager.func_82787_a(CraftingManager.java:307)
at dan200.turtle.shared.TurtleInventoryCrafting.tryCrafting(TurtleInventoryCrafting.java:57)
at dan200.turtle.shared.TurtleInventoryCrafting.doCrafting(TurtleInventoryCrafting.java:68)
at dan200.turtle.shared.TurtleWorkbenchPeripheral$1.handleCommand(TurtleWorkbenchPeripheral.java:93)
at dan200.turtle.shared.TileEntityTurtle.updateCommands(TileEntityTurtle.java:2824)
at dan200.turtle.shared.TileEntityTurtle.func_70316_g(TileEntityTurtle.java:2469)
at net.minecraft.world.World.func_72939_s(World.java:2209)
at net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:550)
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:668)
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:587)
at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:129)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:484)
at net.minecraft.server.ThreadMinecraftServer.run(SourceFile:583)
Bomb Bloke #9
Posted 01 February 2014 - 10:19 PM
CubeX2's mod "Custom Stuff 2" is the last one called before everything falls over in a heap.

So: Blame that. :)/>
Lyqyd #10
Posted 01 February 2014 - 10:52 PM
Yep, this is a bug in the other mod, it's done something to the crafting system to bork it in this situation.
rockobonaparte #11
Posted 02 February 2014 - 02:05 AM
For my own benefit, how'd you figure that one out from the log? I saw it mentioned but I can't tell from the sequence that was culpable. I trust your judgement on that one, but I just want to know so I don't go running back here on another crash without being able to do the check myself.
Lyqyd #12
Posted 02 February 2014 - 02:19 AM
The log has the latest calls at the top, and whatever called that code below it, etc. The top few lines of the log are:


java.lang.ArithmeticException: / by zero
at cubex2.cs2.item.crafting.CSShapedRecipe.func_77569_a(CSShapedRecipe.java:79)
at net.minecraft.item.crafting.CraftingManager.func_82787_a(CraftingManager.java:307)
at dan200.turtle.shared.TurtleInventoryCrafting.tryCrafting(TurtleInventoryCrafting.java:57)

Which means that there was an attempt to divide by zero in code from the cubex.cs2 packages (the CS2 mod), called by Minecraft's crafting manager, called by code in the dan200.turtle package (computercraft). Since the divide by zero error is in the other mod, it will have to be fixed on their end.
Bomb Bloke #13
Posted 02 February 2014 - 02:26 AM
That list is called a stack trace, and we're fortunate that Java happens to throw in lots of information. It's very, very similar to the errors the Lua VM throws when your scripts bomb out - only instead of just saying "something went wrong on this line", it tells you that "something went wrong on this line, which was called through this function, which was called by this function, etc".

I could go on to guess that the issue is a bit of naive programming on CubeX2's part. Normally, when you craft something, it's not possible to complete the action until you've got a valid recipe in the crafting grid (as the actual "craft" action is performed by taking the item from the "result" slot, but nothing's there to take until a complete recipe is in place).

ComputerCraft lets you bypass this little restriction with "turtle.craft()". Odds are that when the "Custom Stuff 2" code is called to craft something, it tries to see exactly how many items can be crafted with the ingredients at hand… without checking to see how many it actually has first. In the case that it can't craft anything, the result is division by zero ("divide who-knows-what recipe's output by no ingredients…"), an action that's simply impossible.
rockobonaparte #14
Posted 02 February 2014 - 03:41 AM
Aww crud I am officially too tired to read a stack trace. I saw all the calls through turtle namespaces without looking at the very tippy tip. But I wouldn't have known about that mod anyways, so thanks for that help.

I gotta double check now that the original script was firing from a similar problem or not. I'll put some guards around the craft line and see if that's where it's consistently dying or what. Otherwise we found another problem from my attempt at isolation.
rockobonaparte #15
Posted 02 February 2014 - 11:41 AM
I went back to the original script, and it does indeed crash with a DIV0 there too from Custom Stuff 2. I removed that mod from the pack without ill effect–so far. I probably have to tell them about the problem. As far as I can tell, that's mostly for people wanting to get that perfect block for their meticulously crafted structure-thing, and I'm not in to that right now. Now it looks like it's running fine, despite apparently a failed crafting operation. So I am adding checks to the craft statements to see what its complaining about.

I can see in my script now the problem was that it pulled from chest 1, and it can only distribute 64 blocks 16 ways, so 1 more block beyond that is invalid. At this point, there isn't much benefit for doing more than that because it appears to only do one craft at a time. I assume that's because of the Minium Stone being a single unit; everything sounded like otherwise I should be able to make multiples in one go like you can regularly. I'm playing with that, and I will probably end up posting a thread about optimization and such, rather than use this one here with its dramatic post title. :P/>
Lyqyd #16
Posted 02 February 2014 - 02:15 PM
It's generally preferable to stick to a single topic for all questions on a given piece of code; it's easier to see the evolution of the code and it's less likely that work will be duplicated or answers missed.