Search code examples
luapico-8

Pico-8 coroutines are occasionally dead


I was trying to replace a for-loop with coroutines to move the stars:

--fine
function _update()
 for c in all(boids) do
  move_boid(c)
 end
end

--broken
function _update()
 for c in all(boids) do
  coresume(cocreate(move_boid),c)
 end
end

Notice that a fixed number of stars are frozen (I'm pretty sure the number is fixed):

boids

But why? How can I handle this? The complete code is on itch.


Solution

  • Thanks for @Vald and @Egor's comments. Seems the problem is caused by "too-long coroutines" to finish in a PICO-8 cycle. So the solution is that I store unfinished coroutines in a table and resume them if not finished. But somehow the movement is changed, kinda like "lost frame".

    Here's my edited code:

    function _init()
     -- code
     cors={}
    end
    
    function _update()
     for i=1,#boids do
      local co=cocreate(move_boid)
      local c=boids[i]
      add(cors,co)
      coresume(co,c)
     end
     for co in all(cors) do
      if (co and costatus(co)!="dead") then
       coresume(co)
      else
       del(cors,co)
      end
     end
    end
    

    And also modify the calculation function, adding a new line in the middle:

    function move_boid(c)
     -- code
     yield()
     -- code
    end
    

    Just to yield before it's completed.


    Update: another way to do it is reusing coroutines.

    function _init()
     -- code
     -- create coroutines
     cors={}
     for i=1,#boids do
      local co=cocreate(move_boid)
      local c=boids[i]
      add(cors,co)
      coresume(co,c)
     end
    end
    
    function _update()
     foreach(cors,coresume)
    end
    
    -- and wrap the move function with a loop
    function move_boid(c)
     while true do
      -- code
      yield()
      -- code
      yield()
     end
    end