Turtle movement yields when lots of peripherals attach/detach at once
Kan18 opened this issue · 9 comments
Minecraft Version
1.19.2
Version
1.100.9
Details
Basically: when while true do print(os.pullEvent()) end
is running in a tab in a turtle's multishell, and the turtle disconnects or connects to a wired modem network with a lot of peripherals (I tested with 512 for this) when moving with turtle.forward()
/turtle.back()
, the turtle movement call sometimes yields until terminated. I think this might be because the peripheral attach and detach events are overflowing the event queue, but I'm not sure.
Video
Same video on different link
Logs attached although it doesn't look like anything relevant to this is showing in them: logs.zip
I forget how big the event queue is, but overflowing it does seem to be a plausible explanation.
What kind of setup do you have that means you have turtles causally going past modems with over 500 peripherals connected to the network? Could you isolate your turtles from this network, perhaps using a proxy computer if they have to interact with it? The setup in the video is very artificial.
Networks with hundreds of chests are not unheard of on SwitchCraft (To be clear, this affects 1.12, 1.19, and probably other versions but I haven't tested with them) - my base has 275 peripherals. This was how I ran into this bug initially, but I later just moved the wired modem on top of the chest so that the turtle doesn't hit it.
What's a bit interesting about this bug is that I couldn't get it to reproduce if I didn't run the while true do print(os.pullEvent()) end
in the REPL in another multishell tab. The other multishell tab wasn't even focused!
Minecraft Version
1.19.2
Version
1.100.9
How are you playing on mc version 1.19.2 ? CC tweaked only supports 1.19.1 as far as I can see?
Basically: when
while true do print(os.pullEvent()) end
is running in a tab in a turtle's multishell, and the turtle disconnects or connects to a wired modem network with a lot of peripherals (I tested with 512 for this) when moving withturtle.forward()
/turtle.back()
, the turtle movement call sometimes yields until terminated. I think this might be because the peripheral attach and detach events are overflowing the event queue, but I'm not sure.
This issue is quite awhile, but this is how I solved the problem:
local function discardAllEvents()
local count = 0
local timer = os.startTimer(0.5)
while true do
local event, id = os.pullEvent()
if event == 'timer' and id == timer then
print('discarded', count, 'events')
return
else
count = count + 1
os.cancelTimer(timer)
timer = os.startTimer(0.5)
end
end
end
local function noCareAction(action, ...)
local thr = coroutine.create(action)
coroutine.resume(thr, ...)
discardAllEvents()
end
local function placeModemCol()
noCareAction(turtle.down)
for i = 2, 13 do
-- print('DBUG: moving back')
noCareAction(turtle.back)
-- print('DBUG: selecting modem')
while not selectItem(modemId) do sleep(0.1) end
-- print('DBUG: placing modem')
noCareAction(turtle.place)
-- print('DBUG: activing modem')
waitForCooldown('useOnBlock')
-- print('DBUG: using on block')
automata.useOnBlock()
discardAllEvents()
end
noCareAction(turtle.up)
for i = 2, 13 do
noCareAction(turtle.forward)
end
end
Yea throwing all events away alongside with coroutinethat is waiting for event is a "solution" but it feels off.
Heck all you probably needed to do is just throw away the coroutine.
I know this suggestion may seem extreme but how about changing how event queue works java side and instead of throwing away overflowing events, if queue reaches point its overflowed just delay overflowed events at next tick and so on so on? This would have side benefit of artificially slowing down computers that generate too many events but it would probably need to get thought thru to make sure it don't have side effects i can't think of right now.