<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.pmdo.pmdcollab.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Tutorial%3ACoroutines_in_Scripts</id>
	<title>Tutorial:Coroutines in Scripts - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.pmdo.pmdcollab.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Tutorial%3ACoroutines_in_Scripts"/>
	<link rel="alternate" type="text/html" href="https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;action=history"/>
	<updated>2026-07-31T10:35:19Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=4620&amp;oldid=prev</id>
		<title>Imbion: Imbion moved page Coroutines in Scripts to Tutorial:Coroutines in Scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=4620&amp;oldid=prev"/>
		<updated>2025-10-16T15:46:23Z</updated>

		<summary type="html">&lt;p&gt;Imbion moved page &lt;a href=&quot;/Coroutines_in_Scripts&quot; class=&quot;mw-redirect&quot; title=&quot;Coroutines in Scripts&quot;&gt;Coroutines in Scripts&lt;/a&gt; to &lt;a href=&quot;/Tutorial:Coroutines_in_Scripts&quot; title=&quot;Tutorial:Coroutines in Scripts&quot;&gt;Tutorial:Coroutines in Scripts&lt;/a&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:46, 16 October 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Imbion</name></author>
	</entry>
	<entry>
		<id>https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=4084&amp;oldid=prev</id>
		<title>Imbion: /* Waiting for Coroutines */</title>
		<link rel="alternate" type="text/html" href="https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=4084&amp;oldid=prev"/>
		<updated>2025-09-02T16:11:21Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Waiting for Coroutines&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:11, 2 September 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l64&quot;&gt;Line 64:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 64:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;To wait for one of the coroutines branched previously, we would do so like the following:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;To wait for one of the coroutines branched previously, we would do so like the following:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;nowiki&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;nowiki&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;TASK:JoinCoroutines({runningCoro})&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/nowiki&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Here is an example of that being performed as a portion of a much larger cutscene script:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Here is an example of that being performed as a portion of a much larger cutscene script:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;nowiki&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  &amp;lt;nowiki&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Imbion</name></author>
	</entry>
	<entry>
		<id>https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=3697&amp;oldid=prev</id>
		<title>Imbion: Created page with &quot;Coroutines are an important part of scripting lua cutscenes in PMDO. This page is a tutorial and reference on basic usage of them. == Coroutine Basics == Like in most programming languages, by default lua executes all of its functions in order of script execution. In most cases, this is a very good thing! Think about it in terms of text boxes - we don&#039;t want other text boxes trying to appear while the player is still on a previous textbox. We have to finish whatever acti...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.pmdo.pmdcollab.org/wiki/index.php?title=Tutorial:Coroutines_in_Scripts&amp;diff=3697&amp;oldid=prev"/>
		<updated>2025-08-17T19:34:25Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Coroutines are an important part of scripting lua cutscenes in PMDO. This page is a tutorial and reference on basic usage of them. == Coroutine Basics == Like in most programming languages, by default lua executes all of its functions in order of script execution. In most cases, this is a very good thing! Think about it in terms of text boxes - we don&amp;#039;t want other text boxes trying to appear while the player is still on a previous textbox. We have to finish whatever acti...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Coroutines are an important part of scripting lua cutscenes in PMDO. This page is a tutorial and reference on basic usage of them.&lt;br /&gt;
== Coroutine Basics ==&lt;br /&gt;
Like in most programming languages, by default lua executes all of its functions in order of script execution. In most cases, this is a very good thing! Think about it in terms of text boxes - we don&amp;#039;t want other text boxes trying to appear while the player is still on a previous textbox. We have to finish whatever action we are doing first before the next line of code can execute.&lt;br /&gt;
&lt;br /&gt;
However, in some cases this becomes a hindrance. If we want two NPCs to walk together, then how do we have them do so simultaneously? The first one has to finish walking before the second one begins, and this looks very... Clunky.&lt;br /&gt;
&lt;br /&gt;
Cases like this, where we want other actions to happen simultaneously before others have &amp;quot;completed&amp;quot;, or when other actions are ongoing, are where we have to make use of coroutines.&lt;br /&gt;
&lt;br /&gt;
Coroutines split off a separate concurrent process that takes place on another &amp;quot;thread&amp;quot; of PMDO&amp;#039;s processes. &lt;br /&gt;
&lt;br /&gt;
== Creating a Coroutine ==&lt;br /&gt;
There is a function in PMDO, called &amp;lt;code&amp;gt;TASK:BranchCoroutine&amp;lt;/code&amp;gt;, that takes the function it is given and executes it on a separate thread.&lt;br /&gt;
&lt;br /&gt;
=== Function Init in Lua ===&lt;br /&gt;
In lua, functions are defined by initializing them as variables. When creating functions in a scripting file, we always do so by first creating a table, then assigning that function to a field of that table:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- The table the function occupies&lt;br /&gt;
myNamespace = {}&lt;br /&gt;
&lt;br /&gt;
-- Defining the function here&lt;br /&gt;
function myNamespace.Fun()&lt;br /&gt;
  -- imagine this function does something&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Calling the function&lt;br /&gt;
myNamespace.Fun()&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This stores the function in a place that can be referenced throughout files. In order to run a coroutine, we need to either reference or define the function that should be executed.&lt;br /&gt;
&lt;br /&gt;
=== Branching a Coroutine ===&lt;br /&gt;
&amp;lt;code&amp;gt;TASK:BranchCoroutine&amp;lt;/code&amp;gt; will create a branch that executes the coroutine we pass it. The ideal way to do this is to first define the coroutine in another variable, and then run &amp;lt;code&amp;gt;TASK:BranchCoroutine&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- The function we want to branch&lt;br /&gt;
local coro = function()&lt;br /&gt;
    GROUND:EntTurn(char, Direction.UpRight)&lt;br /&gt;
    GAME:WaitFrames(60)&lt;br /&gt;
    GROUND:EntTurn(char, Direction.UpLeft)&lt;br /&gt;
    GAME:WaitFrames(60)&lt;br /&gt;
    GROUND:EntTurn(char, Direction.Up)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creating the branch so coro starts but code exeuction of this file continues past this line&lt;br /&gt;
local runningCoro = TASK:BranchCoroutine(coro)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can alternatively define the function itself in the parameters, although this creates code that&amp;#039;s a bit harder to read:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- branching with defining the corotuine in the parameters itself&lt;br /&gt;
local runningCoro = TASK:BranchCoroutine(function() SOUND:PlayBGM(&amp;quot;Murky Forest.ogg&amp;quot;, false) end)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice how we saved the output of &amp;lt;code&amp;gt;TASK:BranchCoroutine&amp;lt;/code&amp;gt; to a variable. This keeps track of the status of the coroutine. There is an important reason why this was done.&lt;br /&gt;
&lt;br /&gt;
== Waiting for Coroutines ==&lt;br /&gt;
When running coroutines, the typical problem with running multiple functions at the same time makes itself known: How do we know that any of our functions actually finished executing? This is important because we need to have a way of determining the current state everything is in.&lt;br /&gt;
&lt;br /&gt;
In the earlier example, we may want the two NPCs to turn to face each other when they stop walking, and then continue the rest of the cutscene. We want to wait for their walking to finish - but we need a way of checking the coroutines branches for completing execution so we can proceed...&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;code&amp;gt;TASK:BranchCoroutine&amp;lt;/code&amp;gt; to a variable like before, we gain the ability to check if the coroutine has finished execution using the function &amp;lt;code&amp;gt;TASK:JoinCoroutines&amp;lt;/code&amp;gt;. This function causes execution of the script to wait until all of the links to the coroutines it is given notify the function that coroutine execution is complete.&lt;br /&gt;
&lt;br /&gt;
To wait for one of the coroutines branched previously, we would do so like the following:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Here is an example of that being performed as a portion of a much larger cutscene script:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- Branch all of the coroutines that will be active&lt;br /&gt;
local coro1 = TASK:BranchCoroutine(function() SOUND:PlayBGM(&amp;quot;Murky Forest.ogg&amp;quot;, false) end)&lt;br /&gt;
local coro2 = TASK:BranchCoroutine(function() GROUND:MoveToPosition(pic, picWalkPoint1.x, picWalkPoint1.y, true, 4) end)&lt;br /&gt;
local coro3 = TASK:BranchCoroutine(noticePichu)&lt;br /&gt;
&lt;br /&gt;
-- All of these coroutines will occur concurrently with this dialogue being shown&lt;br /&gt;
ScriptFunc.StartTalkingDuringConvo(argue.line1, &amp;quot;Shouting&amp;quot;, pic) -- shows a textbox with a new speaker &lt;br /&gt;
&lt;br /&gt;
-- All of the movement, music playing, and expressions must complete first, and then the rest of the script can proceed&lt;br /&gt;
TASK:JoinCoroutines({ coro1, coro2, coro3 })&lt;br /&gt;
&lt;br /&gt;
-- This next textbox will only show up once all three of those coroutine&amp;#039;s actions have completed, even if the player closed the textbox before by then&lt;br /&gt;
ScriptFunc.StartTalkingDuringConvo(argue.line2, &amp;quot;Surprised&amp;quot;, lar) -- shows a textbox with a new speaker &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;TASK:JoinCoroutines&amp;lt;/code&amp;gt; should &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; be used just before hiding the part of the script that may function only if the coroutine has finished, even if there appears to be no practical reason to do so. Otherwise, problems may occur with the script if everything isn&amp;#039;t in a consistent state when continuing. &lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>Imbion</name></author>
	</entry>
</feed>