evennia/docs/0.x/First-Steps-Coding.html

397 lines
34 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>First Steps Coding &#8212; Evennia 0.9.5 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/language_data.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">First Steps Coding</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="first-steps-coding">
<h1>First Steps Coding<a class="headerlink" href="#first-steps-coding" title="Permalink to this headline"></a></h1>
<p>This section gives a brief step-by-step introduction on how to set up Evennia for the first time so
you can modify and overload the defaults easily. You should only need to do these steps once. It
also walks through you making your first few tweaks.</p>
<p>Before continuing, make sure you have Evennia installed and running by following the <a class="reference internal" href="Getting-Started.html"><span class="doc std std-doc">Getting
Started</span></a> instructions. You should have initialized a new game folder with the
<code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">--init</span> <span class="pre">foldername</span></code> command. We will in the following assume this folder is called
“mygame”.</p>
<p>It might be a good idea to eye through the brief <a class="reference internal" href="Coding-Introduction.html"><span class="doc std std-doc">Coding Introduction</span></a> too
(especially the recommendations in the section about the evennia “flat” API and about using <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="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 computers
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>
<section id="your-first-changes">
<h2>Your First Changes<a class="headerlink" href="#your-first-changes" title="Permalink to this headline"></a></h2>
<p>Below are some first things to try with your new custom modules. You can test these to get a feel
for the system. See also <a class="reference internal" href="Tutorials.html"><span class="doc std std-doc">Tutorials</span></a> for more step-by-step help and special cases.</p>
<section id="tweak-default-character">
<h3>Tweak Default Character<a class="headerlink" href="#tweak-default-character" title="Permalink to this headline"></a></h3>
<p>We will add some simple rpg attributes to our default Character. In the next section we will follow
up with a new command to view those attributes.</p>
<ol>
<li><p>Edit <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> and modify the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class. The
<code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> method also exists on the <code class="docutils literal notranslate"><span class="pre">DefaultCharacter</span></code> parent and will overload it. The
<code class="docutils literal notranslate"><span class="pre">get_abilities</span></code> method is unique to our version of <code class="docutils literal notranslate"><span class="pre">Character</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Character</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
<span class="c1"># [...]</span>
<span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called only at initial creation. This is a rather silly</span>
<span class="sd"> example since ability scores should vary from Character to</span>
<span class="sd"> Character and is usually set during some character</span>
<span class="sd"> generation step instead.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1">#set persistent attributes</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">strength</span> <span class="o">=</span> <span class="mi">5</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">agility</span> <span class="o">=</span> <span class="mi">4</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">magic</span> <span class="o">=</span> <span class="mi">2</span>
<span class="k">def</span> <span class="nf">get_abilities</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Simple access method to return ability</span>
<span class="sd"> scores as a tuple (str,agi,mag)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">strength</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">agility</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">magic</span>
</pre></div>
</div>
</li>
<li><p><a class="reference internal" href="Start-Stop-Reload.html"><span class="doc std std-doc">Reload</span></a> the server (you will still be connected to the game after doing
this). Note that if you examine <em>yourself</em> you will <em>not</em> see any new Attributes appear yet. Read
the next section to understand why.</p></li>
</ol>
<section id="updating-yourself">
<h4>Updating Yourself<a class="headerlink" href="#updating-yourself" title="Permalink to this headline"></a></h4>
<p>Its important to note that the new <a class="reference internal" href="Attributes.html"><span class="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 <code class="docutils literal notranslate"><span class="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 doesnt have
them yet. You can see this by calling the <code class="docutils literal notranslate"><span class="pre">get_abilities</span></code> hook on yourself at this point:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># (you have to be superuser to use @py)</span>
<span class="nd">@py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_abilities</span><span class="p">()</span>
<span class="o">&lt;&lt;&lt;</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>This is easily remedied.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@update</span> <span class="bp">self</span>
</pre></div>
</div>
<p>This will (only) re-run <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> on yourself. You should henceforth be able to get the
abilities successfully:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_abilities</span><span class="p">()</span>
<span class="o">&lt;&lt;&lt;</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
<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 <code class="docutils literal notranslate"><span class="pre">typeclasses.myclass.MyClass</span></code>, you can do the following (e.g.
from <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">shell</span></code>):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">typeclasses.myclass</span> <span class="kn">import</span> <span class="n">MyClass</span>
<span class="c1"># loop over all MyClass instances in the database</span>
<span class="c1"># and call .swap_typeclass on them</span>
<span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">MyClass</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
<span class="n">obj</span><span class="o">.</span><span class="n">swap_typeclass</span><span class="p">(</span><span class="n">MyClass</span><span class="p">,</span> <span class="n">run_start_hooks</span><span class="o">=</span><span class="s2">&quot;at_object_creation&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">swap_typeclass</span></code> to the same typeclass we already have will re-run the creation hooks (this is
what the <code class="docutils literal notranslate"><span class="pre">&#64;update</span></code> command does under the hood). From in-game you can do the same with <code class="docutils literal notranslate"><span class="pre">&#64;py</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@py</span> <span class="n">typeclasses</span><span class="o">.</span><span class="n">myclass</span> <span class="kn">import</span> <span class="nn">MyClass</span><span class="p">;[</span><span class="n">obj</span><span class="o">.</span><span class="n">swap_typeclass</span><span class="p">(</span><span class="n">MyClass</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span>
<span class="n">MyClass</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()]</span>
</pre></div>
</div>
<p>See the <a class="reference internal" href="Adding-Object-Typeclass-Tutorial.html"><span class="doc std std-doc">Object Typeclass tutorial</span></a> for more help and the
<a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a> and <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a> page for detailed documentation about
Typeclasses and Attributes.</p>
</section>
<section id="troubleshooting-updating-yourself">
<h4>Troubleshooting: Updating Yourself<a class="headerlink" href="#troubleshooting-updating-yourself" title="Permalink to this headline"></a></h4>
<p>One may experience errors for a number of reasons. Common beginner errors are spelling mistakes,
wrong indentations or code omissions leading to a <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code>. Lets say you leave out a colon
from the end of a class function like so: <code class="docutils literal notranslate"><span class="pre">def</span> <span class="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>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">&quot;C:\mygame</span><span class="se">\t</span><span class="s2">ypeclasses\characters.py&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">33</span>
<span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="o">^</span>
<span class="ne">SyntaxError</span><span class="p">:</span> <span class="n">invalid</span> <span class="n">syntax</span>
</pre></div>
</div>
<p>Evennia will still be restarting and following the tutorial, doing <code class="docutils literal notranslate"><span class="pre">&#64;py</span> <span class="pre">self.get_abilities()</span></code> will
return the right response <code class="docutils literal notranslate"><span class="pre">(None,</span> <span class="pre">None,</span> <span class="pre">None)</span></code>. But when attempting to <code class="docutils literal notranslate"><span class="pre">&#64;typeclass/force</span> <span class="pre">self</span></code> you
will get this response:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="s1">&#39;DefaultObject&#39;</span> <span class="nb">object</span> <span class="n">has</span> <span class="n">no</span> <span class="n">attribute</span> <span class="s1">&#39;get_abilities&#39;</span>
</pre></div>
</div>
<p>The full error will show in the terminal/console but this is confusing since you did add
<code class="docutils literal notranslate"><span class="pre">get_abilities</span></code> before. Note however what the error says - you (<code class="docutils literal notranslate"><span class="pre">self</span></code>) should be a <code class="docutils literal notranslate"><span class="pre">Character</span></code> but
the error talks about <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. What has happened is that due to your unhandled <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code>
earlier, Evennia could not load the <code class="docutils literal notranslate"><span class="pre">character.py</span></code> module at all (its not valid Python). Rather
than crashing, Evennia handles this by temporarily falling back to a safe default - <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code></p>
<ul class="simple">
<li><p>in order to keep your MUD running. Fix the original <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code> and reload the server. Evennia
will then be able to use your modified <code class="docutils literal notranslate"><span class="pre">Character</span></code> class again and things should work.</p></li>
</ul>
<blockquote>
<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
its a <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code> happening at <code class="docutils literal notranslate"><span class="pre">line</span> <span class="pre">33</span></code> of <code class="docutils literal notranslate"><span class="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 youll be able to resolve the vast majority of common errors easily.</p>
</div></blockquote>
</section>
</section>
<section id="add-a-new-default-command">
<h3>Add a New Default Command<a class="headerlink" href="#add-a-new-default-command" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">&#64;py</span></code> command used above is only available to privileged users. We want any player to be able to
see their stats. Lets add a new <a class="reference internal" href="Commands.html"><span class="doc std std-doc">command</span></a> to list the abilities we added in the previous
section.</p>
<ol>
<li><p>Open <code class="docutils literal notranslate"><span class="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
the bottom of this file:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">class</span> <span class="nc">CmdAbilities</span><span class="p">(</span><span class="n">BaseCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> List abilities</span>
<span class="sd"> Usage:</span>
<span class="sd"> abilities</span>
<span class="sd"> Displays a list of your current ability values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;abilities&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;abi&quot;</span><span class="p">]</span>
<span class="n">lock</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;General&quot;</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;implements the actual functionality&quot;&quot;&quot;</span>
<span class="nb">str</span><span class="p">,</span> <span class="n">agi</span><span class="p">,</span> <span class="n">mag</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">get_abilities</span><span class="p">()</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;STR: </span><span class="si">%s</span><span class="s2">, AGI: </span><span class="si">%s</span><span class="s2">, MAG: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">agi</span><span class="p">,</span> <span class="n">mag</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
</pre></div>
</div>
</li>
<li><p>Next you edit <code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code> and add a new import to it near the top:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">commands.command</span> <span class="kn">import</span> <span class="n">CmdAbilities</span>
</pre></div>
</div>
</li>
<li><p>In the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code> class, add the following near the bottom (it says where):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdAbilities</span><span class="p">())</span>
</pre></div>
</div>
</li>
<li><p><a class="reference internal" href="Start-Stop-Reload.html"><span class="doc std std-doc">Reload</span></a> the server (noone will be disconnected by doing this).</p></li>
</ol>
<p>You (and anyone else) should now be able to use <code class="docutils literal notranslate"><span class="pre">abilities</span></code> (or its alias <code class="docutils literal notranslate"><span class="pre">abi</span></code>) as part of your
normal commands in-game:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">abilities</span>
<span class="n">STR</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="n">AGI</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">MAG</span><span class="p">:</span> <span class="mi">2</span>
</pre></div>
</div>
<p>See the <a class="reference internal" href="Adding-Command-Tutorial.html"><span class="doc std std-doc">Adding a Command tutorial</span></a> for more examples and the
<a class="reference internal" href="Commands.html"><span class="doc std std-doc">Commands</span></a> section for detailed documentation about the Command system.</p>
</section>
<section id="make-a-new-type-of-object">
<h3>Make a New Type of Object<a class="headerlink" href="#make-a-new-type-of-object" title="Permalink to this headline"></a></h3>
<p>Lets test to make a new type of object. This example is an “wise stone” object that returns some
random comment when you look at it, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; look stone
A very wise stone
This is a very wise old stone.
It grumbles and says: &#39;The world is like a rock of chocolate.&#39;
</pre></div>
</div>
<ol>
<li><p>Create a new module in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code>. Name it <code class="docutils literal notranslate"><span class="pre">wiseobject.py</span></code> for this example.</p></li>
<li><p>In the module import the base <code class="docutils literal notranslate"><span class="pre">Object</span></code> (<code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>). This is empty by default,
meaning it is just a proxy for the default <code class="docutils literal notranslate"><span class="pre">evennia.DefaultObject</span></code>.</p></li>
<li><p>Make a new class in your module inheriting from <code class="docutils literal notranslate"><span class="pre">Object</span></code>. Overload hooks on it to add new
functionality. Here is an example of how the file could look:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">choice</span>
<span class="kn">from</span> <span class="nn">typeclasses.objects</span> <span class="kn">import</span> <span class="n">Object</span>
<span class="k">class</span> <span class="nc">WiseObject</span><span class="p">(</span><span class="n">Object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> An object speaking when someone looks at it. We</span>
<span class="sd"> assume it looks like a stone in this example.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Called when object is first created&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wise_texts</span> <span class="o">=</span> \
<span class="p">[</span><span class="s2">&quot;Stones have feelings too.&quot;</span><span class="p">,</span>
<span class="s2">&quot;To live like a stone is to not have lived at all.&quot;</span><span class="p">,</span>
<span class="s2">&quot;The world is like a rock of chocolate.&quot;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">return_appearance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">looker</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called by the look command. We want to return</span>
<span class="sd"> a wisdom when we get looked at.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># first get the base string from the</span>
<span class="c1"># parent&#39;s return_appearance.</span>
<span class="n">string</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="n">looker</span><span class="p">)</span>
<span class="n">wisewords</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">It grumbles and says: &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span>
<span class="n">wisewords</span> <span class="o">=</span> <span class="n">wisewords</span> <span class="o">%</span> <span class="n">choice</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wise_texts</span><span class="p">)</span>
<span class="k">return</span> <span class="n">string</span> <span class="o">+</span> <span class="n">wisewords</span>
</pre></div>
</div>
</li>
<li><p>Check your code for bugs. Tracebacks will appear on your command line or log. If you have a grave
Syntax Error in your code, the source file itself will fail to load which can cause issues with the
entire cmdset. If so, fix your bug and <a class="reference internal" href="Start-Stop-Reload.html"><span class="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 <code class="docutils literal notranslate"><span class="pre">&#64;create/drop</span> <span class="pre">stone:wiseobject.WiseObject</span></code> to create a talkative stone. If the <code class="docutils literal notranslate"><span class="pre">&#64;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 <code class="docutils literal notranslate"><span class="pre">&#64;create</span></code> command starts looking
for Typeclasses in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code>.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">look</span> <span class="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 <code class="docutils literal notranslate"><span class="pre">&#64;desc</span> <span class="pre">stone</span> <span class="pre">=</span> <span class="pre">This</span> <span class="pre">is</span> <span class="pre">a</span> <span class="pre">wise</span> <span class="pre">old</span> <span class="pre">stone.</span></code> to make
it look nicer. See the <a class="reference internal" href="Builder-Docs.html"><span class="doc std std-doc">Builder Docs</span></a> for more information.</p></li>
</ol>
<p>Note that <code class="docutils literal notranslate"><span class="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
<code class="docutils literal notranslate"><span class="pre">Character</span></code> example above you can use <code class="docutils literal notranslate"><span class="pre">&#64;typeclass/force</span></code> to tell the stone to re-run its
initialization.</p>
<p>The <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">&#64;reload</span></code> to have all changes applied
automatically to all existing objects.</p>
</section>
</section>
<section id="where-to-go-from-here">
<h2>Where to Go From Here?<a class="headerlink" href="#where-to-go-from-here" title="Permalink to this headline"></a></h2>
<p>There are more <a class="reference internal" href="Tutorials.html"><span class="doc std std-doc">Tutorials</span></a>, including one for building a <a class="reference internal" href="Tutorial-for-basic-MUSH-like-game.html"><span class="doc std std-doc">whole little MUSH-like
game</span></a> - that is instructive also if you have no interest in
MUSHes per se. A good idea is to also get onto the <a class="reference external" href="http://webchat.freenode.net/?channels=evennia">IRC
chat</a> and the <a class="reference external" href="https://groups.google.com/forum/#%21forum/evennia">mailing
list</a> to get in touch with the community and other
developers.</p>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="index.html">
<img class="logo" src="_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<p><h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">First Steps Coding</a><ul>
<li><a class="reference internal" href="#your-first-changes">Your First Changes</a><ul>
<li><a class="reference internal" href="#tweak-default-character">Tweak Default Character</a><ul>
<li><a class="reference internal" href="#updating-yourself">Updating Yourself</a></li>
<li><a class="reference internal" href="#troubleshooting-updating-yourself">Troubleshooting: Updating Yourself</a></li>
</ul>
</li>
<li><a class="reference internal" href="#add-a-new-default-command">Add a New Default Command</a></li>
<li><a class="reference internal" href="#make-a-new-type-of-object">Make a New Type of Object</a></li>
</ul>
</li>
<li><a class="reference internal" href="#where-to-go-from-here">Where to Go From Here?</a></li>
</ul>
</li>
</ul>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="_sources/First-Steps-Coding.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
<li><a href="First-Steps-Coding.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">First Steps Coding</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>