Coroutine uses worth doing?

Most of this coroutine stuff seems to equate to jamming the wrong shaped puzzle piece in and pretending it fits. They are slow. You can, as far as I could always tell, rewrite what they are doing with switches and run it faster.
So that begs the rational that you should: (1) use them sparingly, and (2) you shouldn’t use them unless there is some kind of setup where it is worth a bit of slower runspeed, right? I’m trying to find what that is. Does anyone know?

This was a good read, but it really illustrates the point. You can already make timers with switches…u can already pause code with switches… you can already compartmentalize the case usage into 1-liners u toss into the code for debugging. Alot of these posts about coroutine usage seem to be more about flexing and hobbyist science. The usage with the timer.performWithDelay() REALLY illustrates that feeling, as u have to cheat and use a ‘specific coroutine setup that breaks most coroutine usage rules’ to trick it into working (easy to copy-paste, frustrating to test).

I honestly wouldn’t even consider coroutines but they are in lua and boasted about in the manual. So smart people decided they have a worthy case usage ‘somewhere’. In a game engine, that usage seems even more elusive.

The lua manual talks about iterating with coroutines…I couldn’t understand that page well so I’m hoping I missed the point, but iteration is a key thing to optimize in a game, so isn’t that enough to dismiss their usage as iterators? I think the most promising thing I saw, also in that linked blog post, was the tail calling concept to make an indefinite loop between functions. But I’d guess the speed benefits from the tail call aren’t going to makeup for the coroutine speed sink (at best they might makeup for the jumping between functions constantly cost), and in the case usage examples you are setting the gamestate with them meaning they presumably get used alot. The rational in the linked blogpost about “not remembering names”, was again, really illustrating that concept of “flexing and hobbyist”. I do need to test more in that tailcall area stilll. Maybe there’s enough usage to justify the cost? Or not.

Anyone have a coroutine method they can defend the usage of? Again, please make sure it is still defendable after being rewritten using switches. And assuming it might exist somewhere: I would love to see a usage where coroutines are running faster than their switch rewrite.

Coroutines are great when dealing with listeners and in general I find them very useful to improve the readability of some code.

One of the best uses I give it to manage network calls where keeping track of the flow is impossible without using coroutines.

As a short example, this is how it looks a network call without using coroutines:

  local callback

   local function downloadListener(e)
      callback(e.success)               
   end


   local function authListener(e)
      if e.success then
           Network.request(downloadParams)
      else
           callback(false)
      end
   end

   function download(_callback)
         callback = _callback
         Network.request(authParams)
   end

While by using coroutines you can create an async network instead, which gives you this.

function download(callback)
    local e = AsyncNetowrk.request(authParams)
    
   if not e.success then
        callback(false)
        return
   end

   e = AsyncNetwork.request(downloadParams)
   callback(e.success)
end

Coroutines are not often used, but we built many internal libraries and even entire workflows that are simple thanks to coroutines.

I don’t follow the code, but I think I get what you are saying. I’m using them in the dialogue system, the markup for writing the messages just looks like this. It still gets convoluted once u add inventory items and item/whatever specific dialogue and devolves back into a jungled mess of switch statements anyways …aka whatever organizational benefits can turn superficial rather fast.

		script=function(self) if self.script_end then return end
			script_say([[hello this is slower text crawlspeed]],7)
			script_say[[
			Panda animal is back         
			       in                  
			panda jail
			]]
			script_ask([[more about pandas?]],"Yes", "Yes Cool", "No", "Nooo!!!", "diamond plz?")
	          	If script_ans==5 then inv.diamond=true 
					script_announce[[You received The Diamond!]]  end



		end
1 Like

Thats a great use of it.