read <aclass="reference internal"href="../Components/Commands.html"><spanclass="doc">the documentation on commands</span></a> to get a basic understanding of
<h2>The simple way to pause commands with yield<aclass="headerlink"href="#the-simple-way-to-pause-commands-with-yield"title="Permalink to this headline">¶</a></h2>
<p>Evennia allows a shortcut in syntax to create simple pauses in commands. This
syntax uses the <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> keyword. The <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> keyword is used in Python to
create generators, although you don’t need to know what generators are to use
this syntax. A short example will probably make it clear:</p>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Before ten seconds..."</span><spanclass="p">)</span>
<div><p>Important: The <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> functionality will <em>only</em> work in the <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> method of
Commands. It only works because Evennia has especially
catered for it in Commands. If you want the same functionality elsewhere you
<p>The important line is the <codeclass="docutils literal notranslate"><spanclass="pre">yield</span><spanclass="pre">10</span></code>. It tells Evennia to “pause” the command
and to wait for 10 seconds to execute the rest. If you add this command and
run it, you’ll see the first message, then, after a pause of ten seconds, the
next message. You can use <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> several times in your command.</p>
<p>This syntax will not “freeze” all commands. While the command is “pausing”,
you can execute other commands (or even call the same command again). And
other players aren’t frozen either.</p>
<blockquote>
<div><p>Note: this will not save anything in the database. If you reload the game
while a command is “paused”, it will not resume after the server has
<h2>The more advanced way with utils.delay<aclass="headerlink"href="#the-more-advanced-way-with-utils-delay"title="Permalink to this headline">¶</a></h2>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> syntax is easy to read, easy to understand, easy to use. But it’s not that flexible if
you want more advanced options. Learning to use alternatives might be much worth it in the end.</p>
<spanclass="sd"> This is called at the initial shout. </span>
<spanclass="sd">"""</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You shout '</span><spanclass="si">%s</span><spanclass="s2">' and wait for an echo ..."</span><spanclass="o">%</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">args</span><spanclass="p">)</span>
<spanclass="c1"># this waits non-blocking for 10 seconds, then calls self.echo</span>
<spanclass="n">utils</span><spanclass="o">.</span><spanclass="n">delay</span><spanclass="p">(</span><spanclass="mi">10</span><spanclass="p">,</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">echo</span><spanclass="p">)</span><spanclass="c1"># call echo after 10 seconds</span>
<p><codeclass="docutils literal notranslate"><spanclass="pre">utils.delay(timedelay,</span><spanclass="pre">callback,</span><spanclass="pre">persistent=False,</span><spanclass="pre">*args,</span><spanclass="pre">**kwargs)</span></code> is a useful function. It will
wait <codeclass="docutils literal notranslate"><spanclass="pre">timedelay</span></code> seconds, then call the <codeclass="docutils literal notranslate"><spanclass="pre">callback</span></code> function, optionally passing to it the arguments
provided to utils.delay by way of *args and/or **kwargs`.</p>
<div><p>If you are not familiar with the syntax <codeclass="docutils literal notranslate"><spanclass="pre">*args</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">**kwargs</span></code>, <aclass="reference external"href="https://docs.python.org/2/tutorial/controlflow.html#arbitrary-argument-lists">see the Python documentation
<p>Looking at it you might think that <codeclass="docutils literal notranslate"><spanclass="pre">utils.delay(10,</span><spanclass="pre">callback)</span></code> in the code above is just an
alternative to some more familiar thing like <codeclass="docutils literal notranslate"><spanclass="pre">time.sleep(10)</span></code>. This is <em>not</em> the case. If you do
<codeclass="docutils literal notranslate"><spanclass="pre">time.sleep(10)</span></code> you will in fact freeze the <em>entire server</em> for ten seconds! The <codeclass="docutils literal notranslate"><spanclass="pre">utils.delay()</span></code>is
a thin wrapper around a Twisted
<aclass="reference external"href="http://twistedmatrix.com/documents/11.0.0/core/howto/defer.html">Deferred</a> that will delay
execution until 10 seconds have passed, but will do so asynchronously, without bothering anyone else
(not even you - you can continue to do stuff normally while it waits to continue).</p>
<p>The point to remember here is that the <codeclass="docutils literal notranslate"><spanclass="pre">delay()</span></code> call will not “pause” at that point when it is
called (the way <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> does in the previous section). The lines after the <codeclass="docutils literal notranslate"><spanclass="pre">delay()</span></code> call will
actually execute <em>right away</em>. What you must do is to tell it which function to call <em>after the time
has passed</em> (its “callback”). This may sound strange at first, but it is normal practice in
asynchronous systems. You can also link such calls together as seen below:</p>
<spanclass="s2">"This sets off a chain of delayed calls"</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You shout '</span><spanclass="si">%s</span><spanclass="s2">', waiting for an echo ..."</span><spanclass="o">%</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">args</span><spanclass="p">)</span>
<spanclass="c1"># wait 2 seconds before calling self.echo1</span>
<p>As mentioned, a great thing about the delay introduced by <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">utils.delay()</span></code> is that it does
not block. It just goes on in the background and you are free to play normally in the interim. In
some cases this is not what you want however. Some commands should simply “block” other commands
while they are running. If you are in the process of crafting a helmet you shouldn’t be able to also
start crafting a shield at the same time, or if you just did a huge power-swing with your weapon you
should not be able to do it again immediately.</p>
<p>The simplest way of implementing blocking is to use the technique covered in the <aclass="reference internal"href="Command-Cooldown.html"><spanclass="doc">Command
Cooldown</span></a> tutorial. In that tutorial we implemented cooldowns by having the
Command store the current time. Next time the Command was called, we compared the current time to
the stored time to determine if enough time had passed for a renewed use. This is a <em>very</em>
efficient, reliable and passive solution. The drawback is that there is nothing to tell the Player
when enough time has passed unless they keep trying.</p>
<p>Here is an example where we will use <codeclass="docutils literal notranslate"><spanclass="pre">utils.delay</span></code> to tell the player when the cooldown has passed:</p>
<spanclass="c1"># we are still off-balance.</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You are off balance and need time to recover!"</span><spanclass="p">)</span>
<spanclass="k">return</span>
<spanclass="c1"># [attack/hit code goes here ...]</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You swing big! You are off balance now."</span><spanclass="p">)</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You regain your balance."</span><spanclass="p">)</span>
<p>Note how, after the cooldown, the user will get a message telling them they are now ready for
another swing.</p>
<p>By storing the <codeclass="docutils literal notranslate"><spanclass="pre">off_balance</span></code> flag on the character (rather than on, say, the Command instance
itself) it can be accessed by other Commands too. Other attacks may also not work when you are off
balance. You could also have an enemy Command check your <codeclass="docutils literal notranslate"><spanclass="pre">off_balance</span></code> status to gain bonuses, to
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You are already crafting!"</span><spanclass="p">)</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You create the first part of the armour."</span><spanclass="p">)</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You create the second part of the armour."</span><spanclass="p">)</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You finalize your armour."</span><spanclass="p">)</span>
<spanclass="c1"># example of a command that aborts crafting</span>
<p>The above code creates a delayed crafting command that will gradually create the armour. If the
<codeclass="docutils literal notranslate"><spanclass="pre">attack</span></code> command is issued during this process it will set a flag that causes the crafting to be
quietly canceled next time it tries to update.</p>
<p>In the latter examples above we used <codeclass="docutils literal notranslate"><spanclass="pre">.ndb</span></code> storage. This is fast and easy but it will reset all
cooldowns/blocks/crafting etc if you reload the server. If you don’t want that you can replace
<codeclass="docutils literal notranslate"><spanclass="pre">.ndb</span></code> with <codeclass="docutils literal notranslate"><spanclass="pre">.db</span></code>. But even this won’t help because the <codeclass="docutils literal notranslate"><spanclass="pre">yield</span></code> keyword is not persisent and nor is
the use of <codeclass="docutils literal notranslate"><spanclass="pre">delay</span></code> shown above. To resolve this you can use <codeclass="docutils literal notranslate"><spanclass="pre">delay</span></code> with the <codeclass="docutils literal notranslate"><spanclass="pre">persistent=True</span></code>
keyword. But wait! Making something persistent will add some extra complications, because now you
must make sure Evennia can properly store things to the database.</p>
<spanclass="sd"> This is called at the initial shout. </span>
<spanclass="sd">"""</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"You shout '</span><spanclass="si">%s</span><spanclass="s2">' and wait for an echo ..."</span><spanclass="o">%</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">args</span><spanclass="p">)</span>
<spanclass="c1"># this waits non-blocking for 10 seconds, then calls echo(self.caller, self.args)</span>
<li><p>The callback (<codeclass="docutils literal notranslate"><spanclass="pre">echo</span></code>) was moved out of the class and became its own stand-alone function in the
outermost scope of the module. It also now takes <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">args</span></code> as arguments (it doesn’t have
access to them directly since this is now a stand-alone function).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">utils.delay</span></code> specifies the <codeclass="docutils literal notranslate"><spanclass="pre">echo</span></code> function (not <codeclass="docutils literal notranslate"><spanclass="pre">self.echo</span></code> - it’s no longer a method!) and sends
<codeclass="docutils literal notranslate"><spanclass="pre">self.caller</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">self.args</span></code> as arguments for it to use. We also set <codeclass="docutils literal notranslate"><spanclass="pre">persistent=True</span></code>.</p></li>
<p>The reason for this change is because Evennia needs to <codeclass="docutils literal notranslate"><spanclass="pre">pickle</span></code> the callback into storage and it
cannot do this correctly when the method sits on the command class. Now this behave the same as the
first version except if you reload (or even shut down) the server mid-delay it will still fire the
callback when the server comes back up (it will resume the countdown and ignore the downtime).</p>