PneumaticCraft: Repressurized

PneumaticCraft: Repressurized

43M Downloads

[1.16] Unexpected behavior in loop widgets

MuteTiefling opened this issue ยท 11 comments

commented

Describe the bug

Following the discussion in Discord. It would seem that jumps inside of loops are not being properly released. So if a program needs conditions, for example, inside of a loop, those jumps end up building up until it hits the jump limit.

How to reproduce the bug

Program: https://gist.github.com/MuteTiefling/65c78d8671c9247a278986129612624a

Supply two chests, one as the input (storage in the program), and one as the output. In the storage chest, chuck some random dyes and a bunch of string. The program will attempt to pick up 1 dye and 4 string, and stick them in the output chest. This is as simplified as I could make it.

If you supply no dyes, you'll end up with the drone dying as it starts it's second iteration. Ie, it checks all the way through Black, goes on standby, then starts again from the start of the program and hits the 100 jump limit.

Expected behavior

It should be able to loop through all of the wool types and correctly pull the ingredients for each 'craft'. Jumps that are finished should be getting released.

Additional details

No response

Which Minecraft version are you using?

1.16

Crash log

No response

commented

Here's a slightly better example

Drone: https://gist.github.com/MuteTiefling/537276095ed4755c3e6163d4f96969c4
API with Loop: https://gist.github.com/MuteTiefling/03407f2029399f862f0684daaae43bee
API with Standby: https://gist.github.com/MuteTiefling/5d175abb2be8b69d0dbc7bfa2ceb5e3f

Setup:

  1. Import the Drone program onto a drone and set the Network API variable to an inventory somewhere.
  2. Import the other two programs to separate APIs
  3. Place the Standby program in the first slot of the inventory
  4. Place the Loop program in the second slot
  5. Deply the drone

You'll see it go to standby for 5 seconds, then begin to loop through the wool, renaming itself for each wool.
At the end of the loop, it exits, hits the final rename (loop end) and waits for 5s.

At this point, I'd expect it to move on to the standby program again. However, it instead returns to the start of the loop program. It will keep looping this program until the drone dies from jump exhaustion.

commented

Oh, Hrm... I thought the jump back to the for each was required since I kept ending up on the first item every time without it.

Could have been doing something else wrong though. Will rework this and load up your build to test. Thanks!

commented

I think there were bugs on both sides here ๐Ÿ˜„

Landing back on the first item was a symptom of the problems with External Program & Looping (which this change hopefully fixes). Adding an extra Jump was not the fix :)

commented

Oh, I also changed the Rename to use Type: ${Wool Type.item} to actually show the item name. Otherwise you'll just see (0,0,0) for every item iterated...

commented

Odd, I was getting the names of the wool already :-D much strangeness

commented

I can see one problem immediately (which I think is the cause of the jump stack overflow) - you do not need a Jump at the end of the "Rename Drone" subroutine. When a subroutine called from a Foreach ends, control automatically transfers back to the Foreach widget (and at that point the subroutine is popped from the jump stack). Leaving the subroutine with an explicit Jump means the drone doesn't detect an end of subroutine, and the stack is never popped.

There is an actual bug with using this as an External Program, though. Dropping off the end of the subroutine is intercepted by the External Program, which moves onto the next program. If inside a subroutine like here, that should take precedence, since the program isn't actually finished yet. Hopefully this isn't too hard to detect and fix, but I need to dig into this further. This code is one of the more... esoteric... parts of the mod :D

Another bug is that the jump stack isn't getting cleared when a new sub-program is loaded via the External Program. That's an easy fix, at least.

commented

Give build 310 a go when you get a chance... I think I've fixed the problem (at least your second example now behaves as expected).

Fundamental problem was the AI thinking the program was finished when the subroutine exited, even though at that point the next step is to jump back to the Foreach piece. Wasn't an issue when it's the main program, but when running under External Program, it was taken as a "program exit", and the AI immediately moved to the next program in the inventory.

commented

Well, the wool program is now working perfectly with 310 and removing the superfluous jumps back to the for loop :D I'll stress test some more with the rune program, but I think we have a winner. Thanks!

commented

Oh yeah - been testing in 1.18.2 (although the change does also apply to 1.16.5). While drone AI in general hasn't changed at all from 1.16 to 1.18, variable parsing is a bit different now, and the .item suffix is currently necessary. Although I will change it so .item becomes the default again if the variable is unambiguously an item variable and not a coordinate variable.

commented

Just to confirm here, even though we spoke in Discord. 310 is definitively working perfectly in this regard. Thanks again :D

commented

Fixed in 2.15.4