mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 05:46:31 +01:00
397 lines
34 KiB
HTML
397 lines
34 KiB
HTML
|
|
|
|||
|
|
<!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 — 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> »</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 computer’s
|
|||
|
|
terminal/command line. You also need to have a text editor to edit and create source text files.
|
|||
|
|
There are plenty of online tutorials on how to use the terminal and plenty of good free text
|
|||
|
|
editors. We will assume these things are already familiar to you henceforth.</p>
|
|||
|
|
<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">"""</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"> """</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">"""</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"> """</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>It’s 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 doesn’t 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"><<<</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"><<<</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">"at_object_creation"</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">@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">@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>. Let’s 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">"C:\mygame</span><span class="se">\t</span><span class="s2">ypeclasses\characters.py"</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">@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">@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">'DefaultObject'</span> <span class="nb">object</span> <span class="n">has</span> <span class="n">no</span> <span class="n">attribute</span> <span class="s1">'get_abilities'</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 (it’s 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
|
|||
|
|
it’s 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 you’ll 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">@py</span></code> command used above is only available to privileged users. We want any player to be able to
|
|||
|
|
see their stats. Let’s add a new <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">"""</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"> """</span>
|
|||
|
|
<span class="n">key</span> <span class="o">=</span> <span class="s2">"abilities"</span>
|
|||
|
|
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"abi"</span><span class="p">]</span>
|
|||
|
|
<span class="n">lock</span> <span class="o">=</span> <span class="s2">"cmd:all()"</span>
|
|||
|
|
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">"General"</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">"""implements the actual functionality"""</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">"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">"</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>Let’s 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>> look stone
|
|||
|
|
|
|||
|
|
A very wise stone
|
|||
|
|
|
|||
|
|
This is a very wise old stone.
|
|||
|
|
It grumbles and says: 'The world is like a rock of chocolate.'
|
|||
|
|
</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">"""</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"> """</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">"""Called when object is first created"""</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">"Stones have feelings too."</span><span class="p">,</span>
|
|||
|
|
<span class="s2">"To live like a stone is to not have lived at all."</span><span class="p">,</span>
|
|||
|
|
<span class="s2">"The world is like a rock of chocolate."</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">"""</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"> """</span>
|
|||
|
|
<span class="c1"># first get the base string from the</span>
|
|||
|
|
<span class="c1"># parent'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">"</span><span class="se">\n\n</span><span class="s2">It grumbles and says: '</span><span class="si">%s</span><span class="s2">'"</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">@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">@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">@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">@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">@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">@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> »</li>
|
|||
|
|
<li class="nav-item nav-item-this"><a href="">First Steps Coding</a></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
<div class="footer" role="contentinfo">
|
|||
|
|
© Copyright 2020, The Evennia developer community.
|
|||
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
|||
|
|
</div>
|
|||
|
|
</body>
|
|||
|
|
</html>
|