<p>Time to dip our toe into some coding! Evennia is written and extended in <aclass="reference external"href="http://python.org">Python</a>, which
is a mature and professional programming language that is very fast to work with.</p>
<p>That said, even though Python is widely considered easy to learn, we can only cover the most immediately
important aspects of Python in this series of starting tutorials. Hopefully we can get you started
but then you’ll need to continue learning from there. See our <aclass="reference internal"href="../../../Links.html"><spanclass="doc">link section</span></a> for finding
more reference material and dedicated Python tutorials.</p>
<blockquote>
<div><p>While this will be quite basic if you are an experienced developer, you may want to at least
stay around for the first few sections where we cover how to run Python from inside Evennia.</p>
</div></blockquote>
<p>First, if you were quelling yourself to play the tutorial world, make sure to get your
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> Command (or <codeclass="docutils literal notranslate"><spanclass="pre">!</span></code>, which is an alias) allows you as a superuser to execute raw Python from in-
game. This is useful for quick testing. 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. We are sending “Hello World” as an <em>argument</em> to this function. The quotes <codeclass="docutils literal notranslate"><spanclass="pre">"..."</span></code>
mean that you are inputting 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. A third variant is triple-quotes (<codeclass="docutils literal notranslate"><spanclass="pre">"""..."""</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">'''...'''</span></code>, which work across multiple
lines and are common for larger text-blocks. The way we use the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command right now only supports
<p>When making a text-game you will, unsurprisingly, be working a lot with text. Even if you have the occational
button or even graphical element, the normal process is for the user to input commands as
text and get text back. As we saw above, a piece of text is called a <em>string</em> in Python and is enclosed in
either single- or double-quotes.</p>
<p>Strings can be added together:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">py</span><spanclass="nb">print</span><spanclass="p">(</span><spanclass="s2">"This is a "</span><spanclass="o">+</span><spanclass="s2">"breaking change."</span><spanclass="p">)</span>
<p>While combining different strings is useful, even more powerful is the ability to modify the contents
of the string in-place. There are several ways to do this in Python and we’ll show two of them here. The first
is to use the <codeclass="docutils literal notranslate"><spanclass="pre">.format</span></code><em>method</em> of the string:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> py print("This is a {} idea!".format("good"))
This is a good idea!
</pre></div>
</div>
<divclass="sidebar">
<pclass="sidebar-title">Functions and Methods</p>
<dlclass="simple">
<dt>Function:</dt><dd><p>Something that performs and action when you <cite>call</cite> it with zero or more <cite>arguments</cite>. A function
is stand-alone in a python module, like <cite>print()</cite></p>
</dd>
<dt>Method:</dt><dd><p>A function that sits “on” an object, like <cite><string>.format()</cite>.</p>
</dd>
</dl>
</div>
<p>A method can be thought of as a resource “on” another object. The method knows on which object it
sits and can thus affect it in various ways. You access it with the period <codeclass="docutils literal notranslate"><spanclass="pre">.</span></code>. In this case, the
string has a resource <codeclass="docutils literal notranslate"><spanclass="pre">format(...)</span></code> that modifies it. More specifically, it replaced the <codeclass="docutils literal notranslate"><spanclass="pre">{}</span></code> marker
inside the string with the value passed to the format. You can do so many times:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> py print("This is a {} idea!".format("bad"))
This is a bad idea!
</pre></div>
</div>
<p>or</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> py print("This is the {} and {} {} idea!".format("first", "second", "great"))
This is the first and second great idea!
</pre></div>
</div>
<blockquote>
<div><p>Note the double-parenthesis at the end - the first closes the <codeclass="docutils literal notranslate"><spanclass="pre">format(...</span></code> method and the outermost
closes the <codeclass="docutils literal notranslate"><spanclass="pre">print(...</span></code>. Not closing them will give you a scary <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code>. We will talk a
little more about errors in the next section, for now just fix until it prints as expected.</p>
</div></blockquote>
<p>Here we passed three comma-separated strings as <em>arguments</em> to the string’s <codeclass="docutils literal notranslate"><spanclass="pre">format</span></code> method. These
replaced the <codeclass="docutils literal notranslate"><spanclass="pre">{}</span></code> markers in the same order as they were given.</p>
<p>The input does not have to be strings either:</p>
<p>To separate two Python instructions on the same line, you use the semi-colon, <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code>. Try this:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> py a = "awesome sauce" ; print("This is {}!".format(a))
This is awesome sauce!
</pre></div>
</div>
<divclass="admonition warning">
<pclass="admonition-title">Warning</p>
<p>MUD clients and semi-colon</p>
<p>Some MUD clients use the semi-colon <cite>;</cite> to split client-inputs
into separate sends. If so, the above will give an error. Most clients allow you to
run in ‘verbatim’ mode or to remap to use some other separator than <cite>;</cite>. If you still have
trouble, just use the Evennia web client for now. In real Python code you’ll pretty much never use
the semi-colon.</p>
</div>
<p>What happened here was that we <em>assigned</em> the string <codeclass="docutils literal notranslate"><spanclass="pre">"awesome</span><spanclass="pre">sauce"</span></code> to a <em>variable</em> we chose
to name <codeclass="docutils literal notranslate"><spanclass="pre">a</span></code>. In the next statement, Python remembered what <codeclass="docutils literal notranslate"><spanclass="pre">a</span></code> was and we passed that into <codeclass="docutils literal notranslate"><spanclass="pre">format()</span></code>
to get the output. If you replaced the value of <codeclass="docutils literal notranslate"><spanclass="pre">a</span></code> with something else in between, <em>that</em> would be printed
instead.</p>
<p>Here’s the stat-example again, moving the stats to variables (here we just set them, but in a real
game they may be changed over time, or modified by circumstance):</p>
<p>The point is that even if the values of the stats change, the print() statement would not change - it just keeps
pretty-printing whatever is given to it.</p>
<p>Using <codeclass="docutils literal notranslate"><spanclass="pre">.format()</span></code> is convenient (and there is a <aclass="reference external"href="https://www.w3schools.com/python/ref_string_format.asp">lot more</a>
you can do with it). But the <em>f-string</em> can be even more convenient. An
f-string looks like a normal string … except there is an <codeclass="docutils literal notranslate"><spanclass="pre">f</span></code> front of it, like this:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="n">f</span><spanclass="s2">"this is now an f-string."</span>
</pre></div>
</div>
<p>An f-string on its own is just like any other string. But let’s redo the example we did before, using an f-string:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> py a = "awesome sauce" ; print(f"This is {a}!")
This is awesome sauce!
</pre></div>
</div>
<p>We could just insert that <codeclass="docutils literal notranslate"><spanclass="pre">a</span></code> variable directly into the f-string using <codeclass="docutils literal notranslate"><spanclass="pre">{a}</span></code>. Fewer parentheses to
<p>We will be exploring more complex string concepts when we get to creating Commands and need to
parse and understand player input.</p>
<p>Python itself knows nothing about colored text, this is an Evennia thing. Evennia supports the
standard color schemes of traditional MUDs.</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">py</span><spanclass="nb">print</span><spanclass="p">(</span><spanclass="s2">"|rThis is red text!|n This is normal color."</span><spanclass="p">)</span>
</pre></div>
</div>
<p>Adding that <codeclass="docutils literal notranslate"><spanclass="pre">|r</span></code> at the start will turn our output bright red. <codeclass="docutils literal notranslate"><spanclass="pre">|R</span></code> will make it dark red. <codeclass="docutils literal notranslate"><spanclass="pre">|n</span></code>
gives the normal text color. You can also use RGB (Red-Green-Blue) values from 0-5 (Xterm256 colors):</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">py</span><spanclass="nb">print</span><spanclass="p">(</span><spanclass="s2">"|043This is a blue-green color.|[530|003 This is dark blue text on orange background."</span><spanclass="p">)</span>
</pre></div>
</div>
<blockquote>
<div><p>If you don’t see the expected color, your client or terminal may not support Xterm256 (or
color at all). Use the Evennia webclient.</p>
</div></blockquote>
<p>Use the commands <codeclass="docutils literal notranslate"><spanclass="pre">color</span><spanclass="pre">ansi</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">color</span><spanclass="pre">xterm</span></code> to see which colors are available. Experiment!</p>
<p>As we saw in the previous sections, we used <codeclass="docutils literal notranslate"><spanclass="pre">.format</span></code> to format strings and <codeclass="docutils literal notranslate"><spanclass="pre">me.msg</span></code> to access
the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method on <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code>. This use of the full-stop character is used to access all sorts of resources,
including that in other Python modules.</p>
<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
<p>If you make some error (we’ll cover how to handle errors below), fix the error in the module and
run the <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> command in-game 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
<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 of how Python importing works - it stores all imported modules and 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
<p>Now we see it again. The <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> wiped the server’s memory of what was imported, so it had to
import it anew. You’d have to do this every time you wanted the print to show though, which is
not very useful.</p>
<blockquote>
<div><p>We’ll get back to more advanced ways to import code in later tutorial sections - this is an
important topic. But for now, let’s press on and resolve this particular problem.</p>
<p>As we are moving to 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>.</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, for your own sanity’s sake,
set up your editor to always indent <em>4 spaces</em> (<strong>not</strong> a single tab-character) when you press the TAB key.</p></li>
</ul>
<p>So about that function. Line 1:</p>
<ulclass="simple">
<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. We recommend you do the same.</p></li>
<li><p>The colon (<codeclass="docutils literal notranslate"><spanclass="pre">:</span></code>) at the end of line 1 indicates that the header of the function is complete.</p></li>
</ul>
<p>Line 2:</p>
<ulclass="simple">
<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
start at least at this indentation level.</p></li>
</ul>
<p>Now let’s try this out. First <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> your game to have it pick up
<p>There is our “Hello World”! As mentioned earlier, use use semi-colon to put multiple
Python-statements on one line. Note also the previous warning about mud-clients using the <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code> to their
own ends.</p>
<p>So what happened there? First we imported <codeclass="docutils literal notranslate"><spanclass="pre">world.test</span></code> as usual. But this time we continued and
accessed the <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code> function <em>inside</em> the newly imported module.</p>
<p>By adding <codeclass="docutils literal notranslate"><spanclass="pre">()</span></code> to the <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code> function we <em>call</em> it, that is we run the body of the function and
print our text. We can now redo this as many times as we want without having to <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> in between:</p>
<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 since
we can se the output. 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 a shortcut to ‘us’, the one running the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command. It is not some special
Python thing, but something Evennia just makes available in the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command for convenience
(<codeclass="docutils literal notranslate"><spanclass="pre">self</span></code> is an alias).</p>
<p>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 also contains a lot of useful resources for doing
things with that object. We access those resources with ‘<codeclass="docutils literal notranslate"><spanclass="pre">.</span></code>’.</p>
<p>One such resource is <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code>, which 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>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 <codeclass="docutils literal notranslate"><spanclass="pre">print</span></code> is mainly used for
debugging and <codeclass="docutils literal notranslate"><spanclass="pre">.msg()</span></code> will be more useful for you in the future.</p>
<p>Save your file and <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> your server to tell Evennia to re-import new code,
<p>In regular use, tracebacks will often appear in the log rather than
in the game. Use <cite>evennia –log</cite> to view the log in the terminal. Make
sure to scroll back if you expect an error and don’t see it. Use
<cite>Ctrl-C</cite> (or <cite>Cmd-C</cite> on Mac) to exit the log-view.</p>
</div>
<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 go wrong. It’s important that you learn to parse tracebacks so you
know how to fix your code.</p>
<p>A traceback is to be read from the <em>bottom up</em>:</p>
<ulclass="simple">
<li><p>(line 3) An error of type <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code> is the problem …</p></li>
<li><p>(line 3) … more specifically it is due to the variable <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> not being defined.</p></li>
<li><p>(line 2) This happened on the line <codeclass="docutils literal notranslate"><spanclass="pre">me.msg("Hello</span><spanclass="pre">world!")</span></code> …</p></li>
<li><p>(line 1) … which is on line <codeclass="docutils literal notranslate"><spanclass="pre">2</span></code> of the file <codeclass="docutils literal notranslate"><spanclass="pre">./world/test.py</span></code>.</p></li>
</ul>
<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 the program 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 mentioned, it’s just something Evennia came up with for convenience in the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code>
command). As far as the module is concerned <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is an unfamiliar name, appearing out of nowhere.
Hence the <codeclass="docutils literal notranslate"><spanclass="pre">NameError</span></code>.</p>
<p>We know that <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> exists at the point when we run the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command, because we can do <codeclass="docutils literal notranslate"><spanclass="pre">py</span><spanclass="pre">me.msg("Hello</span><spanclass="pre">World!")</span></code>
with no problem. So let’s <em>pass</em> that me along to the function so it knows what it should be.
Go back to your <codeclass="docutils literal notranslate"><spanclass="pre">test.py</span></code> and change it to this:</p>
<p>We now added an <em>argument</em> to the function. We could have named it anything. Whatever <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> is,
we will call a method <codeclass="docutils literal notranslate"><spanclass="pre">.msg()</span></code> on it.</p>
<p>As usual, <codeclass="docutils literal notranslate"><spanclass="pre">reload</span></code> the server to make sure the new code is available.</p>
<p>Now it worked. We <em>passed</em><codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> to our function. It will appear inside the function renamed as <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> and
now the function works and prints as expected. Note how the <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code> function doesn’t care <em>what</em> you
pass into it as long as it has a <codeclass="docutils literal notranslate"><spanclass="pre">.msg()</span></code> method on it. So you could reuse this function over and over for other
suitable targets.</p>
<blockquote>
<div><p><strong>Extra Credit:</strong> As an exercise, try to pass something else into <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code>. Try for example
to pass the number <codeclass="docutils literal notranslate"><spanclass="pre">5</span></code> or the string <codeclass="docutils literal notranslate"><spanclass="pre">"foo"</span></code>. You’ll get errors telling you that they don’t have
the attribute <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code>. They don’t care about <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> itself not being a string or a number. If you are
familiar with other programming languages (especially C/Java) you may be tempted to start <em>validating</em>
<codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> to make sure it’s of the right type before you send it. This is usually not recommended in Python.
Python philosophy is to <aclass="reference external"href="https://docs.python.org/2/tutorial/errors.html">handle</a> the error if it happens
rather than to add a lot of code to prevent it from happening. See <aclass="reference external"href="https://en.wikipedia.org/wiki/Duck_typing">duck typing</a>
and the concept of <em>Leap before you Look</em>.</p>
<p>Let’s wrap up this first Python <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> crash-course by finding someone else to send to.</p>
<p>In Evennia’s <codeclass="docutils literal notranslate"><spanclass="pre">contrib/</span></code> folder (<codeclass="docutils literal notranslate"><spanclass="pre">evennia/contrib/tutorial_examples/mirror.py</span></code>) is a handy little
object called the <codeclass="docutils literal notranslate"><spanclass="pre">TutorialMirror</span></code>. The mirror will echo whatever is being sent to it to
the room it is in.</p>
<p>On the game command-line, let’s create a mirror:</p>
<p>What you are seeing is actually your own avatar in the game, the same thing that is available as <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> in the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code>
command.</p>
<p>What we are aiming for now is the equivalent of <codeclass="docutils literal notranslate"><spanclass="pre">mirror.msg("Mirror</span><spanclass="pre">Mirror</span><spanclass="pre">on</span><spanclass="pre">the</span><spanclass="pre">wall")</span></code>. But the first thing that
comes to mind will not work:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">py</span><spanclass="n">mirror</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Mirror, Mirror on the wall ..."</span><spanclass="p">)</span>
<p>This is not surprising: Python knows nothing about “mirrors” or locations or anything. The <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> we’ve been using
is, as mentioned, just a convenient thing the Evennia devs makes available to the <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command. They couldn’t possibly
predict that you wanted to talk to mirrors.</p>
<p>Instead we will need to <em>search</em> for that <codeclass="docutils literal notranslate"><spanclass="pre">mirror</span></code> object before we can send to it.
Make sure you are in the same location as the mirror and try:</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">me.search("name")</span></code> will, by default, search and <em>return</em> an object with the given name found in <em>the same location</em>
as the <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> object is. If it can’t find anything you’ll see an error.</p>
<divclass="sidebar">
<pclass="sidebar-title">Function returns</p>
<p>Whereas a function like <cite>print</cite> only prints its arguments, it’s very common
for functions/methods to <cite>return</cite> a result of some kind. Think of the function
as a machine - you put something in and out comes a result you can use. In the case
of <cite>me.search</cite>, it will perform a database search and spit out the object it finds.</p>
<p>Wanting to find things in the same location is very common, but as we continue we’ll
find that Evennia provides ample tools for tagging, searching and finding things from all over your game.</p>
<p>Now that we know how to find the ‘mirror’ object, we just need to use that instead of <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code>!</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">py</span><spanclass="n">mirror</span><spanclass="o">=</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">search</span><spanclass="p">(</span><spanclass="s2">"mirror"</span><spanclass="p">)</span><spanclass="p">;</span><spanclass="n">mirror</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Mirror, Mirror on the wall ..."</span><spanclass="p">)</span>
<spanclass="s2">"Mirror, Mirror on the wall ..."</span>
</pre></div>
</div>
<p>The mirror is useful for testing because its <codeclass="docutils literal notranslate"><spanclass="pre">.msg</span></code> method just echoes whatever is sent to it back to the room. More common
would be to talk to a player character, in which case the text you sent would have appeared in their game client.</p>
<p>So far we have use <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> in single-line mode, using <codeclass="docutils literal notranslate"><spanclass="pre">;</span></code> to separate multiple inputs. This is very convenient
when you want to do some quick testing. But you can also start a full multi-line Python interactive interpreter
<p>Note that we didn’t need to put <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> in front now. The system will also echo your input (that’s the bit after
the <codeclass="docutils literal notranslate"><spanclass="pre">>>></span></code>). For brevity in this tutorual we’ll turn the echo off. First exit <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> and then start again with the
<spanclass="o">></span><spanclass="nb">print</span><spanclass="p">(</span><spanclass="n">f</span><spanclass="s2">"This is a </span><spanclass="si">{a}</span><spanclass="s2">."</span><spanclass="p">}</span>
<li><p>Definining a function with <codeclass="docutils literal notranslate"><spanclass="pre">def</span></code> means we are starting a new code block. Python works so that you mark the content
of the block with indention. So the next line must be manually indented (4 spaces is a good standard) in order
for Python to know it’s part of the function body.</p></li>
<li><p>We expand the <codeclass="docutils literal notranslate"><spanclass="pre">hello_world</span></code> function with another argument <codeclass="docutils literal notranslate"><spanclass="pre">txt</span></code>. This allows us to send any text, not just
“Hello World” over and over.</p></li>
<li><p>To tell <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> that no more lines will be added to the function body, we end with an empty input. When
the normal prompt on how to exit returns, we know we are done.</p></li>
</ul>
<p>Now we have defined a new function. Let’s try it out:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>> hello_world(me, "Hello world to me!")
Hello world to me!
</pre></div>
</div>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> is still available to us, so we pass that as the <codeclass="docutils literal notranslate"><spanclass="pre">who</span></code> argument, along with a little longer
string. Let’s combine this with searching for the mirror.</p>
<spanclass="o">></span><spanclass="n">hello_world</span><spanclass="p">(</span><spanclass="n">mirror</span><spanclass="p">,</span><spanclass="s2">"Mirror, Mirror on the wall ..."</span><spanclass="p">)</span>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> command is very powerful for experimenting with Python in-game. It’s great for quick testing.
But you are still limited to working over telnet or the webclient, interfaces that doesn’t know anything
about Python per-se.</p>
<p>Outside the game, go to the terminal where you ran Evennia (or any terminal where the <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span></code> command
is available).</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">cd</span></code> to your game dir.</p></li>
<p>A Python shell opens. This works like <codeclass="docutils literal notranslate"><spanclass="pre">py</span></code> did inside the game, with the exception that you don’t have
<codeclass="docutils literal notranslate"><spanclass="pre">me</span></code> available out of the box. If you want <codeclass="docutils literal notranslate"><spanclass="pre">me</span></code>, you need to first find yourself:</p>
<p>Here we make use of one of evennia’s search functions, available by importing <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span></code> directly.
We will cover more advanced searching later, but suffice to say, you put your own character name instead of
“YourChar” above.</p>
<blockquote>
<div><p>The <codeclass="docutils literal notranslate"><spanclass="pre">[0]</span></code> at the end is because <codeclass="docutils literal notranslate"><spanclass="pre">.search_object</span></code> returns a list of objects and we want to
get at the first of them (counting starts from 0).</p>
</div></blockquote>
<p>Use <codeclass="docutils literal notranslate"><spanclass="pre">Ctrl-D</span></code> (<codeclass="docutils literal notranslate"><spanclass="pre">Cmd-D</span></code> on Mac) or <codeclass="docutils literal notranslate"><spanclass="pre">quit()</span></code> to exit the Python console.</p>
<p>The default Python shell is quite limited and ugly. It’s <em>highly</em> recommended to install <codeclass="docutils literal notranslate"><spanclass="pre">ipython</span></code> instead. This
is a much nicer, third-party Python interpreter with colors and many usability improvements.</p>
<p>If <codeclass="docutils literal notranslate"><spanclass="pre">ipython</span></code> is installed, <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">shell</span></code> will use it automatically.</p>
<p>That is, enter <codeclass="docutils literal notranslate"><spanclass="pre">evennia.</span></code> and then press the TAB key - you will be given a list of all the resources
available on the <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span></code> object. This is great for exploring what Evennia has to offer. For example,
use your arrow keys to scroll to <codeclass="docutils literal notranslate"><spanclass="pre">search_object()</span></code> to fill it in.</p>
<p>Adding a <codeclass="docutils literal notranslate"><spanclass="pre">?</span></code> and pressing return will give you the full documentation for <codeclass="docutils literal notranslate"><spanclass="pre">.search_object</span></code>. Use <codeclass="docutils literal notranslate"><spanclass="pre">??</span></code> if you
want to see the entire source code.</p>
<p>As for the normal python interpreter, use <codeclass="docutils literal notranslate"><spanclass="pre">Ctrl-D</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">Cmd-D</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">quit()</span></code> to exit ipython.</p>
<divclass="admonition important">
<pclass="admonition-title">Important</p>
<p>Persistent code</p>
<p>Common for both <cite>py</cite> and <cite>python</cite>/<cite>ipython</cite> is that the code you write is not persistent - it will
be gone after you shut down the interpreter (but ipython will remember your input history). For making long-lasting
Python code, we need to save it in a Python module, like we did for <cite>world/test.py</cite>.</p>
<p>This covers quite a lot of basic Python usage. We printed and formatted strings, defined our own
first function, fixed an error and even searched and talked to a mirror! Being able to access
python inside and outside of the game is an important skill for testing and debugging, but in
practice you will be writing most your code in Python modules.</p>
<p>To that end we also created a first new Python module in the <codeclass="docutils literal notranslate"><spanclass="pre">mygame/</span></code> game dir, then imported and used it.
Now let’s look at the rest of the stuff you’ve got going on inside that <codeclass="docutils literal notranslate"><spanclass="pre">mygame/</span></code> folder …</p>