Coroutines are weird, they don't update properly sometimes, and I haven't found the issue as to why. I'm making a game that does heavy use of it, and it doesn't work properly. sometimes functions return nils when they shouldn't, or sometimes functions just ignore values they received. I don't think it's an issue in my part, I debugged everything and I simply didn't find an issue in my part. I tried to test if it was the CPU going above 100% that was the issue, so I did this test
function _init() func=function() cls() if key"a" then for i=0,1000000 do end end print(stat"1",0,0,7) end routine=coroutine.create(func) end function _update() -- func() coroutine.resume(routine) end function _draw() end |
yet it didn't detect my keypresses, or button presses if I changed it to btn(0/1/2/3/4/5). if I swapped the coroutine.resume(routine) to func() it worked.
then I thought maybe I was doing something wrong, so I moved some stuff around and made it so it reads a variable, but no dice. it should work, right?
local key_a_pressed = false function _init() routine=coroutine.create(func) end function _update() if key"a" then key_a_pressed = true end coroutine.resume(routine) print(stat"1", 0, 0, 7) end func = function() if key_a_pressed then for i = 0, 1000000 do end end end |
I don't get what's happening. it has to work... this is driving me crazy. I'd be glad to hear if it's a bug in my part, but for now I just don't know what's happening.
Another thing that happens, is that doing CTRL+R sometimes makes coroutines do the wrong stuff (?) and it makes my code break. I also saw that when my code broke, the CPU percentages when went to 300%, yet I was doing minimal work in my cart. I put a flip() at the end of _init and it fixed the issue. that 300% has to be what's wrong... something in the background is making my cart do all sorts of weird things... at random. also, typing run in the console didn't seem to create that issue.
Picotron uses mostly standard Lua so the problem is unlikely to be with the implementation of coroutines themselves.
You seem to be having a few different problems which may or may not be related but in the case of key presses not being detected this is actually coroutines functioning as expected.
The problem is that routine
is being run once—the first time you call resume
—and since the routine doesn't yield it just finishes and its state is set to 'dead'. Once a coroutine is dead it isn't run again even when you call resume
on it because there's nothing to resume. You can see that in this example:
function _init() count = 0 func=function() count += 1 end routine=coroutine.create(func) end function _update() coroutine.resume(routine) end function _draw() cls() print(count) end |
The coroutine does get called and count
is incremented. But it's only ever incremented once not every frame because once we reach the end of the function the coroutine dies.
The reason it works when you switch to just calling func
is because normal functions don't work the same way: they never "die". So when you call func
in the update cycle it runs every time and works as you're expecting it to.
Here's a version with key presses that works as a coroutine. While you hold down 'a' it prints true and when you release 'a' it prints false.
function _init() pressed = false func=function() while true do if key'a' then pressed = true end coroutine.yield() end end routine=coroutine.create(func) end function _update() pressed = false coroutine.resume(routine) end function _draw() cls() print(tostr(pressed)) end |
Notice that the logic is inside an infinite loop so the function will never return and the coroutine will never die. The call to yield
let's you break out of the coroutine without killing it. Then resume
causes the coroutine to pick up where it left off at the end of the infinite loop until it yield
s again, and so on.
Yep. Picotron hijacks lua's coroutine system, and it breaks things. It also provides its own functions that work properly. costart
, coresume
, and costatus
.
[Please log in to post a comment]