I can see how it might be fun to do something like this for a blog post or simple project, but in a real game this just doesn't work for many reasons, most listed here already.

There are tons of ways of doing dialog system. Mostly it comes down to your specific game and I highly recommend against generic dialog systems. Rather, the most you can do at a generic level is try to come up with a good way to store dialog and retrieve it in the ways you need. This isn't the best thing I've seen or worked with, but here's an easy to understand and documented method and presentation about it form Valve:

http://www.gdcvault.com/play/1015317/AI-driven-Dynamic-Dialo...

Anyway, I've been programming games and game engines for several decades, and coroutines are always in the list of things that you can throw in the junk pile along with other cool things like continuations, various theoretical data structures, fancy dispatch mechanisms, events/signals, application-wide functional purity, etc. Of course all of these things are useful, but they tend to have problems that make them of limited use in professional game development.

Here's a brief checklist of show-stoppers off the top of my head I tend to go through before introducing anything "creative" into a game, and especially a game engine. Most of the aforementioned items fail one or more of these.

- Performs awful in common cases or when applied to actual game-like conditions vs. theoretical

- Murders cache lines

- Hard or impossible to debug

- Hard to save, load, serialize, deserialize, or snapshot

- Doesn't work over networks

- Doesn't play nice with libraries or data coming from other libraries or languages (ex: 3rd party physics lib)

- Unpredictable execution start or end times

- Non-determinant memory usage or allocation patterns

- Risk of stack-overflows

- Non-portable or problems on specific target architectures

- Requires "religion" meaning it infects all your code or forces you to write all of your code a certain way, everywhere

- Fragments memory

- Long blocking or uninterruptable processing

Conversely, besides the obvious opposites of most of the above, I look for the following when introducing some major data structure or conceptual item like coroutines to a game or game engine:

- Leads to predictable, consistent code and resource usage

- Data-driven

- Editor friendly (as a corollary to the above)

- Clear debugging story

- Both simple and easy if possible. No, they are not the same.

- Plays well with the world around it

- Portable

- Fast

- Loved by the CPU, GPU, and/or compiler, and produces reasonable assembly on target hardware

- Easy for someone else to jump in and understand the flow and how it works, assuming they are not a moron.

Pretty much these two lists mean that games tend to be made of meat and potatoes things. Simple data structures like arrays, custom allocators, predictable branching and execution patterns, up-front memory allocation, and CPU and GPU loving goodness. Pretty much anything stashing things away and building up massive states or jumping around all over the place, pointer chasing, and so-on should always be a no-go.

Anyway, if you're building a truly simple game, as in a 2 day sort of affair, do whatever you want. If you want to build something even remotely complex that you will work on for awhile, it's best to do things the right way which means detach yourself from everything you think you know about most of computer science and think in terms of pipelines, CPU instructions, caches, and predictability among other things. This often means programming against the grain of your language a bit, throwing out sugar, std libraries, and all kinds of things. It really sucks, but that's the essence of good game programming. I hope one day it will be different, but as long as there's still need to push gameplay and graphical boundaries, professional developers almost always need to squeeze out what they can.