mirror of
https://github.com/evennia/evennia.git
synced 2026-03-29 20:17:16 +02:00
Updated HTML docs
This commit is contained in:
parent
66d0ad0bc9
commit
7900aad365
2073 changed files with 32986 additions and 41197 deletions
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="our-own-commands">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="our-own-commands">
|
||||
<h1>Our own commands<a class="headerlink" href="#our-own-commands" title="Permalink to this headline">¶</a></h1>
|
||||
<p>In this lesson we’ll learn how to create our own Evennia <em>Commands</em>. If you are new to Python you’ll
|
||||
also learn some more basics about how to manipulate strings and get information out of Evennia.</p>
|
||||
|
|
@ -56,9 +58,11 @@ An example is <code class="docutils literal notranslate"><span class="pre">look<
|
|||
what is in it.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Commands are not typeclassed</p>
|
||||
<p>If you just came from the previous lesson, you might want to know that Commands and
|
||||
CommandSets are not <cite>typeclassed</cite>. That is, instances of them are not saved to the
|
||||
database. They are “just” normal Python classes.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>If you just came from the previous lesson, you might want to know that Commands and
|
||||
CommandSets are not `typeclassed`. That is, instances of them are not saved to the
|
||||
database. They are "just" normal Python classes.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>In Evennia, a Command is a Python <em>class</em>. If you are unsure about what a class is, review the
|
||||
previous lessons! A Command inherits from <code class="docutils literal notranslate"><span class="pre">evennia.Command</span></code> or from one of the alternative command-
|
||||
|
|
@ -77,21 +81,7 @@ commands in that cmdset available to the object. So, to summarize:</p>
|
|||
<section id="creating-a-custom-command">
|
||||
<h2>Creating a custom command<a class="headerlink" href="#creating-a-custom-command" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Open <code class="docutils literal notranslate"><span class="pre">mygame/commands/command.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<span class="sd">(module docstring)</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
|
|
@ -107,7 +97,7 @@ commands in that cmdset available to the object. So, to summarize:</p>
|
|||
<span class="c1"># (lots of commented-out stuff)</span>
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Ignoring the docstrings (which you can read if you want), this is the only really active code in the module.</p>
|
||||
<p>We can see that we import <code class="docutils literal notranslate"><span class="pre">Command</span></code> from <code class="docutils literal notranslate"><span class="pre">evennia</span></code> and use the <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">...</span> <span class="pre">as</span> <span class="pre">...</span></code> form to rename it
|
||||
to <code class="docutils literal notranslate"><span class="pre">BaseCommand</span></code>. This is so we can let our child class also be named <code class="docutils literal notranslate"><span class="pre">Command</span></code> for reference. The class
|
||||
|
|
@ -119,32 +109,18 @@ that a little later.</p>
|
|||
</div></blockquote>
|
||||
<p>We could modify this module directly, but to train imports we’ll work in a separate module. Open a new file
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code> and add the following code:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<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">Command</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"echo"</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This is the simplest form of command you can imagine. It just gives itself a name, “echo”. This is
|
||||
what you will use to call this command later.</p>
|
||||
<p>Next we need to put this in a CmdSet. It will be a one-command CmdSet for now! Change your file as such:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<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">Command</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">CmdSet</span>
|
||||
|
||||
|
|
@ -156,19 +132,20 @@ what you will use to call this command later.</p>
|
|||
|
||||
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdEcho</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Our <code class="docutils literal notranslate"><span class="pre">EchoCmdSet</span></code> class must have an <code class="docutils literal notranslate"><span class="pre">at_cmdset_creation</span></code> method, named exactly
|
||||
like this - this is what Evennia will be looking for when setting up the cmdset later, so
|
||||
if you didn’t set it up, it will use the parent’s version, which is empty. Inside we add the
|
||||
command class to the cmdset by <code class="docutils literal notranslate"><span class="pre">self.add()</span></code>. If you wanted to add more commands to this CmdSet you
|
||||
could just add more lines of <code class="docutils literal notranslate"><span class="pre">self.add</span></code> after this.</p>
|
||||
<p>Finally, let’s add this command to ourselves so we can try it out. In-game you can experiment with <code class="docutils literal notranslate"><span class="pre">py</span></code> again:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"commands.mycommands.MyCmdSet"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.cmdset.add("commands.mycommands.MyCmdSet")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now try</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> echo
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> echo
|
||||
Command echo has no defined `func()` - showing on-command variables:
|
||||
...
|
||||
...
|
||||
|
|
@ -177,7 +154,7 @@ Command echo has no defined `func()` - showing on-command variables:
|
|||
<p>You should be getting a long list of outputs. The reason for this is that your <code class="docutils literal notranslate"><span class="pre">echo</span></code> function is not really
|
||||
“doing” anything yet and the default function is then to show all useful resources available to you when you
|
||||
use your Command. Let’s look at some of those listed:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>Command echo has no defined `func()` - showing on-command variables:
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Command echo has no defined `func()` - showing on-command variables:
|
||||
obj (<class 'typeclasses.characters.Character'>): YourName
|
||||
lockhandler (<class 'evennia.locks.lockhandler.LockHandler'>): cmd:all()
|
||||
caller (<class 'typeclasses.characters.Character'>): YourName
|
||||
|
|
@ -219,22 +196,7 @@ that this would be <code class="docutils literal notranslate"><span class="pre">
|
|||
</ul>
|
||||
<p>The reason our command doesn’t do anything yet is because it’s missing a <code class="docutils literal notranslate"><span class="pre">func</span></code> method. This is what Evennia
|
||||
looks for to figure out what a Command actually does. Modify your <code class="docutils literal notranslate"><span class="pre">CmdEcho</span></code> class:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -251,50 +213,35 @@ looks for to figure out what a Command actually does. Modify your <code class="d
|
|||
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also
|
||||
automatically become the in-game help entry! Next we add the <code class="docutils literal notranslate"><span class="pre">func</span></code> method. It has one active line where it
|
||||
makes use of some of those variables we found the Command offers to us. If you did the
|
||||
<a class="reference internal" href="Python-basic-introduction.html"><span class="doc">basic Python tutorial</span></a>, you will recognize <code class="docutils literal notranslate"><span class="pre">.msg</span></code> - this will send a message
|
||||
<a class="reference internal" href="Python-basic-introduction.html"><span class="doc std std-doc">basic Python tutorial</span></a>, you will recognize <code class="docutils literal notranslate"><span class="pre">.msg</span></code> - this will send a message
|
||||
to the object it is attached to us - in this case <code class="docutils literal notranslate"><span class="pre">self.caller</span></code>, that is, us. We grab <code class="docutils literal notranslate"><span class="pre">self.args</span></code> and includes
|
||||
that in the message.</p>
|
||||
<p>Since we haven’t changed <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code>, that will work as before. Reload and re-add this command to ourselves to
|
||||
try out the new version:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"commands.mycommands.MyCmdSet"</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">echo</span>
|
||||
<span class="n">Echo</span><span class="p">:</span> <span class="s1">''</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.cmdset.add("commands.mycommands.MyCmdSet")
|
||||
> echo
|
||||
Echo: ''
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Try to pass an argument:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> echo Woo Tang!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> echo Woo Tang!
|
||||
Echo: ' Woo Tang!'
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note that there is an extra space before <code class="docutils literal notranslate"><span class="pre">Woo!</span></code>. That is because self.args contains the <em>everything</em> after
|
||||
the command name, including spaces. Evennia will happily understand if you skip that space too:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> echoWoo Tang!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> echoWoo Tang!
|
||||
Echo: 'Woo Tang!'
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>There are ways to force Evennia to <em>require</em> an initial space, but right now we want to just ignore it since
|
||||
it looks a bit weird for our echo example. Tweak the code:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -311,18 +258,18 @@ it looks a bit weird for our echo example. Tweak the code:</p>
|
|||
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The only difference is that we called <code class="docutils literal notranslate"><span class="pre">.strip()</span></code> on <code class="docutils literal notranslate"><span class="pre">self.args</span></code>. This is a helper method available on all
|
||||
strings - it strips out all whitespace before and after the string. Now the Command-argument will no longer
|
||||
have any space in front of it.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.cmdset.add("commands.mycommands.MyCmdSet")
|
||||
> echo Woo Tang!
|
||||
Echo: 'Woo Tang!'
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Don’t forget to look at the help for the echo command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">help</span> <span class="n">echo</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> help echo
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will get the docstring you put in your Command-class.</p>
|
||||
|
|
@ -330,12 +277,12 @@ Echo: 'Woo Tang!'
|
|||
<h3>Making our cmdset persistent<a class="headerlink" href="#making-our-cmdset-persistent" title="Permalink to this headline">¶</a></h3>
|
||||
<p>It’s getting a little annoying to have to re-add our cmdset every time we reload, right? It’s simple
|
||||
enough to make <code class="docutils literal notranslate"><span class="pre">echo</span></code> a <em>persistent</em> change though:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"commands.mycommands.MyCmdSet"</span><span class="p">,</span> <span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.cmdset.add("commands.mycommands.MyCmdSet", persistent=True)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now you can <code class="docutils literal notranslate"><span class="pre">reload</span></code> as much as you want and your code changes will be available directly without
|
||||
needing to re-add the MyCmdSet again. To remove the cmdset again, do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s2">"commands.mycommands.MyCmdSet"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.cmdset.remove("commands.mycommands.MyCmdSet")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>But for now, keep it around, we’ll expand it with some more examples.</p>
|
||||
|
|
@ -344,39 +291,17 @@ needing to re-add the MyCmdSet again. To remove the cmdset again, do</p>
|
|||
<h3>Figuring out who to hit<a class="headerlink" href="#figuring-out-who-to-hit" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Let’s try something a little more exciting than just echo. Let’s make a <code class="docutils literal notranslate"><span class="pre">hit</span></code> command, for punching
|
||||
someone in the face! This is how we want it to work:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> hit <target>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hit <target>
|
||||
You hit <target> with full force!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Not only that, we want the <target> to see</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>You got hit by <hitter> with full force!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You got hit by <hitter> with full force!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here, <code class="docutils literal notranslate"><span class="pre"><hitter></span></code> would be the one using the <code class="docutils literal notranslate"><span class="pre">hit</span></code> command and <code class="docutils literal notranslate"><span class="pre"><target></span></code> is the one doing the punching.</p>
|
||||
<p>Still in <code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code>, add a new class, between <code class="docutils literal notranslate"><span class="pre">CmdEcho</span></code> and <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdHit</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -399,8 +324,9 @@ You hit <target> with full force!
|
|||
<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="sa">f</span><span class="s2">"You hit </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> with full force!"</span><span class="p">)</span>
|
||||
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You got hit by </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> with full force!"</span><span class="p">)</span>
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>A lot of things to dissect here:</p>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Line 4</strong>: The normal <code class="docutils literal notranslate"><span class="pre">class</span></code> header. We inherit from <code class="docutils literal notranslate"><span class="pre">Command</span></code> which we imported at the top of this file.</p></li>
|
||||
|
|
@ -413,20 +339,20 @@ have the whitespace and is not the same as <code class="docutils literal notrans
|
|||
</ul>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">if-statements</p>
|
||||
<p>The full form of the if statement is</p>
|
||||
<blockquote>
|
||||
<div><dl class="simple">
|
||||
<dt>if condition:</dt><dd><p>…</p>
|
||||
</dd>
|
||||
<dt>elif othercondition:</dt><dd><p>…</p>
|
||||
</dd>
|
||||
<dt>else:</dt><dd><p>…</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div></blockquote>
|
||||
<p>There can be any number of <cite>elifs</cite> to mark when different branches of the code should run. If
|
||||
the <cite>else</cite> condition is given, it will run if none of the other conditions was truthy. In Python
|
||||
the <cite>if..elif..else</cite> structure also serves the same function as <cite>case</cite> in some other languages.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The full form of the if statement is
|
||||
|
||||
if condition:
|
||||
...
|
||||
elif othercondition:
|
||||
...
|
||||
else:
|
||||
...
|
||||
|
||||
There can be any number of `elifs` to mark when different branches of the code should run. If
|
||||
the `else` condition is given, it will run if none of the other conditions was truthy. In Python
|
||||
the `if..elif..else` structure also serves the same function as `case` in some other languages.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<ul>
|
||||
<li><p><strong>Line 16</strong> has our first <em>conditional</em>, an <code class="docutils literal notranslate"><span class="pre">if</span></code> statement. This is written on the form <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre"><condition>:</span></code> and only
|
||||
|
|
@ -451,32 +377,29 @@ In that case, <code class="docutils literal notranslate"><span class="pre">targe
|
|||
<li><p><strong>Lines 22-23</strong>: At this point we have a suitable target and can send our punching strings to each.</p></li>
|
||||
</ul>
|
||||
<p>Finally we must also add this to a CmdSet. Let’s add it to <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code> which we made persistent earlier.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">MyCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdEcho</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdHit</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Errors in your code</p>
|
||||
<p>With longer code snippets to try, it gets more and more likely you’ll
|
||||
make an error and get a <cite>traceback</cite> when you reload. This will either appear
|
||||
directly in-game or in your log (view it with <cite>evennia -l</cite> in a terminal).
|
||||
Don’t panic; tracebacks are your friends - they are to be read bottom-up and usually describe
|
||||
exactly where your problem is. Refer to <a class="reference external" href="Python-basic-introduction.html">The Python intro</a> for
|
||||
more hints. If you get stuck, reach out to the Evennia community for help.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>With longer code snippets to try, it gets more and more likely you'll
|
||||
make an error and get a `traceback` when you reload. This will either appear
|
||||
directly in-game or in your log (view it with `evennia -l` in a terminal).
|
||||
Don't panic; tracebacks are your friends - they are to be read bottom-up and usually describe
|
||||
exactly where your problem is. Refer to `The Python intro <Python-basic-introduction.html>`_ for
|
||||
more hints. If you get stuck, reach out to the Evennia community for help.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Next we reload to let Evennia know of these code changes and try it out:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
hit
|
||||
Who do you want to hit?
|
||||
hit me
|
||||
|
|
@ -486,7 +409,7 @@ You got hit by YourName with full force!
|
|||
</div>
|
||||
<p>Lacking a target, we hit ourselves. If you have one of the dragons still around from the previous lesson
|
||||
you could try to hit it (if you dare):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>hit smaug
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>hit smaug
|
||||
You hit Smaug with full force!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -561,7 +484,7 @@ get into how we replace and extend Evennia’s default Commands.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Adding-Commands.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,19 +49,19 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="using-the-game-and-building-stuff">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="using-the-game-and-building-stuff">
|
||||
<h1>Using the game and building stuff<a class="headerlink" href="#using-the-game-and-building-stuff" title="Permalink to this headline">¶</a></h1>
|
||||
<p>In this lesson we will test out what we can do in-game out-of-the-box. Evennia ships with
|
||||
<a class="reference external" href="../../../api/evennia.commands.default.html#modules">around 90 default commands</a>, and while you can override those as you please,
|
||||
<a class="reference internal" href="../../../Components/Default-Commands.html"><span class="doc std std-doc">around 90 default commands</span></a>, and while you can override those as you please,
|
||||
they can be quite useful.</p>
|
||||
<p>Connect and log into your new game and you will end up in the “Limbo” location. This
|
||||
is the only room in the game at this point. Let’s explore the commands a little.</p>
|
||||
<p>The default commands has syntax <a class="reference internal" href="../../../Concepts/Using-MUX-as-a-Standard.html"><span class="doc">similar to MUX</span></a>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">command</span><span class="p">[</span><span class="o">/</span><span class="n">switch</span><span class="o">/</span><span class="n">switch</span><span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">arguments</span> <span class="o">...</span><span class="p">]</span>
|
||||
<p>The default commands has syntax <a class="reference internal" href="../../../Concepts/Using-MUX-as-a-Standard.html"><span class="doc std std-doc">similar to MUX</span></a>:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> command[/switch/switch...] [arguments ...]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An example would be</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> create/drop box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A <em>/switch</em> is a special, optional flag to the command to make it behave differently. It is always
|
||||
|
|
@ -72,11 +74,11 @@ the preceeding @.</p>
|
|||
</div></blockquote>
|
||||
<section id="getting-help">
|
||||
<h2>Getting help<a class="headerlink" href="#getting-help" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">help</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>help
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Will give you a list of all commands available to you. Use</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">help</span> <span class="o"><</span><span class="n">commandname</span><span class="o">></span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>help <commandname>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>to see the in-game help for that command.</p>
|
||||
|
|
@ -84,13 +86,13 @@ the preceeding @.</p>
|
|||
<section id="looking-around">
|
||||
<h2>Looking around<a class="headerlink" href="#looking-around" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The most common comman is</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">look</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show you the description of the current location. <code class="docutils literal notranslate"><span class="pre">l</span></code> is an alias.</p>
|
||||
<p>When targeting objects in commands you have two special labels you can use, <code class="docutils literal notranslate"><span class="pre">here</span></code> for the current
|
||||
room or <code class="docutils literal notranslate"><span class="pre">me</span></code>/<code class="docutils literal notranslate"><span class="pre">self</span></code> to point back to yourself. So</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">look</span> <span class="n">me</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look me
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>will give you your own description. <code class="docutils literal notranslate"><span class="pre">look</span> <span class="pre">here</span></code> is, in this case, the same as plain <code class="docutils literal notranslate"><span class="pre">look</span></code>.</p>
|
||||
|
|
@ -102,14 +104,14 @@ room or <code class="docutils literal notranslate"><span class="pre">me</span></
|
|||
restrictions such as locks. This can be useful, but it also hides some functionality that you might
|
||||
want to test.</p>
|
||||
<p>To temporarily step down from your superuser position you can use the <code class="docutils literal notranslate"><span class="pre">quell</span></code> command in-game:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">quell</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>quell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will make you start using the permission of your current character’s level instead of your
|
||||
superuser level. If you didn’t change any settings your game Character should have an <em>Developer</em>
|
||||
level permission - high as can be without bypassing locks like the superuser does. This will work
|
||||
fine for the examples on this page. Use</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">unquell</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>unquell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>to get superuser status again when you are done.</p>
|
||||
|
|
@ -118,20 +120,22 @@ fine for the examples on this page. Use</p>
|
|||
<h2>Creating an Object<a class="headerlink" href="#creating-an-object" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Basic objects can be anything – swords, flowers and non-player characters. They are created using
|
||||
the <code class="docutils literal notranslate"><span class="pre">create</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">create</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This created a new ‘box’ (of the default object type) in your inventory. Use the command <code class="docutils literal notranslate"><span class="pre">inventory</span></code>
|
||||
(or <code class="docutils literal notranslate"><span class="pre">i</span></code>) to see it. Now, ‘box’ is a rather short name, let’s rename it and tack on a few aliases.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">name</span> <span class="n">box</span> <span class="o">=</span> <span class="n">very</span> <span class="n">large</span> <span class="n">box</span><span class="p">;</span><span class="n">box</span><span class="p">;</span><span class="n">very</span><span class="p">;</span><span class="n">crate</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>name box = very large box;box;very;crate
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>MUD clients and semi-colon</p>
|
||||
<p>Some traditional MUD clients use the semi-colon <cite>;</cite> to separate client inputs. If so,
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Some traditional MUD clients use the semi-colon `;` to separate client inputs. If so,
|
||||
the above line will give an error. You need to change your client to use another command-separator
|
||||
or to put it in ‘verbatim’ mode. If you still have trouble, use the Evennia web client instead.</p>
|
||||
or to put it in 'verbatim' mode. If you still have trouble, use the Evennia web client instead.
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>We now renamed the box to <em>very large box</em> (and this is what we will see when looking at it), but we
|
||||
will also recognize it by any of the other names we give - like <em>crate</em> or simply <em>box</em> as before.
|
||||
|
|
@ -141,64 +145,64 @@ new object. If you had wanted to not change the name itself, but to only add ali
|
|||
used the <code class="docutils literal notranslate"><span class="pre">alias</span></code> command.</p>
|
||||
<p>We are currently carrying the box. Let’s drop it (there is also a short cut to create and drop in
|
||||
one go by using the <code class="docutils literal notranslate"><span class="pre">/drop</span></code> switch, for example <code class="docutils literal notranslate"><span class="pre">create/drop</span> <span class="pre">box</span></code>).</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">drop</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>drop box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Hey presto - there it is on the ground, in all its normality.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">examine</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>examine box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show some technical details about the box object. For now we will ignore what this
|
||||
information means.</p>
|
||||
<p>Try to <code class="docutils literal notranslate"><span class="pre">look</span></code> at the box to see the (default) description.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">look</span> <span class="n">box</span>
|
||||
<span class="n">You</span> <span class="n">see</span> <span class="n">nothing</span> <span class="n">special</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look box
|
||||
You see nothing special.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The description you get is not very exciting. Let’s add some flavor.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">describe</span> <span class="n">box</span> <span class="o">=</span> <span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">large</span> <span class="ow">and</span> <span class="n">very</span> <span class="n">heavy</span> <span class="n">box</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>describe box = This is a large and very heavy box.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you try the <code class="docutils literal notranslate"><span class="pre">get</span></code> command we will pick up the box. So far so good, but if we really want this to
|
||||
be a large and heavy box, people should <em>not</em> be able to run off with it that easily. To prevent
|
||||
this we need to lock it down. This is done by assigning a <em>Lock</em> to it. Make sure the box was
|
||||
dropped in the room, then try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">lock</span> <span class="n">box</span> <span class="o">=</span> <span class="n">get</span><span class="p">:</span><span class="n">false</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>lock box = get:false()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Locks represent a rather <a class="reference internal" href="../../../Components/Locks.html"><span class="doc">big topic</span></a>, but for now that will do what we want. This will lock
|
||||
<p>Locks represent a rather <a class="reference internal" href="../../../Components/Locks.html"><span class="doc std std-doc">big topic</span></a>, but for now that will do what we want. This will lock
|
||||
the box so noone can lift it. The exception is superusers, they override all locks and will pick it
|
||||
up anyway. Make sure you are quelling your superuser powers and try to get the box now:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">get</span> <span class="n">box</span>
|
||||
<span class="n">You</span> <span class="n">can</span><span class="s1">'t get that.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> get box
|
||||
You can't get that.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Think thís default error message looks dull? The <code class="docutils literal notranslate"><span class="pre">get</span></code> command looks for an <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attribute</span></a>
|
||||
<p>Think thís default error message looks dull? The <code class="docutils literal notranslate"><span class="pre">get</span></code> command looks for an <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attribute</span></a>
|
||||
named <code class="docutils literal notranslate"><span class="pre">get_err_msg</span></code> for returning a nicer error message (we just happen to know this, you would need
|
||||
to peek into the
|
||||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/commands/default/general.py#L235">code</a> for
|
||||
the <code class="docutils literal notranslate"><span class="pre">get</span></code> command to find out.). You set attributes using the <code class="docutils literal notranslate"><span class="pre">set</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">box</span><span class="o">/</span><span class="n">get_err_msg</span> <span class="o">=</span> <span class="n">It</span><span class="s1">'s way too heavy for you to lift. </span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>set box/get_err_msg = It's way too heavy for you to lift.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Try to get it now and you should see a nicer error message echoed back to you. To see what this
|
||||
message string is in the future, you can use ‘examine.’</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">examine</span> <span class="n">box</span><span class="o">/</span><span class="n">get_err_msg</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>examine box/get_err_msg
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Examine will return the value of attributes, including color codes. <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">here/desc</span></code> would return
|
||||
the raw description of your current room (including color codes), so that you can copy-and-paste to
|
||||
set its description to something else.</p>
|
||||
<p>You create new Commands (or modify existing ones) in Python outside the game. We will get to that
|
||||
later, in the <a class="reference internal" href="Adding-Commands.html"><span class="doc">Commands tutorial</span></a>.</p>
|
||||
later, in the <a class="reference internal" href="Adding-Commands.html"><span class="doc std std-doc">Commands tutorial</span></a>.</p>
|
||||
</section>
|
||||
<section id="get-a-personality">
|
||||
<h2>Get a Personality<a class="headerlink" href="#get-a-personality" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Scripts</span></a> are powerful out-of-character objects useful for many “under the hood” things.
|
||||
<p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> are powerful out-of-character objects useful for many “under the hood” things.
|
||||
One of their optional abilities is to do things on a timer. To try out a first script, let’s put one
|
||||
on ourselves. There is an example script in <code class="docutils literal notranslate"><span class="pre">evennia/contrib/tutorial_examples/bodyfunctions.py</span></code>
|
||||
that is called <code class="docutils literal notranslate"><span class="pre">BodyFunctions</span></code>. To add this to us we will use the <code class="docutils literal notranslate"><span class="pre">script</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">script</span> <span class="bp">self</span> <span class="o">=</span> <span class="n">tutorial_examples</span><span class="o">.</span><span class="n">bodyfunctions</span><span class="o">.</span><span class="n">BodyFunctions</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script self = tutorial_examples.bodyfunctions.BodyFunctions
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This string will tell Evennia to dig up the Python code at the place we indicate. It already knows
|
||||
|
|
@ -210,7 +214,7 @@ Python code <em>inside</em> files, like the <code class="docutils literal notran
|
|||
These “Python-paths” are used extensively throughout Evennia.</p>
|
||||
</div></blockquote>
|
||||
<p>Wait a while and you will notice yourself starting making random observations …</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">script</span> <span class="bp">self</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script self
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show details about scripts on yourself (also <code class="docutils literal notranslate"><span class="pre">examine</span></code> works). You will see how long it is
|
||||
|
|
@ -218,32 +222,32 @@ until it “fires” next. Don’t be alarmed if nothing happens when the countd
|
|||
particular script has a randomizer to determine if it will say something or not. So you will not see
|
||||
output every time it fires.</p>
|
||||
<p>When you are tired of your character’s “insights”, kill the script with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">script</span><span class="o">/</span><span class="n">stop</span> <span class="bp">self</span> <span class="o">=</span> <span class="n">tutorial_examples</span><span class="o">.</span><span class="n">bodyfunctions</span><span class="o">.</span><span class="n">BodyFunctions</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script/stop self = tutorial_examples.bodyfunctions.BodyFunctions
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You create your own scripts in Python, outside the game; the path you give to <code class="docutils literal notranslate"><span class="pre">script</span></code> is literally
|
||||
the Python path to your script file. The <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Scripts</span></a> page explains more details.</p>
|
||||
the Python path to your script file. The <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> page explains more details.</p>
|
||||
</section>
|
||||
<section id="pushing-your-buttons">
|
||||
<h2>Pushing Your Buttons<a class="headerlink" href="#pushing-your-buttons" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If we get back to the box we made, there is only so much fun you can have with it at this point. It’s
|
||||
just a dumb generic object. If you renamed it to <code class="docutils literal notranslate"><span class="pre">stone</span></code> and changed its description, noone would be
|
||||
the wiser. However, with the combined use of custom <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc">Typeclasses</span></a>, <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Scripts</span></a>
|
||||
and object-based <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Commands</span></a>, you could expand it and other items to be as unique, complex
|
||||
the wiser. However, with the combined use of custom <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a>, <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a>
|
||||
and object-based <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a>, you could expand it and other items to be as unique, complex
|
||||
and interactive as you want.</p>
|
||||
<p>Let’s take an example. So far we have only created objects that use the default object typeclass
|
||||
named simply <code class="docutils literal notranslate"><span class="pre">Object</span></code>. Let’s create an object that is a little more interesting. Under
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/contrib/tutorial_examples</span></code> there is a module <code class="docutils literal notranslate"><span class="pre">red_button.py</span></code>. It contains the enigmatic
|
||||
<code class="docutils literal notranslate"><span class="pre">RedButton</span></code> class.</p>
|
||||
<p>Let’s make us one of <em>those</em>!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">button</span><span class="p">:</span><span class="n">tutorial_examples</span><span class="o">.</span><span class="n">red_button</span><span class="o">.</span><span class="n">RedButton</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create/drop button:tutorial_examples.red_button.RedButton
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The same way we did with the Script Earler, we specify a “Python-path” to the Python code we want Evennia
|
||||
to use for creating the object. There you go - one red button.</p>
|
||||
<p>The RedButton is an example object intended to show off a few of Evennia’s features. You will find
|
||||
that the <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc">Typeclass</span></a> and <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Commands</span></a> controlling it are
|
||||
inside <a class="reference external" href="../../../api/evennia.contrib.tutorial_examples.html">evennia/contrib/tutorial_examples</a></p>
|
||||
that the <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">Typeclass</span></a> and <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a> controlling it are
|
||||
inside <a class="reference internal" href="../../../api/evennia.contrib.tutorial_examples.html"><span class="doc std std-doc">evennia/contrib/tutorial_examples</span></a></p>
|
||||
<p>If you wait for a while (make sure you dropped it!) the button will blink invitingly.</p>
|
||||
<p>Why don’t you try to push it …?</p>
|
||||
<p>Surely a big red button is meant to be pushed.</p>
|
||||
|
|
@ -257,7 +261,7 @@ inside <a class="reference external" href="../../../api/evennia.contrib.tutorial
|
|||
<h2>Making Yourself a House<a class="headerlink" href="#making-yourself-a-house" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The main command for shaping the game world is <code class="docutils literal notranslate"><span class="pre">dig</span></code>. For example, if you are standing in Limbo you
|
||||
can dig a route to your new house location like this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dig</span> <span class="n">house</span> <span class="o">=</span> <span class="n">large</span> <span class="n">red</span> <span class="n">door</span><span class="p">;</span><span class="n">door</span><span class="p">;</span><span class="ow">in</span><span class="p">,</span><span class="n">to</span> <span class="n">the</span> <span class="n">outside</span><span class="p">;</span><span class="n">out</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>dig house = large red door;door;in,to the outside;out
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will create a new room named ‘house’. Spaces at the start/end of names and aliases are ignored
|
||||
|
|
@ -268,28 +272,28 @@ the full thing all the time.</p>
|
|||
<p>If you wanted to use normal compass directions (north, west, southwest etc), you could do that with
|
||||
<code class="docutils literal notranslate"><span class="pre">dig</span></code> too. But Evennia also has a limited version of <code class="docutils literal notranslate"><span class="pre">dig</span></code> that helps for compass directions (and
|
||||
also up/down and in/out). It’s called <code class="docutils literal notranslate"><span class="pre">tunnel</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tunnel</span> <span class="n">sw</span> <span class="o">=</span> <span class="n">cliff</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>tunnel sw = cliff
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will create a new room “cliff” with an exit “southwest” leading there and a path “northeast”
|
||||
leading back from the cliff to your current location.</p>
|
||||
<p>You can create new exits from where you are, using the <code class="docutils literal notranslate"><span class="pre">open</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span> <span class="n">north</span><span class="p">;</span><span class="n">n</span> <span class="o">=</span> <span class="n">house</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open north;n = house
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This opens an exit <code class="docutils literal notranslate"><span class="pre">north</span></code> (with an alias <code class="docutils literal notranslate"><span class="pre">n</span></code>) to the previously created room <code class="docutils literal notranslate"><span class="pre">house</span></code>.</p>
|
||||
<p>If you have many rooms named <code class="docutils literal notranslate"><span class="pre">house</span></code> you will get a list of matches and have to select which one you
|
||||
want to link to.</p>
|
||||
<p>Follow the north exit to your ‘house’ or <code class="docutils literal notranslate"><span class="pre">teleport</span></code> to it:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">north</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>north
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">teleport</span> <span class="n">house</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport house
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To manually open an exit back to Limbo (if you didn’t do so with the <code class="docutils literal notranslate"><span class="pre">dig</span></code> command):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span> <span class="n">door</span> <span class="o">=</span> <span class="n">limbo</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open door = limbo
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(You can also us the #dbref of limbo, which you can find by using <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">here</span></code> when in limbo).</p>
|
||||
|
|
@ -298,25 +302,25 @@ want to link to.</p>
|
|||
<h2>Reshuffling the World<a class="headerlink" href="#reshuffling-the-world" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can find things using the <code class="docutils literal notranslate"><span class="pre">find</span></code> command. Assuming you are back at <code class="docutils literal notranslate"><span class="pre">Limbo</span></code>, let’s teleport the
|
||||
<em>large box</em> to our house.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">teleport</span> <span class="n">box</span> <span class="o">=</span> <span class="n">house</span>
|
||||
<span class="n">very</span> <span class="n">large</span> <span class="n">box</span> <span class="ow">is</span> <span class="n">leaving</span> <span class="n">Limbo</span><span class="p">,</span> <span class="n">heading</span> <span class="k">for</span> <span class="n">house</span><span class="o">.</span>
|
||||
<span class="n">Teleported</span> <span class="n">very</span> <span class="n">large</span> <span class="n">box</span> <span class="o">-></span> <span class="n">house</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport box = house
|
||||
very large box is leaving Limbo, heading for house.
|
||||
Teleported very large box -> house.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We can still find the box by using find:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">find</span> <span class="n">box</span>
|
||||
<span class="n">One</span> <span class="n">Match</span><span class="p">(</span><span class="c1">#1-#8):</span>
|
||||
<span class="n">very</span> <span class="n">large</span> <span class="n">box</span><span class="p">(</span><span class="c1">#8) - src.objects.objects.Object</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>find box
|
||||
One Match(#1-#8):
|
||||
very large box(#8) - src.objects.objects.Object
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Knowing the <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> of the box (#8 in this example), you can grab the box and get it back here
|
||||
without actually yourself going to <code class="docutils literal notranslate"><span class="pre">house</span></code> first:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">teleport</span> <span class="c1">#8 = here</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport #8 = here
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>As mentioned, <code class="docutils literal notranslate"><span class="pre">here</span></code> is an alias for ‘your current location’. The box should now be back in Limbo with you.</p>
|
||||
<p>We are getting tired of the box. Let’s destroy it.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">destroy</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>destroy box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It will ask you for confirmation. Once you give it, the box will be gone.</p>
|
||||
|
|
@ -328,7 +332,7 @@ of #dbrefs, if they are not in the same location) to the command.</p>
|
|||
<p>The Command-help is something you modify in Python code. We’ll get to that when we get to how to
|
||||
add Commands. But you can also add regular help entries, for example to explain something about
|
||||
the history of your game world:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sethelp</span><span class="o">/</span><span class="n">add</span> <span class="n">History</span> <span class="o">=</span> <span class="n">At</span> <span class="n">the</span> <span class="n">dawn</span> <span class="n">of</span> <span class="n">time</span> <span class="o">...</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>sethelp/add History = At the dawn of time ...
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will now find your new <code class="docutils literal notranslate"><span class="pre">History</span></code> entry in the <code class="docutils literal notranslate"><span class="pre">help</span></code> list and read your help-text with <code class="docutils literal notranslate"><span class="pre">help</span> <span class="pre">History</span></code>.</p>
|
||||
|
|
@ -403,7 +407,7 @@ example. Evennia comes with a tutorial world for you to explore. We will try tha
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Building-Quickstart.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,31 +49,31 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="creating-things">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="creating-things">
|
||||
<h1>Creating things<a class="headerlink" href="#creating-things" title="Permalink to this headline">¶</a></h1>
|
||||
<p>We have already created some things - dragons for example. There are many different things to create
|
||||
in Evennia though. In the last lesson we learned about typeclasses, the way to make objects persistent in the database.</p>
|
||||
<p>Given the path to a Typeclass, there are three ways to create an instance of it:</p>
|
||||
<ul>
|
||||
<li><p>Firstly, you can call the class directly, and then <code class="docutils literal notranslate"><span class="pre">.save()</span></code> it:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">obj</span> <span class="o">=</span> <span class="n">SomeTypeClass</span><span class="p">(</span><span class="n">db_key</span><span class="o">=...</span><span class="p">)</span>
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> obj = SomeTypeClass(db_key=...)
|
||||
obj.save()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This has the drawback of being two operations; you must also import the class and have to pass
|
||||
the actual database field names, such as <code class="docutils literal notranslate"><span class="pre">db_key</span></code> instead of <code class="docutils literal notranslate"><span class="pre">key</span></code> as keyword arguments.</p>
|
||||
</li>
|
||||
<li><p>Secondly you can use the Evennia creation helpers:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">obj</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">SomeTypeClass</span><span class="p">,</span> <span class="n">key</span><span class="o">=...</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> obj = evennia.create_object(SomeTypeClass, key=...)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is the recommended way if you are trying to create things in Python. The first argument can either be
|
||||
the class <em>or</em> the python-path to the typeclass, like <code class="docutils literal notranslate"><span class="pre">"path.to.SomeTypeClass"</span></code>. It can also be <code class="docutils literal notranslate"><span class="pre">None</span></code> in which
|
||||
case the Evennia default will be used. While all the creation methods
|
||||
are available on <code class="docutils literal notranslate"><span class="pre">evennia</span></code>, they are actually implemented in <a class="reference external" href="../../../api/evennia.utils.create.html">evennia/utils/create.py</a>.</p>
|
||||
are available on <code class="docutils literal notranslate"><span class="pre">evennia</span></code>, they are actually implemented in <a class="reference internal" href="../../../api/evennia.utils.create.html"><span class="doc std std-doc">evennia/utils/create.py</span></a>.</p>
|
||||
</li>
|
||||
<li><p>Finally, you can create objects using an in-game command, such as</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">obj</span><span class="p">:</span><span class="n">path</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">SomeTypeClass</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> create/drop obj:path.to.SomeTypeClass
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>As a developer you are usually best off using the two other methods, but a command is usually the only way
|
||||
|
|
@ -82,9 +84,9 @@ to let regular players or builders without Python-access help build the game wor
|
|||
<h2>Creating Objects<a class="headerlink" href="#creating-objects" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This is one of the most common creation-types. These are entities that inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> at any distance.
|
||||
They have an existence in the game world and includes rooms, characters, exits, weapons, flower pots and castles.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span>
|
||||
<span class="o">></span> <span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="o">></span> <span class="n">rose</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> import evennia
|
||||
> rose = evennia.create_object(key="rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Since we didn’t specify the <code class="docutils literal notranslate"><span class="pre">typeclass</span></code> as the first argument, the default given by <code class="docutils literal notranslate"><span class="pre">settings.BASE_OBJECT_TYPECLASS</span></code>
|
||||
|
|
@ -153,7 +155,7 @@ You can find the parent class for Accounts in <code class="docutils literal notr
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Creating-Things.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,15 +49,17 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="django-database-queries">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="django-database-queries">
|
||||
<h1>Django Database queries<a class="headerlink" href="#django-database-queries" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="admonition important">
|
||||
<p class="admonition-title">Important</p>
|
||||
<p>More advanced lesson!</p>
|
||||
<p>Learning about Django’s queryset language is very useful once you start doing more advanced things
|
||||
in Evennia. But it’s not strictly needed out the box and can be a little overwhelming for a first
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Learning about Django's queryset language is very useful once you start doing more advanced things
|
||||
in Evennia. But it's not strictly needed out the box and can be a little overwhelming for a first
|
||||
reading. So if you are new to Python and Evennia, feel free to just skim this lesson and refer
|
||||
back to it later when you’ve gained more experience.</p>
|
||||
back to it later when you've gained more experience.
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>The search functions and methods we used in the previous lesson are enough for most cases.
|
||||
But sometimes you need to be more specific:</p>
|
||||
|
|
@ -74,12 +78,12 @@ a database query. One can add querysets together to build ever-more complicated
|
|||
you are trying to use the results of the queryset will it actually call the database.</p>
|
||||
<p>The normal way to build a queryset is to define what class of entity you want to search by getting its
|
||||
<code class="docutils literal notranslate"><span class="pre">.objects</span></code> resource, and then call various methods on that. We’ve seen this one before:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_weapons</span> <span class="o">=</span> <span class="n">Weapon</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_weapons = Weapon.objects.all()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is now a queryset representing all instances of <code class="docutils literal notranslate"><span class="pre">Weapon</span></code>. If <code class="docutils literal notranslate"><span class="pre">Weapon</span></code> had a subclass <code class="docutils literal notranslate"><span class="pre">Cannon</span></code> and we
|
||||
only wanted the cannons, we would do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_cannons</span> <span class="o">=</span> <span class="n">Cannon</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_cannons = Cannon.objects.all()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note that <code class="docutils literal notranslate"><span class="pre">Weapon</span></code> and <code class="docutils literal notranslate"><span class="pre">Cannon</span></code> are different typeclasses. You won’t find any <code class="docutils literal notranslate"><span class="pre">Cannon</span></code> instances in
|
||||
|
|
@ -87,35 +91,37 @@ the <code class="docutils literal notranslate"><span class="pre">all_weapon</spa
|
|||
instances of all its children classes you need to use <code class="docutils literal notranslate"><span class="pre">_family</span></code>:</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">_family</p>
|
||||
<p>The all_family, filter_family etc is an Evennia-specific
|
||||
thing. It’s not part of regular Django.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The all_family, filter_family etc is an Evennia-specific
|
||||
thing. It's not part of regular Django.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">really_all_weapons</span> <span class="o">=</span> <span class="n">Weapon</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all_family</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>really_all_weapons = Weapon.objects.all_family()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This result now contains both <code class="docutils literal notranslate"><span class="pre">Weapon</span></code> and <code class="docutils literal notranslate"><span class="pre">Cannon</span></code> instances.</p>
|
||||
<p>To limit your search by other criteria than the Typeclass you need to use <code class="docutils literal notranslate"><span class="pre">.filter</span></code>
|
||||
(or <code class="docutils literal notranslate"><span class="pre">.filter_family</span></code>) instead:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">roses</span> <span class="o">=</span> <span class="n">Flower</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>roses = Flower.objects.filter(db_key="rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is a queryset representing all objects having a <code class="docutils literal notranslate"><span class="pre">db_key</span></code> equal to <code class="docutils literal notranslate"><span class="pre">"rose"</span></code>.
|
||||
Since this is a queryset you can keep adding to it; this will act as an <code class="docutils literal notranslate"><span class="pre">AND</span></code> condition.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">local_roses</span> <span class="o">=</span> <span class="n">roses</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_location</span><span class="o">=</span><span class="n">myroom</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>local_roses = roses.filter(db_location=myroom)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We could also have written this in one statement:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">local_roses</span> <span class="o">=</span> <span class="n">Flower</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">,</span> <span class="n">db_location</span><span class="o">=</span><span class="n">myroom</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>local_roses = Flower.objects.filter(db_key="rose", db_location=myroom)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We can also <code class="docutils literal notranslate"><span class="pre">.exclude</span></code> something from results</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">local_non_red_roses</span> <span class="o">=</span> <span class="n">local_roses</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"red_rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>local_non_red_roses = local_roses.exclude(db_key="red_rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Only until we actually try to examine the result will the database be called. Here it’s called when we
|
||||
try to loop over the queryset:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">rose</span> <span class="ow">in</span> <span class="n">local_non_red_roses</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="n">rose</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>for rose in local_non_red_roses:
|
||||
print(rose)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>From now on, the queryset is <em>evaluated</em> and we can’t keep adding more queries to it - we’d need to
|
||||
|
|
@ -143,35 +149,35 @@ return querysets, which means you could in principle keep adding queries to thei
|
|||
<h2>Queryset field lookups<a class="headerlink" href="#queryset-field-lookups" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Above we found roses with exactly the <code class="docutils literal notranslate"><span class="pre">db_key</span></code> <code class="docutils literal notranslate"><span class="pre">"rose"</span></code>. This is an <em>exact</em> match that is <em>case sensitive</em>,
|
||||
so it would not find <code class="docutils literal notranslate"><span class="pre">"Rose"</span></code>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># this is case-sensitive and the same as =</span>
|
||||
<span class="n">roses</span> <span class="o">=</span> <span class="n">Flower</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key__exact</span><span class="o">=</span><span class="s2">"rose"</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span># this is case-sensitive and the same as =
|
||||
roses = Flower.objects.filter(db_key__exact="rose"
|
||||
|
||||
<span class="c1"># the i means it's case-insensitive</span>
|
||||
<span class="n">roses</span> <span class="o">=</span> <span class="n">Flower</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key__iexact</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
# the i means it's case-insensitive
|
||||
roses = Flower.objects.filter(db_key__iexact="rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The Django field query language uses <code class="docutils literal notranslate"><span class="pre">__</span></code> in the same way as Python uses <code class="docutils literal notranslate"><span class="pre">.</span></code> to access resources. This
|
||||
is because <code class="docutils literal notranslate"><span class="pre">.</span></code> is not allowed in a function keyword.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">roses</span> <span class="o">=</span> <span class="n">Flower</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key__icontains</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>roses = Flower.objects.filter(db_key__icontains="rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will find all flowers whose name contains the string <code class="docutils literal notranslate"><span class="pre">"rose"</span></code>, like <code class="docutils literal notranslate"><span class="pre">"roses"</span></code>, <code class="docutils literal notranslate"><span class="pre">"wild</span> <span class="pre">rose"</span></code> etc. The
|
||||
<code class="docutils literal notranslate"><span class="pre">i</span></code> in the beginning makes the search case-insensitive. Other useful variations to use
|
||||
are <code class="docutils literal notranslate"><span class="pre">__istartswith</span></code> and <code class="docutils literal notranslate"><span class="pre">__iendswith</span></code>. You can also use <code class="docutils literal notranslate"><span class="pre">__gt</span></code>, <code class="docutils literal notranslate"><span class="pre">__ge</span></code> for “greater-than”/”greater-or-equal-than”
|
||||
are <code class="docutils literal notranslate"><span class="pre">__istartswith</span></code> and <code class="docutils literal notranslate"><span class="pre">__iendswith</span></code>. You can also use <code class="docutils literal notranslate"><span class="pre">__gt</span></code>, <code class="docutils literal notranslate"><span class="pre">__ge</span></code> for “greater-than”/“greater-or-equal-than”
|
||||
comparisons (same for <code class="docutils literal notranslate"><span class="pre">__lt</span></code> and <code class="docutils literal notranslate"><span class="pre">__le</span></code>). There is also <code class="docutils literal notranslate"><span class="pre">__in</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">swords</span> <span class="o">=</span> <span class="n">Weapons</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key__in</span><span class="o">=</span><span class="p">(</span><span class="s2">"rapier"</span><span class="p">,</span> <span class="s2">"two-hander"</span><span class="p">,</span> <span class="s2">"shortsword"</span><span class="p">))</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>swords = Weapons.objects.filter(db_key__in=("rapier", "two-hander", "shortsword"))
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>One also uses <code class="docutils literal notranslate"><span class="pre">__</span></code> to access foreign objects like Tags. Let’s for example assume this is how we identify mages:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">char</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"mage"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"profession"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>char.tags.add("mage", category="profession")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now, in this case we have an Evennia helper to do this search:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mages</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_tags</span><span class="p">(</span><span class="s2">"mage"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"profession"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mages = evennia.search_tags("mage", category="profession")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>But this will find all Objects with this tag+category. Maybe you are only looking for Vampire mages:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sparkly_mages</span> <span class="o">=</span> <span class="n">Vampire</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_tags__db_key</span><span class="o">=</span><span class="s2">"mage"</span><span class="p">,</span> <span class="n">db_tags__db_category</span><span class="o">=</span><span class="s2">"profession"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>sparkly_mages = Vampire.objects.filter(db_tags__db_key="mage", db_tags__db_category="profession")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This looks at the <code class="docutils literal notranslate"><span class="pre">db_tags</span></code> field on the <code class="docutils literal notranslate"><span class="pre">Vampire</span></code> and filters on the values of each tag’s
|
||||
|
|
@ -184,27 +190,21 @@ comparisons (same for <code class="docutils literal notranslate"><span class="pr
|
|||
<p>Let’s see if we can make a query for the werewolves in the moonlight we mentioned at the beginning
|
||||
of this section.</p>
|
||||
<p>Firstly, we make ourselves and our current location match the criteria, so we can test:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">here</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"moonlit"</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="n">me</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">lycantrophy</span> <span class="o">=</span> <span class="mi">3</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py here.tags.add("moonlit")
|
||||
> py me.db.lycantrophy = 3
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is an example of a more complex query. We’ll consider it an example of what is
|
||||
possible.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Line breaks</p>
|
||||
<p>Note the way of writing this code. It would have been very hard to read if we just wrote it in
|
||||
one long line. But since we wrapped it in <cite>(…)</cite> we can spread it out over multiple lines
|
||||
without worrying about line breaks!</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Note the way of writing this code. It would have been very hard to read if we just wrote it in
|
||||
one long line. But since we wrapped it in `(...)` we can spread it out over multiple lines
|
||||
without worrying about line breaks!
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span>
|
||||
<span class="normal">9</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">typeclasses.characters</span> <span class="kn">import</span> <span class="n">Character</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">typeclasses.characters</span> <span class="kn">import</span> <span class="n">Character</span>
|
||||
|
||||
<span class="n">will_transform</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">Character</span><span class="o">.</span><span class="n">objects</span>
|
||||
|
|
@ -214,7 +214,7 @@ without worrying about line breaks!</p>
|
|||
<span class="n">db_attributes__db_value__gt</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Line 3</strong> - We want to find <code class="docutils literal notranslate"><span class="pre">Character</span></code>s, so we access <code class="docutils literal notranslate"><span class="pre">.objects</span></code> on the <code class="docutils literal notranslate"><span class="pre">Character</span></code> typeclass.</p></li>
|
||||
<li><p><strong>Line 4</strong> - We start to filter …</p></li>
|
||||
|
|
@ -231,7 +231,7 @@ that we can treat like an object for this purpose; it references all Tags on the
|
|||
</ul>
|
||||
<p>Running this query makes our newly lycantrrophic Character appear in <code class="docutils literal notranslate"><span class="pre">will_transform</span></code>. Success!</p>
|
||||
<blockquote>
|
||||
<div><p>Don’t confuse database fields with <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attributes</span></a> you set via <code class="docutils literal notranslate"><span class="pre">obj.db.attr</span> <span class="pre">=</span> <span class="pre">'foo'</span></code> or
|
||||
<div><p>Don’t confuse database fields with <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attributes</span></a> you set via <code class="docutils literal notranslate"><span class="pre">obj.db.attr</span> <span class="pre">=</span> <span class="pre">'foo'</span></code> or
|
||||
<code class="docutils literal notranslate"><span class="pre">obj.attributes.add()</span></code>. Attributes are custom database entities <em>linked</em> to an object. They are not
|
||||
separate fields <em>on</em> that object like <code class="docutils literal notranslate"><span class="pre">db_key</span></code> or <code class="docutils literal notranslate"><span class="pre">db_location</span></code> are.</p>
|
||||
</div></blockquote>
|
||||
|
|
@ -239,28 +239,28 @@ separate fields <em>on</em> that object like <code class="docutils literal notra
|
|||
<section id="complex-queries">
|
||||
<h2>Complex queries<a class="headerlink" href="#complex-queries" title="Permalink to this headline">¶</a></h2>
|
||||
<p>All examples so far used <code class="docutils literal notranslate"><span class="pre">AND</span></code> relations. The arguments to <code class="docutils literal notranslate"><span class="pre">.filter</span></code> are added together with <code class="docutils literal notranslate"><span class="pre">AND</span></code>
|
||||
(”we want tag room to be “monlit” <em>and</em> lycantrhopy be > 2”).</p>
|
||||
(“we want tag room to be “monlit” <em>and</em> lycantrhopy be > 2”).</p>
|
||||
<p>For queries using <code class="docutils literal notranslate"><span class="pre">OR</span></code> and <code class="docutils literal notranslate"><span class="pre">NOT</span></code> we need Django’s
|
||||
<a class="reference external" href="https://docs.djangoproject.com/en/1.11/topics/db/queries/#complex-lookups-with-q-objects">Q object</a>. It is
|
||||
imported from Django directly:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from django.db.models import Q
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">Q</span></code> is an object that is created with the same arguments as <code class="docutils literal notranslate"><span class="pre">.filter</span></code>, for example</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"foo"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Q(db_key="foo")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can then use this <code class="docutils literal notranslate"><span class="pre">Q</span></code> instance as argument in a <code class="docutils literal notranslate"><span class="pre">filter</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">q1</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"foo"</span><span class="p">)</span>
|
||||
<span class="n">Character</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">q1</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>q1 = Q(db_key="foo")
|
||||
Character.objects.filter(q1)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The useful thing about <code class="docutils literal notranslate"><span class="pre">Q</span></code> is that these objects can be chained together with special symbols (bit operators):
|
||||
<code class="docutils literal notranslate"><span class="pre">|</span></code> for <code class="docutils literal notranslate"><span class="pre">OR</span></code> and <code class="docutils literal notranslate"><span class="pre">&</span></code> for <code class="docutils literal notranslate"><span class="pre">AND</span></code>. A tilde <code class="docutils literal notranslate"><span class="pre">~</span></code> in front negates the expression inside the <code class="docutils literal notranslate"><span class="pre">Q</span></code> and thus
|
||||
works like <code class="docutils literal notranslate"><span class="pre">NOT</span></code>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">q1</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">"Dalton"</span><span class="p">)</span>
|
||||
<span class="n">q2</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_location</span><span class="o">=</span><span class="n">prison</span><span class="p">)</span>
|
||||
<span class="n">Character</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">q1</span> <span class="o">|</span> <span class="o">~</span><span class="n">q2</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>q1 = Q(db_key="Dalton")
|
||||
q2 = Q(db_location=prison)
|
||||
Character.objects.filter(q1 | ~q2)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Would get all Characters that are either named “Dalton” <em>or</em> which is <em>not</em> in prison. The result is a mix
|
||||
|
|
@ -270,19 +270,7 @@ with a certain level of <code class="docutils literal notranslate"><span class="
|
|||
recently bitten, even if their <code class="docutils literal notranslate"><span class="pre">lycantrophy</span></code> level is not yet high enough (more dramatic this way!). Let’s say there is
|
||||
a Tag “recently_bitten” that controls this.</p>
|
||||
<p>This is how we’d change our query:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
|
||||
<span class="n">will_transform</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">Character</span><span class="o">.</span><span class="n">objects</span>
|
||||
|
|
@ -296,19 +284,9 @@ a Tag “recently_bitten” that controls this.</p>
|
|||
<span class="o">.</span><span class="n">distinct</span><span class="p">()</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>That’s quite compact. It may be easier to see what’s going on if written this way:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
|
||||
|
||||
<span class="n">q_moonlit</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_location__db_tags__db_key__iexact</span><span class="o">=</span><span class="s2">"moonlit"</span><span class="p">)</span>
|
||||
<span class="n">q_lycantropic</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_attributes__db_key</span><span class="o">=</span><span class="s2">"lycantrophy"</span><span class="p">,</span> <span class="n">db_attributes__db_value__gt</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
||||
|
|
@ -320,12 +298,14 @@ a Tag “recently_bitten” that controls this.</p>
|
|||
<span class="o">.</span><span class="n">distinct</span><span class="p">()</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">SQL</p>
|
||||
<p>These Python structures are internally converted to SQL, the native language of the database.
|
||||
If you are familiar with SQL, these are many-to-many tables joined with <cite>LEFT OUTER JOIN</cite>,
|
||||
which may lead to multiple merged rows combining the same object with different relations.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>These Python structures are internally converted to SQL, the native language of the database.
|
||||
If you are familiar with SQL, these are many-to-many tables joined with `LEFT OUTER JOIN`,
|
||||
which may lead to multiple merged rows combining the same object with different relations.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>This reads as “Find all Characters in a moonlit room that either has the Attribute <code class="docutils literal notranslate"><span class="pre">lycantrophy</span></code> higher
|
||||
than two <em>or</em> which has the Tag <code class="docutils literal notranslate"><span class="pre">recently_bitten</span></code>”. With an OR-query like this it’s possible to find the
|
||||
|
|
@ -337,37 +317,22 @@ one instance of each Character in the result.</p>
|
|||
<p>What if we wanted to filter on some condition that isn’t represented easily by a field on the
|
||||
object? Maybe we want to find rooms only containing five or more objects?</p>
|
||||
<p>We <em>could</em> do it like this (don’t actually do it this way!):</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
|
||||
<span class="n">all_rooms</span> <span class="o">=</span> <span class="n">Rooms</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">all_rooms</span> <span class="o">=</span> <span class="n">Rooms</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">rooms_with_five_objects</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">room</span> <span class="ow">in</span> <span class="n">all_rooms</span><span class="p">:</span>
|
||||
<span class="k">for</span> <span class="n">room</span> <span class="ow">in</span> <span class="n">all_rooms</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">room</span><span class="o">.</span><span class="n">contents</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">5</span><span class="p">:</span>
|
||||
<span class="n">rooms_with_five_objects</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Above we get all rooms and then use <code class="docutils literal notranslate"><span class="pre">list.append()</span></code> to keep adding the right rooms
|
||||
to an ever-growing list. This is <em>not</em> a good idea, once your database grows this will
|
||||
be unnecessarily computing-intensive. The database is much more suitable for this.</p>
|
||||
<p><em>Annotations</em> allow you to set a ‘variable’ inside the query that you can
|
||||
then access from other parts of the query. Let’s do the same example as before directly in the database:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span>
|
||||
<span class="normal">9</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
|
||||
|
||||
<span class="n">rooms</span> <span class="o">=</span> <span class="p">(</span>
|
||||
|
|
@ -377,7 +342,7 @@ then access from other parts of the query. Let’s do the same example as before
|
|||
<span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">num_objects__gte</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">Count</span></code> is a Django class for counting the number of things in the database.</p>
|
||||
<p>Here we first create an annotation <code class="docutils literal notranslate"><span class="pre">num_objects</span></code> of type <code class="docutils literal notranslate"><span class="pre">Count</span></code>. It creates an in-database function
|
||||
that will count the number of results inside the database.</p>
|
||||
|
|
@ -396,27 +361,18 @@ instead of having 5 or more objects, we only wanted objects that had a bigger in
|
|||
tags (silly example, but …)? This can be with Django’s
|
||||
<a class="reference external" href="https://docs.djangoproject.com/en/1.11/ref/models/expressions/#f-expressions">F objects</a>.
|
||||
So-called F expressions allow you to do a query that looks at a value of each object in the database.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span><span class="p">,</span> <span class="n">F</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span><span class="p">,</span> <span class="n">F</span>
|
||||
<span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">Room</span><span class="o">.</span><span class="n">objects</span>
|
||||
<span class="o">.</span><span class="n">annotate</span><span class="p">(</span>
|
||||
<span class="n">num_objects</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">'locations_set'</span><span class="p">),</span>
|
||||
<span class="n">num_objects</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">'locations_set'</span><span class="p">),</span>
|
||||
<span class="n">num_tags</span><span class="o">=</span><span class="n">Count</span><span class="p">(</span><span class="s1">'db_tags'</span><span class="p">))</span>
|
||||
<span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">num_objects__gt</span><span class="o">=</span><span class="n">F</span><span class="p">(</span><span class="s1">'num_tags'</span><span class="p">))</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Here we used <code class="docutils literal notranslate"><span class="pre">.annotate</span></code> to create two in-query ‘variables’ <code class="docutils literal notranslate"><span class="pre">num_objects</span></code> and <code class="docutils literal notranslate"><span class="pre">num_tags</span></code>. We then
|
||||
directly use these results in the filter. Using <code class="docutils literal notranslate"><span class="pre">F()</span></code> allows for also the right-hand-side of the filter
|
||||
condition to be calculated on the fly, completely within the database.</p>
|
||||
|
|
@ -429,15 +385,7 @@ need to get the membership count of every organization all at once.</p>
|
|||
you run a <code class="docutils literal notranslate"><span class="pre">.filter</span></code>, what you get back is a bunch of full typeclass instances, like roses or swords.
|
||||
Using <code class="docutils literal notranslate"><span class="pre">.values_list</span></code> you can instead choose to only get back certain properties on objects.
|
||||
The <code class="docutils literal notranslate"><span class="pre">.order_by</span></code> method finally allows for sorting the results according to some criterion:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span>
|
||||
<span class="normal">9</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Count</span>
|
||||
<span class="kn">from</span> <span class="nn">typeclasses.rooms</span> <span class="kn">import</span> <span class="n">Room</span>
|
||||
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="p">(</span>
|
||||
|
|
@ -447,7 +395,7 @@ The <code class="docutils literal notranslate"><span class="pre">.order_by</span
|
|||
<span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s1">'-tagcount'</span><span class="p">))</span>
|
||||
<span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s1">'db_tags__db_key'</span><span class="p">,</span> <span class="s2">"tagcount"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Here we fetch all Characters who …</p>
|
||||
<ul class="simple">
|
||||
<li><p>… has a tag of category “organization” on them</p></li>
|
||||
|
|
@ -461,8 +409,8 @@ and how many matches we found for that organization.</p></li>
|
|||
<p>The result queryset will be a list of tuples ordered in descending order by the number of matches,
|
||||
in a format like the following:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span>
|
||||
<span class="p">(</span><span class="s1">'Griatch'</span><span class="n">s</span> <span class="n">poets</span> <span class="n">society</span><span class="s1">', 3872), </span>
|
||||
<span class="p">(</span><span class="s2">"Chainsol's Ainneve Testers"</span><span class="p">,</span> <span class="mi">2076</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s1">'Griatch'</span><span class="n">s</span> <span class="n">poets</span> <span class="n">society</span><span class="s1">', 3872),</span>
|
||||
<span class="p">(</span><span class="s2">"Chainsol's Ainneve Testers"</span><span class="p">,</span> <span class="mi">2076</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"Blaufeuer's Whitespace Fixers"</span><span class="p">,</span> <span class="mi">1903</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"Volund's Bikeshed Design Crew"</span><span class="p">,</span> <span class="mi">1764</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"Tehom's Glorious Misanthropes"</span><span class="p">,</span> <span class="mi">1763</span><span class="p">)</span>
|
||||
|
|
@ -539,7 +487,7 @@ to understand how to plan what our tutorial game will be about.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Django-queries.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,14 +49,16 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="overview-of-the-evennia-library">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="overview-of-the-evennia-library">
|
||||
<h1>Overview of the Evennia library<a class="headerlink" href="#overview-of-the-evennia-library" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">API</p>
|
||||
<p>API stands for <cite>Application Programming Interface</cite>, a description for how to access
|
||||
the resources of a program or library.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>API stands for `Application Programming Interface`, a description for how to access
|
||||
the resources of a program or library.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>A good place to start exploring Evennia is the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc">Evenia-API frontpage</span></a>.
|
||||
<p>A good place to start exploring Evennia is the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">Evenia-API frontpage</span></a>.
|
||||
This page sums up the main components of Evennia with a short description of each. Try clicking through
|
||||
to a few entries - once you get deep enough you’ll see full descriptions
|
||||
of each component along with their documentation. You can also click <code class="docutils literal notranslate"><span class="pre">[source]</span></code> to see the full Python source
|
||||
|
|
@ -63,101 +67,105 @@ for each thing.</p>
|
|||
what you can download from us. The github repo is also searchable.</p>
|
||||
<p>Finally, you can clone the evennia repo to your own computer and read the sources locally. This is necessary
|
||||
if you want to help with Evennia’s development itself. See the
|
||||
<a class="reference internal" href="../../../Setup/Extended-Installation.html"><span class="doc">extended install instructions</span></a> if you want to do this.</p>
|
||||
<a class="reference internal" href="../../../Setup/Extended-Installation.html"><span class="doc std std-doc">extended install instructions</span></a> if you want to do this.</p>
|
||||
<section id="where-is-it">
|
||||
<h2>Where is it?<a class="headerlink" href="#where-is-it" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If Evennia is installed, you can import from it simply with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">some_module</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.some_module.other_module</span> <span class="kn">import</span> <span class="n">SomeClass</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>import evennia
|
||||
from evennia import some_module
|
||||
from evennia.some_module.other_module import SomeClass
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>and so on.</p>
|
||||
<p>If you installed Evennia with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span></code>, the library folder will be installed deep inside your Python
|
||||
installation. If you cloned the repo there will be a folder <code class="docutils literal notranslate"><span class="pre">evennia</span></code> on your hard drive there.</p>
|
||||
<p>If you cloned the repo or read the code on <code class="docutils literal notranslate"><span class="pre">github</span></code> you’ll find this being the outermost structure:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span><span class="o">/</span>
|
||||
<span class="nb">bin</span><span class="o">/</span>
|
||||
<span class="n">CHANGELOG</span><span class="o">.</span><span class="n">md</span>
|
||||
<span class="o">...</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">docs</span><span class="o">/</span>
|
||||
<span class="n">evennia</span><span class="o">/</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia/
|
||||
bin/
|
||||
CHANGELOG.md
|
||||
...
|
||||
...
|
||||
docs/
|
||||
evennia/
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This outer layer is for Evennia’s installation and package distribution. That internal folder <code class="docutils literal notranslate"><span class="pre">evennia/evennia/</span></code> is
|
||||
the <em>actual</em> library, the thing covered by the API auto-docs and what you get when you do <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">evennia</span></code>.</p>
|
||||
<blockquote>
|
||||
<div><p>The <code class="docutils literal notranslate"><span class="pre">evennia/docs/</span></code> folder contains the sources for this documentation. See
|
||||
<a class="reference internal" href="../../../Contributing-Docs.html"><span class="doc">contributing to the docs</span></a> if you want to learn more about how this works.</p>
|
||||
<a class="reference internal" href="../../../Contributing-Docs.html"><span class="doc std std-doc">contributing to the docs</span></a> if you want to learn more about how this works.</p>
|
||||
</div></blockquote>
|
||||
<p>This the the structure of the Evennia library:</p>
|
||||
<ul class="simple">
|
||||
<li><p>evennia</p>
|
||||
<ul>
|
||||
<li><p><a class="reference external" href="../../../Evennia-API#shortcuts"><code class="docutils literal notranslate"><span class="pre">__init__.py</span></code></a> - The “flat API” of Evennia resides here.</p></li>
|
||||
<li><p><a class="reference external" href="../../../Components/Server-Conf#Settings-file"><code class="docutils literal notranslate"><span class="pre">settings_default.py</span></code></a> - Root settings of Evennia. Copy settings
|
||||
<li><p><a class="reference internal" href="../../../Evennia-API.html#shortcuts"><span class="std std-doc"><code class="docutils literal notranslate"><span class="pre">__init__.py</span></code></span></a> - The “flat API” of Evennia resides here.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Setup/Server-Conf.html#settings-file"><span class="std std-doc"><code class="docutils literal notranslate"><span class="pre">settings_default.py</span></code></span></a> - Root settings of Evennia. Copy settings
|
||||
from here to <code class="docutils literal notranslate"><span class="pre">mygame/server/settings.py</span></code> file.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Commands.html"><span class="doc">commands/</span></a> - The command parser and handler.</p>
|
||||
<li><p><a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">commands/</span></code></span></a> - The command parser and handler.</p>
|
||||
<ul>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">default/</span></code> - The <a class="reference external" href="../../../api/evennia.commands.default.html#modules">default commands</a> and cmdsets.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">default/</span></code> - The <a class="reference internal" href="../../../Components/Default-Commands.html"><span class="doc std std-doc">default commands</span></a> and cmdsets.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Communications.html"><span class="doc">comms/</span></a> - Systems for communicating in-game.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Communications.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">comms/</span></code></span></a> - Systems for communicating in-game.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">contrib/</span></code> - Optional plugins too game-specific for core Evennia.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">game_template/</span></code> - Copied to become the “game directory” when using <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">--init</span></code>.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Help-System.html"><span class="doc">help/</span></a> - Handles the storage and creation of help entries.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">locale/</span></code> - Language files (<a class="reference internal" href="../../../Concepts/Internationalization.html"><span class="doc">i18n</span></a>).</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Locks.html"><span class="doc">locks/</span></a> - Lock system for restricting access to in-game entities.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Objects.html"><span class="doc">objects/</span></a> - In-game entities (all types of items and Characters).</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc">prototypes/</span></a> - Object Prototype/spawning system and OLC menu</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Accounts.html"><span class="doc">accounts/</span></a> - Out-of-game Session-controlled entities (accounts, bots etc)</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">scripts/</span></a> - Out-of-game entities equivalence to Objects, also with timer support.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Portal-And-Server.html"><span class="doc">server/</span></a> - Core server code and Session handling.</p>
|
||||
<li><p><a class="reference internal" href="../../../Components/Help-System.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">help/</span></code></span></a> - Handles the storage and creation of help entries.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">locale/</span></code> - Language files (<a class="reference internal" href="../../../Concepts/Internationalization.html"><span class="doc std std-doc">i18n</span></a>).</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Locks.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">locks/</span></code></span></a> - Lock system for restricting access to in-game entities.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Objects.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">objects/</span></code></span></a> - In-game entities (all types of items and Characters).</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">prototypes/</span></code></span></a> - Object Prototype/spawning system and OLC menu</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Accounts.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">accounts/</span></code></span></a> - Out-of-game Session-controlled entities (accounts, bots etc)</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">scripts/</span></code></span></a> - Out-of-game entities equivalence to Objects, also with timer support.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Portal-And-Server.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">server/</span></code></span></a> - Core server code and Session handling.</p>
|
||||
<ul>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">portal/</span></code> - Portal proxy and connection protocols.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc">typeclasses/</span></a> - Abstract classes for the typeclass storage and database system.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Coding-Utils.html"><span class="doc">utils/</span></a> - Various miscellaneous useful coding resources.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Concepts/Web-Features.html"><span class="doc">web/</span></a> - Web resources and webserver. Partly copied into game directory on initialization.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">typeclasses/</span></code></span></a> - Abstract classes for the typeclass storage and database system.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Coding-Utils.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">utils/</span></code></span></a> - Various miscellaneous useful coding resources.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Concepts/Web-Features.html"><span class="doc std std-doc"><code class="docutils literal notranslate"><span class="pre">web/</span></code></span></a> - Web resources and webserver. Partly copied into game directory on initialization.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">__init__.py</p>
|
||||
<p>The <cite>__init__.py</cite> file is a special Python filename used to represent a Python ‘package’.
|
||||
When you import <cite>evennia</cite> on its own, you import this file. When you do <cite>evennia.foo</cite> Python will
|
||||
first look for a property <cite>.foo</cite> in <cite>__init__.py</cite> and then for a module or folder of that name
|
||||
in the same location.</p>
|
||||
<p class="sidebar-title"><strong>init</strong>.py</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The `__init__.py` file is a special Python filename used to represent a Python 'package'.
|
||||
When you import `evennia` on its own, you import this file. When you do `evennia.foo` Python will
|
||||
first look for a property `.foo` in `__init__.py` and then for a module or folder of that name
|
||||
in the same location.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>While all the actual Evennia code is found in the various folders, the <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> represents the entire
|
||||
package <code class="docutils literal notranslate"><span class="pre">evennia</span></code>. It contains “shortcuts” to code that is actually located elsewhere. Most of these shortcuts
|
||||
are listed if you <a class="reference internal" href="../../../Evennia-API.html"><span class="doc">scroll down a bit</span></a> on the Evennia-API page.</p>
|
||||
are listed if you <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">scroll down a bit</span></a> on the Evennia-API page.</p>
|
||||
</section>
|
||||
<section id="an-example-of-exploring-the-library">
|
||||
<h2>An example of exploring the library<a class="headerlink" href="#an-example-of-exploring-the-library" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In the previous lesson we took a brief look at <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects</span></code> as an example of a Python module. Let’s
|
||||
open it again. Inside is the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class, which inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>.
|
||||
Near the top of the module is this line:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from evennia import DefaultObject
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We want to figure out just what this DefaultObject offers. Since this is imported directly from <code class="docutils literal notranslate"><span class="pre">evennia</span></code>, we
|
||||
are actually importing from <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code>.</p>
|
||||
<p><a class="reference external" href="Howto/Starting/Part1/evennia/__init__.py#L189">Look at Line 189</a> of <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> and you’ll find this line:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
|
||||
<p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/__init__.py#159">Look at Line 159</a> of <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> and you’ll find this line:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from .objects.objects import DefaultObject
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Relative and absolute imports</p>
|
||||
<p>The first full-stop in <cite>from .objects.objects …</cite> means that
|
||||
we are importing from the current location. This is called a <cite>relative import</cite>.
|
||||
By comparison, <cite>from evennia.objects.objects</cite> is an <cite>absolute import</cite>. In this particular
|
||||
case, the two would give the same result.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The first full-stop in `from .objects.objects ...` means that
|
||||
we are importing from the current location. This is called a `relative import`.
|
||||
By comparison, `from evennia.objects.objects` is an `absolute import`. In this particular
|
||||
case, the two would give the same result.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<blockquote>
|
||||
<div><p>You can also look at <a class="reference external" href="Evennia-API.html#typeclasses">the right section of the API frontpage</a> and click through
|
||||
<div><p>You can also look at <a class="reference internal" href="../../../Evennia-API.html#typeclasses"><span class="std std-doc">the right section of the API frontpage</span></a> and click through
|
||||
to the code that way.</p>
|
||||
</div></blockquote>
|
||||
<p>The fact that <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> is imported into <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> here is what makes it possible to also import
|
||||
|
|
@ -165,12 +173,11 @@ it as <code class="docutils literal notranslate"><span class="pre">from</span> <
|
|||
<p>So to find the code for <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> we need to look in <code class="docutils literal notranslate"><span class="pre">evennia/objects/objects.py</span></code>. Here’s how
|
||||
to look it up in the docs:</p>
|
||||
<ol class="simple">
|
||||
<li><p>Open the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc">API frontpage</span></a></p></li>
|
||||
<li><p>Locate the link to <a class="reference external" href="../../../api/evennia.objects.html">evennia.objects</a> and click on it.</p></li>
|
||||
<li><p>Click through to <a class="reference external" href="../../../api/evennia.objects.objects.html">evennia.objects.objects</a>.</p></li>
|
||||
<li><p>You are now in the python module. Scroll down (or search in your web browser) to find the <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> class.</p></li>
|
||||
<li><p>You can now read what this does and what methods are on it. If you want to see the full source, click the
|
||||
[<a class="reference external" href="../../../_modules/evennia/objects/objects.html#DefaultObject">source</a>] link.</p></li>
|
||||
<li><p>Open the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">API frontpage</span></a></p></li>
|
||||
<li><p>Locate the link to <a class="reference internal" href="../../../api/evennia.objects.objects.html#evennia-objects-objects"><span class="std std-ref">evennia.objects.objects</span></a> and click on it.
|
||||
3 You are now in the python module. Scroll down (or search in your web browser) to find the <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> class.
|
||||
4 You can now read what this does and what methods are on it. If you want to see the full source, click the
|
||||
[source] link next to it.</p></li>
|
||||
</ol>
|
||||
</section>
|
||||
</section>
|
||||
|
|
@ -230,7 +237,7 @@ to look it up in the docs:</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Evennia-Library-Overview.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="overview-of-your-new-game-dir">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="overview-of-your-new-game-dir">
|
||||
<h1>Overview of your new Game Dir<a class="headerlink" href="#overview-of-your-new-game-dir" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Next we will take a little detour to look at the <em>Tutorial World</em>. This is a little solo adventure
|
||||
that comes with Evennia, a showcase for some of the things that are possible.</p>
|
||||
|
|
@ -64,15 +66,18 @@ Python package management).</p>
|
|||
“python paths”, such as</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Python-paths</p>
|
||||
<p>A ‘python path’ uses ‘.’ instead of ‘/’ or ‘<cite>\</cite>’ and
|
||||
skips the <cite>.py</cite> ending of files. It can also point to
|
||||
the code contents of python files. Since Evennia is already
|
||||
looking for code in your game dir, your python paths can start
|
||||
from there.</p>
|
||||
<p>So a path <cite>/home/foo/devel/mygame/commands/command.py</cite>
|
||||
would translate to a Python-path <cite>commands.command</cite>.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>A 'python path' uses '.' instead of '/' or '`\\`' and
|
||||
skips the `.py` ending of files. It can also point to
|
||||
the code contents of python files. Since Evennia is already
|
||||
looking for code in your game dir, your python paths can start
|
||||
from there.
|
||||
|
||||
So a path `/home/foo/devel/mygame/commands/command.py`
|
||||
would translate to a Python-path `commands.command`.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">button</span><span class="p">:</span><span class="n">tutorial_examples</span><span class="o">.</span><span class="n">red_button</span><span class="o">.</span><span class="n">RedButton</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create/drop button:tutorial_examples.red_button.RedButton
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is a fundamental aspect of coding Evennia - <em>you create code and then you tell Evennia where that
|
||||
|
|
@ -110,13 +115,15 @@ to update Evennia’s default settings to point to the right places in the new s
|
|||
</div></blockquote>
|
||||
<section id="commands">
|
||||
<h2>commands/<a class="headerlink" href="#commands" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">commands/</span></code> folder holds Python modules related to creating and extending the <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Commands</span></a>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">commands/</span></code> folder holds Python modules related to creating and extending the <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a>
|
||||
of Evennia. These manifest in game like the server understanding input like <code class="docutils literal notranslate"><span class="pre">look</span></code> or <code class="docutils literal notranslate"><span class="pre">dig</span></code>.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Classes</p>
|
||||
<p>A <cite>class</cite> is template for creating object-instances of a particular type
|
||||
in Python. We will explain classes in more detail in the next
|
||||
<a class="reference external" href="Python-basic-tutorial-part-two">python overview</a>.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>A `class` is template for creating object-instances of a particular type
|
||||
in Python. We will explain classes in more detail in the next
|
||||
`python overview <Python-basic-tutorial-part-two>`_.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/commands/command.py">command.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">commands.command</span></code>) - this contain the
|
||||
|
|
@ -155,11 +162,11 @@ knows where they are and will read them to configure itself at startup.</p>
|
|||
are expected to copy&paste the changes you need from <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/default_settings.py">evennia/default_settings.py</a>.
|
||||
The default settings file is extensively documented. Importing/accessing the values in the settings
|
||||
file is done in a special way, like this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> from django.conf import settings
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To get to the setting <code class="docutils literal notranslate"><span class="pre">TELNET_PORT</span></code> in the settings file you’d then do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">telnet_port</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">TELNET_PORT</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> telnet_port = settings.TELNET_PORT
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You cannot assign to the settings file dynamically; you must change the <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> file directly to
|
||||
|
|
@ -203,28 +210,28 @@ to add them.</p></li>
|
|||
</section>
|
||||
<section id="typeclasses">
|
||||
<h3>typeclasses/<a class="headerlink" href="#typeclasses" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc">Typeclasses</span></a> of Evennia are Evennia-specific Python classes whose instances save themselves
|
||||
<p>The <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a> of Evennia are Evennia-specific Python classes whose instances save themselves
|
||||
to the database. This allows a Character to remain in the same place and your updated strength stat to still
|
||||
be the same after a server reboot.</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/accounts.py">accounts.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.accounts</span></code>) - An
|
||||
<a class="reference internal" href="../../../Components/Accounts.html"><span class="doc">Account</span></a> represents the player connecting to the game. It holds information like email,
|
||||
<a class="reference internal" href="../../../Components/Accounts.html"><span class="doc std std-doc">Account</span></a> represents the player connecting to the game. It holds information like email,
|
||||
password and other out-of-character details.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/channels.py">channels.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.channels</span></code>) -
|
||||
<a class="reference internal" href="../../../Components/Channels.html"><span class="doc">Channels</span></a> are used to manage in-game communication between players.</p></li>
|
||||
<a class="reference internal" href="../../../Components/Channels.html"><span class="doc std std-doc">Channels</span></a> are used to manage in-game communication between players.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/objects.py">objects.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.objects</span></code>) -
|
||||
<a class="reference internal" href="../../../Components/Objects.html"><span class="doc">Objects</span></a> represent all things having a location within the game world.</p></li>
|
||||
<a class="reference internal" href="../../../Components/Objects.html"><span class="doc std std-doc">Objects</span></a> represent all things having a location within the game world.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/characters.py">characters.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.characters</span></code>) -
|
||||
The <a class="reference external" href="Components/Objects.html#Characers">Character</a> is a subclass of Objects, controlled by Accounts - they are the player’s
|
||||
The <a class="reference internal" href="../../../Components/Objects.html#characters"><span class="std std-doc">Character</span></a> is a subclass of Objects, controlled by Accounts - they are the player’s
|
||||
avatars in the game world.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/rooms.py">rooms.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.rooms</span></code>) - A
|
||||
<a class="reference external" href="Components/Objects.html#Room">Room</a> is also a subclass of Object; describing discrete locations. While the traditional
|
||||
<a class="reference internal" href="../../../Components/Objects.html#rooms"><span class="std std-doc">Room</span></a> is also a subclass of Object; describing discrete locations. While the traditional
|
||||
term is ‘room’, such a location can be anything and on any scale that fits your game, from a forest glade,
|
||||
an entire planet or an actual dungeon room.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/exits.py">exits.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.exits</span></code>) -
|
||||
<a class="reference external" href="Components/Objects.html#Exit">Exits</a> is another subclass of Object. Exits link one Room to another.</p></li>
|
||||
<a class="reference internal" href="../../../Components/Objects.html#exits"><span class="std std-doc">Exits</span></a> is another subclass of Object. Exits link one Room to another.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/scripts.py">scripts.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.scripts</span></code>) -
|
||||
<a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Scripts</span></a> are ‘out-of-character’ objects. They have no location in-game and can serve as basis for
|
||||
<a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> are ‘out-of-character’ objects. They have no location in-game and can serve as basis for
|
||||
anything that needs database persistence, such as combat, weather, or economic systems. They also
|
||||
have the ability to execute code repeatedly, on a timer.</p></li>
|
||||
</ul>
|
||||
|
|
@ -256,8 +263,8 @@ people change and re-structure this in various ways to better fit their ideas.</
|
|||
<ul class="simple">
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/batch_cmds.ev">batch_cmds.ev</a> - This is an <code class="docutils literal notranslate"><span class="pre">.ev</span></code> file, which is essentially
|
||||
just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The
|
||||
<a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc">Tutorial World</span></a> was built with such a batch-file.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/prototypes.py">prototypes.py</a> - A <a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc">prototype</span></a> is a way
|
||||
<a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc std std-doc">Tutorial World</span></a> was built with such a batch-file.</p></li>
|
||||
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/prototypes.py">prototypes.py</a> - A <a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc std std-doc">prototype</span></a> is a way
|
||||
to easily vary objects without changing their base typeclass. For example, one could use prototypes to
|
||||
tell that Two goblins, while both of the class ‘Goblin’ (so they follow the same code logic), should have different
|
||||
equipment, stats and looks.</p></li>
|
||||
|
|
@ -328,7 +335,7 @@ equipment, stats and looks.</p></li>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Gamedir-Overview.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,40 +49,14 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="persistent-objects-and-typeclasses">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="persistent-objects-and-typeclasses">
|
||||
<h1>Persistent objects and typeclasses<a class="headerlink" href="#persistent-objects-and-typeclasses" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Now that we have learned a little about how to find things in the Evennia library, let’s use it.</p>
|
||||
<p>In the <a class="reference internal" href="Python-classes-and-objects.html"><span class="doc">Python classes and objects</span></a> lesson we created the dragons Fluffy, Cuddly
|
||||
<p>In the <a class="reference internal" href="Python-classes-and-objects.html"><span class="doc std std-doc">Python classes and objects</span></a> lesson we created the dragons Fluffy, Cuddly
|
||||
and Smaug and made them fly and breathe fire. So far our dragons are short-lived - whenever we <code class="docutils literal notranslate"><span class="pre">restart</span></code>
|
||||
the server or <code class="docutils literal notranslate"><span class="pre">quit()</span></code> out of python mode they are gone.</p>
|
||||
<p>This is what you should have in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code> so far:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
|
||||
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> This is a base class for Monsters.</span>
|
||||
|
|
@ -107,22 +83,14 @@ the server or <code class="docutils literal notranslate"><span class="pre">quit(
|
|||
<span class="sd"> Let our dragon breathe fire.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> breathes fire!"</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<section id="our-first-persistent-object">
|
||||
<h2>Our first persistent object<a class="headerlink" href="#our-first-persistent-object" title="Permalink to this headline">¶</a></h2>
|
||||
<p>At this point we should know enough to understand what is happening in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects.py</span></code>. Let’s
|
||||
open it:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<span class="sd">module docstring</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
|
||||
|
|
@ -133,7 +101,7 @@ open it:</p>
|
|||
<span class="sd"> """</span>
|
||||
<span class="k">pass</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>So we have a class <code class="docutils literal notranslate"><span class="pre">Object</span></code> that <em>inherits</em> from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, which we have imported from Evennia.
|
||||
The class itself doesn’t do anything (it just <code class="docutils literal notranslate"><span class="pre">pass</span></code>es) but that doesn’t mean it’s useless. As we’ve seen,
|
||||
it inherits all the functionality of its parent. It’s in fact an <em>exact replica</em> of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> right now.
|
||||
|
|
@ -141,37 +109,13 @@ If we knew what kind of methods and resources were available on <code class="doc
|
|||
change the way it works!</p>
|
||||
<blockquote>
|
||||
<div><p>Hint: We will get back to this, but to learn what resources an Evennia parent like <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> offers,
|
||||
easiest is to peek at its <a class="reference external" href="../../../api/evennia.objects.objects.html#DefaultObject">API documentation</a>. The docstring for
|
||||
easiest is to peek at its <a class="reference internal" href="../../../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">API documentation</span></a>. The docstring for
|
||||
the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class can also help.</p>
|
||||
</div></blockquote>
|
||||
<p>One thing that Evennia classes offers and which you don’t get with vanilla Python classes is <em>persistence</em>. As
|
||||
you’ve found, Fluffy, Cuddly and Smaug are gone once we reload the server. Let’s see if we can fix this.</p>
|
||||
<p>Go back to <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code>. Change it as follows:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></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">Monster</span><span class="p">(</span><span class="n">Object</span><span class="p">):</span>
|
||||
|
|
@ -196,8 +140,9 @@ you’ve found, Fluffy, Cuddly and Smaug are gone once we reload the server. Let
|
|||
<span class="sd"> Let our dragon breathe fire.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> breathes fire!"</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Don’t forget to save. We removed <code class="docutils literal notranslate"><span class="pre">Monster.__init__</span></code> and made <code class="docutils literal notranslate"><span class="pre">Monster</span></code> inherit from Evennia’s <code class="docutils literal notranslate"><span class="pre">Object</span></code> (which in turn
|
||||
inherits from Evennia’s <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, as we saw). By extension, this means that <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> also inherits
|
||||
from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, just from further away!</p>
|
||||
|
|
@ -206,12 +151,14 @@ from <code class="docutils literal notranslate"><span class="pre">DefaultObject<
|
|||
<p>First reload the server as usual. We will need to create the dragon a little differently this time:</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Keyword arguments</p>
|
||||
<p>Keyword arguments (like <cite>db_key=”Smaug”</cite>) is a way to
|
||||
name the input arguments to a function or method. They make
|
||||
things easier to read but also allows for conveniently setting
|
||||
defaults for values not given explicitly.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Keyword arguments (like `db_key="Smaug"`) is a way to
|
||||
name the input arguments to a function or method. They make
|
||||
things easier to read but also allows for conveniently setting
|
||||
defaults for values not given explicitly.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Dragon
|
||||
> smaug = Dragon(db_key="Smaug", db_location=here)
|
||||
> smaug.save()
|
||||
|
|
@ -222,14 +169,14 @@ The world trembles.
|
|||
</div>
|
||||
<p>Smaug works the same as before, but we created him differently: first we used
|
||||
<code class="docutils literal notranslate"><span class="pre">Dragon(db_key="Smaug",</span> <span class="pre">db_location=here)</span></code> to create the object, and then we used <code class="docutils literal notranslate"><span class="pre">smaug.save()</span></code> afterwards.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quit</span><span class="p">()</span>
|
||||
<span class="n">Python</span> <span class="n">Console</span> <span class="ow">is</span> <span class="n">closing</span><span class="o">.</span>
|
||||
<span class="o">></span> <span class="n">look</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quit()
|
||||
Python Console is closing.
|
||||
> look
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You should now see that Smaug <em>is in the room with you</em>. Woah!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">look</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> look
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><em>He’s still there</em>… What we just did was to create a new entry in the database for Smaug. We gave the object
|
||||
|
|
@ -237,7 +184,7 @@ its name (key) and set its location to our current location (remember that <code
|
|||
in the <code class="docutils literal notranslate"><span class="pre">py</span></code> command, you can’t use it elsewhere).</p>
|
||||
<p>To make use of Smaug in code we must first find him in the database. For an object in the current
|
||||
location we can easily do this in <code class="docutils literal notranslate"><span class="pre">py</span></code> by using <code class="docutils literal notranslate"><span class="pre">me.search()</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py smaug = me.search("Smaug") ; smaug.firebreath()
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py smaug = me.search("Smaug") ; smaug.firebreath()
|
||||
Smaug breathes fire!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -248,14 +195,14 @@ Smaug breathes fire!
|
|||
bound Python instances before. But you need to use <code class="docutils literal notranslate"><span class="pre">db_key</span></code> instead of <code class="docutils literal notranslate"><span class="pre">key</span></code> and you also have to
|
||||
remember to call <code class="docutils literal notranslate"><span class="pre">.save()</span></code> afterwards. Evennia has a helper function that is more common to use,
|
||||
called <code class="docutils literal notranslate"><span class="pre">create_object</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">fluffy</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="s1">'typeclases.monster.Monster'</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"Fluffy"</span><span class="p">,</span> <span class="n">location</span><span class="o">=</span><span class="n">here</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">look</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py fluffy = evennia.create_object('typeclases.monster.Monster', key="Fluffy", location=here)
|
||||
> look
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Boom, Fluffy should now be in the room with you, a little less scary than Smaug. You specify the
|
||||
python-path to the code you want and then set the key and location. Evennia sets things up and saves for you.</p>
|
||||
<p>If you want to find Fluffy from anywhere, you can use Evennia’s <code class="docutils literal notranslate"><span class="pre">search_object</span></code> helper:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> fluffy = evennia.search_object("Fluffy")[0] ; fluffy.move_around()
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> fluffy = evennia.search_object("Fluffy")[0] ; fluffy.move_around()
|
||||
Fluffy is moving!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -268,13 +215,13 @@ multiple Fluffies we could get the second one with <code class="docutils literal
|
|||
<section id="creating-using-create-command">
|
||||
<h3>Creating using create-command<a class="headerlink" href="#creating-using-create-command" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Finally, you can also create a new Dragon using the familiar builder-commands we explored a few lessons ago:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">Cuddly</span><span class="p">:</span><span class="n">typeclasses</span><span class="o">.</span><span class="n">monsters</span><span class="o">.</span><span class="n">Monster</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> create/drop Cuddly:typeclasses.monsters.Monster
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Cuddly is now in the room. After learning about how objects are created you’ll realize that all this command really
|
||||
does is to parse your input, figure out that <code class="docutils literal notranslate"><span class="pre">/drop</span></code> means to “give the object the same location as the caller”,
|
||||
and then do a call akin to</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="s2">"typeclasses.monsters.Monster"</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"Cuddly"</span><span class="p">,</span> <span class="n">location</span><span class="o">=</span><span class="n">here</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia.create_object("typeclasses.monsters.Monster", key="Cuddly", location=here)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>That’s pretty much all there is to the mighty <code class="docutils literal notranslate"><span class="pre">create</span></code> command! The rest is just parsing for the command
|
||||
|
|
@ -325,31 +272,31 @@ own modules and import the base class.</p>
|
|||
<section id="examining-and-defaults">
|
||||
<h3>Examining and defaults<a class="headerlink" href="#examining-and-defaults" title="Permalink to this headline">¶</a></h3>
|
||||
<p>When you do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">giantess</span><span class="p">:</span><span class="n">typeclasses</span><span class="o">.</span><span class="n">monsters</span><span class="o">.</span><span class="n">Monster</span>
|
||||
<span class="n">You</span> <span class="n">create</span> <span class="n">a</span> <span class="n">new</span> <span class="n">Monster</span><span class="p">:</span> <span class="n">giantess</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> create/drop giantess:typeclasses.monsters.Monster
|
||||
You create a new Monster: giantess.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">evennia</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="s2">"typeclasses.monsters.Monster"</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"Giantess"</span><span class="p">,</span> <span class="n">location</span><span class="o">=</span><span class="n">here</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py evennia.create_object("typeclasses.monsters.Monster", key="Giantess", location=here)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You are specifying exactly which typeclass you want to use to build the Giantess. Let’s examine the result:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">examine</span> <span class="n">giantess</span>
|
||||
<span class="o">-------------------------------------------------------------------------------</span>
|
||||
<span class="n">Name</span><span class="o">/</span><span class="n">key</span><span class="p">:</span> <span class="n">Giantess</span> <span class="p">(</span><span class="c1">#14)</span>
|
||||
<span class="n">Typeclass</span><span class="p">:</span> <span class="n">Monster</span> <span class="p">(</span><span class="n">typeclasses</span><span class="o">.</span><span class="n">monsters</span><span class="o">.</span><span class="n">Monster</span><span class="p">)</span>
|
||||
<span class="n">Location</span><span class="p">:</span> <span class="n">Limbo</span> <span class="p">(</span><span class="c1">#2)</span>
|
||||
<span class="n">Home</span><span class="p">:</span> <span class="n">Limbo</span> <span class="p">(</span><span class="c1">#2)</span>
|
||||
<span class="n">Permissions</span><span class="p">:</span> <span class="o"><</span><span class="kc">None</span><span class="o">></span>
|
||||
<span class="n">Locks</span><span class="p">:</span> <span class="n">call</span><span class="p">:</span><span class="n">true</span><span class="p">();</span> <span class="n">control</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">);</span> <span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">);</span>
|
||||
<span class="n">drop</span><span class="p">:</span><span class="n">holds</span><span class="p">();</span> <span class="n">edit</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">);</span> <span class="n">examine</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Builder</span><span class="p">);</span> <span class="n">get</span><span class="p">:</span><span class="nb">all</span><span class="p">();</span>
|
||||
<span class="n">puppet</span><span class="p">:</span><span class="n">pperm</span><span class="p">(</span><span class="n">Developer</span><span class="p">);</span> <span class="n">tell</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">);</span> <span class="n">view</span><span class="p">:</span><span class="nb">all</span><span class="p">()</span>
|
||||
<span class="n">Persistent</span> <span class="n">attributes</span><span class="p">:</span>
|
||||
<span class="n">desc</span> <span class="o">=</span> <span class="n">You</span> <span class="n">see</span> <span class="n">nothing</span> <span class="n">special</span><span class="o">.</span>
|
||||
<span class="o">-------------------------------------------------------------------------------</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> examine giantess
|
||||
-------------------------------------------------------------------------------
|
||||
Name/key: Giantess (#14)
|
||||
Typeclass: Monster (typeclasses.monsters.Monster)
|
||||
Location: Limbo (#2)
|
||||
Home: Limbo (#2)
|
||||
Permissions: <None>
|
||||
Locks: call:true(); control:id(1) or perm(Admin); delete:id(1) or perm(Admin);
|
||||
drop:holds(); edit:perm(Admin); examine:perm(Builder); get:all();
|
||||
puppet:pperm(Developer); tell:perm(Admin); view:all()
|
||||
Persistent attributes:
|
||||
desc = You see nothing special.
|
||||
-------------------------------------------------------------------------------
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We used the <code class="docutils literal notranslate"><span class="pre">examine</span></code> command briefly in the <a class="reference internal" href="Building-Quickstart.html"><span class="doc">lesson about building in-game</span></a>. Now these lines
|
||||
<p>We used the <code class="docutils literal notranslate"><span class="pre">examine</span></code> command briefly in the <a class="reference internal" href="Building-Quickstart.html"><span class="doc std std-doc">lesson about building in-game</span></a>. Now these lines
|
||||
may be more useful to us:</p>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Name/key</strong> - The name of this thing. The value <code class="docutils literal notranslate"><span class="pre">(#14)</span></code> is probably different for you. This is the
|
||||
|
|
@ -368,20 +315,20 @@ to those in the next section.</p></li>
|
|||
<p>Note how the <strong>Typeclass</strong> line describes exactly where to find the code of this object? This is very useful for
|
||||
understanding how any object in Evennia works.</p>
|
||||
<p>What happens if we <em>don’t</em> specify the typeclass though?</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">box</span>
|
||||
<span class="n">You</span> <span class="n">create</span> <span class="n">a</span> <span class="n">new</span> <span class="n">Object</span><span class="p">:</span> <span class="n">box</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> create/drop box
|
||||
You create a new Object: box.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"box"</span><span class="p">,</span> <span class="n">location</span><span class="o">=</span><span class="n">here</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py create.create_object(None, key="box", location=here)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now check it out:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">examine</span> <span class="n">box</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> examine box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will find that the <strong>Typeclass</strong> line now reads</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Typeclass</span><span class="p">:</span> <span class="n">Object</span> <span class="p">(</span><span class="n">typeclasses</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">Object</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Typeclass: Object (typeclasses.objects.Object)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>So when you didn’t specify a typeclass, Evennia used a default, more specifically the (so far) empty <code class="docutils literal notranslate"><span class="pre">Object</span></code> class in
|
||||
|
|
@ -392,10 +339,12 @@ in <a class="reference external" href="https://github.com/evennia/evennia/blob/m
|
|||
with the name <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code>, which is set to <code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Changing things</p>
|
||||
<p>While it’s tempting to change folders around to your liking, this can
|
||||
make it harder to follow tutorials and may confuse if
|
||||
you are asking others for help. So don’t overdo it unless you really
|
||||
know what you are doing.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>While it's tempting to change folders around to your liking, this can
|
||||
make it harder to follow tutorials and may confuse if
|
||||
you are asking others for help. So don't overdo it unless you really
|
||||
know what you are doing.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>So if you wanted the creation commands and methods to default to some other class you could
|
||||
add your own <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code> line to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>. The same is true for all the other
|
||||
|
|
@ -406,16 +355,7 @@ layout of your game dir considerably if you wanted. You just need to tell Evenni
|
|||
<section id="modifying-ourselves">
|
||||
<h2>Modifying ourselves<a class="headerlink" href="#modifying-ourselves" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Let’s try to modify ourselves a little. Open up <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<span class="sd">(module docstring)</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
|
@ -426,34 +366,34 @@ layout of your game dir considerably if you wanted. You just need to tell Evenni
|
|||
<span class="sd"> """</span>
|
||||
<span class="k">pass</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This looks quite familiar now - an empty class inheriting from the Evennia base typeclass. As you would expect,
|
||||
this is also the default typeclass used for creating Characters if you don’t specify it. You can verify it:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">examine</span> <span class="n">me</span>
|
||||
<span class="o">------------------------------------------------------------------------------</span>
|
||||
<span class="n">Name</span><span class="o">/</span><span class="n">key</span><span class="p">:</span> <span class="n">YourName</span> <span class="p">(</span><span class="c1">#1)</span>
|
||||
<span class="n">Session</span> <span class="nb">id</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="c1">#1</span>
|
||||
<span class="n">Account</span><span class="p">:</span> <span class="n">YourName</span>
|
||||
<span class="n">Account</span> <span class="n">Perms</span><span class="p">:</span> <span class="o"><</span><span class="n">Superuser</span><span class="o">></span> <span class="p">(</span><span class="n">quelled</span><span class="p">)</span>
|
||||
<span class="n">Typeclass</span><span class="p">:</span> <span class="n">Character</span> <span class="p">(</span><span class="n">typeclasses</span><span class="o">.</span><span class="n">characters</span><span class="o">.</span><span class="n">Character</span><span class="p">)</span>
|
||||
<span class="n">Location</span><span class="p">:</span> <span class="n">Limbo</span> <span class="p">(</span><span class="c1">#2)</span>
|
||||
<span class="n">Home</span><span class="p">:</span> <span class="n">Limbo</span> <span class="p">(</span><span class="c1">#2)</span>
|
||||
<span class="n">Permissions</span><span class="p">:</span> <span class="n">developer</span><span class="p">,</span> <span class="n">player</span>
|
||||
<span class="n">Locks</span><span class="p">:</span> <span class="n">boot</span><span class="p">:</span><span class="n">false</span><span class="p">();</span> <span class="n">call</span><span class="p">:</span><span class="n">false</span><span class="p">();</span> <span class="n">control</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Developer</span><span class="p">);</span> <span class="n">delete</span><span class="p">:</span><span class="n">false</span><span class="p">();</span>
|
||||
<span class="n">drop</span><span class="p">:</span><span class="n">holds</span><span class="p">();</span> <span class="n">edit</span><span class="p">:</span><span class="n">false</span><span class="p">();</span> <span class="n">examine</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Developer</span><span class="p">);</span> <span class="n">get</span><span class="p">:</span><span class="n">false</span><span class="p">();</span>
|
||||
<span class="n">msg</span><span class="p">:</span><span class="nb">all</span><span class="p">();</span> <span class="n">puppet</span><span class="p">:</span><span class="n">false</span><span class="p">();</span> <span class="n">tell</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">);</span> <span class="n">view</span><span class="p">:</span><span class="nb">all</span><span class="p">()</span>
|
||||
<span class="n">Stored</span> <span class="n">Cmdset</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="n">commands</span><span class="o">.</span><span class="n">default_cmdsets</span><span class="o">.</span><span class="n">CharacterCmdSet</span> <span class="p">[</span><span class="n">DefaultCharacter</span><span class="p">]</span> <span class="p">(</span><span class="n">Union</span><span class="p">,</span> <span class="n">prio</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="n">Merged</span> <span class="n">Cmdset</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">Commands</span> <span class="n">available</span> <span class="n">to</span> <span class="n">YourName</span> <span class="p">(</span><span class="n">result</span> <span class="n">of</span> <span class="n">Merged</span> <span class="n">CmdSets</span><span class="p">):</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">Persistent</span> <span class="n">attributes</span><span class="p">:</span>
|
||||
<span class="n">desc</span> <span class="o">=</span> <span class="n">This</span> <span class="ow">is</span> <span class="n">User</span> <span class="c1">#1.</span>
|
||||
<span class="n">prelogout_location</span> <span class="o">=</span> <span class="n">Limbo</span>
|
||||
<span class="n">Non</span><span class="o">-</span><span class="n">Persistent</span> <span class="n">attributes</span><span class="p">:</span>
|
||||
<span class="n">last_cmd</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="o">------------------------------------------------------------------------------</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> examine me
|
||||
------------------------------------------------------------------------------
|
||||
Name/key: YourName (#1)
|
||||
Session id(s): #1
|
||||
Account: YourName
|
||||
Account Perms: <Superuser> (quelled)
|
||||
Typeclass: Character (typeclasses.characters.Character)
|
||||
Location: Limbo (#2)
|
||||
Home: Limbo (#2)
|
||||
Permissions: developer, player
|
||||
Locks: boot:false(); call:false(); control:perm(Developer); delete:false();
|
||||
drop:holds(); edit:false(); examine:perm(Developer); get:false();
|
||||
msg:all(); puppet:false(); tell:perm(Admin); view:all()
|
||||
Stored Cmdset(s):
|
||||
commands.default_cmdsets.CharacterCmdSet [DefaultCharacter] (Union, prio 0)
|
||||
Merged Cmdset(s):
|
||||
...
|
||||
Commands available to YourName (result of Merged CmdSets):
|
||||
...
|
||||
Persistent attributes:
|
||||
desc = This is User #1.
|
||||
prelogout_location = Limbo
|
||||
Non-Persistent attributes:
|
||||
last_cmd = None
|
||||
------------------------------------------------------------------------------
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You got a lot longer output this time. You have a lot more going on than a simple Object. Here are some new fields of note:</p>
|
||||
|
|
@ -461,7 +401,7 @@ this is also the default typeclass used for creating Characters if you don’t s
|
|||
<li><p><strong>Session id(s)</strong>: This identifies the <em>Session</em> (that is, the individual connection to a player’s game client).</p></li>
|
||||
<li><p><strong>Account</strong> shows, well the <code class="docutils literal notranslate"><span class="pre">Account</span></code> object associated with this Character and Session.</p></li>
|
||||
<li><p><strong>Stored/Merged Cmdsets</strong> and <strong>Commands available</strong> is related to which <em>Commands</em> are stored on you. We will
|
||||
get to them in the <a class="reference internal" href="Adding-Commands.html"><span class="doc">next lesson</span></a>. For now it’s enough to know these consitute all the
|
||||
get to them in the <a class="reference internal" href="Adding-Commands.html"><span class="doc std std-doc">next lesson</span></a>. For now it’s enough to know these consitute all the
|
||||
commands available to you at a given moment.</p></li>
|
||||
<li><p><strong>Non-Persistent attributes</strong> are Attributes that are only stored temporarily and will go away on next reload.</p></li>
|
||||
</ul>
|
||||
|
|
@ -470,21 +410,7 @@ So if we modify this class we’ll also modify ourselves.</p>
|
|||
<section id="a-method-on-ourselves">
|
||||
<h3>A method on ourselves<a class="headerlink" href="#a-method-on-ourselves" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Let’s try something simple first. Back in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<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="sd">"""</span>
|
||||
<span class="sd"> (class docstring)</span>
|
||||
|
|
@ -499,49 +425,50 @@ So if we modify this class we’ll also modify ourselves.</p>
|
|||
<span class="sd"> Get the main stats of this character</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">dex</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">int</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
</div>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.get_stats()
|
||||
(10, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tuples and lists</p>
|
||||
<ul class="simple">
|
||||
<li><p>A <cite>list</cite> is written <cite>[a, b, c, d, …]</cite>. It can be modified after creation.</p></li>
|
||||
<li><p>A <cite>tuple</cite> is written <cite>(a, b, c, …)</cite>. It cannot be modified once created.</p></li>
|
||||
</ul>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>- A `list` is written `[a, b, c, d, ...]`. It can be modified after creation.
|
||||
- A `tuple` is written `(a, b, c, ...)`. It cannot be modified once created.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>We made a new method, gave it a docstring and had it <code class="docutils literal notranslate"><span class="pre">return</span></code> the RP-esque values we set. It comes back as a
|
||||
<em>tuple</em> <code class="docutils literal notranslate"><span class="pre">(10,</span> <span class="pre">12,</span> <span class="pre">15)</span></code>. To get a specific value you could specify the <em>index</em> of the value you want,
|
||||
starting from zero:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">stats</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span> <span class="p">;</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Strength is </span><span class="si">{</span><span class="n">stats</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
||||
<span class="n">Strength</span> <span class="ow">is</span> <span class="mf">10.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py stats = self.get_stats() ; print(f"Strength is {stats[0]}.")
|
||||
Strength is 10.
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="attributes">
|
||||
<h3>Attributes<a class="headerlink" href="#attributes" title="Permalink to this headline">¶</a></h3>
|
||||
<p>So what happens when we increase our strength? This would be one way:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span> <span class="o">+</span> <span class="mi">1</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span>
|
||||
<span class="mi">11</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.str = self.str + 1
|
||||
> py self.str
|
||||
11
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here we set the strength equal to its previous value + 1. A shorter way to write this is to use Python’s <code class="docutils literal notranslate"><span class="pre">+=</span></code>
|
||||
operator:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span> <span class="o">+=</span> <span class="mi">1</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span>
|
||||
<span class="mi">12</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.str += 1
|
||||
> py self.str
|
||||
12
|
||||
> py self.get_stats()
|
||||
(12, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This looks correct! Try to change the values for dex and int too; it works fine. However:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.get_stats()
|
||||
(10, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>After a reload all our changes were forgotten. When we change properties like this, it only changes in memory,
|
||||
|
|
@ -552,17 +479,7 @@ since we have the stats hardcoded in the class, <em>every</em> character instanc
|
|||
same <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">dex</span></code> and <code class="docutils literal notranslate"><span class="pre">int</span></code> now! This is clearly not what we want.</p>
|
||||
<p>Evennia offers a special, persistent type of property for this, called an <code class="docutils literal notranslate"><span class="pre">Attribute</span></code>. Rework your
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> like this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<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="sd">"""</span>
|
||||
<span class="sd"> (class docstring)</span>
|
||||
|
|
@ -574,47 +491,49 @@ same <code class="docutils literal notranslate"><span class="pre">str</span></co
|
|||
<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">str</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">dex</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">int</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Spaces in Attribute name?</p>
|
||||
<p>What if you want spaces in your Attribute name? Or you want to assign the
|
||||
name of the Attribute on-the fly? Then you can use <cite>.attributes.add(name, value)</cite> instead,
|
||||
for example <cite>self.attributes.add(“str”, 10)</cite>.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>What if you want spaces in your Attribute name? Or you want to assign the
|
||||
name of the Attribute on-the fly? Then you can use `.attributes.add(name, value)` instead,
|
||||
for example `self.attributes.add("str", 10)`.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>We removed the hard-coded stats and added added <code class="docutils literal notranslate"><span class="pre">.db</span></code> for every stat. The <code class="docutils literal notranslate"><span class="pre">.db</span></code> handler makes the stat
|
||||
into an an Evennia <code class="docutils literal notranslate"><span class="pre">Attribute</span></code>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</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>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.get_stats()
|
||||
(None, None, None)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Since we removed the hard-coded values, Evennia don’t know what they should be (yet). So all we get back
|
||||
is <code class="docutils literal notranslate"><span class="pre">None</span></code>, which is a Python reserved word to represent nothing, a no-value. This is different from a normal python
|
||||
property:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span>
|
||||
<span class="ne">AttributeError</span><span class="p">:</span> <span class="s1">'Character'</span> <span class="nb">object</span> <span class="n">has</span> <span class="n">no</span> <span class="n">attribute</span> <span class="s1">'str'</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</span>
|
||||
<span class="p">(</span><span class="n">nothing</span> <span class="n">will</span> <span class="n">be</span> <span class="n">displayed</span><span class="p">,</span> <span class="n">because</span> <span class="n">it</span><span class="s1">'s None)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.str
|
||||
AttributeError: 'Character' object has no attribute 'str'
|
||||
> py self.db.str
|
||||
(nothing will be displayed, because it's None)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Trying to get an unknown normal Python property will give an error. Getting an unknown Evennia <code class="docutils literal notranslate"><span class="pre">Attribute</span></code> will
|
||||
never give an error, but only result in <code class="docutils literal notranslate"><span class="pre">None</span></code> being returned. This is often very practical.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</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">dex</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">int</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.db.str, self.db.dex, self.db.int = 10, 12, 15
|
||||
> py self.get_stats()
|
||||
(10, 12, 15)
|
||||
> reload
|
||||
> py self.get_stats()
|
||||
(10, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now we set the Attributes to the right values. We can see that things work the same as before, also after a
|
||||
server reload. Let’s modify the strength:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</span> <span class="o">+=</span> <span class="mi">2</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.db.str += 2
|
||||
> py self.get_stats()
|
||||
(12, 12, 15)
|
||||
> reload
|
||||
> py self.get_stats()
|
||||
(12, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Our change now survives a reload since Evennia automatically saves the Attribute to the database for us.</p>
|
||||
|
|
@ -627,30 +546,15 @@ in more detail. For now, let’s give every new character some random stats to s
|
|||
<p>We want those stats to be set only once, when the object is first created. For the Character, this method
|
||||
is called <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">__init__ vs at_object_creation</p>
|
||||
<p>For the <cite>Monster</cite> class we used <cite>__init__</cite> to set up the class. We can’t use this
|
||||
<p class="sidebar-title"><strong>init</strong> vs at_object_creation</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>For the `Monster` class we used `__init__` to set up the class. We can't use this
|
||||
for a typeclass because it will be called more than once, at the very least after
|
||||
every reload and maybe more depending on caching. Even if you are familiar with Python,
|
||||
avoid touching <cite>__init__</cite> for typeclasses, the results will not be what you expect.</p>
|
||||
avoid touching `__init__` for typeclasses, the results will not be what you expect.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># up by the other imports</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># up by the other imports</span>
|
||||
<span class="kn">import</span> <span class="nn">random</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Character</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
|
|
@ -669,28 +573,28 @@ avoid touching <cite>__init__</cite> for typeclasses, the results will not be wh
|
|||
<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">str</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">dex</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">int</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>We imported a new module, <code class="docutils literal notranslate"><span class="pre">random</span></code>. This is part of Python’s standard library. We used <code class="docutils literal notranslate"><span class="pre">random.randint</span></code> to
|
||||
set a random value from 3 to 18 to each stat. Simple, but for some classical RPGs this is all you need!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py self.get_stats()
|
||||
(12, 12, 15)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Hm, this is the same values we set before. They are not random. The reason for this is of course that, as said,
|
||||
<code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> only runs <em>once</em>, the very first time a character is created. Our character object was already
|
||||
created long before, so it will not be called again.</p>
|
||||
<p>It’s simple enough to run it manually though:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">at_object_creation</span><span class="p">()</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</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">8</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> self.at_object_creation()
|
||||
> py self.get_stats()
|
||||
(5, 4, 8)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Lady luck didn’t smile on us for this example; maybe you’ll fare better. Evennia has a helper command
|
||||
<code class="docutils literal notranslate"><span class="pre">update</span></code> that re-runs the creation hook and also cleans up any other Attributes not re-created by <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">update</span> <span class="bp">self</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">14</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> update self
|
||||
> py self.get_stats()
|
||||
(8, 16, 14)
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -700,37 +604,39 @@ created long before, so it will not be called again.</p>
|
|||
before you create a lot of objects (characters in this case). But should it come to that you don’t want to have to
|
||||
go around and re-run the method on everyone manually. For the Python beginner, doing this will also give a chance to
|
||||
try out Python <em>loops</em>. We try them out in multi-line Python mode:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span>
|
||||
<span class="o">></span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"foo"</span><span class="p">]:</span> <span class="o">></span> <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
|
||||
<span class="mi">1</span>
|
||||
<span class="mi">2</span>
|
||||
<span class="n">foo</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> for a in [1, 2, "foo"]: > print(a)
|
||||
1
|
||||
2
|
||||
foo
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A python <em>for-loop</em> allows us to loop over something. Above, we made a <em>list</em> of two numbers and a string. In
|
||||
every iteration of the loop, the variable <code class="docutils literal notranslate"><span class="pre">a</span></code> becomes one element in turn, and we print that.</p>
|
||||
<p>For our list, we want to loop over all Characters, and want to call <code class="docutils literal notranslate"><span class="pre">.at_object_creation</span></code> on each. This is how
|
||||
this is done (still in python multi-line mode):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="kn">from</span> <span class="nn">typeclasses.characters</span> <span class="kn">import</span> <span class="n">Character</span>
|
||||
<span class="o">></span> <span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">Character</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="o">></span> <span class="n">char</span><span class="o">.</span><span class="n">at_object_creation</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> from typeclasses.characters import Character
|
||||
> for char in Character.objects.all()
|
||||
> char.at_object_creation()
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Database queries</p>
|
||||
<p><cite>Character.objects.all()</cite> is an example of a database query expressed in Python. This will be converted
|
||||
into a database query under the hood. This syntax is part of
|
||||
<a class="reference external" href="https://docs.djangoproject.com/en/3.0/topics/db/queries/">Django’s query language</a>. You don’t need to
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>`Character.objects.all()` is an example of a database query expressed in Python. This will be converted
|
||||
into a database query under the hood. This syntax is part of
|
||||
`Django's query language <https://docs.djangoproject.com/en/3.0/topics/db/queries/>`_. You don't need to
|
||||
know Django to use Evennia, but if you ever need more specific database queries, this is always available
|
||||
when you need it.</p>
|
||||
when you need it.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>We import the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class and then we use <code class="docutils literal notranslate"><span class="pre">.objects.all()</span></code> to get all <code class="docutils literal notranslate"><span class="pre">Character</span></code> instances. Simplified,
|
||||
<code class="docutils literal notranslate"><span class="pre">.objects</span></code> is a resource from which one can <em>query</em> for all <code class="docutils literal notranslate"><span class="pre">Characters</span></code>. Using <code class="docutils literal notranslate"><span class="pre">.all()</span></code> gets us a listing
|
||||
of all of them that we then immediately loop over. Boom, we just updated all Characters, including ourselves:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quit</span><span class="p">()</span>
|
||||
<span class="n">Closing</span> <span class="n">the</span> <span class="n">Python</span> <span class="n">console</span><span class="o">.</span>
|
||||
<span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">get_stats</span><span class="p">()</span>
|
||||
<span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quit()
|
||||
Closing the Python console.
|
||||
> self.get_stats()
|
||||
(3, 18, 10)
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -825,7 +731,7 @@ this tutorial. But that’s enough of them for now. It’s time to take some act
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Learning-Typeclasses.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="more-about-commands">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="more-about-commands">
|
||||
<h1>More about Commands<a class="headerlink" href="#more-about-commands" title="Permalink to this headline">¶</a></h1>
|
||||
<p>In this lesson we learn some basics about parsing the input of Commands. We will
|
||||
also learn how to add, modify and extend Evennia’s default commands.</p>
|
||||
|
|
@ -56,61 +58,19 @@ also learn how to add, modify and extend Evennia’s default commands.</p>
|
|||
<p>In the last lesson we made a <code class="docutils literal notranslate"><span class="pre">hit</span></code> Command and hit a dragon with it. You should have the code
|
||||
from that still around.</p>
|
||||
<p>Let’s expand our simple <code class="docutils literal notranslate"><span class="pre">hit</span></code> command to accept a little more complex input:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hit</span> <span class="o"><</span><span class="n">target</span><span class="o">></span> <span class="p">[[</span><span class="k">with</span><span class="p">]</span> <span class="o"><</span><span class="n">weapon</span><span class="o">></span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>hit <target> [[with] <weapon>]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>That is, we want to support all of these forms</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hit</span> <span class="n">target</span>
|
||||
<span class="n">hit</span> <span class="n">target</span> <span class="n">weapon</span>
|
||||
<span class="n">hit</span> <span class="n">target</span> <span class="k">with</span> <span class="n">weapon</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>hit target
|
||||
hit target weapon
|
||||
hit target with weapon
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you don’t specify a weapon you’ll use your fists. It’s also nice to be able to skip “with” if
|
||||
you are in a hurry. Time to modify <code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code> again. Let us break out the parsing
|
||||
a little, in a new method <code class="docutils literal notranslate"><span class="pre">parse</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">#...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdHit</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -153,18 +113,19 @@ a little, in a new method <code class="docutils literal notranslate"><span class
|
|||
<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="sa">f</span><span class="s2">"You hit </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> with </span><span class="si">{</span><span class="n">weaponstr</span><span class="si">}</span><span class="s2">!"</span><span class="p">)</span>
|
||||
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You got hit by </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> with </span><span class="si">{</span><span class="n">weaponstr</span><span class="si">}</span><span class="s2">!"</span><span class="p">)</span>
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">parse</span></code> method is called before <code class="docutils literal notranslate"><span class="pre">func</span></code> and has access to all the same on-command variables as in <code class="docutils literal notranslate"><span class="pre">func</span></code>. Using
|
||||
<code class="docutils literal notranslate"><span class="pre">parse</span></code> not only makes things a little easier to read, it also means you can easily let other Commands <em>inherit</em>
|
||||
your parsing - if you wanted some other Command to also understand input on the form <code class="docutils literal notranslate"><span class="pre"><arg></span> <span class="pre">with</span> <span class="pre"><arg></span></code> you’d inherit
|
||||
from this class and just implement the <code class="docutils literal notranslate"><span class="pre">func</span></code> needed for that command without implementing <code class="docutils literal notranslate"><span class="pre">parse</span></code> anew.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tuples and Lists</p>
|
||||
<ul class="simple">
|
||||
<li><p>A <cite>list</cite> is written as <cite>[a, b, c, d, …]</cite>. You can add and grow/shrink a list after it was first created.</p></li>
|
||||
<li><p>A <cite>tuple</cite> is written as <cite>(a, b, c, d, …)</cite>. A tuple cannot be modified once it is created.</p></li>
|
||||
</ul>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>- A `list` is written as `[a, b, c, d, ...]`. You can add and grow/shrink a list after it was first created.
|
||||
- A `tuple` is written as `(a, b, c, d, ...)`. A tuple cannot be modified once it is created.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<ul>
|
||||
<li><p><strong>Line 14</strong> - We do the stripping of <code class="docutils literal notranslate"><span class="pre">self.args</span></code> once and for all here. We also store the stripped version back
|
||||
|
|
@ -215,7 +176,7 @@ use this to create a <code class="docutils literal notranslate"><span class="pre
|
|||
<li><p><strong>Lines 41-42</strong> - We merge the <code class="docutils literal notranslate"><span class="pre">weaponstr</span></code> with our attack text.</p></li>
|
||||
</ul>
|
||||
<p>Let’s try it out!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> hit smaug with sword
|
||||
Could not find 'sword'.
|
||||
You hit smaug with bare fists!
|
||||
|
|
@ -224,13 +185,13 @@ You hit smaug with bare fists!
|
|||
<p>Oops, our <code class="docutils literal notranslate"><span class="pre">self.caller.search(self.weapon)</span></code> is telling us that it found no sword. Since we are not <code class="docutils literal notranslate"><span class="pre">return</span></code>ing
|
||||
in this situation (like we do if failing to find <code class="docutils literal notranslate"><span class="pre">target</span></code>) we still continue fighting with our bare hands.
|
||||
This won’t do. Let’s make ourselves a sword.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">create</span> <span class="n">sword</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> create sword
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Since we didn’t specify <code class="docutils literal notranslate"><span class="pre">/drop</span></code>, the sword will end up in our inventory and can seen with the <code class="docutils literal notranslate"><span class="pre">i</span></code> or
|
||||
<code class="docutils literal notranslate"><span class="pre">inventory</span></code> command. The <code class="docutils literal notranslate"><span class="pre">.search</span></code> helper will still find it there. There is no need to reload to see this
|
||||
change (no code changed, only stuff in the database).</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> hit smaug with sword
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hit smaug with sword
|
||||
You hit smaug with sword!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -238,49 +199,51 @@ You hit smaug with sword!
|
|||
<section id="adding-a-command-to-an-object">
|
||||
<h2>Adding a Command to an object<a class="headerlink" href="#adding-a-command-to-an-object" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The commands of a cmdset attached to an object with <code class="docutils literal notranslate"><span class="pre">obj.cmdset.add()</span></code> will by default be made available to that object
|
||||
but <em>also to those in the same location as that object</em>. If you did the <a class="reference internal" href="Building-Quickstart.html"><span class="doc">Building introduction</span></a>
|
||||
you’ve seen an example of this with the “Red Button” object. The <a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc">Tutorial world</span></a>
|
||||
but <em>also to those in the same location as that object</em>. If you did the <a class="reference internal" href="Building-Quickstart.html"><span class="doc std std-doc">Building introduction</span></a>
|
||||
you’ve seen an example of this with the “Red Button” object. The <a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc std std-doc">Tutorial world</span></a>
|
||||
also has many examples of objects with commands on them.</p>
|
||||
<p>To show how this could work, let’s put our ‘hit’ Command on our simple <code class="docutils literal notranslate"><span class="pre">sword</span></code> object from the previous section.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"sword"</span><span class="p">)</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"commands.mycommands.MyCmdSet"</span><span class="p">,</span> <span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> self.search("sword").cmdset.add("commands.mycommands.MyCmdSet", persistent=True)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We find the sword (it’s still in our inventory so <code class="docutils literal notranslate"><span class="pre">self.search</span></code> should be able to find it), then
|
||||
add <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code> to it. This actually adds both <code class="docutils literal notranslate"><span class="pre">hit</span></code> and <code class="docutils literal notranslate"><span class="pre">echo</span></code> to the sword, which is fine.</p>
|
||||
<p>Let’s try to swing it!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">hit</span>
|
||||
<span class="n">More</span> <span class="n">than</span> <span class="n">one</span> <span class="n">match</span> <span class="k">for</span> <span class="s1">'hit'</span> <span class="p">(</span><span class="n">please</span> <span class="n">narrow</span> <span class="n">target</span><span class="p">):</span>
|
||||
<span class="n">hit</span><span class="o">-</span><span class="mi">1</span> <span class="p">(</span><span class="n">sword</span> <span class="c1">#11)</span>
|
||||
<span class="n">hit</span><span class="o">-</span><span class="mi">2</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hit
|
||||
More than one match for 'hit' (please narrow target):
|
||||
hit-1 (sword #11)
|
||||
hit-2
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Multi-matches</p>
|
||||
<p>Some game engines will just pick the first hit when finding more than one.
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Some game engines will just pick the first hit when finding more than one.
|
||||
Evennia will always give you a choice. The reason for this is that Evennia
|
||||
cannot know if <cite>hit</cite> and <cite>hit</cite> are different or the same - maybe it behaves
|
||||
cannot know if `hit` and `hit` are different or the same - maybe it behaves
|
||||
differently depending on the object it sits on? Besides, imagine if you had
|
||||
a red and a blue button both with the command <cite>push</cite> on it. Now you just write
|
||||
<cite>push</cite>. Wouldn’t you prefer to be asked <cite>which</cite> button you really wanted to push?</p>
|
||||
a red and a blue button both with the command `push` on it. Now you just write
|
||||
`push`. Wouldn't you prefer to be asked `which` button you really wanted to push?
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Woah, that didn’t go as planned. Evennia actually found <em>two</em> <code class="docutils literal notranslate"><span class="pre">hit</span></code> commands to didn’t know which one to use
|
||||
(<em>we</em> know they are the same, but Evennia can’t be sure of that). As we can see, <code class="docutils literal notranslate"><span class="pre">hit-1</span></code> is the one found on
|
||||
the sword. The other one is from adding <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code> to ourself earlier. It’s easy enough to tell Evennia which
|
||||
one you meant:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> hit-1
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hit-1
|
||||
Who do you want to hit?
|
||||
> hit-2
|
||||
Who do you want to hit?
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In this case we don’t need both command-sets, so let’s just keep the one on the sword:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> self.cmdset.remove("commands.mycommands.MyCmdSet")
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> self.cmdset.remove("commands.mycommands.MyCmdSet")
|
||||
> hit
|
||||
Who do you want to hit?
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> tunnel n = kitchen
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> tunnel n = kitchen
|
||||
> n
|
||||
> drop sword
|
||||
> s
|
||||
|
|
@ -300,12 +263,14 @@ for limiting the kind of things you can do with an object, including limiting ju
|
|||
it.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Locks</p>
|
||||
<p>Evennia Locks are defined as a mini-language defined in <cite>lockstrings</cite>. The lockstring
|
||||
is on a form <cite><situation>:<lockfuncs></cite>, where <cite>situation</cite> determines when this
|
||||
lock applies and the <cite>lockfuncs</cite> (there can be more than one) are run to determine
|
||||
if the lock-check passes or not depending on circumstance.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Evennia Locks are defined as a mini-language defined in `lockstrings`. The lockstring
|
||||
is on a form `<situation>:<lockfuncs>`, where `situation` determines when this
|
||||
lock applies and the `lockfuncs` (there can be more than one) are run to determine
|
||||
if the lock-check passes or not depending on circumstance.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"sword"</span><span class="p">)</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"call:holds()"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.search("sword").locks.add("call:holds()")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We added a new lock to the sword. The <em>lockstring</em> <code class="docutils literal notranslate"><span class="pre">"call:holds()"</span></code> means that you can only <em>call</em> commands on
|
||||
|
|
@ -314,16 +279,18 @@ this object if you are <em>holding</em> the object (that is, it’s in your inve
|
|||
first:</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">quell/unquell</p>
|
||||
<p>Quelling allows you as a developer to take on the role of players with less
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Quelling allows you as a developer to take on the role of players with less
|
||||
priveleges. This is useful for testing and debugging, in particular since a
|
||||
superuser has a little <cite>too</cite> much power sometimes.
|
||||
Use <cite>unquell</cite> to get back to your normal self.</p>
|
||||
superuser has a little `too` much power sometimes.
|
||||
Use `unquell` to get back to your normal self.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quell</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If the sword lies on the ground, try</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> hit
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hit
|
||||
Command 'hit' is not available. ..
|
||||
> get sword
|
||||
> hit
|
||||
|
|
@ -332,11 +299,11 @@ Command 'hit' is not available. ..
|
|||
</div>
|
||||
<p>Finally, we get rid of ours sword so we have a clean slate with no more <code class="docutils literal notranslate"><span class="pre">hit</span></code> commands floating around.
|
||||
We can do that in two ways:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delete</span> <span class="n">sword</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>delete sword
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"sword"</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>py self.search("sword").delete()
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -355,55 +322,7 @@ All these commands are in just loaded on the default objects that Evennia provid
|
|||
</ul>
|
||||
<p>The thing must commonly modified is the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>.</p>
|
||||
<p>The default cmdset are defined in <code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code>. Open that file now:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span>
|
||||
<span class="normal">44</span>
|
||||
<span class="normal">45</span>
|
||||
<span class="normal">46</span>
|
||||
<span class="normal">47</span>
|
||||
<span class="normal">48</span>
|
||||
<span class="normal">49</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<span class="sd">(module docstring)</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
|
|
@ -453,11 +372,13 @@ All these commands are in just loaded on the default objects that Evennia provid
|
|||
<span class="c1"># any commands you add below will overload the default ones</span>
|
||||
<span class="c1">#</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">super()</p>
|
||||
<p>The <cite>super()</cite> function refers to the parent of the current class and is commonly
|
||||
used to call same-named methods on the parent.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The `super()` function refers to the parent of the current class and is commonly
|
||||
used to call same-named methods on the parent.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">evennia.default_cmds</span></code> is a container that holds all of Evennia’s default commands and cmdsets. In this module
|
||||
we can see that this was imported and then a new child class was made for each cmdset. Each class looks familiar
|
||||
|
|
@ -468,22 +389,7 @@ This is what adds all the default commands to each CmdSet.</p>
|
|||
add a Command with the same <code class="docutils literal notranslate"><span class="pre">.key</span></code> as a default command, it would completely replace that original. So if you were
|
||||
to add a command with a key <code class="docutils literal notranslate"><span class="pre">look</span></code>, the original <code class="docutils literal notranslate"><span class="pre">look</span></code> command would be replaced by your own version.</p>
|
||||
<p>For now, let’s add our own <code class="docutils literal notranslate"><span class="pre">hit</span></code> and <code class="docutils literal notranslate"><span class="pre">echo</span></code> commands to the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">mycommands</span>
|
||||
|
||||
|
|
@ -499,28 +405,17 @@ to add a command with a key <code class="docutils literal notranslate"><span cla
|
|||
<span class="c1">#</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">mycommands</span><span class="o">.</span><span class="n">CmdEcho</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">mycommands</span><span class="o">.</span><span class="n">CmdHit</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
</div>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> hit
|
||||
Who do you want to hit?
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Your new commands are now available for all player characters in the game. There is another way to add a bunch
|
||||
of commands at once, and that is to add a <em>CmdSet</em> to the other cmdset. All commands in that cmdset will then be added:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">mycommands</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">mycommands</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CharacterCmdSet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CharacterCmdSet</span><span class="p">):</span>
|
||||
|
||||
|
|
@ -534,7 +429,7 @@ of commands at once, and that is to add a <em>CmdSet</em> to the other cmdset. A
|
|||
<span class="c1">#</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">mycommands</span><span class="o">.</span><span class="n">MyCmdSet</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Which way you use depends on how much control you want, but if you already have a CmdSet,
|
||||
this is practical. A Command can be a part of any number of different CmdSets.</p>
|
||||
<section id="removing-commands">
|
||||
|
|
@ -544,22 +439,7 @@ this is practical. A Command can be a part of any number of different CmdSets.</
|
|||
<p>We already know that we use <code class="docutils literal notranslate"><span class="pre">cmdset.remove()</span></code> to remove a cmdset. It turns out you can
|
||||
do the same in <code class="docutils literal notranslate"><span class="pre">at_cmdset_creation</span></code>. For example, let’s remove the default <code class="docutils literal notranslate"><span class="pre">get</span></code> Command
|
||||
from Evennia. We happen to know this can be found as <code class="docutils literal notranslate"><span class="pre">default_cmds.CmdGet</span></code>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">mycommands</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CharacterCmdSet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CharacterCmdSet</span><span class="p">):</span>
|
||||
|
|
@ -576,10 +456,10 @@ from Evennia. We happen to know this can be found as <code class="docutils liter
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdGet</span><span class="p">)</span>
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">get</span>
|
||||
<span class="n">Command</span> <span class="s1">'get'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">available</span> <span class="o">...</span>
|
||||
</div>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> get
|
||||
Command 'get' is not available ...
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -591,15 +471,7 @@ command with the same <code class="docutils literal notranslate"><span class="pr
|
|||
<p>Let’s combine this with what we know about classes and
|
||||
how to <em>override</em> a parent class. Open <code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code> and lets override
|
||||
that <code class="docutils literal notranslate"><span class="pre">CmdGet</span></code> command.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span>
|
||||
<span class="normal">9</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># up top, by the other imports</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># up top, by the other imports</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">default_cmds</span>
|
||||
|
||||
<span class="c1"># somewhere below</span>
|
||||
|
|
@ -608,8 +480,9 @@ that <code class="docutils literal notranslate"><span class="pre">CmdGet</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="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">func</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="nb">str</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">location</span><span class="o">.</span><span class="n">contents</span><span class="p">))</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Line2</strong>: We import <code class="docutils literal notranslate"><span class="pre">default_cmds</span></code> so we can get the parent class.
|
||||
We made a new class and we make it <em>inherit</em> <code class="docutils literal notranslate"><span class="pre">default_cmds.CmdGet</span></code>. We don’t
|
||||
|
|
@ -627,22 +500,7 @@ has a special function <code class="docutils literal notranslate"><span class="p
|
|||
</ul>
|
||||
<p>We now just have to add this so it replaces the default <code class="docutils literal notranslate"><span class="pre">get</span></code> command. Open
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code> again:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">mycommands</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CharacterCmdSet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CharacterCmdSet</span><span class="p">):</span>
|
||||
|
|
@ -659,14 +517,16 @@ has a special function <code class="docutils literal notranslate"><span class="p
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">mycommands</span><span class="o">.</span><span class="n">MyCmdGet</span><span class="p">)</span>
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Another way</p>
|
||||
<p>Instead of adding <cite>MyCmdGet</cite> explicitly in default_cmdset.py,
|
||||
you could also add it to <cite>mycommands.MyCmdSet</cite> and let it be
|
||||
added automatically for you.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Instead of adding `MyCmdGet` explicitly in default_cmdset.py,
|
||||
you could also add it to `mycommands.MyCmdSet` and let it be
|
||||
added automatically for you.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> get
|
||||
Get What?
|
||||
[smaug, fluffy, YourName, ...]
|
||||
|
|
@ -747,7 +607,7 @@ command on ourselves.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="More-on-Commands.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,13 +49,13 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="starting-to-code-evennia">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="starting-to-code-evennia">
|
||||
<h1>Starting to code Evennia<a class="headerlink" href="#starting-to-code-evennia" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Time to dip our toe into some coding! Evennia is written and extended in <a class="reference external" href="https://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 <a class="reference internal" href="../../../Links.html"><span class="doc">link section</span></a> for finding
|
||||
but then you’ll need to continue learning from there. See our <a class="reference internal" href="../../../Links.html"><span class="doc std std-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
|
||||
|
|
@ -61,23 +63,25 @@ stay around for the first few sections where we cover how to run Python from ins
|
|||
</div></blockquote>
|
||||
<p>First, if you were quelling yourself to play the tutorial world, make sure to get your
|
||||
superuser powers back:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">unquell</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> unquell
|
||||
</pre></div>
|
||||
</div>
|
||||
<section id="evennia-hello-world">
|
||||
<h2>Evennia Hello world<a class="headerlink" href="#evennia-hello-world" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">py</span></code> Command (or <code class="docutils literal notranslate"><span class="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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("Hello World!")
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Command input</p>
|
||||
<p>The line with <cite>></cite> indicates input to enter in-game, while the lines below are the
|
||||
expected return from that input.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The line with `>` indicates input to enter in-game, while the lines below are the
|
||||
expected return from that input.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>You will see</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> print("Hello world!")
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> print("Hello world!")
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -95,24 +99,24 @@ button or even graphical element, the normal process is for the user to input co
|
|||
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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"This is a "</span> <span class="o">+</span> <span class="s2">"breaking change."</span><span class="p">)</span>
|
||||
<span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">breaking</span> <span class="n">change</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("This is a " + "breaking change.")
|
||||
This is a breaking change.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A string multiplied with a number will repeat that string as many times:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"|"</span> <span class="o">+</span> <span class="s2">"-"</span> <span class="o">*</span> <span class="mi">40</span> <span class="o">+</span> <span class="s2">"|"</span><span class="p">)</span>
|
||||
<span class="o">|----------------------------------------|</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("|" + "-" * 40 + "|")
|
||||
|----------------------------------------|
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py print("A" + "a" * 5 + "rgh!")
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("A" + "a" * 5 + "rgh!")
|
||||
Aaaaaargh!
|
||||
</pre></div>
|
||||
</div>
|
||||
<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 <code class="docutils literal notranslate"><span class="pre">.format</span></code> <em>method</em> of the string:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py print("This is a {} idea!".format("good"))
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("This is a {} idea!".format("good"))
|
||||
This is a good idea!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -130,12 +134,12 @@ is stand-alone in a python module, like <cite>print()</cite></p>
|
|||
sits and can thus affect it in various ways. You access it with the period <code class="docutils literal notranslate"><span class="pre">.</span></code>. In this case, the
|
||||
string has a resource <code class="docutils literal notranslate"><span class="pre">format(...)</span></code> that modifies it. More specifically, it replaced the <code class="docutils literal notranslate"><span class="pre">{}</span></code> marker
|
||||
inside the string with the value passed to the format. You can do so many times:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py print("This is a {} idea!".format("bad"))
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("This is a {} idea!".format("bad"))
|
||||
This is a bad idea!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py print("This is the {} and {} {} idea!".format("first", "second", "great"))
|
||||
<div class="highlight-none notranslate"><div class="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>
|
||||
|
|
@ -147,23 +151,25 @@ little more about errors in the next section, for now just fix until it prints a
|
|||
<p>Here we passed three comma-separated strings as <em>arguments</em> to the string’s <code class="docutils literal notranslate"><span class="pre">format</span></code> method. These
|
||||
replaced the <code class="docutils literal notranslate"><span class="pre">{}</span></code> markers in the same order as they were given.</p>
|
||||
<p>The input does not have to be strings either:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"STR: </span><span class="si">{}</span><span class="s2">, DEX: </span><span class="si">{}</span><span class="s2">, INT: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
|
||||
<span class="n">STR</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="n">DEX</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span> <span class="n">INT</span><span class="p">:</span> <span class="mi">8</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("STR: {}, DEX: {}, INT: {}".format(12, 14, 8))
|
||||
STR: 12, DEX: 14, INT: 8
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To separate two Python instructions on the same line, you use the semi-colon, <code class="docutils literal notranslate"><span class="pre">;</span></code>. Try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py a = "awesome sauce" ; print("This is {}!".format(a))
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py a = "awesome sauce" ; print("This is {}!".format(a))
|
||||
This is awesome sauce!
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="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
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Some MUD clients use the semi-colon `;` 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>
|
||||
run in 'verbatim' mode or to remap to use some other separator than `;`. 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.
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>What happened here was that we <em>assigned</em> the string <code class="docutils literal notranslate"><span class="pre">"awesome</span> <span class="pre">sauce"</span></code> to a <em>variable</em> we chose
|
||||
to name <code class="docutils literal notranslate"><span class="pre">a</span></code>. In the next statement, Python remembered what <code class="docutils literal notranslate"><span class="pre">a</span></code> was and we passed that into <code class="docutils literal notranslate"><span class="pre">format()</span></code>
|
||||
|
|
@ -171,8 +177,8 @@ to get the output. If you replaced the value of <code class="docutils literal no
|
|||
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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">stren</span><span class="p">,</span> <span class="n">dex</span><span class="p">,</span> <span class="n">intel</span> <span class="o">=</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">8</span> <span class="p">;</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"STR: </span><span class="si">{}</span><span class="s2">, DEX: </span><span class="si">{dex}</span><span class="s2">, INT: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">stren</span><span class="p">,</span> <span class="n">dex</span><span class="p">,</span> <span class="n">intel</span><span class="p">))</span>
|
||||
<span class="n">STR</span><span class="p">:</span> <span class="mi">13</span><span class="p">,</span> <span class="n">DEX</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span> <span class="n">INT</span><span class="p">:</span> <span class="mi">8</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py stren, dex, intel = 13, 14, 8 ; print("STR: {}, DEX: {dex}, INT: {}".format(stren, dex, intel))
|
||||
STR: 13, DEX: 14, INT: 8
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The point is that even if the values of the stats change, the print() statement would not change - it just keeps
|
||||
|
|
@ -180,30 +186,30 @@ pretty-printing whatever is given to it.</p>
|
|||
<p>Using <code class="docutils literal notranslate"><span class="pre">.format()</span></code> is convenient (and there is a <a class="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 <code class="docutils literal notranslate"><span class="pre">f</span></code> front of it, like this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sa">f</span><span class="s2">"this is now an f-string."</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>f"this is now an f-string."
|
||||
</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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py a = "awesome sauce" ; print(f"This is {a}!")
|
||||
<div class="highlight-none notranslate"><div class="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 <code class="docutils literal notranslate"><span class="pre">a</span></code> variable directly into the f-string using <code class="docutils literal notranslate"><span class="pre">{a}</span></code>. Fewer parentheses to
|
||||
remember and arguable easier to read as well.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">stren</span><span class="p">,</span> <span class="n">dex</span><span class="p">,</span> <span class="n">intel</span> <span class="o">=</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">8</span> <span class="p">;</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"STR: </span><span class="si">{</span><span class="n">stren</span><span class="si">}</span><span class="s2">, DEX: </span><span class="si">{</span><span class="n">dex</span><span class="si">}</span><span class="s2">, INT: </span><span class="si">{</span><span class="n">intel</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">STR</span><span class="p">:</span> <span class="mi">13</span><span class="p">,</span> <span class="n">DEX</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span> <span class="n">INT</span><span class="p">:</span> <span class="mi">8</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py stren, dex, intel = 13, 14, 8 ; print(f"STR: {stren}, DEX: {dex}, INT: {intel}")
|
||||
STR: 13, DEX: 14, INT: 8
|
||||
</pre></div>
|
||||
</div>
|
||||
<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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"|rThis is red text!|n This is normal color."</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("|rThis is red text!|n This is normal color.")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Adding that <code class="docutils literal notranslate"><span class="pre">|r</span></code> at the start will turn our output bright red. <code class="docutils literal notranslate"><span class="pre">|R</span></code> will make it dark red. <code class="docutils literal notranslate"><span class="pre">|n</span></code>
|
||||
gives the normal text color. You can also use RGB (Red-Green-Blue) values from 0-5 (Xterm256 colors):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"|043This is a blue-green color.|[530|003 This is dark blue text on orange background."</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py print("|043This is a blue-green color.|[530|003 This is dark blue text on orange background.")
|
||||
</pre></div>
|
||||
</div>
|
||||
<blockquote>
|
||||
|
|
@ -226,19 +232,21 @@ structure should look:</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
<p>For now, only add one line to <code class="docutils literal notranslate"><span class="pre">test.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Python module</p>
|
||||
<p>This is a text file with the <cite>.py</cite> file ending. A module
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>This is a text file with the `.py` file ending. A module
|
||||
contains Python source code and from within Python one can
|
||||
access its contents by importing it via its python-path.</p>
|
||||
access its contents by importing it via its python-path.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Don’t forget to <em>save</em> the file. We just created our first Python <em>module</em>!
|
||||
To use this in-game we have to <em>import</em> it. Try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="kn">import</span> <span class="nn">world.test</span>
|
||||
<span class="n">Hello</span> <span class="n">World</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test
|
||||
Hello World
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you make some error (we’ll cover how to handle errors below), fix the error in the module and
|
||||
|
|
@ -252,7 +260,7 @@ path - Evennia handles this for us.</p>
|
|||
<p>When you import the module, the top “level” of it will execute. In this case, it will immediately
|
||||
print “Hello World”.</p>
|
||||
<p>Now try to run this a second time:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="kn">import</span> <span class="nn">world.test</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will <em>not</em> see any output this second time or any subsequent times! This is not a bug. Rather
|
||||
|
|
@ -260,11 +268,11 @@ it is because of how Python importing works - it stores all imported modules and
|
|||
avoid importing them more than once. So your <code class="docutils literal notranslate"><span class="pre">print</span></code> will only run the first time, when the module
|
||||
is first imported.</p>
|
||||
<p>Try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>And then</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py import world.test
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -275,16 +283,14 @@ not very useful.</p>
|
|||
<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>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="our-first-own-function">
|
||||
<h2>Our first own function<a class="headerlink" href="#our-first-own-function" title="Permalink to this headline">¶</a></h2>
|
||||
<h3>Our first own function<a class="headerlink" href="#our-first-own-function" title="Permalink to this headline">¶</a></h3>
|
||||
<p>We want to be able to print our hello-world message at any time, not just once after a server
|
||||
reload. Change your <code class="docutils literal notranslate"><span class="pre">mygame/world/test.py</span></code> file to look like this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>As we are moving to multi-line Python code, there are some important things to remember:</p>
|
||||
<ul class="simple">
|
||||
<li><p>Capitalization matters in Python. It must be <code class="docutils literal notranslate"><span class="pre">def</span></code> and not <code class="docutils literal notranslate"><span class="pre">DEF</span></code>, <code class="docutils literal notranslate"><span class="pre">who</span></code> is not the same as <code class="docutils literal notranslate"><span class="pre">Who</span></code>.</p></li>
|
||||
|
|
@ -310,14 +316,14 @@ start at least at this indentation level.</p></li>
|
|||
</ul>
|
||||
<p>Now let’s try this out. First <code class="docutils literal notranslate"><span class="pre">reload</span></code> your game to have it pick up
|
||||
our updated Python module, then import it.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">reload</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="kn">import</span> <span class="nn">world.test</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> reload
|
||||
> py import world.test
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Nothing happened! That is because the function in our module won’t do anything just by importing it (this
|
||||
is what we wanted). It will only act when we <em>call</em> it. So we need to first import the module and then access the
|
||||
function within:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world()
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world()
|
||||
Hello world!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -328,19 +334,20 @@ own ends.</p>
|
|||
accessed the <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> function <em>inside</em> the newly imported module.</p>
|
||||
<p>By adding <code class="docutils literal notranslate"><span class="pre">()</span></code> to the <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">reload</span></code> in between:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world()
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world()
|
||||
Hello world!
|
||||
> py import world.test ; world.test.hello_world()
|
||||
Hello world!
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="sending-text-to-others">
|
||||
<h2>Sending text to others<a class="headerlink" href="#sending-text-to-others" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">print</span></code> command is a standard Python structure. We can use that here in the <code class="docutils literal notranslate"><span class="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, <code class="docutils literal notranslate"><span class="pre">print</span></code> won’t do, because it doesn’t know <em>who</em> to send to. Try this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py me.msg("Hello world!")
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py me.msg("Hello world!")
|
||||
Hello world!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -361,30 +368,29 @@ debugging and <code class="docutils literal notranslate"><span class="pre">.msg(
|
|||
<h2>Parsing Python errors<a class="headerlink" href="#parsing-python-errors" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Let’s try this new text-sending in the function we just created. Go back to
|
||||
your <code class="docutils literal notranslate"><span class="pre">test.py</span></code> file and Replace the function with this instead:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span>
|
||||
<span class="n">me</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Save your file and <code class="docutils literal notranslate"><span class="pre">reload</span></code> your server to tell Evennia to re-import new code,
|
||||
then run it like before:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">></span> <span class="n">py</span> <span class="kn">import</span> <span class="nn">world.test</span> <span class="p">;</span> <span class="n">world</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">hello_world</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > py import world.test ; world.test.hello_world()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>No go - this time you get an error!</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">File</span> <span class="s2">"./world/test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">2</span><span class="p">,</span> <span class="ow">in</span> <span class="n">hello_world</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">File</span> <span class="s2">"./world/test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">2</span><span class="p">,</span> <span class="ow">in</span> <span class="n">hello_world</span>
|
||||
<span class="n">me</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
<span class="ne">NameError</span><span class="p">:</span> <span class="n">name</span> <span class="s1">'me'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">defined</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Errors in the logs</p>
|
||||
<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 class="highlight-none notranslate"><div class="highlight"><pre><span></span>In regular use, tracebacks will often appear in the log rather than
|
||||
in the game. Use `evennia --log` to view the log in the terminal. Make
|
||||
sure to scroll back if you expect an error and don't see it. Use
|
||||
`Ctrl-C` (or `Cmd-C` on Mac) to exit the log-view.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<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
|
||||
|
|
@ -411,15 +417,14 @@ Hence the <code class="docutils literal notranslate"><span class="pre">NameError
|
|||
<p>We know that <code class="docutils literal notranslate"><span class="pre">me</span></code> exists at the point when we run the <code class="docutils literal notranslate"><span class="pre">py</span></code> command, because we can do <code class="docutils literal notranslate"><span class="pre">py</span> <span class="pre">me.msg("Hello</span> <span class="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 <code class="docutils literal notranslate"><span class="pre">test.py</span></code> and change it to this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">who</span><span class="p">):</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">who</span><span class="p">):</span>
|
||||
<span class="n">who</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>We now added an <em>argument</em> to the function. We could have named it anything. Whatever <code class="docutils literal notranslate"><span class="pre">who</span></code> is,
|
||||
we will call a method <code class="docutils literal notranslate"><span class="pre">.msg()</span></code> on it.</p>
|
||||
<p>As usual, <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server to make sure the new code is available.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world(me)
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world(me)
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -445,27 +450,29 @@ and the concept of <em>Leap before you Look</em>.</p>
|
|||
object called the <code class="docutils literal notranslate"><span class="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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">mirror</span><span class="p">:</span><span class="n">contrib</span><span class="o">.</span><span class="n">tutorial_examples</span><span class="o">.</span><span class="n">mirror</span><span class="o">.</span><span class="n">TutorialMirror</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> create/drop mirror:contrib.tutorial_examples.mirror.TutorialMirror
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Creating objects</p>
|
||||
<p>The <cite>create</cite> command was first used to create boxes in the
|
||||
<a class="reference external" href="Building-Quickstart">Building Stuff</a> tutorial. Note how it
|
||||
uses a “python-path” to describe where to load the mirror’s code from.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>The `create` command was first used to create boxes in the
|
||||
`Building Stuff <Building-Quickstart>`_ tutorial. Note how it
|
||||
uses a "python-path" to describe where to load the mirror's code from.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>A mirror should appear in your location.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">look</span> <span class="n">mirror</span>
|
||||
<span class="n">mirror</span> <span class="n">shows</span> <span class="n">your</span> <span class="n">reflection</span><span class="p">:</span>
|
||||
<span class="n">This</span> <span class="ow">is</span> <span class="n">User</span> <span class="c1">#1</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> look mirror
|
||||
mirror shows your reflection:
|
||||
This is User #1
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>What you are seeing is actually your own avatar in the game, the same thing that is available as <code class="docutils literal notranslate"><span class="pre">me</span></code> in the <code class="docutils literal notranslate"><span class="pre">py</span></code>
|
||||
command.</p>
|
||||
<p>What we are aiming for now is the equivalent of <code class="docutils literal notranslate"><span class="pre">mirror.msg("Mirror</span> <span class="pre">Mirror</span> <span class="pre">on</span> <span class="pre">the</span> <span class="pre">wall")</span></code>. But the first thing that
|
||||
comes to mind will not work:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">mirror</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Mirror, Mirror on the wall ..."</span><span class="p">)</span>
|
||||
<span class="ne">NameError</span><span class="p">:</span> <span class="n">name</span> <span class="s1">'mirror'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">defined</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py mirror.msg("Mirror, Mirror on the wall ...")
|
||||
NameError: name 'mirror' is not defined.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is not surprising: Python knows nothing about “mirrors” or locations or anything. The <code class="docutils literal notranslate"><span class="pre">me</span></code> we’ve been using
|
||||
|
|
@ -473,29 +480,31 @@ is, as mentioned, just a convenient thing the Evennia devs makes available to th
|
|||
predict that you wanted to talk to mirrors.</p>
|
||||
<p>Instead we will need to <em>search</em> for that <code class="docutils literal notranslate"><span class="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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">me</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"mirror"</span><span class="p">)</span>
|
||||
<span class="n">mirror</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py me.search("mirror")
|
||||
mirror
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">me</span></code> object is. If it can’t find anything you’ll see an error.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="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
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Whereas a function like `print` only prints its arguments, it's very common
|
||||
for functions/methods to `return` 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>
|
||||
of `me.search`, it will perform a database search and spit out the object it finds.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">me</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"dummy"</span><span class="p">)</span>
|
||||
<span class="n">Could</span> <span class="ow">not</span> <span class="n">find</span> <span class="s1">'dummy'</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py me.search("dummy")
|
||||
Could not find 'dummy'.
|
||||
</pre></div>
|
||||
</div>
|
||||
<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 <code class="docutils literal notranslate"><span class="pre">me</span></code>!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="n">mirror</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"mirror"</span><span class="p">)</span> <span class="p">;</span> <span class="n">mirror</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Mirror, Mirror on the wall ..."</span><span class="p">)</span>
|
||||
<span class="n">mirror</span> <span class="n">echoes</span> <span class="n">back</span> <span class="n">to</span> <span class="n">you</span><span class="p">:</span>
|
||||
<span class="s2">"Mirror, Mirror on the wall ..."</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py mirror = self.search("mirror") ; mirror.msg("Mirror, Mirror on the wall ...")
|
||||
mirror echoes back to you:
|
||||
"Mirror, Mirror on the wall ..."
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The mirror is useful for testing because its <code class="docutils literal notranslate"><span class="pre">.msg</span></code> method just echoes whatever is sent to it back to the room. More common
|
||||
|
|
@ -506,57 +515,57 @@ would be to talk to a player character, in which case the text you sent would ha
|
|||
<p>So far we have use <code class="docutils literal notranslate"><span class="pre">py</span></code> in single-line mode, using <code class="docutils literal notranslate"><span class="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
|
||||
inside Evennia.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span>
|
||||
<span class="n">Evennia</span> <span class="n">Interactive</span> <span class="n">Python</span> <span class="n">mode</span>
|
||||
<span class="n">Python</span> <span class="mf">3.7.1</span> <span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">Oct</span> <span class="mi">22</span> <span class="mi">2018</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">55</span><span class="p">)</span>
|
||||
<span class="p">[</span><span class="n">GCC</span> <span class="mf">8.2.0</span><span class="p">]</span> <span class="n">on</span> <span class="n">Linux</span>
|
||||
<span class="p">[</span><span class="n">py</span> <span class="n">mode</span> <span class="o">-</span> <span class="n">quit</span><span class="p">()</span> <span class="n">to</span> <span class="n">exit</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
Evennia Interactive Python mode
|
||||
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
|
||||
[GCC 8.2.0] on Linux
|
||||
[py mode - quit() to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(the details of the output will vary with your Python version and OS). You are now in python interpreter mode. It means
|
||||
that <em>everything</em> you insert from now on will become a line of Python (you can no longer look around or do other
|
||||
commands).</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> print("Hello World")
|
||||
|
||||
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World"</span><span class="p">)</span>
|
||||
<span class="n">Hello</span> <span class="n">World</span>
|
||||
<span class="p">[</span><span class="n">py</span> <span class="n">mode</span> <span class="o">-</span> <span class="n">quit</span><span class="p">()</span> <span class="n">to</span> <span class="n">exit</span><span class="p">]</span>
|
||||
>>> print("Hello World")
|
||||
Hello World
|
||||
[py mode - quit() to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note that we didn’t need to put <code class="docutils literal notranslate"><span class="pre">py</span></code> in front now. The system will also echo your input (that’s the bit after
|
||||
the <code class="docutils literal notranslate"><span class="pre">>>></span></code>). For brevity in this tutorual we’ll turn the echo off. First exit <code class="docutils literal notranslate"><span class="pre">py</span></code> and then start again with the
|
||||
<code class="docutils literal notranslate"><span class="pre">/noecho</span></code> flag.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quit</span><span class="p">()</span>
|
||||
<span class="n">Closing</span> <span class="n">the</span> <span class="n">Python</span> <span class="n">console</span><span class="o">.</span>
|
||||
<span class="o">></span> <span class="n">py</span><span class="o">/</span><span class="n">noecho</span>
|
||||
<span class="n">Evennia</span> <span class="n">Interactive</span> <span class="n">Python</span> <span class="n">mode</span> <span class="p">(</span><span class="n">no</span> <span class="n">echoing</span> <span class="n">of</span> <span class="n">prompts</span><span class="p">)</span>
|
||||
<span class="n">Python</span> <span class="mf">3.7.1</span> <span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">Oct</span> <span class="mi">22</span> <span class="mi">2018</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">55</span><span class="p">)</span>
|
||||
<span class="p">[</span><span class="n">GCC</span> <span class="mf">8.2.0</span><span class="p">]</span> <span class="n">on</span> <span class="n">Linux</span>
|
||||
<span class="p">[</span><span class="n">py</span> <span class="n">mode</span> <span class="o">-</span> <span class="n">quit</span><span class="p">()</span> <span class="n">to</span> <span class="n">exit</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quit()
|
||||
Closing the Python console.
|
||||
> py/noecho
|
||||
Evennia Interactive Python mode (no echoing of prompts)
|
||||
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
|
||||
[GCC 8.2.0] on Linux
|
||||
[py mode - quit() to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">interactive py</p>
|
||||
<ul class="simple">
|
||||
<li><p>Start with <cite>py</cite>.</p></li>
|
||||
<li><p>Use <cite>py/noecho</cite> if you don’t want your input to be echoed for every line.</p></li>
|
||||
<li><p>All your inputs will now be interpreted as Python code.</p></li>
|
||||
<li><p>Exit with <cite>quit()</cite>.</p></li>
|
||||
</ul>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>- Start with `py`.
|
||||
- Use `py/noecho` if you don't want your input to be echoed for every line.
|
||||
- All your inputs will now be interpreted as Python code.
|
||||
- Exit with `quit()`.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>We can now enter multi-line Python code:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">a</span> <span class="o">=</span> <span class="s2">"Test"</span>
|
||||
<span class="o">></span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"This is a </span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s2">."</span><span class="p">}</span>
|
||||
<span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">Test</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> a = "Test"
|
||||
> print(f"This is a {a}."}
|
||||
This is a Test.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Let’s try to define a function:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">who</span><span class="p">,</span> <span class="n">txt</span><span class="p">):</span>
|
||||
<span class="o">...</span>
|
||||
<span class="o">></span> <span class="n">who</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">txt</span><span class="p">)</span>
|
||||
<span class="o">...</span>
|
||||
<span class="o">></span>
|
||||
<span class="p">[</span><span class="n">py</span> <span class="n">mode</span> <span class="o">-</span> <span class="n">quit</span><span class="p">()</span> <span class="n">to</span> <span class="n">exit</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> def hello_world(who, txt):
|
||||
...
|
||||
> who.msg(txt)
|
||||
...
|
||||
>
|
||||
[py mode - quit() to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Some important things above:</p>
|
||||
|
|
@ -570,21 +579,21 @@ for Python to know it’s part of the function body.</p></li>
|
|||
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>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> hello_world(me, "Hello world to me!")
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> hello_world(me, "Hello world to me!")
|
||||
Hello world to me!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">me</span></code> is still available to us, so we pass that as the <code class="docutils literal notranslate"><span class="pre">who</span></code> argument, along with a little longer
|
||||
string. Let’s combine this with searching for the mirror.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">mirror</span> <span class="o">=</span> <span class="n">me</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"mirror"</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">hello_world</span><span class="p">(</span><span class="n">mirror</span><span class="p">,</span> <span class="s2">"Mirror, Mirror on the wall ..."</span><span class="p">)</span>
|
||||
<span class="n">mirror</span> <span class="n">echoes</span> <span class="n">back</span> <span class="n">to</span> <span class="n">you</span><span class="p">:</span>
|
||||
<span class="s2">"Mirror, Mirror on the wall ..."</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> mirror = me.search("mirror")
|
||||
> hello_world(mirror, "Mirror, Mirror on the wall ...")
|
||||
mirror echoes back to you:
|
||||
"Mirror, Mirror on the wall ..."
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Exit the <code class="docutils literal notranslate"><span class="pre">py</span></code> mode with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quit</span><span class="p">()</span>
|
||||
<span class="n">Closing</span> <span class="n">the</span> <span class="n">Python</span> <span class="n">console</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quit()
|
||||
Closing the Python console.
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -601,8 +610,8 @@ is available).</p>
|
|||
</ul>
|
||||
<p>A Python shell opens. This works like <code class="docutils literal notranslate"><span class="pre">py</span></code> did inside the game, with the exception that you don’t have
|
||||
<code class="docutils literal notranslate"><span class="pre">me</span></code> available out of the box. If you want <code class="docutils literal notranslate"><span class="pre">me</span></code>, you need to first find yourself:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="o">></span> <span class="n">me</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="s2">"YourChar"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> import evennia
|
||||
> me = evennia.search_object("YourChar")[0]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here we make use of one of evennia’s search functions, available by importing <code class="docutils literal notranslate"><span class="pre">evennia</span></code> directly.
|
||||
|
|
@ -613,29 +622,28 @@ We will cover more advanced searching later, but suffice to say, you put your ow
|
|||
get at the first of them (counting starts from 0).</p>
|
||||
</div></blockquote>
|
||||
<p>Use <code class="docutils literal notranslate"><span class="pre">Ctrl-D</span></code> (<code class="docutils literal notranslate"><span class="pre">Cmd-D</span></code> on Mac) or <code class="docutils literal notranslate"><span class="pre">quit()</span></code> to exit the Python console.</p>
|
||||
</section>
|
||||
<section id="ipython">
|
||||
<h3>ipython<a class="headerlink" href="#ipython" title="Permalink to this headline">¶</a></h3>
|
||||
<h2>ipython<a class="headerlink" href="#ipython" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The default Python shell is quite limited and ugly. It’s <em>highly</em> recommended to install <code class="docutils literal notranslate"><span class="pre">ipython</span></code> instead. This
|
||||
is a much nicer, third-party Python interpreter with colors and many usability improvements.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">ipython</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install ipython
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If <code class="docutils literal notranslate"><span class="pre">ipython</span></code> is installed, <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">shell</span></code> will use it automatically.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">shell</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">IPython</span> <span class="mf">7.4.0</span> <span class="o">--</span> <span class="n">An</span> <span class="n">enhanced</span> <span class="n">Interactive</span> <span class="n">Python</span><span class="o">.</span> <span class="n">Type</span> <span class="s1">'?'</span> <span class="k">for</span> <span class="n">help</span>
|
||||
<span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You now have Tab-completion:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="o">></span> <span class="n">evennia</span><span class="o">.<</span><span class="n">TAB</span><span class="o">></span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia shell
|
||||
...
|
||||
IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help
|
||||
In [1]: You now have Tab-completion:
|
||||
|
||||
> import evennia
|
||||
> evennia.<TAB>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>That is, enter <code class="docutils literal notranslate"><span class="pre">evennia.</span></code> and then press the TAB key - you will be given a list of all the resources
|
||||
available on the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> object. This is great for exploring what Evennia has to offer. For example,
|
||||
use your arrow keys to scroll to <code class="docutils literal notranslate"><span class="pre">search_object()</span></code> to fill it in.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> evennia.search_object?
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> evennia.search_object?
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Adding a <code class="docutils literal notranslate"><span class="pre">?</span></code> and pressing return will give you the full documentation for <code class="docutils literal notranslate"><span class="pre">.search_object</span></code>. Use <code class="docutils literal notranslate"><span class="pre">??</span></code> if you
|
||||
|
|
@ -644,21 +652,22 @@ want to see the entire source code.</p>
|
|||
<div class="admonition important">
|
||||
<p class="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
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Common for both `py` and `python`/`ipython` 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>
|
||||
Python code, we need to save it in a Python module, like we did for `world/test.py`.
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="conclusions">
|
||||
<h2>Conclusions<a class="headerlink" href="#conclusions" title="Permalink to this headline">¶</a></h2>
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="conclusions">
|
||||
<h1>Conclusions<a class="headerlink" href="#conclusions" title="Permalink to this headline">¶</a></h1>
|
||||
<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 <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> folder …</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
|
|
@ -686,20 +695,20 @@ Now let’s look at the rest of the stuff you’ve got going on inside that <cod
|
|||
<li><a class="reference internal" href="#">Starting to code Evennia</a><ul>
|
||||
<li><a class="reference internal" href="#evennia-hello-world">Evennia Hello world</a></li>
|
||||
<li><a class="reference internal" href="#making-some-text-graphics">Making some text ‘graphics’</a></li>
|
||||
<li><a class="reference internal" href="#importing-code-from-other-modules">Importing code from other modules</a></li>
|
||||
<li><a class="reference internal" href="#importing-code-from-other-modules">Importing code from other modules</a><ul>
|
||||
<li><a class="reference internal" href="#our-first-own-function">Our first own function</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#sending-text-to-others">Sending text to others</a></li>
|
||||
<li><a class="reference internal" href="#parsing-python-errors">Parsing Python errors</a></li>
|
||||
<li><a class="reference internal" href="#passing-arguments-to-functions">Passing arguments to functions</a></li>
|
||||
<li><a class="reference internal" href="#finding-others-to-send-to">Finding others to send to</a></li>
|
||||
<li><a class="reference internal" href="#multi-line-py">Multi-line py</a></li>
|
||||
<li><a class="reference internal" href="#other-ways-to-test-python-code">Other ways to test Python code</a><ul>
|
||||
<li><a class="reference internal" href="#other-ways-to-test-python-code">Other ways to test Python code</a></li>
|
||||
<li><a class="reference internal" href="#ipython">ipython</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#conclusions">Conclusions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
|
|
@ -728,7 +737,7 @@ Now let’s look at the rest of the stuff you’ve got going on inside that <cod
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Python-basic-introduction.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="python-classes-and-objects">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="python-classes-and-objects">
|
||||
<h1>Python Classes and objects<a class="headerlink" href="#python-classes-and-objects" title="Permalink to this headline">¶</a></h1>
|
||||
<p>We have now learned how to run some simple Python code from inside (and outside) your game server.
|
||||
We have also taken a look at what our game dir looks and what is where. Now we’ll start to use it.</p>
|
||||
|
|
@ -63,23 +65,23 @@ it much easier to find errors and to know what code is good and which has issues
|
|||
and it will import and use it (often instead of its defaults).</p>
|
||||
</div></blockquote>
|
||||
<p>We have already successfully imported things, for example:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world(me)
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py import world.test ; world.test.hello_world(me)
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In this example, on your hard drive, the files looks like this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mygame</span><span class="o">/</span>
|
||||
<span class="n">world</span><span class="o">/</span>
|
||||
<span class="n">world</span><span class="o">/</span>
|
||||
<span class="n">test</span><span class="o">.</span><span class="n">py</span> <span class="o"><-</span> <span class="n">inside</span> <span class="n">this</span> <span class="n">file</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">function</span> <span class="n">hello_world</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you followed earlier tutorial lessons, the <code class="docutils literal notranslate"><span class="pre">mygame/world/test.py</span></code> file should look like this (if
|
||||
not, make it so):</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">who</span><span class="p">):</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">who</span><span class="p">):</span>
|
||||
<span class="n">who</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Hello World!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Remember:</p>
|
||||
<ul class="simple">
|
||||
|
|
@ -94,43 +96,43 @@ not, make it so):</p>
|
|||
Python <em>modules</em> (that is, files ending with .py). A python-path separates each part of the
|
||||
path <code class="docutils literal notranslate"><span class="pre">.</span></code> and always skips the <code class="docutils literal notranslate"><span class="pre">.py</span></code> file endings. Also, Evennia already knows to start looking
|
||||
for python resources inside <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> so this should never be specified. Hence</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">world.test</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>import world.test
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">import</span></code> Python instruction loads <code class="docutils literal notranslate"><span class="pre">world.test</span></code> so you have it available. You can now go “into”
|
||||
this module to get to the function you want:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">world</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">hello_world</span><span class="p">(</span><span class="n">me</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>world.test.hello_world(me)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Using <code class="docutils literal notranslate"><span class="pre">import</span></code> like this means that you have to specify the full <code class="docutils literal notranslate"><span class="pre">world.test</span></code> every time you want
|
||||
to get to your function. Here’s a more powerful form of import:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">world.test</span> <span class="kn">import</span> <span class="n">hello_world</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from world.test import hello_world
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">...</span></code> is very, very common as long as you want to get something with a longer
|
||||
python path. It imports <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> directly, so you can use it right away!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> > py from world.test import hello_world ; hello_world(me)
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > py from world.test import hello_world ; hello_world(me)
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Let’s say your <code class="docutils literal notranslate"><span class="pre">test.py</span></code> module had a bunch of interesting functions. You could then import them
|
||||
all one by one:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">world.test</span> <span class="kn">import</span> <span class="n">hello_world</span><span class="p">,</span> <span class="n">my_func</span><span class="p">,</span> <span class="n">awesome_func</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from world.test import hello_world, my_func, awesome_func
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If there were <em>a lot</em> of functions, you could instead just import <code class="docutils literal notranslate"><span class="pre">test</span></code> and get the function
|
||||
from there when you need (without having to give the full <code class="docutils literal notranslate"><span class="pre">world.test</span></code> every time):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> from world import test ; test.hello_world(me
|
||||
Hello World!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> from world import test ; test.hello_world(me
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can also <em>rename</em> stuff you import. Say for example that the module you import to already
|
||||
has a function <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> but we also want to use the one from <code class="docutils literal notranslate"><span class="pre">world/test.py</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">world.test</span> <span class="kn">import</span> <span class="n">hello_world</span> <span class="k">as</span> <span class="n">test_hello_world</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from world.test import hello_world as test_hello_world
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The form <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">...</span> <span class="pre">as</span> <span class="pre">...</span></code> renames the import.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> from world.test import hello_world as hw ; hw(me)
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> from world.test import hello_world as hw ; hw(me)
|
||||
Hello World!
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -138,17 +140,17 @@ Hello World!
|
|||
<div><p>Avoid renaming unless it’s to avoid a name-collistion like above - you want to make things as
|
||||
easy to read as possible, and renaming adds another layer of potential confusion.</p>
|
||||
</div></blockquote>
|
||||
<p>In <a class="reference internal" href="Python-basic-introduction.html"><span class="doc">the basic intro to Python</span></a> we learned how to open the in-game
|
||||
<p>In <a class="reference internal" href="Python-basic-introduction.html"><span class="doc std std-doc">the basic intro to Python</span></a> we learned how to open the in-game
|
||||
multi-line interpreter.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span>
|
||||
<span class="n">Evennia</span> <span class="n">Interactive</span> <span class="n">Python</span> <span class="n">mode</span>
|
||||
<span class="n">Python</span> <span class="mf">3.7.1</span> <span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">Oct</span> <span class="mi">22</span> <span class="mi">2018</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">55</span><span class="p">)</span>
|
||||
<span class="p">[</span><span class="n">GCC</span> <span class="mf">8.2.0</span><span class="p">]</span> <span class="n">on</span> <span class="n">Linux</span>
|
||||
<span class="p">[</span><span class="n">py</span> <span class="n">mode</span> <span class="o">-</span> <span class="n">quit</span><span class="p">()</span> <span class="n">to</span> <span class="n">exit</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
Evennia Interactive Python mode
|
||||
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
|
||||
[GCC 8.2.0] on Linux
|
||||
[py mode - quit() to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You now only need to import once to use the imported function over and over.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> from world.test import hello_world
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> from world.test import hello_world
|
||||
> hello_world()
|
||||
Hello World!
|
||||
> hello_world()
|
||||
|
|
@ -166,16 +168,7 @@ imports at the top, resources that are then used by all code in that module.</p>
|
|||
<h2>On classes and objects<a class="headerlink" href="#on-classes-and-objects" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Now that we know about imports, let look at a real Evennia module and try to understand it.</p>
|
||||
<p>Open <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects.py</span></code> in your text editor of choice.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">"""</span>
|
||||
<span class="sd">module docstring</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
|
||||
|
|
@ -186,12 +179,14 @@ imports at the top, resources that are then used by all code in that module.</p>
|
|||
<span class="sd"> """</span>
|
||||
<span class="k">pass</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Docstrings vs Comments</p>
|
||||
<p>A docstring is not the same as a comment (created by <cite>#</cite>). A
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>A docstring is not the same as a comment (created by `#`). A
|
||||
docstring is not ignored by Python but is an integral part of the thing
|
||||
it is documenting (the module and the class in this case).</p>
|
||||
it is documenting (the module and the class in this case).
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>The real file is much longer but we can ignore the multi-line strings (<code class="docutils literal notranslate"><span class="pre">"""</span> <span class="pre">...</span> <span class="pre">"""</span></code>). These serve
|
||||
as documentation-strings, or <em>docstrings</em> for the module (at the top) and the <code class="docutils literal notranslate"><span class="pre">class</span></code> below.</p>
|
||||
|
|
@ -201,13 +196,15 @@ as a black box.</p>
|
|||
<p>Next we have a <code class="docutils literal notranslate"><span class="pre">class</span></code> named <code class="docutils literal notranslate"><span class="pre">Object</span></code>, which <em>inherits</em> from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. This class doesn’t
|
||||
actually do anything on its own, its only code (except the docstring) is <code class="docutils literal notranslate"><span class="pre">pass</span></code> which means,
|
||||
well, to pass and don’t do anything.</p>
|
||||
<p>We will get back to this module in the <a class="reference internal" href="Learning-Typeclasses.html"><span class="doc">next lesson</span></a>. First we need to do a
|
||||
<p>We will get back to this module in the <a class="reference internal" href="Learning-Typeclasses.html"><span class="doc std std-doc">next lesson</span></a>. First we need to do a
|
||||
little detour to understand what a ‘class’, an ‘object’ or ‘instance’ is. These are fundamental
|
||||
things to understand before you can use Evennia efficiently.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">OOP</p>
|
||||
<p>Classes, objects, instances and inheritance are fundamental to Python. This and some
|
||||
other concepts are often clumped together under the term Object-Oriented-Programming (OOP).</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Classes, objects, instances and inheritance are fundamental to Python. This and some
|
||||
other concepts are often clumped together under the term Object-Oriented-Programming (OOP).
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<section id="classes-and-instances">
|
||||
<h3>Classes and instances<a class="headerlink" href="#classes-and-instances" title="Permalink to this headline">¶</a></h3>
|
||||
|
|
@ -215,21 +212,16 @@ other concepts are often clumped together under the term Object-Oriented-Program
|
|||
of everyone of that class. For example, we could have a class <code class="docutils literal notranslate"><span class="pre">Monster</span></code> which has resources for moving itself
|
||||
from room to room.</p>
|
||||
<p>Open a new file <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code>. Add the following simple class:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
|
||||
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
|
||||
|
||||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"Monster"</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">move_around</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!"</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Above we have defined a <code class="docutils literal notranslate"><span class="pre">Monster</span></code> class with one variable <code class="docutils literal notranslate"><span class="pre">key</span></code> (that is, the name) and one
|
||||
<em>method</em> on it. A method is like a function except it sits “on” the class. It also always has
|
||||
at least one argument (almost always written as <code class="docutils literal notranslate"><span class="pre">self</span></code> although you could in principle use
|
||||
|
|
@ -245,11 +237,11 @@ back to the <code class="docutils literal notranslate"><span class="pre">key</sp
|
|||
<p>A class is just a template. Before it can be used, we must create an <em>instance</em> of the class. If
|
||||
<code class="docutils literal notranslate"><span class="pre">Monster</span></code> is a class, then an instance is Fluffy, the individual red dragon. You instantiate
|
||||
by <em>calling</em> the class, much like you would a function:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fluffy</span> <span class="o">=</span> <span class="n">Monster</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>fluffy = Monster()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Let’s try it in-game (we use multi-line mode, it’s easier)</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Monster
|
||||
> fluffy = Monster()
|
||||
> fluffy.move_around()
|
||||
|
|
@ -264,78 +256,73 @@ there when defining the method, we <em>never</em> add it explicitly when we call
|
|||
will add the correct <code class="docutils literal notranslate"><span class="pre">self</span></code> for us automatically behind the scenes).</p>
|
||||
</div></blockquote>
|
||||
<p>Let’s create the sibling of Fluffy, Cuddly:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> cuddly = Monster()
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> cuddly = Monster()
|
||||
> cuddly.move_around()
|
||||
Monster is moving!
|
||||
Monster is moving!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We now have two dragons and they’ll hang around until with call <code class="docutils literal notranslate"><span class="pre">quit()</span></code> to exit this Python
|
||||
instance. We can have them move as many times as we want. But no matter how many dragons we
|
||||
create, they will all show the same printout since <code class="docutils literal notranslate"><span class="pre">key</span></code> is always fixed as “Monster”.</p>
|
||||
<p>Let’s make the class a little more flexible:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
|
||||
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">move_around</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!"</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">__init__</span></code> is a special method that Python recognizes. If given, this handles extra arguments
|
||||
when you instantiate a new Monster. We have it add an argument <code class="docutils literal notranslate"><span class="pre">key</span></code> that we store on <code class="docutils literal notranslate"><span class="pre">self</span></code>.</p>
|
||||
<p>Now, for Evennia to see this code change, we need to reload the server. You can either do it this
|
||||
way:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">quit</span><span class="p">()</span>
|
||||
<span class="n">Python</span> <span class="n">Console</span> <span class="ow">is</span> <span class="n">closing</span><span class="o">.</span>
|
||||
<span class="o">></span> <span class="n">reload</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> quit()
|
||||
Python Console is closing.
|
||||
> reload
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Or you can use a separate terminal and restart from outside the game:</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">On reloading</p>
|
||||
<p>Reloading with the python mode gets a little annoying since you need to redo everything
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Reloading with the python mode gets a little annoying since you need to redo everything
|
||||
after every reload. Just keep in mind that during regular development you will not be
|
||||
working this way. The in-game python mode is practical for quick fixes and experiments like
|
||||
this, but actual code is normally written externally, in python modules.</p>
|
||||
this, but actual code is normally written externally, in python modules.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia reload (or restart)
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia reload (or restart)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Either way you’ll need to go into <code class="docutils literal notranslate"><span class="pre">py</span></code> again:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Monster
|
||||
fluffy = Monster("Fluffy")
|
||||
fluffy.move_around()
|
||||
Fluffy is moving!
|
||||
Fluffy is moving!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now we passed <code class="docutils literal notranslate"><span class="pre">"Fluffy"</span></code> as an argument to the class. This went into <code class="docutils literal notranslate"><span class="pre">__init__</span></code> and set <code class="docutils literal notranslate"><span class="pre">self.key</span></code>, which we
|
||||
later used to print with the right name! Again, note that we didn’t include <code class="docutils literal notranslate"><span class="pre">self</span></code> when calling.</p>
|
||||
</section>
|
||||
<section id="what-s-so-good-about-objects">
|
||||
<h3>What’s so good about objects?<a class="headerlink" href="#what-s-so-good-about-objects" title="Permalink to this headline">¶</a></h3>
|
||||
<section id="whats-so-good-about-objects">
|
||||
<h3>What’s so good about objects?<a class="headerlink" href="#whats-so-good-about-objects" title="Permalink to this headline">¶</a></h3>
|
||||
<p>So far all we’ve seen a class do is to behave our first <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> function but more complex. We
|
||||
could just have made a function:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">monster_move_around</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!"</span><span class="p">)</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">monster_move_around</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The difference between the function and an instance of a class (the object), is that the
|
||||
object retains <em>state</em>. Once you called the function it forgets everything about what you called
|
||||
it with last time. The object, on the other hand, remembers changes:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> fluffy.key = "Cuddly"
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> fluffy.key = "Cuddly"
|
||||
> fluffy.move_around()
|
||||
Cuddly is moving!
|
||||
Cuddly is moving!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">fluffy</span></code> object’s <code class="docutils literal notranslate"><span class="pre">key</span></code> was changed to “Cuddly” for as long as it’s around. This makes objects
|
||||
|
|
@ -357,39 +344,14 @@ objects in turn:</p>
|
|||
<p>Classes can <em>inherit</em> from each other. A “child” class will inherit everything from its “parent” class. But if
|
||||
the child adds something with the same name as its parent, it will <em>override</em> whatever it got from its parent.</p>
|
||||
<p>Let’s expand <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code> with another class:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
|
||||
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> This is a base class for Monster.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">move_around</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!"</span><span class="p">)</span>
|
||||
|
|
@ -404,30 +366,33 @@ the child adds something with the same name as its parent, it will <em>override<
|
|||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> flies through the air high above!"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">firebreath</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" </span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Let our dragon breathe fire.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> breathes fire!"</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>We added some docstrings for clarity. It’s always a good idea to add doc strings; you can do so also for methods,
|
||||
as exemplified for the new <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method.</p>
|
||||
<p>We created the new class <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> but we also specified that <code class="docutils literal notranslate"><span class="pre">Monster</span></code> is the <em>parent</em> of <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> but adding
|
||||
the parent in parenthesis. <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Classname(Parent)</span></code> is the way to do this.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Multi-inheritance</p>
|
||||
<p>It’s possible to add more comma-separated parents to a class. You should usually avoid
|
||||
this until you <cite>really</cite> know what you are doing. A single parent will be enough for almost
|
||||
every case you’ll need.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>It's possible to add more comma-separated parents to a class. You should usually avoid
|
||||
this until you `really` know what you are doing. A single parent will be enough for almost
|
||||
every case you'll need.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Let’s try out our new class. First <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and the do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Dragon
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Dragon
|
||||
> smaug = Dragon("Smaug")
|
||||
> smaug.move_around()
|
||||
Smaug flies through the air high above!
|
||||
> smaug.firebreath()
|
||||
Smaug breathes fire!
|
||||
Smaug breathes fire!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Because we didn’t implement <code class="docutils literal notranslate"><span class="pre">__init__</span></code> in <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>, we got the one from <code class="docutils literal notranslate"><span class="pre">Monster</span></code> instead. But since we
|
||||
|
|
@ -436,33 +401,25 @@ available for <code class="docutils literal notranslate"><span class="pre">Drago
|
|||
can breathe fire.</p>
|
||||
<p>One can also force a class to use resources from the parent even if you are overriding some of it. This is done
|
||||
with the <code class="docutils literal notranslate"><span class="pre">super()</span></code> method. Modify your <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> class as follows:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span>
|
||||
<span class="normal">8</span>
|
||||
<span class="normal">9</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ... </span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Dragon</span><span class="p">(</span><span class="n">Monster</span><span class="p">):</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">move_around</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">move_around</span><span class="p">()</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"The world trembles."</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<blockquote>
|
||||
<div><p>Keep <code class="docutils literal notranslate"><span class="pre">Monster</span></code> and the <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method, <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">...</span></code> indicates the rest of the code is untouched.</p>
|
||||
</div></blockquote>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">super().move_around()</span></code> line means that we are calling <code class="docutils literal notranslate"><span class="pre">move_around()</span></code> on the parent of the class. So in this
|
||||
case, we will call <code class="docutils literal notranslate"><span class="pre">Monster.move_around</span></code> first, before doing our own thing.</p>
|
||||
<p>Now <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and then:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Dragon
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py
|
||||
> from typeclasses.monsters import Dragon
|
||||
> smaug = Dragon("Smaug")
|
||||
> smaug.move_around()
|
||||
Smaug is moving!
|
||||
|
|
@ -511,7 +468,7 @@ provides. But first we need to learn just where to find everything.</p>
|
|||
<li><a class="reference internal" href="#importing-things">Importing things</a></li>
|
||||
<li><a class="reference internal" href="#on-classes-and-objects">On classes and objects</a><ul>
|
||||
<li><a class="reference internal" href="#classes-and-instances">Classes and instances</a></li>
|
||||
<li><a class="reference internal" href="#what-s-so-good-about-objects">What’s so good about objects?</a></li>
|
||||
<li><a class="reference internal" href="#whats-so-good-about-objects">What’s so good about objects?</a></li>
|
||||
<li><a class="reference internal" href="#classes-can-have-children">Classes can have children</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
@ -546,7 +503,7 @@ provides. But first we need to learn just where to find everything.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Python-classes-and-objects.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,49 +49,51 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="searching-for-things">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="searching-for-things">
|
||||
<h1>Searching for things<a class="headerlink" href="#searching-for-things" title="Permalink to this headline">¶</a></h1>
|
||||
<p>We have gone through how to create the various entities in Evennia. But creating something is of little use
|
||||
if we cannot find and use it afterwards.</p>
|
||||
<section id="main-search-functions">
|
||||
<h2>Main search functions<a class="headerlink" href="#main-search-functions" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The base tools are the <code class="docutils literal notranslate"><span class="pre">evennia.search_*</span></code> functions, such as <code class="docutils literal notranslate"><span class="pre">evennia.search_object</span></code>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">rose</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
<span class="n">acct</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_account</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">"MyAccountName"</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="s2">"foo@bar.com"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> rose = evennia.search_object(key="rose")
|
||||
acct = evennia.search_account(key="MyAccountName", email="foo@bar.com")
|
||||
</pre></div>
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Querysets</p>
|
||||
<p>What is returned from the main search functions is actually a <cite>queryset</cite>. They can be
|
||||
treated like lists except that they can’t modified in-place. We’ll discuss querysets in
|
||||
the <cite>next lesson</cite> <Django-queries>`_.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>What is returned from the main search functions is actually a `queryset`. They can be
|
||||
treated like lists except that they can't modified in-place. We'll discuss querysets in
|
||||
the `next lesson` <Django-queries>`_.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Strings are always case-insensitive, so searching for <code class="docutils literal notranslate"><span class="pre">"rose"</span></code>, <code class="docutils literal notranslate"><span class="pre">"Rose"</span></code> or <code class="docutils literal notranslate"><span class="pre">"rOsE"</span></code> give the same results.
|
||||
It’s important to remember that what is returned from these search methods is a <em>listing</em> of 0, one or more
|
||||
elements - all the matches to your search. To get the first match:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rose</span> <span class="o">=</span> <span class="n">rose</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>rose = rose[0]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Often you really want all matches to the search parameters you specify. In other situations, having zero or
|
||||
more than one match is a sign of a problem and you need to handle this case yourself.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">the_one_ring</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s2">"The one Ring"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">the_one_ring</span><span class="p">:</span>
|
||||
<span class="c1"># handle not finding the ring at all</span>
|
||||
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">the_one_ring</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
||||
<span class="c1"># handle finding more than one ring</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># ok - exactly one ring found</span>
|
||||
<span class="n">the_one_ring</span> <span class="o">=</span> <span class="n">the_one_ring</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>the_one_ring = evennia.search_object(key="The one Ring")
|
||||
if not the_one_ring:
|
||||
# handle not finding the ring at all
|
||||
elif len(the_one_ring) > 1:
|
||||
# handle finding more than one ring
|
||||
else:
|
||||
# ok - exactly one ring found
|
||||
the_one_ring = the_one_ring[0]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>There are equivalent search functions for all the main resources. You can find a listing of them
|
||||
<a class="reference internal" href="../../../Evennia-API.html"><span class="doc">in the Search functions section</span></a> of the API frontpage.</p>
|
||||
<a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">in the Search functions section</span></a> of the API frontpage.</p>
|
||||
</section>
|
||||
<section id="searching-using-object-search">
|
||||
<h2>Searching using Object.search<a class="headerlink" href="#searching-using-object-search" title="Permalink to this headline">¶</a></h2>
|
||||
<p>On the <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> is a <code class="docutils literal notranslate"><span class="pre">.search</span></code> method which we have already tried out when we made Commands. For
|
||||
this to be used you must already have an object available:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rose</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>rose = obj.search("rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">.search</span></code> method wraps <code class="docutils literal notranslate"><span class="pre">evennia.search_object</span></code> and handles its output in various ways.</p>
|
||||
|
|
@ -100,17 +104,7 @@ things in obj’s inventory or in the same room).</p></li>
|
|||
<li><p>On a no-match or multimatch, <code class="docutils literal notranslate"><span class="pre">.search</span></code> will automatically send an error message to <code class="docutils literal notranslate"><span class="pre">obj</span></code>.</p></li>
|
||||
</ul>
|
||||
<p>So this method handles error messaging for you. A very common way to use it is in commands:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">MyCommand</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
|
||||
|
|
@ -122,26 +116,26 @@ things in obj’s inventory or in the same room).</p></li>
|
|||
<span class="k">if</span> <span class="ow">not</span> <span class="n">foo</span><span class="p">:</span>
|
||||
<span class="k">return</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Remember, <code class="docutils literal notranslate"><span class="pre">self.caller</span></code> is the one calling the command. This is usually a Character, which
|
||||
inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>! This (rather stupid) Command searches for an object named “foo” in
|
||||
the same location. If it can’t find it, <code class="docutils literal notranslate"><span class="pre">foo</span></code> will be <code class="docutils literal notranslate"><span class="pre">None</span></code>. The error has already been reported
|
||||
to <code class="docutils literal notranslate"><span class="pre">self.caller</span></code> so we just abort with <code class="docutils literal notranslate"><span class="pre">return</span></code>.</p>
|
||||
<p>You can use <code class="docutils literal notranslate"><span class="pre">.search</span></code> to find anything, not just stuff in the same room:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">volcano</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">search</span><span class="p">(</span><span class="s2">"Volcano"</span><span class="p">,</span> <span class="k">global</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>volcano = self.caller.search("Volcano", global=True)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you only want to search for a specific list of things, you can do so too:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stone</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">search</span><span class="p">(</span><span class="s2">"MyStone"</span><span class="p">,</span> <span class="n">candidates</span><span class="o">=</span><span class="p">[</span><span class="n">obj1</span><span class="p">,</span> <span class="n">obj2</span><span class="p">,</span> <span class="n">obj3</span><span class="p">,</span> <span class="n">obj4</span><span class="p">])</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>stone = self.caller.search("MyStone", candidates=[obj1, obj2, obj3, obj4])
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will only return a match if MyStone is one of the four provided candidate objects. This is quite powerful,
|
||||
here’s how you’d find something only in your inventory:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">potion</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">search</span><span class="p">(</span><span class="s2">"Healing potion"</span><span class="p">,</span> <span class="n">candidates</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">contents</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>potion = self.caller.search("Healing potion", candidates=self.caller.contents)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can also turn off the automatic error handling:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">swords</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">search</span><span class="p">(</span><span class="s2">"Sword"</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>swords = self.caller.search("Sword", quiet=True)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>With <code class="docutils literal notranslate"><span class="pre">quiet=True</span></code> the user will not be notified on zero or multi-match errors. Instead you are expected to handle this
|
||||
|
|
@ -151,12 +145,12 @@ yourself and what you get back is now a list of zero, one or more matches!</p>
|
|||
<h2>What can be searched for<a class="headerlink" href="#what-can-be-searched-for" title="Permalink to this headline">¶</a></h2>
|
||||
<p>These are the main database entities one can search for:</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="../../../Components/Objects.html"><span class="doc">Objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Accounts.html"><span class="doc">Accounts</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Scripts</span></a>,</p></li>
|
||||
<li><p><a class="reference external" href="Components/Communications.html#channels">Channels</a>,</p></li>
|
||||
<li><p><a class="reference external" href="Howto/Starting/Part1/Communication#Msg">Messages</a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Help-System.html"><span class="doc">Help Entries</span></a>.</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Objects.html"><span class="doc std std-doc">Objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Accounts.html"><span class="doc std std-doc">Accounts</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a>,</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Channels.html"><span class="doc std std-doc">Channels</span></a>,</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Msg.html"><span class="doc std std-doc">Messages</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Components/Help-System.html"><span class="doc std std-doc">Help Entries</span></a>.</p></li>
|
||||
</ul>
|
||||
<p>Most of the time you’ll likely spend your time searching for Objects and the occasional Accounts.</p>
|
||||
<p>So to find an entity, what can be searched for?</p>
|
||||
|
|
@ -168,7 +162,7 @@ yourself and what you get back is now a list of zero, one or more matches!</p>
|
|||
<h3>Search by aliases<a class="headerlink" href="#search-by-aliases" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Objects and Accounts can have any number of aliases. When searching for <code class="docutils literal notranslate"><span class="pre">key</span></code> these will searched too,
|
||||
you can’t easily search only for aliases.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rose</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"flower"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>rose.aliases.add("flower")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If the above <code class="docutils literal notranslate"><span class="pre">rose</span></code> has a <code class="docutils literal notranslate"><span class="pre">key</span></code> <code class="docutils literal notranslate"><span class="pre">"Rose"</span></code>, it can now also be found by searching for <code class="docutils literal notranslate"><span class="pre">flower</span></code>. In-game
|
||||
|
|
@ -179,55 +173,55 @@ you can assign new aliases to things with the <code class="docutils literal notr
|
|||
<p>Only Objects (things inheriting from <code class="docutils literal notranslate"><span class="pre">evennia.DefaultObject</span></code>) has a location. This is usually a room.
|
||||
The <code class="docutils literal notranslate"><span class="pre">Object.search</span></code> method will automatically limit it search by location, but it also works for the
|
||||
general search function. If we assume <code class="docutils literal notranslate"><span class="pre">room</span></code> is a particular Room instance,</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">chest</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="s2">"Treasure chest"</span><span class="p">,</span> <span class="n">location</span><span class="o">=</span><span class="n">room</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>chest = evennia.search_object("Treasure chest", location=room)
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="search-by-tags">
|
||||
<h3>Search by Tags<a class="headerlink" href="#search-by-tags" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Think of a <a class="reference internal" href="../../../Components/Tags.html"><span class="doc">Tag</span></a> as the label the airport puts on your luggage when flying.
|
||||
<p>Think of a <a class="reference internal" href="../../../Components/Tags.html"><span class="doc std std-doc">Tag</span></a> as the label the airport puts on your luggage when flying.
|
||||
Everyone going on the same plane gets a tag grouping them together so the airport can know what should
|
||||
go to which plane. Entities in Evennia can be grouped in the same way. Any number of tags can be attached
|
||||
to each object.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rose</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"flowers"</span><span class="p">)</span>
|
||||
<span class="n">daffodil</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"flowers"</span><span class="p">)</span>
|
||||
<span class="n">tulip</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"flowers"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>rose.tags.add("flowers")
|
||||
daffodil.tags.add("flowers")
|
||||
tulip.tags.add("flowers")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can now find all flowers using the <code class="docutils literal notranslate"><span class="pre">search_tag</span></code> function:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_flowers</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_tag</span><span class="p">(</span><span class="s2">"flowers"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_flowers = evennia.search_tag("flowers")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Tags can also have categories. By default this category is <code class="docutils literal notranslate"><span class="pre">None</span></code> which is also considered a category.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">silmarillion</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"fantasy"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"books"</span><span class="p">)</span>
|
||||
<span class="n">ice_and_fire</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"fantasy"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"books"</span><span class="p">)</span>
|
||||
<span class="n">mona_lisa_overdrive</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"cyberpunk"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"books"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>silmarillion.tags.add("fantasy", category="books")
|
||||
ice_and_fire.tags.add("fantasy", category="books")
|
||||
mona_lisa_overdrive.tags.add("cyberpunk", category="books")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note that if you specify the tag you <em>must</em> also include its category, otherwise that category
|
||||
will be <code class="docutils literal notranslate"><span class="pre">None</span></code> and find no matches.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_fantasy_books</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_tag</span><span class="p">(</span><span class="s2">"fantasy"</span><span class="p">)</span> <span class="c1"># no matches! </span>
|
||||
<span class="n">all_fantasy_books</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_tag</span><span class="p">(</span><span class="s2">"fantasy"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">"books"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_fantasy_books = evennia.search_tag("fantasy") # no matches!
|
||||
all_fantasy_books = evennia.search_tag("fantasy", category="books")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Only the second line above returns the two fantasy books. If we specify a category however,
|
||||
we can get all tagged entities within that category:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_books</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_tag</span><span class="p">(</span><span class="n">category</span><span class="o">=</span><span class="s2">"books"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_books = evennia.search_tag(category="books")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This gets all three books.</p>
|
||||
</section>
|
||||
<section id="search-by-attribute">
|
||||
<h3>Search by Attribute<a class="headerlink" href="#search-by-attribute" title="Permalink to this headline">¶</a></h3>
|
||||
<p>We can also search by the <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attributes</span></a> associated with entities.</p>
|
||||
<p>We can also search by the <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attributes</span></a> associated with entities.</p>
|
||||
<p>For example, let’s give our rose thorns:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rose</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">has_thorns</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">wines</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">has_thorns</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">daffodil</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">has_thorns</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>rose.db.has_thorns = True
|
||||
wines.db.has_thorns = True
|
||||
daffodil.db.has_thorns = False
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now we can find things attribute and the value we want it to have:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">is_ouch</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object_attribute</span><span class="p">(</span><span class="s2">"has_thorns"</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>is_ouch = evennia.search_object_attribute("has_thorns", True)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This returns the rose and the wines.</p>
|
||||
|
|
@ -239,36 +233,38 @@ by-tag is generally faster.</p>
|
|||
<section id="search-by-typeclass">
|
||||
<h3>Search by Typeclass<a class="headerlink" href="#search-by-typeclass" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Sometimes it’s useful to find all objects of a specific Typeclass. All of Evennia’s search tools support this.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_roses</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="n">typeclass</span><span class="o">=</span><span class="s2">"typeclasses.flowers.Rose"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_roses = evennia.search_object(typeclass="typeclasses.flowers.Rose")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you have the <code class="docutils literal notranslate"><span class="pre">Rose</span></code> class already imported you can also pass it directly:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_roses</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="n">typeclass</span><span class="o">=</span><span class="n">Rose</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_roses = evennia.search_object(typeclass=Rose)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can also search using the typeclass itself:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">all_roses</span> <span class="o">=</span> <span class="n">Rose</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>all_roses = Rose.objects.all()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This last way of searching is a simple form of a Django <em>query</em>. This is a way to express SQL queries using
|
||||
Python. We’ll cover this some more as an <a class="reference external" href="#Extra-Credits">Extra-credits</a> section at the end of this lesson.</p>
|
||||
Python.</p>
|
||||
</section>
|
||||
<section id="search-by-dbref">
|
||||
<h3>Search by dbref<a class="headerlink" href="#search-by-dbref" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The database id or <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> is unique and never-reused within each database table. In search methods you can
|
||||
replace the search for <code class="docutils literal notranslate"><span class="pre">key</span></code> with the dbref to search for. This must be written as a string <code class="docutils literal notranslate"><span class="pre">#dbref</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">the_answer</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">search</span><span class="p">(</span><span class="s2">"#42"</span><span class="p">)</span>
|
||||
<span class="n">eightball</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="s2">"#8"</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>the_answer = self.caller.search("#42")
|
||||
eightball = evennia.search_object("#8")
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Since <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> is always unique, this search is always global.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>Relying on #dbrefs</p>
|
||||
<p>You may be used to using #dbrefs a lot from other codebases. It is however considered
|
||||
<cite>bad practice</cite> in Evennia to rely on hard-coded #dbrefs. It makes your code hard to maintain
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You may be used to using #dbrefs a lot from other codebases. It is however considered
|
||||
`bad practice` in Evennia to rely on hard-coded #dbrefs. It makes your code hard to maintain
|
||||
and tied to the exact layout of the database. In 99% of cases you should pass the actual objects
|
||||
around and search by key/tags/attribute instead.</p>
|
||||
around and search by key/tags/attribute instead.
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
|
@ -381,7 +377,7 @@ Django queries and querysets in earnest.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Searching-Things.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -46,7 +48,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="starting-tutorial-part-1">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="starting-tutorial-part-1">
|
||||
<h1>Starting Tutorial (Part 1)<a class="headerlink" href="#starting-tutorial-part-1" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tutorial Parts</p>
|
||||
|
|
@ -71,18 +73,18 @@ and share with others!</p>
|
|||
<h2>Lessons of Part 1 - “What we have”<a class="headerlink" href="#lessons-of-part-1-what-we-have" title="Permalink to this headline">¶</a></h2>
|
||||
<ol class="simple">
|
||||
<li><p>Introduction (you are here)</p></li>
|
||||
<li><p><a class="reference internal" href="Building-Quickstart.html"><span class="doc">Building stuff</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc">The Tutorial World</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Python-basic-introduction.html"><span class="doc">Python basics</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Gamedir-Overview.html"><span class="doc">Game dir overview</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Python-classes-and-objects.html"><span class="doc">Python classes and objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Evennia-Library-Overview.html"><span class="doc">Accessing the Evennia library</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Learning-Typeclasses.html"><span class="doc">Typeclasses and Persistent objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Adding-Commands.html"><span class="doc">Making first own Commands</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="More-on-Commands.html"><span class="doc">Parsing and replacing default Commands</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Creating-Things.html"><span class="doc">Creating things</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Searching-Things.html"><span class="doc">Searching for things</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Django-queries.html"><span class="doc">Advanced searching with Django queries</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Building-Quickstart.html"><span class="doc std std-doc">Building stuff</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Tutorial-World-Introduction.html"><span class="doc std std-doc">The Tutorial World</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Python-basic-introduction.html"><span class="doc std std-doc">Python basics</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Gamedir-Overview.html"><span class="doc std std-doc">Game dir overview</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Python-classes-and-objects.html"><span class="doc std std-doc">Python classes and objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Evennia-Library-Overview.html"><span class="doc std std-doc">Accessing the Evennia library</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Learning-Typeclasses.html"><span class="doc std std-doc">Typeclasses and Persistent objects</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Adding-Commands.html"><span class="doc std std-doc">Making first own Commands</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="More-on-Commands.html"><span class="doc std std-doc">Parsing and replacing default Commands</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Creating-Things.html"><span class="doc std std-doc">Creating things</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Searching-Things.html"><span class="doc std std-doc">Searching for things</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Django-queries.html"><span class="doc std std-doc">Advanced searching with Django queries</span></a></p></li>
|
||||
</ol>
|
||||
<p>In this first part we’ll focus on what we get out of the box in Evennia - we’ll get used to the tools,
|
||||
and how to find things we are looking for. We will also dive into some of things you’ll
|
||||
|
|
@ -106,7 +108,7 @@ to convert this to back-slashes <code class="docutils literal notranslate"><span
|
|||
</section>
|
||||
<section id="a-mud-client">
|
||||
<h3>A MUD client<a class="headerlink" href="#a-mud-client" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You might already have a MUD-client you prefer. Check out the <a class="reference internal" href="../../../Setup/Client-Support-Grid.html"><span class="doc">grid of supported clients</span></a> for aid.
|
||||
<p>You might already have a MUD-client you prefer. Check out the <a class="reference internal" href="../../../Setup/Client-Support-Grid.html"><span class="doc std std-doc">grid of supported clients</span></a> for aid.
|
||||
If telnet’s not your thing, you can also just use Evennia’s web client in your browser.</p>
|
||||
<blockquote>
|
||||
<div><p>In this documentation we often use ‘MUD’ and ‘MU’ or ‘MU*’ interchangeably
|
||||
|
|
@ -131,13 +133,13 @@ Python is whitespace-aware, this will make your life a lot easier.</p>
|
|||
</section>
|
||||
<section id="set-up-a-game-dir-for-the-tutorial">
|
||||
<h3>Set up a game dir for the tutorial<a class="headerlink" href="#set-up-a-game-dir-for-the-tutorial" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Next you should make sure you have <a class="reference internal" href="../../../Setup/Setup-Quickstart.html"><span class="doc">installed Evennia</span></a>. If you followed the instructions
|
||||
<p>Next you should make sure you have <a class="reference internal" href="../../../Setup/Setup-Quickstart.html"><span class="doc std std-doc">installed Evennia</span></a>. If you followed the instructions
|
||||
you will already have created a game-dir. You could use that for this tutorial or you may want to do the
|
||||
tutorial in its own, isolated game dir; it’s up to you.</p>
|
||||
<ul>
|
||||
<li><p>If you want a new gamedir for the tutorial game and already have Evennia running with another gamedir,
|
||||
first enter that gamedir and run</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span> <span class="n">stop</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia stop
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -149,10 +151,10 @@ different ports from the defaults, or there’d be a clash. We will go into chan
|
|||
<ul>
|
||||
<li><p>Now go to where you want to create your tutorial-game. We will always refer to it as <code class="docutils literal notranslate"><span class="pre">mygame</span></code> so
|
||||
it may be convenient if you do too:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span> <span class="o">--</span><span class="n">init</span> <span class="n">mygame</span>
|
||||
<span class="n">cd</span> <span class="n">mygame</span>
|
||||
<span class="n">evennia</span> <span class="n">migrate</span>
|
||||
<span class="n">evennia</span> <span class="n">start</span> <span class="o">--</span><span class="n">log</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia --init mygame
|
||||
cd mygame
|
||||
evennia migrate
|
||||
evennia start --log
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Add your superuser name and password at the prompt (email is optional). Make sure you can
|
||||
|
|
@ -161,7 +163,7 @@ in your web browser (Mac users: Try <code class="docutils literal notranslate"><
|
|||
<p>The above <code class="docutils literal notranslate"><span class="pre">--log</span></code> flag will have Evennia output all its logs to the terminal. This will block
|
||||
the terminal from other input. To leave the log-view, press <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code> (<code class="docutils literal notranslate"><span class="pre">Cmd-C</span></code> on Mac). To see
|
||||
the log again just run</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span> <span class="o">--</span><span class="n">log</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia --log
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -234,7 +236,7 @@ the log again just run</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Starting-Part1.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,12 +49,13 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="the-tutorial-world">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="the-tutorial-world">
|
||||
<h1>The Tutorial World<a class="headerlink" href="#the-tutorial-world" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The <em>Tutorial World</em> is a small and functioning MUD-style game world shipped with Evennia.<br />It’s a small showcase of what is possible. It can also be useful for those who have an easier
|
||||
<p>The <em>Tutorial World</em> is a small and functioning MUD-style game world shipped with Evennia.
|
||||
It’s a small showcase of what is possible. It can also be useful for those who have an easier
|
||||
time learning by deconstructing existing code.</p>
|
||||
<p>Stand in the Limbo room and install it with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">batchcommand</span> <span class="n">tutorial_world</span><span class="o">.</span><span class="n">build</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>batchcommand tutorial_world.build
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>What this does is to run the build script
|
||||
|
|
@ -61,7 +64,7 @@ This is pretty much just a list of build-commands executed in sequence by the <c
|
|||
Wait for the building to complete and don’t run it twice. A new exit should have appeared named <em>Tutorial</em>.</p>
|
||||
<p>The game consists of a single-player quest and has some 20 rooms that you can explore as you seek
|
||||
to discover the whereabouts of a mythical weapon. Make sure you don’t play as superuser:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">quell</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>quell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Enter the new exit by writing <code class="docutils literal notranslate"><span class="pre">tutorial</span></code>. Enjoy! If you succeed you will eventually
|
||||
|
|
@ -121,15 +124,19 @@ Either way you should now be back in Limbo, able to reflect on the experience.</
|
|||
</ul>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Extra Credit</p>
|
||||
<p>If you have previous programming experience (or after you have gone
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>If you have previous programming experience (or after you have gone
|
||||
through this Starter tutorial) it may be instructive to dig a little deeper into the Tutorial-world
|
||||
code to learn how it achieves what it does. The code is heavily documented.
|
||||
You can find all the code in <a class="reference external" href="../../api/evennia.contrib.tutorial_world.html">evennia/contrib/tutorial_world</a>,
|
||||
the build-script is <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/contrib/tutorial_world/build.ev">here</a>.</p>
|
||||
<p>When reading and learning from the code, however, keep in mind that <em>Tutorial World</em> was created with a very
|
||||
You can find all the code in `evennia/contrib/tutorial_world <../../api/evennia.contrib.tutorial_world.html>`_,
|
||||
the build-script is `here <https://github.com/evennia/evennia/blob/master/evennia/contrib/tutorial_world/build.ev>`_.
|
||||
|
||||
|
||||
When reading and learning from the code, however, keep in mind that *Tutorial World* was created with a very
|
||||
specific goal in mind: to install easily and to not permanently modify the rest of the server. It therefore
|
||||
goes to some length to use only temporary solutions and to clean up after itself. This is not something
|
||||
you will usually need to worry about when making your own game.</p>
|
||||
you will usually need to worry about when making your own game.
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Quite a lot of stuff crammed in such a small area!</p>
|
||||
</section>
|
||||
|
|
@ -138,14 +145,14 @@ you will usually need to worry about when making your own game.</p>
|
|||
<p>Once are done playing with the tutorial world, let’s uninstall it.
|
||||
Uninstalling the tutorial world basically means deleting all the rooms and objects it consists of.
|
||||
Make sure you are back in Limbo, then</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">find</span> <span class="n">tut</span><span class="c1">#01</span>
|
||||
<span class="n">find</span> <span class="n">tut</span><span class="c1">#16</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> find tut#01
|
||||
find tut#16
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This should locate the first and last rooms created by <code class="docutils literal notranslate"><span class="pre">build.ev</span></code> - <em>Intro</em> and <em>Outro</em>. If you
|
||||
installed normally, everything created between these two numbers should be part of the tutorial.
|
||||
Note their #dbref numbers, for example 5 and 80. Next we just delete all objects in that range:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="k">del</span> <span class="mi">5</span><span class="o">-</span><span class="mi">80</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> del 5-80
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will see some errors since some objects are auto-deleted and so cannot be found when the delete
|
||||
|
|
@ -216,7 +223,7 @@ move on with how to access this power through code.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Tutorial-World-Introduction.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -48,7 +50,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="on-planning-a-game">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="on-planning-a-game">
|
||||
<h1>On Planning a Game<a class="headerlink" href="#on-planning-a-game" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Last lesson we asked ourselves some questions about our motivation. In this one we’ll present
|
||||
some more technical questions to consider. In the next lesson we’ll answer them for the sake of
|
||||
|
|
@ -172,10 +174,12 @@ release. Make a list. Keep future expansions in mind but limit yourself.</p>
|
|||
build a little “tech demo” along the way.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tech demo</p>
|
||||
<p>With “tech demo” we mean a small example of your code in-action: A room with a mob,
|
||||
a way to jump into and test character-creation etc. The tech demo need not be pretty, it’s
|
||||
there to test functionality. It’s not the beginning of your game world (unless you find that
|
||||
to be more fun).</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>With "tech demo" we mean a small example of your code in-action: A room with a mob,
|
||||
a way to jump into and test character-creation etc. The tech demo need not be pretty, it's
|
||||
there to test functionality. It's not the beginning of your game world (unless you find that
|
||||
to be more fun).
|
||||
</pre></div>
|
||||
</div>
|
||||
</aside>
|
||||
<p>Try to avoid going wild with building a huge game world before you have a tech-demo showing off all parts
|
||||
you expect to have in the first version of your game. Otherwise you run the risk of having to redo it all
|
||||
|
|
@ -191,10 +195,10 @@ what tools you have available.</p>
|
|||
<p>During Coding you look back at the things you wanted during the <strong>Planning</strong> phase and try to
|
||||
implement them. Don’t be shy to update your plans if you find things easier/harder than you thought.
|
||||
The earlier you revise problems, the easier they will be to fix.</p>
|
||||
<p>A good idea is to host your code online using <em>version control</em>. Github.com offers free Private repos
|
||||
<p>A good idea is to host your code online using <em>version control</em>. <a class="reference external" href="http://Github.com">Github.com</a> offers free Private repos
|
||||
these days if you don’t want the world to learn your secrets. Not only version control
|
||||
make it easy for your team to collaborate, it also means
|
||||
your work is backed up at all times. The page on <a class="reference internal" href="../../../Coding/Version-Control.html"><span class="doc">Version Control</span></a>
|
||||
your work is backed up at all times. The page on <a class="reference internal" href="../../../Coding/Version-Control.html"><span class="doc std std-doc">Version Control</span></a>
|
||||
will help you to setting up a sane developer environment with proper version control.</p>
|
||||
</section>
|
||||
<section id="world-building">
|
||||
|
|
@ -226,7 +230,7 @@ flag and let people try it!</p>
|
|||
you never could have imagined. In Alpha you might be best off to
|
||||
focus on inviting friends and maybe other MUD developers, people who you can pester to give proper
|
||||
feedback and bug reports (there <em>will</em> be bugs, there is no way around it).</p>
|
||||
<p>Follow the quick instructions for <a class="reference internal" href="../../../Setup/Online-Setup.html"><span class="doc">Online Setup</span></a> to make your
|
||||
<p>Follow the quick instructions for <a class="reference internal" href="../../../Setup/Online-Setup.html"><span class="doc std std-doc">Online Setup</span></a> to make your
|
||||
game visible online.</p>
|
||||
<p>If you hadn’t already, make sure to put up your game on the
|
||||
<a class="reference external" href="http://games.evennia.com/">Evennia game index</a> so people know it’s in the works (actually, even
|
||||
|
|
@ -320,7 +324,7 @@ have made their dream game a reality!</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Game-Planning.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -48,7 +50,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="planning-the-use-of-some-useful-contribs">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="planning-the-use-of-some-useful-contribs">
|
||||
<h1>Planning the use of some useful contribs<a class="headerlink" href="#planning-the-use-of-some-useful-contribs" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia is deliberately bare-bones out of the box. The idea is that you should be as unrestricted as possible
|
||||
in designing your game. This is why you can easily replace the few defaults we have and why we don’t try to
|
||||
|
|
@ -56,7 +58,7 @@ prescribe any major game systems on you.</p>
|
|||
<p>That said, Evennia <em>does</em> offer some more game-opinionated <em>optional</em> stuff. These are referred to as <em>Contribs</em>
|
||||
and is an ever-growing treasure trove of code snippets, concepts and even full systems you can pick and choose
|
||||
from to use, tweak or take inspiration from when you make your game.</p>
|
||||
<p>The <a class="reference internal" href="../../../Contribs/Contrib-Overview.html"><span class="doc">Contrib overview</span></a> page gives the full list of the current roster of contributions. On
|
||||
<p>The <a class="reference internal" href="../../../Contribs/Contrib-Overview.html"><span class="doc std std-doc">Contrib overview</span></a> page gives the full list of the current roster of contributions. On
|
||||
this page we will review a few contribs we will make use of for our game. We will do the actual installation
|
||||
of them when we start coding in the next part of this tutorial series. While we will introduce them here, you
|
||||
are wise to read their doc-strings yourself for the details.</p>
|
||||
|
|
@ -73,13 +75,13 @@ are wise to read their doc-strings yourself for the details.</p>
|
|||
</ul>
|
||||
<section id="barter-contrib">
|
||||
<h2>Barter contrib<a class="headerlink" href="#barter-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.barter.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.barter.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>Reviewing this contrib suggests that it allows for safe trading between two parties. The basic principle
|
||||
is that the parties puts up the stuff they want to sell and the system will guarantee that these systems are
|
||||
exactly what is being offered. Both sides can modify their offers (bartering) until both mark themselves happy
|
||||
with the deal. Only then the deal is sealed and the objects are exchanged automatically. Interestingly, this
|
||||
works just fine for money too - just put coin objects on one side of the transaction.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>Sue > trade Tom: Hi, I have a necklace to sell; wanna trade for a healing potion?
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Sue > trade Tom: Hi, I have a necklace to sell; wanna trade for a healing potion?
|
||||
Tom > trade Sue: Hm, I could use a necklace ...
|
||||
<both accepted trade. Start trade>
|
||||
Sue > offer necklace: This necklace is really worth it.
|
||||
|
|
@ -102,20 +104,20 @@ things than boring gold coin.</p>
|
|||
</section>
|
||||
<section id="character-generation-contrib">
|
||||
<h2>Character generation contrib<a class="headerlink" href="#character-generation-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.chargen.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.chargen.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This contrib is an example module for creating characters. Since we will be using <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=3</span></code> we will
|
||||
get a selection screen like this automatically. We also plan to use a proper menu to build our character, so
|
||||
we will <em>not</em> be using this contrib.</p>
|
||||
</section>
|
||||
<section id="clothing-contrib">
|
||||
<h2>Clothing contrib<a class="headerlink" href="#clothing-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.clothing.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.clothing.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This contrib provides a full system primarily aimed at wearing clothes, but it could also work for armor. You wear
|
||||
an object in a particular location and this will then be reflected in your character’s description. You can
|
||||
also add roleplaying flavor:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">wear</span> <span class="n">helmet</span> <span class="n">slightly</span> <span class="n">askew</span> <span class="n">on</span> <span class="n">her</span> <span class="n">head</span>
|
||||
<span class="n">look</span> <span class="bp">self</span>
|
||||
<span class="n">Username</span> <span class="ow">is</span> <span class="n">wearing</span> <span class="n">a</span> <span class="n">helmet</span> <span class="n">slightly</span> <span class="n">askew</span> <span class="n">on</span> <span class="n">her</span> <span class="n">head</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> wear helmet slightly askew on her head
|
||||
look self
|
||||
Username is wearing a helmet slightly askew on her head.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>By default there are no ‘body locations’ in this contrib, we will need to expand on it a little to make it useful
|
||||
|
|
@ -123,16 +125,16 @@ for things like armor. It’s a good contrib to build from though, so that’s w
|
|||
</section>
|
||||
<section id="dice-contrib">
|
||||
<h2>Dice contrib<a class="headerlink" href="#dice-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.dice.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.dice.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>The dice contrib presents a general dice roller to use in game.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">roll</span> <span class="mi">2</span><span class="n">d6</span>
|
||||
<span class="n">Roll</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="mi">2</span> <span class="ow">and</span> <span class="mf">5.</span> <span class="n">Total</span> <span class="n">result</span> <span class="ow">is</span> <span class="mf">7.</span>
|
||||
<span class="o">></span> <span class="n">roll</span> <span class="mi">1</span><span class="n">d100</span> <span class="o">+</span> <span class="mi">2</span>
|
||||
<span class="n">Roll</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="mf">43.</span> <span class="n">Total</span> <span class="n">result</span> <span class="ow">is</span> <span class="mi">47</span>
|
||||
<span class="o">></span> <span class="n">roll</span> <span class="mi">1</span><span class="n">d20</span> <span class="o">></span> <span class="mi">12</span>
|
||||
<span class="n">Roll</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="mf">7.</span> <span class="n">Total</span> <span class="n">result</span> <span class="ow">is</span> <span class="mf">7.</span> <span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">failure</span> <span class="p">(</span><span class="n">by</span> <span class="mi">5</span><span class="p">)</span>
|
||||
<span class="o">></span> <span class="n">roll</span><span class="o">/</span><span class="n">hidden</span> <span class="mi">1</span><span class="n">d20</span> <span class="o">></span> <span class="mi">12</span>
|
||||
<span class="n">Roll</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="mf">18.</span> <span class="n">Total</span> <span class="n">result</span> <span class="ow">is</span> <span class="mf">17.</span> <span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">success</span> <span class="p">(</span><span class="n">by</span> <span class="mi">6</span><span class="p">)</span><span class="o">.</span> <span class="p">(</span><span class="ow">not</span> <span class="n">echoed</span><span class="p">)</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> roll 2d6
|
||||
Roll(s): 2 and 5. Total result is 7.
|
||||
> roll 1d100 + 2
|
||||
Roll(s): 43. Total result is 47
|
||||
> roll 1d20 > 12
|
||||
Roll(s): 7. Total result is 7. This is a failure (by 5)
|
||||
> roll/hidden 1d20 > 12
|
||||
Roll(s): 18. Total result is 17. This is a success (by 6). (not echoed)
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The contrib also has a python function for producing these results in-code. However, while
|
||||
|
|
@ -143,7 +145,7 @@ or play a game, we will not need it for the core of our game.</p>
|
|||
</section>
|
||||
<section id="extended-room-contrib">
|
||||
<h2>Extended room contrib<a class="headerlink" href="#extended-room-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.extended_room.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.extended_room.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This is a custom Room typeclass that changes its description based on time of day and season.</p>
|
||||
<p>For example, at night, in wintertime you could show the room as being dark and frost-covered while in daylight
|
||||
at summer it could describe a flowering meadow. The description can also contain special markers, so
|
||||
|
|
@ -158,25 +160,25 @@ game, why not!</p>
|
|||
</section>
|
||||
<section id="rp-system-contrib">
|
||||
<h2>RP-System contrib<a class="headerlink" href="#rp-system-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.rpsystem.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.rpsystem.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This contrib adds a full roleplaying subsystem to your game. It gives every character a “short-description”
|
||||
(sdesc) that is what people will see when first meeting them. Let’s say Tom has an sdesc “A tall man” and
|
||||
Sue has the sdesc “A muscular, blonde woman”</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tom</span> <span class="o">></span> <span class="n">look</span>
|
||||
<span class="n">Tom</span><span class="p">:</span> <span class="o"><</span><span class="n">room</span> <span class="n">desc</span><span class="o">></span> <span class="o">...</span> <span class="n">You</span> <span class="n">see</span><span class="p">:</span> <span class="n">A</span> <span class="n">muscular</span><span class="p">,</span> <span class="n">blonde</span> <span class="n">woman</span>
|
||||
<span class="n">Tom</span> <span class="o">></span> <span class="n">emote</span> <span class="o">/</span><span class="n">me</span> <span class="n">smiles</span> <span class="n">to</span> <span class="o">/</span><span class="n">muscular</span><span class="o">.</span>
|
||||
<span class="n">Tom</span><span class="p">:</span> <span class="n">Tom</span> <span class="n">smiles</span> <span class="n">to</span> <span class="n">A</span> <span class="n">muscular</span><span class="p">,</span> <span class="n">blonde</span> <span class="n">woman</span><span class="o">.</span>
|
||||
<span class="n">Sue</span><span class="p">:</span> <span class="n">A</span> <span class="n">tall</span> <span class="n">man</span> <span class="n">smiles</span> <span class="n">to</span> <span class="n">Sue</span><span class="o">.</span>
|
||||
<span class="n">Tom</span> <span class="o">></span> <span class="n">emote</span> <span class="n">Leaning</span> <span class="n">forward</span><span class="p">,</span> <span class="o">/</span><span class="n">me</span> <span class="n">says</span><span class="p">,</span> <span class="s2">"Well hello, what's yer name?"</span>
|
||||
<span class="n">Tom</span><span class="p">:</span> <span class="n">Leaning</span> <span class="n">forward</span><span class="p">,</span> <span class="n">Tom</span> <span class="n">says</span><span class="p">,</span> <span class="s2">"Well hello..."</span>
|
||||
<span class="n">Sue</span><span class="p">:</span> <span class="n">Leaning</span> <span class="n">forward</span><span class="p">,</span> <span class="n">A</span> <span class="n">tall</span> <span class="n">man</span> <span class="n">says</span><span class="p">,</span> <span class="s2">"Well hello, what's yer name?"</span>
|
||||
<span class="n">Sue</span> <span class="o">></span> <span class="n">emote</span> <span class="o">/</span><span class="n">me</span> <span class="n">grins</span><span class="o">.</span> <span class="s2">"I'm Angelica"</span><span class="p">,</span> <span class="n">she</span> <span class="n">says</span><span class="o">.</span>
|
||||
<span class="n">Sue</span><span class="p">:</span> <span class="n">Sue</span> <span class="n">grins</span><span class="o">.</span> <span class="s2">"I'm Angelica"</span><span class="p">,</span> <span class="n">she</span> <span class="n">says</span><span class="o">.</span>
|
||||
<span class="n">Tom</span><span class="p">:</span> <span class="n">A</span> <span class="n">muscular</span><span class="p">,</span> <span class="n">blonde</span> <span class="n">woman</span> <span class="n">grins</span><span class="o">.</span> <span class="s2">"I'm Angelica"</span><span class="p">,</span> <span class="n">she</span> <span class="n">says</span><span class="o">.</span>
|
||||
<span class="n">Tom</span> <span class="o">></span> <span class="n">recog</span> <span class="n">muscular</span> <span class="n">Angelica</span>
|
||||
<span class="n">Tom</span> <span class="o">></span> <span class="n">emote</span> <span class="o">/</span><span class="n">me</span> <span class="n">nods</span> <span class="n">to</span> <span class="o">/</span><span class="n">angelica</span><span class="p">:</span> <span class="s2">"I have a message for you ..."</span>
|
||||
<span class="n">Tom</span><span class="p">:</span> <span class="n">Tom</span> <span class="n">nods</span> <span class="n">to</span> <span class="n">Angelica</span><span class="p">:</span> <span class="s2">"I have a message for you ..."</span>
|
||||
<span class="n">Sue</span><span class="p">:</span> <span class="n">A</span> <span class="n">tall</span> <span class="n">man</span> <span class="n">nods</span> <span class="n">to</span> <span class="n">Sue</span><span class="p">:</span> <span class="s2">"I have a message for you ..."</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Tom > look
|
||||
Tom: <room desc> ... You see: A muscular, blonde woman
|
||||
Tom > emote /me smiles to /muscular.
|
||||
Tom: Tom smiles to A muscular, blonde woman.
|
||||
Sue: A tall man smiles to Sue.
|
||||
Tom > emote Leaning forward, /me says, "Well hello, what's yer name?"
|
||||
Tom: Leaning forward, Tom says, "Well hello..."
|
||||
Sue: Leaning forward, A tall man says, "Well hello, what's yer name?"
|
||||
Sue > emote /me grins. "I'm Angelica", she says.
|
||||
Sue: Sue grins. "I'm Angelica", she says.
|
||||
Tom: A muscular, blonde woman grins. "I'm Angelica", she says.
|
||||
Tom > recog muscular Angelica
|
||||
Tom > emote /me nods to /angelica: "I have a message for you ..."
|
||||
Tom: Tom nods to Angelica: "I have a message for you ..."
|
||||
Sue: A tall man nods to Sue: "I have a message for you ..."
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Above, Sue introduces herself as “Angelica” and Tom uses this info to <code class="docutils literal notranslate"><span class="pre">recoc</span></code> her as “Angelica” hereafter. He
|
||||
|
|
@ -184,40 +186,40 @@ could have <code class="docutils literal notranslate"><span class="pre">recoc</s
|
|||
<code class="docutils literal notranslate"><span class="pre">say</span></code>, the spoken words are embedded in the emotes in quotes <code class="docutils literal notranslate"><span class="pre">"..."</span></code>.</p>
|
||||
<p>The RPSystem module also includes options for <code class="docutils literal notranslate"><span class="pre">poses</span></code>, which help to establish your position in the room
|
||||
when others look at you.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tom</span> <span class="o">></span> <span class="n">pose</span> <span class="n">stands</span> <span class="n">by</span> <span class="n">the</span> <span class="n">bar</span><span class="p">,</span> <span class="n">looking</span> <span class="n">bored</span><span class="o">.</span>
|
||||
<span class="n">Sue</span> <span class="o">></span> <span class="n">look</span>
|
||||
<span class="n">Sue</span><span class="p">:</span> <span class="o"><</span><span class="n">room</span> <span class="n">desc</span><span class="o">></span> <span class="o">...</span> <span class="n">A</span> <span class="n">tall</span> <span class="n">man</span> <span class="n">stands</span> <span class="n">by</span> <span class="n">the</span> <span class="n">bar</span><span class="p">,</span> <span class="n">looking</span> <span class="n">bored</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Tom > pose stands by the bar, looking bored.
|
||||
Sue > look
|
||||
Sue: <room desc> ... A tall man stands by the bar, looking bored.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can also wear a mask to hide your identity; your sdesc will then be changed to the sdesc of the mask,
|
||||
like <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">person</span> <span class="pre">with</span> <span class="pre">a</span> <span class="pre">mask</span></code>.</p>
|
||||
<p>The RPSystem gives a lot of roleplaying power out of the box, so we will add it. There is also a separate
|
||||
<a class="reference external" href="../../../api/evennia.contrib.rplanguage.html">rplanguage</a> module that integrates with the spoken words in your emotes and garbles them if you don’t understand
|
||||
<a class="reference internal" href="../../../api/evennia.contrib.rplanguage.html"><span class="doc std std-doc">rplanguage</span></a> module that integrates with the spoken words in your emotes and garbles them if you don’t understand
|
||||
the language spoken. In order to restrict the scope we will not include languages for the tutorial game.</p>
|
||||
</section>
|
||||
<section id="talking-npc-contrib">
|
||||
<h2>Talking NPC contrib<a class="headerlink" href="#talking-npc-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.talking_npc.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.talking_npc.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This exemplifies an NPC with a menu-driven dialogue tree. We will not use this contrib explicitly, but it’s
|
||||
good as inspiration for how we’ll do quest-givers later.</p>
|
||||
</section>
|
||||
<section id="traits-contrib">
|
||||
<h2>Traits contrib<a class="headerlink" href="#traits-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.traits.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.traits.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>An issue with dealing with roleplaying attributes like strength, dexterity, or skills like hunting, sword etc
|
||||
is how to keep track of the values in the moment. Your strength may temporarily be buffed by a strength-potion.
|
||||
Your swordmanship may be worse because you are encumbered. And when you drink your health potion you must make
|
||||
sure that those +20 health does not bring your health higher than its maximum. All this adds complexity.</p>
|
||||
<p>The <em>Traits</em> contrib consists of several types of objects to help track and manage values like this. When
|
||||
installed, the traits are accessed on a new handler <code class="docutils literal notranslate"><span class="pre">.traits</span></code>, for example</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
|
||||
<span class="mi">100</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span> <span class="o">-=</span> <span class="mi">20</span> <span class="c1"># getting hurt</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
|
||||
<span class="mi">80</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span> <span class="c1"># drink a potion</span>
|
||||
<span class="o">></span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
|
||||
<span class="mi">100</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> py self.traits.hp.value
|
||||
100
|
||||
> py self.traits.hp -= 20 # getting hurt
|
||||
> py self.traits.hp.value
|
||||
80
|
||||
> py self.traits.hp.reset() # drink a potion
|
||||
> py self.traits.hp.value
|
||||
100
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A Trait is persistent (it uses an Attribute under the hood) and tracks changes, min/max and other things
|
||||
|
|
@ -253,7 +255,7 @@ effects of slow poisons and healing both.</p></li>
|
|||
</section>
|
||||
<section id="turnbattle-contrib">
|
||||
<h2>Turnbattle contrib<a class="headerlink" href="#turnbattle-contrib" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="../../../api/evennia.contrib.turnbattle.html">source</a></p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.contrib.turnbattle.html"><span class="doc std std-doc">source</span></a></p>
|
||||
<p>This contrib consists of several implementations of a turn-based combat system, divivided into complexity:</p>
|
||||
<ul class="simple">
|
||||
<li><p>basic - initiative and turn order, attacks against defense values, damage.</p></li>
|
||||
|
|
@ -339,7 +341,7 @@ back to your planning and adjust it as you learn what works and what does not.</
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Planning-Some-Useful-Contribs.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,7 +40,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="planning-our-tutorial-game">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="planning-our-tutorial-game">
|
||||
<h1>Planning our tutorial game<a class="headerlink" href="#planning-our-tutorial-game" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Using the general plan from last lesson we’ll now establish what kind of game we want to create for this tutorial.
|
||||
Remembering that we need to keep the scope down, let’s establish some parameters.
|
||||
|
|
@ -101,8 +103,8 @@ goes outside the regular hierarchy and should usually only.</p>
|
|||
other. By default, the <code class="docutils literal notranslate"><span class="pre">public</span></code> channel is created for general discourse.
|
||||
Channels are logged to a file and when you are coming back to the game you can view the history of a channel
|
||||
in case you missed something.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> public Hello world!
|
||||
[Public] MyName: Hello world!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> public Hello world!
|
||||
[Public] MyName: Hello world!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>But Channels can also be set up to work between Characters instead of Accounts. This would mean the channels
|
||||
|
|
@ -149,7 +151,7 @@ build the brunt of things using Evennia’s Batchcode system.</p>
|
|||
the ability to create objects with in-built commands is easy and safe, actual code-creation (aka <em>softcode</em> ) is
|
||||
not something Evennia supports natively. Regular, untrusted users should never be allowed to execute raw Python
|
||||
code (such as what you can do with the <code class="docutils literal notranslate"><span class="pre">py</span></code> command). You can
|
||||
<a class="reference internal" href="../../../Concepts/Soft-Code.html"><span class="doc">read more about Evennia’s stance on softcode here</span></a>. If you want users to do limited scripting,
|
||||
<a class="reference internal" href="../../../Concepts/Soft-Code.html"><span class="doc std std-doc">read more about Evennia’s stance on softcode here</span></a>. If you want users to do limited scripting,
|
||||
it’s suggested that this is accomplished by adding more powerful build-commands for them to use.</p>
|
||||
<p>For our tutorial-game, we will only allow privileged builders to modify the world. The exception is crafting,
|
||||
which we will limit to repairing broken items by combining them with other repair-related items.</p>
|
||||
|
|
@ -556,7 +558,7 @@ to code themselves. So in the next lesson we will check out what help we have fr
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Planning-The-Tutorial-Game.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -48,7 +50,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="where-do-i-begin">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="where-do-i-begin">
|
||||
<h1>Where do I begin?<a class="headerlink" href="#where-do-i-begin" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The good news is that following this Starting tutorial is a great way to begin making an Evennia game.</p>
|
||||
<p>The bad news is that everyone’s different and when it comes to starting your own game there is no
|
||||
|
|
@ -161,7 +163,7 @@ so you can read, understand and replicate example code without being completely
|
|||
</ul>
|
||||
<p>Once you are out of the starting tutorial, you’ll be off to do your own thing.</p>
|
||||
<ul class="simple">
|
||||
<li><p>The starting tutorial cannot cover everything. Skim through the <a class="reference internal" href="../../../index.html"><span class="doc">Evennia docs</span></a>.
|
||||
<li><p>The starting tutorial cannot cover everything. Skim through the <a class="reference internal" href="../../../index.html"><span class="doc std std-doc">Evennia docs</span></a>.
|
||||
Even if you don’t read everything, it gives you a feeling for what’s available should you need
|
||||
to look for something later. Make sure to use the search function.</p></li>
|
||||
<li><p>You can now start by expanding on the tutorial-game we will have created. In the last part there
|
||||
|
|
@ -246,7 +248,7 @@ then try to answer those questions for the sake of creating our little tutorial
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Planning-Where-Do-I-Begin.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="evennia-starting-tutorial-part-2">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="evennia-starting-tutorial-part-2">
|
||||
<h1>Evennia Starting Tutorial (Part 2)<a class="headerlink" href="#evennia-starting-tutorial-part-2" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tutorial Parts</p>
|
||||
|
|
@ -71,9 +73,9 @@ game we want to make. This is a more ‘theoretical’ part where we won’t do
|
|||
programming.</p>
|
||||
<ol class="simple">
|
||||
<li><p>Introduction & Overview (you are here)</p></li>
|
||||
<li><p><a class="reference internal" href="Planning-Where-Do-I-Begin.html"><span class="doc">Where do I begin</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Game-Planning.html"><span class="doc">On planning a game</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Planning-Some-Useful-Contribs.html"><span class="doc">Planning to use some useful Contribs</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Planning-Where-Do-I-Begin.html"><span class="doc std std-doc">Where do I begin</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Game-Planning.html"><span class="doc std std-doc">On planning a game</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Planning-Some-Useful-Contribs.html"><span class="doc std std-doc">Planning to use some useful Contribs</span></a></p></li>
|
||||
</ol>
|
||||
<p>In the process we’ll go through the common questions of “where to start”
|
||||
and “what to think about” when creating a multiplayer online text game.</p>
|
||||
|
|
@ -136,7 +138,7 @@ and “what to think about” when creating a multiplayer online text game.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Starting-Part2.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,7 +40,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="implementing-a-game-rule-system">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="implementing-a-game-rule-system">
|
||||
<h1>Implementing a game rule system<a class="headerlink" href="#implementing-a-game-rule-system" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The simplest way to create an online roleplaying game (at least from a code perspective) is to
|
||||
simply grab a paperback RPG rule book, get a staff of game masters together and start to run scenes
|
||||
|
|
@ -79,23 +81,21 @@ makes it easier to change and update things in one place later.</p></li>
|
|||
values for Health, a list of skills etc, store those things on the Character - don’t store how to
|
||||
roll or change them.</p></li>
|
||||
<li><p>Next is to determine just how you want to store things on your Objects and Characters. You can
|
||||
choose to either store things as individual <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attributes</span></a>, like <code class="docutils literal notranslate"><span class="pre">character.db.STR=34</span></code> and
|
||||
choose to either store things as individual <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attributes</span></a>, like <code class="docutils literal notranslate"><span class="pre">character.db.STR=34</span></code> and
|
||||
<code class="docutils literal notranslate"><span class="pre">character.db.Hunting_skill=20</span></code>. But you could also use some custom storage method, like a
|
||||
dictionary <code class="docutils literal notranslate"><span class="pre">character.db.skills</span> <span class="pre">=</span> <span class="pre">{"Hunting":34,</span> <span class="pre">"Fishing":20,</span> <span class="pre">...}</span></code>. A much more fancy solution is
|
||||
to look at the Ainneve <a class="reference external" href="https://github.com/evennia/ainneve/blob/master/world/traits.py">Trait
|
||||
handler</a>. Finally you could even go
|
||||
with a <a class="reference internal" href="../../../Concepts/New-Models.html"><span class="doc">custom django model</span></a>. Which is the better depends on your game and the
|
||||
with a <a class="reference internal" href="../../../Concepts/New-Models.html"><span class="doc std std-doc">custom django model</span></a>. Which is the better depends on your game and the
|
||||
complexity of your system.</p></li>
|
||||
<li><p>Make a clear <a class="reference external" href="https://en.wikipedia.org/wiki/Application_programming_interface">API</a> into your
|
||||
rules. That is, make methods/functions that you feed with, say, your Character and which skill you
|
||||
want to check. That is, you want something similar to this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">world</span> <span class="kn">import</span> <span class="n">rules</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">world</span> <span class="kn">import</span> <span class="n">rules</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">rules</span><span class="o">.</span><span class="n">roll_skill</span><span class="p">(</span><span class="n">character</span><span class="p">,</span> <span class="s2">"hunting"</span><span class="p">)</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">rules</span><span class="o">.</span><span class="n">roll_challenge</span><span class="p">(</span><span class="n">character1</span><span class="p">,</span> <span class="n">character2</span><span class="p">,</span> <span class="s2">"swords"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<p>You might need to make these functions more or less complex depending on your game. For example the
|
||||
|
|
@ -158,21 +158,7 @@ value goes up by 2 points and <code class="docutils literal notranslate"><span c
|
|||
<h3>Character<a class="headerlink" href="#character" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The Character typeclass is simple. It goes in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code>. There is already
|
||||
an empty <code class="docutils literal notranslate"><span class="pre">Character</span></code> class there that Evennia will look to and use.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
|
||||
<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">randint</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Character</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
|
|
@ -188,7 +174,7 @@ an empty <code class="docutils literal notranslate"><span class="pre">Character<
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">STR</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</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">combat</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">@reload</span></code> the server to load up the new code. Doing <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">self</span></code> will however <em>not</em> show the new
|
||||
Attributes on yourself. This is because the <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> hook is only called on <em>new</em>
|
||||
Characters. Your Character was already created and will thus not have them. To force a reload, use
|
||||
|
|
@ -201,75 +187,7 @@ the following command:</p>
|
|||
<section id="rule-module">
|
||||
<h3>Rule module<a class="headerlink" href="#rule-module" title="Permalink to this headline">¶</a></h3>
|
||||
<p>This is a module <code class="docutils literal notranslate"><span class="pre">mygame/world/rules.py</span></code>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span>
|
||||
<span class="normal">44</span>
|
||||
<span class="normal">45</span>
|
||||
<span class="normal">46</span>
|
||||
<span class="normal">47</span>
|
||||
<span class="normal">48</span>
|
||||
<span class="normal">49</span>
|
||||
<span class="normal">50</span>
|
||||
<span class="normal">51</span>
|
||||
<span class="normal">52</span>
|
||||
<span class="normal">53</span>
|
||||
<span class="normal">54</span>
|
||||
<span class="normal">55</span>
|
||||
<span class="normal">56</span>
|
||||
<span class="normal">57</span>
|
||||
<span class="normal">58</span>
|
||||
<span class="normal">59</span>
|
||||
<span class="normal">60</span>
|
||||
<span class="normal">61</span>
|
||||
<span class="normal">62</span>
|
||||
<span class="normal">63</span>
|
||||
<span class="normal">64</span>
|
||||
<span class="normal">65</span>
|
||||
<span class="normal">66</span>
|
||||
<span class="normal">67</span>
|
||||
<span class="normal">68</span>
|
||||
<span class="normal">69</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
|
||||
<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">randint</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">roll_hit</span><span class="p">():</span>
|
||||
<span class="s2">"Roll 1d100"</span>
|
||||
|
|
@ -339,7 +257,7 @@ the following command:</p>
|
|||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="n">RunTimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Skillname </span><span class="si">{</span><span class="n">skillname</span><span class="si">}</span><span class="s2"> not found."</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>These few functions implement the entirety of our simple rule system. We have a function to check
|
||||
the “defeat” condition and reset the <code class="docutils literal notranslate"><span class="pre">HP</span></code> back to 100 again. We define a generic “skill” function.
|
||||
Multiple skills could all be added with the same signature; our <code class="docutils literal notranslate"><span class="pre">SKILLS</span></code> dictionary makes it easy to
|
||||
|
|
@ -348,30 +266,7 @@ function <code class="docutils literal notranslate"><span class="pre">roll_chall
|
|||
<p>In this example, the skill function actually does a lot - it not only rolls results, it also informs
|
||||
everyone of their results via <code class="docutils literal notranslate"><span class="pre">character.msg()</span></code> calls.</p>
|
||||
<p>Here is an example of usage in a game command:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||||
<span class="kn">from</span> <span class="nn">world</span> <span class="kn">import</span> <span class="n">rules</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdAttack</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
|
|
@ -396,7 +291,7 @@ everyone of their results via <code class="docutils literal notranslate"><span c
|
|||
<span class="k">if</span> <span class="n">target</span><span class="p">:</span>
|
||||
<span class="n">rules</span><span class="o">.</span><span class="n">roll_challenge</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="s2">"combat"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Note how simple the command becomes and how generic you can make it. It becomes simple to offer any
|
||||
number of Combat commands by just extending this functionality - you can easily roll challenges and
|
||||
pick different skills to check. And if you ever decided to, say, change how to determine hit chance,
|
||||
|
|
@ -460,7 +355,7 @@ your <code class="docutils literal notranslate"><span class="pre">rules</span></
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Implementing-a-game-rule-system.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -48,11 +50,11 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="evennia-starting-tutorial-part-3">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="evennia-starting-tutorial-part-3">
|
||||
<h1>Evennia Starting Tutorial (Part 3)<a class="headerlink" href="#evennia-starting-tutorial-part-3" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tutorial Parts</p>
|
||||
<dl class="simple">
|
||||
<p>sidebar:: Tutorial Parts</p>
|
||||
<blockquote>
|
||||
<div><dl class="simple">
|
||||
<dt>Part 1: <a class="reference external" href="../Part1/Starting-Part1.html">What we have</a></dt><dd><p>A tour of Evennia and how to use the tools, including an introduction to Python.</p>
|
||||
</dd>
|
||||
<dt>Part 2: <a class="reference external" href="../Part2/Starting-Part2.html">What we want</a></dt><dd><p>Planning our tutorial game and what to think about when planning your own in the future.</p>
|
||||
|
|
@ -64,22 +66,22 @@
|
|||
<dt>Part 5: <a class="reference external" href="../Part5/Starting-Part5.html">Showing the world</a></dt><dd><p>Taking our new game online and let players try it out</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</aside>
|
||||
</div></blockquote>
|
||||
<p>In part three of the Evennia Starting tutorial we will go through the creation of several key parts
|
||||
of our tutorial game <em>EvAdventure</em>. As we go, we will test each part and create a simple “tech demo” to
|
||||
show off all the moving parts.</p>
|
||||
<ol class="simple">
|
||||
<li><p>Introduction & Overview (you are here)</p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Changing settings</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Applying contribs</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Creating a rule module</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Tweaking the base Typeclasses</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Character creation menu</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Wearing armor and wielding weapons</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Two types of combat</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Monsters and AI</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Questing and rewards</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc">Overview of Tech demo</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Changing settings</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Applying contribs</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Creating a rule module</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Tweaking the base Typeclasses</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Character creation menu</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Wearing armor and wielding weapons</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Two types of combat</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Monsters and AI</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Questing and rewards</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="../../../Unimplemented.html"><span class="doc std std-doc">Overview of Tech demo</span></a></p></li>
|
||||
</ol>
|
||||
<p>If you followed the previous parts of this tutorial you will have some notions about Python and where to find
|
||||
and make use of things in Evennia. We also have a good idea of the type of game we want.
|
||||
|
|
@ -136,7 +138,7 @@ with using Evennia. This be of much use when doing your own thing later.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Starting-Part3.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,7 +40,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="turn-based-combat-system">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="turn-based-combat-system">
|
||||
<h1>Turn based Combat System<a class="headerlink" href="#turn-based-combat-system" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This tutorial gives an example of a full, if simplified, combat system for Evennia. It was inspired
|
||||
by the discussions held on the <a class="reference external" href="https://groups.google.com/forum/#%21msg/evennia/wnJNM2sXSfs/-dbLRrgWnYMJ">mailing
|
||||
|
|
@ -68,7 +70,7 @@ allows for emoting as part of combat which is an advantage for roleplay-heavy ga
|
|||
<p>To implement a freeform combat system all you need is a dice roller and a roleplaying rulebook. See
|
||||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/contrib/dice.py">contrib/dice.py</a> for an
|
||||
example dice roller. To implement at twitch-based system you basically need a few combat
|
||||
<a class="reference internal" href="../../../Components/Commands.html"><span class="doc">commands</span></a>, possibly ones with a <a class="reference internal" href="../../Command-Cooldown.html"><span class="doc">cooldown</span></a>. You also need a <a class="reference internal" href="Implementing-a-game-rule-system.html"><span class="doc">game rule
|
||||
<a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">commands</span></a>, possibly ones with a <a class="reference internal" href="../../Command-Cooldown.html"><span class="doc std std-doc">cooldown</span></a>. You also need a <a class="reference internal" href="Implementing-a-game-rule-system.html"><span class="doc std std-doc">game rule
|
||||
module</span></a> that makes use of it. We will focus on the turn-based
|
||||
variety here.</p>
|
||||
</section>
|
||||
|
|
@ -86,7 +88,7 @@ free.</p></li>
|
|||
<li><p>The commands are (in our example) simple; they can either <code class="docutils literal notranslate"><span class="pre">hit</span> <span class="pre"><target></span></code>, <code class="docutils literal notranslate"><span class="pre">feint</span> <span class="pre"><target></span></code> or
|
||||
<code class="docutils literal notranslate"><span class="pre">parry</span> <span class="pre"><target></span></code>. They can also <code class="docutils literal notranslate"><span class="pre">defend</span></code>, a generic passive defense. Finally they may choose to
|
||||
<code class="docutils literal notranslate"><span class="pre">disengage/flee</span></code>.</p></li>
|
||||
<li><p>When attacking we use a classic [rock-paper-scissors](https://en.wikipedia.org/wiki/Rock-paper-
|
||||
<li><p>When attacking we use a classic [rock-paper-scissors](<a class="reference external" href="https://en.wikipedia.org/wiki/Rock-paper-">https://en.wikipedia.org/wiki/Rock-paper-</a>
|
||||
scissors) mechanic to determine success: <code class="docutils literal notranslate"><span class="pre">hit</span></code> defeats <code class="docutils literal notranslate"><span class="pre">feint</span></code>, which defeats <code class="docutils literal notranslate"><span class="pre">parry</span></code> which defeats
|
||||
<code class="docutils literal notranslate"><span class="pre">hit</span></code>. <code class="docutils literal notranslate"><span class="pre">defend</span></code> is a general passive action that has a percentage chance to win against <code class="docutils literal notranslate"><span class="pre">hit</span></code>
|
||||
(only).</p></li>
|
||||
|
|
@ -98,23 +100,23 @@ reported. A new turn then begins.</p></li>
|
|||
</ul>
|
||||
<p>For creating the combat system we will need the following components:</p>
|
||||
<ul class="simple">
|
||||
<li><p>A combat handler. This is the main mechanic of the system. This is a <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Script</span></a> object
|
||||
<li><p>A combat handler. This is the main mechanic of the system. This is a <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Script</span></a> object
|
||||
created for each combat. It is not assigned to a specific object but is shared by the combating
|
||||
characters and handles all the combat information. Since Scripts are database entities it also means
|
||||
that the combat will not be affected by a server reload.</p></li>
|
||||
<li><p>A combat <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc">command set</span></a> with the relevant commands needed for combat, such as the
|
||||
<li><p>A combat <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc std std-doc">command set</span></a> with the relevant commands needed for combat, such as the
|
||||
various attack/defend options and the <code class="docutils literal notranslate"><span class="pre">flee/disengage</span></code> command to leave the combat mode.</p></li>
|
||||
<li><p>A rule resolution system. The basics of making such a module is described in the <a class="reference internal" href="Implementing-a-game-rule-system.html"><span class="doc">rule system
|
||||
<li><p>A rule resolution system. The basics of making such a module is described in the <a class="reference internal" href="Implementing-a-game-rule-system.html"><span class="doc std std-doc">rule system
|
||||
tutorial</span></a>. We will only sketch such a module here for our end-turn
|
||||
combat resolution.</p></li>
|
||||
<li><p>An <code class="docutils literal notranslate"><span class="pre">attack</span></code> <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">command</span></a> for initiating the combat mode. This is added to the default
|
||||
<li><p>An <code class="docutils literal notranslate"><span class="pre">attack</span></code> <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">command</span></a> for initiating the combat mode. This is added to the default
|
||||
command set. It will create the combat handler and add the character(s) to it. It will also assign
|
||||
the combat command set to the characters.</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="the-combat-handler">
|
||||
<h2>The combat handler<a class="headerlink" href="#the-combat-handler" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <em>combat handler</em> is implemented as a stand-alone <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc">Script</span></a>. This Script is created when
|
||||
<p>The <em>combat handler</em> is implemented as a stand-alone <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Script</span></a>. This Script is created when
|
||||
the first Character decides to attack another and is deleted when no one is fighting any more. Each
|
||||
handler represents one instance of combat and one combat only. Each instance of combat can hold any
|
||||
number of characters but each character can only be part of one combat at a time (a player would
|
||||
|
|
@ -125,172 +127,12 @@ combat. Vice-versa, all characters holds a back-reference to the current combat
|
|||
don’t use this very much here this might allow the combat commands on the characters to access and
|
||||
update the combat handler state directly.</p>
|
||||
<p><em>Note: Another way to implement a combat handler would be to use a normal Python object and handle
|
||||
time-keeping with the <a class="reference internal" href="../../../Components/TickerHandler.html"><span class="doc">TickerHandler</span></a>. This would require either adding custom hook
|
||||
time-keeping with the <a class="reference internal" href="../../../Components/TickerHandler.html"><span class="doc std std-doc">TickerHandler</span></a>. This would require either adding custom hook
|
||||
methods on the character or to implement a custom child of the TickerHandler class to track turns.
|
||||
Whereas the TickerHandler is easy to use, a Script offers more power in this case.</em></p>
|
||||
<p>Here is a basic combat handler. Assuming our game folder is named <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, we store it in
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/combat_handler.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal"> 10</span>
|
||||
<span class="normal"> 11</span>
|
||||
<span class="normal"> 12</span>
|
||||
<span class="normal"> 13</span>
|
||||
<span class="normal"> 14</span>
|
||||
<span class="normal"> 15</span>
|
||||
<span class="normal"> 16</span>
|
||||
<span class="normal"> 17</span>
|
||||
<span class="normal"> 18</span>
|
||||
<span class="normal"> 19</span>
|
||||
<span class="normal"> 20</span>
|
||||
<span class="normal"> 21</span>
|
||||
<span class="normal"> 22</span>
|
||||
<span class="normal"> 23</span>
|
||||
<span class="normal"> 24</span>
|
||||
<span class="normal"> 25</span>
|
||||
<span class="normal"> 26</span>
|
||||
<span class="normal"> 27</span>
|
||||
<span class="normal"> 28</span>
|
||||
<span class="normal"> 29</span>
|
||||
<span class="normal"> 30</span>
|
||||
<span class="normal"> 31</span>
|
||||
<span class="normal"> 32</span>
|
||||
<span class="normal"> 33</span>
|
||||
<span class="normal"> 34</span>
|
||||
<span class="normal"> 35</span>
|
||||
<span class="normal"> 36</span>
|
||||
<span class="normal"> 37</span>
|
||||
<span class="normal"> 38</span>
|
||||
<span class="normal"> 39</span>
|
||||
<span class="normal"> 40</span>
|
||||
<span class="normal"> 41</span>
|
||||
<span class="normal"> 42</span>
|
||||
<span class="normal"> 43</span>
|
||||
<span class="normal"> 44</span>
|
||||
<span class="normal"> 45</span>
|
||||
<span class="normal"> 46</span>
|
||||
<span class="normal"> 47</span>
|
||||
<span class="normal"> 48</span>
|
||||
<span class="normal"> 49</span>
|
||||
<span class="normal"> 50</span>
|
||||
<span class="normal"> 51</span>
|
||||
<span class="normal"> 52</span>
|
||||
<span class="normal"> 53</span>
|
||||
<span class="normal"> 54</span>
|
||||
<span class="normal"> 55</span>
|
||||
<span class="normal"> 56</span>
|
||||
<span class="normal"> 57</span>
|
||||
<span class="normal"> 58</span>
|
||||
<span class="normal"> 59</span>
|
||||
<span class="normal"> 60</span>
|
||||
<span class="normal"> 61</span>
|
||||
<span class="normal"> 62</span>
|
||||
<span class="normal"> 63</span>
|
||||
<span class="normal"> 64</span>
|
||||
<span class="normal"> 65</span>
|
||||
<span class="normal"> 66</span>
|
||||
<span class="normal"> 67</span>
|
||||
<span class="normal"> 68</span>
|
||||
<span class="normal"> 69</span>
|
||||
<span class="normal"> 70</span>
|
||||
<span class="normal"> 71</span>
|
||||
<span class="normal"> 72</span>
|
||||
<span class="normal"> 73</span>
|
||||
<span class="normal"> 74</span>
|
||||
<span class="normal"> 75</span>
|
||||
<span class="normal"> 76</span>
|
||||
<span class="normal"> 77</span>
|
||||
<span class="normal"> 78</span>
|
||||
<span class="normal"> 79</span>
|
||||
<span class="normal"> 80</span>
|
||||
<span class="normal"> 81</span>
|
||||
<span class="normal"> 82</span>
|
||||
<span class="normal"> 83</span>
|
||||
<span class="normal"> 84</span>
|
||||
<span class="normal"> 85</span>
|
||||
<span class="normal"> 86</span>
|
||||
<span class="normal"> 87</span>
|
||||
<span class="normal"> 88</span>
|
||||
<span class="normal"> 89</span>
|
||||
<span class="normal"> 90</span>
|
||||
<span class="normal"> 91</span>
|
||||
<span class="normal"> 92</span>
|
||||
<span class="normal"> 93</span>
|
||||
<span class="normal"> 94</span>
|
||||
<span class="normal"> 95</span>
|
||||
<span class="normal"> 96</span>
|
||||
<span class="normal"> 97</span>
|
||||
<span class="normal"> 98</span>
|
||||
<span class="normal"> 99</span>
|
||||
<span class="normal">100</span>
|
||||
<span class="normal">101</span>
|
||||
<span class="normal">102</span>
|
||||
<span class="normal">103</span>
|
||||
<span class="normal">104</span>
|
||||
<span class="normal">105</span>
|
||||
<span class="normal">106</span>
|
||||
<span class="normal">107</span>
|
||||
<span class="normal">108</span>
|
||||
<span class="normal">109</span>
|
||||
<span class="normal">110</span>
|
||||
<span class="normal">111</span>
|
||||
<span class="normal">112</span>
|
||||
<span class="normal">113</span>
|
||||
<span class="normal">114</span>
|
||||
<span class="normal">115</span>
|
||||
<span class="normal">116</span>
|
||||
<span class="normal">117</span>
|
||||
<span class="normal">118</span>
|
||||
<span class="normal">119</span>
|
||||
<span class="normal">120</span>
|
||||
<span class="normal">121</span>
|
||||
<span class="normal">122</span>
|
||||
<span class="normal">123</span>
|
||||
<span class="normal">124</span>
|
||||
<span class="normal">125</span>
|
||||
<span class="normal">126</span>
|
||||
<span class="normal">127</span>
|
||||
<span class="normal">128</span>
|
||||
<span class="normal">129</span>
|
||||
<span class="normal">130</span>
|
||||
<span class="normal">131</span>
|
||||
<span class="normal">132</span>
|
||||
<span class="normal">133</span>
|
||||
<span class="normal">134</span>
|
||||
<span class="normal">135</span>
|
||||
<span class="normal">136</span>
|
||||
<span class="normal">137</span>
|
||||
<span class="normal">138</span>
|
||||
<span class="normal">139</span>
|
||||
<span class="normal">140</span>
|
||||
<span class="normal">141</span>
|
||||
<span class="normal">142</span>
|
||||
<span class="normal">143</span>
|
||||
<span class="normal">144</span>
|
||||
<span class="normal">145</span>
|
||||
<span class="normal">146</span>
|
||||
<span class="normal">147</span>
|
||||
<span class="normal">148</span>
|
||||
<span class="normal">149</span>
|
||||
<span class="normal">150</span>
|
||||
<span class="normal">151</span>
|
||||
<span class="normal">152</span>
|
||||
<span class="normal">153</span>
|
||||
<span class="normal">154</span>
|
||||
<span class="normal">155</span>
|
||||
<span class="normal">156</span>
|
||||
<span class="normal">157</span>
|
||||
<span class="normal">158</span>
|
||||
<span class="normal">159</span>
|
||||
<span class="normal">160</span>
|
||||
<span class="normal">161</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/typeclasses/combat_handler.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/typeclasses/combat_handler.py</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">random</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultScript</span>
|
||||
|
|
@ -452,7 +294,7 @@ Whereas the TickerHandler is easy to use, a Script offers more power in this cas
|
|||
<span class="p">(</span><span class="s2">"defend"</span><span class="p">,</span> <span class="n">character</span><span class="p">,</span> <span class="kc">None</span><span class="p">)]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg_all</span><span class="p">(</span><span class="s2">"Next turn begins ..."</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This implements all the useful properties of our combat handler. This Script will survive a reboot
|
||||
and will automatically re-assert itself when it comes back online. Even the current state of the
|
||||
combat should be unaffected since it is saved in Attributes at every turn. An important part to note
|
||||
|
|
@ -468,41 +310,7 @@ an exercise.</p>
|
|||
example) very simple. In a full implementation the commands available might be determined by the
|
||||
weapon(s) held by the player or by which skills they know.</p>
|
||||
<p>We create them in <code class="docutils literal notranslate"><span class="pre">mygame/commands/combat.py</span></code>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span>
|
||||
|
||||
|
|
@ -538,31 +346,12 @@ weapon(s) held by the player or by which skills they know.</p>
|
|||
<span class="c1"># tell the handler to check if turn is over</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">combat_handler</span><span class="o">.</span><span class="n">check_end_turn</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The other commands <code class="docutils literal notranslate"><span class="pre">CmdParry</span></code>, <code class="docutils literal notranslate"><span class="pre">CmdFeint</span></code>, <code class="docutils literal notranslate"><span class="pre">CmdDefend</span></code> and <code class="docutils literal notranslate"><span class="pre">CmdDisengage</span></code> look basically the same.
|
||||
We should also add a custom <code class="docutils literal notranslate"><span class="pre">help</span></code> command to list all the available combat commands and what they
|
||||
do.</p>
|
||||
<p>We just need to put them all in a cmdset. We do this at the end of the same module:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">CmdSet</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">default_cmds</span>
|
||||
|
|
@ -583,7 +372,7 @@ do.</p>
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdPose</span><span class="p">())</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdSay</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="rules-module">
|
||||
<h2>Rules module<a class="headerlink" href="#rules-module" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -611,83 +400,7 @@ subsequent attack and so on …</em></p>
|
|||
<li><p><code class="docutils literal notranslate"><span class="pre">flee/disengage</span></code> must succeed two times in a row (i.e. not beaten by a <code class="docutils literal notranslate"><span class="pre">hit</span></code> once during the
|
||||
turn). If so the character leaves combat.</p></li>
|
||||
</ul>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span>
|
||||
<span class="normal">44</span>
|
||||
<span class="normal">45</span>
|
||||
<span class="normal">46</span>
|
||||
<span class="normal">47</span>
|
||||
<span class="normal">48</span>
|
||||
<span class="normal">49</span>
|
||||
<span class="normal">50</span>
|
||||
<span class="normal">51</span>
|
||||
<span class="normal">52</span>
|
||||
<span class="normal">53</span>
|
||||
<span class="normal">54</span>
|
||||
<span class="normal">55</span>
|
||||
<span class="normal">56</span>
|
||||
<span class="normal">57</span>
|
||||
<span class="normal">58</span>
|
||||
<span class="normal">59</span>
|
||||
<span class="normal">60</span>
|
||||
<span class="normal">61</span>
|
||||
<span class="normal">62</span>
|
||||
<span class="normal">63</span>
|
||||
<span class="normal">64</span>
|
||||
<span class="normal">65</span>
|
||||
<span class="normal">66</span>
|
||||
<span class="normal">67</span>
|
||||
<span class="normal">68</span>
|
||||
<span class="normal">69</span>
|
||||
<span class="normal">70</span>
|
||||
<span class="normal">71</span>
|
||||
<span class="normal">72</span>
|
||||
<span class="normal">73</span>
|
||||
<span class="normal">74</span>
|
||||
<span class="normal">75</span>
|
||||
<span class="normal">76</span>
|
||||
<span class="normal">77</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/rules.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/rules.py</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">random</span>
|
||||
|
||||
|
|
@ -765,7 +478,7 @@ turn). If so the character leaves combat.</p></li>
|
|||
<span class="n">combat_handler</span><span class="o">.</span><span class="n">msg_all</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">char</span><span class="si">}</span><span class="s2"> withdraws from combat."</span><span class="p">)</span>
|
||||
<span class="n">combat_handler</span><span class="o">.</span><span class="n">remove_character</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>To make it simple (and to save space), this example rule module actually resolves each interchange
|
||||
twice - first when it gets to each character and then again when handling the target. Also, since we
|
||||
use the combat handler’s <code class="docutils literal notranslate"><span class="pre">msg_all</span></code> method here, the system will get pretty spammy. To clean it up,
|
||||
|
|
@ -776,43 +489,7 @@ reported once.</p>
|
|||
<h2>Combat initiator command<a class="headerlink" href="#combat-initiator-command" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This is the last component we need, a command to initiate combat. This will tie everything together.
|
||||
We store this with the other combat commands.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/commands/combat.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_script</span>
|
||||
|
||||
|
|
@ -850,9 +527,9 @@ We store this with the other combat commands.</p>
|
|||
<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="sa">f</span><span class="s2">"You attack </span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2">! You are in combat."</span><span class="p">)</span>
|
||||
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="si">}</span><span class="s2"> attacks you! You are in combat."</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">attack</span></code> command will not go into the combat cmdset but rather into the default cmdset. See e.g.
|
||||
the <a class="reference internal" href="../Part1/Adding-Commands.html"><span class="doc">Adding Command Tutorial</span></a> if you are unsure about how to do this.</p>
|
||||
the <a class="reference internal" href="../Part1/Adding-Commands.html"><span class="doc std std-doc">Adding Command Tutorial</span></a> if you are unsure about how to do this.</p>
|
||||
</section>
|
||||
<section id="expanding-the-example">
|
||||
<h2>Expanding the example<a class="headerlink" href="#expanding-the-example" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -921,7 +598,7 @@ show others what’s going on.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Turn-based-Combat-System.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,14 +40,14 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="tutorial-for-basic-mush-like-game">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="tutorial-for-basic-mush-like-game">
|
||||
<h1>Tutorial for basic MUSH like game<a class="headerlink" href="#tutorial-for-basic-mush-like-game" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This tutorial lets you code a small but complete and functioning MUSH-like game in Evennia. A
|
||||
<a class="reference external" href="https://en.wikipedia.org/wiki/MUSH">MUSH</a> is, for our purposes, a class of roleplay-centric games
|
||||
focused on free form storytelling. Even if you are not interested in MUSH:es, this is still a good
|
||||
first game-type to try since it’s not so code heavy. You will be able to use the same principles for
|
||||
building other types of games.</p>
|
||||
<p>The tutorial starts from scratch. If you did the <a class="reference internal" href="../Part1/Starting-Part1.html"><span class="doc">First Steps Coding</span></a> tutorial
|
||||
<p>The tutorial starts from scratch. If you did the <a class="reference internal" href="../Part1/Starting-Part1.html"><span class="doc std std-doc">First Steps Coding</span></a> tutorial
|
||||
already you should have some ideas about how to do some of the steps already.</p>
|
||||
<p>The following are the (very simplistic and cut-down) features we will implement (this was taken from
|
||||
a feature request from a MUSH user new to Evennia). A Character in this system should:</p>
|
||||
|
|
@ -79,18 +81,7 @@ SQLite3 database.</p>
|
|||
<p>First thing is to choose how our Character class works. We don’t need to define a special NPC object
|
||||
– an NPC is after all just a Character without an Account currently controlling them.</p>
|
||||
<p>Make your changes in the <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> file:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/typeclasses/characters.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/typeclasses/characters.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
||||
|
|
@ -103,19 +94,19 @@ SQLite3 database.</p>
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">power</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_score</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>We defined two new <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attributes</span></a> <code class="docutils literal notranslate"><span class="pre">power</span></code> and <code class="docutils literal notranslate"><span class="pre">combat_score</span></code> and set them to default
|
||||
</div>
|
||||
<p>We defined two new <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attributes</span></a> <code class="docutils literal notranslate"><span class="pre">power</span></code> and <code class="docutils literal notranslate"><span class="pre">combat_score</span></code> and set them to default
|
||||
values. Make sure to <code class="docutils literal notranslate"><span class="pre">@reload</span></code> the server if you had it already running (you need to reload every
|
||||
time you update your python code, don’t worry, no accounts will be disconnected by the reload).</p>
|
||||
<p>Note that only <em>new</em> characters will see your new Attributes (since the <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> hook is
|
||||
called when the object is first created, existing Characters won’t have it). To update yourself,
|
||||
run</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="nd">@typeclass</span><span class="o">/</span><span class="n">force</span> <span class="bp">self</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> @typeclass/force self
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This resets your own typeclass (the <code class="docutils literal notranslate"><span class="pre">/force</span></code> switch is a safety measure to not do this
|
||||
accidentally), this means that <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> is re-run.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">examine</span> <span class="bp">self</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> examine self
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Under the “Persistent attributes” heading you should now find the new Attributes <code class="docutils literal notranslate"><span class="pre">power</span></code> and <code class="docutils literal notranslate"><span class="pre">score</span></code>
|
||||
|
|
@ -134,8 +125,8 @@ example, we could simply set an <code class="docutils literal notranslate"><span
|
|||
check it. Using this method however will make it easy to add more functionality later.</p>
|
||||
<p>What we need are the following:</p>
|
||||
<ul class="simple">
|
||||
<li><p>One character generation <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Command</span></a> to set the “Power” on the <code class="docutils literal notranslate"><span class="pre">Character</span></code>.</p></li>
|
||||
<li><p>A chargen <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc">CmdSet</span></a> to hold this command. Lets call it <code class="docutils literal notranslate"><span class="pre">ChargenCmdset</span></code>.</p></li>
|
||||
<li><p>One character generation <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Command</span></a> to set the “Power” on the <code class="docutils literal notranslate"><span class="pre">Character</span></code>.</p></li>
|
||||
<li><p>A chargen <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc std std-doc">CmdSet</span></a> to hold this command. Lets call it <code class="docutils literal notranslate"><span class="pre">ChargenCmdset</span></code>.</p></li>
|
||||
<li><p>A custom <code class="docutils literal notranslate"><span class="pre">ChargenRoom</span></code> type that makes this set of commands available to players in such rooms.</p></li>
|
||||
<li><p>One such room to test things in.</p></li>
|
||||
</ul>
|
||||
|
|
@ -143,9 +134,9 @@ check it. Using this method however will make it easy to add more functionality
|
|||
<h3>The +setpower command<a class="headerlink" href="#the-setpower-command" title="Permalink to this headline">¶</a></h3>
|
||||
<p>For this tutorial we will add all our new commands to <code class="docutils literal notranslate"><span class="pre">mygame/commands/command.py</span></code> but you could
|
||||
split your commands into multiple module if you prefered.</p>
|
||||
<p>For this tutorial character generation will only consist of one <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Command</span></a> to set the
|
||||
<p>For this tutorial character generation will only consist of one <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Command</span></a> to set the
|
||||
Character s “power” stat. It will be called on the following MUSH-like form:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">+</span><span class="n">setpower</span> <span class="mi">4</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> +setpower 4
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Open <code class="docutils literal notranslate"><span class="pre">command.py</span></code> file. It contains documented empty templates for the base command and the
|
||||
|
|
@ -153,40 +144,7 @@ Character s “power” stat. It will be called on the following MUSH-like form:
|
|||
<code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> class offers some extra features like stripping whitespace that may be useful - if so,
|
||||
just import from that instead.</p>
|
||||
<p>Add the following to the end of the <code class="docutils literal notranslate"><span class="pre">command.py</span></code> file:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># end of command.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># end of command.py</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span> <span class="c1"># just for clarity; already imported above</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdSetPower</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
|
|
@ -221,31 +179,21 @@ just import from that instead.</p>
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">power</span> <span class="o">=</span> <span class="n">power</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="sa">f</span><span class="s2">"Your Power was set to </span><span class="si">{</span><span class="n">power</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This is a pretty straightforward command. We do some error checking, then set the power on ourself.
|
||||
We use a <code class="docutils literal notranslate"><span class="pre">help_category</span></code> of “mush” for all our commands, just so they are easy to find and separate
|
||||
in the help list.</p>
|
||||
<p>Save the file. We will now add it to a new <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc">CmdSet</span></a> so it can be accessed (in a full
|
||||
<p>Save the file. We will now add it to a new <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc std std-doc">CmdSet</span></a> so it can be accessed (in a full
|
||||
chargen system you would of course have more than one command here).</p>
|
||||
<p>Open <code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code> and import your <code class="docutils literal notranslate"><span class="pre">command.py</span></code> module at the top. We also
|
||||
import the default <code class="docutils literal notranslate"><span class="pre">CmdSet</span></code> class for the next step:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">CmdSet</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">CmdSet</span>
|
||||
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">command</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Next scroll down and define a new command set (based on the base <code class="docutils literal notranslate"><span class="pre">CmdSet</span></code> class we just imported at
|
||||
the end of this file, to hold only our chargen-specific command(s):</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># end of default_cmdsets.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># end of default_cmdsets.py</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">ChargenCmdset</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -256,7 +204,7 @@ the end of this file, to hold only our chargen-specific command(s):</p>
|
|||
<span class="s2">"This is called at initialization"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">command</span><span class="o">.</span><span class="n">CmdSetPower</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>In the future you can add any number of commands to this cmdset, to expand your character generation
|
||||
system as you desire. Now we need to actually put that cmdset on something so it’s made available to
|
||||
users. We could put it directly on the Character, but that would make it available all the time.
|
||||
|
|
@ -266,19 +214,7 @@ It’s cleaner to put it on a room, so it’s only available when players are in
|
|||
<h3>Chargen areas<a class="headerlink" href="#chargen-areas" title="Permalink to this headline">¶</a></h3>
|
||||
<p>We will create a simple Room typeclass to act as a template for all our Chargen areas. Edit
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/rooms.py</span></code> next:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">commands.default_cmdsets</span> <span class="kn">import</span> <span class="n">ChargenCmdset</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">commands.default_cmdsets</span> <span class="kn">import</span> <span class="n">ChargenCmdset</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
<span class="c1"># down at the end of rooms.py</span>
|
||||
|
|
@ -292,10 +228,10 @@ It’s cleaner to put it on a room, so it’s only available when players are in
|
|||
<span class="s2">"this is called only at first creation"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">ChargenCmdset</span><span class="p">,</span> <span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Note how new rooms created with this typeclass will always start with <code class="docutils literal notranslate"><span class="pre">ChargenCmdset</span></code> on themselves.
|
||||
Don’t forget the <code class="docutils literal notranslate"><span class="pre">persistent=True</span></code> keyword or you will lose the cmdset after a server reload. For
|
||||
more information about <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc">Command Sets</span></a> and <a class="reference internal" href="../../../Components/Commands.html"><span class="doc">Commands</span></a>, see the respective
|
||||
more information about <a class="reference internal" href="../../../Components/Command-Sets.html"><span class="doc std std-doc">Command Sets</span></a> and <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a>, see the respective
|
||||
links.</p>
|
||||
</section>
|
||||
<section id="testing-chargen">
|
||||
|
|
@ -305,7 +241,7 @@ your new python code added to the game. Check your terminal and fix any errors y
|
|||
traceback lists exactly where the error is found - look line numbers in files you have changed.</p>
|
||||
<p>We can’t test things unless we have some chargen areas to test. Log into the game (you should at
|
||||
this point be using the new, custom Character class). Let’s dig a chargen area to test.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="nd">@dig</span> <span class="n">chargen</span><span class="p">:</span><span class="n">rooms</span><span class="o">.</span><span class="n">ChargenRoom</span> <span class="o">=</span> <span class="n">chargen</span><span class="p">,</span><span class="n">finish</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> @dig chargen:rooms.ChargenRoom = chargen,finish
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you read the help for <code class="docutils literal notranslate"><span class="pre">@dig</span></code> you will find that this will create a new room named <code class="docutils literal notranslate"><span class="pre">chargen</span></code>. The
|
||||
|
|
@ -319,13 +255,13 @@ as <code class="docutils literal notranslate"><span class="pre">chargen;characte
|
|||
an exit back here named <code class="docutils literal notranslate"><span class="pre">finish</span></code>. If you see errors at this stage, you must fix them in your code.
|
||||
<code class="docutils literal notranslate"><span class="pre">@reload</span></code>
|
||||
between fixes. Don’t continue until the creation seems to have worked okay.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">chargen</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> chargen
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This should bring you to the chargen room. Being in there you should now have the <code class="docutils literal notranslate"><span class="pre">+setpower</span></code>
|
||||
command available, so test it out. When you leave (via the <code class="docutils literal notranslate"><span class="pre">finish</span></code> exit), the command will go away
|
||||
and trying <code class="docutils literal notranslate"><span class="pre">+setpower</span></code> should now give you a command-not-found error. Use <code class="docutils literal notranslate"><span class="pre">ex</span> <span class="pre">me</span></code> (as a privileged
|
||||
user) to check so the <code class="docutils literal notranslate"><span class="pre">Power</span></code> <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attribute</span></a> has been set correctly.</p>
|
||||
user) to check so the <code class="docutils literal notranslate"><span class="pre">Power</span></code> <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attribute</span></a> has been set correctly.</p>
|
||||
<p>If things are not working, make sure your typeclasses and commands are free of bugs and that you
|
||||
have entered the paths to the various command sets and commands correctly. Check the logs or command
|
||||
line for tracebacks and errors.</p>
|
||||
|
|
@ -340,51 +276,12 @@ We also change the default <code class="docutils literal notranslate"><span clas
|
|||
<h3>Attacking with the +attack command<a class="headerlink" href="#attacking-with-the-attack-command" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Attacking in this simple system means rolling a random “combat score” influenced by the <code class="docutils literal notranslate"><span class="pre">power</span></code> stat
|
||||
set during Character generation:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>> +attack
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> +attack
|
||||
You +attack with a combat score of 12!
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Go back to <code class="docutils literal notranslate"><span class="pre">mygame/commands/command.py</span></code> and add the command to the end like this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">random</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">random</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
|
|
@ -425,15 +322,15 @@ You +attack with a combat score of 12!
|
|||
<span class="n">c_score</span><span class="o">=</span><span class="n">combat_score</span><span class="p">,</span>
|
||||
<span class="p">),</span> <span class="n">exclude</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>What we do here is simply to generate a “combat score” using Python’s inbuilt <code class="docutils literal notranslate"><span class="pre">random.randint()</span></code>
|
||||
function. We then store that and echo the result to everyone involved.</p>
|
||||
<p>To make the <code class="docutils literal notranslate"><span class="pre">+attack</span></code> command available to you in game, go back to
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code> and scroll down to the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code> class. At the correct
|
||||
place add this line:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><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">command</span><span class="o">.</span><span class="n">CmdAttack</span><span class="p">())</span>
|
||||
<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">command</span><span class="o">.</span><span class="n">CmdAttack</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">@reload</span></code> Evennia and the <code class="docutils literal notranslate"><span class="pre">+attack</span></code> command should be available to you. Run it and use e.g. <code class="docutils literal notranslate"><span class="pre">@ex</span></code> to
|
||||
make sure the <code class="docutils literal notranslate"><span class="pre">combat_score</span></code> attribute is saved correctly.</p>
|
||||
</section>
|
||||
|
|
@ -443,9 +340,9 @@ make sure the <code class="docutils literal notranslate"><span class="pre">comba
|
|||
adding a second command named something like <code class="docutils literal notranslate"><span class="pre">+combatscores</span></code>, but we will instead let the default
|
||||
<code class="docutils literal notranslate"><span class="pre">look</span></code> command do the heavy lifting for us and display our scores as part of its normal output, like
|
||||
this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">look</span> <span class="n">Tom</span>
|
||||
<span class="n">Tom</span> <span class="p">(</span><span class="n">combat</span> <span class="n">score</span><span class="p">:</span> <span class="mi">3</span><span class="p">)</span>
|
||||
<span class="n">This</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">great</span> <span class="n">warrior</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> look Tom
|
||||
Tom (combat score: 3)
|
||||
This is a great warrior.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We don’t actually have to modify the <code class="docutils literal notranslate"><span class="pre">look</span></code> command itself however. To understand why, take a look
|
||||
|
|
@ -462,30 +359,7 @@ implementation of <code class="docutils literal notranslate"><span class="pre">r
|
|||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/objects/objects.py#L1438">here</a>). If you
|
||||
want to make bigger changes you could copy & paste the whole default thing into our overloading
|
||||
method. In our case the change is small though:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span></pre></div></td><td class="code"><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>
|
||||
<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="sd">"""</span>
|
||||
<span class="sd"> [...]</span>
|
||||
<span class="sd"> """</span>
|
||||
|
|
@ -510,7 +384,7 @@ method. In our case the change is small though:</p>
|
|||
<span class="n">text</span> <span class="o">+=</span> <span class="n">cscore</span>
|
||||
<span class="k">return</span> <span class="n">text</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>What we do is to simply let the default <code class="docutils literal notranslate"><span class="pre">return_appearance</span></code> do its thing (<code class="docutils literal notranslate"><span class="pre">super</span></code> will call the
|
||||
parent’s version of the same method). We then split out the first line of this text, append our
|
||||
<code class="docutils literal notranslate"><span class="pre">combat_score</span></code> and put it back together again.</p>
|
||||
|
|
@ -532,58 +406,16 @@ should also be able to set its Power and order it around.</p>
|
|||
and put a custom NPC-specific cmdset on all NPCs. This cmdset could hold all manipulation commands.
|
||||
Since we expect NPC manipulation to be a common occurrence among the user base however, we will
|
||||
instead put all relevant NPC commands in the default command set and limit eventual access with
|
||||
<a class="reference external" href="Components/Locks.html#Permissions">Permissions and Locks</a>.</p>
|
||||
<a class="reference internal" href="../../../Components/Permissions.html"><span class="doc std std-doc">Permissions and Locks</span></a>.</p>
|
||||
<section id="creating-an-npc-with-createnpc">
|
||||
<h3>Creating an NPC with +createNPC<a class="headerlink" href="#creating-an-npc-with-createnpc" title="Permalink to this headline">¶</a></h3>
|
||||
<p>We need a command for creating the NPC, this is a very straightforward command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="o">+</span><span class="n">createnpc</span> <span class="n">Anna</span>
|
||||
<span class="n">You</span> <span class="n">created</span> <span class="n">the</span> <span class="n">NPC</span> <span class="s1">'Anna'</span><span class="o">.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> +createnpc Anna
|
||||
You created the NPC 'Anna'.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>At the end of <code class="docutils literal notranslate"><span class="pre">command.py</span></code>, create our new command:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CmdCreateNPC</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
|
|
@ -627,14 +459,14 @@ instead put all relevant NPC commands in the default command set and limit event
|
|||
<span class="n">npc</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="p">),</span> <span class="n">exclude</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Here we define a <code class="docutils literal notranslate"><span class="pre">+createnpc</span></code> (<code class="docutils literal notranslate"><span class="pre">+createNPC</span></code> works too) that is callable by everyone <em>not</em> having the
|
||||
<code class="docutils literal notranslate"><span class="pre">nonpcs</span></code> “<a class="reference external" href="Components/Locks.html#Permissions">permission</a>” (in Evennia, a “permission” can just as well be used to
|
||||
<code class="docutils literal notranslate"><span class="pre">nonpcs</span></code> “<a class="reference internal" href="../../../Components/Permissions.html"><span class="doc std std-doc">permission</span></a>” (in Evennia, a “permission” can just as well be used to
|
||||
block access, it depends on the lock we define). We create the NPC object in the caller’s current
|
||||
location, using our custom <code class="docutils literal notranslate"><span class="pre">Character</span></code> typeclass to do so.</p>
|
||||
<p>We set an extra lock condition on the NPC, which we will use to check who may edit the NPC later –
|
||||
we allow the creator to do so, and anyone with the Builders permission (or higher). See
|
||||
<a class="reference internal" href="../../../Components/Locks.html"><span class="doc">Locks</span></a> for more information about the lock system.</p>
|
||||
<a class="reference internal" href="../../../Components/Locks.html"><span class="doc std std-doc">Locks</span></a> for more information about the lock system.</p>
|
||||
<p>Note that we just give the object default permissions (by not specifying the <code class="docutils literal notranslate"><span class="pre">permissions</span></code> keyword
|
||||
to the <code class="docutils literal notranslate"><span class="pre">create_object()</span></code> call). In some games one might want to give the NPC the same permissions
|
||||
as the Character creating them, this might be a security risk though.</p>
|
||||
|
|
@ -646,92 +478,21 @@ as the Character creating them, this might be a security risk though.</p>
|
|||
<p>Since we re-used our custom character typeclass, our new NPC already has a <em>Power</em> value - it
|
||||
defaults to 1. How do we change this?</p>
|
||||
<p>There are a few ways we can do this. The easiest is to remember that the <code class="docutils literal notranslate"><span class="pre">power</span></code> attribute is just a
|
||||
simple <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc">Attribute</span></a> stored on the NPC object. So as a Builder or Admin we could set this
|
||||
simple <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attribute</span></a> stored on the NPC object. So as a Builder or Admin we could set this
|
||||
right away with the default <code class="docutils literal notranslate"><span class="pre">@set</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="nd">@set</span> <span class="n">mynpc</span><span class="o">/</span><span class="n">power</span> <span class="o">=</span> <span class="mi">6</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> @set mynpc/power = 6
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">@set</span></code> command is too generally powerful though, and thus only available to staff. We will add a
|
||||
custom command that only changes the things we want players to be allowed to change. We could in
|
||||
principle re-work our old <code class="docutils literal notranslate"><span class="pre">+setpower</span></code> command, but let’s try something more useful. Let’s make a
|
||||
<code class="docutils literal notranslate"><span class="pre">+editNPC</span></code> command.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="o">+</span><span class="n">editNPC</span> <span class="n">Anna</span><span class="o">/</span><span class="n">power</span> <span class="o">=</span> <span class="mi">10</span>
|
||||
<span class="n">Set</span> <span class="n">Anna</span><span class="s1">'s property '</span><span class="n">power</span><span class="s1">' to 10.</span>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> +editNPC Anna/power = 10
|
||||
Set Anna's property 'power' to 10.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is a slightly more complex command. It goes at the end of your <code class="docutils literal notranslate"><span class="pre">command.py</span></code> file as before.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span>
|
||||
<span class="normal">38</span>
|
||||
<span class="normal">39</span>
|
||||
<span class="normal">40</span>
|
||||
<span class="normal">41</span>
|
||||
<span class="normal">42</span>
|
||||
<span class="normal">43</span>
|
||||
<span class="normal">44</span>
|
||||
<span class="normal">45</span>
|
||||
<span class="normal">46</span>
|
||||
<span class="normal">47</span>
|
||||
<span class="normal">48</span>
|
||||
<span class="normal">49</span>
|
||||
<span class="normal">50</span>
|
||||
<span class="normal">51</span>
|
||||
<span class="normal">52</span>
|
||||
<span class="normal">53</span>
|
||||
<span class="normal">54</span>
|
||||
<span class="normal">55</span>
|
||||
<span class="normal">56</span>
|
||||
<span class="normal">57</span>
|
||||
<span class="normal">58</span>
|
||||
<span class="normal">59</span>
|
||||
<span class="normal">60</span>
|
||||
<span class="normal">61</span>
|
||||
<span class="normal">62</span>
|
||||
<span class="normal">63</span>
|
||||
<span class="normal">64</span>
|
||||
<span class="normal">65</span>
|
||||
<span class="normal">66</span>
|
||||
<span class="normal">67</span>
|
||||
<span class="normal">68</span>
|
||||
<span class="normal">69</span>
|
||||
<span class="normal">70</span>
|
||||
<span class="normal">71</span>
|
||||
<span class="normal">72</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdEditNPC</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdEditNPC</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> edit an existing NPC</span>
|
||||
|
||||
|
|
@ -804,7 +565,7 @@ principle re-work our old <code class="docutils literal notranslate"><span class
|
|||
<span class="p">(</span><span class="n">npc</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">propname</span><span class="p">,</span>
|
||||
<span class="n">npc</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">propname</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">"N/A"</span><span class="p">)))</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This command example shows off the use of more advanced parsing but otherwise it’s mostly error
|
||||
checking. It searches for the given npc in the same room, and checks so the caller actually has
|
||||
permission to “edit” it before continuing. An account without the proper permission won’t even be
|
||||
|
|
@ -824,48 +585,12 @@ anyone to use the NPC.</p>
|
|||
it doesn’t have access to are Session and Player-based cmdsets (which means, among other things that
|
||||
they cannot chat on channels, but they could do that if you just added those commands). This makes
|
||||
the <code class="docutils literal notranslate"><span class="pre">+npc</span></code> command simple:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>+npc Anna = say Hello!
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+npc Anna = say Hello!
|
||||
Anna says, 'Hello!'
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Again, add to the end of your <code class="docutils literal notranslate"><span class="pre">command.py</span></code> module:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span>
|
||||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span>
|
||||
<span class="normal">16</span>
|
||||
<span class="normal">17</span>
|
||||
<span class="normal">18</span>
|
||||
<span class="normal">19</span>
|
||||
<span class="normal">20</span>
|
||||
<span class="normal">21</span>
|
||||
<span class="normal">22</span>
|
||||
<span class="normal">23</span>
|
||||
<span class="normal">24</span>
|
||||
<span class="normal">25</span>
|
||||
<span class="normal">26</span>
|
||||
<span class="normal">27</span>
|
||||
<span class="normal">28</span>
|
||||
<span class="normal">29</span>
|
||||
<span class="normal">30</span>
|
||||
<span class="normal">31</span>
|
||||
<span class="normal">32</span>
|
||||
<span class="normal">33</span>
|
||||
<span class="normal">34</span>
|
||||
<span class="normal">35</span>
|
||||
<span class="normal">36</span>
|
||||
<span class="normal">37</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdNPC</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdNPC</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> controls an NPC</span>
|
||||
|
||||
|
|
@ -903,13 +628,13 @@ Anna says, 'Hello!'
|
|||
<span class="n">npc</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cmdname</span><span class="p">)</span>
|
||||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You told </span><span class="si">{</span><span class="n">npc</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> to do '</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">cmdname</span><span class="si">}</span><span class="s2">'."</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Note that if you give an erroneous command, you will not see any error message, since that error
|
||||
will be returned to the npc object, not to you. If you want players to see this, you can give the
|
||||
caller’s session ID to the <code class="docutils literal notranslate"><span class="pre">execute_cmd</span></code> call, like this:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">npc</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cmdname</span><span class="p">,</span> <span class="n">sessid</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">sessid</span><span class="p">)</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">npc</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cmdname</span><span class="p">,</span> <span class="n">sessid</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">sessid</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Another thing to remember is however that this is a very simplistic way to control NPCs. Evennia
|
||||
supports full puppeting very easily. An Account (assuming the “puppet” permission was set correctly)
|
||||
could simply do <code class="docutils literal notranslate"><span class="pre">@ic</span> <span class="pre">mynpc</span></code> and be able to play the game “as” that NPC. This is in fact just what
|
||||
|
|
@ -927,9 +652,9 @@ generation.</p>
|
|||
<p>The simple “Power” game mechanic should be easily expandable to something more full-fledged and
|
||||
useful, same is true for the combat score principle. The <code class="docutils literal notranslate"><span class="pre">+attack</span></code> could be made to target a
|
||||
specific player (or npc) and automatically compare their relevant attributes to determine a result.</p>
|
||||
<p>To continue from here, you can take a look at the <a class="reference internal" href="../Part1/Tutorial-World-Introduction.html"><span class="doc">Tutorial World</span></a>. For
|
||||
more specific ideas, see the <a class="reference internal" href="../../Howto-Overview.html"><span class="doc">other tutorials and hints</span></a> as well
|
||||
as the <a class="reference internal" href="../../../Components/Components-Overview.html"><span class="doc">Evennia Component overview</span></a>.</p>
|
||||
<p>To continue from here, you can take a look at the <a class="reference internal" href="../Part1/Tutorial-World-Introduction.html"><span class="doc std std-doc">Tutorial World</span></a>. For
|
||||
more specific ideas, see the <a class="reference internal" href="../../Howto-Overview.html"><span class="doc std std-doc">other tutorials and hints</span></a> as well
|
||||
as the <a class="reference internal" href="../../../Components/Components-Overview.html"><span class="doc std std-doc">Evennia Component overview</span></a>.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
|
@ -1000,7 +725,7 @@ as the <a class="reference internal" href="../../../Components/Components-Overvi
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Tutorial-for-basic-MUSH-like-game.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,11 +40,11 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="evennia-starting-tutorial-part-4">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="evennia-starting-tutorial-part-4">
|
||||
<h1>Evennia Starting Tutorial (Part 4)<a class="headerlink" href="#evennia-starting-tutorial-part-4" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tutorial Parts</p>
|
||||
<dl class="simple">
|
||||
<p>sidebar:: Tutorial Parts</p>
|
||||
<blockquote>
|
||||
<div><dl class="simple">
|
||||
<dt>Part 1: <a class="reference external" href="../Part1/Starting-Part1.html">What we have</a></dt><dd><p>A tour of Evennia and how to use the tools, including an introduction to Python.</p>
|
||||
</dd>
|
||||
<dt>Part 2: <a class="reference external" href="../Part2/Starting-Part2.html">What we want</a></dt><dd><p>Planning our tutorial game and what to think about when planning your own in the future.</p>
|
||||
|
|
@ -54,7 +56,7 @@
|
|||
<dt>Part 5: <a class="reference external" href="../Part5/Starting-Part5.html">Showing the world</a></dt><dd><p>Taking our new game online and let players try it out</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</aside>
|
||||
</div></blockquote>
|
||||
<p>We now have the code underpinnings of everything we need. We have also tested the various components
|
||||
and has a simple tech-demo to show it all works together. But there is no real coherence to it at this
|
||||
point - we need to actually make a world.
|
||||
|
|
@ -103,7 +105,7 @@ and batchcode processors.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Starting-Part4.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,7 +40,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="add-a-simple-new-web-page">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="add-a-simple-new-web-page">
|
||||
<h1>Add a simple new web page<a class="headerlink" href="#add-a-simple-new-web-page" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia leverages <a class="reference external" href="https://docs.djangoproject.com">Django</a> which is a web development framework.
|
||||
Huge professional websites are made in Django and there is extensive documentation (and books) on it
|
||||
|
|
@ -56,19 +58,14 @@ cool stuff with the page in the view, like adding dynamic content or change it o
|
|||
<code class="docutils literal notranslate"><span class="pre">mygame/web</span></code> folder and add a new module there named <code class="docutils literal notranslate"><span class="pre">story.py</span></code> (you could also put it in its own
|
||||
folder if you wanted to be neat. Don’t forget to add an empty <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> file if you do, to tell
|
||||
Python you can import from the new folder). Here’s how it looks:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/story.py</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/story.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">storypage</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s2">"story.html"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>This view takes advantage of a shortcut provided to use by Django, <em>render</em>. This shortcut gives the
|
||||
template some information from the request, for instance, the game name, and then renders it.</p>
|
||||
</section>
|
||||
|
|
@ -79,17 +76,7 @@ Django parlance). You can specify such places in your settings (see the <code cl
|
|||
<code class="docutils literal notranslate"><span class="pre">default_settings.py</span></code> for more info), but here we’ll use an existing one. Go to
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/template/overrides/website/</span></code> and create a page <code class="docutils literal notranslate"><span class="pre">story.html</span></code> there.</p>
|
||||
<p>This is not a HTML tutorial, so we’ll go simple:</p>
|
||||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>{% extends "base.html" %}
|
||||
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span>{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"row"</span><span class="p">></span>
|
||||
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"col"</span><span class="p">></span>
|
||||
|
|
@ -101,16 +88,10 @@ Django parlance). You can specify such places in your settings (see the <code cl
|
|||
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
|
||||
{% endblock %}
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>Since we’ve used the <em>render</em> shortcut, Django will allow us to extend our base styles easily.</p>
|
||||
<p>If you’d rather not take advantage of Evennia’s base styles, you can do something like this instead:</p>
|
||||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">html</span><span class="p">></span>
|
||||
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">html</span><span class="p">></span>
|
||||
<span class="p"><</span><span class="nt">body</span><span class="p">></span>
|
||||
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>A story about a tree<span class="p"></</span><span class="nt">h1</span><span class="p">></span>
|
||||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>
|
||||
|
|
@ -118,7 +99,7 @@ Django parlance). You can specify such places in your settings (see the <code cl
|
|||
<span class="p"></</span><span class="nt">body</span><span class="p">></span>
|
||||
<span class="p"></</span><span class="nt">html</span><span class="p">></span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="the-url">
|
||||
<h2>The URL<a class="headerlink" href="#the-url" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -130,13 +111,7 @@ Open it now.</p>
|
|||
<p>Django looks for the variable <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> in this file. You want to add your new pattern to the
|
||||
<code class="docutils literal notranslate"><span class="pre">custom_patterns</span></code> list we have prepared - that is then merged with the default <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code>. Here’s
|
||||
how it could look:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">web</span> <span class="kn">import</span> <span class="n">story</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">web</span> <span class="kn">import</span> <span class="n">story</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
|
|
@ -144,7 +119,7 @@ how it could look:</p>
|
|||
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'story'</span><span class="p">,</span> <span class="n">story</span><span class="o">.</span><span class="n">storypage</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Story'</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<p>That is, we import our story view module from where we created it earlier and then create an <code class="docutils literal notranslate"><span class="pre">url</span></code>
|
||||
instance. The first argument to <code class="docutils literal notranslate"><span class="pre">url</span></code> is the pattern of the url we want to find (<code class="docutils literal notranslate"><span class="pre">"story"</span></code>) (this is
|
||||
a regular expression if you are familiar with those) and then our view function we want to direct
|
||||
|
|
@ -203,7 +178,7 @@ to.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Add-a-simple-new-web-page.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,7 +40,7 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="evennia-starting-tutorial-part-5">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="evennia-starting-tutorial-part-5">
|
||||
<h1>Evennia Starting Tutorial (part 5)<a class="headerlink" href="#evennia-starting-tutorial-part-5" title="Permalink to this headline">¶</a></h1>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">Tutorial Parts</p>
|
||||
|
|
@ -101,7 +103,7 @@ to bring your game online so you can invite your first players.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Starting-Part5.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
<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" />
|
||||
|
|
@ -38,13 +40,13 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="web-tutorial">
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="web-tutorial">
|
||||
<h1>Web Tutorial<a class="headerlink" href="#web-tutorial" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia uses the <a class="reference external" href="https://www.djangoproject.com/">Django</a> web framework as the basis of both its
|
||||
database configuration and the website it provides. While a full understanding of Django requires
|
||||
reading the Django documentation, we have provided this tutorial to get you running with the basics
|
||||
and how they pertain to Evennia. This text details getting everything set up. The
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc">Web-based Character view Tutorial</span></a> gives a more explicit example of making a
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc std std-doc">Web-based Character view Tutorial</span></a> gives a more explicit example of making a
|
||||
custom web page connected to your game, and you may want to read that after finishing this guide.</p>
|
||||
<section id="a-basic-overview">
|
||||
<h2>A Basic Overview<a class="headerlink" href="#a-basic-overview" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -61,7 +63,7 @@ like <a class="reference external" href="https://en.wikipedia.org/wiki/CSS">CSS<
|
|||
and Image files (You may note your mygame/web folder does not have a <code class="docutils literal notranslate"><span class="pre">static</span></code> or <code class="docutils literal notranslate"><span class="pre">template</span></code> folder.
|
||||
This is intended and explained further below). Django applications may also have a <code class="docutils literal notranslate"><span class="pre">models.py</span></code> file
|
||||
for storing information in the database. We will not change any models here, take a look at the
|
||||
<a class="reference internal" href="../../../Concepts/New-Models.html"><span class="doc">New Models</span></a> page (as well as the <a class="reference external" href="https://docs.djangoproject.com/en/1.7/topics/db/models/">Django docs</a> on models) if you are interested.</p>
|
||||
<a class="reference internal" href="../../../Concepts/New-Models.html"><span class="doc std std-doc">New Models</span></a> page (as well as the <a class="reference external" href="https://docs.djangoproject.com/en/1.7/topics/db/models/">Django docs</a> on models) if you are interested.</p>
|
||||
<p>There is also a root <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> that determines the URL structure for the entire project. A starter
|
||||
<code class="docutils literal notranslate"><span class="pre">urls.py</span></code> is included in the default game template, and automatically imports all of Evennia’s
|
||||
default URLs for you. This is located in <code class="docutils literal notranslate"><span class="pre">web/urls.py</span></code>.</p>
|
||||
|
|
@ -115,8 +117,8 @@ everything) in the <code class="docutils literal notranslate"><span class="pre">
|
|||
scratch.</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="changing-the-front-page-s-text">
|
||||
<h2>Changing the Front Page’s Text<a class="headerlink" href="#changing-the-front-page-s-text" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="changing-the-front-pages-text">
|
||||
<h2>Changing the Front Page’s Text<a class="headerlink" href="#changing-the-front-pages-text" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The default front page for Evennia contains information about the Evennia project. You’ll probably
|
||||
want to replace this information with information about your own project. Changing the page template
|
||||
is done in a similar way to changing static resources.</p>
|
||||
|
|
@ -127,7 +129,7 @@ means that when you edit a template, the changes are instant. You don’t have t
|
|||
run any extra commands to see these changes - reloading the web page in your browser is enough.</p>
|
||||
<p>To replace the index page’s text, we’ll need to find the template for it. We’ll go into more detail
|
||||
about how to determine which template is used for rendering a page in the
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc">Web-based Character view Tutorial</span></a>. For now, you should know that the template we want to change
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc std std-doc">Web-based Character view Tutorial</span></a>. For now, you should know that the template we want to change
|
||||
is stored in <code class="docutils literal notranslate"><span class="pre">evennia/web/website/templates/website/index.html</span></code>.</p>
|
||||
<p>To replace this template file, you will put your changed template inside the
|
||||
<code class="docutils literal notranslate"><span class="pre">web/template_overrides/website</span></code> directory in your game folder. In the same way as with static
|
||||
|
|
@ -140,7 +142,7 @@ original file already has all the markup and tags, ready for editing.</p>
|
|||
<section id="further-reading">
|
||||
<h2>Further reading<a class="headerlink" href="#further-reading" title="Permalink to this headline">¶</a></h2>
|
||||
<p>For further hints on working with the web presence, you could now continue to the
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc">Web-based Character view Tutorial</span></a> where you learn to make a web page that
|
||||
<a class="reference internal" href="../../Web-Character-View-Tutorial.html"><span class="doc std std-doc">Web-based Character view Tutorial</span></a> where you learn to make a web page that
|
||||
displays in-game character stats. You can also look at <a class="reference external" href="https://docs.djangoproject.com/en/1.7/intro/tutorial01/">Django’s own
|
||||
tutorial</a> to get more insight in how Django
|
||||
works and what possibilities exist.</p>
|
||||
|
|
@ -172,7 +174,7 @@ works and what possibilities exist.</p>
|
|||
<li><a class="reference internal" href="#">Web Tutorial</a><ul>
|
||||
<li><a class="reference internal" href="#a-basic-overview">A Basic Overview</a></li>
|
||||
<li><a class="reference internal" href="#changing-the-logo-on-the-front-page">Changing the logo on the front page</a></li>
|
||||
<li><a class="reference internal" href="#changing-the-front-page-s-text">Changing the Front Page’s Text</a></li>
|
||||
<li><a class="reference internal" href="#changing-the-front-pages-text">Changing the Front Page’s Text</a></li>
|
||||
<li><a class="reference internal" href="#further-reading">Further reading</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
@ -198,7 +200,7 @@ works and what possibilities exist.</p>
|
|||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Web-Tutorial.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||||
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue