Fluid text,no coroutines
I when working on my game, I have never found an easy way that didn't imply using coroutines of doing fluid text, but with a little googling(well, al ot googling) I have found a way.
I don't know if I am the only one with problems on this matter but, I think that it is itnetresting.
So, I was doing the intro for my game and did it this way.
Tomorrow I post the cartridge.
It is possible that this code doesn't work, because I kind of just made it up on the run, but I think that it is prettysimilar to the one I did on my game, but if anyone can help on polishing it, it will be welcome.
function _init() intro=the days of hiding\nhave ended (for example) char=0 end function _updat() char+=(depending on the speed you want the text to appear, normal speed is around 0.2) end function _draw() cls() print(sub(char,#intro),x,y,colour) end |
Sorry, my bad, it is _update, I didn't write the e by mistake
Coroutines are a way of organizing logic and maintaining state. You can certainly do it in other ways. Any way you do it, the end result is a machine with a crank that gets turned by the game loop to push state forward.
One thing I like about coroutines specifically with PICO-8 is that they can describe complex sequences concisely. Building a state machine that can describe complex actions can add quite a bit of token overhead. Coroutines take advantage of built-in features of the language to describe states, local memory, and sequencing.
One reason to avoid coroutines is speed, depending on what you're using them for. And they can certainly be mind bending. :) Timers, tweens, and events can be reasonable alternatives and are easy to build as needed.
Well, my problem was that i read a lot of webs, googled a lot of info, but I just didn't understand coroutines.
Of course, coroutines are more versatile, for example to get a circle mving across the screen, but the only thing I needed was the fluid text, so I tought it would be interesting to anyone that was in my same position
You've probably already found my article on the subject and it probably didn't help ( :) ), but I'll mention it to reinforce the point I was making about alternatives. It presents two simple animations that don't use coroutines to illustrate how they keep track of and advance the state of the animation.
To animate a scene with multiple steps, such as a conversation between two characters, you'd need a data representation that describes the steps like a script, and a machine that keeps track of which step is being executed and what's happening in each step. For example, you could have a table that describes each line of dialog and who is speaking, an "in dialog" flag so the game loop knows not to allow the player move or attack during the dialog, a variable representing which line of dialog is being spoken, a variable representing which character of the line is being displayed, and other timing mechanisms to delay the text (and maybe allow the player to speed it up). All of this is handled in the game loop, which has to manage all of this for every aspect of the game.
Coroutines take advantage of the fact that a computer program is already a good representation of a sequence of steps and state. Instead of turning the crank one frame at a time in a custom-built machine, the game loop just resumes a coroutine once per frame, and the coroutine yields when it has done one frame's worth of work. When the coroutine yields, its steps and state of the animation are preserved in memory, and control goes back to the game loop so it can turn the crank again.
Another way to think of it: a function is just a coroutine that never yields. It starts, it performs each of its instructions one at a time and maintains an internal state along the way, then it returns and all of that state disappears out of memory. Yielding is a way of returning temporarily: it's saying "I'm not done yet but you go ahead and let me know when I can go again." It stays in memory, remembering the instruction it was last on (the yield statement) and all of its local variables, so that they're still there when it is resumed by the caller.
I read the article you linked + the one named «cutscenes and coroutines» and it helped me write my own coroutines. But I also knew about them in Python first, so I knew what they are (functions that you pause and resume) and why they’re useful (no callbacks or global variables, all the steps are here in one function, easy to reason about or change). I would say that these articles describe the space well, but jump to an advanced example instead of showing a very simple one. Your post above may be clearer than the article on this point.
My own use case was a simple blinking text. I want some text to be drawn for half a second, then invisible, then drawn, etc. I could look at my history to get the classic version (need a tick variable, increase it in _update, don’t forget to reset, draw the text if tick < 30) and post it alongside the coroutine version (while true: yield 30 times, set obj.show=true, yield 30 times, set obj.show=false).
I found very interesting your articlec @dddaaannn.
I think next time I might use them for doing a conversation in cutscenes, but I just couldn't understand them
[Please log in to post a comment]