mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 22:06:30 +01:00
824 lines
No EOL
80 KiB
HTML
824 lines
No EOL
80 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||
|
||
<title>Commands — Evennia 1.0-dev documentation</title>
|
||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<script src="../_static/language_data.js"></script>
|
||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="next" title="Command Sets" href="Command-Sets.html" />
|
||
<link rel="prev" title="Command System" href="Command-System.html" />
|
||
</head><body>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="Command-Sets.html" title="Command Sets"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Command-System.html" title="Command System"
|
||
accesskey="P">previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Commands</a></li>
|
||
</ul>
|
||
<div class="develop">develop branch</div>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" id="commands">
|
||
<h1>Commands<a class="headerlink" href="#commands" title="Permalink to this headline">¶</a></h1>
|
||
<p>Commands are intimately linked to <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Command Sets</span></a> and you need to read that page too to
|
||
be familiar with how the command system works. The two pages were split for easy reading.</p>
|
||
<p>The basic way for users to communicate with the game is through <em>Commands</em>. These can be commands
|
||
directly related to the game world such as <em>look</em>, <em>get</em>, <em>drop</em> and so on, or administrative
|
||
commands such as <em>examine</em> or <em>@dig</em>.</p>
|
||
<p>The <a class="reference internal" href="Default-Commands.html"><span class="doc std std-doc">default commands</span></a> coming with Evennia are ‘MUX-like’ in that they use @
|
||
for admin commands, support things like switches, syntax with the ‘=’ symbol etc, but there is
|
||
nothing that prevents you from implementing a completely different command scheme for your game. You
|
||
can find the default commands in <code class="docutils literal notranslate"><span class="pre">evennia/commands/default</span></code>. You should not edit these directly -
|
||
they will be updated by the Evennia team as new features are added. Rather you should look to them
|
||
for inspiration and inherit your own designs from them.</p>
|
||
<p>There are two components to having a command running - the <em>Command</em> class and the
|
||
<a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Command Set</span></a> (command sets were split into a separate wiki page for ease of reading).</p>
|
||
<ol class="simple">
|
||
<li><p>A <em>Command</em> is a python class containing all the functioning code for what a command does - for
|
||
example, a <em>get</em> command would contain code for picking up objects.</p></li>
|
||
<li><p>A <em>Command Set</em> (often referred to as a CmdSet or cmdset) is like a container for one or more
|
||
Commands. A given Command can go into any number of different command sets. Only by putting the
|
||
command set on a character object you will make all the commands therein available to use by that
|
||
character. You can also store command sets on normal objects if you want users to be able to use the
|
||
object in various ways. Consider a “Tree” object with a cmdset defining the commands <em>climb</em> and
|
||
<em>chop down</em>. Or a “Clock” with a cmdset containing the single command <em>check time</em>.</p></li>
|
||
</ol>
|
||
<p>This page goes into full detail about how to use Commands. To fully use them you must also read the
|
||
page detailing <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Command Sets</span></a>. There is also a step-by-step
|
||
<a class="reference internal" href="../Howtos/Beginner-Tutorial/Part1/Adding-Commands.html"><span class="doc std std-doc">Adding Command Tutorial</span></a> that will get you started quickly without the
|
||
extra explanations.</p>
|
||
<section id="defining-commands">
|
||
<h2>Defining Commands<a class="headerlink" href="#defining-commands" title="Permalink to this headline">¶</a></h2>
|
||
<p>All commands are implemented as normal Python classes inheriting from the base class <code class="docutils literal notranslate"><span class="pre">Command</span></code>
|
||
(<code class="docutils literal notranslate"><span class="pre">evennia.Command</span></code>). You will find that this base class is very “bare”. The default commands of
|
||
Evennia actually inherit from a child of <code class="docutils literal notranslate"><span class="pre">Command</span></code> called <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> - this is the class that
|
||
knows all the mux-like syntax like <code class="docutils literal notranslate"><span class="pre">/switches</span></code>, splitting by “=” etc. Below we’ll avoid mux-
|
||
specifics and use the base <code class="docutils literal notranslate"><span class="pre">Command</span></code> class directly.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># basic Command definition</span>
|
||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||
|
||
<span class="k">class</span> <span class="nc">MyCmd</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="sd">"""</span>
|
||
<span class="sd"> This is the help-text for the command</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"mycommand"</span>
|
||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># parsing the command line here</span>
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># executing the command here</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Here is a minimalistic command with no custom parsing:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"echo"</span>
|
||
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># echo the caller's input back to the caller</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Echo: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>You define a new command by assigning a few class-global properties on your inherited class and
|
||
overloading one or two hook functions. The full gritty mechanic behind how commands work are found
|
||
towards the end of this page; for now you only need to know that the command handler creates an
|
||
instance of this class and uses that instance whenever you use this command - it also dynamically
|
||
assigns the new command instance a few useful properties that you can assume to always be available.</p>
|
||
<section id="who-is-calling-the-command">
|
||
<h3>Who is calling the command?<a class="headerlink" href="#who-is-calling-the-command" title="Permalink to this headline">¶</a></h3>
|
||
<p>In Evennia there are three types of objects that may call the command. It is important to be aware
|
||
of this since this will also assign appropriate <code class="docutils literal notranslate"><span class="pre">caller</span></code>, <code class="docutils literal notranslate"><span class="pre">session</span></code>, <code class="docutils literal notranslate"><span class="pre">sessid</span></code> and <code class="docutils literal notranslate"><span class="pre">account</span></code>
|
||
properties on the command body at runtime. Most often the calling type is <code class="docutils literal notranslate"><span class="pre">Session</span></code>.</p>
|
||
<ul class="simple">
|
||
<li><p>A <a class="reference internal" href="Sessions.html"><span class="doc std std-doc">Session</span></a>. This is by far the most common case when a user is entering a command in
|
||
their client.</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">caller</span></code> - this is set to the puppeted <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a> if such an object exists. If no
|
||
puppet is found, <code class="docutils literal notranslate"><span class="pre">caller</span></code> is set equal to <code class="docutils literal notranslate"><span class="pre">account</span></code>. Only if an Account is not found either (such as
|
||
before being logged in) will this be set to the Session object itself.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">session</span></code> - a reference to the <a class="reference internal" href="Sessions.html"><span class="doc std std-doc">Session</span></a> object itself.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">sessid</span></code> - <code class="docutils literal notranslate"><span class="pre">sessid.id</span></code>, a unique integer identifier of the session.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - the <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> object connected to this Session. None if not logged in.</p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p>An <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a>. This only happens if <code class="docutils literal notranslate"><span class="pre">account.execute_cmd()</span></code> was used. No Session
|
||
information can be obtained in this case.</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">caller</span></code> - this is set to the puppeted Object if such an object can be determined (without
|
||
Session info this can only be determined in <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=0</span></code> or <code class="docutils literal notranslate"><span class="pre">1</span></code>). If no puppet is found,
|
||
this is equal to <code class="docutils literal notranslate"><span class="pre">account</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">session</span></code> - <code class="docutils literal notranslate"><span class="pre">None*</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">sessid</span></code> - <code class="docutils literal notranslate"><span class="pre">None*</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - Set to the Account object.</p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p>An <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a>. This only happens if <code class="docutils literal notranslate"><span class="pre">object.execute_cmd()</span></code> was used (for example by an
|
||
NPC).</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">caller</span></code> - This is set to the calling Object in question.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">session</span></code> - <code class="docutils literal notranslate"><span class="pre">None*</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">sessid</span></code> - <code class="docutils literal notranslate"><span class="pre">None*</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - <code class="docutils literal notranslate"><span class="pre">None</span></code></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<blockquote>
|
||
<div><p><code class="docutils literal notranslate"><span class="pre">*)</span></code>: There is a way to make the Session available also inside tests run directly on Accounts and
|
||
Objects, and that is to pass it to <code class="docutils literal notranslate"><span class="pre">execute_cmd</span></code> like so: <code class="docutils literal notranslate"><span class="pre">account.execute_cmd("...",</span> <span class="pre">session=<Session>)</span></code>. Doing so <em>will</em> make the <code class="docutils literal notranslate"><span class="pre">.session</span></code> and <code class="docutils literal notranslate"><span class="pre">.sessid</span></code> properties available in the
|
||
command.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="properties-assigned-to-the-command-instance-at-run-time">
|
||
<h3>Properties assigned to the command instance at run-time<a class="headerlink" href="#properties-assigned-to-the-command-instance-at-run-time" title="Permalink to this headline">¶</a></h3>
|
||
<p>Let’s say account <em>Bob</em> with a character <em>BigGuy</em> enters the command <em>look at sword</em>. After the
|
||
system having successfully identified this as the “look” command and determined that BigGuy really
|
||
has access to a command named <code class="docutils literal notranslate"><span class="pre">look</span></code>, it chugs the <code class="docutils literal notranslate"><span class="pre">look</span></code> command class out of storage and either
|
||
loads an existing Command instance from cache or creates one. After some more checks it then assigns
|
||
it the following properties:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">caller</span></code> - The character BigGuy, in this example. This is a reference to the object executing the
|
||
command. The value of this depends on what type of object is calling the command; see the previous
|
||
section.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">session</span></code> - the <a class="reference internal" href="Sessions.html"><span class="doc std std-doc">Session</span></a> Bob uses to connect to the game and control BigGuy (see also
|
||
previous section).</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">sessid</span></code> - the unique id of <code class="docutils literal notranslate"><span class="pre">self.session</span></code>, for quick lookup.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - the <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> Bob (see previous section).</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">cmdstring</span></code> - the matched key for the command. This would be <em>look</em> in our example.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">args</span></code> - this is the rest of the string, except the command name. So if the string entered was
|
||
<em>look at sword</em>, <code class="docutils literal notranslate"><span class="pre">args</span></code> would be ” <em>at sword</em>”. Note the space kept - Evennia would correctly
|
||
interpret <code class="docutils literal notranslate"><span class="pre">lookat</span> <span class="pre">sword</span></code> too. This is useful for things like <code class="docutils literal notranslate"><span class="pre">/switches</span></code> that should not use space.
|
||
In the <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> class used for default commands, this space is stripped. Also see the
|
||
<code class="docutils literal notranslate"><span class="pre">arg_regex</span></code> property if you want to enforce a space to make <code class="docutils literal notranslate"><span class="pre">lookat</span> <span class="pre">sword</span></code> give a command-not-found
|
||
error.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">obj</span></code> - the game <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a> on which this command is defined. This need not be the caller,
|
||
but since <code class="docutils literal notranslate"><span class="pre">look</span></code> is a common (default) command, this is probably defined directly on <em>BigGuy</em> - so
|
||
<code class="docutils literal notranslate"><span class="pre">obj</span></code> will point to BigGuy. Otherwise <code class="docutils literal notranslate"><span class="pre">obj</span></code> could be an Account or any interactive object with
|
||
commands defined on it, like in the example of the “check time” command defined on a “Clock” object.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">cmdset</span></code> - this is a reference to the merged CmdSet (see below) from which this command was
|
||
matched. This variable is rarely used, it’s main use is for the [auto-help system](Help-
|
||
System#command-auto-help-system) (<em>Advanced note: the merged cmdset need NOT be the same as
|
||
<code class="docutils literal notranslate"><span class="pre">BigGuy.cmdset</span></code>. The merged set can be a combination of the cmdsets from other objects in the room,
|
||
for example</em>).</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">raw_string</span></code> - this is the raw input coming from the user, without stripping any surrounding
|
||
whitespace. The only thing that is stripped is the ending newline marker.</p></li>
|
||
</ul>
|
||
<section id="other-useful-utility-methods">
|
||
<h4>Other useful utility methods:<a class="headerlink" href="#other-useful-utility-methods" title="Permalink to this headline">¶</a></h4>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">.get_help(caller,</span> <span class="pre">cmdset)</span></code> - Get the help entry for this command. By default the arguments are
|
||
not
|
||
used, but they could be used to implement alternate help-display systems.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">.client_width()</span></code> - Shortcut for getting the client’s screen-width. Note that not all clients will
|
||
truthfully report this value - that case the <code class="docutils literal notranslate"><span class="pre">settings.DEFAULT_SCREEN_WIDTH</span></code> will be returned.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">.styled_table(*args,</span> <span class="pre">**kwargs)</span></code> - This returns an [EvTable](module-
|
||
evennia.utils.evtable) styled based on the
|
||
session calling this command. The args/kwargs are the same as for EvTable, except styling defaults
|
||
are set.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">.styled_header</span></code>, <code class="docutils literal notranslate"><span class="pre">_footer</span></code>, <code class="docutils literal notranslate"><span class="pre">separator</span></code> - These will produce styled decorations for
|
||
display to the user. They are useful for creating listings and forms with colors adjustable per-
|
||
user.</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="defining-your-own-command-classes">
|
||
<h3>Defining your own command classes<a class="headerlink" href="#defining-your-own-command-classes" title="Permalink to this headline">¶</a></h3>
|
||
<p>Beyond the properties Evennia always assigns to the command at run-time (listed above), your job is
|
||
to define the following class properties:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">key</span></code> (string) - the identifier for the command, like <code class="docutils literal notranslate"><span class="pre">look</span></code>. This should (ideally) be unique. A
|
||
key can consist of more than one word, like “press button” or “pull left lever”. Note that <em>both</em>
|
||
<code class="docutils literal notranslate"><span class="pre">key</span></code> and <code class="docutils literal notranslate"><span class="pre">aliases</span></code> below determine the identity of a command. So two commands are considered if
|
||
either matches. This is important for merging cmdsets described below.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">aliases</span></code> (optional list) - a list of alternate names for the command (<code class="docutils literal notranslate"><span class="pre">["glance",</span> <span class="pre">"see",</span> <span class="pre">"l"]</span></code>).
|
||
Same name rules as for <code class="docutils literal notranslate"><span class="pre">key</span></code> applies.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">locks</span></code> (string) - a <a class="reference internal" href="Locks.html"><span class="doc std std-doc">lock definition</span></a>, usually on the form <code class="docutils literal notranslate"><span class="pre">cmd:<lockfuncs></span></code>. Locks is a
|
||
rather big topic, so until you learn more about locks, stick to giving the lockstring <code class="docutils literal notranslate"><span class="pre">"cmd:all()"</span></code>
|
||
to make the command available to everyone (if you don’t provide a lock string, this will be assigned
|
||
for you).</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">help_category</span></code> (optional string) - setting this helps to structure the auto-help into categories.
|
||
If none is set, this will be set to <em>General</em>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">save_for_next</span></code> (optional boolean). This defaults to <code class="docutils literal notranslate"><span class="pre">False</span></code>. If <code class="docutils literal notranslate"><span class="pre">True</span></code>, a copy of this command
|
||
object (along with any changes you have done to it) will be stored by the system and can be accessed
|
||
by the next command by retrieving <code class="docutils literal notranslate"><span class="pre">self.caller.ndb.last_cmd</span></code>. The next run command will either clear
|
||
or replace the storage.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">arg_regex</span></code> (optional raw string): Used to force the parser to limit itself and tell it when the
|
||
command-name ends and arguments begin (such as requiring this to be a space or a /switch). This is
|
||
done with a regular expression. <a class="reference internal" href="#on-arg-regex"><span class="std std-doc">See the arg_regex section</span></a> for the details.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">auto_help</span></code> (optional boolean). Defaults to <code class="docutils literal notranslate"><span class="pre">True</span></code>. This allows for turning off the
|
||
<a class="reference internal" href="Help-System.html#command-auto-help-system"><span class="std std-doc">auto-help system</span></a> on a per-command basis. This could be useful if you
|
||
either want to write your help entries manually or hide the existence of a command from <code class="docutils literal notranslate"><span class="pre">help</span></code>’s
|
||
generated list.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">is_exit</span></code> (bool) - this marks the command as being used for an in-game exit. This is, by default,
|
||
set by all Exit objects and you should not need to set it manually unless you make your own Exit
|
||
system. It is used for optimization and allows the cmdhandler to easily disregard this command when
|
||
the cmdset has its <code class="docutils literal notranslate"><span class="pre">no_exits</span></code> flag set.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">is_channel</span></code> (bool)- this marks the command as being used for an in-game channel. This is, by
|
||
default, set by all Channel objects and you should not need to set it manually unless you make your
|
||
own Channel system. is used for optimization and allows the cmdhandler to easily disregard this
|
||
command when its cmdset has its <code class="docutils literal notranslate"><span class="pre">no_channels</span></code> flag set.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">msg_all_sessions</span></code> (bool): This affects the behavior of the <code class="docutils literal notranslate"><span class="pre">Command.msg</span></code> method. If unset
|
||
(default), calling <code class="docutils literal notranslate"><span class="pre">self.msg(text)</span></code> from the Command will always only send text to the Session that
|
||
actually triggered this Command. If set however, <code class="docutils literal notranslate"><span class="pre">self.msg(text)</span></code> will send to all Sessions relevant
|
||
to the object this Command sits on. Just which Sessions receives the text depends on the object and
|
||
the server’s <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span></code>.</p></li>
|
||
</ul>
|
||
<p>You should also implement at least two methods, <code class="docutils literal notranslate"><span class="pre">parse()</span></code> and <code class="docutils literal notranslate"><span class="pre">func()</span></code> (You could also implement
|
||
<code class="docutils literal notranslate"><span class="pre">perm()</span></code>, but that’s not needed unless you want to fundamentally change how access checks work).</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">at_pre_cmd()</span></code> is called very first on the command. If this function returns anything that
|
||
evaluates to <code class="docutils literal notranslate"><span class="pre">True</span></code> the command execution is aborted at this point.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">parse()</span></code> is intended to parse the arguments (<code class="docutils literal notranslate"><span class="pre">self.args</span></code>) of the function. You can do this in any
|
||
way you like, then store the result(s) in variable(s) on the command object itself (i.e. on <code class="docutils literal notranslate"><span class="pre">self</span></code>).
|
||
To take an example, the default mux-like system uses this method to detect “command switches” and
|
||
store them as a list in <code class="docutils literal notranslate"><span class="pre">self.switches</span></code>. Since the parsing is usually quite similar inside a command
|
||
scheme you should make <code class="docutils literal notranslate"><span class="pre">parse()</span></code> as generic as possible and then inherit from it rather than re-
|
||
implementing it over and over. In this way, the default <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> class implements a <code class="docutils literal notranslate"><span class="pre">parse()</span></code>
|
||
for all child commands to use.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">func()</span></code> is called right after <code class="docutils literal notranslate"><span class="pre">parse()</span></code> and should make use of the pre-parsed input to actually
|
||
do whatever the command is supposed to do. This is the main body of the command. The return value
|
||
from this method will be returned from the execution as a Twisted Deferred.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">at_post_cmd()</span></code> is called after <code class="docutils literal notranslate"><span class="pre">func()</span></code> to handle eventual cleanup.</p></li>
|
||
</ul>
|
||
<p>Finally, you should always make an informative <a class="reference external" href="https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring">doc
|
||
string</a> (<code class="docutils literal notranslate"><span class="pre">__doc__</span></code>) at the top of
|
||
your class. This string is dynamically read by the <a class="reference internal" href="Help-System.html"><span class="doc std std-doc">Help System</span></a> to create the help
|
||
entry for this command. You should decide on a way to format your help and stick to that.</p>
|
||
<p>Below is how you define a simple alternative “<code class="docutils literal notranslate"><span class="pre">smile</span></code>” command:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdSmile</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="sd">"""</span>
|
||
<span class="sd"> A smile command</span>
|
||
|
||
<span class="sd"> Usage:</span>
|
||
<span class="sd"> smile [at] [<someone>]</span>
|
||
<span class="sd"> grin [at] [<someone>]</span>
|
||
|
||
<span class="sd"> Smiles to someone in your vicinity or to the room</span>
|
||
<span class="sd"> in general.</span>
|
||
|
||
<span class="sd"> (This initial string (the __doc__ string)</span>
|
||
<span class="sd"> is also used to auto-generate the help</span>
|
||
<span class="sd"> for this command)</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"smile"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"smile at"</span><span class="p">,</span> <span class="s2">"grin"</span><span class="p">,</span> <span class="s2">"grin at"</span><span class="p">]</span>
|
||
<span class="n">locks</span> <span class="o">=</span> <span class="s2">"cmd:all()"</span>
|
||
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">"General"</span>
|
||
|
||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="s2">"Very trivial parser"</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="s2">"This actually does things"</span>
|
||
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">==</span> <span class="s2">"here"</span><span class="p">:</span>
|
||
<span class="n">string</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">caller</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> smiles"</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">target</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">target</span><span class="p">:</span>
|
||
<span class="k">return</span>
|
||
<span class="n">string</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">caller</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> smiles at </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">"</span>
|
||
|
||
<span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>The power of having commands as classes and to separate <code class="docutils literal notranslate"><span class="pre">parse()</span></code> and <code class="docutils literal notranslate"><span class="pre">func()</span></code>
|
||
lies in the ability to inherit functionality without having to parse every
|
||
command individually. For example, as mentioned the default commands all
|
||
inherit from <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code>. <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> implements its own version of <code class="docutils literal notranslate"><span class="pre">parse()</span></code>
|
||
that understands all the specifics of MUX-like commands. Almost none of the
|
||
default commands thus need to implement <code class="docutils literal notranslate"><span class="pre">parse()</span></code> at all, but can assume the
|
||
incoming string is already split up and parsed in suitable ways by its parent.</p>
|
||
<p>Before you can actually use the command in your game, you must now store it
|
||
within a <em>command set</em>. See the <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Command Sets</span></a> page.</p>
|
||
</section>
|
||
<section id="command-prefixes">
|
||
<h3>Command prefixes<a class="headerlink" href="#command-prefixes" title="Permalink to this headline">¶</a></h3>
|
||
<p>Historically, many MU* servers used to use prefix, such as <code class="docutils literal notranslate"><span class="pre">@</span></code> or <code class="docutils literal notranslate"><span class="pre">&</span></code> to signify that
|
||
a command is used for administration or requires staff privileges. The problem with this is that
|
||
newcomers to MU often find such extra symbols confusing. Evennia allows commands that can be
|
||
accessed both with- or without such a prefix.</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>CMD_IGNORE_PREFIXES = "@&/+`
|
||
</pre></div>
|
||
</div>
|
||
<p>This is a setting consisting of a string of characters. Each is a prefix that will be considered
|
||
a skippable prefix - <em>if the command is still unique in its cmdset when skipping the prefix</em>.</p>
|
||
<p>So if you wanted to write <code class="docutils literal notranslate"><span class="pre">@look</span></code> instead of <code class="docutils literal notranslate"><span class="pre">look</span></code> you can do so - the <code class="docutils literal notranslate"><span class="pre">@</span></code> will be ignored. But If
|
||
we added an actual <code class="docutils literal notranslate"><span class="pre">@look</span></code> command (with a <code class="docutils literal notranslate"><span class="pre">key</span></code> or alias <code class="docutils literal notranslate"><span class="pre">@look</span></code>) then we would need to use the
|
||
<code class="docutils literal notranslate"><span class="pre">@</span></code> to separate between the two.</p>
|
||
<p>This is also used in the default commands. For example, <code class="docutils literal notranslate"><span class="pre">@open</span></code> is a building
|
||
command that allows you to create new exits to link two rooms together. Its <code class="docutils literal notranslate"><span class="pre">key</span></code> is set to <code class="docutils literal notranslate"><span class="pre">@open</span></code>,
|
||
including the <code class="docutils literal notranslate"><span class="pre">@</span></code> (no alias is set). By default you can use both <code class="docutils literal notranslate"><span class="pre">@open</span></code> and <code class="docutils literal notranslate"><span class="pre">open</span></code> for
|
||
this command. But “open” is a pretty common word and let’s say a developer adds a new <code class="docutils literal notranslate"><span class="pre">open</span></code> command
|
||
for opening a door. Now <code class="docutils literal notranslate"><span class="pre">@open</span></code> and <code class="docutils literal notranslate"><span class="pre">open</span></code> are two different commands and the <code class="docutils literal notranslate"><span class="pre">@</span></code> must be used to
|
||
separate them.</p>
|
||
<blockquote>
|
||
<div><p>The <code class="docutils literal notranslate"><span class="pre">help</span></code> command will prefer to show all command names without prefix if
|
||
possible. Only if there is a collision, will the prefix be shown in the help system.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="on-arg-regex">
|
||
<h3>On arg_regex<a class="headerlink" href="#on-arg-regex" title="Permalink to this headline">¶</a></h3>
|
||
<p>The command parser is very general and does not require a space to end your command name. This means
|
||
that the alias <code class="docutils literal notranslate"><span class="pre">:</span></code> to <code class="docutils literal notranslate"><span class="pre">emote</span></code> can be used like <code class="docutils literal notranslate"><span class="pre">:smiles</span></code> without modification. It also means
|
||
<code class="docutils literal notranslate"><span class="pre">getstone</span></code> will get you the stone (unless there is a command specifically named <code class="docutils literal notranslate"><span class="pre">getstone</span></code>, then
|
||
that will be used). If you want to tell the parser to require a certain separator between the
|
||
command name and its arguments (so that <code class="docutils literal notranslate"><span class="pre">get</span> <span class="pre">stone</span></code> works but <code class="docutils literal notranslate"><span class="pre">getstone</span></code> gives you a ‘command not
|
||
found’ error) you can do so with the <code class="docutils literal notranslate"><span class="pre">arg_regex</span></code> property.</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">arg_regex</span></code> is a <a class="reference external" href="https://docs.python.org/library/re.html">raw regular expression string</a>. The
|
||
regex will be compiled by the system at runtime. This allows you to customize how the part
|
||
<em>immediately following</em> the command name (or alias) must look in order for the parser to match for
|
||
this command. Some examples:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">commandname</span> <span class="pre">argument</span></code> (<code class="docutils literal notranslate"><span class="pre">arg_regex</span> <span class="pre">=</span> <span class="pre">r"\s.+"</span></code>): This forces the parser to require the command name
|
||
to be followed by one or more spaces. Whatever is entered after the space will be treated as an
|
||
argument. However, if you’d forget the space (like a command having no arguments), this would <em>not</em>
|
||
match <code class="docutils literal notranslate"><span class="pre">commandname</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">commandname</span></code> or <code class="docutils literal notranslate"><span class="pre">commandname</span> <span class="pre">argument</span></code> (<code class="docutils literal notranslate"><span class="pre">arg_regex</span> <span class="pre">=</span> <span class="pre">r"\s.+|$"</span></code>): This makes both <code class="docutils literal notranslate"><span class="pre">look</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">look</span> <span class="pre">me</span></code> work but <code class="docutils literal notranslate"><span class="pre">lookme</span></code> will not.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">commandname/switches</span> <span class="pre">arguments</span></code> (<code class="docutils literal notranslate"><span class="pre">arg_regex</span> <span class="pre">=</span> <span class="pre">r"(?:^(?:\s+|\/).*$)|^$"</span></code>. If you are using
|
||
Evennia’s <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> Command parent, you may wish to use this since it will allow <code class="docutils literal notranslate"><span class="pre">/switche</span></code>s to
|
||
work as well as having or not having a space.</p></li>
|
||
</ul>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">arg_regex</span></code> allows you to customize the behavior of your commands. You can put it in the parent
|
||
class of your command to customize all children of your Commands. However, you can also change the
|
||
base default behavior for all Commands by modifying <code class="docutils literal notranslate"><span class="pre">settings.COMMAND_DEFAULT_ARG_REGEX</span></code>.</p>
|
||
</section>
|
||
</section>
|
||
<section id="exiting-a-command">
|
||
<h2>Exiting a command<a class="headerlink" href="#exiting-a-command" title="Permalink to this headline">¶</a></h2>
|
||
<p>Normally you just use <code class="docutils literal notranslate"><span class="pre">return</span></code> in one of your Command class’ hook methods to exit that method. That
|
||
will however still fire the other hook methods of the Command in sequence. That’s usually what you
|
||
want but sometimes it may be useful to just abort the command, for example if you find some
|
||
unacceptable input in your parse method. To exit the command this way you can raise
|
||
<code class="docutils literal notranslate"><span class="pre">evennia.InterruptCommand</span></code>:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">InterruptCommand</span>
|
||
|
||
<span class="k">class</span> <span class="nc">MyCommand</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
|
||
<span class="c1"># ...</span>
|
||
|
||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># ...</span>
|
||
<span class="c1"># if this fires, `func()` and `at_post_cmd` will not</span>
|
||
<span class="c1"># be called at all</span>
|
||
<span class="k">raise</span> <span class="n">InterruptCommand</span><span class="p">()</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="pauses-in-commands">
|
||
<h2>Pauses in commands<a class="headerlink" href="#pauses-in-commands" title="Permalink to this headline">¶</a></h2>
|
||
<p>Sometimes you want to pause the execution of your command for a little while before continuing -
|
||
maybe you want to simulate a heavy swing taking some time to finish, maybe you want the echo of your
|
||
voice to return to you with an ever-longer delay. Since Evennia is running asynchronously, you
|
||
cannot use <code class="docutils literal notranslate"><span class="pre">time.sleep()</span></code> in your commands (or anywhere, really). If you do, the <em>entire game</em> will
|
||
be frozen for everyone! So don’t do that. Fortunately, Evennia offers a really quick syntax for
|
||
making pauses in commands.</p>
|
||
<p>In your <code class="docutils literal notranslate"><span class="pre">func()</span></code> method, you can use the <code class="docutils literal notranslate"><span class="pre">yield</span></code> keyword. This is a Python keyword that will freeze
|
||
the current execution of your command and wait for more before processing.</p>
|
||
<blockquote>
|
||
<div><p>Note that you <em>cannot</em> just drop <code class="docutils literal notranslate"><span class="pre">yield</span></code> into any code and expect it to pause. Evennia will only
|
||
pause for you if you <code class="docutils literal notranslate"><span class="pre">yield</span></code> inside the Command’s <code class="docutils literal notranslate"><span class="pre">func()</span></code> method. Don’t expect it to work anywhere
|
||
else.</p>
|
||
</div></blockquote>
|
||
<p>Here’s an example of a command using a small pause of five seconds between messages:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdWait</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="sd">"""</span>
|
||
<span class="sd"> A dummy command to show how to wait</span>
|
||
|
||
<span class="sd"> Usage:</span>
|
||
<span class="sd"> wait</span>
|
||
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"wait"</span>
|
||
<span class="n">locks</span> <span class="o">=</span> <span class="s2">"cmd:all()"</span>
|
||
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">"General"</span>
|
||
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="sd">"""Command execution."""</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Beginner-Tutorial to wait ..."</span><span class="p">)</span>
|
||
<span class="k">yield</span> <span class="mi">5</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"... This shows after 5 seconds. Waiting ..."</span><span class="p">)</span>
|
||
<span class="k">yield</span> <span class="mi">2</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"... And now another 2 seconds have passed."</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The important line is the <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">5</span></code> and <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">2</span></code> lines. It will tell Evennia to pause execution
|
||
here and not continue until the number of seconds given has passed.</p>
|
||
<p>There are two things to remember when using <code class="docutils literal notranslate"><span class="pre">yield</span></code> in your Command’s <code class="docutils literal notranslate"><span class="pre">func</span></code> method:</p>
|
||
<ol class="simple">
|
||
<li><p>The paused state produced by the <code class="docutils literal notranslate"><span class="pre">yield</span></code> is not saved anywhere. So if the server reloads in the
|
||
middle of your command pausing, it will <em>not</em> resume when the server comes back up - the remainder
|
||
of the command will never fire. So be careful that you are not freezing the character or account in
|
||
a way that will not be cleared on reload.</p></li>
|
||
<li><p>If you use <code class="docutils literal notranslate"><span class="pre">yield</span></code> you may not also use <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre"><values></span></code> in your <code class="docutils literal notranslate"><span class="pre">func</span></code> method. You’ll get an
|
||
error explaining this. This is due to how Python generators work. You can however use a “naked”
|
||
<code class="docutils literal notranslate"><span class="pre">return</span></code> just fine. Usually there is no need for <code class="docutils literal notranslate"><span class="pre">func</span></code> to return a value, but if you ever do need
|
||
to mix <code class="docutils literal notranslate"><span class="pre">yield</span></code> with a final return value in the same <code class="docutils literal notranslate"><span class="pre">func</span></code>, look at
|
||
<a class="reference external" href="https://twistedmatrix.com/documents/current/api/twisted.internet.defer.html#returnValue">twisted.internet.defer.returnValue</a>.</p></li>
|
||
</ol>
|
||
</section>
|
||
<section id="asking-for-user-input">
|
||
<h2>Asking for user input<a class="headerlink" href="#asking-for-user-input" title="Permalink to this headline">¶</a></h2>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">yield</span></code> keyword can also be used to ask for user input. Again you can’t
|
||
use Python’s <code class="docutils literal notranslate"><span class="pre">input</span></code> in your command, for it would freeze Evennia for
|
||
everyone while waiting for that user to input their text. Inside a Command’s
|
||
<code class="docutils literal notranslate"><span class="pre">func</span></code> method, the following syntax can also be used:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">answer</span> <span class="o">=</span> <span class="k">yield</span><span class="p">(</span><span class="s2">"Your question"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Here’s a very simple example:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdConfirm</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
|
||
<span class="sd">"""</span>
|
||
<span class="sd"> A dummy command to show confirmation.</span>
|
||
|
||
<span class="sd"> Usage:</span>
|
||
<span class="sd"> confirm</span>
|
||
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"confirm"</span>
|
||
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">answer</span> <span class="o">=</span> <span class="k">yield</span><span class="p">(</span><span class="s2">"Are you sure you want to go on?"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">answer</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"yes"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Yes!"</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"No!"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This time, when the user enters the ‘confirm’ command, she will be asked if she wants to go on.
|
||
Entering ‘yes’ or “y” (regardless of case) will give the first reply, otherwise the second reply
|
||
will show.</p>
|
||
<blockquote>
|
||
<div><p>Note again that the <code class="docutils literal notranslate"><span class="pre">yield</span></code> keyword does not store state. If the game reloads while waiting for
|
||
the user to answer, the user will have to start over. It is not a good idea to use <code class="docutils literal notranslate"><span class="pre">yield</span></code> for
|
||
important or complex choices, a persistent <a class="reference internal" href="EvMenu.html"><span class="doc std std-doc">EvMenu</span></a> might be more appropriate in this case.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="system-commands">
|
||
<h2>System commands<a class="headerlink" href="#system-commands" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Note: This is an advanced topic. Skip it if this is your first time learning about commands.</em></p>
|
||
<p>There are several command-situations that are exceptional in the eyes of the server. What happens if
|
||
the account enters an empty string? What if the ‘command’ given is infact the name of a channel the
|
||
user wants to send a message to? Or if there are multiple command possibilities?</p>
|
||
<p>Such ‘special cases’ are handled by what’s called <em>system commands</em>. A system command is defined
|
||
in the same way as other commands, except that their name (key) must be set to one reserved by the
|
||
engine (the names are defined at the top of <code class="docutils literal notranslate"><span class="pre">evennia/commands/cmdhandler.py</span></code>). You can find (unused)
|
||
implementations of the system commands in <code class="docutils literal notranslate"><span class="pre">evennia/commands/default/system_commands.py</span></code>. Since these
|
||
are not (by default) included in any <code class="docutils literal notranslate"><span class="pre">CmdSet</span></code> they are not actually used, they are just there for
|
||
show. When the special situation occurs, Evennia will look through all valid <code class="docutils literal notranslate"><span class="pre">CmdSet</span></code>s for your
|
||
custom system command. Only after that will it resort to its own, hard-coded implementation.</p>
|
||
<p>Here are the exceptional situations that triggers system commands. You can find the command keys
|
||
they use as properties on <code class="docutils literal notranslate"><span class="pre">evennia.syscmdkeys</span></code>:</p>
|
||
<ul class="simple">
|
||
<li><p>No input (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_NOINPUT</span></code>) - the account just pressed return without any input. Default
|
||
is to do nothing, but it can be useful to do something here for certain implementations such as line
|
||
editors that interpret non-commands as text input (an empty line in the editing buffer).</p></li>
|
||
<li><p>Command not found (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_NOMATCH</span></code>) - No matching command was found. Default is to
|
||
display the “Huh?” error message.</p></li>
|
||
<li><p>Several matching commands where found (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_MULTIMATCH</span></code>) - Default is to show a list of
|
||
matches.</p></li>
|
||
<li><p>User is not allowed to execute the command (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_NOPERM</span></code>) - Default is to display the
|
||
“Huh?” error message.</p></li>
|
||
<li><p>Channel (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_CHANNEL</span></code>) - This is a <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channel</span></a> name of a channel you are
|
||
subscribing to - Default is to relay the command’s argument to that channel. Such commands are
|
||
created by the Comm system on the fly depending on your subscriptions.</p></li>
|
||
<li><p>New session connection (<code class="docutils literal notranslate"><span class="pre">syscmdkeys.CMD_LOGINSTART</span></code>). This command name should be put in the
|
||
<code class="docutils literal notranslate"><span class="pre">settings.CMDSET_UNLOGGEDIN</span></code>. Whenever a new connection is established, this command is always
|
||
called on the server (default is to show the login screen).</p></li>
|
||
</ul>
|
||
<p>Below is an example of redefining what happens when the account doesn’t provide any input (e.g. just
|
||
presses return). Of course the new system command must be added to a cmdset as well before it will
|
||
work.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">syscmdkeys</span><span class="p">,</span> <span class="n">Command</span>
|
||
|
||
<span class="k">class</span> <span class="nc">MyNoInputCommand</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="s2">"Usage: Just press return, I dare you"</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="n">syscmdkeys</span><span class="o">.</span><span class="n">CMD_NOINPUT</span>
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Don't just press return like that, talk to me!"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="dynamic-commands">
|
||
<h2>Dynamic Commands<a class="headerlink" href="#dynamic-commands" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Note: This is an advanced topic.</em></p>
|
||
<p>Normally Commands are created as fixed classes and used without modification. There are however
|
||
situations when the exact key, alias or other properties is not possible (or impractical) to pre-
|
||
code (<a class="reference internal" href="#exits"><span class="std std-doc">Exits</span></a> is an example of this).</p>
|
||
<p>To create a command with a dynamic call signature, first define the command body normally in a class
|
||
(set your <code class="docutils literal notranslate"><span class="pre">key</span></code>, <code class="docutils literal notranslate"><span class="pre">aliases</span></code> to default values), then use the following call (assuming the command
|
||
class you created is named <code class="docutils literal notranslate"><span class="pre">MyCommand</span></code>):</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">cmd</span> <span class="o">=</span> <span class="n">MyCommand</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">"newname"</span><span class="p">,</span>
|
||
<span class="n">aliases</span><span class="o">=</span><span class="p">[</span><span class="s2">"test"</span><span class="p">,</span> <span class="s2">"test2"</span><span class="p">],</span>
|
||
<span class="n">locks</span><span class="o">=</span><span class="s2">"cmd:all()"</span><span class="p">,</span>
|
||
<span class="o">...</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><em>All</em> keyword arguments you give to the Command constructor will be stored as a property on the
|
||
command object. This will overload existing properties defined on the parent class.</p>
|
||
<p>Normally you would define your class and only overload things like <code class="docutils literal notranslate"><span class="pre">key</span></code> and <code class="docutils literal notranslate"><span class="pre">aliases</span></code> at run-time.
|
||
But you could in principle also send method objects (like <code class="docutils literal notranslate"><span class="pre">func</span></code>) as keyword arguments in order to
|
||
make your command completely customized at run-time.</p>
|
||
</section>
|
||
<section id="exits">
|
||
<h2>Exits<a class="headerlink" href="#exits" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Note: This is an advanced topic.</em></p>
|
||
<p>Exits are examples of the use of a <a class="reference internal" href="#dynamic-commands"><span class="std std-doc">Dynamic Command</span></a>.</p>
|
||
<p>The functionality of <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Exit</span></a> objects in Evennia is not hard-coded in the engine. Instead
|
||
Exits are normal <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">typeclassed</span></a> objects that auto-create a <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">CmdSet</span></a> on
|
||
themselves when they load. This cmdset has a single dynamically created Command with the same
|
||
properties (key, aliases and locks) as the Exit object itself. When entering the name of the exit,
|
||
this dynamic exit-command is triggered and (after access checks) moves the Character to the exit’s
|
||
destination.
|
||
Whereas you could customize the Exit object and its command to achieve completely different
|
||
behaviour, you will usually be fine just using the appropriate <code class="docutils literal notranslate"><span class="pre">traverse_*</span></code> hooks on the Exit
|
||
object. But if you are interested in really changing how things work under the hood, check out
|
||
<code class="docutils literal notranslate"><span class="pre">evennia/objects/objects.py</span></code> for how the <code class="docutils literal notranslate"><span class="pre">Exit</span></code> typeclass is set up.</p>
|
||
</section>
|
||
<section id="command-instances-are-re-used">
|
||
<h2>Command instances are re-used<a class="headerlink" href="#command-instances-are-re-used" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Note: This is an advanced topic that can be skipped when first learning about Commands.</em></p>
|
||
<p>A Command class sitting on an object is instantiated once and then re-used. So if you run a command
|
||
from object1 over and over you are in fact running the same command instance over and over (if you
|
||
run the same command but sitting on object2 however, it will be a different instance). This is
|
||
usually not something you’ll notice, since every time the Command-instance is used, all the relevant
|
||
properties on it will be overwritten. But armed with this knowledge you can implement some of the
|
||
more exotic command mechanism out there, like the command having a ‘memory’ of what you last entered
|
||
so that you can back-reference the previous arguments etc.</p>
|
||
<blockquote>
|
||
<div><p>Note: On a server reload, all Commands are rebuilt and memory is flushed.</p>
|
||
</div></blockquote>
|
||
<p>To show this in practice, consider this command:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdTestID</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"testid"</span>
|
||
|
||
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"xval"</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">xval</span> <span class="o">=</span> <span class="mi">0</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">xval</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Command memory ID: </span><span class="si">{</span><span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="si">}</span><span class="s2"> (xval=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">xval</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>Adding this to the default character cmdset gives a result like this in-game:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">testid</span>
|
||
<span class="n">Command</span> <span class="n">memory</span> <span class="n">ID</span><span class="p">:</span> <span class="mi">140313967648552</span> <span class="p">(</span><span class="n">xval</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="o">></span> <span class="n">testid</span>
|
||
<span class="n">Command</span> <span class="n">memory</span> <span class="n">ID</span><span class="p">:</span> <span class="mi">140313967648552</span> <span class="p">(</span><span class="n">xval</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="o">></span> <span class="n">testid</span>
|
||
<span class="n">Command</span> <span class="n">memory</span> <span class="n">ID</span><span class="p">:</span> <span class="mi">140313967648552</span> <span class="p">(</span><span class="n">xval</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note how the in-memory address of the <code class="docutils literal notranslate"><span class="pre">testid</span></code> command never changes, but <code class="docutils literal notranslate"><span class="pre">xval</span></code> keeps ticking up.</p>
|
||
</section>
|
||
<section id="dynamically-created-commands">
|
||
<h2>Dynamically created commands<a class="headerlink" href="#dynamically-created-commands" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>This is also an advanced topic.</em></p>
|
||
<p>Commands can also be created and added to a cmdset on the fly. Creating a class instance with a
|
||
keyword argument, will assign that keyword argument as a property on this paricular command:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
|
||
|
||
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">MyCommand</span><span class="p">(</span><span class="n">myvar</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">foo</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>This will start the <code class="docutils literal notranslate"><span class="pre">MyCommand</span></code> with <code class="docutils literal notranslate"><span class="pre">myvar</span></code> and <code class="docutils literal notranslate"><span class="pre">foo</span></code> set as properties (accessable as <code class="docutils literal notranslate"><span class="pre">self.myvar</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">self.foo</span></code>). How they are used is up to the Command. Remember however the discussion from the
|
||
previous section - since the Command instance is re-used, those properties will <em>remain</em> on the
|
||
command as long as this cmdset and the object it sits is in memory (i.e. until the next reload).
|
||
Unless <code class="docutils literal notranslate"><span class="pre">myvar</span></code> and <code class="docutils literal notranslate"><span class="pre">foo</span></code> are somehow reset when the command runs, they can be modified and that
|
||
change will be remembered for subsequent uses of the command.</p>
|
||
</section>
|
||
<section id="how-commands-actually-work">
|
||
<h2>How commands actually work<a class="headerlink" href="#how-commands-actually-work" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Note: This is an advanced topic mainly of interest to server developers.</em></p>
|
||
<p>Any time the user sends text to Evennia, the server tries to figure out if the text entered
|
||
corresponds to a known command. This is how the command handler sequence looks for a logged-in user:</p>
|
||
<ol class="simple">
|
||
<li><p>A user enters a string of text and presses enter.</p></li>
|
||
<li><p>The user’s Session determines the text is not some protocol-specific control sequence or OOB
|
||
command, but sends it on to the command handler.</p></li>
|
||
<li><p>Evennia’s <em>command handler</em> analyzes the Session and grabs eventual references to Account and
|
||
eventual puppeted Characters (these will be stored on the command object later). The <em>caller</em>
|
||
property is set appropriately.</p></li>
|
||
<li><p>If input is an empty string, resend command as <code class="docutils literal notranslate"><span class="pre">CMD_NOINPUT</span></code>. If no such command is found in
|
||
cmdset, ignore.</p></li>
|
||
<li><p>If command.key matches <code class="docutils literal notranslate"><span class="pre">settings.IDLE_COMMAND</span></code>, update timers but don’t do anything more.</p></li>
|
||
<li><p>The command handler gathers the CmdSets available to <em>caller</em> at this time:</p>
|
||
<ul class="simple">
|
||
<li><p>The caller’s own currently active CmdSet.</p></li>
|
||
<li><p>CmdSets defined on the current account, if caller is a puppeted object.</p></li>
|
||
<li><p>CmdSets defined on the Session itself.</p></li>
|
||
<li><p>The active CmdSets of eventual objects in the same location (if any). This includes commands
|
||
on <a class="reference internal" href="Objects.html#exits"><span class="std std-doc">Exits</span></a>.</p></li>
|
||
<li><p>Sets of dynamically created <em>System commands</em> representing available
|
||
<a class="reference internal" href="Channels.html"><span class="doc std std-doc">Communications</span></a></p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p>All CmdSets <em>of the same priority</em> are merged together in groups. Grouping avoids order-
|
||
dependent issues of merging multiple same-prio sets onto lower ones.</p></li>
|
||
<li><p>All the grouped CmdSets are <em>merged</em> in reverse priority into one combined CmdSet according to
|
||
each set’s merge rules.</p></li>
|
||
<li><p>Evennia’s <em>command parser</em> takes the merged cmdset and matches each of its commands (using its
|
||
key and aliases) against the beginning of the string entered by <em>caller</em>. This produces a set of
|
||
candidates.</p></li>
|
||
<li><p>The <em>cmd parser</em> next rates the matches by how many characters they have and how many percent
|
||
matches the respective known command. Only if candidates cannot be separated will it return multiple
|
||
matches.</p>
|
||
<ul class="simple">
|
||
<li><p>If multiple matches were returned, resend as <code class="docutils literal notranslate"><span class="pre">CMD_MULTIMATCH</span></code>. If no such command is found in
|
||
cmdset, return hard-coded list of matches.</p></li>
|
||
<li><p>If no match was found, resend as <code class="docutils literal notranslate"><span class="pre">CMD_NOMATCH</span></code>. If no such command is found in cmdset, give
|
||
hard-coded error message.</p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p>If a single command was found by the parser, the correct command object is plucked out of
|
||
storage. This usually doesn’t mean a re-initialization.</p></li>
|
||
<li><p>It is checked that the caller actually has access to the command by validating the <em>lockstring</em>
|
||
of the command. If not, it is not considered as a suitable match and <code class="docutils literal notranslate"><span class="pre">CMD_NOMATCH</span></code> is triggered.</p></li>
|
||
<li><p>If the new command is tagged as a channel-command, resend as <code class="docutils literal notranslate"><span class="pre">CMD_CHANNEL</span></code>. If no such command
|
||
is found in cmdset, use hard-coded implementation.</p></li>
|
||
<li><p>Assign several useful variables to the command instance (see previous sections).</p></li>
|
||
<li><p>Call <code class="docutils literal notranslate"><span class="pre">at_pre_command()</span></code> on the command instance.</p></li>
|
||
<li><p>Call <code class="docutils literal notranslate"><span class="pre">parse()</span></code> on the command instance. This is fed the remainder of the string, after the name
|
||
of the command. It’s intended to pre-parse the string into a form useful for the <code class="docutils literal notranslate"><span class="pre">func()</span></code> method.</p></li>
|
||
<li><p>Call <code class="docutils literal notranslate"><span class="pre">func()</span></code> on the command instance. This is the functional body of the command, actually
|
||
doing useful things.</p></li>
|
||
<li><p>Call <code class="docutils literal notranslate"><span class="pre">at_post_command()</span></code> on the command instance.</p></li>
|
||
</ol>
|
||
</section>
|
||
<section id="assorted-notes">
|
||
<h2>Assorted notes<a class="headerlink" href="#assorted-notes" title="Permalink to this headline">¶</a></h2>
|
||
<p>The return value of <code class="docutils literal notranslate"><span class="pre">Command.func()</span></code> is a Twisted
|
||
<a class="reference external" href="https://twistedmatrix.com/documents/current/core/howto/defer.html">deferred</a>.
|
||
Evennia does not use this return value at all by default. If you do, you must
|
||
thus do so asynchronously, using callbacks.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># in command class func()</span>
|
||
<span class="k">def</span> <span class="nf">callback</span><span class="p">(</span><span class="n">ret</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
|
||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Returned is </span><span class="si">{</span><span class="n">ret</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="n">deferred</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_command</span><span class="p">(</span><span class="s2">"longrunning"</span><span class="p">)</span>
|
||
<span class="n">deferred</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="n">callback</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This is probably not relevant to any but the most advanced/exotic designs (one might use it to
|
||
create a “nested” command structure for example).</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">save_for_next</span></code> class variable can be used to implement state-persistent commands. For example
|
||
it can make a command operate on “it”, where it is determined by what the previous command operated
|
||
on.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<p class="logo"><a href="../index.html">
|
||
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
|
||
</a></p>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="../search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script>$('#searchbox').show(0);</script>
|
||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Commands</a><ul>
|
||
<li><a class="reference internal" href="#defining-commands">Defining Commands</a><ul>
|
||
<li><a class="reference internal" href="#who-is-calling-the-command">Who is calling the command?</a></li>
|
||
<li><a class="reference internal" href="#properties-assigned-to-the-command-instance-at-run-time">Properties assigned to the command instance at run-time</a><ul>
|
||
<li><a class="reference internal" href="#other-useful-utility-methods">Other useful utility methods:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#defining-your-own-command-classes">Defining your own command classes</a></li>
|
||
<li><a class="reference internal" href="#command-prefixes">Command prefixes</a></li>
|
||
<li><a class="reference internal" href="#on-arg-regex">On arg_regex</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#exiting-a-command">Exiting a command</a></li>
|
||
<li><a class="reference internal" href="#pauses-in-commands">Pauses in commands</a></li>
|
||
<li><a class="reference internal" href="#asking-for-user-input">Asking for user input</a></li>
|
||
<li><a class="reference internal" href="#system-commands">System commands</a></li>
|
||
<li><a class="reference internal" href="#dynamic-commands">Dynamic Commands</a></li>
|
||
<li><a class="reference internal" href="#exits">Exits</a></li>
|
||
<li><a class="reference internal" href="#command-instances-are-re-used">Command instances are re-used</a></li>
|
||
<li><a class="reference internal" href="#dynamically-created-commands">Dynamically created commands</a></li>
|
||
<li><a class="reference internal" href="#how-commands-actually-work">How commands actually work</a></li>
|
||
<li><a class="reference internal" href="#assorted-notes">Assorted notes</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="Command-System.html"
|
||
title="previous chapter">Command System</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="Command-Sets.html"
|
||
title="next chapter">Command Sets</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/Components/Commands.md.txt"
|
||
rel="nofollow">Show Page Source</a></li>
|
||
</ul>
|
||
</div><h3>Links</h3>
|
||
<ul>
|
||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||
<li>
|
||
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
|
||
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
|
||
<a href="https://evennia.blogspot.com/">Blog</a>
|
||
</li>
|
||
</ul>
|
||
<h3>Versions</h3>
|
||
<ul>
|
||
<li><a href="Commands.html">1.0-dev (develop branch)</a></li>
|
||
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||
</ul>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="Command-Sets.html" title="Command Sets"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Command-System.html" title="Command System"
|
||
>previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Components-Overview.html" >Core Components</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Commands</a></li>
|
||
</ul>
|
||
<div class="develop">develop branch</div>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2020, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |