Jump to content

Rick's Blog

  • entries
    65
  • comments
    96
  • views
    24,825

Rick

3,059 views

 Share

I'm currently working on coroutines in lua. This will help people setup scripting sequences for their game. The cool part of this will be that you will use it in the editor like any other entity. Drag it into your scene and now in your other scripts you'll have access to these functions. Here is an example usage of what you would do in lua.

 

 

--- This defines the function that stores your script sequence
function MyScript01(cr)   -- cr is the coroutine to this function. The functions that pause execution of the script require it to be passed in
  MoveTo(cr, player, pivot1)   -- This method will move the player entity to the pivot1 entity and only return when it has reached it's destination
  PlaySound(cr, "hello.wav")   -- This method will return only after the hello.wav is finished playing
  PlayAnimation(cr, "animation") -- This method returns after the animation is complete
  Wait(cr, 2000)      -- This method will simply wait for 2 seconds before returning. Time is in ms.
end

-- When you are ready to run your script function simply pass the function to RunScriptFunction() and it'll start playing out
RunScriptFunction(MyScript01)

 

This can give us more interactive games than seen in the past with LE. You could create a volume trigger that runs a script when it's touched by the player, that moves an NPC to a location. Have it start talking. Have it play an animation, etc all in sequence. Maybe you make a button in game that when the player presses the 'use' key it runs a script. The script could do all sorts of things.

 

The main benefit of using coroutines like this is that the function where you define your script is actually "paused" until something restarts it again. This means that your game continues to run. That's where I come in. I'm defining the function that will pause and how they will start up again. I'm interested in hearing if people have other functions that would be useful to them that act like this. So far the functions I have are:

 

Wait()

MoveTo()

PlayAnimation()

PlaySound()

 Share

6 Comments


Recommended Comments

Yeah, it can get confusing when working with, but thankfully using it once a system is setup is straight forward. I'll explain:

 

Lua has these things called coroutines. These allow you to stop execution of a function and continue it at a later time (that time is something you define). There are a few functions tied to them, namely:

routine = coroutine.create(func) (ties a function to this coroutine that is returned)

coroutine.yield() (jumps out of the coroutine function are in. when we resume it'll start back up after this statement)

coroutine.resume(routine, args_to_function) (starts/resumes a coroutine function you defined)

 

These are the building blocks for how coroutines work. If I want to be able to stop execution of a function I must create a coroutine for that function.

 

function Test(name)
end

-- associates the coroutine (cr) to the function (Test)
cr = coroutine.create(Test)

 

When I have a coroutine named cr that controls the function execution. I can start the function with:

coroutine.resume(cr, "Rick")

 

I can also step out of the function with:

coroutine.yield()

 

So to show a complete small & simple example. You can run this script using lua.exe.

 

function Test(name)
  print(name)
  coroutine.yield()  -- This will jump out of the Test() function and continue to do the while loop below
  print("is cool")
end

cr = coroutine.create(Test)   -- create a coroutine tied to the function Test
coroutine.resume(cr, "Rick")  -- This actually starts the function Test passing in "Rick" as the parameter

-- will loop for 5 seconds
i = os.time() + 5
while os.time() < i do
       -- This is here to show that it truly did leave the Test function.
       -- With this here you can't see that the Test function prints "Rick" so if you comment this print out
       -- you can see it prints "Rick" out on the console.
print("Looping") 
end

-- this will resume the Test function and you'll see it starts off where it left off, after the yield
-- inside the Test function. At this point it really doesn't matter what value I send it as the 2nd parameter
-- which is the parameter to the Test function, because it'll use whatever I sent it the first time. Which is
-- kind of a bummer because I thought it would be pretty neat if I could pass different values on every resume
-- but it's not a big deal really
coroutine.resume(cr, "Rick")

Link to comment

The way how coroutines work sounds like a simple function call to me.

It stops the execution of the calling function, and continues when the called function returns.

Link to comment

Not really. It continues when you tell it to continue not when the called function returns. You tell it to continue with a call to coroutine.resume() passing in the coroutine "handle". Coroutines also store all it's variable data the function had when you left it so when it continues it can call them back on the stack for you to use again once inside the coroutine function again.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...