<p>Before continuing, make sure you have Evennia installed and running by following the <aclass="reference internal"href="Getting-Started.html"><spanclass="doc std std-doc">Getting
Started</span></a> instructions. You should have initialized a new game folder with the
<codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">--init</span><spanclass="pre">foldername</span></code> command. We will in the following assume this folder is called
<p>It might be a good idea to eye through the brief <aclass="reference internal"href="Coding-Introduction.html"><spanclass="doc std std-doc">Coding Introduction</span></a> too
(especially the recommendations in the section about the evennia “flat” API and about using <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">shell</span></code> will help you here and in the future).</p>
<p>To follow this tutorial you also need to know the basics of operating your computer’s
terminal/command line. You also need to have a text editor to edit and create source text files.
There are plenty of online tutorials on how to use the terminal and plenty of good free text
editors. We will assume these things are already familiar to you henceforth.</p>
for the system. See also <aclass="reference internal"href="Tutorials.html"><spanclass="doc std std-doc">Tutorials</span></a> for more step-by-step help and special cases.</p>
<li><p>Edit <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses/characters.py</span></code> and modify the <codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code> class. The
<codeclass="docutils literal notranslate"><spanclass="pre">at_object_creation</span></code> method also exists on the <codeclass="docutils literal notranslate"><spanclass="pre">DefaultCharacter</span></code> parent and will overload it. The
<codeclass="docutils literal notranslate"><spanclass="pre">get_abilities</span></code> method is unique to our version of <codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code>.</p>
<li><p><aclass="reference internal"href="Start-Stop-Reload.html"><spanclass="doc std std-doc">Reload</span></a> the server (you will still be connected to the game after doing
<p>It’s important to note that the new <aclass="reference internal"href="Attributes.html"><spanclass="doc std std-doc">Attributes</span></a> we added above will only be stored on
<em>newly</em> created characters. The reason for this is simple: The <codeclass="docutils literal notranslate"><spanclass="pre">at_object_creation</span></code> method, where we
added those Attributes, is per definition only called when the object is <em>first created</em>, then never
again. This is usually a good thing since those Attributes may change over time - calling that hook
would reset them back to start values. But it also means that your existing character doesn’t have
them yet. You can see this by calling the <codeclass="docutils literal notranslate"><spanclass="pre">get_abilities</span></code> hook on yourself at this point:</p>
<p>This will (only) re-run <codeclass="docutils literal notranslate"><spanclass="pre">at_object_creation</span></code> on yourself. You should henceforth be able to get the
<p>This is something to keep in mind if you start building your world before your code is stable -
startup-hooks will not (and should not) automatically run on <em>existing</em> objects - you have to update
your existing objects manually. Luckily this is a one-time thing and pretty simple to do. If the
typeclass you want to update is in <codeclass="docutils literal notranslate"><spanclass="pre">typeclasses.myclass.MyClass</span></code>, you can do the following (e.g.
from <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">shell</span></code>):</p>
<p>Using <codeclass="docutils literal notranslate"><spanclass="pre">swap_typeclass</span></code> to the same typeclass we already have will re-run the creation hooks (this is
what the <codeclass="docutils literal notranslate"><spanclass="pre">@update</span></code> command does under the hood). From in-game you can do the same with <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code>:</p>
<p>See the <aclass="reference internal"href="Adding-Object-Typeclass-Tutorial.html"><spanclass="doc std std-doc">Object Typeclass tutorial</span></a> for more help and the
<aclass="reference internal"href="Typeclasses.html"><spanclass="doc std std-doc">Typeclasses</span></a> and <aclass="reference internal"href="Attributes.html"><spanclass="doc std std-doc">Attributes</span></a> page for detailed documentation about
<p>One may experience errors for a number of reasons. Common beginner errors are spelling mistakes,
wrong indentations or code omissions leading to a <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code>. Let’s say you leave out a colon
from the end of a class function like so: <codeclass="docutils literal notranslate"><spanclass="pre">def</span><spanclass="pre">at_object_creation(self)</span></code>. The client will reload
without issue. <em>However</em>, if you look at the terminal/console (i.e. not in-game), you will see
Evennia complaining (this is called a <em>traceback</em>):</p>
<p>Evennia will still be restarting and following the tutorial, doing <codeclass="docutils literal notranslate"><spanclass="pre">@py</span><spanclass="pre">self.get_abilities()</span></code> will
return the right response <codeclass="docutils literal notranslate"><spanclass="pre">(None,</span><spanclass="pre">None,</span><spanclass="pre">None)</span></code>. But when attempting to <codeclass="docutils literal notranslate"><spanclass="pre">@typeclass/force</span><spanclass="pre">self</span></code> you
<p>The full error will show in the terminal/console but this is confusing since you did add
<codeclass="docutils literal notranslate"><spanclass="pre">get_abilities</span></code> before. Note however what the error says - you (<codeclass="docutils literal notranslate"><spanclass="pre">self</span></code>) should be a <codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code> but
the error talks about <codeclass="docutils literal notranslate"><spanclass="pre">DefaultObject</span></code>. What has happened is that due to your unhandled <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code>
earlier, Evennia could not load the <codeclass="docutils literal notranslate"><spanclass="pre">character.py</span></code> module at all (it’s not valid Python). Rather
than crashing, Evennia handles this by temporarily falling back to a safe default - <codeclass="docutils literal notranslate"><spanclass="pre">DefaultObject</span></code></p>
<ulclass="simple">
<li><p>in order to keep your MUD running. Fix the original <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code> and reload the server. Evennia
will then be able to use your modified <codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code> class again and things should work.</p></li>
<div><p>Note: Learning how to interpret an error traceback is a critical skill for anyone learning Python.
Full tracebacks will appear in the terminal/Console you started Evennia from. The traceback text can
sometimes be quite long, but you are usually just looking for the last few lines: The description of
the error and the filename + line number for where the error occurred. In the example above, we see
it’s a <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code> happening at <codeclass="docutils literal notranslate"><spanclass="pre">line</span><spanclass="pre">33</span></code> of <codeclass="docutils literal notranslate"><spanclass="pre">mygame\typeclasses\characters.py</span></code>. In this case it
even points out <em>where</em> on the line it encountered the error (the missing colon). Learn to read
tracebacks and you’ll be able to resolve the vast majority of common errors easily.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code> command used above is only available to privileged users. We want any player to be able to
see their stats. Let’s add a new <aclass="reference internal"href="Commands.html"><spanclass="doc std std-doc">command</span></a> to list the abilities we added in the previous
<li><p>Open <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/command.py</span></code>. You could in principle put your command anywhere but this
module has all the imports already set up along with some useful documentation. Make a new class at
<li><p>Next you edit <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/default_cmdsets.py</span></code> and add a new import to it near the top:</p>
<li><p>In the <codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code> class, add the following near the bottom (it says where):</p>
<li><p><aclass="reference internal"href="Start-Stop-Reload.html"><spanclass="doc std std-doc">Reload</span></a> the server (noone will be disconnected by doing this).</p></li>
<p>You (and anyone else) should now be able to use <codeclass="docutils literal notranslate"><spanclass="pre">abilities</span></code> (or its alias <codeclass="docutils literal notranslate"><spanclass="pre">abi</span></code>) as part of your
<p>See the <aclass="reference internal"href="Adding-Command-Tutorial.html"><spanclass="doc std std-doc">Adding a Command tutorial</span></a> for more examples and the
<aclass="reference internal"href="Commands.html"><spanclass="doc std std-doc">Commands</span></a> section for detailed documentation about the Command system.</p>
<li><p>Create a new module in <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses/</span></code>. Name it <codeclass="docutils literal notranslate"><spanclass="pre">wiseobject.py</span></code> for this example.</p></li>
<li><p>In the module import the base <codeclass="docutils literal notranslate"><spanclass="pre">Object</span></code> (<codeclass="docutils literal notranslate"><spanclass="pre">typeclasses.objects.Object</span></code>). This is empty by default,
meaning it is just a proxy for the default <codeclass="docutils literal notranslate"><spanclass="pre">evennia.DefaultObject</span></code>.</p></li>
<li><p>Make a new class in your module inheriting from <codeclass="docutils literal notranslate"><spanclass="pre">Object</span></code>. Overload hooks on it to add new
functionality. Here is an example of how the file could look:</p>
<spanclass="n">wisewords</span><spanclass="o">=</span><spanclass="s2">"</span><spanclass="se">\n\n</span><spanclass="s2">It grumbles and says: '</span><spanclass="si">%s</span><spanclass="s2">'"</span>
entire cmdset. If so, fix your bug and <aclass="reference internal"href="Start-Stop-Reload.html"><spanclass="doc std std-doc">reload the server from the command line</span></a>
(noone will be disconnected by doing this).</p></li>
<li><p>Use <codeclass="docutils literal notranslate"><spanclass="pre">@create/drop</span><spanclass="pre">stone:wiseobject.WiseObject</span></code> to create a talkative stone. If the <codeclass="docutils literal notranslate"><spanclass="pre">@create</span></code>
command spits out a warning or cannot find the typeclass (it will tell you which paths it searched),
re-check your code for bugs and that you gave the correct path. The <codeclass="docutils literal notranslate"><spanclass="pre">@create</span></code> command starts looking
for Typeclasses in <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses/</span></code>.</p></li>
<li><p>Use <codeclass="docutils literal notranslate"><spanclass="pre">look</span><spanclass="pre">stone</span></code> to test. You will see the default description (“You see nothing special”)
followed by a random message of stony wisdom. Use <codeclass="docutils literal notranslate"><spanclass="pre">@desc</span><spanclass="pre">stone</span><spanclass="pre">=</span><spanclass="pre">This</span><spanclass="pre">is</span><spanclass="pre">a</span><spanclass="pre">wise</span><spanclass="pre">old</span><spanclass="pre">stone.</span></code> to make
it look nicer. See the <aclass="reference internal"href="Builder-Docs.html"><spanclass="doc std std-doc">Builder Docs</span></a> for more information.</p></li>
<p>Note that <codeclass="docutils literal notranslate"><spanclass="pre">at_object_creation</span></code> is only called once, when the stone is first created. If you make
changes to this method later, already existing stones will not see those changes. As with the
<codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code> example above you can use <codeclass="docutils literal notranslate"><spanclass="pre">@typeclass/force</span></code> to tell the stone to re-run its
initialization.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">at_object_creation</span></code> is a special case though. Changing most other aspects of the typeclass does
<em>not</em> require manual updating like this - you just need to <codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> to have all changes applied
<p>There are more <aclass="reference internal"href="Tutorials.html"><spanclass="doc std std-doc">Tutorials</span></a>, including one for building a <aclass="reference internal"href="Tutorial-for-basic-MUSH-like-game.html"><spanclass="doc std std-doc">whole little MUSH-like