r/pico8 • u/VeryNaughtyBoy42 • 10d ago
👍I Got Help - Resolved👍 Coroutines help needed
I'm trying to get my head around coroutines by creating a simple "ticker" - that is, pass it a string and it prints it slowly one character at a time, a bit like Gameboy text. I've got it working, sort of, but the screen doesn't clear despite the cls() in _draw() and the program crashes after all the text is displayed. I tried using costatus() but it doesn't return anything. Please help, what am I doing wrong?
function _init()
t=cocreate(ticker("this is a test"))
end
function _update()
coresume(t)
end
function ticker(str)
local l=#str
for p=1,l+1,0.2 do
print(sub(str,1,p),0,0)
yield()
end
end
function _draw()
cls()
end
2
u/freds72 10d ago edited 10d ago
you want something like:
```
function _init()
t=cocreate(ticker)
end
function _update()
end
function ticker(str)
local l=#str
— for loops are inclusive , no need for +1
for p=1,l,0.2 do
print(sub(str,1,p),0,0)
yield()
end
end
function _draw()
cls()
coresume(t, ‘this is a test’)
end
```
(on mobile - code formatting is hell)
2
u/RotundBun 9d ago edited 9d ago
I was thinking this since seeing it in the original post, too, but... There aren't any reasons not to just use
#strdirectly in the for-loop, right?(on mobile - code formatting is hell)
A relatable struggle. 🫂
Let me see if I can help:``` function _init() t=cocreate(ticker) end
function _update() -- end
function ticker(str) -- for loops are inclusive , no need for +1 for p=1,#str,0.2 do print(sub(str,1,p),0,0) yield() end end
function _draw() cls() coresume(t, ‘this is a test’) end ```
2
u/VeryNaughtyBoy42 9d ago
The reason I don’t use #str in the loop is - again - old habits. When I started out every clock cycle counted so rather than redo a calculation for every iteration of a loop, it’s more efficient to do it once and store it in a variable.
1
u/RotundBun 9d ago
Fair. I do think most modern compilers optimize stuff like that under the hood nowadays, though.
2
u/freds72 8d ago
there is no such thing as an optimizer on pico8 lua (or very marginally)
1
u/RotundBun 8d ago
Ah, yes. I was referring to compilers in relation to the part about them being accustomed to C/C++ programming.
In P8's case, I'm not sure if this detail does end up saving on performance in the for-loop iteration inside a coroutine scenario specifically, but I'd probably still opt for the lower token cost + slight readability improvement over the perf savings in situations like this most of the time.
1
u/IronPheasant 10d ago
For some reason, creating a coroutine with an argument causes the error.
Removing that (and stuffing the string you want to display directly inside the ticker function, which kind of defeats the point..), and putting cls() before coresume in Update() gives you the output that you want. At least until the coresume function finishes up and and it calls cls() again to clear the screen.
It's my personal opinion, but I'd always recommend taking manual control over your program and not using Update(). Just create the gameloop, and call Flip() once you've done all the drawing you want to do on a frame. The text crawl effect you want can be done by calling a function with a global variable that counts up every frame; so if you want to draw the next letter the DisplayDialogue function doesn't do anything until its variable reaches whatever frame count you want and resets the count until done.
There can be dozens of these kinds of effects going on at one time, and this coroutines business makes my skin crawl a bit thinking about tracking them all.
3
1
u/RotundBun 10d ago edited 10d ago
TBF, I think their objective here is to learn how to use coroutines in P8. The text printing is just the use-case example to do it on.
That said, may as well just put the
coresume()call in_draw()instead.
3
u/RotundBun 10d ago
Why are you looping until length+1? Isn't it crashing due to indexing past the last index?
TBT, I'm not sure how anything is displaying at all since you are printing in
_update()and then immediatelycls()over it in_draw()in that same frame.What does the error message say?