<h1>Python basic introduction<aclass="headerlink"href="#python-basic-introduction"title="Permalink to this headline">¶</a></h1>
<p>This is the first part of our beginner’s guide to the basics of using Python with Evennia. It’s aimed at you with limited or no programming/Python experience. But also if you are an experienced programmer new to Evennia or Python you might still pick up a thing or two. It is by necessity brief and low on detail. There are countless Python guides and tutorials, books and videos out there for learning more in-depth - use them!</p>
<li><p>(continued in <aclass="reference internal"href="Python-basic-tutorial-part-two.html"><spanclass="doc">part 2</span></a>)</p></li>
</ul>
<p>This quickstart assumes you have <aclass="reference internal"href="Getting-Started.html"><spanclass="doc">gotten Evennia started</span></a>. You should make sure that you are able to see the output from the server in the console from which you started it. Log into the game either with a mud client on <codeclass="docutils literal notranslate"><spanclass="pre">localhost:4000</span></code> or by pointing a web browser to <codeclass="docutils literal notranslate"><spanclass="pre">localhost:4001/webclient</span></code>. Log in as your superuser (the user you created during install).</p>
<p>Below, lines starting with a single <codeclass="docutils literal notranslate"><spanclass="pre">></span></code> means command input.</p>
<divclass="section"id="evennia-hello-world">
<h2>Evennia Hello world<aclass="headerlink"href="#evennia-hello-world"title="Permalink to this headline">¶</a></h2>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> (or <codeclass="docutils literal notranslate"><spanclass="pre">!</span></code> which is an alias) command allows you as a superuser to run raw Python from in-game. From the game’s input line, enter the following:</p>
<p>To understand what is going on: some extra info: The <codeclass="docutils literal notranslate"><spanclass="pre">print(...)</span></code><em>function</em> is the basic, in-built way to output text in Python. The quotes <codeclass="docutils literal notranslate"><spanclass="pre">"..."</span></code> means you are inputing a <em>string</em> (i.e. text). You could also have used single-quotes <codeclass="docutils literal notranslate"><spanclass="pre">'...'</span></code>, Python accepts both.</p>
<p>The first return line (with <codeclass="docutils literal notranslate"><spanclass="pre">>>></span></code>) is just <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> echoing what you input (we won’t include that in the examples henceforth).</p>
<blockquote>
<div><p>Note: You may sometimes see people/docs refer to <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code> or other commands starting with <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code>. Evennia ignores <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code> by default, so <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code> is the exact same thing as <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code>.</p>
</div></blockquote>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> command is a standard Python structure. We can use that here in the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command, and it’s great for debugging and quick testing. But if you need to send a text to an actual player, <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> won’t do, because it doesn’t know <em>who</em> to send to. Try this:</p>
<p>This looks the same as the <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> result, but we are now actually messaging a specific <em>object</em>, <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code>. The <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is something uniquely available in the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command (we could also use <codeclass="docutils literal notranslate"><spanclass="pre">self</span></code>, it’s an alias). It represents “us”, the ones calling the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command. The <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is an example of an <em>Object instance</em>. Objects are fundamental in Python and Evennia. The <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> object not only represents the character we play in the game, it also contains a lot of useful resources for doing things with that Object. One such resource is <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code>. <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> works like <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> except it sends the text to the object it is attached to. So if we, for example, had an object <codeclass="docutils literal notranslate"><spanclass="pre">you</span></code>, doing <codeclass="docutils literal notranslate"><spanclass="pre">you.msg(...)</span></code> would send a message to the object <codeclass="docutils literal notranslate"><spanclass="pre">you</span></code>.</p>
<p>You access an Object’s resources by using the full-stop character <codeclass="docutils literal notranslate"><spanclass="pre">.</span></code>. So <codeclass="docutils literal notranslate"><spanclass="pre">self.msg</span></code> accesses the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> resource and then we call it like we did print, with our “Hello World!” greeting in parentheses.</p>
<blockquote>
<div><p>Important: something like <codeclass="docutils literal notranslate"><spanclass="pre">print(...)</span></code> we refer to as a <em>function</em>, while <codeclass="docutils literal notranslate"><spanclass="pre">msg(...)</span></code> which sits on an object is called a <em>method</em>.</p>
</div></blockquote>
<p>For now, <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">me.msg</span></code> behaves the same, just remember that you’re going to mostly be using the latter in the future. Try printing other things. Also try to include <codeclass="docutils literal notranslate"><spanclass="pre">|r</span></code> at the start of your string to make the output red in-game. Use <codeclass="docutils literal notranslate"><spanclass="pre">color</span></code> to learn more color tags.</p>
</div>
<divclass="section"id="importing-modules">
<h2>Importing modules<aclass="headerlink"href="#importing-modules"title="Permalink to this headline">¶</a></h2>
<p>Keep your game running, then open a text editor of your choice. If your game folder is called <codeclass="docutils literal notranslate"><spanclass="pre">mygame</span></code>, create a new text file <codeclass="docutils literal notranslate"><spanclass="pre">test.py</span></code> in the subfolder <codeclass="docutils literal notranslate"><spanclass="pre">mygame/world</span></code>. This is how the file structure should look:</p>
<p>Don’t forget to save the file. A file with the ending <codeclass="docutils literal notranslate"><spanclass="pre">.py</span></code> is referred to as a Python <em>module</em>. To use this in-game we have to <em>import</em> it. Try this:</p>
<p>If you make some error (we’ll cover how to handle errors below) you may need to run the <codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> command for your changes to take effect.</p>
<p>So importing <codeclass="docutils literal notranslate"><spanclass="pre">world.test</span></code> actually means importing <codeclass="docutils literal notranslate"><spanclass="pre">world/test.py</span></code>. Think of the period <codeclass="docutils literal notranslate"><spanclass="pre">.</span></code> as replacing <codeclass="docutils literal notranslate"><spanclass="pre">/</span></code> (or <codeclass="docutils literal notranslate"><spanclass="pre">\</span></code> for Windows) in your path. The <codeclass="docutils literal notranslate"><spanclass="pre">.py</span></code> ending of <codeclass="docutils literal notranslate"><spanclass="pre">test.py</span></code> is also never included in this “Python-path”, but <em>only</em> files with that ending can be imported this way. Where is <codeclass="docutils literal notranslate"><spanclass="pre">mygame</span></code> in that Python-path? The answer is that Evennia has already told Python that your <codeclass="docutils literal notranslate"><spanclass="pre">mygame</span></code> folder is a good place to look for imports. So we don’t include <codeclass="docutils literal notranslate"><spanclass="pre">mygame</span></code> in the path - Evennia handles this for us.</p>
<p>When you import the module, the top “level” of it will execute. In this case, it will immediately print “Hello World”.</p>
<blockquote>
<div><p>If you look in the folder you’ll also often find new files ending with <codeclass="docutils literal notranslate"><spanclass="pre">.pyc</span></code>. These are compiled Python binaries that Python auto-creates when running code. Just ignore them, you should never edit those anyway.</p>
<p>You will <em>not</em> see any output this second time or any subsequent times! This is not a bug. Rather it is because Python is being clever - it stores all imported modules and to be efficient it will avoid importing them more than once. So your <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> will only run the first time, when the module is first imported. To see it again you need to <codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> first, so Python forgets about the module and has to import it again.</p>
<p>We’ll get back to importing code in the second part of this tutorial. For now, let’s press on.</p>
</div>
<divclass="section"id="parsing-python-errors">
<h2>Parsing Python errors<aclass="headerlink"href="#parsing-python-errors"title="Permalink to this headline">¶</a></h2>
<p>Next, erase the single <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> statement you had in <codeclass="docutils literal notranslate"><spanclass="pre">test.py</span></code> and replace it with this instead:</p>
<p>As you recall we used this from <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> earlier - it echoed “Hello World!” in-game.
Save your file and <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> your server - this makes sure Evennia sees the new version of your code. Try to import it from <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> in the same way as earlier:</p>
<p>This is called a <em>traceback</em>. Python’s errors are very friendly and will most of the time tell you exactly what and where things are wrong. It’s important that you learn to parse tracebacks so you can fix your code. Let’s look at this one. A traceback is to be read from the <em>bottom up</em>. The last line is the error Python balked at, while the two lines above it details exactly where that error was encountered.</p>
<olclass="simple">
<li><p>An error of type <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code> is the problem …</p></li>
<li><p>… more specifically it is due to the variable <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> not being defined.</p></li>
<li><p>This happened on the line <codeclass="docutils literal notranslate"><spanclass="pre">me.msg("Hello</span><spanclass="pre">world!")</span></code> …</p></li>
<li><p>… which is on line <codeclass="docutils literal notranslate"><spanclass="pre">1</span></code> of the file <codeclass="docutils literal notranslate"><spanclass="pre">./world/test.py</span></code>.</p></li>
</ol>
<p>In our case the traceback is short. There may be many more lines above it, tracking just how different modules called each other until it got to the faulty line. That can sometimes be useful information, but reading from the bottom is always a good start.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code> we see here is due to a module being its own isolated thing. It knows nothing about the environment into which it is imported. It knew what <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> is because that is a special <aclass="reference external"href="https://docs.python.org/2.5/ref/keywords.html">reserved Python keyword</a>. But <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is <em>not</em> such a reserved word. As far as the module is concerned <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is just there out of nowhere. Hence the <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code>.</p>
</div>
<divclass="section"id="our-first-function">
<h2>Our first function<aclass="headerlink"href="#our-first-function"title="Permalink to this headline">¶</a></h2>
<p>Let’s see if we can resolve that <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code> from the previous section. We know that <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is defined at the time we use the <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code> command because if we do <codeclass="docutils literal notranslate"><spanclass="pre">py</span><spanclass="pre">me.msg("Hello</span><spanclass="pre">World!")</span></code> directly in-game it works fine. What if we could <em>send</em> that <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> to the <codeclass="docutils literal notranslate"><spanclass="pre">test.py</span></code> module so it knows what it is? One way to do this is with a <em>function</em>.</p>
<p>Change your <codeclass="docutils literal notranslate"><spanclass="pre">mygame/world/test.py</span></code> file to look like this:</p>
<p>Now that we are moving onto multi-line Python code, there are some important things to remember:</p>
<ulclass="simple">
<li><p>Capitalization matters in Python. It must be <codeclass="docutils literal notranslate"><spanclass="pre">def</span></code> and not <codeclass="docutils literal notranslate"><spanclass="pre">DEF</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> is not the same as <codeclass="docutils literal notranslate"><spanclass="pre">Who</span></code> etc.</p></li>
<li><p>Indentation matters in Python. The second line must be indented or it’s not valid code. You should also use a consistent indentation length. We <em>strongly</em> recommend that you set up your editor to always indent <em>4 spaces</em> (<strong>not</strong> a single tab-character) when you press the TAB key - it will make your life a lot easier.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">def</span></code> is short for “define” and defines a <em>function</em> (or a <em>method</em>, if sitting on an object). This is a <aclass="reference external"href="https://docs.python.org/2.5/ref/keywords.html">reserved Python keyword</a>; try not to use these words anywhere else.</p></li>
<li><p>A function name can not have spaces but otherwise we could have called it almost anything. We call it <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code>. Evennia follows <aclass="reference external"href="https://github.com/evennia/evennia/blob/master/CODING_STYLE.md#a-quick-list-of-code-style-points">Python’s standard naming style</a> with lowercase letters and underscores. Use this style for now.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> is what we call the <em>argument</em> to our function. Arguments are variables we pass to the function. We could have named it anything and we could also have multiple arguments separated by commas. What <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> is depends on what we pass to this function when we <em>call</em> it later (hint: we’ll pass <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> to it).</p></li>
<li><p>The colon (<codeclass="docutils literal notranslate"><spanclass="pre">:</span></code>) at the end of the first line indicates that the header of the function is complete.</p></li>
<li><p>The indentation marks the beginning of the actual operating code of the function (the function’s <em>body</em>). If we wanted more lines to belong to this function those lines would all have to have to start at this indentation level.</p></li>
<li><p>In the function body we take the <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> argument and treat it as we would have treated <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> earlier - we expect it to have a <codeclass="docutils literal notranslate"><spanclass="pre">.msg</span></code> method we can use to send “Hello World” to.</p></li>
</ul>
<p>First, <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> your game to make it aware of the updated Python module. Now we have defined our first function, let’s use it.</p>
<p>Nothing happened! That is because the function in our module won’t do anything just by importing it. It will only act when we <em>call</em> it. We will need to enter the module we just imported and do so.</p>
<p>There is our “Hello World”! The <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code> is the way to put multiple Python-statements on one line.</p>
<blockquote>
<div><p>Some MUD clients use <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code> for their own purposes to separate client-inputs. If so you’ll get a <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code> stating that <codeclass="docutils literal notranslate"><spanclass="pre">world</span></code> is not defined. Check so you understand why this is! Change the use of <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code> in your client or use the Evennia web client if this is a problem.</p>
</div></blockquote>
<p>In the second statement we access the module path we imported (<codeclass="docutils literal notranslate"><spanclass="pre">world.test</span></code>) and reach for the <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code> function within. We <em>call</em> the function with <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code>, which becomes the <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> variable we use inside the <codeclass="docutils literal notranslate"><spanclass="pre">hello_function</span></code>.</p>
<blockquote>
<div><p>As an exercise, try to pass something else into <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code>. Try for example to pass <em>who</em> as the number <codeclass="docutils literal notranslate"><spanclass="pre">5</span></code> or the simple string <codeclass="docutils literal notranslate"><spanclass="pre">"foo"</span></code>. You’ll get errors that they don’t have the attribute <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code>. As we’ve seen, <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code><em>does</em> make <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> available which is why it works (you’ll learn more about Objects like <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> in the next part of this tutorial). If you are familiar with other programming languages you may be tempted to start <em>validating</em><codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> to make sure it works as expected. This is usually not recommended in Python which suggests it’s better to <aclass="reference external"href="https://docs.python.org/2/tutorial/errors.html">handle</a> the error if it happens rather than to make a lot of code to prevent it from happening. See also <aclass="reference external"href="https://en.wikipedia.org/wiki/Duck_typing">duck typing</a>.</p>
</div></blockquote>
</div>
</div>
<divclass="section"id="looking-at-the-log">
<h1>Looking at the log<aclass="headerlink"href="#looking-at-the-log"title="Permalink to this headline">¶</a></h1>
<p>As you start to explore Evennia, it’s important that you know where to look when things go wrong. While using the friendly <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command you’ll see errors directly in-game. But if something goes wrong in your code while the game runs, you must know where to find the <em>log</em>.</p>
<p>Open a terminal (or go back to the terminal you started Evennia in), make sure your <codeclass="docutils literal notranslate"><spanclass="pre">virtualenv</span></code> is active and that you are standing in your game directory (the one created with <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">--init</span></code> during installation). Enter</p>
<p>This will show the log. New entries will show up in real time. Whenever you want to leave the log, enter <codeclass="docutils literal notranslate"><spanclass="pre">Ctrl-C</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">Cmd-C</span></code> depending on your system. As a game dev it is important to look at the log output when working in Evennia - many errors will only appear with full details here. You may sometimes have to scroll up in the history if you miss it.</p>
<p>This tutorial is continued in <aclass="reference internal"href="Python-basic-tutorial-part-two.html"><spanclass="doc">Part 2</span></a>, where we’ll start learning about objects and to explore the Evennia library.</p>