<h1><spanclass="section-number">9. </span>Parsing Command input<aclass="headerlink"href="#parsing-command-input"title="Permalink to this headline">¶</a></h1>
<p>In this lesson we learn some basics about parsing the input of Commands. We will
also learn how to add, modify and extend Evennia’s default commands.</p>
<sectionid="more-advanced-parsing">
<h2><spanclass="section-number">9.1. </span>More advanced parsing<aclass="headerlink"href="#more-advanced-parsing"title="Permalink to this headline">¶</a></h2>
<p>In the <aclass="reference internal"href="Beginner-Tutorial-Adding-Commands.html"><spanclass="doc std std-doc">last lesson</span></a> we made a <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> Command and struck a dragon with it. You should have the code from that still around.</p>
<p>Let’s expand our simple <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> command to accept a little more complex input:</p>
<p>If you don’t specify a weapon you’ll use your fists. It’s also nice to be able to skip “with” if
you are in a hurry. Time to modify <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/mycommands.py</span></code> again. Let us break out the parsing a little, in a new method <codeclass="docutils literal notranslate"><spanclass="pre">parse</span></code>:</p>
</span><spanclass="hll"><spanclass="n">target</span><spanclass="p">,</span><spanclass="o">*</span><spanclass="n">weapon</span><spanclass="o">=</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">args</span><spanclass="o">.</span><spanclass="n">split</span><spanclass="p">(</span><spanclass="s2">" with "</span><spanclass="p">,</span><spanclass="mi">1</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">"Who do you want to hit?"</span><spanclass="p">)</span>
<spanclass="k">return</span>
<spanclass="c1"># get the target for the hit</span>
<spanclass="hll"><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="sa">f</span><spanclass="s2">"You hit </span><spanclass="si">{</span><spanclass="n">target</span><spanclass="o">.</span><spanclass="n">key</span><spanclass="si">}</span><spanclass="s2"> with </span><spanclass="si">{</span><spanclass="n">weaponstr</span><spanclass="si">}</span><spanclass="s2">!"</span><spanclass="p">)</span>
</span><spanclass="n">target</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="sa">f</span><spanclass="s2">"You got hit by </span><spanclass="si">{</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">key</span><spanclass="si">}</span><spanclass="s2"> with </span><spanclass="si">{</span><spanclass="n">weaponstr</span><spanclass="si">}</span><spanclass="s2">!"</span><spanclass="p">)</span>
<spanclass="c1"># ...</span>
</pre></div></td></tr></table></div>
</div>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">parse</span></code> method is a special one Evennia knows to call <em>before</em><codeclass="docutils literal notranslate"><spanclass="pre">func</span></code>. At this time it has access to all the same on-command variables as <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> does. Using <codeclass="docutils literal notranslate"><spanclass="pre">parse</span></code> not only makes things a little easier to read, it also means you can easily let other Commands <em>inherit</em> your parsing - if you wanted some other Command to also understand input on the form <codeclass="docutils literal notranslate"><spanclass="pre"><arg></span><spanclass="pre">with</span><spanclass="pre"><arg></span></code> you’d inherit from this class and just implement the <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> needed for that command without implementing <codeclass="docutils literal notranslate"><spanclass="pre">parse</span></code> anew.</p>
<asideclass="sidebar">
<pclass="sidebar-title">Tuples and Lists</p>
<ulclass="simple">
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">list</span></code> is written as <codeclass="docutils literal notranslate"><spanclass="pre">[a,</span><spanclass="pre">b,</span><spanclass="pre">c,</span><spanclass="pre">d,</span><spanclass="pre">...]</span></code>. You can add and grow/shrink a list after it was first created.</p></li>
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">tuple</span></code> is written as <codeclass="docutils literal notranslate"><spanclass="pre">(a,</span><spanclass="pre">b,</span><spanclass="pre">c,</span><spanclass="pre">d,</span><spanclass="pre">...)</span></code>. A tuple cannot be modified once it is created.</p></li>
</ul>
</aside>
<ul>
<li><p><strong>Line 14</strong> - We do the stripping of <codeclass="docutils literal notranslate"><spanclass="pre">self.args</span></code> once and for all here. We also store the stripped version back
into <codeclass="docutils literal notranslate"><spanclass="pre">self.args</span></code>, overwriting it. So there is no way to get back the non-stripped version from here on, which is fine
for this command.</p></li>
<li><p><strong>Line 15</strong> - This makes use of the <codeclass="docutils literal notranslate"><spanclass="pre">.split</span></code> method of strings. <codeclass="docutils literal notranslate"><spanclass="pre">.split</span></code> will, well, split the string by some criterion.
<codeclass="docutils literal notranslate"><spanclass="pre">.split("</span><spanclass="pre">with</span><spanclass="pre">",</span><spanclass="pre">1)</span></code> means “split the string once, around the substring <codeclass="docutils literal notranslate"><spanclass="pre">"</span><spanclass="pre">with</span><spanclass="pre">"</span></code> if it exists”. The result
of this split is a <em>list</em>. Just how that list looks depends on the string we are trying to split:</p>
<olclass="simple">
<li><p>If we entered just <codeclass="docutils literal notranslate"><spanclass="pre">hit</span><spanclass="pre">smaug</span></code>, we’d be splitting just <codeclass="docutils literal notranslate"><spanclass="pre">"smaug"</span></code> which would give the result <codeclass="docutils literal notranslate"><spanclass="pre">["smaug"]</span></code>.</p></li>
<p>So we get a list of 1 or 2 elements. We assign it to two variables like this, <codeclass="docutils literal notranslate"><spanclass="pre">target,</span><spanclass="pre">*weapon</span><spanclass="pre">=</span></code>. That asterisk in <codeclass="docutils literal notranslate"><spanclass="pre">*weapon</span></code> is a nifty trick - it will automatically become a tuple of <em>0 or more</em> values. It sorts of “soaks” up everything left over.</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">target</span></code> becomes <codeclass="docutils literal notranslate"><spanclass="pre">"smaug"</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">weapon</span></code> becomes <codeclass="docutils literal notranslate"><spanclass="pre">("sword",)</span></code> (this is a tuple with one element, the comma <aclass="reference external"href="https://docs.python.org/3/tutorial/datastructures.html?highlight=tuple#tuples-and-sequences">is required</a> to indicate this).</p></li>
</ol>
</li>
<li><p><strong>Lines 16-17</strong> - In this <codeclass="docutils literal notranslate"><spanclass="pre">if</span></code> condition we check if <codeclass="docutils literal notranslate"><spanclass="pre">weapon</span></code> is falsy (that is, the empty list). This can happen
under two conditions (from the example above):</p>
<olclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">target</span></code> is simply <codeclass="docutils literal notranslate"><spanclass="pre">smaug</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">target</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">smaug</span><spanclass="pre">sword</span></code></p></li>
</ol>
<p>To separate these cases we split <codeclass="docutils literal notranslate"><spanclass="pre">target</span></code> once again, this time by empty space <codeclass="docutils literal notranslate"><spanclass="pre">"</span><spanclass="pre">"</span></code>. Again we store the result back with <codeclass="docutils literal notranslate"><spanclass="pre">target,</span><spanclass="pre">*weapon</span><spanclass="pre">=</span></code>. The result will be one of the following:</p>
<li><p><strong>Lines 18-22</strong> - We now store <codeclass="docutils literal notranslate"><spanclass="pre">target</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">weapon</span></code> into <codeclass="docutils literal notranslate"><spanclass="pre">self.target</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">self.weapon</span></code>. We must store on <codeclass="docutils literal notranslate"><spanclass="pre">self</span></code> in order for these local variables to become available in <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> later. Note that once we know that <codeclass="docutils literal notranslate"><spanclass="pre">weapon</span></code> exists, it must be a tuple (like <codeclass="docutils literal notranslate"><spanclass="pre">("sword",)</span></code>), so we use <codeclass="docutils literal notranslate"><spanclass="pre">weapon[0]</span></code> to get the first element of that tuple (tuples and lists in Python are indexed from 0). The instruction <codeclass="docutils literal notranslate"><spanclass="pre">weapon[0].strip()</span></code> can be read as “get the first string stored in the tuple <codeclass="docutils literal notranslate"><spanclass="pre">weapon</span></code> and remove all extra whitespace on it with <codeclass="docutils literal notranslate"><spanclass="pre">.strip()</span></code>”. If we forgot the <codeclass="docutils literal notranslate"><spanclass="pre">[0]</span></code> here, we’d get an error since a tuple (unlike the string inside the tuple) does not have the <codeclass="docutils literal notranslate"><spanclass="pre">.strip()</span></code> method.</p></li>
</ul>
<p>Now onto the <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> method. The main difference is we now have <codeclass="docutils literal notranslate"><spanclass="pre">self.target</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">self.weapon</span></code> available for convenient use.</p>
<asideclass="sidebar">
<p>Here we create the messages to send to each side of the fight explicitly. Later we’ll find out how to use Evennia’s <aclass="reference internal"href="../../../Components/FuncParser.html"><spanclass="doc std std-doc">inline functions</span></a> to send a single string that looks different depending on who sees it.</p>
<li><p><strong>Lines 29 and 35</strong> - We make use of the previously parsed search terms for the target and weapon to find the
respective resource.</p></li>
<li><p><strong>Lines 34-39</strong> - Since the weapon is optional, we need to supply a default (use our fists!) if it’s not set. We
use this to create a <codeclass="docutils literal notranslate"><spanclass="pre">weaponstr</span></code> that is different depending on if we have a weapon or not.</p></li>
<li><p><strong>Lines 41-42</strong> - We merge the <codeclass="docutils literal notranslate"><spanclass="pre">weaponstr</span></code> with our attack texts and send it to attacker and target respectively.</p></li>
<p>Oops, our <codeclass="docutils literal notranslate"><spanclass="pre">self.caller.search(self.weapon)</span></code> is telling us that it found no sword. This is reasonable (we don’t have a sword). Since we are not <codeclass="docutils literal notranslate"><spanclass="pre">return</span></code>ing when failing to find a weapon in the way we do if we find no <codeclass="docutils literal notranslate"><spanclass="pre">target</span></code>, we still continue fighting with our bare hands.</p>
<p>This won’t do. Let’s make ourselves a sword:</p>
<p>Since we didn’t specify <codeclass="docutils literal notranslate"><spanclass="pre">/drop</span></code>, the sword will end up in our inventory and can seen with the <codeclass="docutils literal notranslate"><spanclass="pre">i</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">inventory</span></code> command. The <codeclass="docutils literal notranslate"><spanclass="pre">.search</span></code> helper will still find it there. There is no need to reload to see this change (no code changed, only stuff in the database).</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>> hit smaug with sword
You hit smaug with sword!
</pre></div>
</div>
<p>Poor Smaug.</p>
</section>
<sectionid="adding-a-command-to-an-object">
<h2><spanclass="section-number">9.2. </span>Adding a Command to an object<aclass="headerlink"href="#adding-a-command-to-an-object"title="Permalink to this headline">¶</a></h2>
<asideclass="sidebar">
<pclass="sidebar-title">Command Sets on Characters </p>
<p>In case you wonder, the ‘Character CmdSet’ on <codeclass="docutils literal notranslate"><spanclass="pre">Characters</span></code> is configured to be available to <em>only</em> that Character. If not, you’d get command multi-matches for things like <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> whenever you were in the same room with another character using the same command set. See <aclass="reference internal"href="../../../Components/Command-Sets.html"><spanclass="doc std std-doc">Command Sets</span></a> docs for more info.</p>
</aside>
<p>As we learned in the lesson about <aclass="reference internal"href="Beginner-Tutorial-Adding-Commands.html"><spanclass="doc std std-doc">Adding commands</span></a>, Commands are are grouped in Command Sets. Such Command Sets are attached to an object with <codeclass="docutils literal notranslate"><spanclass="pre">obj.cmdset.add()</span></code> and will then be available for that object to use.</p>
<p>What we didn’t mention before is that by default those commands are <em>also available to those in the same location as that object</em>. If you did the <aclass="reference internal"href="Beginner-Tutorial-Building-Quickstart.html"><spanclass="doc std std-doc">Building quickstart lesson</span></a> you’ve seen an example of this with the “Red Button” object. The <aclass="reference internal"href="Beginner-Tutorial-Tutorial-World.html"><spanclass="doc std std-doc">Tutorial world</span></a> also has many examples of objects with commands on them.</p>
<p>To show how this could work, let’s put our ‘hit’ Command on our simple <codeclass="docutils literal notranslate"><spanclass="pre">sword</span></code> object from the previous section.</p>
<p>We find the sword (it’s still in our inventory so <codeclass="docutils literal notranslate"><spanclass="pre">self.search</span></code> should be able to find it), then
add <codeclass="docutils literal notranslate"><spanclass="pre">MyCmdSet</span></code> to it. This actually adds both <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">echo</span></code> to the sword, which is fine.</p>
<p>Let’s try to swing it!</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>> hit
More than one match for 'hit' (please narrow target):
hit-1 (sword #11)
hit-2
</pre></div>
</div>
<asideclass="sidebar">
<pclass="sidebar-title">Multi-matches</p>
<p>Some game engines will just pick the first hit when finding more than one. Evennia will always give you a choice. The reason for this is that Evennia cannot know if <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> are different or the same - maybe it behaves differently depending on the object it sits on? Besides, imagine if you had a red and a blue button both with the command <codeclass="docutils literal notranslate"><spanclass="pre">push</span></code> on it. Now you just write <codeclass="docutils literal notranslate"><spanclass="pre">push</span></code>. Wouldn’t you prefer to be asked <em>which</em> button you really wanted to push?</p>
</aside>
<p>Woah, that didn’t go as planned. Evennia actually found <em>two</em><codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> commands and didn’t know which one to use (<em>we</em> know they are the same, but Evennia can’t be sure of that). As we can see, <codeclass="docutils literal notranslate"><spanclass="pre">hit-1</span></code> is the one found on the sword. The other one is from adding <codeclass="docutils literal notranslate"><spanclass="pre">MyCmdSet</span></code> to ourself earlier. It’s easy enough to tell Evennia which one you meant:</p>
<p>In this case we don’t need both command-sets, we should drop the version of <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> sitting on our ourselves.</p>
<p>Go to <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/default_cmdsets.py</span></code> and find the line where you added
<codeclass="docutils literal notranslate"><spanclass="pre">MyCmdSet</span></code> in the previous lesson. Delete or comment it out:</p>
<p>Next <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> and you’ll only have one <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> command available:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>> hit
<p>Now try making a new location and then drop the sword in it.</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>> tunnel n = kitchen
> n
> drop sword
> s
> hit
Command 'hit' is not available. Maybe you meant ...
> n
> hit
Who do you want to hit?
</pre></div>
</div>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> command is only available if you hold <em>or</em> are in the same room as the sword.</p>
<sectionid="you-need-to-hold-the-sword">
<h3><spanclass="section-number">9.2.1. </span>You need to hold the sword!<aclass="headerlink"href="#you-need-to-hold-the-sword"title="Permalink to this headline">¶</a></h3>
<asideclass="sidebar">
<pclass="sidebar-title">Locks</p>
<p>Evennia Locks are defined as a mini-language defined in <codeclass="docutils literal notranslate"><spanclass="pre">lockstrings</span></code>. The lockstring is on a form <codeclass="docutils literal notranslate"><spanclass="pre"><situation>:<lockfuncs></span></code>, where <codeclass="docutils literal notranslate"><spanclass="pre">situation</span></code> determines when this lock applies and the <codeclass="docutils literal notranslate"><spanclass="pre">lockfuncs</span></code> (there can be more than one) are run to determine if the lock-check passes or not depending on circumstance.</p>
</aside>
<p>Let’s get a little ahead of ourselves and make it so you have to <em>hold</em> the sword for the <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> command to be available. This involves a <aclass="reference internal"href="../../../Components/Locks.html"><spanclass="doc std std-doc">Lock</span></a>. We’ll cover locks in more detail later, just know that they are useful for limiting the kind of things you can do with an object, including limiting just when you can call commands on it.</p>
<p>We added a new lock to the sword. The <em>lockstring</em><codeclass="docutils literal notranslate"><spanclass="pre">"call:holds()"</span></code> means that you can only <em>call</em> commands on this object if you are <em>holding</em> the object (that is, it’s in your inventory).</p>
<p>For locks to work, you cannot be <em>superuser</em>, since the superuser passes all locks. You need to <codeclass="docutils literal notranslate"><spanclass="pre">quell</span></code> yourself first:</p>
<asideclass="sidebar">
<pclass="sidebar-title">quell/unquell</p>
<p>Quelling allows you as a developer to take on the role of players with less priveleges. This is useful for testing and debugging, in particular since a superuser has a little <codeclass="docutils literal notranslate"><spanclass="pre">too</span></code> much power sometimes. Use <codeclass="docutils literal notranslate"><spanclass="pre">unquell</span></code> to get back to your normal self.</p>
<p>After we’ve waved the sword around (hit a dragon or two), we will get rid of ours sword so we have a clean slate with no more <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> commands floating around. We can do that in two ways:</p>
<h2><spanclass="section-number">9.3. </span>Adding the Command to a default Cmdset<aclass="headerlink"href="#adding-the-command-to-a-default-cmdset"title="Permalink to this headline">¶</a></h2>
<p>As we have seen we can use <codeclass="docutils literal notranslate"><spanclass="pre">obj.cmdset.add()</span></code> to add a new cmdset to objects, whether that object is ourself (<codeclass="docutils literal notranslate"><spanclass="pre">self</span></code>) or other objects like the <codeclass="docutils literal notranslate"><spanclass="pre">sword</span></code>. Doing this this way is a little cumbersome though. It would be better to add this to all characters.</p>
<p>The default cmdset are defined in <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/default_cmdsets.py</span></code>. Open that file now:</p>
<spanclass="c1"># any commands you add below will overload the default ones</span>
<spanclass="c1">#</span>
</pre></div>
</div>
<asideclass="sidebar">
<pclass="sidebar-title">super()</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">super()</span></code> function refers to the parent of the current class and is commonly used to call same-named methods on the parent.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">evennia.default_cmds</span></code> is a container that holds all of Evennia’s default commands and cmdsets. In this module we can see that this was imported and then a new child class was made for each cmdset. Each class looks familiar (except the <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code>, that’s mainly used to easily identify the cmdset in listings). In each <codeclass="docutils literal notranslate"><spanclass="pre">at_cmdset_creation</span></code> all we do is call <codeclass="docutils literal notranslate"><spanclass="pre">super().at_cmdset_creation</span></code> which means that we call `at_cmdset_creation() on the <em>parent</em> CmdSet.</p>
<p>This is what adds all the default commands to each CmdSet.</p>
<p>When the <codeclass="docutils literal notranslate"><spanclass="pre">DefaultCharacter</span></code> (or a child of it) is created, you’ll find that the equivalence of <codeclass="docutils literal notranslate"><spanclass="pre">self.cmdset.add("default_cmdsets.CharacterCmdSet,</span><spanclass="pre">persistent=True")</span></code> gets called. This means that all new Characters get this cmdset. After adding more commands to it, you just need to reload to have all characters see it.</p>
<ulclass="simple">
<li><p>Characters (that is ‘you’ in the gameworld) has the <codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code>.</p></li>
<li><p>Accounts (the thing that represents your out-of-character existence on the server) has the <codeclass="docutils literal notranslate"><spanclass="pre">AccountCmdSet</span></code></p></li>
<li><p>Sessions (representing one single client connection) has the <codeclass="docutils literal notranslate"><spanclass="pre">SessionCmdSet</span></code></p></li>
<li><p>Before you log in (at the connection screen) your Session have access to the <codeclass="docutils literal notranslate"><spanclass="pre">UnloggedinCmdSet</span></code>.</p></li>
</ul>
<p>For now, let’s add our own <codeclass="docutils literal notranslate"><spanclass="pre">hit</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">echo</span></code> commands to the <codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code>:</p>
<p>Your new commands are now available for all player characters in the game. There is another way to add a bunch of commands at once, and that is to add your own <em>CmdSet</em> to the other cmdset.</p>
<p>Which way you use depends on how much control you want, but if you already have a CmdSet,
this is practical. A Command can be a part of any number of different CmdSets.</p>
<sectionid="removing-commands">
<h3><spanclass="section-number">9.3.1. </span>Removing Commands<aclass="headerlink"href="#removing-commands"title="Permalink to this headline">¶</a></h3>
<p>To remove your custom commands again, you of course just delete the change you did to
<codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/default_cmdsets.py</span></code>. But what if you want to remove a default command?</p>
<p>We already know that we use <codeclass="docutils literal notranslate"><spanclass="pre">cmdset.remove()</span></code> to remove a cmdset. It turns out you can
do the same in <codeclass="docutils literal notranslate"><spanclass="pre">at_cmdset_creation</span></code>. For example, let’s remove the default <codeclass="docutils literal notranslate"><spanclass="pre">get</span></code> Command
from Evennia. If you investigate the <codeclass="docutils literal notranslate"><spanclass="pre">default_cmds.CharacterCmdSet</span></code> parent, you’ll find that its class is <codeclass="docutils literal notranslate"><spanclass="pre">default_cmds.CmdGet</span></code> (the ‘real’ location is <codeclass="docutils literal notranslate"><spanclass="pre">evennia.commands.default.general.CmdGet</span></code>).</p>
<h2><spanclass="section-number">9.4. </span>Replace a default command<aclass="headerlink"href="#replace-a-default-command"title="Permalink to this headline">¶</a></h2>
<p>At this point you already have all the pieces for how to do this! We just need to add a new
command with the same <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> in the <codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code> to replace the default one.</p>
<p>Let’s combine this with what we know about classes and how to <em>override</em> a parent class. Open <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/mycommands.py</span></code> and make a new <codeclass="docutils literal notranslate"><spanclass="pre">get</span></code> command:</p>
<li><p><strong>Line 2</strong>: We import <codeclass="docutils literal notranslate"><spanclass="pre">default_cmds</span></code> so we can get the parent class.
We made a new class and we make it <em>inherit</em><codeclass="docutils literal notranslate"><spanclass="pre">default_cmds.CmdGet</span></code>. We don’t
need to set <codeclass="docutils literal notranslate"><spanclass="pre">.key</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">.parse</span></code>, that’s already handled by the parent.
In <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> we call <codeclass="docutils literal notranslate"><spanclass="pre">super().func()</span></code> to let the parent do its normal thing,</p></li>
<li><p><strong>Line 7</strong>: By adding our own <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> we replace the one in the parent.</p></li>
<li><p><strong>Line 8</strong>: For this simple change we still want the command to work the
same as before, so we use <codeclass="docutils literal notranslate"><spanclass="pre">super()</span></code> to call <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> on the parent.</p></li>
<li><p><strong>Line 9</strong>: <codeclass="docutils literal notranslate"><spanclass="pre">.location</span></code> is the place an object is at. <codeclass="docutils literal notranslate"><spanclass="pre">.contents</span></code> contains, well, the
contents of an object. If you tried <codeclass="docutils literal notranslate"><spanclass="pre">py</span><spanclass="pre">self.contents</span></code> you’d get a list that equals
your inventory. For a room, the contents is everything in it.
So <codeclass="docutils literal notranslate"><spanclass="pre">self.caller.location.contents</span></code> gets the contents of our current location. This is
a <em>list</em>. In order send this to us with <codeclass="docutils literal notranslate"><spanclass="pre">.msg</span></code> we turn the list into a string. Python
has a special function <codeclass="docutils literal notranslate"><spanclass="pre">str()</span></code> to do this.</p></li>
</ul>
<p>We now just have to add this so it replaces the default <codeclass="docutils literal notranslate"><spanclass="pre">get</span></code> command. Open
<p>We don’t need to use <codeclass="docutils literal notranslate"><spanclass="pre">self.remove()</span></code> first; just adding a command with the same <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> (<codeclass="docutils literal notranslate"><spanclass="pre">get</span></code>) will replace the default <codeclass="docutils literal notranslate"><spanclass="pre">get</span></code> we had from before.</p>
<asideclass="sidebar">
<pclass="sidebar-title">Another way</p>
<p>Instead of adding <codeclass="docutils literal notranslate"><spanclass="pre">MyCmdGet</span></code> explicitly in default_cmdset.py, you could also add it to <codeclass="docutils literal notranslate"><spanclass="pre">mycommands.MyCmdSet</span></code> and let it be added automatically here for you.</p>
<p>We just made a new <codeclass="docutils literal notranslate"><spanclass="pre">get</span></code>-command that tells us everything we could pick up (well, we can’t pick up ourselves, so there’s some room for improvement there …).</p>
</section>
<sectionid="summary">
<h2><spanclass="section-number">9.5. </span>Summary<aclass="headerlink"href="#summary"title="Permalink to this headline">¶</a></h2>
<p>In this lesson we got into some more advanced string formatting - many of those tricks will help you a lot in the future! We also made a functional sword. Finally we got into how to add to, extend and replace a default command on ourselves. Knowing to add commands is a big part of making a game!</p>
<p>We have been beating on poor Smaug for too long. Next we’ll create more things to play around with.</p>