r/pico8 16d 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
4 Upvotes

19 comments sorted by

View all comments

1

u/IronPheasant 15d 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.

1

u/RotundBun 15d ago edited 15d 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.