Updated HTML docs

This commit is contained in:
Griatch 2021-10-26 21:41:11 +02:00
parent 66d0ad0bc9
commit 7900aad365
2073 changed files with 32986 additions and 41197 deletions

View file

@ -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,10 +49,10 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="a-voice-operated-elevator-using-events">
<section class="tex2jax_ignore mathjax_ignore" id="a-voice-operated-elevator-using-events">
<h1>A voice operated elevator using events<a class="headerlink" href="#a-voice-operated-elevator-using-events" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><p>Previous tutorial: <a class="reference internal" href="Dialogues-in-events.html"><span class="doc">Adding dialogues in events</span></a></p></li>
<li><p>Previous tutorial: <a class="reference internal" href="Dialogues-in-events.html"><span class="doc std std-doc">Adding dialogues in events</span></a></p></li>
</ul>
<p>This tutorial will walk you through the steps to create a voice-operated elevator, using the <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md">in-
game Python
@ -97,13 +99,13 @@ usually the safest path in our callbacks.</p>
</div></blockquote>
<p>Lets go into limbo (<code class="docutils literal notranslate"><span class="pre">#2</span></code>) to add our elevator. Well add it to the north. To create this room,
in-game you could type:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tunnel</span> <span class="n">n</span> <span class="o">=</span> <span class="n">Inside</span> <span class="n">of</span> <span class="n">an</span> <span class="n">elevator</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>tunnel n = Inside of an elevator
</pre></div>
</div>
<p>The game should respond by telling you:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Created</span> <span class="n">room</span> <span class="n">Inside</span> <span class="n">of</span> <span class="n">an</span> <span class="n">elevator</span><span class="p">(</span><span class="c1">#3) of type typeclasses.rooms.Room.</span>
<span class="n">Created</span> <span class="n">Exit</span> <span class="kn">from</span> <span class="nn">Limbo</span> <span class="n">to</span> <span class="n">Inside</span> <span class="n">of</span> <span class="n">an</span> <span class="n">elevator</span><span class="p">:</span> <span class="n">north</span><span class="p">(</span><span class="c1">#4) (n).</span>
<span class="n">Created</span> <span class="n">Exit</span> <span class="n">back</span> <span class="kn">from</span> <span class="nn">Inside</span> <span class="n">of</span> <span class="n">an</span> <span class="n">elevator</span> <span class="n">to</span> <span class="n">Limbo</span><span class="p">:</span> <span class="n">south</span><span class="p">(</span><span class="c1">#5) (s).</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Created room Inside of an elevator(#3) of type typeclasses.rooms.Room.
Created Exit from Limbo to Inside of an elevator: north(#4) (n).
Created Exit back from Inside of an elevator to Limbo: south(#5) (s).
</pre></div>
</div>
<p>Note the given IDs:</p>
@ -122,13 +124,13 @@ will do, at every floor, will be to change these exits so they become connected
Youll see this process a bit later.</p>
<p>We have two more rooms to create: our floor 2 and 3. This time, well use <code class="docutils literal notranslate"><span class="pre">dig</span></code>, because we dont
need exits leading there, not yet anyway.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dig</span> <span class="n">The</span> <span class="n">second</span> <span class="n">floor</span>
<span class="n">dig</span> <span class="n">The</span> <span class="n">third</span> <span class="n">floor</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>dig The second floor
dig The third floor
</pre></div>
</div>
<p>Evennia should answer with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Created</span> <span class="n">room</span> <span class="n">The</span> <span class="n">second</span> <span class="n">floor</span><span class="p">(</span><span class="c1">#6) of type typeclasses.rooms.Room.</span>
<span class="n">Created</span> <span class="n">room</span> <span class="n">The</span> <span class="n">third</span> <span class="n">floor</span><span class="p">(</span><span class="c1">#7) of type typeclasses.rooms.Room.</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Created room The second floor(#6) of type typeclasses.rooms.Room.
Created room The third floor(#7) of type typeclasses.rooms.Room.
</pre></div>
</div>
<p>Add these IDs to your list, we will use them too.</p>
@ -140,7 +142,7 @@ need exits leading there, not yet anyway.</p>
things to decorate it a bit.</p>
<p>But what we want now is to be able to say “1”, “2” or “3” and have the elevator move in that
direction.</p>
<p>If you have read <a class="reference internal" href="Dialogues-in-events.html"><span class="doc">the previous tutorial about adding dialogues in events</span></a>, you
<p>If you have read <a class="reference internal" href="Dialogues-in-events.html"><span class="doc std std-doc">the previous tutorial about adding dialogues in events</span></a>, you
may remember what we need to do. If not, heres a summary: we need to run some code when somebody
speaks in the room. So we need to create a callback (the callback will contain our lines of code).
We just need to know on which event this should be set. You can enter <code class="docutils literal notranslate"><span class="pre">call</span> <span class="pre">here</span></code> to see the
@ -148,7 +150,7 @@ possible events in this room.</p>
<p>In the table, you should see the “say” event, which is called when somebody says something in the
room. So well need to add a callback to this event. Dont worry if youre a bit lost, just follow
the following steps, the way they connect together will become more obvious.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">add</span> <span class="n">here</span> <span class="o">=</span> <span class="n">say</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/add here = say 1, 2, 3
</pre></div>
</div>
<ol class="simple">
@ -179,20 +181,20 @@ all, the list of variables that are available in this callback:</p>
</div>
<p>This is important, in order to know what variables we can use in our callback out-of-the-box. Lets
write a single line to be sure our callback is called when we expect it to:</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">character</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You just said </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">character</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You just said </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>You can paste this line in-game, then type the <code class="docutils literal notranslate"><span class="pre">:wq</span></code> command to exit the editor and save your
modifications.</p>
<p>Lets check. Try to say “hello” in the room. You should see the standard message, but nothing
more. Now try to say “1”. Below the standard message, you should see:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">You</span> <span class="n">just</span> <span class="n">said</span> <span class="mf">1.</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You just said 1.
</pre></div>
</div>
<p>You can try it. Our callback is only called when we say “1”, “2” or “3”. Which is just what we
want.</p>
<p>Lets go back in our code editor and add something more useful.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">edit</span> <span class="n">here</span> <span class="o">=</span> <span class="n">say</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/edit here = say
</pre></div>
</div>
<blockquote>
@ -200,11 +202,11 @@ want.</p>
it.</p>
</div></blockquote>
<p>The editor opens again. Lets empty it first:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">:</span><span class="n">DD</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>:DD
</pre></div>
</div>
<p>And turn off automatic indentation, which will help us:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">:=</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>:=
</pre></div>
</div>
<blockquote>
@ -222,29 +224,7 @@ exits. Remember, we already have the exits, we just need to change their locati
</ol>
<p>Its a good idea to try to write this callback yourself, but dont feel bad about checking the
solution right now. Heres a possible code that you could paste in the code editor:</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"># First let&#39;s have some constants</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># First let&#39;s have some constants</span>
<span class="n">ELEVATOR</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">FLOORS</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;1&quot;</span><span class="p">:</span> <span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">),</span>
@ -268,7 +248,7 @@ solution right now. Heres a possible code that you could paste in the code e
<span class="n">room</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;The doors of the elevator open to </span><span class="si">{floor}</span><span class="s2">.&quot;</span><span class="p">,</span>
<span class="n">mapping</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">floor</span><span class="o">=</span><span class="n">floor</span><span class="p">))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Lets review this longer callback:</p>
<ol class="simple">
<li><p>We first obtain the objects of both exits and our three floors. We use the <code class="docutils literal notranslate"><span class="pre">get()</span></code> eventfunc,
@ -312,25 +292,20 @@ chained event a more explicit name.</p></li>
</ul>
<p>Other than that, a chained event can be connected to a callback as usual. Well create a chained
event in our elevator, that will only contain the code necessary to open the doors to the new floor.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">add</span> <span class="n">here</span> <span class="o">=</span> <span class="n">chain_1</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/add here = chain_1
</pre></div>
</div>
<p>The callback is added to the “chain_1” event, an event that will not be automatically called by the
system when something happens. Inside this event, you can paste the code to open the doors at the
new floor. You can notice a few differences:</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="n">TO_EXIT</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="n">floor</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">TO_EXIT</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="n">floor</span>
<span class="n">TO_EXIT</span><span class="o">.</span><span class="n">destination</span> <span class="o">=</span> <span class="n">ELEVATOR</span>
<span class="n">BACK_EXIT</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="n">ELEVATOR</span>
<span class="n">BACK_EXIT</span><span class="o">.</span><span class="n">destination</span> <span class="o">=</span> <span class="n">floor</span>
<span class="n">room</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;The doors of the elevator open to </span><span class="si">{floor}</span><span class="s2">.&quot;</span><span class="p">,</span>
<span class="n">mapping</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">floor</span><span class="o">=</span><span class="n">floor</span><span class="p">))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Paste this code into the editor, then use <code class="docutils literal notranslate"><span class="pre">:wq</span></code> to save and quit the editor.</p>
<p>Now lets edit our callback in the “say” event. Well have to change it a bit:</p>
<ul class="simple">
@ -339,39 +314,16 @@ new floor. You can notice a few differences:</p>
<li><p>It has to call the “chain_1” event we have defined. It should call it 15 seconds later.</p></li>
</ul>
<p>Lets see the code in our callback.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">edit</span> <span class="n">here</span> <span class="o">=</span> <span class="n">say</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/edit here = say
</pre></div>
</div>
<p>Remove the current code and disable auto-indentation again:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">:</span><span class="n">DD</span>
<span class="o">:=</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>:DD
:=
</pre></div>
</div>
<p>And you can paste instead the following code. Notice the differences with our first attempt:</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="c1"># First let&#39;s have some constants</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># First let&#39;s have some constants</span>
<span class="n">ELEVATOR</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">FLOORS</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;1&quot;</span><span class="p">:</span> <span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">),</span>
@ -396,7 +348,7 @@ new floor. You can notice a few differences:</p>
<span class="n">BACK_EXIT</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">call_event</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="s2">&quot;chain_1&quot;</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>What changed?</p>
<ol class="simple">
<li><p>We added a little test to make sure the elevator wasnt already moving. If it is, the
@ -431,7 +383,7 @@ altering the others. In this case, when someone goes north into our elevator, w
something like: “someone walks into the elevator.” Something similar for the back exit would be
great too.</p>
<p>Inside of the elevator, you can look at the available events on the exit leading outside (south).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span> <span class="n">south</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call south
</pre></div>
</div>
<p>You should see two interesting rows in this table:</p>
@ -443,37 +395,37 @@ great too.</p>
</div>
<p>So we can change the message others see when a character leaves, by editing the “msg_leave” event.
Lets do that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">add</span> <span class="n">south</span> <span class="o">=</span> <span class="n">msg_leave</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/add south = msg_leave
</pre></div>
</div>
<p>Take the time to read the help. It gives you all the information you should need. Well need to
change the “message” variable, and use custom mapping (between braces) to alter the message. Were
given an example, lets use it. In the code editor, you can paste the following 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="n">message</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> walks out of the elevator.&quot;</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">message</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> walks out of the elevator.&quot;</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Again, save and quit the editor by entering <code class="docutils literal notranslate"><span class="pre">:wq</span></code>. You can create a new character to see it leave.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">charcreate</span> <span class="n">A</span> <span class="n">beggar</span>
<span class="n">tel</span> <span class="c1">#8 = here</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>charcreate A beggar
tel #8 = here
</pre></div>
</div>
<p>(Obviously, adapt the ID if necessary.)</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">&quot;beggar&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">move_to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;south&quot;</span><span class="p">))</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>py self.search(&quot;beggar&quot;).move_to(self.search(&quot;south&quot;))
</pre></div>
</div>
<p>This is a crude way to force our beggar out of the elevator, but it allows us to test. You should
see:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span> <span class="n">beggar</span><span class="p">(</span><span class="c1">#8) walks out of the elevator.</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>A beggar(#8) walks out of the elevator.
</pre></div>
</div>
<p>Great! Lets do the same thing for the exit leading inside of the elevator. Follow the beggar,
then edit “msg_leave” of “north”:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call</span><span class="o">/</span><span class="n">add</span> <span class="n">north</span> <span class="o">=</span> <span class="n">msg_leave</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>call/add north = msg_leave
</pre></div>
</div>
<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">message</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> walks into the elevator.&quot;</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">message</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> walks into the elevator.&quot;</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Again, you can force our beggar to move and see the message we have just set. This modification
applies to these two exits, obviously: the custom message wont be used for other exits. Since we
use the same exits for every floor, this will be available no matter at what floor the elevator is,
@ -511,7 +463,7 @@ for instance.</p></li>
to consider adding the code in the source itself. Another possibility is to call chained events
with the expected behavior, which makes porting code very easy. This side of chained events will be
shown in the next tutorial.</p></li>
<li><p>Previous tutorial: <a class="reference internal" href="Dialogues-in-events.html"><span class="doc">Adding dialogues in events</span></a></p></li>
<li><p>Previous tutorial: <a class="reference internal" href="Dialogues-in-events.html"><span class="doc std std-doc">Adding dialogues in events</span></a></p></li>
</ul>
</section>
</section>
@ -576,7 +528,7 @@ shown in the next tutorial.</p></li>
<h3>Versions</h3>
<ul>
<li><a href="A-voice-operated-elevator-using-events.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>

View file

@ -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="arxcode-installing-help">
<section class="tex2jax_ignore mathjax_ignore" id="arxcode-installing-help">
<h1>Arxcode installing help<a class="headerlink" href="#arxcode-installing-help" title="Permalink to this headline"></a></h1>
<section id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
@ -50,7 +52,7 @@ Arx on github</a>. This is a treasure-trove for developers wanting
to pick ideas or even get a starting game to build on. These instructions are based on the Arx-code
released as of <em>Aug 12, 2018</em>.</p>
<p>If you are not familiar with what Evennia is, you can read
<a class="reference internal" href="../Evennia-Introduction.html"><span class="doc">an introduction here</span></a>.</p>
<a class="reference internal" href="../Evennia-Introduction.html"><span class="doc std std-doc">an introduction here</span></a>.</p>
<p>Its not too hard to run Arx from the sources (of course youll start with an empty database) but
since part of Arx has grown organically, it doesnt follow standard Evennia paradigms everywhere.
This page covers one take on installing and setting things up while making your new Arx-based game
@ -60,13 +62,13 @@ better match with the vanilla Evennia install.</p>
<h2>Installing Evennia<a class="headerlink" href="#installing-evennia" title="Permalink to this headline"></a></h2>
<p>Firstly, set aside a folder/directory on your drive for everything to follow.</p>
<p>You need to start by installing <a class="reference external" href="https://www.evennia.com">Evennia</a> by following most of the
<a class="reference internal" href="../Setup/Setup-Quickstart.html"><span class="doc">Getting Started Instructions</span></a> for your OS. The difference is that you need to <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">clone</span> <span class="pre">https://github.com/TehomCD/evennia.git</span></code> instead of Evennias repo because Arx uses TehomCDs older
<a class="reference internal" href="../Setup/Setup-Quickstart.html"><span class="doc std std-doc">Getting Started Instructions</span></a> for your OS. The difference is that you need to <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">clone</span> <span class="pre">https://github.com/TehomCD/evennia.git</span></code> instead of Evennias repo because Arx uses TehomCDs older
Evennia 0.8 <a class="reference external" href="https://github.com/TehomCD/evennia">fork</a>, notably still using Python2. This detail is
important if referring to newer Evennia documentation.</p>
<p>If you are new to Evennia its <em>highly</em> recommended that you run through the
instructions in full - including initializing and starting a new empty game and connecting to it.
That way you can be sure Evennia works correctly as a base line. If you have trouble, make sure to
read the <a class="reference external" href="Contribs/Getting-Started#troubleshooting">Troubleshooting instructions</a> for your
read the <a class="reference internal" href="../Setup/Extended-Installation.html#troubleshooting"><span class="std std-doc">Troubleshooting instructions</span></a> for your
operating system. You can also drop into our
<a class="reference external" href="https://groups.google.com/forum/#%21forum/evennia">forums</a>, join <code class="docutils literal notranslate"><span class="pre">#evennia</span></code> on <code class="docutils literal notranslate"><span class="pre">irc.freenode.net</span></code>
or chat from the linked <a class="reference external" href="https://discord.gg/NecFePw">Discord Server</a>.</p>
@ -75,6 +77,7 @@ structure in your set-aside folder:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">vienv</span><span class="o">/</span>
<span class="n">evennia</span><span class="o">/</span>
<span class="n">mygame</span><span class="o">/</span>
</pre></div>
</div>
<p>Here <code class="docutils literal notranslate"><span class="pre">mygame</span></code> is the empty game you created during the Evennia install, with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">--init</span></code>. Go to
@ -87,13 +90,13 @@ to compare to.</p>
<section id="clone-the-arxcode-repo">
<h3>Clone the arxcode repo<a class="headerlink" href="#clone-the-arxcode-repo" title="Permalink to this headline"></a></h3>
<p>Cd to the root of your directory and clone the released source code from github:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">clone</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">Arx</span><span class="o">-</span><span class="n">Game</span><span class="o">/</span><span class="n">arxcode</span><span class="o">.</span><span class="n">git</span> <span class="n">myarx</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git clone https://github.com/Arx-Game/arxcode.git myarx
</pre></div>
</div>
<p>A new folder <code class="docutils literal notranslate"><span class="pre">myarx</span></code> should appear next to the ones you already had. You could rename this to
something else if you want.</p>
<p>Cd into <code class="docutils literal notranslate"><span class="pre">myarx</span></code>. If you wonder about the structure of the game dir, you can
<a class="reference internal" href="../Howto/Starting/Part1/Gamedir-Overview.html"><span class="doc">read more about it here</span></a>.</p>
<a class="reference internal" href="../Howto/Starting/Part1/Gamedir-Overview.html"><span class="doc std std-doc">read more about it here</span></a>.</p>
</section>
<section id="clean-up-settings">
<h3>Clean up settings<a class="headerlink" href="#clean-up-settings" title="Permalink to this headline"></a></h3>
@ -104,7 +107,7 @@ way but remove the secret-handling and replace it with the normal Evennia method
<code class="docutils literal notranslate"><span class="pre">&quot;&quot;&quot;...&quot;&quot;&quot;</span></code>) is just help text. Wipe everything underneath that and make it look like this instead
(dont forget to save):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">base_settings</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">TELNET_PORTS</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4000</span><span class="p">]</span>
<span class="n">SERVERNAME</span> <span class="o">=</span> <span class="s2">&quot;MyArx&quot;</span>
<span class="n">GAME_SLOGAN</span> <span class="o">=</span> <span class="s2">&quot;The cool game&quot;</span>
@ -125,9 +128,10 @@ the game a name. The slogan changes the sub-text shown under the name of your ga
header. You can tweak these to your own liking later.</p>
<p>Next, create a new, empty file <code class="docutils literal notranslate"><span class="pre">secret_settings.py</span></code> in the same location as the <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> file.
This can just contain the following:</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">SECRET_KEY</span> <span class="o">=</span> <span class="s2">&quot;sefsefiwwj3 jnwidufhjw4545_oifej whewiu hwejfpoiwjrpw09&amp;4er43233fwefwfw&quot;</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">SECRET_KEY</span> <span class="o">=</span> <span class="s2">&quot;sefsefiwwj3 jnwidufhjw4545_oifej whewiu hwejfpoiwjrpw09&amp;4er43233fwefwfw&quot;</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Replace the long random string with random ASCII characters of your own. The secret key should not
be shared.</p>
<p>Next, open <code class="docutils literal notranslate"><span class="pre">myarx/server/conf/base_settings.py</span></code> in your text editor. We want to remove/comment out
@ -146,7 +150,7 @@ relevant to us.</p>
<code class="docutils literal notranslate"><span class="pre">pypiwin32==219</span></code> - its only needed on Windows and will give an error on other platforms.</p>
</div></blockquote>
<p>Make sure your <code class="docutils literal notranslate"><span class="pre">virtualenv</span></code> is active, then run</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">r</span> <span class="n">requirements</span><span class="o">.</span><span class="n">txt</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install -r requirements.txt
</pre></div>
</div>
<p>The needed Python packages will be installed for you.</p>
@ -155,21 +159,21 @@ relevant to us.</p>
<h3>Adding logs/ folder<a class="headerlink" href="#adding-logs-folder" title="Permalink to this headline"></a></h3>
<p>The Arx repo does not contain the <code class="docutils literal notranslate"><span class="pre">myarx/server/logs/</span></code> folder Evennia expects for storing server
logs. This is simple to add:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># linux/mac</span>
<span class="n">mkdir</span> <span class="n">server</span><span class="o">/</span><span class="n">logs</span>
<span class="c1"># windows</span>
<span class="n">mkdir</span> <span class="n">server</span>\<span class="n">logs</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span># linux/mac
mkdir server/logs
# windows
mkdir server\logs
</pre></div>
</div>
</section>
<section id="setting-up-the-database-and-starting">
<h3>Setting up the database and starting<a class="headerlink" href="#setting-up-the-database-and-starting" title="Permalink to this headline"></a></h3>
<p>From the <code class="docutils literal notranslate"><span class="pre">myarx</span></code> folder, run</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">migrate</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia migrate
</pre></div>
</div>
<p>This creates the database and will step through all database migrations needed.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">start</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia start
</pre></div>
</div>
<p>If all goes well Evennia will now start up, running Arx! You can connect to it on <code class="docutils literal notranslate"><span class="pre">localhost</span></code> (or
@ -229,9 +233,9 @@ identical to the ones above), its possible to get Evennia running under Anaco
process is a little bit trickier.</p>
<p>Make sure you have:</p>
<ul class="simple">
<li><p>Git for Windows https://git-scm.com/download/win</p></li>
<li><p>Anaconda for Windows https://www.anaconda.com/distribution/</p></li>
<li><p>VC++ Compiler for Python 2.7 https://aka.ms/vcpython27</p></li>
<li><p>Git for Windows <a class="reference external" href="https://git-scm.com/download/win">https://git-scm.com/download/win</a></p></li>
<li><p>Anaconda for Windows <a class="reference external" href="https://www.anaconda.com/distribution/">https://www.anaconda.com/distribution/</a></p></li>
<li><p>VC++ Compiler for Python 2.7 <a class="reference external" href="https://aka.ms/vcpython27">https://aka.ms/vcpython27</a></p></li>
</ul>
<p>conda update conda
conda create -n arx python=2.7
@ -245,8 +249,8 @@ cd Arx</p>
<p>Replace the SSH git clone links below with your own github forks.
If you dont plan to change Evennia at all, you can use the
evennia/evennia.git repo instead of a forked one.</p>
<p>git clone git&#64;github.com:<youruser>/evennia.git
git clone git&#64;github.com:<youruser>/arxcode.git</p>
<p>git clone <a class="reference external" href="mailto:git&#37;&#52;&#48;github&#46;com">git<span>&#64;</span>github<span>&#46;</span>com</a>:<youruser>/evennia.git
git clone <a class="reference external" href="mailto:git&#37;&#52;&#48;github&#46;com">git<span>&#64;</span>github<span>&#46;</span>com</a>:<youruser>/arxcode.git</p>
<p>Evennia is a package itself, so we want to install it and all of its
prerequisites, after switching to the appropriately-tagged branch for
Arxcode.</p>
@ -255,22 +259,22 @@ git checkout tags/v0.7 -b arx-master
pip install -e .</p>
<p>Arx has some dependencies of its own, so now well go install them
As it is not a package, well use the normal requirements file.</p>
<p>cd ../arxcode
<p>cd /arxcode
pip install -r requirements.txt</p>
<p>The git repo doesnt include the empty log directory and Evennia is unhappy if you
dont have it, so while still in the arxcode directory…</p>
<p>mkdir server/logs</p>
<p>Now hit https://github.com/evennia/evennia/wiki/Arxcode-installing-help and
<p>Now hit <a class="reference external" href="https://github.com/evennia/evennia/wiki/Arxcode-installing-help">https://github.com/evennia/evennia/wiki/Arxcode-installing-help</a> and
change the setup stuff as in the Clean up settings section.</p>
<p>Then we will create our default database…</p>
<p>../evennia/bin/windows/evennia.bat migrate</p>
<p>/evennia/bin/windows/evennia.bat migrate</p>
<p>…and do the first run. You need winpty because Windows does not have a TTY/PTY
by default, and so the Python console input commands (used for prompts on first
run) will fail and you will end up in an unhappy place. Future runs, you should
not need winpty.</p>
<p>winpty ../evennia/bin/windows/evennia.bat start</p>
<p>winpty /evennia/bin/windows/evennia.bat start</p>
<p>Once this is done, you should have your Evennia server running Arxcode up
on localhost at port 4000, and the webserver at http://localhost:4001/</p>
on localhost at port 4000, and the webserver at <a class="reference external" href="http://localhost:4001/">http://localhost:4001/</a></p>
<p>And you are done! Huzzah!</p>
</section>
</section>
@ -334,7 +338,7 @@ on localhost at port 4000, and the webserver at http://localhost:4001/</p>
<h3>Versions</h3>
<ul>
<li><a href="Arxcode-installing-help.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>

View file

@ -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,10 +49,10 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="building-menus">
<section class="tex2jax_ignore mathjax_ignore" id="building-menus">
<h1>Building menus<a class="headerlink" href="#building-menus" title="Permalink to this headline"></a></h1>
</section>
<section id="the-building-menu-contrib">
<section class="tex2jax_ignore mathjax_ignore" id="the-building-menu-contrib">
<h1>The building_menu contrib<a class="headerlink" href="#the-building-menu-contrib" title="Permalink to this headline"></a></h1>
<p>This contrib allows you to write custom and easy to use building menus. As the name implies, these
menus are most useful for building things, that is, your builders might appreciate them, although
@ -79,50 +81,7 @@ demonstration, but we will override it in this example, using the same code with
<h3>A generic editing command<a class="headerlink" href="#a-generic-editing-command" title="Permalink to this headline"></a></h3>
<p>Lets begin by adding a new command. You could add or edit the following file (theres no trick
here, feel free to organize the code differently):</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file: commands/building.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># file: commands/building.py</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.building_menu</span> <span class="kn">import</span> <span class="n">BuildingMenu</span>
<span class="kn">from</span> <span class="nn">commands.command</span> <span class="kn">import</span> <span class="n">Command</span>
@ -167,7 +126,7 @@ here, feel free to organize the code differently):</p>
<span class="n">menu</span> <span class="o">=</span> <span class="n">Menu</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
<span class="n">menu</span><span class="o">.</span><span class="n">open</span><span class="p">()</span>
</pre></div>
</td></tr></table></div>
</div>
<p>This command is rather simple in itself:</p>
<ol class="simple">
<li><p>It has a key <code class="docutils literal notranslate"><span class="pre">&#64;edit</span></code> and a lock to only allow builders to use it.</p></li>
@ -193,14 +152,7 @@ create an instance of our building menu and call its <code class="docutils liter
<code class="docutils literal notranslate"><span class="pre">RoomBuildingMenu</span></code> yet.</p>
<p>To add this command, edit <code class="docutils literal notranslate"><span class="pre">commands/default_cmdsets.py</span></code>. Import our command, adding an import line
at the top of the 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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">...</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -209,25 +161,9 @@ at the top of the file:</p>
<span class="c1"># The following line is to be added</span>
<span class="kn">from</span> <span class="nn">commands.building</span> <span class="kn">import</span> <span class="n">EditCmd</span>
</pre></div>
</td></tr></table></div>
</div>
<p>And in the class below (<code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>), add the last line of this 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></pre></div></td><td class="code"><div class="highlight"><pre><span></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>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></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>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The `CharacterCmdSet` contains general in-game commands like `look`,</span>
<span class="sd"> `get`, etc available on in-game Character objects. It is merged with</span>
@ -245,26 +181,13 @@ at the top of the file:</p>
<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">EditCmd</span><span class="p">())</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="our-first-menu">
<h3>Our first menu<a class="headerlink" href="#our-first-menu" title="Permalink to this headline"></a></h3>
<p>So far, we cant use our building menu. Our <code class="docutils literal notranslate"><span class="pre">&#64;edit</span></code> command will throw an error. We have to define
the <code class="docutils literal notranslate"><span class="pre">RoomBuildingMenu</span></code> class. Open the <code class="docutils literal notranslate"><span class="pre">commands/building.py</span></code> file and add to the end of the 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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ... at the end of commands/building.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ... at the end of commands/building.py</span>
<span class="c1"># Our building menu</span>
<span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
@ -279,7 +202,7 @@ the <code class="docutils literal notranslate"><span class="pre">RoomBuildingMen
<span class="k">def</span> <span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="s2">&quot;k&quot;</span><span class="p">,</span> <span class="n">attr</span><span class="o">=</span><span class="s2">&quot;key&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Save these changes, reload your game. You can now use the <code class="docutils literal notranslate"><span class="pre">&#64;edit</span></code> command. Heres what we get
(notice that the commands we enter into the game are prefixed with <code class="docutils literal notranslate"><span class="pre">&gt;</span> </code>, though this prefix will
probably not appear in your MUD client):</p>
@ -359,17 +282,7 @@ class, with a method and a single line of code within, weve added a menu with
<section id="code-explanation">
<h3>Code explanation<a class="headerlink" href="#code-explanation" title="Permalink to this headline"></a></h3>
<p>Lets examine our 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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Building menu to edit a room.</span>
@ -381,7 +294,7 @@ class, with a method and a single line of code within, weve added a menu with
<span class="k">def</span> <span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="s2">&quot;k&quot;</span><span class="p">,</span> <span class="n">attr</span><span class="o">=</span><span class="s2">&quot;key&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<ul class="simple">
<li><p>We first create a class inheriting from <code class="docutils literal notranslate"><span class="pre">BuildingMenu</span></code>. This is usually the case when we want to
create a building menu with this contrib.</p></li>
@ -436,16 +349,7 @@ can specify the title and key of this menu. You can also call a function when t
</ul>
<p>So heres a more complete example (you can replace your <code class="docutils literal notranslate"><span class="pre">RoomBuildingMenu</span></code> class in
<code class="docutils literal notranslate"><span class="pre">commands/building.py</span></code> to see 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="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Building menu to edit a room.</span>
@ -456,7 +360,7 @@ can specify the title and key of this menu. You can also call a function when t
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice_edit</span><span class="p">(</span><span class="s2">&quot;description&quot;</span><span class="p">,</span> <span class="s2">&quot;d&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice_quit</span><span class="p">(</span><span class="s2">&quot;quit this editor&quot;</span><span class="p">,</span> <span class="s2">&quot;q&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>So far, our building menu class is still thin… and yet we already have some interesting feature.
See for yourself the following MUD client output (again, the commands are prefixed with <code class="docutils literal notranslate"><span class="pre">&gt;</span> </code> to
distinguish them):</p>
@ -548,26 +452,7 @@ choice. This can be useful for cleanup as well.</p></li>
<p>These are a lot of possibilities, and most of the time you wont need them all. Here is a short
example using some of these arguments (again, replace the <code class="docutils literal notranslate"><span class="pre">RoomBuildingMenu</span></code> class in
<code class="docutils literal notranslate"><span class="pre">commands/building.py</span></code> with the following code to see it working):</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="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Building menu to edit a room.</span>
@ -588,7 +473,7 @@ example using some of these arguments (again, replace the <code class="docutils
<span class="s2"> &quot;&quot;&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">back</span><span class="o">=</span><span class="s2">&quot;|n or |y&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">keys_go_back</span><span class="p">)))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice_edit</span><span class="p">(</span><span class="s2">&quot;description&quot;</span><span class="p">,</span> <span class="s2">&quot;d&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Reload your game and see it in action:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&gt;</span> <span class="nd">@edit</span> <span class="n">here</span>
<span class="n">Building</span> <span class="n">menu</span><span class="p">:</span> <span class="n">A</span> <span class="n">beautiful</span> <span class="n">meadow</span>
@ -661,38 +546,7 @@ can we show that?</p>
great. Perhaps even add new exits?</p>
<p>First of all, lets write a function to display the <code class="docutils literal notranslate"><span class="pre">glance</span></code> on existing exits. Heres the code,
its explained below:</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Building menu to edit a room.</span>
@ -725,7 +579,7 @@ its explained below:</p>
<span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2"> |gNo exit yet|n&quot;</span>
</pre></div>
</td></tr></table></div>
</div>
<p>When the building menu opens, it displays each choice to the caller. A choice is displayed with its
title (rendered a bit nicely to show the key as well) and the glance. In the case of the <code class="docutils literal notranslate"><span class="pre">exits</span></code>
choice, the glance is a function, so the building menu calls this function giving it the object
@ -769,9 +623,9 @@ building menu.</p></li>
<li><p>Anything else: any other argument will contain the object being edited by the building menu.</p></li>
</ul>
<p>So in our case:</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="k">def</span> <span class="nf">glance_exits</span><span class="p">(</span><span class="n">room</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">glance_exits</span><span class="p">(</span><span class="n">room</span><span class="p">):</span>
</pre></div>
</td></tr></table></div>
</div>
<p>The only argument we need is <code class="docutils literal notranslate"><span class="pre">room</span></code>. Its not present in the list of possible arguments, so the
editing object of the building menu (the room, here) is given.</p>
<blockquote>
@ -783,60 +637,7 @@ possibilities. Just know that they exist.</p>
<p>We should also define a text callback, so that we can enter our menu to see the room exits. Well
see how to edit them in the next section but this is a good opportunity to show a more complete
callback. To see it in action, as usual, replace the class and functions in <code class="docutils literal notranslate"><span class="pre">commands/building.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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># Our building menu</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Our building menu</span>
<span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
@ -891,7 +692,7 @@ callback. To see it in action, as usual, replace the class and functions in <co
<span class="k">return</span> <span class="n">text</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Look at the second callback in particular. It takes an additional argument, the caller (remember,
the argument names are important, their order is not relevant). This is useful for displaying
destination of exits accurately. Here is a demonstration of this menu:</p>
@ -1036,107 +837,7 @@ you could change the exit key or description.</p>
</div>
<p>This needs a bit of code and a bit of explanation. So here we go… the code first, the
explanations 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>
<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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ... from commands/building.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ... from commands/building.py</span>
<span class="c1"># Our building menu</span>
<span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
@ -1238,7 +939,7 @@ explanations next!</p>
<span class="n">exit</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">string</span>
<span class="k">return</span> <span class="kc">True</span>
</pre></div>
</td></tr></table></div>
</div>
<blockquote>
<div><p>Thats a lot of code! And we only handle editing the exit key!</p>
</div></blockquote>
@ -1283,86 +984,7 @@ handle a choice.</p>
</ul>
<p>The first one will have to redirect on the second. This might be more intuitive and flexible,
depending on what you want to achieve. So lets build two menus:</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># Still in commands/building.py, replace the menu class and functions by...</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Still in commands/building.py, replace the menu class and functions by...</span>
<span class="c1"># Our building menus</span>
<span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
@ -1443,7 +1065,7 @@ depending on what you want to achieve. So lets build two menus:</p>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">&quot;k&quot;</span><span class="p">,</span> <span class="n">attr</span><span class="o">=</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">glance</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{obj.key}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_choice_edit</span><span class="p">(</span><span class="s2">&quot;description&quot;</span><span class="p">,</span> <span class="s2">&quot;d&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>The code might be much easier to read. But before detailing it, lets see how it behaves in the
game:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>&gt; @edit here
@ -1558,9 +1180,9 @@ This is the northern exit. Cool huh?
</div>
<p>Very simply, we created two menus and bridged them together. This needs much less callbacks. There
is only one line in the <code class="docutils literal notranslate"><span class="pre">nomatch_exits</span></code> to add:</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">menu</span><span class="o">.</span><span class="n">open_submenu</span><span class="p">(</span><span class="s2">&quot;commands.building.ExitBuildingMenu&quot;</span><span class="p">,</span> <span class="n">exit</span><span class="p">,</span> <span class="n">parent_keys</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;e&quot;</span><span class="p">])</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">menu</span><span class="o">.</span><span class="n">open_submenu</span><span class="p">(</span><span class="s2">&quot;commands.building.ExitBuildingMenu&quot;</span><span class="p">,</span> <span class="n">exit</span><span class="p">,</span> <span class="n">parent_keys</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;e&quot;</span><span class="p">])</span>
</pre></div>
</td></tr></table></div>
</div>
<p>We have to call <code class="docutils literal notranslate"><span class="pre">open_submenu</span></code> on the menu object (which opens, as its name implies, a sub menu)
with three arguments:</p>
<ul class="simple">
@ -1594,13 +1216,11 @@ without giving it a key. If so, the menu system will try to “guess” the key
change the minimum length of any key for security reasons.</p></li>
</ul>
<p>To set one of them just do so in your menu class(es):</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="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">RoomBuildingMenu</span><span class="p">(</span><span class="n">BuildingMenu</span><span class="p">):</span>
<span class="n">keys_go_back</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;/&quot;</span><span class="p">]</span>
<span class="n">min_shortcut</span> <span class="o">=</span> <span class="mi">2</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
</section>
<section id="conclusion">
@ -1687,7 +1307,7 @@ exhaustive but user-friendly.</p>
<h3>Versions</h3>
<ul>
<li><a href="Building-menus.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>

View file

@ -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,9 +48,9 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="contrib-modules">
<section class="tex2jax_ignore mathjax_ignore" id="contrib-modules">
<h1>Contrib modules<a class="headerlink" href="#contrib-modules" title="Permalink to this headline"></a></h1>
<p>Contribs are found in <a class="reference external" href="../api/evennia.contrib.html">evennia/contrib/</a> and are optional game-specific code-snippets
<p>Contribs are found in <a class="reference internal" href="../api/evennia.contrib.html#evennia-contrib"><span class="std std-ref">evennia/contrib/</span></a> and are optional game-specific code-snippets
or even full systems you can use for your game. They are contributed by the Evennia community and
released under the same license as Evennia itself. Each contrib has its own installation instructions.
Bugs are reported to the Evennia <a class="reference external" href="https://github.com/evennia/evennia/issues/new/choose">issue tracker</a> as usual.</p>
@ -86,7 +88,7 @@ Bugs are reported to the Evennia <a class="reference external" href="https://git
<p>Adds an XYZgrid to Evennia, with map-display and pathfinding. Created via map
strings and maintained outside of the game via Evennia launch commands.</p>
<ul class="simple">
<li><p><a class="reference internal" href="XYZGrid.html"><span class="doc">XYZGrid documentation</span></a></p></li>
<li><p><a class="reference internal" href="XYZGrid.html"><span class="doc std std-doc">XYZGrid documentation</span></a></p></li>
</ul>
</section>
<section id="extended-room">
@ -99,7 +101,7 @@ strings and maintained outside of the game via Evennia launch commands.</p>
<p><em>CloudKeeper 2016</em></p>
<p>Build a game area based on a 2D “graphical” unicode map. Supports asymmetric exits.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Static-In-Game-Map.html"><span class="doc">Static in-game map</span></a></p></li>
<li><p><a class="reference internal" href="Static-In-Game-Map.html"><span class="doc std std-doc">Static in-game map</span></a></p></li>
</ul>
</section>
<section id="simple-door">
@ -117,7 +119,7 @@ strings and maintained outside of the game via Evennia launch commands.</p>
<p><em>titeuf87 2017</em></p>
<p>Make infinitely large wilderness areas with dynamically created locations.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Dynamic-In-Game-Map.html"><span class="doc">Dynamic in-game map</span></a></p></li>
<li><p><a class="reference internal" href="Dynamic-In-Game-Map.html"><span class="doc std std-doc">Dynamic in-game map</span></a></p></li>
</ul>
</section>
</section>
@ -135,9 +137,9 @@ strings and maintained outside of the game via Evennia launch commands.</p>
<p><em>Griatch 2020</em></p>
<p>A full, extendable crafting system.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Crafting.html"><span class="doc">Crafting overview</span></a></p></li>
<li><p><a class="reference external" href="../api/evennia.contrib.crafting.crafting.html">Crafting API documentation</a></p></li>
<li><p><a class="reference external" href="../api/evennia.contrib.crafting.example_recipes.html">Example of a sword crafting tree</a></p></li>
<li><p><a class="reference internal" href="Crafting.html"><span class="doc std std-doc">Crafting overview</span></a></p></li>
<li><p><a class="reference internal" href="../api/evennia.contrib.crafting.crafting.html#evennia-contrib-crafting-crafting"><span class="std std-ref">Crafting API documentation</span></a></p></li>
<li><p><a class="reference internal" href="../api/evennia.contrib.crafting.example_recipes.html#evennia-contrib-crafting-example-recipes"><span class="std std-ref">Example of a sword crafting tree</span></a></p></li>
</ul>
</section>
<section id="dice">
@ -198,8 +200,8 @@ and includes optional expansions for equipment and combat movement, magic and ra
<p><em>Vincent Le Geoff 2017</em></p>
<p>Allow Builders to add Python-scripted events to their objects (OBS-not for untrusted users!)</p>
<ul class="simple">
<li><p><a class="reference internal" href="A-voice-operated-elevator-using-events.html"><span class="doc">A voice-operated elevator using events</span></a></p></li>
<li><p><a class="reference internal" href="Dialogues-in-events.html"><span class="doc">Dialogues using events</span></a></p></li>
<li><p><a class="reference internal" href="A-voice-operated-elevator-using-events.html"><span class="doc std std-doc">A voice-operated elevator using events</span></a></p></li>
<li><p><a class="reference internal" href="Dialogues-in-events.html"><span class="doc std std-doc">Dialogues using events</span></a></p></li>
</ul>
</section>
<section id="menu-builder">
@ -207,7 +209,7 @@ and includes optional expansions for equipment and combat movement, magic and ra
<p>A tool for building using an in-game menu instead of the normal build commands. Meant to
be expanded for the needs of your game.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Building-menus.html"><span class="doc">Building Menus</span></a></p></li>
<li><p><a class="reference internal" href="Building-menus.html"><span class="doc std std-doc">Building Menus</span></a></p></li>
</ul>
</section>
<section id="security-auditing">
@ -284,7 +286,7 @@ multi-line string.</p>
<p><em>Griatch 2011, 2015</em></p>
<p>The Evennia single-player sole quest. Made to be analyzed to learn.</p>
<ul class="simple">
<li><p><a class="reference internal" href="../Howto/Starting/Part1/Tutorial-World-Introduction.html"><span class="doc">The tutorial world introduction</span></a></p></li>
<li><p><a class="reference internal" href="../Howto/Starting/Part1/Tutorial-World-Introduction.html"><span class="doc std std-doc">The tutorial world introduction</span></a></p></li>
</ul>
</section>
</section>
@ -312,7 +314,7 @@ is maintained by Tehom in its own repository so bug reports should be directed t
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/Arx-Game/arxcode">Arxcode repository on github</a></p></li>
<li><p><a class="reference external" href="https://github.com/Arx-Game/arxcode/issues">Arxcode issue tracker</a></p></li>
<li><p><a class="reference internal" href="Arxcode-installing-help.html"><span class="doc">Arxcode installation help</span></a> - this may not always be fully up-to-date with
<li><p><a class="reference internal" href="Arxcode-installing-help.html"><span class="doc std std-doc">Arxcode installation help</span></a> - this may not always be fully up-to-date with
latest Evennia. Report your findings!</p></li>
</ul>
</section>
@ -322,10 +324,10 @@ latest Evennia. Report your findings!</p></li>
<p>A full engine for making multiplayer escape-rooms completely in code.
This is based on the 2019 MUD Game jam winner <em>Evscaperoom</em>.</p>
<ul class="simple">
<li><p><a class="reference external" href="../api/evennia.contrib.evscaperoom.html">contrib/evscaperoom</a> - game engine to make your own escape rooms.</p></li>
<li><p><a class="reference internal" href="../api/evennia.contrib.evscaperoom.html#evennia-contrib-evscaperoom"><span class="std std-ref">contrib/evscaperoom</span></a> - game engine to make your own escape rooms.</p></li>
<li><p><a class="reference external" href="https://demo.evennia.com">https://demo.evennia.com</a> - a full installation of the original game can
be played by entering the <em>evscaperoom</em> exit in the first Limbo room.</p></li>
<li><p>https://github.com/Griatch/evscaperoom - the original games source code (warning for spoilers if you
<li><p><a class="reference external" href="https://github.com/Griatch/evscaperoom">https://github.com/Griatch/evscaperoom</a> - the original games source code (warning for spoilers if you
want to solve the puzzles and mystery yourself).</p></li>
</ul>
<div class="toctree-wrapper compound">
@ -449,7 +451,7 @@ want to solve the puzzles and mystery yourself).</p></li>
<h3>Versions</h3>
<ul>
<li><a href="Contrib-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>

View file

@ -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="crafting-system-contrib">
<section class="tex2jax_ignore mathjax_ignore" id="crafting-system-contrib">
<h1>Crafting system contrib<a class="headerlink" href="#crafting-system-contrib" title="Permalink to this headline"></a></h1>
<p><em>Contrib by Griatch 2020</em></p>
<div class="versionadded">
@ -55,17 +57,16 @@
</div>
<p>This contrib implements a full Crafting system that can be expanded and modified to fit your game.</p>
<ul class="simple">
<li><p>See the <a class="reference external" href="../api/evennia.contrib.crafting.crafting.html">evennia/contrib/crafting/crafting.py API</a> for installation
<li><p>See the <a class="reference internal" href="../api/evennia.contrib.crafting.crafting.html#evennia-contrib-crafting-crafting"><span class="std std-ref">evennia/contrib/crafting/crafting.py API</span></a> for installation
instructrions.</p></li>
<li><p>See the <a class="reference external" href="../api/evennia.contrib.crafting.example_recipes.html">sword example</a> for an example of how to design
<li><p>See the <a class="reference internal" href="../api/evennia.contrib.crafting.example_recipes.html#evennia-contrib-crafting-example-recipes"><span class="std std-ref">sword example</span></a> for an example of how to design
a crafting tree for crafting a sword from base elements.</p></li>
</ul>
<p>From in-game it uses the new <code class="docutils literal notranslate"><span class="pre">craft</span></code> command:</p>
<div class="highlight-bash 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>&gt; craft bread from flour, eggs, salt, water, yeast using oven, roller
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>&gt; craft bread from flour, eggs, salt, water, yeast using oven, roller
&gt; craft bandage from cloth using scissors
</pre></div>
</td></tr></table></div>
</div>
<p>The syntax is <code class="docutils literal notranslate"><span class="pre">craft</span> <span class="pre">&lt;recipe&gt;</span> <span class="pre">[from</span> <span class="pre">&lt;ingredient&gt;,...][</span> <span class="pre">using</span> <span class="pre">&lt;tool&gt;,...]</span></code>.</p>
<p>The above example uses the <code class="docutils literal notranslate"><span class="pre">bread</span></code> <em>recipe</em> and requires <code class="docutils literal notranslate"><span class="pre">flour</span></code>, <code class="docutils literal notranslate"><span class="pre">eggs</span></code>, <code class="docutils literal notranslate"><span class="pre">salt</span></code>, <code class="docutils literal notranslate"><span class="pre">water</span></code> and <code class="docutils literal notranslate"><span class="pre">yeast</span></code> objects
to be in your inventory. These will be consumed as part of crafting (baking) the bread.</p>
@ -79,15 +80,14 @@ the requirements of the recipe, a new <code class="docutils literal notranslate"
<p>With a little creativity, the recipe concept could be adopted to all sorts of things, like puzzles or
magic systems.</p>
<p>In code, you can craft using the <code class="docutils literal notranslate"><span class="pre">evennia.contrib.crafting.crafting.craft</span></code> 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>
<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">evennia.contrib.crafting.crafting</span> <span class="kn">import</span> <span class="n">craft</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia.contrib.crafting.crafting</span> <span class="kn">import</span> <span class="n">craft</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">craft</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;recipename&quot;</span><span class="p">,</span> <span class="o">*</span><span class="n">inputs</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Here, <code class="docutils literal notranslate"><span class="pre">caller</span></code> is the one doing the crafting and <code class="docutils literal notranslate"><span class="pre">*inputs</span></code> is any combination of consumables and/or tool
Objects. The system will identify which is which by the <a class="reference internal" href="../Components/Tags.html"><span class="doc">Tags</span></a> on them (see below)
Objects. The system will identify which is which by the <a class="reference internal" href="../Components/Tags.html"><span class="doc std std-doc">Tags</span></a> on them (see below)
The <code class="docutils literal notranslate"><span class="pre">result</span></code> is always a list.</p>
<section id="adding-new-recipes">
<h2>Adding new recipes<a class="headerlink" href="#adding-new-recipes" title="Permalink to this headline"></a></h2>
@ -96,26 +96,13 @@ implements the most common form of crafting - that using in-game objects. Each r
which gets initialized with the consumables/tools you provide.</p>
<p>For the <code class="docutils literal notranslate"><span class="pre">craft</span></code> command to find your custom recipes, you need to tell Evennia where they are. Add a new
line to your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> file, with a list to any new modules with recipe classes.</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">CRAFT_RECIPE_MODULES</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;world.myrecipes&quot;</span><span class="p">]</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">CRAFT_RECIPE_MODULES</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;world.myrecipes&quot;</span><span class="p">]</span>
</pre></div>
</td></tr></table></div>
</div>
<p>(You need to reload after adding this). All global-level classes in these modules (whose names dont start
with underscore) are considered by the system as viable recipes.</p>
<p>Here we assume you created <code class="docutils literal notranslate"><span class="pre">mygame/world/myrecipes.py</span></code> to match the above example setting:</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/myrecipes.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/myrecipes.py</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.crafting.crafting</span> <span class="kn">import</span> <span class="n">CraftingRecipe</span>
@ -129,27 +116,25 @@ with underscore) are considered by the system as viable recipes.</p>
<span class="s2">&quot;typeclass&quot;</span><span class="p">:</span> <span class="s2">&quot;typeclasses.objects.decorations.Toys&quot;</span><span class="p">,</span>
<span class="s2">&quot;desc&quot;</span><span class="p">:</span> <span class="s2">&quot;A small carved doll&quot;</span><span class="p">}</span>
<span class="p">]</span>
</pre></div>
</td></tr></table></div>
<p>This specifies which tags to look for in the inputs. It defines a <a class="reference internal" href="../Components/Prototypes.html"><span class="doc">Prototype</span></a>
</div>
<p>This specifies which tags to look for in the inputs. It defines a <a class="reference internal" href="../Components/Prototypes.html"><span class="doc std std-doc">Prototype</span></a>
for the recipe to use to spawn the result on the fly (a recipe could spawn more than one result if needed).
Instead of specifying the full prototype-dict, you could also just provide a list of <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code>s to
existing prototypes you have.</p>
<p>After reloading the server, this recipe would now be available to use. To try it we should
create materials and tools to insert into the recipe.</p>
<p>The recipe analyzes inputs, looking for <a class="reference internal" href="../Components/Tags.html"><span class="doc">Tags</span></a> with specific tag-categories.
<p>The recipe analyzes inputs, looking for <a class="reference internal" href="../Components/Tags.html"><span class="doc std std-doc">Tags</span></a> with specific tag-categories.
The tag-category used can be set per-recipe using the (<code class="docutils literal notranslate"><span class="pre">.consumable_tag_category</span></code> and
<code class="docutils literal notranslate"><span class="pre">.tool_tag_category</span></code> respectively). The defaults are <code class="docutils literal notranslate"><span class="pre">crafting_material</span></code> and <code class="docutils literal notranslate"><span class="pre">crafting_tool</span></code>. For
the puppet we need one object with the <code class="docutils literal notranslate"><span class="pre">wood</span></code> tag and another with the <code class="docutils literal notranslate"><span class="pre">knife</span></code> tag:</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></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="n">knife</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">&quot;Hobby knife&quot;</span><span class="p">,</span> <span class="n">tags</span><span class="o">=</span><span class="p">[(</span><span class="s2">&quot;knife&quot;</span><span class="p">,</span> <span class="s2">&quot;crafting_tool&quot;</span><span class="p">)])</span>
<span class="n">wood</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">&quot;Piece of wood&quot;</span><span class="p">,</span> <span class="n">tags</span><span class="p">[(</span><span class="s2">&quot;wood&quot;</span><span class="p">,</span> <span class="s2">&quot;crafting_material&quot;</span><span class="p">)])</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Note that the objects can have any name, all that matters is the tag/tag-category. This means if a
“bayonet” also had the “knife” crafting tag, it could also be used to carve a puppet. This is also
potentially interesting for use in puzzles and to allow users to experiment and find alternatives to
@ -161,39 +146,35 @@ know ingredients.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">seed</span></code> class-method will create simple dummy objects that fulfills the recipes requirements. This
is great for testing.</p>
<p>Assuming these objects were put in our inventory, we could now craft using the in-game command:</p>
<div class="highlight-bash 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>&gt; craft wooden puppet from wood using hobby knife
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>&gt; craft wooden puppet from wood using hobby knife
</pre></div>
</td></tr></table></div>
</div>
<p>In code we would do</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.contrub.crafting.crafting</span> <span class="kn">import</span> <span class="n">craft</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia.contrub.crafting.crafting</span> <span class="kn">import</span> <span class="n">craft</span>
<span class="n">puppet</span> <span class="o">=</span> <span class="n">craft</span><span class="p">(</span><span class="n">crafter</span><span class="p">,</span> <span class="s2">&quot;wooden puppet&quot;</span><span class="p">,</span> <span class="n">knife</span><span class="p">,</span> <span class="n">wood</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>In the call to <code class="docutils literal notranslate"><span class="pre">craft</span></code>, the order of <code class="docutils literal notranslate"><span class="pre">knife</span></code> and <code class="docutils literal notranslate"><span class="pre">wood</span></code> doesnt matter - the recipe will sort out which
is which based on their tags.</p>
</section>
<section id="deeper-customization-of-recipes">
<h2>Deeper customization of recipes<a class="headerlink" href="#deeper-customization-of-recipes" title="Permalink to this headline"></a></h2>
<p>For customizing recipes further, it helps to understand how to use the recipe-class directly:</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="k">class</span> <span class="nc">MyRecipe</span><span class="p">(</span><span class="n">CraftingRecipe</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyRecipe</span><span class="p">(</span><span class="n">CraftingRecipe</span><span class="p">):</span>
<span class="c1"># ...</span>
<span class="n">tools</span><span class="p">,</span> <span class="n">consumables</span> <span class="o">=</span> <span class="n">MyRecipe</span><span class="o">.</span><span class="n">seed</span><span class="p">()</span>
<span class="n">recipe</span> <span class="o">=</span> <span class="n">MyRecipe</span><span class="p">(</span><span class="n">crafter</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">tools</span> <span class="o">+</span> <span class="n">consumables</span><span class="p">))</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">craft</span><span class="p">()</span>
</pre></div>
</td></tr></table></div>
</div>
<p>This is useful for testing and allows you to use the class directly without adding it to a module
in <code class="docutils literal notranslate"><span class="pre">settings.CRAFTING_RECIPE_MODULES</span></code>.</p>
<p>Even without modifying more than the class properties, there are a lot of options to set on
the <code class="docutils literal notranslate"><span class="pre">CraftingRecipe</span></code> class. Easiest is to refer to the
<a class="reference external" href="Contribs/evennia.contrib.crafting.crafting.html#evennia.contrib.crafting.crafting.CraftingRecipe">CraftingRecipe api documentation</a>.
<a class="reference internal" href="../api/evennia.contrib.crafting.crafting.html#evennia.contrib.crafting.crafting.CraftingRecipe" title="evennia.contrib.crafting.crafting.CraftingRecipe"><span class="xref myst py py-class">CraftingRecipe api documentation</span></a>.
For example, you can customize the validation-error messages, decide if the ingredients have
to be exactly right, if a failure still consumes the ingredients or not, and much more.</p>
<p>For even more control you can override hooks in your own class:</p>
@ -217,30 +198,7 @@ into each crafting hook. These are unused by default but could be used to custom
<p>What the crafting system does not have out of the box is a skill system - the notion of being able
to fail the craft if you are not skilled enough. Just how skills work is game-dependent, so to add
this you need to make your own recipe parent class and have your recipes inherit from 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></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.contrib.crafting.crafting</span> <span class="kn">import</span> <span class="n">CraftingRecipe</span>
<span class="k">class</span> <span class="nc">SkillRecipe</span><span class="p">(</span><span class="n">CraftingRecipe</span><span class="p">):</span>
@ -265,12 +223,12 @@ this you need to make your own recipe parent class and have your recipes inherit
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You are not good enough to craft this. Better luck next time!&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[]</span>
</pre></div>
</td></tr></table></div>
</div>
<p>In this example we introduce a <code class="docutils literal notranslate"><span class="pre">.difficulty</span></code> for the recipe and makes a dice roll to see
if we succed. We would of course make this a lot more immersive and detailed in a full game. In
principle you could customize each recipe just the way you want it, but you could also inherit from
a central parent like this to cut down on work.</p>
<p>The <a class="reference external" href="../api/evennia.contrib.crafting.example_recipes.html">sword recipe example module</a> also shows an example
<p>The <a class="reference internal" href="../api/evennia.contrib.crafting.example_recipes.html#evennia-contrib-crafting-example-recipes"><span class="std std-ref">sword recipe example module</span></a> also shows an example
of a random skill-check being implemented in a parent and then inherited for multiple use.</p>
</section>
</section>
@ -342,7 +300,7 @@ from this rather than the more opinionated <code class="docutils literal notrans
<h3>Versions</h3>
<ul>
<li><a href="Crafting.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>

View file

@ -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="dialogues-in-events">
<section class="tex2jax_ignore mathjax_ignore" id="dialogues-in-events">
<h1>Dialogues in events<a class="headerlink" href="#dialogues-in-events" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><p>Next tutorial: [adding a voice-operated elevator with events](A-voice-operated-elevator-using-
@ -74,7 +76,7 @@ respond to specific messages said by others.</p>
<section id="a-first-example-with-a-first-character">
<h2>A first example with a first character<a class="headerlink" href="#a-first-example-with-a-first-character" title="Permalink to this headline"></a></h2>
<p>Lets create a character to begin with.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@charcreate</span> <span class="n">a</span> <span class="n">merchant</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@charcreate a merchant
</pre></div>
</div>
<p>This will create a merchant in the room where you currently are. It doesnt have anything, like a
@ -88,25 +90,25 @@ conditions.</p>
<p>You can have an overview of every “conditions” in which callbacks can be created using the <code class="docutils literal notranslate"><span class="pre">&#64;call</span></code>
command (short for <code class="docutils literal notranslate"><span class="pre">&#64;callback</span></code>). You need to give it an object as argument. Here for instance, we
could do:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@call</span> <span class="n">a</span> <span class="n">merchant</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@call a merchant
</pre></div>
</div>
<p>You should see a table with three columns, showing the list of events existing on our newly-created
merchant. There are quite a lot of them, as it is, althougn no line of code has been set yet. For
our system, you might be more interested by the line describing the <code class="docutils literal notranslate"><span class="pre">say</span></code> event:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">|</span> <span class="n">say</span> <span class="o">|</span> <span class="mi">0</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">|</span> <span class="n">After</span> <span class="n">another</span> <span class="n">character</span> <span class="n">has</span> <span class="n">said</span> <span class="n">something</span> <span class="ow">in</span> <span class="o">|</span>
<span class="o">|</span> <span class="o">|</span> <span class="o">|</span> <span class="n">the</span> <span class="n">character</span><span class="s1">&#39;s room. |</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>| say | 0 (0) | After another character has said something in |
| | | the character&#39;s room. |
</pre></div>
</div>
<p>Well create a callback on the <code class="docutils literal notranslate"><span class="pre">say</span></code> event, called when we say “hello” in the merchants room:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@call</span><span class="o">/</span><span class="n">add</span> <span class="n">a</span> <span class="n">merchant</span> <span class="o">=</span> <span class="n">say</span> <span class="n">hello</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@call/add a merchant = say hello
</pre></div>
</div>
<p>Before seeing what this command displays, lets see the command syntax itself:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&#64;call</span></code> is the command name, <code class="docutils literal notranslate"><span class="pre">/add</span></code> is a switch. You can read the help of the command to get the
help of available switches and a brief overview of syntax.</p></li>
<li><p>We then enter the objects name, here “a merchant”. You can enter the ID too (#3” in my case),
<li><p>We then enter the objects name, here “a merchant”. You can enter the ID too (#3” in my case),
which is useful to edit the object when youre not in the same room. You can even enter part of the
name, as usual.</p></li>
<li><p>An equal sign, a simple separator.</p></li>
@ -160,11 +162,10 @@ when the function was called.</p>
</pre></div>
</div>
<p>For our first test, lets type something like:</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="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> shrugs and says: &#39;well, yes, hello to you!&#39;&quot;</span><span class="p">,</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> shrugs and says: &#39;well, yes, hello to you!&#39;&quot;</span><span class="p">,</span>
<span class="n">mapping</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">character</span><span class="o">=</span><span class="n">character</span><span class="p">))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Once you have entered this line, you can type <code class="docutils literal notranslate"><span class="pre">:wq</span></code> to save the editor and quit it.</p>
<p>And now if you use the “say” command with a message containing “hello”:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">You</span> <span class="n">say</span><span class="p">,</span> <span class="s2">&quot;Hello sir merchant!&quot;</span>
@ -185,23 +186,22 @@ have also used mapping to easily display the characters name. This is not sp
Python system. If you feel overwhelmed by the code weve used, just shorten it and use something
more simple, for instance:</p></li>
</ol>
<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">speaker</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You have said something to me.&quot;</span><span class="p">)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">speaker</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You have said something to me.&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="the-same-callback-for-several-keywords">
<h2>The same callback for several keywords<a class="headerlink" href="#the-same-callback-for-several-keywords" title="Permalink to this headline"></a></h2>
<p>Its easy to create a callback that will be triggered if the sentence contains one of several
keywords.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@call</span><span class="o">/</span><span class="n">add</span> <span class="n">merchant</span> <span class="o">=</span> <span class="n">say</span> <span class="n">trade</span><span class="p">,</span> <span class="n">trader</span><span class="p">,</span> <span class="n">goods</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@call/add merchant = say trade, trader, goods
</pre></div>
</div>
<p>And in the editor that opens:</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="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> says: &#39;Ho well, trade&#39;s fine as long as roads are</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> says: &#39;Ho well, trade&#39;s fine as long as roads are</span>
<span class="n">safe</span><span class="o">.</span><span class="s1">&#39;&quot;, mapping=dict(character=character))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Then you can say something with either “trade”, “trader” or “goods” in your sentence, which should
call the callback:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">You</span> <span class="n">say</span><span class="p">,</span> <span class="s2">&quot;and how is your trade going?&quot;</span>
@ -214,21 +214,11 @@ call the callback:</p>
<h2>A longer callback<a class="headerlink" href="#a-longer-callback" title="Permalink to this headline"></a></h2>
<p>So far, we have only set one line in our callbacks. Which is useful, but we often need more. For
an entire dialogue, you might want to do a bit more than that.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@call</span><span class="o">/</span><span class="n">add</span> <span class="n">merchant</span> <span class="o">=</span> <span class="n">say</span> <span class="n">bandit</span><span class="p">,</span> <span class="n">bandits</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@call/add merchant = say bandit, bandits
</pre></div>
</div>
<p>And in the editor you can paste the following lines:</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="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> says: &#39;Bandits he?&#39;&quot;</span><span class="p">,</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> says: &#39;Bandits he?&#39;&quot;</span><span class="p">,</span>
<span class="n">mapping</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">character</span><span class="o">=</span><span class="n">character</span><span class="p">))</span>
<span class="n">character</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{character}</span><span class="s2"> scratches his head, considering.&quot;</span><span class="p">,</span>
<span class="n">mapping</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">character</span><span class="o">=</span><span class="n">character</span><span class="p">))</span>
@ -240,7 +230,7 @@ an entire dialogue, you might want to do a bit more than that.</p>
<span class="s1">&#39;em, they&#39;</span><span class="n">re</span> <span class="n">encamped</span> <span class="n">some</span> <span class="n">distance</span> <span class="n">away</span> <span class="kn">from</span> <span class="nn">the</span> <span class="n">road</span><span class="p">,</span> <span class="n">I</span> <span class="n">guess</span> <span class="n">near</span> <span class="n">a</span> <span class="n">cave</span> <span class="ow">or</span>
<span class="n">something</span><span class="o">.</span><span class="s1">&#39;.&quot;.format(character=character.get_display_name(speaker)))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Now try to ask the merchant about bandits:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">You</span> <span class="n">say</span><span class="p">,</span> <span class="s2">&quot;have you seen bandits?&quot;</span>
<span class="n">a</span> <span class="n">merchant</span><span class="p">(</span><span class="c1">#3) says: &#39;Bandits he?&#39;</span>
@ -277,7 +267,7 @@ another.</p></li>
<li><p><strong>A:</strong> Its possible but not so easy to do. Usually, event grouping is set in code, and depends
on different games. However, if it is for some infrequent occurrences, its easy to do using
[chained
events](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md#chained-
events](<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md#chained-">https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md#chained-</a>
events).</p></li>
<li><p><strong>Q:</strong> is it possible to deploy callbacks on all characters sharing the same prototype?</p></li>
<li><p><strong>A:</strong> not out of the box. This depends on individual settings in code. One can imagine that all
@ -347,7 +337,7 @@ events).</p></li>
<h3>Versions</h3>
<ul>
<li><a href="Dialogues-in-events.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>

View file

@ -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,11 +49,11 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="dynamic-in-game-map">
<section class="tex2jax_ignore mathjax_ignore" id="dynamic-in-game-map">
<h1>Dynamic In Game Map<a class="headerlink" href="#dynamic-in-game-map" title="Permalink to this headline"></a></h1>
<section id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>An often desired feature in a MUD is to show an in-game map to help navigation. The <a class="reference internal" href="Static-In-Game-Map.html"><span class="doc">Static in-game
<p>An often desired feature in a MUD is to show an in-game map to help navigation. The <a class="reference internal" href="Static-In-Game-Map.html"><span class="doc std std-doc">Static in-game
map</span></a> tutorial solves this by creating a <em>static</em> map, meaning the map is pre-
drawn once and for all - the rooms are then created to match that map. When walking around, parts of
the static map is then cut out and displayed next to the room description.</p>
@ -67,9 +69,9 @@ world to be logically impossible with rooms looping to themselves or exits
side of the map. Exits can also be named anything, from “jumping out the window” to “into the fifth
dimension”. This tutorial assumes you can only move in the cardinal directions (N, E, S and W).</p></li>
<li><p>Rooms must be connected and linked together for the map to be generated correctly. Vanilla
Evennia comes with a admin command <a class="reference external" href="Components/Default-Command-Help#tunnel-cmdtunnel">&#64;tunnel</a> that allows a
Evennia comes with a admin command <a class="reference internal" href="../api/evennia.commands.default.building.html#evennia.commands.default.building.CmdTunnel" title="evennia.commands.default.building.CmdTunnel"><span class="xref myst py py-class">tunnel</span></a> that allows a
user to create rooms in the cardinal directions, but additional work is needed to assure that rooms
are connected. For example, if you <code class="docutils literal notranslate"><span class="pre">&#64;tunnel</span> <span class="pre">east</span></code> and then immediately do <code class="docutils literal notranslate"><span class="pre">&#64;tunnel</span> <span class="pre">west</span></code> youll find
are connected. For example, if you <code class="docutils literal notranslate"><span class="pre">tunnel</span> <span class="pre">east</span></code> and then immediately do <code class="docutils literal notranslate"><span class="pre">tunnel</span> <span class="pre">west</span></code> youll find
that you have created two completely stand-alone rooms. So care is needed if you want to create a
“logical” layout. In this tutorial we assume you have such a grid of rooms that we can generate the
map from.</p></li>
@ -107,13 +109,7 @@ this tutorial we understand two symbols - a normal room and the room with us in
fallback symbol for rooms without said Attribute - that way the map will still work even if we
didnt prepare the room correctly. Assuming your game folder is named <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, we create this code
in <code class="docutils literal notranslate"><span class="pre">mygame/world/map.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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
<span class="c1"># the symbol is identified with a key &quot;sector_type&quot; on the </span>
<span class="c1"># Room. Keys None and &quot;you&quot; must always exist. </span>
@ -121,21 +117,11 @@ in <code class="docutils literal notranslate"><span class="pre">mygame/world/map
<span class="s1">&#39;you&#39;</span> <span class="p">:</span> <span class="s1">&#39;[@]&#39;</span><span class="p">,</span>
<span class="s1">&#39;SECT_INSIDE&#39;</span><span class="p">:</span> <span class="s1">&#39;[.]&#39;</span> <span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Since trying to access an unset Attribute returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, this means rooms without the <code class="docutils literal notranslate"><span class="pre">sector_type</span></code>
Atttribute will show as <code class="docutils literal notranslate"><span class="pre">.</span></code>. Next we start building the custom class <code class="docutils literal notranslate"><span class="pre">Map</span></code>. It will hold all
methods we need.</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="c1"># in mygame/world/map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
@ -147,7 +133,7 @@ methods we need.</p>
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="kc">None</span>
</pre></div>
</td></tr></table></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">self.caller</span></code> is normally your Character object, the one using the map.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">self.max_width/length</span></code> determine the max width and length of the map that will be generated. Note
@ -161,26 +147,7 @@ worm has been and what it has mapped so far.</p></li>
</ul>
<p>Before any sort of mapping can actually be done we need to create an empty display area and do some
sanity checks on it by using the following methods.</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"># in mygame/world/map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="c1"># [... continued]</span>
@ -201,24 +168,10 @@ sanity checks on it by using the following methods.</p>
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span>\
<span class="k">else</span> <span class="kc">False</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Before we can set our worm on its way, we need to know some of the computer science behind all this
called Graph Traversing. In Pseudo code what we are trying to accomplish is 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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># pseudo code</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># pseudo code</span>
<span class="k">def</span> <span class="nf">draw_room_on_map</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="n">max_distance</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
@ -234,7 +187,7 @@ called Graph Traversing. In Pseudo code what we are trying to accomplish i
<span class="c1"># first time here!</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">max_distance</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>The beauty of Python is that our actual code of doing this doesnt differ much if at all from this
Pseudo code example.</p>
<ul class="simple">
@ -272,24 +225,7 @@ location in the middle of the grid</p></li>
</ul>
<p>Now that we know which methods we need, lets refine our initial <code class="docutils literal notranslate"><span class="pre">__init__(self)</span></code> to pass some
conditional statements and set it up to start building the display.</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
@ -307,31 +243,14 @@ conditional statements and set it up to start building the display.</p>
<span class="c1"># we use the algebraic relationship</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
<span class="p">((</span><span class="nb">min</span><span class="p">(</span><span class="n">max_width</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span> <span class="o">-</span><span class="mi">1</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Here we check to see if the parameters for the grid are okay, then we create an empty canvas and map
our initial location as the first room!</p>
<p>As mentioned above, the code for the <code class="docutils literal notranslate"><span class="pre">self.draw_room_on_map()</span></code> is not much different than the Pseudo
code. The method is shown below:</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py, in the Map class</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py, in the Map class</span>
<span class="k">def</span> <span class="nf">draw_room_on_map</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">max_distance</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
@ -351,20 +270,9 @@ code. The method is shown below:</p>
<span class="bp">self</span><span class="o">.</span><span class="n">update_pos</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="n">exit</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">max_distance</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>The first thing the “worm” does is to draw your current location in <code class="docutils literal notranslate"><span class="pre">self.draw</span></code>. Lets define that…</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">#in mygame/word/map.py, in the Map class </span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#in mygame/word/map.py, in the Map class </span>
<span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
<span class="c1"># draw initial ch location on map first!</span>
@ -377,22 +285,9 @@ code. The method is shown below:</p>
<span class="c1"># this will use the sector_type Attribute or None if not set.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="n">room</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">sector_type</span><span class="p">]</span>
</pre></div>
</td></tr></table></div>
</div>
<p>In <code class="docutils literal notranslate"><span class="pre">self.start_loc_on_grid()</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">median</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">median</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">):</span>
<span class="n">lst</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num</span><span class="p">))</span>
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lst</span><span class="p">)</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">n</span> <span class="o">-</span><span class="mi">1</span>
@ -407,35 +302,19 @@ code. The method is shown below:</p>
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="s1">&#39;you&#39;</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="c1"># updating worms current location</span>
</pre></div>
</td></tr></table></div>
</div>
<p>After the system has drawn the current map it checks to see if the <code class="docutils literal notranslate"><span class="pre">max_distance</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code> (since this
is the inital start phase it is not). Now we handle the iteration once we have each individual exit
in the room. The first thing it does is check if the room the Worm is in has been mapped already..
in the room. The first thing it does is check if the room the Worm is in has been mapped already
lets define that…</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">has_drawn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">has_drawn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">room</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span> <span class="k">else</span> <span class="kc">False</span>
</pre></div>
</td></tr></table></div>
</div>
<p>If <code class="docutils literal notranslate"><span class="pre">has_drawn</span></code> returns <code class="docutils literal notranslate"><span class="pre">False</span></code> that means the worm has found a room that hasnt been mapped yet. It
will then move there. The self.curX/Y sort of lags behind, so we have to make sure to track the
position of the worm; we do this in <code class="docutils literal notranslate"><span class="pre">self.update_pos()</span></code> below.</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="k">def</span> <span class="nf">update_pos</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">exit_name</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update_pos</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">exit_name</span><span class="p">):</span>
<span class="c1"># this ensures the coordinates stays up to date </span>
<span class="c1"># to where the worm is currently at.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> \
@ -452,18 +331,12 @@ position of the worm; we do this in <code class="docutils literal notranslate"><
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">&#39;south&#39;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">+=</span> <span class="mi">1</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Once the system updates the position of the worm it feeds the new room back into the original
<code class="docutils literal notranslate"><span class="pre">draw_room_on_map()</span></code> and starts the process all over again..</p>
<code class="docutils literal notranslate"><span class="pre">draw_room_on_map()</span></code> and starts the process all over again</p>
<p>That is essentially the entire thing. The final method is to bring it all together and make a nice
presentational string out of it using the <code class="docutils literal notranslate"><span class="pre">self.show_map()</span></code> method.</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="k">def</span> <span class="nf">show_map</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">show_map</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">map_string</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">:</span>
<span class="n">map_string</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
@ -471,7 +344,7 @@ presentational string out of it using the <code class="docutils literal notransl
<span class="k">return</span> <span class="n">map_string</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="using-the-map">
<h2>Using the Map<a class="headerlink" href="#using-the-map" title="Permalink to this headline"></a></h2>
@ -481,20 +354,7 @@ presentational string out of it using the <code class="docutils literal notransl
<div><p><code class="docutils literal notranslate"><span class="pre">return_appearance</span></code> is a default Evennia hook available on all objects; it is called e.g. by the
<code class="docutils literal notranslate"><span class="pre">look</span></code> command to get the description of something (the room in this case).</p>
</div></blockquote>
<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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/typeclasses/rooms.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/typeclasses/rooms.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultRoom</span>
<span class="kn">from</span> <span class="nn">world.map</span> <span class="kn">import</span> <span class="n">Map</span>
@ -509,15 +369,15 @@ presentational string out of it using the <code class="docutils literal notransl
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="n">looker</span><span class="p">)</span>
<span class="k">return</span> <span class="n">string</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Obviously this method of generating maps doesnt take into account of any doors or exits that are
hidden.. etc.. but hopefully it serves as a good base to start with. Like previously mentioned, it
hidden… etc… but hopefully it serves as a good base to start with. Like previously mentioned, it
is very important to have a solid foundation on rooms before implementing this. You can try this on
vanilla evennia by using &#64;tunnel and essentially you can just create a long straight/edgy non-
looping rooms that will show on your in-game map.</p>
<p>The above example will display the map above the room description. You could also use an
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.utils.evtable">EvTable</a> to place description and map next to each other. Some other
things you can do is to have a <a class="reference internal" href="../Components/Commands.html"><span class="doc">Command</span></a> that displays with a larger radius, maybe with a
things you can do is to have a <a class="reference internal" href="../Components/Commands.html"><span class="doc std std-doc">Command</span></a> that displays with a larger radius, maybe with a
legend and other features.</p>
<p>Below is the whole <code class="docutils literal notranslate"><span class="pre">map.py</span></code> for your reference. You need to update your <code class="docutils literal notranslate"><span class="pre">Room</span></code> typeclass (see above)
to actually call it. Remember that to see different symbols for a location you also need to set the
@ -525,119 +385,7 @@ to actually call it. Remember that to see different symbols for a location you a
example, to make a room be mapped as <code class="docutils literal notranslate"><span class="pre">[.]</span></code> you would set the rooms <code class="docutils literal notranslate"><span class="pre">sector_type</span></code> to
<code class="docutils literal notranslate"><span class="pre">&quot;SECT_INSIDE&quot;</span></code>. Try it out with <code class="docutils literal notranslate"><span class="pre">&#64;set</span> <span class="pre">here/sector_type</span> <span class="pre">=</span> <span class="pre">&quot;SECT_INSIDE&quot;</span></code>. If you wanted all new
rooms to have a given sector symbol, you could change the default in the <code class="docutils literal notranslate"><span class="pre">SYMBOLS´</span> <span class="pre">dictionary</span> <span class="pre">below,</span> <span class="pre">or</span> <span class="pre">you</span> <span class="pre">could</span> <span class="pre">add</span> <span class="pre">the</span> <span class="pre">Attribute</span> <span class="pre">in</span> <span class="pre">the</span> <span class="pre">Room's</span> </code>at_object_creation` method.</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
<span class="c1"># These are keys set with the Attribute sector_type on the room.</span>
<span class="c1"># The keys None and &quot;you&quot; must always exist.</span>
@ -751,7 +499,7 @@ rooms to have a given sector symbol, you could change the default in the <code c
<span class="k">return</span> <span class="n">map_string</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="final-comments">
<h2>Final Comments<a class="headerlink" href="#final-comments" title="Permalink to this headline"></a></h2>
@ -821,7 +569,7 @@ also look into up/down directions and figure out how to display that in a good w
<h3>Versions</h3>
<ul>
<li><a href="Dynamic-In-Game-Map.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>

View file

@ -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="static-in-game-map">
<section class="tex2jax_ignore mathjax_ignore" id="static-in-game-map">
<h1>Static In Game Map<a class="headerlink" href="#static-in-game-map" title="Permalink to this headline"></a></h1>
<section id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>This tutorial describes the creation of an in-game map display based on a pre-drawn map. It also
details how to use the <a class="reference internal" href="../Components/Batch-Code-Processor.html"><span class="doc">Batch code processor</span></a> for advanced building. There is
also the <a class="reference internal" href="Dynamic-In-Game-Map.html"><span class="doc">Dynamic in-game map tutorial</span></a> that works in the opposite direction,
details how to use the <a class="reference internal" href="../Components/Batch-Code-Processor.html"><span class="doc std std-doc">Batch code processor</span></a> for advanced building. There is
also the <a class="reference internal" href="Dynamic-In-Game-Map.html"><span class="doc std std-doc">Dynamic in-game map tutorial</span></a> that works in the opposite direction,
by generating a map from an existing grid of rooms.</p>
<p>Evennia does not require its rooms to be positioned in a “logical” way. Your exits could be named
anything. You could make an exit “west” that leads to a room described to be in the far north. You
@ -86,13 +88,13 @@ Exits: north(#8), east(#9), south(#10), west(#11)
</li>
</ol>
<p>We will henceforth assume your game folder is name named <code class="docutils literal notranslate"><span class="pre">mygame</span></code> and that you havent modified the
default commands. We will also not be using <a class="reference external" href="Concepts/TextTags.html#colored-text">Colors</a> for our map since they
default commands. We will also not be using <a class="reference internal" href="../Concepts/Colors.html"><span class="doc std std-doc">Colors</span></a> for our map since they
dont show in the documentation wiki.</p>
</section>
<section id="planning-the-map">
<h2>Planning the Map<a class="headerlink" href="#planning-the-map" title="Permalink to this headline"></a></h2>
<p>Lets begin with the fun part! Maps in MUDs come in many different [shapes and
sizes](http://journal.imaginary-realities.com/volume-05/issue-01/modern-interface-modern-
sizes](<a class="reference external" href="http://journal.imaginary-realities.com/volume-05/issue-01/modern-interface-modern-">http://journal.imaginary-realities.com/volume-05/issue-01/modern-interface-modern-</a>
mud/index.html). Some appear as just boxes connected by lines. Others have complex graphics that are
external to the game itself.</p>
<p>Our map will be in-game text but that doesnt mean were restricted to the normal alphabet! If
@ -124,54 +126,28 @@ planning at this stage can solve many problems before they happen.</p>
<h2>Creating a Map Object<a class="headerlink" href="#creating-a-map-object" title="Permalink to this headline"></a></h2>
<p>In this section we will try to create an actual “map” object that an account can pick up and look
at.</p>
<p>Evennia offers a range of <a class="reference external" href="../api/evennia.commands.default.html#modules">default commands</a> for
<a class="reference internal" href="../Howto/Starting/Part1/Building-Quickstart.html"><span class="doc">creating objects and rooms in-game</span></a>. While readily accessible, these commands are made to do very
<p>Evennia offers a range of <a class="reference internal" href="../Components/Default-Commands.html"><span class="doc std std-doc">default commands</span></a> for
<a class="reference internal" href="../Howto/Starting/Part1/Building-Quickstart.html"><span class="doc std std-doc">creating objects and rooms in-game</span></a>. While readily accessible, these commands are made to do very
specific, restricted things and will thus not offer as much flexibility to experiment (for an
advanced exception see <a class="reference external" href="Concepts/TextTags.html#new-inlinefuncs">in-line functions</a>). Additionally, entering long
advanced exception see <a class="reference internal" href="../Components/FuncParser.html"><span class="doc std std-doc">the FuncParser</span></a>). Additionally, entering long
descriptions and properties over and over in the game client can become tedious; especially when
testing and you may want to delete and recreate things over and over.</p>
<p>To overcome this, Evennia offers <a class="reference internal" href="../Components/Batch-Processors.html"><span class="doc">batch processors</span></a> that work as input-files
<p>To overcome this, Evennia offers <a class="reference internal" href="../Components/Batch-Processors.html"><span class="doc std std-doc">batch processors</span></a> that work as input-files
created out-of-game. In this tutorial well be using the more powerful of the two available batch
processors, the <a class="reference internal" href="../Components/Batch-Code-Processor.html"><span class="doc">Batch Code Processor </span></a>, called with the <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span></code> command.
processors, the <a class="reference internal" href="../Components/Batch-Code-Processor.html"><span class="doc std std-doc">Batch Code Processor </span></a>, called with the <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span></code> command.
This is a very powerful tool. It allows you to craft Python files to act as blueprints of your
entire game world. These files have access to use Evennias Python API directly. Batchcode allows
for easy editing and creation in whatever text editor you prefer, avoiding having to manually build
the world line-by-line inside the game.</p>
<blockquote>
<div><p>Important warning: <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span></code>s power is only rivaled by the <code class="docutils literal notranslate"><span class="pre">&#64;py</span></code> command. Batchcode is so
powerful it should be reserved only for the <a class="reference internal" href="../Concepts/Building-Permissions.html"><span class="doc">superuser</span></a>. Think carefully
powerful it should be reserved only for the <a class="reference internal" href="../Concepts/Building-Permissions.html"><span class="doc std std-doc">superuser</span></a>. Think carefully
before you let others (such as <code class="docutils literal notranslate"><span class="pre">Developer</span></code>- level staff) run <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span></code> on their own - make sure
you are okay with them running <em>arbitrary Python code</em> on your server.</p>
</div></blockquote>
<p>While a simple example, the map object it serves as good way to try out <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span></code>. Go to
<code class="docutils literal notranslate"><span class="pre">mygame/world</span></code> and create a new file there named <code class="docutils literal notranslate"><span class="pre">batchcode_map.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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/batchcode_map.py</span>
<div class="highlight-Python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/batchcode_map.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
@ -199,7 +175,7 @@ you are okay with them running <em>arbitrary Python code</em> on your server.</p
<span class="c1"># This message lets us know our map was created successfully.</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;A map appears out of thin air and falls to the ground.&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Log into your game project as the superuser and run the command</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@batchcode</span> <span class="n">batchcode_map</span>
</pre></div>
@ -216,75 +192,7 @@ map does not actually exist yet - were all mapped up with nowhere to go! Let
build a game area based on our map. We have five areas outlined: a castle, a cottage, a campsite, a
coastal beach and the crossroads which connects them. Create a new batchcode file for this in
<code class="docutils literal notranslate"><span class="pre">mygame/world</span></code>, named <code class="docutils literal notranslate"><span class="pre">batchcode_world.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="c1"># mygame/world/batchcode_world.py</span>
<div class="highlight-Python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/batchcode_world.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span><span class="p">,</span> <span class="n">search_object</span>
<span class="kn">from</span> <span class="nn">typeclasses</span> <span class="kn">import</span> <span class="n">rooms</span><span class="p">,</span> <span class="n">exits</span>
@ -354,7 +262,7 @@ coastal beach and the crossroads which connects them. Create a new batchcode fil
<span class="n">limbo_exit</span> <span class="o">=</span> <span class="n">create_object</span><span class="p">(</span><span class="n">exits</span><span class="o">.</span><span class="n">Exit</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">&quot;enter world&quot;</span><span class="p">,</span>
<span class="n">aliases</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;enter&quot;</span><span class="p">],</span> <span class="n">location</span><span class="o">=</span><span class="n">limbo</span><span class="p">,</span> <span class="n">destination</span><span class="o">=</span><span class="n">centre</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Apply this new batch code with <code class="docutils literal notranslate"><span class="pre">&#64;batchcode</span> <span class="pre">batchcode_world</span></code>. If there are no errors in the code we
now have a nice mini-world to explore. Remember that if you get lost you can look at the map we
created!</p>
@ -373,51 +281,7 @@ batchcode.</p>
in a format which allows us to do that easily. Luckily, python allows us to treat strings as lists
of characters allowing us to pick out the characters we need.</p>
<p><code class="docutils literal notranslate"><span class="pre">mygame/world/map_module.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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># We place our map into a sting here.</span>
<div class="highlight-Python notranslate"><div class="highlight"><pre><span></span><span class="c1"># We place our map into a sting here.</span>
<span class="n">world_map</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span><span class="se">\</span>
<span class="s2">≈≈↑↑↑↑↑∩∩</span>
<span class="s2">≈≈↑╔═╗↑∩∩</span>
@ -463,20 +327,10 @@ of characters allowing us to pick out the characters we need.</p>
<span class="k">return</span> <span class="nb">map</span>
</pre></div>
</td></tr></table></div>
</div>
<p>With our map_module set up, lets replace our hardcoded map in <code class="docutils literal notranslate"><span class="pre">mygame/world/batchcode_map.py</span></code> with
a reference to our map module. Make sure to import our map_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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/batchcode_map.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/world/batchcode_map.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
@ -488,7 +342,7 @@ a reference to our map module. Make sure to import our map_module!</p>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;A map appears out of thin air and falls to the ground.&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Log into Evennia as the superuser and run this batchcode. If everything worked our new map should
look exactly the same as the old map - you can use <code class="docutils literal notranslate"><span class="pre">&#64;delete</span></code> to delete the old one (use a number to
pick which to delete).</p>
@ -503,67 +357,7 @@ is a little module called <a class="reference external" href="https://github.com
creator for you to utilize in your game. Well use it by creating a basic table with 1 row and two
columns (one for our map and one for our text) whilst also hiding the borders. Open the batchfile
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>
<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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame\world\batchcode_world.py</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame\world\batchcode_world.py</span>
<span class="c1"># Add to imports</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">evtable</span>
@ -625,7 +419,7 @@ again</p>
<span class="n">border</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="n">west</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span><span class="o">.</span><span class="n">reformat_column</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">70</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Before we run our new batchcode, if you are anything like me you would have something like 100 maps
lying around and 3-4 different versions of our rooms extending from limbo. Lets wipe it all and
start with a clean slate. In Command Prompt you can run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">flush</span></code> to clear the database and
@ -640,8 +434,8 @@ Prompt use <code class="docutils literal notranslate"><span class="pre">evennia<
easily new game defining features can be added to Evennia.</p>
<p>You can easily build from this tutorial by expanding the map and creating more rooms to explore. Why
not add more features to your game by trying other tutorials: [Add weather to your world](Weather-
Tutorial), <a class="reference internal" href="../Howto/Tutorial-Aggressive-NPCs.html"><span class="doc">fill your world with NPCs</span></a> or
<a class="reference internal" href="../Howto/Starting/Part3/Turn-based-Combat-System.html"><span class="doc">implement a combat system</span></a>.</p>
Tutorial), <a class="reference internal" href="../Howto/Tutorial-Aggressive-NPCs.html"><span class="doc std std-doc">fill your world with NPCs</span></a> or
<a class="reference internal" href="../Howto/Starting/Part3/Turn-based-Combat-System.html"><span class="doc std std-doc">implement a combat system</span></a>.</p>
</section>
</section>
@ -704,7 +498,7 @@ Tutorial), <a class="reference internal" href="../Howto/Tutorial-Aggressive-NPCs
<h3>Versions</h3>
<ul>
<li><a href="Static-In-Game-Map.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>

View file

@ -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="xyzgrid-contrib">
<section class="tex2jax_ignore mathjax_ignore" id="xyzgrid-contrib">
<h1>XYZGrid contrib<a class="headerlink" href="#xyzgrid-contrib" title="Permalink to this headline"></a></h1>
<div class="versionadded">
<p><span class="versionmodified added">New in version 1.0.</span></p>
@ -49,7 +51,8 @@ aware of their X, Y, Z coordinates. The system includes shortest-path
pathfinding, auto-stepping and in-game map visualization (with visibility
range). Grid-management is done outside of the game using a new evennia-launcher
option.</p>
<script id="asciicast-Zz36JuVAiPF0fSUR09Ii7lcxc" src="https://asciinema.org/a/Zz36JuVAiPF0fSUR09Ii7lcxc.js" async></script><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-#-# #</span>
<script id="asciicast-Zz36JuVAiPF0fSUR09Ii7lcxc" src="https://asciinema.org/a/Zz36JuVAiPF0fSUR09Ii7lcxc.js" async></script>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-#-# #</span>
<span class="o">|</span> <span class="o">/</span> <span class="n">d</span>
<span class="c1">#-# | #</span>
\ <span class="n">u</span> <span class="o">|</span>\
@ -70,6 +73,7 @@ option.</p>
<span class="n">Dungeon</span> <span class="n">Entrance</span>
<span class="n">To</span> <span class="n">the</span> <span class="n">east</span><span class="p">,</span> <span class="n">a</span> <span class="n">narrow</span> <span class="n">opening</span> <span class="n">leads</span> <span class="n">into</span> <span class="n">darkness</span><span class="o">.</span>
<span class="n">Exits</span><span class="p">:</span> <span class="n">northeast</span> <span class="ow">and</span> <span class="n">east</span>
</pre></div>
</div>
<section id="installation">
@ -78,9 +82,9 @@ option.</p>
<li><p>XYZGrid requires the <code class="docutils literal notranslate"><span class="pre">scipy</span></code> library. Easiest is to just install the
optional/contrib requirements in <code class="docutils literal notranslate"><span class="pre">evennia/requirements_extra.txt</span></code> by
doing</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="n">cd</span> <span class="n">to</span> <span class="n">evennia</span><span class="o">/</span> <span class="n">folder</span><span class="p">)</span>
<span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">r</span> <span class="n">requirements_extra</span><span class="o">.</span><span class="n">txt</span>
<span class="p">(</span><span class="n">then</span> <span class="n">go</span> <span class="n">back</span> <span class="n">to</span> <span class="n">your</span> <span class="n">mygame</span><span class="o">/</span> <span class="n">folder</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> (cd to evennia/ folder)
pip install -r requirements_extra.txt
(then go back to your mygame/ folder)
</pre></div>
</div>
<p>This will install all optional requirements of Evennia.</p>
@ -90,11 +94,11 @@ doing</p>
the server. This makes the <code class="docutils literal notranslate"><span class="pre">map</span></code>, <code class="docutils literal notranslate"><span class="pre">goto/path</span></code> and the modified <code class="docutils literal notranslate"><span class="pre">teleport</span></code> and
<code class="docutils literal notranslate"><span class="pre">open</span></code> commands available in-game.</p></li>
<li><p>Edit <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> and add</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">EXTRA_LAUNCHER_COMMANDS</span><span class="p">[</span><span class="s1">&#39;xyzgrid&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;evennia.contrib.launchcmd.xyzcommand&#39;</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>EXTRA_LAUNCHER_COMMANDS[&#39;xyzgrid&#39;] = &#39;evennia.contrib.launchcmd.xyzcommand&#39;
</pre></div>
</div>
<p>and</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>PROTOTYPE_MODULES += [evennia.contrib.xyzgrid.prototypes]
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>PROTOTYPE_MODULES += [evennia.contrib.xyzgrid.prototypes]
</pre></div>
</div>
<p>This will add the new ability to enter <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span> <span class="pre">&lt;option&gt;</span></code> on the
@ -103,7 +107,7 @@ available for use as prototype-parents when spawning the grid.</p>
</li>
<li><p>Run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span> <span class="pre">help</span></code> for available options.</p></li>
<li><p>(Optional): By default, the xyzgrid will only spawn module-based
<a class="reference internal" href="../Components/Prototypes.html"><span class="doc">prototypes</span></a>. This is an optimization and usually makes sense
<a class="reference internal" href="../Components/Prototypes.html"><span class="doc std std-doc">prototypes</span></a>. This is an optimization and usually makes sense
since the grid is entirely defined outside the game anyway. If you want to
also make use of in-game (db-) created prototypes, add
<code class="docutils literal notranslate"><span class="pre">XYZGRID_USE_DB_PROTOTYPES</span> <span class="pre">=</span> <span class="pre">True</span></code> to settings.</p></li>
@ -116,11 +120,11 @@ also make use of in-game (db-) created prototypes, add
<li><p>The <code class="docutils literal notranslate"><span class="pre">XYMap</span></code> - This class parses modules with special <em>Map strings</em>
and <em>Map legends</em> into one Python object. It has helpers for pathfinding and
visual-range handling.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> - This is a singleton <a class="reference internal" href="../Components/Scripts.html"><span class="doc">Script</span></a> that
<li><p>The <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> - This is a singleton <a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Script</span></a> that
stores all <code class="docutils literal notranslate"><span class="pre">XYMaps</span></code> in the game. It is the central point for managing the grid
of the game.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">XYZRoom</span></code> and <code class="docutils literal notranslate"><span class="pre">XYZExit</span></code>are custom typeclasses that use
<a class="reference internal" href="../Components/Tags.html"><span class="doc">Tags</span></a>
<a class="reference internal" href="../Components/Tags.html"><span class="doc std std-doc">Tags</span></a>
to know which X,Y,Z coordinate they are located at. The <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> is
abstract until it is used to <em>spawn</em> these database entities into
something you can actually interract with in the game. The <code class="docutils literal notranslate"><span class="pre">XYZRoom</span></code>
@ -135,57 +139,57 @@ manage the grid from the terminal (no game login is needed).</p></li>
<h2>First example usage<a class="headerlink" href="#first-example-usage" title="Permalink to this headline"></a></h2>
<p>After installation, do the following from your command line (where the
<code class="docutils literal notranslate"><span class="pre">evennia</span></code> command is available):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid init
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid init
</pre></div>
</div>
<p>use <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span> <span class="pre">help</span></code> to see all options)
This will create a new <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> <a class="reference internal" href="../Components/Scripts.html"><span class="doc">Script</span></a> if one didnt already exist.
This will create a new <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> <a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Script</span></a> if one didnt already exist.
The <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span></code> is a custom launch option added only for this contrib.</p>
<p>The xyzgrid-contrib comes with a full grid example. Lets add it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid add evennia.contrib.xyzgrid.example
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid add evennia.contrib.xyzgrid.example
</pre></div>
</div>
<p>You can now list the maps on your grid:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid list
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid list
</pre></div>
</div>
<p>Youll find there are two new maps added. You can find a lot of extra info
about each map with the <code class="docutils literal notranslate"><span class="pre">show</span></code> subcommand:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid show &quot;the large tree&quot;
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid show &quot;the large tree&quot;
$ evennia xyzgrid show &quot;the small cave&quot;
</pre></div>
</div>
<p>If you want to peek at how the grids code, open
<a class="reference external" href="../api/evennia.contrib.xyzgrid.example.html">evennia/contrib/xyzgrid/example.py</a>.
<a class="reference internal" href="../api/evennia.contrib.xyzgrid.example.html#evennia-contrib-xyzgrid-example"><span class="std std-ref">evennia/contrib/xyzgrid/example.py</span></a>.
(Well explain the details in later sections).</p>
<p>So far the grid is abstract and has no actual in-game presence. Lets
spawn actual rooms/exits from it. This will take a little while.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid spawn
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid spawn
</pre></div>
</div>
<p>This will take prototypes stored with each maps <em>map legend</em> and use that
to build XYZ-aware rooms there. It will also parse all links to make suitable
exits between locations. You should rerun this command if you ever modify the
layout/prototypes of your grid. Running it multiple times is safe.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia reload
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia reload
</pre></div>
</div>
<p>(or <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">start</span></code> if server was not running). This is important to do after
every spawning operation, since the <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span></code> operates outside of the
regular evennia process. Reloading makes sure all caches are refreshed.</p>
<p>Now you can log into the server. Some new commands should be available to you.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">teleport</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">the</span> <span class="n">large</span> <span class="n">tree</span><span class="p">)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport (3,0,the large tree)
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">teleport</span></code> command now accepts an optional (X, Y, Z) coordinate. Teleporting
to a room-name or <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> still works the same. This will teleport you onto the
grid. You should see a map-display. Try walking around.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">map</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>map
</pre></div>
</div>
<p>This new builder-only command shows the current map in its full form (also
showing invisible markers usually not visible to users.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">teleport</span> <span class="p">(</span><span class="mi">3</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>teleport (3, 0)
</pre></div>
</div>
<p>Once you are in a grid-room, you can teleport to another grid room <em>on the same
@ -193,14 +197,14 @@ map</em> without specifying the Z coordinate/map name.</p>
<p>You can use <code class="docutils literal notranslate"><span class="pre">open</span></code> to make an exit back to the non-grid, but remember that you
mustnt use a cardinal direction to do so - if you do, the <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span> <span class="pre">spawn</span></code>
will likely remove it next time you run it.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span> <span class="n">To</span> <span class="n">limbo</span><span class="p">;</span><span class="n">limbo</span> <span class="o">=</span> <span class="c1">#2</span>
<span class="n">limbo</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open To limbo;limbo = #2
limbo
</pre></div>
</div>
<p>You are back in Limbo (which doesnt know anything about XYZ coordinates). You
can however make a permanent link back into the gridmap:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span> <span class="n">To</span> <span class="n">grid</span><span class="p">;</span><span class="n">grid</span> <span class="o">=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">the</span> <span class="n">large</span> <span class="n">tree</span><span class="p">)</span>
<span class="n">grid</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open To grid;grid = (3,0,the large tree)
grid
</pre></div>
</div>
<p>This is how you link non-grid and grid locations together. You could for example
@ -208,13 +212,13 @@ embed a house inside the grid this way.</p>
<p>the <code class="docutils literal notranslate"><span class="pre">(3,0,the</span> <span class="pre">large</span> <span class="pre">tree)</span></code> is a Dungeon entrance. If you walk east youll
<em>transition</em> into “the small cave” map. This is a small underground dungeon
with limited visibility. Go back outside again (back on “the large tree” map).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">path</span> <span class="n">view</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>path view
</pre></div>
</div>
<p>This finds the shortest path to the “A gorgeous view” room, high up in the large
tree. If you have color in your client, you should see the start of the path
visualized in yellow.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">goto</span> <span class="n">view</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>goto view
</pre></div>
</div>
<p>This will start auto-walking you to the view. On the way youll both move up
@ -222,7 +226,7 @@ into the tree as well as traverse an in-map teleporter. Use <code class="docutil
to abort the auto-walk.</p>
<p>When you are done exploring, open the terminal (outside the game) again and
remove everything:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid delete
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid delete
</pre></div>
</div>
<p>You will be asked to confirm the deletion of the grid and unloading of the
@ -246,6 +250,7 @@ precedence. This allows for storing multiple maps in one module.</p></li>
<span class="s2">&quot;prototypes&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="nb">dict</span><span class="p">,</span> <span class="n">optional</span><span class="o">&gt;</span>
<span class="s2">&quot;options&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="nb">dict</span><span class="p">,</span> <span class="n">optional</span><span class="o">&gt;</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
@ -316,10 +321,11 @@ how pathfinding should work etc.</p></li>
<span class="n">XYMAP_DATA_LIST</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">XYMAP_DATA</span>
<span class="p">]</span>
</pre></div>
</div>
<p>The above map would be added to the grid with</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid add world.mymap
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ evennia xyzgrid add world.mymap
</pre></div>
</div>
<p>In the following sections well discuss each component in turn.</p>
@ -358,6 +364,7 @@ It is added to <code class="docutils literal notranslate"><span class="pre">XYMA
<span class="s2">+ 0 1 2</span>
<span class="s2">&quot;&quot;&quot;</span>
</pre></div>
</div>
<p>On the coordinate axes, only the two <code class="docutils literal notranslate"><span class="pre">+</span></code> are significant - the numbers are
@ -391,19 +398,19 @@ to organize.</p>
space along all axes. Between these full coordinates are <code class="docutils literal notranslate"><span class="pre">.5</span></code> coordinates.
Note that there are <em>no</em> <code class="docutils literal notranslate"><span class="pre">.5</span></code> coordinates spawned in-game; they are only used
in the map string to have space to describe how rooms/nodes link to one another.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">+</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+ 0 1 2 3 4 5
<span class="mi">4</span> <span class="n">E</span>
<span class="n">B</span>
<span class="mi">3</span>
4 E
B
3
<span class="mi">2</span> <span class="n">D</span>
2 D
<span class="mi">1</span> <span class="n">C</span>
1 C
<span class="mi">0</span> <span class="n">A</span>
0 A
<span class="o">+</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span>
+ 0 1 2 3 4 5
</pre></div>
</div>
<ul class="simple">
@ -441,14 +448,15 @@ on the map to Python code.</p>
<span class="p">}</span>
<span class="c1"># added to XYMAP_DATA dict as &#39;legend&#39;: LEGEND below</span>
</pre></div>
</div>
<p>The legend is optional, and any symbol not explicitly given in your legend will
fall back to its value in the default legend <a class="reference external" href="#default-legend">outlined below</a>.</p>
fall back to its value in the default legend <a class="reference internal" href="#default-legend"><span class="std std-doc">outlined below</span></a>.</p>
<ul class="simple">
<li><p><a class="reference external" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapNode">MapNode</a>
<li><p><a class="reference internal" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapNode" title="evennia.contrib.xyzgrid.xymap_legend.MapNode"><span class="xref myst py py-class">MapNode</span></a>
is the base class for all nodes.</p></li>
<li><p><a class="reference external" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapLink">MapLink</a>
<li><p><a class="reference internal" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapLink" title="evennia.contrib.xyzgrid.xymap_legend.MapLink"><span class="xref myst py py-class">MapLink</span></a>
is the base class for all links.</p></li>
</ul>
<p>As the <em>Map String</em> is parsed, each found symbol is looked up in the legend and
@ -459,7 +467,7 @@ initialized into the corresponding MapNode/Link instance.</p>
with a full set of map elements that use these properties in various ways
(described in the next section).</p>
<p>Some useful properties of the
<a class="reference external" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapNode">MapNode</a>
<a class="reference internal" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapNode" title="evennia.contrib.xyzgrid.xymap_legend.MapNode"><span class="xref myst py py-class">MapNode</span></a>
class (see class doc for hook methods):</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">symbol</span></code> (str) - The character to parse from the map into this node. By default this
@ -482,12 +490,12 @@ further in-game action not covered by the map (such as a guard or locked gate
etc).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">prototype</span></code> (dict) - The default <code class="docutils literal notranslate"><span class="pre">prototype</span></code> dict to use for reproducing this
map component on the game grid. This is used if not overridden specifically
for this coordinate in the “prototype” dict of <code class="docutils literal notranslate"><span class="pre">XYMAP_DATA</span></code>.. If this is not
for this coordinate in the “prototype” dict of <code class="docutils literal notranslate"><span class="pre">XYMAP_DATA</span></code> If this is not
given, nothing will be spawned for this coordinate (a virtual node can be
useful for various reasons, mostly map-transitions).</p></li>
</ul>
<p>Some useful properties of the
<a class="reference external" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapLink">MapLink</a>
<a class="reference internal" href="../api/evennia.contrib.xyzgrid.xymap_legend.html#evennia.contrib.xyzgrid.xymap_legend.MapLink" title="evennia.contrib.xyzgrid.xymap_legend.MapLink"><span class="xref myst py py-class">MapLink</span></a>
class (see class doc for hook methods):</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">symbol</span></code> (str) - The character to parse from the map into this node. This must
@ -551,6 +559,7 @@ custom directions outside of the cardinal directions + up/down. The exits key
<span class="n">LEGEND</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">&#39;#&#39;</span><span class="p">:</span> <span class="n">RedMapNode</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
@ -710,17 +719,17 @@ same-symbol teleporter on the same map.
can connect to the node from any of the 8 cardinal directions, but since nodes
must <em>only</em> exist on full coordinates, they can never appear directly next to
each other.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>\<span class="o">|/</span>
<span class="o">-</span><span class="c1">#-</span>
<span class="o">/|</span>\
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>\|/
-#-
/|\
<span class="c1">## invalid!</span>
## invalid!
</pre></div>
</div>
<p>All links or link-chains <em>must</em> end in nodes on both sides.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-----#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-#-----#
<span class="c1">#-#----- invalid!</span>
#-#----- invalid!
</pre></div>
</div>
</section>
@ -728,8 +737,8 @@ each other.</p>
<h4>One-way links<a class="headerlink" href="#one-way-links" title="Permalink to this headline"></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">&gt;</span></code>,<code class="docutils literal notranslate"><span class="pre">&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">v</span></code>, <code class="docutils literal notranslate"><span class="pre">^</span></code> are used to indicate one-way links. These indicators should
either be <em>first</em> or <em>last</em> in a link chain (think of them as arrows):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-----&gt;#</span>
<span class="c1">#&gt;-----#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-----&gt;#
#&gt;-----#
</pre></div>
</div>
<p>These two are equivalent, but the first one is arguably easier to read. It is also
@ -751,32 +760,32 @@ connect (unlike e.g. <code class="docutils literal notranslate"><span class="pre
directions are visually clear. For example, multiple links cannot connect to the
up-down links (itd be unclear which leads where) and if adjacent to a node, the
link will prioritize connecting to the node. Here are some examples:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="c1">#</span>
<span class="n">u</span> <span class="o">-</span> <span class="n">moving</span> <span class="n">up</span> <span class="ow">in</span> <span class="n">BOTH</span> <span class="n">directions</span> <span class="n">will</span> <span class="n">bring</span> <span class="n">you</span> <span class="n">to</span> <span class="n">the</span> <span class="n">other</span> <span class="n">node</span> <span class="p">(</span><span class="n">two</span><span class="o">-</span><span class="n">way</span><span class="p">)</span>
<span class="c1">#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> #
u - moving up in BOTH directions will bring you to the other node (two-way)
#
<span class="c1">#</span>
<span class="o">|</span> <span class="o">-</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="n">up</span> <span class="kn">from</span> <span class="nn">the</span> <span class="n">lower</span> <span class="n">node</span> <span class="n">to</span> <span class="n">the</span> <span class="n">upper</span><span class="p">,</span> <span class="n">south</span> <span class="n">to</span> <span class="n">go</span> <span class="n">back</span>
<span class="n">u</span>
<span class="c1">#</span>
#
| - one-way up from the lower node to the upper, south to go back
u
#
<span class="c1">#</span>
<span class="o">^</span> <span class="o">-</span> <span class="n">true</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="n">up</span> <span class="n">movement</span><span class="p">,</span> <span class="n">combined</span> <span class="k">with</span> <span class="n">a</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="s1">&#39;n&#39;</span> <span class="n">link</span>
<span class="n">u</span>
<span class="c1">#</span>
#
^ - true one-way up movement, combined with a one-way &#39;n&#39; link
u
#
<span class="c1">#</span>
<span class="n">d</span> <span class="o">-</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="n">up</span><span class="p">,</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="n">down</span> <span class="n">again</span> <span class="p">(</span><span class="n">standard</span> <span class="n">up</span><span class="o">/</span><span class="n">down</span> <span class="n">behavior</span><span class="p">)</span>
<span class="n">u</span>
<span class="c1">#</span>
#
d - one-way up, one-way down again (standard up/down behavior)
u
#
<span class="c1">#u#</span>
<span class="n">u</span> <span class="o">-</span> <span class="n">invalid</span> <span class="n">since</span> <span class="n">top</span><span class="o">-</span><span class="n">left</span> <span class="n">node</span> <span class="n">has</span> <span class="n">two</span> <span class="s1">&#39;up&#39;</span> <span class="n">directions</span> <span class="n">to</span> <span class="n">go</span> <span class="n">to</span>
<span class="c1">#</span>
#u#
u - invalid since top-left node has two &#39;up&#39; directions to go to
#
<span class="c1"># |</span>
<span class="n">u</span><span class="c1"># or u- - invalid since the direction of u is unclear</span>
<span class="c1"># |</span>
# |
u# or u- - invalid since the direction of u is unclear
# |
</pre></div>
</div>
</section>
@ -785,7 +794,7 @@ link will prioritize connecting to the node. Here are some examples:</p>
<p>An interrupt-node (<code class="docutils literal notranslate"><span class="pre">I</span></code>, <code class="docutils literal notranslate"><span class="pre">InterruptMapNode</span></code>) is a node that acts like any other
node except it is considered a point of interest and the auto-walk of the
<code class="docutils literal notranslate"><span class="pre">goto</span></code> command will always stop auto-stepping at this location.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-I-#-#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-#-I-#-#
</pre></div>
</div>
<p>So if auto-walking from left to right, the auto-walk will correctly map a path
@ -805,7 +814,7 @@ correctly trace a path to the other side, the auto-stepper will never cross an
interrupting link - you have to do so manually. Similarly to up/down links,
the InterruptMapLink must be placed so that its direction is un-ambiguous (with
a priority of linking to nearby nodes).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-#i#-#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-#-#i#-#
</pre></div>
</div>
<p>When pathfinding from left to right, the pathfinder will find the end room just
@ -823,7 +832,7 @@ cross the threshold manually before they can continue.</p>
<p>Blockers (<code class="docutils literal notranslate"><span class="pre">b</span></code>, <code class="docutils literal notranslate"><span class="pre">BlockedMapLink</span></code>) indicates a route that the pathfinder should not use. The
pathfinder will treat it as impassable even though it will be spawned as a
normal exit in-game.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-#-#b#-#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-#-#b#-#
</pre></div>
</div>
<p>There is no way to auto-step from left to right because the pathfinder will
@ -841,11 +850,11 @@ such maps).</p>
<h4>Router-links<a class="headerlink" href="#router-links" title="Permalink to this headline"></a></h4>
<p>Routers (<code class="docutils literal notranslate"><span class="pre">o</span></code>, <code class="docutils literal notranslate"><span class="pre">RouterMapLink</span></code>) allow for connecting nodes with links at an
angle, by creating a knee.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#----o</span>
<span class="o">|</span> \
<span class="c1">#-#-# o</span>
<span class="o">|</span>
<span class="c1">#-o</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#----o
| \
#-#-# o
|
#-o
</pre></div>
</div>
<p>Above, you can move east between from the top-left room and the bottommost
@ -854,22 +863,22 @@ only be one step (one exit <code class="docutils literal notranslate"><span clas
<p>Routers can link connect multiple connections as long as there as as many
ingoing as there are outgoing links. If in doubt, the system will assume a
link will continue to the outgoing link on the opposite side of the router.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">/</span>
<span class="o">-</span><span class="n">o</span> <span class="o">-</span> <span class="n">this</span> <span class="ow">is</span> <span class="n">ok</span><span class="p">,</span> <span class="n">there</span> <span class="n">can</span> <span class="n">only</span> <span class="n">be</span> <span class="n">one</span> <span class="n">path</span><span class="p">,</span> <span class="n">w</span><span class="o">-</span><span class="n">ne</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> /
-o - this is ok, there can only be one path, w-ne
<span class="o">|</span>
<span class="o">-</span><span class="n">o</span><span class="o">-</span> <span class="o">-</span> <span class="n">equivalent</span> <span class="n">to</span> <span class="s1">&#39;+&#39;</span><span class="p">:</span> <span class="n">one</span> <span class="n">n</span><span class="o">-</span><span class="n">s</span> <span class="ow">and</span> <span class="n">one</span> <span class="n">w</span><span class="o">-</span><span class="n">e</span> <span class="n">link</span> <span class="n">crossing</span>
<span class="o">|</span>
|
-o- - equivalent to &#39;+&#39;: one n-s and one w-e link crossing
|
\<span class="o">|/</span>
<span class="o">-</span><span class="n">o</span><span class="o">-</span> <span class="o">-</span> <span class="nb">all</span> <span class="n">links</span> <span class="n">are</span> <span class="n">passing</span> <span class="n">straight</span> <span class="n">through</span>
<span class="o">/|</span>\
\|/
-o- - all links are passing straight through
/|\
<span class="o">-</span><span class="n">o</span><span class="o">-</span> <span class="o">-</span> <span class="n">w</span><span class="o">-</span><span class="n">e</span> <span class="n">link</span> <span class="k">pass</span> <span class="n">straight</span> <span class="n">through</span><span class="p">,</span> <span class="n">other</span> <span class="n">link</span> <span class="ow">is</span> <span class="n">sw</span><span class="o">-</span><span class="n">s</span>
<span class="o">/|</span>
-o- - w-e link pass straight through, other link is sw-s
/|
<span class="o">-</span><span class="n">o</span> <span class="o">-</span> <span class="n">invalid</span><span class="p">;</span> <span class="n">impossible</span> <span class="n">to</span> <span class="n">know</span> <span class="n">which</span> <span class="nb">input</span> <span class="n">goes</span> <span class="n">to</span> <span class="n">which</span> <span class="n">output</span>
<span class="o">/|</span>
-o - invalid; impossible to know which input goes to which output
/|
</pre></div>
</div>
</section>
@ -881,49 +890,26 @@ matching teleport link. The pair must both be on the same XYMap and both sides
must connect/chain to a node (like all links). Only a single link (or node) may
connect to the teleport link.</p>
<p>Pathfinding will also work correctly across the teleport.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-t t-#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-t t-#
</pre></div>
</div>
<p>Moving east from the leftmost node will have you appear at the rightmost node
and vice versa (think of the two <code class="docutils literal notranslate"><span class="pre">t</span></code> as thinking they are in the same location).</p>
<p>Teleportation movement is always two-way, but you can use one-way links to
create the effect of a one-way teleport:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-t t&gt;#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-t t&gt;#
</pre></div>
</div>
<p>In this example you can move east across the teleport, but not west since the
teleporter-link is hidden behind a one-way exit.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#-t# (invalid!)</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#-t# (invalid!)
</pre></div>
</div>
<p>The above is invalid since only one link/node may connect to the teleport at a
time.</p>
<p>You can have multiple teleports on the same map, by assigning each pair a
different (unused) unique symbol in your map legend:</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="c1"># in your map definition module</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in your map definition module</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.xyzgrid</span> <span class="kn">import</span> <span class="n">xymap_legend</span>
@ -947,8 +933,9 @@ different (unused) unique symbol in your map legend:</p>
<span class="s1">&#39;q&#39;</span><span class="p">:</span> <span class="n">xymap_legend</span><span class="o">.</span><span class="n">TeleportermapLink</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</section>
<section id="map-transition-nodes">
<h4>Map-Transition Nodes<a class="headerlink" href="#map-transition-nodes" title="Permalink to this headline"></a></h4>
@ -967,45 +954,7 @@ coordinate the player should end up in when going towards this node. This
must be customized in a child class for every transition.</p>
<p>If there are more than one transition, separate transition classes should be
added, with different map-legend symbols:</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></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in your map definition module (let&#39;s say this is mapB)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in your map definition module (let&#39;s say this is mapB)</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.xyzgrid</span> <span class="kn">import</span> <span class="n">xymap_legend</span>
@ -1044,15 +993,16 @@ added, with different map-legend symbols:</p>
<span class="s2">&quot;legend&quot;</span><span class="p">:</span> <span class="n">LEGEND</span>
<span class="c1"># ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Moving west from <code class="docutils literal notranslate"><span class="pre">(1,0)</span></code> will bring you to <code class="docutils literal notranslate"><span class="pre">(1,4)</span></code> of MapA, and moving east from
<code class="docutils literal notranslate"><span class="pre">(1,2)</span></code> will bring you to <code class="docutils literal notranslate"><span class="pre">(12,14)</span></code> on MapC (assuming those maps exist).</p>
<p>A map transition is always one-way, and can lead to the coordinates of <em>any</em>
existing node on the other map:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">map1</span> <span class="n">map2</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>map1 map2
<span class="c1">#-T #-#---#-#-#-#</span>
#-T #-#---#-#-#-#
</pre></div>
</div>
<p>A player moving east towards <code class="docutils literal notranslate"><span class="pre">T</span></code> could for example end up at the 4th <code class="docutils literal notranslate"><span class="pre">#</span></code> from
@ -1060,9 +1010,9 @@ the left on map2 if so desired (even though it doesnt make sense visually).
There is no way to get back to map1 from there.</p>
<p>To create the effect of a two-way transition, one can set up a mirrored
transition-node on the other map:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">citymap</span> <span class="n">dungeonmap</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>citymap dungeonmap
<span class="c1">#-T T-#</span>
#-T T-#
</pre></div>
</div>
<p>The transition-node of each map above has <code class="docutils literal notranslate"><span class="pre">target_map_xyz</span></code> pointing to the
@ -1074,11 +1024,11 @@ across the map boundary.</p>
</section>
<section id="prototypes">
<h3>Prototypes<a class="headerlink" href="#prototypes" title="Permalink to this headline"></a></h3>
<p><a class="reference internal" href="../Components/Prototypes.html"><span class="doc">Prototypes</span></a> are dicts that describe how to <em>spawn</em> a new instance
<p><a class="reference internal" href="../Components/Prototypes.html"><span class="doc std std-doc">Prototypes</span></a> are dicts that describe how to <em>spawn</em> a new instance
of an object. Each of the <em>nodes</em> and <em>links</em> above have a default prototype
that allows the <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">xyzgrid</span> <span class="pre">spawn</span></code> command to convert them to
a <a class="reference external" href="../api/evennia.contrib.xyzgrid.xyzroom.html#XYZRoom">XYZRoom</a>
or an <a class="reference external" href="../api/evennia.contrib.xyzgrid.xyzroom.html#XYZExit">XYZExit</a> respectively.</p>
a <a class="reference internal" href="../api/evennia.contrib.xyzgrid.xyzroom.html#evennia.contrib.xyzgrid.xyzroom.XYZRoom" title="evennia.contrib.xyzgrid.xyzroom.XYZRoom"><span class="xref myst py py-class">XYZRoom</span></a>
or an <a class="reference internal" href="../api/evennia.contrib.xyzgrid.xyzroom.html#evennia.contrib.xyzgrid.xyzroom.XYZRoom" title="evennia.contrib.xyzgrid.xyzroom.XYZRoom"><span class="xref myst py py-class">XYZExit</span></a> respectively.</p>
<p>The default prototypes are found in <code class="docutils literal notranslate"><span class="pre">evennia.contrib.xyzgrid.prototypes</span></code> (added
during installation of this contrib), with <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code>s <code class="docutils literal notranslate"><span class="pre">&quot;xyz_room&quot;</span></code> and
<code class="docutils literal notranslate"><span class="pre">&quot;xyz_exit&quot;</span></code> - use these as <code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code> to add your own custom prototypes.</p>
@ -1087,58 +1037,11 @@ prototype is used for each coordinate in your XYMap. The coordinate is given as
<code class="docutils literal notranslate"><span class="pre">(X,</span> <span class="pre">Y)</span></code> for nodes/rooms and <code class="docutils literal notranslate"><span class="pre">(X,</span> <span class="pre">Y,</span> <span class="pre">direction)</span></code> for links/exits, where the
direction is one of “n”, “ne”, “e”, “se”, “s”, “sw”, “w”, “nw”, “u” or “d”. For
exits, its recommended to <em>not</em> set a <code class="docutils literal notranslate"><span class="pre">key</span></code> since this is generated
automatically by the grid spawner to be as expected (north” with alias “n”, for
automatically by the grid spawner to be as expected (north” with alias “n”, for
example).</p>
<p>A special coordinate is <code class="docutils literal notranslate"><span class="pre">*</span></code>. This acts as a wild card for that coordinate and
allows you to add default prototypes to be used for rooms.</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></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="n">MAPSTR</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2">+ 0 1</span>
@ -1186,8 +1089,9 @@ allows you to add default prototypes to be used for rooms.</p>
<span class="s2">&quot;prototypes&quot;</span><span class="p">:</span> <span class="n">PROTOTYPES</span>
<span class="c1"># ...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>When spawning the above map, the room at the bottom-left and top-right of the
map will get custom descriptions and names, while the others will have default
values. One exit (the east exit out of the room in the bottom-left will have a
@ -1208,8 +1112,8 @@ picked up and applied to the existing objects.</p>
should be included as <code class="docutils literal notranslate"><span class="pre">prototype_parents</span></code> for prototypes on the map. Would it
not be nice to be able to change these and have the change apply to all of the
grid? You can, by adding the following to your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">XYZROOM_PROTOTYPE_OVERRIDE</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;typeclass&quot;</span><span class="p">:</span> <span class="s2">&quot;myxyzroom.MyXYZRoom&quot;</span><span class="p">}</span>
<span class="n">XYZEXIT_PROTOTYPE_OVERRIDE</span> <span class="o">=</span> <span class="p">{</span><span class="o">...</span><span class="p">}</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>XYZROOM_PROTOTYPE_OVERRIDE = {&quot;typeclass&quot;: &quot;myxyzroom.MyXYZRoom&quot;}
XYZEXIT_PROTOTYPE_OVERRIDE = {...}
</pre></div>
</div>
<blockquote>
@ -1234,6 +1138,7 @@ after a change like this.</p>
<span class="s2">&quot;map_visual_range&quot;</span><span class="p">:</span> <span class="mi">2</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">options</span></code> dict is passed as <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> to <code class="docutils literal notranslate"><span class="pre">XYZRoom.return_appearance</span></code>
@ -1250,6 +1155,7 @@ could of course also override <code class="docutils literal notranslate"><span c
<span class="n">Dungeon</span> <span class="n">Entrance</span>
<span class="n">To</span> <span class="n">the</span> <span class="n">east</span><span class="p">,</span> <span class="n">a</span> <span class="n">narrow</span> <span class="n">opening</span> <span class="n">leads</span> <span class="n">into</span> <span class="n">darkness</span><span class="o">.</span>
<span class="n">Exits</span><span class="p">:</span> <span class="n">northeast</span> <span class="ow">and</span> <span class="n">east</span>
</pre></div>
</div>
<ul>
@ -1264,24 +1170,24 @@ range is calculated.
In “node” mode, the range shows how many <em>nodes</em> away from that you can see. In “scan”
mode you can instead see that many <em>on-screen characters</em> away from your character.
To visualize, assume this is the full map (where &#64; is the character location):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#----------------#</span>
<span class="o">|</span> <span class="o">|</span>
<span class="o">|</span> <span class="o">|</span>
<span class="c1"># @------------#-#</span>
<span class="o">|</span> <span class="o">|</span>
<span class="c1">#----------------#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#----------------#
| |
| |
# @------------#-#
| |
#----------------#
</pre></div>
</div>
<p>This is what the player will see in nodes mode with <code class="docutils literal notranslate"><span class="pre">map_visual_range=2</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">@------------</span><span class="c1">#-#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@------------#-#
</pre></div>
</div>
<p>… and in scan mode:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">|</span>
<span class="o">|</span>
<span class="c1"># @--</span>
<span class="o">|</span>
<span class="c1">#----</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>|
|
# @--
|
#----
</pre></div>
</div>
<p>The nodes mode has the advantage of showing only connected links and is
@ -1290,11 +1196,11 @@ visually far away from you. The scan mode can accidentally reveal unconnec
parts of the map (see example above), but limiting the range can be used as a
way to hide information.</p>
<p>This is what the player will see in nodes mode with <code class="docutils literal notranslate"><span class="pre">map_visual_range=1</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">@------------</span><span class="c1">#</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@------------#
</pre></div>
</div>
<p>… and in scan mode:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">@-</span>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@-
</pre></div>
</div>
<p>One could for example use nodes for outdoor/town maps and scan for
@ -1353,12 +1259,12 @@ This behavior can be changed per-link by using links with
</section>
<section id="xyzgrid">
<h2>XYZGrid<a class="headerlink" href="#xyzgrid" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> is a <a class="reference internal" href="../Components/Scripts.html"><span class="doc">Global Script</span></a> that holds all <code class="docutils literal notranslate"><span class="pre">XYMap</span></code> objects on
<p>The <code class="docutils literal notranslate"><span class="pre">XYZGrid</span></code> is a <a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Global Script</span></a> that holds all <code class="docutils literal notranslate"><span class="pre">XYMap</span></code> objects on
the grid. There should be only one XYZGrid created at any time.</p>
<p>To access the grid in-code, there are several ways:</p>
<ul>
<li><p>You can search for the grid like any other Script. Its named “XYZGrid”.</p>
<p>grid = evennia.search_script(XYZGrid”)[0]</p>
<p>grid = evennia.search_script(XYZGrid”)[0]</p>
<p>(<code class="docutils literal notranslate"><span class="pre">search_script</span></code> always returns a list)</p>
</li>
<li><p>You can get it with <code class="docutils literal notranslate"><span class="pre">evennia.contrib.xyzgrid.xyzgrid.get_xyzgrid</span></code></p>
@ -1399,24 +1305,27 @@ know how to call find the pathfinder though:</p>
<li><p><code class="docutils literal notranslate"><span class="pre">xymap.get_shortest_path(start_xy,</span> <span class="pre">end_xy)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xymap.get_visual_range(xy,</span> <span class="pre">dist=2,</span> <span class="pre">**kwargs)</span></code></p></li>
</ul>
<p>See the <a class="reference external" href="../api/evennia.contrib.xyzgrid.xymap.html#XYMap">XYMap</a> documentation for
<p>See the <a class="reference internal" href="../api/evennia.contrib.xyzgrid.commands.html#evennia.contrib.xyzgrid.commands.PathData.xymap" title="evennia.contrib.xyzgrid.commands.PathData.xymap"><span class="xref myst py py-attr">XYMap</span></a> documentation for
details.</p>
</section>
<section id="xyzroom-and-xyzexit">
<h2>XYZRoom and XYZExit<a class="headerlink" href="#xyzroom-and-xyzexit" title="Permalink to this headline"></a></h2>
<p>These are new custom <a class="reference internal" href="../Components/Typeclasses.html"><span class="doc">Typeclasses</span></a> located in
<p>These are new custom <a class="reference internal" href="../Components/Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a> located in
<code class="docutils literal notranslate"><span class="pre">evennia.contrib.xyzgrid.xyzroom</span></code>. They extend the base <code class="docutils literal notranslate"><span class="pre">DefaultRoom</span></code> and
<code class="docutils literal notranslate"><span class="pre">DefaultExit</span></code> to be aware of their <code class="docutils literal notranslate"><span class="pre">X</span></code>, <code class="docutils literal notranslate"><span class="pre">Y</span></code> and <code class="docutils literal notranslate"><span class="pre">Z</span></code> coordinates.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>You should usually <strong>not</strong> create XYZRooms/Exits manually. They are intended
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You should usually **not** create XYZRooms/Exits manually. They are intended
to be created/deleted based on the layout of the grid. So to add a new room, add
a new node to your map. To delete it, you remove it. Then rerun
<strong>evennia xyzgrid spawn</strong>. Having manually created XYZRooms/exits in the mix
can lead to them getting deleted or the system getting confused.</p>
<p>If you <strong>still</strong> want to create XYZRoom/Exits manually (dont say we didnt
warn you!), you should do it with their <cite>XYZRoom.create()</cite> and
<cite>XYZExit.create()</cite> methods. This makes sure the XYZ they use are unique.</p>
**evennia xyzgrid spawn**. Having manually created XYZRooms/exits in the mix
can lead to them getting deleted or the system getting confused.
If you **still** want to create XYZRoom/Exits manually (don&#39;t say we didn&#39;t
warn you!), you should do it with their `XYZRoom.create()` and
`XYZExit.create()` methods. This makes sure the XYZ they use are unique.
</pre></div>
</div>
</div>
<p>Useful (extra) properties on <code class="docutils literal notranslate"><span class="pre">XYZRoom</span></code>, <code class="docutils literal notranslate"><span class="pre">XYZExit</span></code>:</p>
<ul class="simple">
@ -1431,37 +1340,14 @@ map display in depth.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xyz_destination</span></code> (only for <code class="docutils literal notranslate"><span class="pre">XYZExits</span></code>) - this gives the xyz-coordinate of
the exits destination.</p></li>
</ul>
<p>The coordinates are stored as <a class="reference internal" href="../Components/Tags.html"><span class="doc">Tags</span></a> where both rooms and exits tag
<p>The coordinates are stored as <a class="reference internal" href="../Components/Tags.html"><span class="doc std std-doc">Tags</span></a> where both rooms and exits tag
categories <code class="docutils literal notranslate"><span class="pre">room_x_coordinate</span></code>, <code class="docutils literal notranslate"><span class="pre">room_y_coordinate</span></code> and <code class="docutils literal notranslate"><span class="pre">room_z_coordinate</span></code>
while exits use the same in addition to tags for their destination, with tag
categories <code class="docutils literal notranslate"><span class="pre">exit_dest_x_coordinate</span></code>, <code class="docutils literal notranslate"><span class="pre">exit_dest_y_coordinate</span></code> and
<code class="docutils literal notranslate"><span class="pre">exit_dest_z_coordinate</span></code>.</p>
<p>The make it easier to query the database by coordinates, each typeclass offers
custom manager methods. The filter methods allow for <code class="docutils literal notranslate"><span class="pre">'*'</span></code> as a wildcard.</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>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="c1"># find a list of all rooms in map foo</span>
<span class="n">rooms</span> <span class="o">=</span> <span class="n">XYZRoom</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter_xyz</span><span class="p">((</span><span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span><span class="p">))</span>
@ -1485,12 +1371,13 @@ custom manager methods. The filter methods allow for <code class="docutils liter
<span class="c1"># find exactly one exit to specific destination (no wildcards allowed)</span>
<span class="n">exit</span> <span class="o">=</span> <span class="n">XYZExit</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_xyz_exit</span><span class="p">(</span><span class="n">xyz</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span><span class="p">),</span> <span class="n">xyz_destination</span><span class="o">=</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span><span class="p">))</span>
</pre></div>
</td></tr></table></div>
</div>
<p>You can customize the XYZRoom/Exit by having the grid spawn your own subclasses
of them. To do this you need to override the prototype used to spawn rooms on
the grid. Easiest is to modify the base prototype-parents in settings (see the
<a class="reference external" href="#extending-the-base-prototypes">Extending the base prototypes</a> section above).</p>
<a class="reference internal" href="#xyzroom-and-xyzexit"><span class="std std-doc">XYZRoom and XYZExit</span></a> section above).</p>
</section>
<section id="working-with-the-grid">
<h2>Working with the grid<a class="headerlink" href="#working-with-the-grid" title="Permalink to this headline"></a></h2>
@ -1602,7 +1489,7 @@ apply the changes.</p></li>
<h3>Versions</h3>
<ul>
<li><a href="XYZGrid.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>