Updated HTML docs.

This commit is contained in:
Evennia docbuilder action 2023-08-06 15:58:16 +00:00
parent 255d6104b6
commit f727c54710
45 changed files with 371 additions and 816 deletions

View file

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 3a92a0cec4eec4980006257e6fc6febf
config: 5615d088121acbee6ea5c09af16b49f9
tags: 645f666f9bcd5a90fca523b33c5a78b7

View file

@ -185,7 +185,10 @@
<h2>Evennia main branch<a class="headerlink" href="#evennia-main-branch" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Contrib: Large-language-model (LLM) AI integration; allows NPCs to talk using
responses from a neural network server.</p></li>
responses from an LLM server.</p></li>
<li><p>Fix: Make sure <code class="docutils literal notranslate"><span class="pre">at_server_reload</span></code> is called also on non-repeating Scripts.</p></li>
<li><p>Fix: Webclient was not giving a proper error when sending an unknown outputfunc to it.</p></li>
<li><p>Documentation fixes.</p></li>
</ul>
</section>
<section id="evennia-2-1-0">

View file

@ -184,7 +184,7 @@ a small but full game with Evennia. Other tutorials and how-tos tend
<li class="toctree-l1"><a class="reference internal" href="Web-Add-a-wiki.html">Add a wiki on your website</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Character-Generation.html">Web Character Generation</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Character-View-Tutorial.html">Web Character View Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Help-System-Tutorial.html">Help System Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Help-System-Tutorial.html">Web Help System Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Extending-the-REST-API.html">Extending the REST API</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-Tweeting-Game-Stats.html">Automatically Tweet game stats</a></li>
</ul>

View file

@ -152,21 +152,9 @@
<h1>Web Character Generation<a class="headerlink" href="#web-character-generation" 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 will create a simple web-based interface for generating a new in-game Character.
Accounts will need to have first logged into the website (with their <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> account). Once
finishing character generation the Character will be created immediately and the Accounts can then
log into the game and play immediately (the Character will not require staff approval or anything
like that). This guide does not go over how to create an AccountDB on the website with the right
permissions to transfer to their web-created characters.</p>
<p>It is probably most useful to set <code class="docutils literal notranslate"><span class="pre">AUTO_CREATE_CHARACTER_WITH_ACCOUNT</span> <span class="pre">=</span> <span class="pre">False</span></code> so that all player
characters can be created through this.</p>
<p>You should have some familiarity with how Django sets up its Model Template View framework. You need
to understand what is happening in the basic <a class="reference internal" href="Web-Character-View-Tutorial.html"><span class="doc std std-doc">Web Character View tutorial</span></a>.
If you dont understand the listed tutorial or have a grasp of Django basics, please look at the
<a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/">Django tutorial</a> to get a taste of what Django does,
before throwing Evennia into the mix (Evennia shares its API and attributes with the website
interface). This guide will outline the format of the models, views, urls, and html templates
needed.</p>
<p>This tutorial will create a simple web-based interface for generating a new in-game Character. Accounts will need to have first logged into the website (with their <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> account). Once finishing character generation the Character will be created immediately and the Accounts can then log into the game and play immediately (the Character will not require staff approval or anything like that). This guide does not go over how to create an AccountDB on the website with the right permissions to transfer to their web-created characters.</p>
<p>It is probably most useful to set <code class="docutils literal notranslate"><span class="pre">AUTO_CREATE_CHARACTER_WITH_ACCOUNT</span> <span class="pre">=</span> <span class="pre">False</span></code> so that all player characters can be created through this.</p>
<p>You should have some familiarity with how Django sets up its Model Template View framework. You need to understand what is happening in the basic <a class="reference internal" href="Web-Character-View-Tutorial.html"><span class="doc std std-doc">Web Character View tutorial</span></a>. If you dont understand the listed tutorial or have a grasp of Django basics, please look at the <a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/">Django tutorial</a> to get a taste of what Django does, before throwing Evennia into the mix (Evennia shares its API and attributes with the website interface). This guide will outline the format of the models, views, urls, and html templates needed.</p>
</section>
<section id="pictures">
<h2>Pictures<a class="headerlink" href="#pictures" title="Permalink to this headline"></a></h2>
@ -175,18 +163,15 @@ needed.</p>
<hr class="docutils" />
<p><img alt="Index page, with no character application yet done." src="https://lh3.googleusercontent.com/-57KuSWHXQ_M/VWcULN152tI/AAAAAAAAEZg/kINTmVlHf6M/w425-h189-no/webchargen_index2.gif" /></p>
<hr class="docutils" />
<p>Having clicked the “create” link you get to create your character (here we will only have name and
background, you can add whatever is needed to fit your game):</p>
<p>Having clicked the “create” link you get to create your character (here we will only have name and background, you can add whatever is needed to fit your game):</p>
<hr class="docutils" />
<p><img alt="Character creation." src="https://lh3.googleusercontent.com/-ORiOEM2R_yQ/VWcUKgy84rI/AAAAAAAAEZY/B3CBh3FHii4/w607-h60-no/webchargen_creation.gif" /></p>
<hr class="docutils" />
<p>Back to the index page. Having entered our character application (we called our character “TestApp”)
you see it listed:</p>
<p>Back to the index page. Having entered our character application (we called our character “TestApp”) you see it listed:</p>
<hr class="docutils" />
<p><img alt="Having entered an application." src="https://lh6.googleusercontent.com/-HlxvkvAimj4/VWcUKjFxEiI/AAAAAAAAEZo/gLppebr05JI/w321-h194-no/webchargen_index1.gif" /></p>
<hr class="docutils" />
<p>We can also view an already written character application by clicking on it - this brings us to the
<em>detail</em> page:</p>
<p>We can also view an already written character application by clicking on it - this brings us to the <em>detail</em> page:</p>
<hr class="docutils" />
<p><img alt="Detail view of character application." src="https://lh6.googleusercontent.com/-2m1UhSE7s_k/VWcUKfLRfII/AAAAAAAAEZc/UFmBOqVya4k/w267-h175-no/webchargen_detail.gif" /></p>
</section>
@ -194,21 +179,17 @@ you see it listed:</p>
<section id="installing-an-app">
<h2>Installing an App<a class="headerlink" href="#installing-an-app" title="Permalink to this headline"></a></h2>
<p>Assuming your game is named “mygame”, navigate to your <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> directory, and type:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia startapp chargen
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cd web
evennia startapp chargen
</pre></div>
</div>
<p>This will initialize a new Django app we choose to call “chargen”. It is directory containing some
basic starting things Django needs. You will need to move this directory: for the time being, it is
in your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> directory. Better to move it in your <code class="docutils literal notranslate"><span class="pre">mygame/web</span></code> directory, so you have
<code class="docutils literal notranslate"><span class="pre">mygame/web/chargen</span></code> in the end.</p>
<p>Next, navigate to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> and add or edit the following line to make
Evennia (and Django) aware of our new app:</p>
<p>This will initialize a new Django app we choose to call “chargen” in <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code>. We put it under <code class="docutils literal notranslate"><span class="pre">web/</span></code> to keep all web stuff together, but you can organize however you like. It is directory containing some basic starting things Django needs.</p>
<p>Next, navigate to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> and add or edit the following line to make Evennia (and Django) aware of our new app:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>INSTALLED_APPS += (&#39;web.chargen&#39;,)
</pre></div>
</div>
<p>After this, we will get into defining our <em>models</em> (the description of the database storage),
<em>views</em> (the server-side website content generators), <em>urls</em> (how the web browser finds the pages)
and <em>templates</em> (how the web page should be structured).</p>
<em>views</em> (the server-side website content generators), <em>urls</em> (how the web browser finds the pages) and <em>templates</em> (how the web page should be structured).</p>
<section id="installing-checkpoint">
<h3>Installing - Checkpoint:<a class="headerlink" href="#installing-checkpoint" title="Permalink to this headline"></a></h3>
<ul class="simple">
@ -221,10 +202,8 @@ and <em>templates</em> (how the web page should be structured).</p>
<h2>Create Models<a class="headerlink" href="#create-models" title="Permalink to this headline"></a></h2>
<p>Models are created in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/models.py</span></code>.</p>
<p>A <a class="reference internal" href="../Concepts/Models.html"><span class="doc std std-doc">Django database model</span></a> is a Python class that describes the database storage of the
data you want to manage. Any data you choose to store is stored in the same database as the game and
you have access to all the games objects here.</p>
<p>We need to define what a character application actually is. This will differ from game to game so
for this tutorial we will define a simple character sheet with the following database fields:</p>
data you want to manage. Any data you choose to store is stored in the same database as the game and you have access to all the games objects here.</p>
<p>We need to define what a character application actually is. This will differ from game to game so for this tutorial we will define a simple character sheet with the following database fields:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">app_id</span></code> (AutoField): Primary key for this character application sheet.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">char_name</span></code> (CharField): The new characters name.</p></li>
@ -235,8 +214,7 @@ AccountID from the AccountDB object.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">submitted</span></code> (BooleanField): <code class="docutils literal notranslate"><span class="pre">True</span></code>/<code class="docutils literal notranslate"><span class="pre">False</span></code> depending on if the application has been submitted yet.</p></li>
</ul>
<blockquote>
<div><p>Note: In a full-fledged game, youd likely want them to be able to select races, skills,
attributes and so on.</p>
<div><p>Note: In a full-fledged game, youd likely want them to be able to select races, skills, attributes and so on.</p>
</div></blockquote>
<p>Our <code class="docutils literal notranslate"><span class="pre">models.py</span></code> file should look something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/chargen/models.py</span>
@ -252,30 +230,22 @@ attributes and so on.</p>
<span class="n">submitted</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">BooleanField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
<p>You should consider how you are going to link your application to your account. For this tutorial,
we are using the account_id attribute on our character application model in order to keep track of
which characters are owned by which accounts. Since the account id is a primary key in Evennia, it
is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use
anything else, but for the purposes of this guide, we are going to use account ID to join the
character applications with the proper account.</p>
<p>You should consider how you are going to link your application to your account. For this tutorial, we are using the account_id attribute on our character application model in order to keep track of which characters are owned by which accounts. Since the account id is a primary key in Evennia, it is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use anything else, but for the purposes of this guide, we are going to use account ID to join the character applications with the proper account.</p>
<section id="model-checkpoint">
<h3>Model - Checkpoint:<a class="headerlink" href="#model-checkpoint" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>you should have filled out <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/models.py</span></code> with the model class shown above
(eventually adding fields matching what you need for your game).</p></li>
<li><p>you should have filled out <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/models.py</span></code> with the model class shown above (eventually adding fields matching what you need for your game).</p></li>
</ul>
</section>
</section>
<section id="create-views">
<h2>Create Views<a class="headerlink" href="#create-views" title="Permalink to this headline"></a></h2>
<p><em>Views</em> are server-side constructs that make dynamic data available to a web page. We are going to
add them to <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen.views.py</span></code>. Each view in our example represents the backbone of a
<p><em>Views</em> are server-side constructs that make dynamic data available to a web page. We are going to add them to <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen.views.py</span></code>. Each view in our example represents the backbone of a
specific web page. We will use three views and three pages here:</p>
<ul class="simple">
<li><p>The index (managing <code class="docutils literal notranslate"><span class="pre">index.html</span></code>). This is what you see when you navigate to
<code class="docutils literal notranslate"><span class="pre">http://yoursite.com/chargen</span></code>.</p></li>
<li><p>The detail display sheet (manages <code class="docutils literal notranslate"><span class="pre">detail.html</span></code>). A page that passively displays the stats of a
given Character.</p></li>
<li><p>The detail display sheet (manages <code class="docutils literal notranslate"><span class="pre">detail.html</span></code>). A page that passively displays the stats of a given Character.</p></li>
<li><p>Character creation sheet (manages <code class="docutils literal notranslate"><span class="pre">create.html</span></code>). This is the main form with fields to fill in.</p></li>
</ul>
<section id="index-view">
@ -299,14 +269,12 @@ given Character.</p></li>
</section>
<section id="detail-view">
<h3><em>Detail</em> view<a class="headerlink" href="#detail-view" title="Permalink to this headline"></a></h3>
<p>Our detail page will have pertinent character application information our users can see. Since this
is a basic demonstration, our detail page will only show two fields:</p>
<p>Our detail page will have pertinent character application information our users can see. Since this is a basic demonstration, our detail page will only show two fields:</p>
<ul class="simple">
<li><p>Character name</p></li>
<li><p>Character background</p></li>
</ul>
<p>We will use the account ID again just to double-check that whoever tries to check our character page
is actually the account who owns the application.</p>
<p>We will use the account ID again just to double-check that whoever tries to check our character page is actually the account who owns the application.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen.views.py</span>
<span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">app_id</span><span class="p">):</span>
@ -324,11 +292,8 @@ is actually the account who owns the application.</p>
</section>
<section id="creating-view">
<h2><em>Creating</em> view<a class="headerlink" href="#creating-view" title="Permalink to this headline"></a></h2>
<p>Predictably, our <em>create</em> function will be the most complicated of the views, as it needs to accept
information from the user, validate the information, and send the information to the server. Once
the form content is validated will actually create a playable Character.</p>
<p>The form itself we will define first. In our simple example we are just looking for the Characters
name and background. This form we create in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/forms.py</span></code>:</p>
<p>Predictably, our <em>create</em> function will be the most complicated of the views, as it needs to accept information from the user, validate the information, and send the information to the server. Once the form content is validated will actually create a playable Character.</p>
<p>The form itself we will define first. In our simple example we are just looking for the Characters name and background. This form we create in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/forms.py</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/forms.py</span>
<span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
@ -390,10 +355,7 @@ name and background. This form we create in <code class="docutils literal notran
</pre></div>
</div>
<blockquote>
<div><p>Note also that we basically create the character using the Evennia API, and we grab the proper
permissions from the <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> object and copy them to the character object. We take the user
permissions attribute and turn that list of strings into a string object in order for the
create_object function to properly process the permissions.</p>
<div><p>Note also that we basically create the character using the Evennia API, and we grab the proper permissions from the <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> object and copy them to the character object. We take the user permissions attribute and turn that list of strings into a string object in order for the create_object function to properly process the permissions.</p>
</div></blockquote>
<p>Most importantly, the following attributes must be set on the created character object:</p>
<ul class="simple">
@ -403,10 +365,7 @@ create_object function to properly process the permissions.</p>
<li><p>Character name (key)</p></li>
<li><p>The Characters home room location (<code class="docutils literal notranslate"><span class="pre">#2</span></code> by default)</p></li>
</ul>
<p>Other attributes are strictly speaking optional, such as the <code class="docutils literal notranslate"><span class="pre">background</span></code> attribute on our
character. It may be a good idea to decompose this function and create a separate _create_character
function in order to set up your character object the account owns. But with the Evennia API,
setting custom attributes is as easy as doing it in the meat of your Evennia game directory.</p>
<p>Other attributes are strictly speaking optional, such as the <code class="docutils literal notranslate"><span class="pre">background</span></code> attribute on our character. It may be a good idea to decompose this function and create a separate _create_character function in order to set up your character object the account owns. But with the Evennia API, setting custom attributes is as easy as doing it in the meat of your Evennia game directory.</p>
<p>After all of this, our <code class="docutils literal notranslate"><span class="pre">views.py</span></code> file should look like something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/views.py</span>
@ -481,16 +440,14 @@ setting custom attributes is as easy as doing it in the meat of your Evennia gam
<h3>Create Views - Checkpoint:<a class="headerlink" href="#create-views-checkpoint" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>youve defined a <code class="docutils literal notranslate"><span class="pre">views.py</span></code> that has an index, detail, and creating functions.</p></li>
<li><p>youve defined a <a class="reference external" href="http://forms.py">forms.py</a> with the <code class="docutils literal notranslate"><span class="pre">AppForm</span></code> class needed by the <code class="docutils literal notranslate"><span class="pre">creating</span></code> function of
<code class="docutils literal notranslate"><span class="pre">views.py</span></code>.</p></li>
<li><p>youve defined a <a class="reference external" href="http://forms.py">forms.py</a> with the <code class="docutils literal notranslate"><span class="pre">AppForm</span></code> class needed by the <code class="docutils literal notranslate"><span class="pre">creating</span></code> function of <code class="docutils literal notranslate"><span class="pre">views.py</span></code>.</p></li>
<li><p>your <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen</span></code> directory should now have a <code class="docutils literal notranslate"><span class="pre">views.py</span></code> and <code class="docutils literal notranslate"><span class="pre">forms.py</span></code> file</p></li>
</ul>
</section>
</section>
<section id="create-urls">
<h2>Create URLs<a class="headerlink" href="#create-urls" title="Permalink to this headline"></a></h2>
<p>URL patterns helps redirect requests from the web browser to the right views. These patterns are
created in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/urls.py</span></code>.</p>
<p>URL patterns helps redirect requests from the web browser to the right views. These patterns are created in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/urls.py</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/urls.py</span>
<span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>
@ -506,12 +463,8 @@ created in <code class="docutils literal notranslate"><span class="pre">mygame/w
<span class="p">]</span>
</pre></div>
</div>
<p>You could change the format as you desire. To make it more secure, you could remove app_id from the
“detail” url, and instead just fetch the accounts applications using a unifying field like
account_id to find all the character application objects to display.</p>
<p>To add this to our website, we must also update the main <code class="docutils literal notranslate"><span class="pre">mygame/website/urls.py</span></code> file; this
will help tying our new chargen app in with the rest of the website. <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> variable, and
change it to include:</p>
<p>You could change the format as you desire. To make it more secure, you could remove app_id from the “detail” url, and instead just fetch the accounts applications using a unifying field like account_id to find all the character application objects to display.</p>
<p>To add this to our website, we must also update the main <code class="docutils literal notranslate"><span class="pre">mygame/website/urls.py</span></code> file; this will help tying our new chargen app in with the rest of the website. <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> variable, and change it to include:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in file mygame/website/urls.py</span>
<span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span><span class="p">,</span> <span class="n">include</span>
@ -533,18 +486,12 @@ change it to include:</p>
</section>
<section id="html-templates">
<h2>HTML Templates<a class="headerlink" href="#html-templates" title="Permalink to this headline"></a></h2>
<p>So we have our url patterns, views, and models defined. Now we must define our HTML templates that
the actual user will see and interact with. For this tutorial we us the basic <em>prosimii</em> template
that comes with Evennia.</p>
<p>Take note that we use <code class="docutils literal notranslate"><span class="pre">user.is_authenticated</span></code> to make sure that the user cannot create a character
without logging in.</p>
<p>So we have our url patterns, views, and models defined. Now we must define our HTML templates that the actual user will see and interact with. For this tutorial we us the basic <em>prosimii</em> template that comes with Evennia.</p>
<p>Take note that we use <code class="docutils literal notranslate"><span class="pre">user.is_authenticated</span></code> to make sure that the user cannot create a character without logging in.</p>
<p>These files will all go into the <code class="docutils literal notranslate"><span class="pre">/mygame/web/chargen/templates/chargen/</span></code> directory.</p>
<section id="index-html">
<h3>index.html<a class="headerlink" href="#index-html" title="Permalink to this headline"></a></h3>
<p>This HTML template should hold a list of all the applications the account currently has active. For
this demonstration, we will only list the applications that the account has submitted. You could
easily adjust this to include saved applications, or other types of applications if you have
different kinds.</p>
<p>This HTML template should hold a list of all the applications the account currently has active. For this demonstration, we will only list the applications that the account has submitted. You could easily adjust this to include saved applications, or other types of applications if you have different kinds.</p>
<p>Please refer back to <code class="docutils literal notranslate"><span class="pre">views.py</span></code> to see where we define the variables these templates make use of.</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="cm">&lt;!-- file mygame/web/chargen/templates/chargen/index.html--&gt;</span>
@ -570,10 +517,7 @@ different kinds.</p>
</section>
<section id="detail-html">
<h3>detail.html<a class="headerlink" href="#detail-html" title="Permalink to this headline"></a></h3>
<p>This page should show a detailed character sheet of their application. This will only show their
name and character background. You will likely want to extend this to show many more fields for your
game. In a full-fledged character generation, you may want to extend the boolean attribute of
submitted to allow accounts to save character applications and submit them later.</p>
<p>This page should show a detailed character sheet of their application. This will only show their name and character background. You will likely want to extend this to show many more fields for your game. In a full-fledged character generation, you may want to extend the boolean attribute of submitted to allow accounts to save character applications and submit them later.</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="cm">&lt;!-- file mygame/web/chargen/templates/chargen/detail.html--&gt;</span>
{% extends &quot;base.html&quot; %}
@ -597,11 +541,7 @@ submitted to allow accounts to save character applications and submit them later
</section>
<section id="create-html">
<h3>create.html<a class="headerlink" href="#create-html" title="Permalink to this headline"></a></h3>
<p>Our create HTML template will use the Django form we defined back in <a class="reference external" href="http://views.py/forms.py">views.py/forms.py</a> to drive the
majority of the application process. There will be a form input for every field we defined in
<a class="reference external" href="http://forms.py">forms.py</a>, which is handy. We have used POST as our method because we are sending information to the
server that will update the database. As an alternative, GET would be much less secure. You can read
up on documentation elsewhere on the web for GET vs. POST.</p>
<p>Our create HTML template will use the Django form we defined back in <a class="reference external" href="http://views.py/forms.py">views.py/forms.py</a> to drive the majority of the application process. There will be a form input for every field we defined in <a class="reference external" href="http://forms.py">forms.py</a>, which is handy. We have used POST as our method because we are sending information to the server that will update the database. As an alternative, GET would be much less secure. You can read up on documentation elsewhere on the web for GET vs. POST.</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="cm">&lt;!-- file mygame/web/chargen/templates/chargen/create.html--&gt;</span>
{% extends &quot;base.html&quot; %}
@ -623,8 +563,7 @@ up on documentation elsewhere on the web for GET vs. POST.</p>
<section id="templates-checkpoint">
<h3>Templates - Checkpoint:<a class="headerlink" href="#templates-checkpoint" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>Create a <code class="docutils literal notranslate"><span class="pre">index.html</span></code>, <code class="docutils literal notranslate"><span class="pre">detail.html</span></code> and <code class="docutils literal notranslate"><span class="pre">create.html</span></code> template in your
<code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/templates/chargen</span></code> directory</p></li>
<li><p>Create a <code class="docutils literal notranslate"><span class="pre">index.html</span></code>, <code class="docutils literal notranslate"><span class="pre">detail.html</span></code> and <code class="docutils literal notranslate"><span class="pre">create.html</span></code> template in your <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/templates/chargen</span></code> directory</p></li>
</ul>
</section>
</section>
@ -645,45 +584,26 @@ mygame/web/chargen/templates/chargen/detail.html
evennia<span class="w"> </span>migrate
</pre></div>
</div>
<p>This will create and update the models. If you see any errors at this stage, read the traceback
carefully, it should be relatively easy to figure out where the error is.</p>
<p>Login to the website (you need to have previously registered an Player account with the game to do
this). Next you navigate to <code class="docutils literal notranslate"><span class="pre">http://yourwebsite.com/chargen</span></code> (if you are running locally this will
be something like <code class="docutils literal notranslate"><span class="pre">http://localhost:4001/chargen</span></code> and you will see your new app in action.</p>
<p>This should hopefully give you a good starting point in figuring out how youd like to approach your
own web generation. The main difficulties are in setting the appropriate settings on your newly
created character object. Thankfully, the Evennia API makes this easy.</p>
<p>This will create and update the models. If you see any errors at this stage, read the traceback carefully, it should be relatively easy to figure out where the error is.</p>
<p>Login to the website (you need to have previously registered an Player account with the game to do this). Next you navigate to <code class="docutils literal notranslate"><span class="pre">http://yourwebsite.com/chargen</span></code> (if you are running locally this will be something like <code class="docutils literal notranslate"><span class="pre">http://localhost:4001/chargen</span></code> and you will see your new app in action.</p>
<p>This should hopefully give you a good starting point in figuring out how youd like to approach your own web generation. The main difficulties are in setting the appropriate settings on your newly created character object. Thankfully, the Evennia API makes this easy.</p>
</section>
<section id="adding-a-no-capcha-recapcha-on-your-character-generation">
<h2>Adding a no CAPCHA reCAPCHA on your character generation<a class="headerlink" href="#adding-a-no-capcha-recapcha-on-your-character-generation" title="Permalink to this headline"></a></h2>
<p>As sad as it is, if your server is open to the web, bots might come to visit and take advantage of
your open form to create hundreds, thousands, millions of characters if you give them the
opportunity. This section shows you how to use the <a class="reference external" href="https://www.google.com/recaptcha/intro/invisible.html">No CAPCHA
reCAPCHA</a> designed by Google. Not only is it
easy to use, it is user-friendly… for humans. A simple checkbox to check, except if Google has
some suspicion, in which case you will have a more difficult test with an image and the usual text
inside. Its worth pointing out that, as long as Google doesnt suspect you of being a robot, this
is quite useful, not only for common users, but to screen-reader users, to which reading inside of
an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in
your website.</p>
<p>As sad as it is, if your server is open to the web, bots might come to visit and take advantage of your open form to create hundreds, thousands, millions of characters if you give them the opportunity. This section shows you how to use the <a class="reference external" href="https://www.google.com/recaptcha/intro/invisible.html">No CAPCHA
reCAPCHA</a> designed by Google. Not only is it easy to use, it is user-friendly… for humans. A simple checkbox to check, except if Google has some suspicion, in which case you will have a more difficult test with an image and the usual text inside. Its worth pointing out that, as long as Google doesnt suspect you of being a robot, this is quite useful, not only for common users, but to screen-reader users, to which reading inside of an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in your website.</p>
<section id="step-1-obtain-a-sitekey-and-secret-from-google">
<h3>Step 1: Obtain a SiteKey and secret from Google<a class="headerlink" href="#step-1-obtain-a-sitekey-and-secret-from-google" title="Permalink to this headline"></a></h3>
<p>The first thing is to ask Google for a way to safely authenticate your website to their service. To
do it, we need to create a site key and a secret. Go to
<a class="reference external" href="https://www.google.com/recaptcha/admin">https://www.google.com/recaptcha/admin</a> to create such a
site key. Its quite easy when you have a Google account.</p>
<p>When you have created your site key, save it safely. Also copy your secret key as well. You should
find both information on the web page. Both would contain a lot of letters and figures.</p>
<p>The first thing is to ask Google for a way to safely authenticate your website to their service. To do it, we need to create a site key and a secret. Go to <a class="reference external" href="https://www.google.com/recaptcha/admin">https://www.google.com/recaptcha/admin</a> to create such a site key. Its quite easy when you have a Google account.</p>
<p>When you have created your site key, save it safely. Also copy your secret key as well. You should find both information on the web page. Both would contain a lot of letters and figures.</p>
</section>
<section id="step-2-installing-and-configuring-the-dedicated-django-app">
<h3>Step 2: installing and configuring the dedicated Django app<a class="headerlink" href="#step-2-installing-and-configuring-the-dedicated-django-app" title="Permalink to this headline"></a></h3>
<p>Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to
install the dedicated Django app. Quite easy:</p>
<p>Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to install the dedicated Django app. Quite easy:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install django-nocaptcha-recaptcha
</pre></div>
</div>
<p>And add it to the installed apps in your settings. In your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>, you
might have something like this:</p>
<p>And add it to the installed apps in your settings. In your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>, you might have something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
<span class="n">INSTALLED_APPS</span> <span class="o">+=</span> <span class="p">(</span>
<span class="s1">&#39;web.chargen&#39;</span><span class="p">,</span>
@ -691,8 +611,7 @@ might have something like this:</p>
<span class="p">)</span>
</pre></div>
</div>
<p>Dont close the setting file just yet. We have to add in the site key and secret key. You can add
them below:</p>
<p>Dont close the setting file just yet. We have to add in the site key and secret key. You can add them below:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># NoReCAPCHA site key</span>
<span class="n">NORECAPTCHA_SITE_KEY</span> <span class="o">=</span> <span class="s2">&quot;PASTE YOUR SITE KEY HERE&quot;</span>
<span class="c1"># NoReCAPCHA secret key</span>
@ -702,9 +621,7 @@ them below:</p>
</section>
<section id="step-3-adding-the-capcha-to-our-form">
<h3>Step 3: Adding the CAPCHA to our form<a class="headerlink" href="#step-3-adding-the-capcha-to-our-form" title="Permalink to this headline"></a></h3>
<p>Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your
<code class="docutils literal notranslate"><span class="pre">web/chargen/forms.py</span></code> file. Were going to add a new field, but hopefully, all the hard work has
been done for us. Update at your convenience, You might end up with something like this:</p>
<p>Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your <code class="docutils literal notranslate"><span class="pre">web/chargen/forms.py</span></code> file. Were going to add a new field, but hopefully, all the hard work has been done for us. Update at your convenience, You might end up with something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
<span class="kn">from</span> <span class="nn">nocaptcha_recaptcha.fields</span> <span class="kn">import</span> <span class="n">NoReCaptchaField</span>
@ -720,9 +637,7 @@ been done for us. Update at your convenience, You might end up with something l
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span><span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;https://www.google.com/recaptcha/api.js&quot;</span> <span class="na">async</span> <span class="na">defer</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</pre></div>
</div>
<p>And you should put it at the bottom of the page. Just before the closing body would be good, but
for the time being, the base page doesnt provide a footer block, so well put it in the content
block. Note that its not the best place, but it will work. In the end, your
<p>And you should put it at the bottom of the page. Just before the closing body would be good, but for the time being, the base page doesnt provide a footer block, so well put it in the content block. Note that its not the best place, but it will work. In the end, your
<code class="docutils literal notranslate"><span class="pre">web/chargen/templates/chargen/create.html</span></code> file should look like this:</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span>{% extends &quot;base.html&quot; %}
{% block content %}
@ -740,9 +655,7 @@ block. Note that its not the best place, but it will work. In the end, your
{% endblock %}
</pre></div>
</div>
<p>Reload and open <a class="reference external" href="http://localhost:4001/chargen/create/">http://localhost:4001/chargen/create</a> and
you should see your beautiful CAPCHA just before the “submit” button. Try not to check the checkbox
to see what happens. And do the same while checking the checkbox!</p>
<p>Reload and open <a class="reference external" href="http://localhost:4001/chargen/create/">http://localhost:4001/chargen/create</a> and you should see your beautiful CAPCHA just before the “submit” button. Try not to check the checkbox to see what happens. And do the same while checking the checkbox!</p>
</section>
</section>
</section>

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Help System Tutorial" href="Web-Help-System-Tutorial.html" />
<link rel="next" title="Web Help System Tutorial" href="Web-Help-System-Tutorial.html" />
<link rel="prev" title="Web Character Generation" href="Web-Character-Generation.html" />
</head><body>
@ -34,7 +34,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-Help-System-Tutorial.html" title="Help System Tutorial"
<a href="Web-Help-System-Tutorial.html" title="Web Help System Tutorial"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Web-Character-Generation.html" title="Web Character Generation"
@ -68,7 +68,7 @@
title="previous chapter">Web Character Generation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Web-Help-System-Tutorial.html"
title="next chapter">Help System Tutorial</a></p>
title="next chapter">Web Help System Tutorial</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -106,36 +106,23 @@
<section class="tex2jax_ignore mathjax_ignore" id="web-character-view-tutorial">
<h1>Web Character View Tutorial<a class="headerlink" href="#web-character-view-tutorial" title="Permalink to this headline"></a></h1>
<p><strong>Before doing this tutorial you will probably want to read the intro in [Basic Web tutorial](Web- Tutorial).</strong></p>
<p>In this tutorial we will create a web page that displays the stats of a game character. For this,
and all other pages we want to make specific to our game, well need to create our own Django “app”</p>
<p>Well call our app <code class="docutils literal notranslate"><span class="pre">character</span></code>, since it will be dealing with character information. From your game
dir, run</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia startapp character
<p><strong>Before doing this tutorial you will probably want to read the intro in <a class="reference internal" href="Web-Changing-Webpage.html"><span class="doc std std-doc">Changing The Web Page tutorial</span></a>.</strong></p>
<p>In this tutorial we will create a web page that displays the stats of a game character. For this, and all other pages we want to make specific to our game, well need to create our own Django “app”. Well call our app <code class="docutils literal notranslate"><span class="pre">character</span></code>, since it will be dealing with character information. From your game dir, run</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cd web
evennia startapp character
</pre></div>
</div>
<p>This will create a directory named <code class="docutils literal notranslate"><span class="pre">character</span></code> in the root of your game dir. It contains all basic
files that a Django app needs. To keep <code class="docutils literal notranslate"><span class="pre">mygame</span></code> well ordered, move it to your <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code>
directory instead:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mv character web/
</pre></div>
</div>
<p>Note that we will not edit all files in this new directory, many of the generated files are outside
the scope of this tutorial.</p>
<p>In order for Django to find our new web app, well need to add it to the <code class="docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code> setting.
Evennias default installed apps are already set, so in <code class="docutils literal notranslate"><span class="pre">server/conf/settings.py</span></code>, well just extend
them:</p>
<p>This will create a new directory named <code class="docutils literal notranslate"><span class="pre">character</span></code> inside <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code>. We put it in <code class="docutils literal notranslate"><span class="pre">web/</span></code> to keep things tidy, but you could place it wherever you like. It contains all basic files that a Django app needs.</p>
<p>Note that we will not edit all files in this new directory, many of the generated files are outside the scope of this tutorial.</p>
<p>In order for Django to find our new web app, well need to add it to the <code class="docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code> setting. Evennias default installed apps are already set, so in <code class="docutils literal notranslate"><span class="pre">server/conf/settings.py</span></code>, well just extend them:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">INSTALLED_APPS</span> <span class="o">+=</span> <span class="p">(</span><span class="s1">&#39;web.character&#39;</span><span class="p">,)</span>
</pre></div>
</div>
<blockquote>
<div><p>Note: That end comma is important. It makes sure that Python interprets the addition as a tuple
instead of a string.</p>
<div><p>Note: That end comma is important. It makes sure that Python interprets the addition as a tuple instead of a string.</p>
</div></blockquote>
<p>The first thing we need to do is to create a <em>view</em> and an <em>URL pattern</em> to point to it. A view is a
function that generates the web page that a visitor wants to see, while the URL pattern lets Django
know what URL should trigger the view. The pattern may also provide some information of its own as
we shall see.</p>
function that generates the web page that a visitor wants to see, while the URL pattern lets Django know what URL should trigger the view. The pattern may also provide some information of its own as we shall see.</p>
<p>Here is our <code class="docutils literal notranslate"><span class="pre">character/urls.py</span></code> file (<strong>Note</strong>: you may have to create this file if a blank one
wasnt generated for you):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># URL patterns for the character app</span>
@ -150,30 +137,13 @@ wasnt generated for you):</p>
</div>
<p>This file contains all of the URL patterns for the application. The <code class="docutils literal notranslate"><span class="pre">url</span></code> function in the
<code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> list are given three arguments. The first argument is a pattern-string used to
identify which URLs are valid. Patterns are specified as <em>regular expressions</em>. Regular expressions
are used to match strings and are written in a special, very compact, syntax. A detailed description
of regular expressions is beyond this tutorial but you can learn more about them
<a class="reference external" href="https://docs.python.org/2/howto/regex.html">here</a>. For now, just accept that this regular
expression requires that the visitors URL looks something like this:</p>
identify which URLs are valid. Patterns are specified as <em>regular expressions</em>. Regular expressions are used to match strings and are written in a special, very compact, syntax. A detailed description of regular expressions is beyond this tutorial but you can learn more about them <a class="reference external" href="https://docs.python.org/2/howto/regex.html">here</a>. For now, just accept that this regular expression requires that the visitors URL looks something like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sheet</span><span class="o">/</span><span class="mi">123</span><span class="o">/</span>
</pre></div>
</div>
<p>That is, <code class="docutils literal notranslate"><span class="pre">sheet/</span></code> followed by a number, rather than some other possible URL pattern. We will
interpret this number as object ID. Thanks to how the regular expression is formulated, the pattern
recognizer stores the number in a variable called <code class="docutils literal notranslate"><span class="pre">object_id</span></code>. This will be passed to the view (see
below). We add the imported view function (<code class="docutils literal notranslate"><span class="pre">sheet</span></code>) in the second argument. We also add the <code class="docutils literal notranslate"><span class="pre">name</span></code>
keyword to identify the URL pattern itself. You should always name your URL patterns, this makes
them easy to refer to in html templates using the <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">url</span> <span class="pre">%}</span></code> tag (but we wont get more into that
in this tutorial).</p>
<p>That is, <code class="docutils literal notranslate"><span class="pre">sheet/</span></code> followed by a number, rather than some other possible URL pattern. We will interpret this number as object ID. Thanks to how the regular expression is formulated, the pattern recognizer stores the number in a variable called <code class="docutils literal notranslate"><span class="pre">object_id</span></code>. This will be passed to the view (see below). We add the imported view function (<code class="docutils literal notranslate"><span class="pre">sheet</span></code>) in the second argument. We also add the <code class="docutils literal notranslate"><span class="pre">name</span></code> keyword to identify the URL pattern itself. You should always name your URL patterns, this makes them easy to refer to in html templates using the <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">url</span> <span class="pre">%}</span></code> tag (but we wont get more into that in this tutorial).</p>
<blockquote>
<div><p>Security Note: Normally, users do not have the ability to see object IDs within the game (its
restricted to superusers only). Exposing the games object IDs to the public like this enables
griefers to perform what is known as an <a class="reference external" href="http://www.sans.edu/research/security-laboratory/article/attacks-browsing">account enumeration
attack</a> in the efforts of
hijacking your superuser account. Consider this: in every Evennia installation, there are two
objects that we can <em>always</em> expect to exist and have the same object IDs Limbo (#2) and the
superuser you create in the beginning (#1). Thus, the griefer can get 50% of the information they
need to hijack the admin account (the admins username) just by navigating to <code class="docutils literal notranslate"><span class="pre">sheet/1</span></code>!</p>
<div><p>Security Note: Normally, users do not have the ability to see object IDs within the game (its restricted to superusers only). Exposing the games object IDs to the public like this enables griefers to perform what is known as an <a class="reference external" href="http://www.sans.edu/research/security-laboratory/article/attacks-browsing">account enumeration attack</a> in the efforts of hijacking your superuser account. Consider this: in every Evennia installation, there are two objects that we can <em>always</em> expect to exist and have the same object IDs Limbo (#2) and the superuser you create in the beginning (#1). Thus, the griefer can get 50% of the information they need to hijack the admin account (the admins username) just by navigating to <code class="docutils literal notranslate"><span class="pre">sheet/1</span></code>!</p>
</div></blockquote>
<p>Next we create <code class="docutils literal notranslate"><span class="pre">views.py</span></code>, the view file that <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> refers to.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Views for our character app</span>
@ -197,20 +167,10 @@ need to hijack the admin account (the admins username) just by navigating to
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;character/sheet.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;character&#39;</span><span class="p">:</span> <span class="n">character</span><span class="p">})</span>
</pre></div>
</div>
<p>As explained earlier, the URL pattern parser in <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> parses the URL and passes <code class="docutils literal notranslate"><span class="pre">object_id</span></code> to
our view function <code class="docutils literal notranslate"><span class="pre">sheet</span></code>. We do a database search for the object using this number. We also make
sure such an object exists and that it is actually a Character. The view function is also handed a
<code class="docutils literal notranslate"><span class="pre">request</span></code> object. This gives us information about the request, such as if a logged-in user viewed it</p>
<ul class="simple">
<li><p>we wont use that information here but it is good to keep in mind.</p></li>
</ul>
<p>As explained earlier, the URL pattern parser in <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> parses the URL and passes <code class="docutils literal notranslate"><span class="pre">object_id</span></code> to our view function <code class="docutils literal notranslate"><span class="pre">sheet</span></code>. We do a database search for the object using this number. We also make sure such an object exists and that it is actually a Character. The view function is also handed a <code class="docutils literal notranslate"><span class="pre">request</span></code> object. This gives us information about the request, such as if a logged-in user viewed it - we wont use that information here but it is good to keep in mind.</p>
<p>On the last line, we call the <code class="docutils literal notranslate"><span class="pre">render</span></code> function. Apart from the <code class="docutils literal notranslate"><span class="pre">request</span></code> object, the <code class="docutils literal notranslate"><span class="pre">render</span></code>
function takes a path to an html template and a dictionary with extra data you want to pass into
said template. As extra data we pass the Character object we just found. In the template it will be
available as the variable “character”.</p>
<p>The html template is created as <code class="docutils literal notranslate"><span class="pre">templates/character/sheet.html</span></code> under your <code class="docutils literal notranslate"><span class="pre">character</span></code> app folder.
You may have to manually create both <code class="docutils literal notranslate"><span class="pre">template</span></code> and its subfolder <code class="docutils literal notranslate"><span class="pre">character</span></code>. Heres the template
to create:</p>
function takes a path to an html template and a dictionary with extra data you want to pass into said template. As extra data we pass the Character object we just found. In the template it will be available as the variable “character”.</p>
<p>The html template is created as <code class="docutils literal notranslate"><span class="pre">templates/character/sheet.html</span></code> under your <code class="docutils literal notranslate"><span class="pre">character</span></code> app folder. You may have to manually create both <code class="docutils literal notranslate"><span class="pre">template</span></code> and its subfolder <code class="docutils literal notranslate"><span class="pre">character</span></code>. Heres the template to create:</p>
<div class="highlight-html notranslate"><div class="highlight"><pre><span></span>{% extends &quot;base.html&quot; %}
{% block content %}
@ -259,26 +219,14 @@ to create:</p>
{% endblock %}
</pre></div>
</div>
<p>In Django templates, <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">...</span> <span class="pre">%}</span></code> denotes special in-template “functions” that Django understands.
The <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">...</span> <span class="pre">}}</span></code> blocks work as “slots”. They are replaced with whatever value the code inside the
block returns.</p>
<p>The first line, <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">&quot;base.html&quot;</span> <span class="pre">%}</span></code>, tells Django that this template extends the base
template that Evennia is using. The base template is provided by the theme. Evennia comes with the
open-source third-party theme <code class="docutils literal notranslate"><span class="pre">prosimii</span></code>. You can find it and its <code class="docutils literal notranslate"><span class="pre">base.html</span></code> in
<p>In Django templates, <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">...</span> <span class="pre">%}</span></code> denotes special in-template “functions” that Django understands. The <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">...</span> <span class="pre">}}</span></code> blocks work as “slots”. They are replaced with whatever value the code inside the block returns.</p>
<p>The first line, <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">&quot;base.html&quot;</span> <span class="pre">%}</span></code>, tells Django that this template extends the base template that Evennia is using. The base template is provided by the theme. Evennia comes with the open-source third-party theme <code class="docutils literal notranslate"><span class="pre">prosimii</span></code>. You can find it and its <code class="docutils literal notranslate"><span class="pre">base.html</span></code> in
<code class="docutils literal notranslate"><span class="pre">evennia/web/templates/prosimii</span></code>. Like other templates, these can be overwritten.</p>
<p>The next line is <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">content</span> <span class="pre">%}</span></code>. The <code class="docutils literal notranslate"><span class="pre">base.html</span></code> file has <code class="docutils literal notranslate"><span class="pre">block</span></code>s, which are placeholders
that templates can extend. The main block, and the one we use, is named <code class="docutils literal notranslate"><span class="pre">content</span></code>.</p>
<p>We can access the <code class="docutils literal notranslate"><span class="pre">character</span></code> variable anywhere in the template because we passed it in the <code class="docutils literal notranslate"><span class="pre">render</span></code>
call at the end of <code class="docutils literal notranslate"><span class="pre">view.py</span></code>. That means we also have access to the Characters <code class="docutils literal notranslate"><span class="pre">db</span></code> attributes,
much like you would in normal Python code. You dont have the ability to call functions with
arguments in the template in fact, if you need to do any complicated logic, you should do it in
<code class="docutils literal notranslate"><span class="pre">view.py</span></code> and pass the results as more variables to the template. But you still have a great deal of
flexibility in how you display the data.</p>
<p>We can do a little bit of logic here as well. We use the <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endfor</span> <span class="pre">%}</span></code> and <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">if</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">else</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endif</span> <span class="pre">%}</span></code> structures to change how the template renders depending on how many
skills the user has, or if the user is approved (assuming your game has an approval system).</p>
<p>The last file we need to edit is the master URLs file. This is needed in order to smoothly integrate
the URLs from your new <code class="docutils literal notranslate"><span class="pre">character</span></code> app with the URLs from Evennias existing pages. Find the file
<code class="docutils literal notranslate"><span class="pre">web/website/urls.py</span></code> and update its <code class="docutils literal notranslate"><span class="pre">patterns</span></code> list as follows:</p>
<p>We can access the <code class="docutils literal notranslate"><span class="pre">character</span></code> variable anywhere in the template because we passed it in the <code class="docutils literal notranslate"><span class="pre">render</span></code> call at the end of <code class="docutils literal notranslate"><span class="pre">view.py</span></code>. That means we also have access to the Characters <code class="docutils literal notranslate"><span class="pre">db</span></code> attributes, much like you would in normal Python code. You dont have the ability to call functions with arguments in the template in fact, if you need to do any complicated logic, you should do it in <code class="docutils literal notranslate"><span class="pre">view.py</span></code> and pass the results as more variables to the template. But you still have a great deal of flexibility in how you display the data.</p>
<p>We can do a little bit of logic here as well. We use the <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endfor</span> <span class="pre">%}</span></code> and <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">if</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">else</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endif</span> <span class="pre">%}</span></code> structures to change how the template renders depending on how many skills the user has, or if the user is approved (assuming your game has an approval system).</p>
<p>The last file we need to edit is the master URLs file. This is needed in order to smoothly integrate the URLs from your new <code class="docutils literal notranslate"><span class="pre">character</span></code> app with the URLs from Evennias existing pages. Find the file <code class="docutils literal notranslate"><span class="pre">web/website/urls.py</span></code> and update its <code class="docutils literal notranslate"><span class="pre">patterns</span></code> list as follows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># web/website/urls.py</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
@ -290,10 +238,8 @@ the URLs from your new <code class="docutils literal notranslate"><span class="p
<p>Now reload the server with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reload</span></code> and visit the page in your browser. If you havent
changed your defaults, you should be able to find the sheet for character <code class="docutils literal notranslate"><span class="pre">#1</span></code> at
<code class="docutils literal notranslate"><span class="pre">http://localhost:4001/character/sheet/1/</span></code></p>
<p>Try updating the stats in-game and refresh the page in your browser. The results should show
immediately.</p>
<p>As an optional final step, you can also change your character typeclass to have a method called
get_absolute_url.</p>
<p>Try updating the stats in-game and refresh the page in your browser. The results should show immediately.</p>
<p>As an optional final step, you can also change your character typeclass to have a method called get_absolute_url.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># typeclasses/characters.py</span>
<span class="c1"># inside Character</span>
@ -303,10 +249,8 @@ immediately.</p>
</pre></div>
</div>
<p>Doing so will give you a view on site button in the top right of the Django Admin Objects
changepage that links to your new character sheet, and allow you to get the link to a characters
page by using <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">object.get_absolute_url</span> <span class="pre">}}</span></code> in any template where you have a given object.</p>
<p><em>Now that youve made a basic page and app with Django, you may want to read the full Django
tutorial to get a better idea of what it can do. <a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/tutorial01/">You can find Djangos tutorial
changepage that links to your new character sheet, and allow you to get the link to a characters page by using <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">object.get_absolute_url</span> <span class="pre">}}</span></code> in any template where you have a given object.</p>
<p><em>Now that youve made a basic page and app with Django, you may want to read the full Django tutorial to get a better idea of what it can do. <a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/tutorial01/">You can find Djangos tutorial
here</a>.</em></p>
</section>
@ -326,7 +270,7 @@ here</a>.</em></p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-Help-System-Tutorial.html" title="Help System Tutorial"
<a href="Web-Help-System-Tutorial.html" title="Web Help System Tutorial"
>next</a> |</li>
<li class="right" >
<a href="Web-Character-Generation.html" title="Web Character Generation"

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Automatically Tweet game stats" href="Web-Tweeting-Game-Stats.html" />
<link rel="prev" title="Help System Tutorial" href="Web-Help-System-Tutorial.html" />
<link rel="prev" title="Web Help System Tutorial" href="Web-Help-System-Tutorial.html" />
</head><body>
@ -37,7 +37,7 @@
<a href="Web-Tweeting-Game-Stats.html" title="Automatically Tweet game stats"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Web-Help-System-Tutorial.html" title="Help System Tutorial"
<a href="Web-Help-System-Tutorial.html" title="Web Help System Tutorial"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" accesskey="U">Tutorials and How-Tos</a> &#187;</li>
@ -79,7 +79,7 @@
<h4>Previous topic</h4>
<p class="topless"><a href="Web-Help-System-Tutorial.html"
title="previous chapter">Help System Tutorial</a></p>
title="previous chapter">Web Help System Tutorial</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Web-Tweeting-Game-Stats.html"
title="next chapter">Automatically Tweet game stats</a></p>
@ -531,7 +531,7 @@
<a href="Web-Tweeting-Game-Stats.html" title="Automatically Tweet game stats"
>next</a> |</li>
<li class="right" >
<a href="Web-Help-System-Tutorial.html" title="Help System Tutorial"
<a href="Web-Help-System-Tutorial.html" title="Web Help System Tutorial"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" >Tutorials and How-Tos</a> &#187;</li>

View file

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Help System Tutorial &#8212; Evennia 2.x documentation</title>
<title>Web Help System Tutorial &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
@ -41,7 +41,7 @@
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" accesskey="U">Tutorials and How-Tos</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Help System Tutorial</a></li>
<li class="nav-item nav-item-this"><a href="">Web Help System Tutorial</a></li>
</ul>
</div>
@ -65,7 +65,7 @@
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Help System Tutorial</a><ul>
<li><a class="reference internal" href="#">Web Help System Tutorial</a><ul>
<li><a class="reference internal" href="#creating-our-app">Creating our app</a></li>
<li><a class="reference internal" href="#our-new-page">Our new page</a><ul>
<li><a class="reference internal" href="#create-a-view">Create a view</a></li>
@ -128,11 +128,10 @@
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="help-system-tutorial">
<h1>Help System Tutorial<a class="headerlink" href="#help-system-tutorial" title="Permalink to this headline"></a></h1>
<p><strong>Before doing this tutorial you will probably want to read the intro in [Basic Web tutorial](Web- Tutorial).</strong> Reading the three first parts of the <a class="reference external" href="https://docs.djangoproject.com/en/4.0/intro/tutorial01/">Django tutorial</a> might help as well.</p>
<p>This tutorial will show you how to access the help system through your website. Both help commands
and regular help entries will be visible, depending on the logged-in user or an anonymous character.</p>
<section class="tex2jax_ignore mathjax_ignore" id="web-help-system-tutorial">
<h1>Web Help System Tutorial<a class="headerlink" href="#web-help-system-tutorial" title="Permalink to this headline"></a></h1>
<p><strong>Before doing this tutorial you will probably want to read the intro in the <a class="reference internal" href="Web-Changing-Webpage.html"><span class="doc std std-doc">Changing the Web page tutorial</span></a>.</strong> Reading the three first parts of the <a class="reference external" href="https://docs.djangoproject.com/en/4.0/intro/tutorial01/">Django tutorial</a> might help as well.</p>
<p>This tutorial will show you how to access the help system through your website. Both help commands and regular help entries will be visible, depending on the logged-in user or an anonymous character.</p>
<p>This tutorial will show you how to:</p>
<ul class="simple">
<li><p>Create a new page to add to your website.</p></li>
@ -142,23 +141,16 @@ and regular help entries will be visible, depending on the logged-in user or an
</ul>
<section id="creating-our-app">
<h2>Creating our app<a class="headerlink" href="#creating-our-app" title="Permalink to this headline"></a></h2>
<p>The first step is to create our new Django <em>app</em>. An app in Django can contain pages and
mechanisms: your website may contain different apps. Actually, the website provided out-of-the-box
by Evennia has already three apps: a “webclient” app, to handle the entire webclient, a “website”
app to contain your basic pages, and a third app provided by Django to create a simple admin
interface. So well create another app in parallel, giving it a clear name to represent our help
system.</p>
<p>From your game directory, use the following command:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia startapp help_system
<p>The first step is to create our new Django <em>app</em>. An app in Django can contain pages and mechanisms: your website may contain different apps. Actually, the website provided out-of-the-box by Evennia has already three apps: a “webclient” app, to handle the entire webclient, a “website” app to contain your basic pages, and a third app provided by Django to create a simple admin interface. So well create another app in parallel, giving it a clear name to represent our help system.</p>
<p>From your game directory, use the following commands:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cd web
evennia startapp help_system
</pre></div>
</div>
<blockquote>
<div><p>Note: calling the app “help” would have been more explicit, but this name is already used by
Django.</p>
<div><p>Note: calling the app “help” would have been more explicit, but this name is already used by Django.</p>
</div></blockquote>
<p>This will create a directory named <code class="docutils literal notranslate"><span class="pre">help_system</span></code> at the root of your game directory. Its a good
idea to keep things organized and move this directory in the “web” directory of your game. Your
game directory should look like:</p>
<p>This will create a directory named <code class="docutils literal notranslate"><span class="pre">help_system</span></code> under <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code>. We put it there to keep all web-related things together, but you can organize however you like. Heres how the structure looks:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mygame/
...
web/
@ -166,42 +158,32 @@ game directory should look like:</p>
...
</pre></div>
</div>
<p>The “web/help_system” directory contains files created by Django. Well use some of them, but if
you want to learn more about them all, you should read <a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/tutorial01/">the Django
tutorial</a>.</p>
<p>There is a last thing to be done: your folder has been added, but Django doesnt know about it, it
doesnt know its a new app. We need to tell it, and we do so by editing a simple setting. Open
your “server/conf/settings.py” file and add, or edit, these lines:</p>
<p>The “web/help_system” directory contains files created by Django. Well use some of them, but if you want to learn more about them all, you should read <a class="reference external" href="https://docs.djangoproject.com/en/4.1/intro/tutorial01/">the Django tutorial</a>.</p>
<p>There is a last thing to be done: your folder has been added, but Django doesnt know about it, it doesnt know its a new app. We need to tell it, and we do so by editing a simple setting. Open your “server/conf/settings.py” file and add, or edit, these lines:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Web configuration</span>
<span class="n">INSTALLED_APPS</span> <span class="o">+=</span> <span class="p">(</span>
<span class="s2">&quot;web.help_system&quot;</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<p>You can start Evennia if you want, and go to your website, probably at
<a class="reference external" href="http://localhost:4001">http://localhost:4001</a> . You wont see anything different though: we added
the app but its fairly empty.</p>
<p>You can start Evennia if you want, and go to your website, probably at <a class="reference external" href="http://localhost:4001">http://localhost:4001</a> . You wont see anything different though: we added the app but its fairly empty.</p>
</section>
<section id="our-new-page">
<h2>Our new page<a class="headerlink" href="#our-new-page" title="Permalink to this headline"></a></h2>
<p>At this point, our new <em>app</em> contains mostly empty files that you can explore. In order to create
a page for our help system, we need to add:</p>
<p>At this point, our new <em>app</em> contains mostly empty files that you can explore. In order to create a page for our help system, we need to add:</p>
<ul class="simple">
<li><p>A <em>view</em>, dealing with the logic of our page.</p></li>
<li><p>A <em>template</em> to display our new page.</p></li>
<li><p>A new <em>URL</em> pointing to our page.</p></li>
</ul>
<blockquote>
<div><p>We could get away by creating just a view and a new URL, but thats not a recommended way to work
with your website. Building on templates is so much more convenient.</p>
<div><p>We could get away by creating just a view and a new URL, but thats not a recommended way to work with your website. Building on templates is so much more convenient.</p>
</div></blockquote>
<section id="create-a-view">
<h3>Create a view<a class="headerlink" href="#create-a-view" title="Permalink to this headline"></a></h3>
<p>A <em>view</em> in Django is a simple Python function placed in the “<a class="reference external" href="http://views.py">views.py</a>” file in your app. It will
handle the behavior that is triggered when a user asks for this information by entering a <em>URL</em> (the
connection between <em>views</em> and <em>URLs</em> will be discussed later).</p>
<p>So lets create our view. You can open the “web/help_system/views.py” file and paste the following
lines:</p>
handle the behavior that is triggered when a user asks for this information by entering a <em>URL</em> (the connection between <em>views</em> and <em>URLs</em> will be discussed later).</p>
<p>So lets create our view. You can open the “web/help_system/views.py” file and paste the following lines:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>
<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
@ -209,16 +191,11 @@ lines:</p>
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s2">&quot;help_system/index.html&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Our view handles all code logic. This time, theres not much: when this function is called, it will
render the template we will now create. But thats where we will do most of our work afterward.</p>
<p>Our view handles all code logic. This time, theres not much: when this function is called, it will render the template we will now create. But thats where we will do most of our work afterward.</p>
</section>
<section id="create-a-template">
<h3>Create a template<a class="headerlink" href="#create-a-template" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">render</span></code> function called into our <em>view</em> asks the <em>template</em> <code class="docutils literal notranslate"><span class="pre">help_system/index.html</span></code>. The
<em>templates</em> of our apps are stored in the app directory, “templates” sub-directory. Django may have
created the “templates” folder already. If not, create it yourself. In it, create another folder
“help_system”, and inside of this folder, create a file named “index.html”. Wow, thats some
hierarchy. Your directory structure (starting from <code class="docutils literal notranslate"><span class="pre">web</span></code>) should look like this:</p>
<p>The <code class="docutils literal notranslate"><span class="pre">render</span></code> function called into our <em>view</em> asks the <em>template</em> <code class="docutils literal notranslate"><span class="pre">help_system/index.html</span></code>. The <em>templates</em> of our apps are stored in the app directory, “templates” sub-directory. Django may have created the “templates” folder already. If not, create it yourself. In it, create another folder “help_system”, and inside of this folder, create a file named “index.html”. Wow, thats some hierarchy. Your directory structure (starting from <code class="docutils literal notranslate"><span class="pre">web</span></code>) should look like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>web/
help_system/
...
@ -237,24 +214,17 @@ hierarchy. Your directory structure (starting from <code class="docutils litera
</div>
<p>Heres a little explanation line by line of what this template does:</p>
<ol class="simple">
<li><p>It loads the “base.html” <em>template</em>. This describes the basic structure of all your pages, with
a menu at the top and a footer, and perhaps other information like images and things to be present
on each page. You can create templates that do not inherit from “base.html”, but you should have a
good reason for doing so.</p></li>
<li><p>The “base.html” <em>template</em> defines all the structure of the page. What is left is to override
some sections of our pages. These sections are called <em>blocks</em>. On line 2, we override the block
named “blocktitle”, which contains the title of our page.</p></li>
<li><p>Same thing here, we override the <em>block</em> named “content”, which contains the main content of our
web page. This block is bigger, so we define it on several lines.</p></li>
<li><p>It loads the “base.html” <em>template</em>. This describes the basic structure of all your pages, with a menu at the top and a footer, and perhaps other information like images and things to be present on each page. You can create templates that do not inherit from “base.html”, but you should have a good reason for doing so.</p></li>
<li><p>The “base.html” <em>template</em> defines all the structure of the page. What is left is to override some sections of our pages. These sections are called <em>blocks</em>. On line 2, we override the block named “blocktitle”, which contains the title of our page.</p></li>
<li><p>Same thing here, we override the <em>block</em> named “content”, which contains the main content of our web page. This block is bigger, so we define it on several lines.</p></li>
<li><p>This is perfectly normal HTML code to display a level-2 heading.</p></li>
<li><p>And finally we close the <em>block</em> named “content”.</p></li>
</ol>
</section>
<section id="create-a-new-url">
<h3>Create a new URL<a class="headerlink" href="#create-a-new-url" title="Permalink to this headline"></a></h3>
<p>Last step to add our page: we need to add a <em>URL</em> leading to it… otherwise users wont be able to
access it. The URLs of our apps are stored in the apps directory “<a class="reference external" href="http://urls.py">urls.py</a>” file.</p>
<p>Open the <code class="docutils literal notranslate"><span class="pre">web/help_system/urls.py</span></code> file (you might have to create it) and make it look like this.</p>
<p>Last step to add our page: we need to add a <em>URL</em> leading to it… otherwise users wont be able to access it. The URLs of our apps are stored in the apps directory “<a class="reference external" href="http://urls.py">urls.py</a>” file.</p>
<p>Open the <code class="docutils literal notranslate"><span class="pre">web/help_system/urls.py</span></code> file (you might have to create it) and make it look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># URL patterns for the help_system app</span>
<span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>
@ -265,12 +235,8 @@ access it. The URLs of our apps are stored in the apps directory “<a class
<span class="p">]</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> variable is what Django/Evennia looks for to figure out how to
direct a user entering an URL in their browser to the view-code you have
written.</p>
<p>Last we need to tie this into the main namespace for your game. Edit the file
<code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code>. In it you will find the <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> list again.
Add a new <code class="docutils literal notranslate"><span class="pre">path</span></code> to the end of the list.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> variable is what Django/Evennia looks for to figure out how to direct a user entering an URL in their browser to the view-code you have written.</p>
<p>Last we need to tie this into the main namespace for your game. Edit the file <code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code>. In it you will find the <code class="docutils literal notranslate"><span class="pre">urlpatterns</span></code> list again. Add a new <code class="docutils literal notranslate"><span class="pre">path</span></code> to the end of the list.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/urls.py</span>
<span class="c1"># [...]</span>
@ -292,21 +258,14 @@ Add a new <code class="docutils literal notranslate"><span class="pre">path</spa
</div>
<p>When a user will ask for a specific <em>URL</em> on your site, Django will:</p>
<ol class="simple">
<li><p>Read the list of custom patterns defined in “web/urls.py”. Theres one pattern here, which
describes to Django that all URLs beginning by help/ should be sent to the help_system app. The
help/ part is removed.</p></li>
<li><p>Then Django will check the “web.help_system/urls.py” file. It contains only one URL, which is
empty (<code class="docutils literal notranslate"><span class="pre">^$</span></code>).</p></li>
<li><p>Read the list of custom patterns defined in “web/urls.py”. Theres one pattern here, which describes to Django that all URLs beginning by help/ should be sent to the help_system app. The help/ part is removed.</p></li>
<li><p>Then Django will check the “web.help_system/urls.py” file. It contains only one URL, which is empty (<code class="docutils literal notranslate"><span class="pre">^$</span></code>).</p></li>
</ol>
<p>In other words, if the URL is /help/, then Django will execute our defined view.</p>
</section>
<section id="lets-see-it-work">
<h3>Lets see it work<a class="headerlink" href="#lets-see-it-work" title="Permalink to this headline"></a></h3>
<p>You can now reload or start Evennia. Open a tab in your browser and go to
<a class="reference external" href="http://localhost:4001/help/">http://localhost:4001/help/</a> . If everything goes well, you should
see your new page… which isnt empty since Evennia uses our “base.html” <em>template</em>. In the
content of our page, theres only a heading that reads “help index”. Notice that the title of our
page is “mygame - Help index” (“mygame” is replaced by the name of your game).</p>
<p>You can now reload or start Evennia. Open a tab in your browser and go to <a class="reference external" href="http://localhost:4001/help/">http://localhost:4001/help/</a> . If everything goes well, you should see your new page… which isnt empty since Evennia uses our “base.html” <em>template</em>. In the content of our page, theres only a heading that reads “help index”. Notice that the title of our page is “mygame - Help index” (“mygame” is replaced by the name of your game).</p>
<p>From now on, it will be easier to move forward and add features.</p>
</section>
<section id="a-brief-reminder">
@ -325,30 +284,17 @@ page is “mygame - Help index” (“mygame” is replaced by the name of your
<blockquote>
<div><p>Should we create two URLs?</p>
</div></blockquote>
<p>The answer is… maybe. It depends on what you want to do. We have our help index accessible
through the “/help/” URL. We could have the detail of a help entry accessible through “/help/desc”
(to see the detail of the “desc” command). The problem is that our commands or help topics may
contain special characters that arent to be present in URLs. There are different ways around this
problem. I have decided to use a <em>GET variable</em> here, which would create URLs like this:</p>
<p>The answer is… maybe. It depends on what you want to do. We have our help index accessible through the “/help/” URL. We could have the detail of a help entry accessible through “/help/desc” (to see the detail of the “desc” command). The problem is that our commands or help topics may contain special characters that arent to be present in URLs. There are different ways around this problem. I have decided to use a <em>GET variable</em> here, which would create URLs like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/help?name=desc
</pre></div>
</div>
<p>If you use this system, you dont have to add a new URL: GET and POST variables are accessible
through our requests and well see how soon enough.</p>
<p>If you use this system, you dont have to add a new URL: GET and POST variables are accessible through our requests and well see how soon enough.</p>
</section>
</section>
<section id="handling-logged-in-users">
<h2>Handling logged-in users<a class="headerlink" href="#handling-logged-in-users" title="Permalink to this headline"></a></h2>
<p>One of our requirements is to have a help system tailored to our accounts. If an account with admin
access logs in, the page should display a lot of commands that arent accessible to common users.
And perhaps even some additional help topics.</p>
<p>Fortunately, its fairly easy to get the logged in account in our view (remember that well do most
of our coding there). The <em>request</em> object, passed to our function, contains a <code class="docutils literal notranslate"><span class="pre">user</span></code> attribute.
This attribute will always be there: we cannot test whether its <code class="docutils literal notranslate"><span class="pre">None</span></code> or not, for instance. But
when the request comes from a user that isnt logged in, the <code class="docutils literal notranslate"><span class="pre">user</span></code> attribute will contain an
anonymous Django user. We then can use the <code class="docutils literal notranslate"><span class="pre">is_anonymous</span></code> method to see whether the user is logged-
in or not. Last gift by Evennia, if the user is logged in, <code class="docutils literal notranslate"><span class="pre">request.user</span></code> contains a reference to
an account object, which will help us a lot in coupling the game and online system.</p>
<p>One of our requirements is to have a help system tailored to our accounts. If an account with admin access logs in, the page should display a lot of commands that arent accessible to common users. And perhaps even some additional help topics.</p>
<p>Fortunately, its fairly easy to get the logged in account in our view (remember that well do most of our coding there). The <em>request</em> object, passed to our function, contains a <code class="docutils literal notranslate"><span class="pre">user</span></code> attribute. This attribute will always be there: we cannot test whether its <code class="docutils literal notranslate"><span class="pre">None</span></code> or not, for instance. But when the request comes from a user that isnt logged in, the <code class="docutils literal notranslate"><span class="pre">user</span></code> attribute will contain an anonymous Django user. We then can use the <code class="docutils literal notranslate"><span class="pre">is_anonymous</span></code> method to see whether the user is logged-in or not. Last gift by Evennia, if the user is logged in, <code class="docutils literal notranslate"><span class="pre">request.user</span></code> contains a reference to an account object, which will help us a lot in coupling the game and online system.</p>
<p>So we might end up with something like:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The &#39;index&#39; view.&quot;&quot;&quot;</span>
@ -358,8 +304,7 @@ an account object, which will help us a lot in coupling the game and online syst
</pre></div>
</div>
<blockquote>
<div><p>Note: this code works when your MULTISESSION_MODE is set to 0 or 1. When its above, you would
have something like:</p>
<div><p>Note: this code works when your MULTISESSION_MODE is set to 0 or 1. When its above, you would have something like:</p>
</div></blockquote>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The &#39;index&#39; view.&quot;&quot;&quot;</span>
@ -369,14 +314,12 @@ have something like:</p>
</pre></div>
</div>
<p>In this second case, it will select the first character of the account.</p>
<p>But what if the users not logged in? Again, we have different solutions. One of the most simple
is to create a character that will behave as our default character for the help system. You can
create it through your game: connect to it and enter:</p>
<p>But what if the users not logged in? Again, we have different solutions. One of the most simple is to create a character that will behave as our default character for the help system. You can create it through your game: connect to it and enter:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@charcreate anonymous
</pre></div>
</div>
<p>The system should answer:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Created new character anonymous. Use @ic anonymous to enter the game as this character.
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> Created new character anonymous. Use @ic anonymous to enter the game as this character.
</pre></div>
</div>
<p>So in our view, we could have something like this:</p>
@ -391,15 +334,12 @@ create it through your game: connect to it and enter:</p>
<span class="n">character</span> <span class="o">=</span> <span class="n">Character</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="s2">&quot;anonymous&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>This time, we have a valid character no matter what: remember to adapt this code if youre running
in multisession mode above 1.</p>
<p>This time, we have a valid character no matter what: remember to adapt this code if youre running in multisession mode above 1.</p>
</section>
<section id="the-full-system">
<h2>The full system<a class="headerlink" href="#the-full-system" title="Permalink to this headline"></a></h2>
<p>What were going to do is to browse through all commands and help entries, and list all the commands
that can be seen by this character (either our anonymous character, or our logged-in character).</p>
<p>The code is longer, but it presents the entire concept in our view. Edit the
“web/help_system/views.py” file and paste into it:</p>
<p>What were going to do is to browse through all commands and help entries, and list all the commands that can be seen by this character (either our anonymous character, or our logged-in character).</p>
<p>The code is longer, but it presents the entire concept in our view. Edit the “web/help_system/views.py” file and paste into it:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">Http404</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>
<span class="kn">from</span> <span class="nn">evennia.help.models</span> <span class="kn">import</span> <span class="n">HelpEntry</span>
@ -493,26 +433,17 @@ that can be seen by this character (either our anonymous character, or our
<li><p>The <code class="docutils literal notranslate"><span class="pre">index</span></code> function is our view:</p>
<ul>
<li><p>It begins by getting the character as we saw in the previous section.</p></li>
<li><p>It gets the help topics (commands and help entries) accessible to this character. Its another
function that handles that part.</p></li>
<li><p>If theres a <em>GET variable</em> “name” in our URL (like “/help?name=drop”), it will retrieve it. If
its not a valid topics name, it returns a <em>404</em>. Otherwise, it renders the template called
“detail.html”, to display the detail of our topic.</p></li>
<li><p>It gets the help topics (commands and help entries) accessible to this character. Its another function that handles that part.</p></li>
<li><p>If theres a <em>GET variable</em> “name” in our URL (like “/help?name=drop”), it will retrieve it. If its not a valid topics name, it returns a <em>404</em>. Otherwise, it renders the template called “detail.html”, to display the detail of our topic.</p></li>
<li><p>If theres no <em>GET variable</em> “name”, render “index.html”, to display the list of topics.</p></li>
</ul>
</li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">_get_topics</span></code> is a private function. Its sole mission is to retrieve the commands a character
can execute, and the help entries this same character can see. This code is more Evennia-specific
than Django-specific, it will not be detailed in this tutorial. Just notice that all help topics
are stored in a dictionary. This is to simplify our job when displaying them in our templates.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">_get_topics</span></code> is a private function. Its sole mission is to retrieve the commands a character can execute, and the help entries this same character can see. This code is more Evennia-specific than Django-specific, it will not be detailed in this tutorial. Just notice that all help topics are stored in a dictionary. This is to simplify our job when displaying them in our templates.</p></li>
</ul>
<p>Notice that, in both cases when we asked to render a <em>template</em>, we passed to <code class="docutils literal notranslate"><span class="pre">render</span></code> a third
argument which is the dictionary of variables used in our templates. We can pass variables this
way, and we will use them in our templates.</p>
<p>Notice that, in both cases when we asked to render a <em>template</em>, we passed to <code class="docutils literal notranslate"><span class="pre">render</span></code> a third argument which is the dictionary of variables used in our templates. We can pass variables this way, and we will use them in our templates.</p>
<section id="the-index-template">
<h3>The index template<a class="headerlink" href="#the-index-template" title="Permalink to this headline"></a></h3>
<p>Lets look at our full “index” <em>template</em>. You can open the
“web/help_system/templates/help_sstem/index.html” file and paste the following into it:</p>
<p>Lets look at our full “index” <em>template</em>. You can open the “web/help_system/templates/help_sstem/index.html” file and paste the following into it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="o">%</span> <span class="n">extends</span> <span class="s2">&quot;base.html&quot;</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">block</span> <span class="n">titleblock</span> <span class="o">%</span><span class="p">}</span><span class="n">Help</span> <span class="n">index</span><span class="p">{</span><span class="o">%</span> <span class="n">endblock</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">block</span> <span class="n">content</span> <span class="o">%</span><span class="p">}</span>
@ -541,18 +472,13 @@ way, and we will use them in our templates.</p>
<ol class="simple">
<li><p>Browse through all categories.</p></li>
<li><p>For all categories, display a level-2 heading with the name of the category.</p></li>
<li><p>All topics in a category (remember, they can be either commands or help entries) are displayed in
a table. The trickier part may be that, when the loop is above 5, it will create a new line. The
table will have 5 columns at the most per row.</p></li>
<li><p>For every cell in the table, we create a link redirecting to the detail page (see below). The
URL would look something like “help?name=say”. We use <code class="docutils literal notranslate"><span class="pre">urlencode</span></code> to ensure special characters are
properly escaped.</p></li>
<li><p>All topics in a category (remember, they can be either commands or help entries) are displayed in a table. The trickier part may be that, when the loop is above 5, it will create a new line. The table will have 5 columns at the most per row.</p></li>
<li><p>For every cell in the table, we create a link redirecting to the detail page (see below). The URL would look something like “help?name=say”. We use <code class="docutils literal notranslate"><span class="pre">urlencode</span></code> to ensure special characters are properly escaped.</p></li>
</ol>
</section>
<section id="the-detail-template">
<h3>The detail template<a class="headerlink" href="#the-detail-template" title="Permalink to this headline"></a></h3>
<p>Its now time to show the detail of a topic (command or help entry). You can create the file
“web/help_system/templates/help_system/detail.html”. You can paste into it the following code:</p>
<p>Its now time to show the detail of a topic (command or help entry). You can create the file “web/help_system/templates/help_system/detail.html”. You can paste into it the following code:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="o">%</span> <span class="n">extends</span> <span class="s2">&quot;base.html&quot;</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">block</span> <span class="n">titleblock</span> <span class="o">%</span><span class="p">}</span><span class="n">Help</span> <span class="k">for</span> <span class="p">{{</span> <span class="n">topic</span><span class="o">.</span><span class="n">name</span> <span class="p">}}{</span><span class="o">%</span> <span class="n">endblock</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">block</span> <span class="n">content</span> <span class="o">%</span><span class="p">}</span>
@ -562,30 +488,21 @@ properly escaped.</p></li>
<span class="p">{</span><span class="o">%</span> <span class="n">endblock</span> <span class="o">%</span><span class="p">}</span>
</pre></div>
</div>
<p>This template is much easier to read. Some <em>filters</em> might be unknown to you, but they are just
used to format here.</p>
<p>This template is much easier to read. Some <em>filters</em> might be unknown to you, but they are just used to format here.</p>
</section>
<section id="put-it-all-together">
<h3>Put it all together<a class="headerlink" href="#put-it-all-together" title="Permalink to this headline"></a></h3>
<p>Remember to reload or start Evennia, and then go to
<a class="reference external" href="http://localhost:4001/help/">http://localhost:4001/help</a>. You should see the list of commands and
topics accessible by all characters. Try to login (click the “login” link in the menu of your
website) and go to the same page again. You should now see a more detailed list of commands and
help entries. Click on one to see its detail.</p>
<p>Remember to reload or start Evennia, and then go to <a class="reference external" href="http://localhost:4001/help/">http://localhost:4001/help</a>. You should see the list of commands and topics accessible by all characters. Try to login (click the “login” link in the menu of your website) and go to the same page again. You should now see a more detailed list of commands and help entries. Click on one to see its detail.</p>
</section>
</section>
<section id="to-improve-this-feature">
<h2>To improve this feature<a class="headerlink" href="#to-improve-this-feature" title="Permalink to this headline"></a></h2>
<p>As always, a tutorial is here to help you feel comfortable adding new features and code by yourself.
Here are some ideas of things to improve this little feature:</p>
<p>As always, a tutorial is here to help you feel comfortable adding new features and code by yourself. Here are some ideas of things to improve this little feature:</p>
<ul class="simple">
<li><p>Links at the bottom of the detail template to go back to the index might be useful.</p></li>
<li><p>A link in the main menu to link to this page would be great… for the time being you have to
enter the URL, users wont guess its there.</p></li>
<li><p>A link in the main menu to link to this page would be great… for the time being you have to enter the URL, users wont guess its there.</p></li>
<li><p>Colors arent handled at this point, which isnt exactly surprising. You could add it though.</p></li>
<li><p>Linking help entries between one another wont be simple, but it would be great. For instance, if
you see a help entry about how to use several commands, it would be great if these commands were
themselves links to display their details.</p></li>
<li><p>Linking help entries between one another wont be simple, but it would be great. For instance, if you see a help entry about how to use several commands, it would be great if these commands were themselves links to display their details.</p></li>
</ul>
</section>
</section>
@ -613,7 +530,7 @@ themselves links to display their details.</p></li>
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" >Tutorials and How-Tos</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Help System Tutorial</a></li>
<li class="nav-item nav-item-this"><a href="">Web Help System Tutorial</a></li>
</ul>
</div>

View file

@ -318,7 +318,7 @@ over a web client if they are in a public place, and your websocket can also be
<li><p>The <a class="reference external" href="https://certbot.eff.org/">CertBot Client</a> is a program for automatically obtaining a certificate, use it and maintain it with your website.</p></li>
</ul>
<p>Also, on Freenode visit the #letsencrypt channel for assistance from the community. For an additional resource, Lets Encrypt has a very active <a class="reference external" href="https://community.letsencrypt.org/">community forum</a>.</p>
<p>[A blog where someone sets up Lets Encrypt](<a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-">https://www.digitalocean.com/community/tutorials/how-</a> to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04)</p>
<p><a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04">A blog where someone sets up Lets Encrypt</a></p>
<p>The only process missing from all of the above documentation is how to pass verification. This is how Lets Encrypt verifies that you have control over your domain (not necessarily ownership, its Domain Validation (DV)). This can be done either with configuring a certain path on your web server or through a TXT record in your DNS. Which one you will want to do is a personal preference, but can also be based on your hosting choice. In a controlled/cPanel environment, you will most likely have to use DNS verification.</p>
</section>
<section id="relevant-ssl-proxy-setup-information">

View file

@ -3,7 +3,10 @@
## Evennia main branch
- Contrib: Large-language-model (LLM) AI integration; allows NPCs to talk using
responses from a neural network server.
responses from an LLM server.
- Fix: Make sure `at_server_reload` is called also on non-repeating Scripts.
- Fix: Webclient was not giving a proper error when sending an unknown outputfunc to it.
- Documentation fixes.
## Evennia 2.1.0

View file

@ -3,23 +3,11 @@
## Introduction
This tutorial will create a simple web-based interface for generating a new in-game Character.
Accounts will need to have first logged into the website (with their `AccountDB` account). Once
finishing character generation the Character will be created immediately and the Accounts can then
log into the game and play immediately (the Character will not require staff approval or anything
like that). This guide does not go over how to create an AccountDB on the website with the right
permissions to transfer to their web-created characters.
This tutorial will create a simple web-based interface for generating a new in-game Character. Accounts will need to have first logged into the website (with their `AccountDB` account). Once finishing character generation the Character will be created immediately and the Accounts can then log into the game and play immediately (the Character will not require staff approval or anything like that). This guide does not go over how to create an AccountDB on the website with the right permissions to transfer to their web-created characters.
It is probably most useful to set `AUTO_CREATE_CHARACTER_WITH_ACCOUNT = False` so that all player
characters can be created through this.
It is probably most useful to set `AUTO_CREATE_CHARACTER_WITH_ACCOUNT = False` so that all player characters can be created through this.
You should have some familiarity with how Django sets up its Model Template View framework. You need
to understand what is happening in the basic [Web Character View tutorial](./Web-Character-View-Tutorial.md).
If you dont understand the listed tutorial or have a grasp of Django basics, please look at the
[Django tutorial](https://docs.djangoproject.com/en/4.1/intro/) to get a taste of what Django does,
before throwing Evennia into the mix (Evennia shares its API and attributes with the website
interface). This guide will outline the format of the models, views, urls, and html templates
needed.
You should have some familiarity with how Django sets up its Model Template View framework. You need to understand what is happening in the basic [Web Character View tutorial](./Web-Character-View-Tutorial.md). If you dont understand the listed tutorial or have a grasp of Django basics, please look at the [Django tutorial](https://docs.djangoproject.com/en/4.1/intro/) to get a taste of what Django does, before throwing Evennia into the mix (Evennia shares its API and attributes with the website interface). This guide will outline the format of the models, views, urls, and html templates needed.
## Pictures
@ -31,22 +19,19 @@ Index page, with no character application yet done:
![Index page, with no character application yet done.](https://lh3.googleusercontent.com/-57KuSWHXQ_M/VWcULN152tI/AAAAAAAAEZg/kINTmVlHf6M/w425-h189-no/webchargen_index2.gif)
***
Having clicked the "create" link you get to create your character (here we will only have name and
background, you can add whatever is needed to fit your game):
Having clicked the "create" link you get to create your character (here we will only have name and background, you can add whatever is needed to fit your game):
***
![Character creation.](https://lh3.googleusercontent.com/-ORiOEM2R_yQ/VWcUKgy84rI/AAAAAAAAEZY/B3CBh3FHii4/w607-h60-no/webchargen_creation.gif)
***
Back to the index page. Having entered our character application (we called our character "TestApp")
you see it listed:
Back to the index page. Having entered our character application (we called our character "TestApp") you see it listed:
***
![Having entered an application.](https://lh6.googleusercontent.com/-HlxvkvAimj4/VWcUKjFxEiI/AAAAAAAAEZo/gLppebr05JI/w321-h194-no/webchargen_index1.gif)
***
We can also view an already written character application by clicking on it - this brings us to the
*detail* page:
We can also view an already written character application by clicking on it - this brings us to the *detail* page:
***
![Detail view of character application.](https://lh6.googleusercontent.com/-2m1UhSE7s_k/VWcUKfLRfII/AAAAAAAAEZc/UFmBOqVya4k/w267-h175-no/webchargen_detail.gif)
@ -56,21 +41,17 @@ We can also view an already written character application by clicking on it - th
Assuming your game is named "mygame", navigate to your `mygame/` directory, and type:
cd web
evennia startapp chargen
This will initialize a new Django app we choose to call "chargen". It is directory containing some
basic starting things Django needs. You will need to move this directory: for the time being, it is
in your `mygame` directory. Better to move it in your `mygame/web` directory, so you have
`mygame/web/chargen` in the end.
This will initialize a new Django app we choose to call "chargen" in `mygame/web/`. We put it under `web/` to keep all web stuff together, but you can organize however you like. It is directory containing some basic starting things Django needs.
Next, navigate to `mygame/server/conf/settings.py` and add or edit the following line to make
Evennia (and Django) aware of our new app:
Next, navigate to `mygame/server/conf/settings.py` and add or edit the following line to make Evennia (and Django) aware of our new app:
INSTALLED_APPS += ('web.chargen',)
After this, we will get into defining our *models* (the description of the database storage),
*views* (the server-side website content generators), *urls* (how the web browser finds the pages)
and *templates* (how the web page should be structured).
*views* (the server-side website content generators), *urls* (how the web browser finds the pages) and *templates* (how the web page should be structured).
### Installing - Checkpoint:
@ -82,12 +63,9 @@ and *templates* (how the web page should be structured).
Models are created in `mygame/web/chargen/models.py`.
A [Django database model](../Concepts/Models.md) is a Python class that describes the database storage of the
data you want to manage. Any data you choose to store is stored in the same database as the game and
you have access to all the game's objects here.
We need to define what a character application actually is. This will differ from game to game so
for this tutorial we will define a simple character sheet with the following database fields:
data you want to manage. Any data you choose to store is stored in the same database as the game and you have access to all the game's objects here.
We need to define what a character application actually is. This will differ from game to game so for this tutorial we will define a simple character sheet with the following database fields:
* `app_id` (AutoField): Primary key for this character application sheet.
* `char_name` (CharField): The new character's name.
@ -97,8 +75,7 @@ for this tutorial we will define a simple character sheet with the following dat
AccountID from the AccountDB object.
* `submitted` (BooleanField): `True`/`False` depending on if the application has been submitted yet.
> Note: In a full-fledged game, youd likely want them to be able to select races, skills,
attributes and so on.
> Note: In a full-fledged game, youd likely want them to be able to select races, skills, attributes and so on.
Our `models.py` file should look something like this:
@ -116,28 +93,20 @@ class CharApp(models.Model):
submitted = models.BooleanField(default=False)
```
You should consider how you are going to link your application to your account. For this tutorial,
we are using the account_id attribute on our character application model in order to keep track of
which characters are owned by which accounts. Since the account id is a primary key in Evennia, it
is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use
anything else, but for the purposes of this guide, we are going to use account ID to join the
character applications with the proper account.
You should consider how you are going to link your application to your account. For this tutorial, we are using the account_id attribute on our character application model in order to keep track of which characters are owned by which accounts. Since the account id is a primary key in Evennia, it is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use anything else, but for the purposes of this guide, we are going to use account ID to join the character applications with the proper account.
### Model - Checkpoint:
* you should have filled out `mygame/web/chargen/models.py` with the model class shown above
(eventually adding fields matching what you need for your game).
* you should have filled out `mygame/web/chargen/models.py` with the model class shown above (eventually adding fields matching what you need for your game).
## Create Views
*Views* are server-side constructs that make dynamic data available to a web page. We are going to
add them to `mygame/web/chargen.views.py`. Each view in our example represents the backbone of a
*Views* are server-side constructs that make dynamic data available to a web page. We are going to add them to `mygame/web/chargen.views.py`. Each view in our example represents the backbone of a
specific web page. We will use three views and three pages here:
* The index (managing `index.html`). This is what you see when you navigate to
`http://yoursite.com/chargen`.
* The detail display sheet (manages `detail.html`). A page that passively displays the stats of a
given Character.
* The detail display sheet (manages `detail.html`). A page that passively displays the stats of a given Character.
* Character creation sheet (manages `create.html`). This is the main form with fields to fill in.
### *Index* view
@ -163,14 +132,12 @@ def index(request):
### *Detail* view
Our detail page will have pertinent character application information our users can see. Since this
is a basic demonstration, our detail page will only show two fields:
Our detail page will have pertinent character application information our users can see. Since this is a basic demonstration, our detail page will only show two fields:
* Character name
* Character background
We will use the account ID again just to double-check that whoever tries to check our character page
is actually the account who owns the application.
We will use the account ID again just to double-check that whoever tries to check our character page is actually the account who owns the application.
```python
# file mygame/web/chargen.views.py
@ -188,12 +155,9 @@ def detail(request, app_id):
## *Creating* view
Predictably, our *create* function will be the most complicated of the views, as it needs to accept
information from the user, validate the information, and send the information to the server. Once
the form content is validated will actually create a playable Character.
Predictably, our *create* function will be the most complicated of the views, as it needs to accept information from the user, validate the information, and send the information to the server. Once the form content is validated will actually create a playable Character.
The form itself we will define first. In our simple example we are just looking for the Character's
name and background. This form we create in `mygame/web/chargen/forms.py`:
The form itself we will define first. In our simple example we are just looking for the Character's name and background. This form we create in `mygame/web/chargen/forms.py`:
```python
# file mygame/web/chargen/forms.py
@ -258,10 +222,7 @@ def creating(request):
return render(request, 'chargen/create.html', {'form': form})
```
> Note also that we basically create the character using the Evennia API, and we grab the proper
permissions from the `AccountDB` object and copy them to the character object. We take the user
permissions attribute and turn that list of strings into a string object in order for the
create_object function to properly process the permissions.
> Note also that we basically create the character using the Evennia API, and we grab the proper permissions from the `AccountDB` object and copy them to the character object. We take the user permissions attribute and turn that list of strings into a string object in order for the create_object function to properly process the permissions.
Most importantly, the following attributes must be set on the created character object:
@ -271,10 +232,7 @@ Most importantly, the following attributes must be set on the created character
* Character name (key)
* The Character's home room location (`#2` by default)
Other attributes are strictly speaking optional, such as the `background` attribute on our
character. It may be a good idea to decompose this function and create a separate _create_character
function in order to set up your character object the account owns. But with the Evennia API,
setting custom attributes is as easy as doing it in the meat of your Evennia game directory.
Other attributes are strictly speaking optional, such as the `background` attribute on our character. It may be a good idea to decompose this function and create a separate _create_character function in order to set up your character object the account owns. But with the Evennia API, setting custom attributes is as easy as doing it in the meat of your Evennia game directory.
After all of this, our `views.py` file should look like something like this:
@ -351,14 +309,12 @@ def creating(request):
### Create Views - Checkpoint:
* youve defined a `views.py` that has an index, detail, and creating functions.
* youve defined a forms.py with the `AppForm` class needed by the `creating` function of
`views.py`.
* youve defined a forms.py with the `AppForm` class needed by the `creating` function of `views.py`.
* your `mygame/web/chargen` directory should now have a `views.py` and `forms.py` file
## Create URLs
URL patterns helps redirect requests from the web browser to the right views. These patterns are
created in `mygame/web/chargen/urls.py`.
URL patterns helps redirect requests from the web browser to the right views. These patterns are created in `mygame/web/chargen/urls.py`.
```python
# file mygame/web/chargen/urls.py
@ -376,13 +332,9 @@ urlpatterns = [
]
```
You could change the format as you desire. To make it more secure, you could remove app_id from the
"detail" url, and instead just fetch the accounts applications using a unifying field like
account_id to find all the character application objects to display.
You could change the format as you desire. To make it more secure, you could remove app_id from the "detail" url, and instead just fetch the accounts applications using a unifying field like account_id to find all the character application objects to display.
To add this to our website, we must also update the main `mygame/website/urls.py` file; this
will help tying our new chargen app in with the rest of the website. `urlpatterns` variable, and
change it to include:
To add this to our website, we must also update the main `mygame/website/urls.py` file; this will help tying our new chargen app in with the rest of the website. `urlpatterns` variable, and change it to include:
```python
# in file mygame/website/urls.py
@ -403,21 +355,15 @@ urlpatterns = [
## HTML Templates
So we have our url patterns, views, and models defined. Now we must define our HTML templates that
the actual user will see and interact with. For this tutorial we us the basic *prosimii* template
that comes with Evennia.
So we have our url patterns, views, and models defined. Now we must define our HTML templates that the actual user will see and interact with. For this tutorial we us the basic *prosimii* template that comes with Evennia.
Take note that we use `user.is_authenticated` to make sure that the user cannot create a character
without logging in.
Take note that we use `user.is_authenticated` to make sure that the user cannot create a character without logging in.
These files will all go into the `/mygame/web/chargen/templates/chargen/` directory.
### index.html
This HTML template should hold a list of all the applications the account currently has active. For
this demonstration, we will only list the applications that the account has submitted. You could
easily adjust this to include saved applications, or other types of applications if you have
different kinds.
This HTML template should hold a list of all the applications the account currently has active. For this demonstration, we will only list the applications that the account has submitted. You could easily adjust this to include saved applications, or other types of applications if you have different kinds.
Please refer back to `views.py` to see where we define the variables these templates make use of.
@ -445,10 +391,7 @@ Please refer back to `views.py` to see where we define the variables these templ
### detail.html
This page should show a detailed character sheet of their application. This will only show their
name and character background. You will likely want to extend this to show many more fields for your
game. In a full-fledged character generation, you may want to extend the boolean attribute of
submitted to allow accounts to save character applications and submit them later.
This page should show a detailed character sheet of their application. This will only show their name and character background. You will likely want to extend this to show many more fields for your game. In a full-fledged character generation, you may want to extend the boolean attribute of submitted to allow accounts to save character applications and submit them later.
```html
<!-- file mygame/web/chargen/templates/chargen/detail.html-->
@ -473,11 +416,7 @@ submitted to allow accounts to save character applications and submit them later
### create.html
Our create HTML template will use the Django form we defined back in views.py/forms.py to drive the
majority of the application process. There will be a form input for every field we defined in
forms.py, which is handy. We have used POST as our method because we are sending information to the
server that will update the database. As an alternative, GET would be much less secure. You can read
up on documentation elsewhere on the web for GET vs. POST.
Our create HTML template will use the Django form we defined back in views.py/forms.py to drive the majority of the application process. There will be a form input for every field we defined in forms.py, which is handy. We have used POST as our method because we are sending information to the server that will update the database. As an alternative, GET would be much less secure. You can read up on documentation elsewhere on the web for GET vs. POST.
```html
<!-- file mygame/web/chargen/templates/chargen/create.html-->
@ -499,8 +438,7 @@ up on documentation elsewhere on the web for GET vs. POST.
### Templates - Checkpoint:
* Create a `index.html`, `detail.html` and `create.html` template in your
`mygame/web/chargen/templates/chargen` directory
* Create a `index.html`, `detail.html` and `create.html` template in your `mygame/web/chargen/templates/chargen` directory
## Activating your new character generation
@ -523,49 +461,30 @@ evennia makemigrations
evennia migrate
```
This will create and update the models. If you see any errors at this stage, read the traceback
carefully, it should be relatively easy to figure out where the error is.
This will create and update the models. If you see any errors at this stage, read the traceback carefully, it should be relatively easy to figure out where the error is.
Login to the website (you need to have previously registered an Player account with the game to do
this). Next you navigate to `http://yourwebsite.com/chargen` (if you are running locally this will
be something like `http://localhost:4001/chargen` and you will see your new app in action.
Login to the website (you need to have previously registered an Player account with the game to do this). Next you navigate to `http://yourwebsite.com/chargen` (if you are running locally this will be something like `http://localhost:4001/chargen` and you will see your new app in action.
This should hopefully give you a good starting point in figuring out how youd like to approach your
own web generation. The main difficulties are in setting the appropriate settings on your newly
created character object. Thankfully, the Evennia API makes this easy.
This should hopefully give you a good starting point in figuring out how youd like to approach your own web generation. The main difficulties are in setting the appropriate settings on your newly created character object. Thankfully, the Evennia API makes this easy.
## Adding a no CAPCHA reCAPCHA on your character generation
As sad as it is, if your server is open to the web, bots might come to visit and take advantage of
your open form to create hundreds, thousands, millions of characters if you give them the
opportunity. This section shows you how to use the [No CAPCHA
reCAPCHA](https://www.google.com/recaptcha/intro/invisible.html) designed by Google. Not only is it
easy to use, it is user-friendly... for humans. A simple checkbox to check, except if Google has
some suspicion, in which case you will have a more difficult test with an image and the usual text
inside. It's worth pointing out that, as long as Google doesn't suspect you of being a robot, this
is quite useful, not only for common users, but to screen-reader users, to which reading inside of
an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in
your website.
As sad as it is, if your server is open to the web, bots might come to visit and take advantage of your open form to create hundreds, thousands, millions of characters if you give them the opportunity. This section shows you how to use the [No CAPCHA
reCAPCHA](https://www.google.com/recaptcha/intro/invisible.html) designed by Google. Not only is it easy to use, it is user-friendly... for humans. A simple checkbox to check, except if Google has some suspicion, in which case you will have a more difficult test with an image and the usual text inside. It's worth pointing out that, as long as Google doesn't suspect you of being a robot, this is quite useful, not only for common users, but to screen-reader users, to which reading inside of an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in your website.
### Step 1: Obtain a SiteKey and secret from Google
The first thing is to ask Google for a way to safely authenticate your website to their service. To
do it, we need to create a site key and a secret. Go to
[https://www.google.com/recaptcha/admin](https://www.google.com/recaptcha/admin) to create such a
site key. It's quite easy when you have a Google account.
The first thing is to ask Google for a way to safely authenticate your website to their service. To do it, we need to create a site key and a secret. Go to [https://www.google.com/recaptcha/admin](https://www.google.com/recaptcha/admin) to create such a site key. It's quite easy when you have a Google account.
When you have created your site key, save it safely. Also copy your secret key as well. You should
find both information on the web page. Both would contain a lot of letters and figures.
When you have created your site key, save it safely. Also copy your secret key as well. You should find both information on the web page. Both would contain a lot of letters and figures.
### Step 2: installing and configuring the dedicated Django app
Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to
install the dedicated Django app. Quite easy:
Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to install the dedicated Django app. Quite easy:
pip install django-nocaptcha-recaptcha
And add it to the installed apps in your settings. In your `mygame/server/conf/settings.py`, you
might have something like this:
And add it to the installed apps in your settings. In your `mygame/server/conf/settings.py`, you might have something like this:
```python
# ...
@ -575,8 +494,7 @@ INSTALLED_APPS += (
)
```
Don't close the setting file just yet. We have to add in the site key and secret key. You can add
them below:
Don't close the setting file just yet. We have to add in the site key and secret key. You can add them below:
```python
# NoReCAPCHA site key
@ -587,9 +505,7 @@ NORECAPTCHA_SECRET_KEY = "PUT YOUR SECRET KEY HERE"
### Step 3: Adding the CAPCHA to our form
Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your
`web/chargen/forms.py` file. We're going to add a new field, but hopefully, all the hard work has
been done for us. Update at your convenience, You might end up with something like this:
Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your `web/chargen/forms.py` file. We're going to add a new field, but hopefully, all the hard work has been done for us. Update at your convenience, You might end up with something like this:
```python
from django import forms
@ -610,9 +526,7 @@ And lastly, we need to update our HTML file to add in the Google library. You c
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
```
And you should put it at the bottom of the page. Just before the closing body would be good, but
for the time being, the base page doesn't provide a footer block, so we'll put it in the content
block. Note that it's not the best place, but it will work. In the end, your
And you should put it at the bottom of the page. Just before the closing body would be good, but for the time being, the base page doesn't provide a footer block, so we'll put it in the content block. Note that it's not the best place, but it will work. In the end, your
`web/chargen/templates/chargen/create.html` file should look like this:
```html
@ -632,6 +546,4 @@ block. Note that it's not the best place, but it will work. In the end, your
{% endblock %}
```
Reload and open [http://localhost:4001/chargen/create](http://localhost:4001/chargen/create/) and
you should see your beautiful CAPCHA just before the "submit" button. Try not to check the checkbox
to see what happens. And do the same while checking the checkbox!
Reload and open [http://localhost:4001/chargen/create](http://localhost:4001/chargen/create/) and you should see your beautiful CAPCHA just before the "submit" button. Try not to check the checkbox to see what happens. And do the same while checking the checkbox!

View file

@ -1,40 +1,27 @@
# Web Character View Tutorial
**Before doing this tutorial you will probably want to read the intro in [Basic Web tutorial](Web- Tutorial).**
**Before doing this tutorial you will probably want to read the intro in [Changing The Web Page tutorial](./Web-Changing-Webpage.md).**
In this tutorial we will create a web page that displays the stats of a game character. For this,
and all other pages we want to make specific to our game, we'll need to create our own Django "app"
We'll call our app `character`, since it will be dealing with character information. From your game
dir, run
In this tutorial we will create a web page that displays the stats of a game character. For this, and all other pages we want to make specific to our game, we'll need to create our own Django "app". We'll call our app `character`, since it will be dealing with character information. From your game dir, run
cd web
evennia startapp character
This will create a directory named `character` in the root of your game dir. It contains all basic
files that a Django app needs. To keep `mygame` well ordered, move it to your `mygame/web/`
directory instead:
This will create a new directory named `character` inside `mygame/web/`. We put it in `web/` to keep things tidy, but you could place it wherever you like. It contains all basic files that a Django app needs.
mv character web/
Note that we will not edit all files in this new directory, many of the generated files are outside the scope of this tutorial.
Note that we will not edit all files in this new directory, many of the generated files are outside
the scope of this tutorial.
In order for Django to find our new web app, we'll need to add it to the `INSTALLED_APPS` setting.
Evennia's default installed apps are already set, so in `server/conf/settings.py`, we'll just extend
them:
In order for Django to find our new web app, we'll need to add it to the `INSTALLED_APPS` setting. Evennia's default installed apps are already set, so in `server/conf/settings.py`, we'll just extend them:
```python
INSTALLED_APPS += ('web.character',)
```
> Note: That end comma is important. It makes sure that Python interprets the addition as a tuple
instead of a string.
> Note: That end comma is important. It makes sure that Python interprets the addition as a tuple instead of a string.
The first thing we need to do is to create a *view* and an *URL pattern* to point to it. A view is a
function that generates the web page that a visitor wants to see, while the URL pattern lets Django
know what URL should trigger the view. The pattern may also provide some information of its own as
we shall see.
function that generates the web page that a visitor wants to see, while the URL pattern lets Django know what URL should trigger the view. The pattern may also provide some information of its own as we shall see.
Here is our `character/urls.py` file (**Note**: you may have to create this file if a blank one
wasn't generated for you):
@ -52,32 +39,15 @@ urlpatterns = [
This file contains all of the URL patterns for the application. The `url` function in the
`urlpatterns` list are given three arguments. The first argument is a pattern-string used to
identify which URLs are valid. Patterns are specified as *regular expressions*. Regular expressions
are used to match strings and are written in a special, very compact, syntax. A detailed description
of regular expressions is beyond this tutorial but you can learn more about them
[here](https://docs.python.org/2/howto/regex.html). For now, just accept that this regular
expression requires that the visitor's URL looks something like this:
identify which URLs are valid. Patterns are specified as *regular expressions*. Regular expressions are used to match strings and are written in a special, very compact, syntax. A detailed description of regular expressions is beyond this tutorial but you can learn more about them [here](https://docs.python.org/2/howto/regex.html). For now, just accept that this regular expression requires that the visitor's URL looks something like this:
````
sheet/123/
````
That is, `sheet/` followed by a number, rather than some other possible URL pattern. We will
interpret this number as object ID. Thanks to how the regular expression is formulated, the pattern
recognizer stores the number in a variable called `object_id`. This will be passed to the view (see
below). We add the imported view function (`sheet`) in the second argument. We also add the `name`
keyword to identify the URL pattern itself. You should always name your URL patterns, this makes
them easy to refer to in html templates using the `{% url %}` tag (but we won't get more into that
in this tutorial).
That is, `sheet/` followed by a number, rather than some other possible URL pattern. We will interpret this number as object ID. Thanks to how the regular expression is formulated, the pattern recognizer stores the number in a variable called `object_id`. This will be passed to the view (see below). We add the imported view function (`sheet`) in the second argument. We also add the `name` keyword to identify the URL pattern itself. You should always name your URL patterns, this makes them easy to refer to in html templates using the `{% url %}` tag (but we won't get more into that in this tutorial).
> Security Note: Normally, users do not have the ability to see object IDs within the game (it's
restricted to superusers only). Exposing the game's object IDs to the public like this enables
griefers to perform what is known as an [account enumeration
attack](http://www.sans.edu/research/security-laboratory/article/attacks-browsing) in the efforts of
hijacking your superuser account. Consider this: in every Evennia installation, there are two
objects that we can *always* expect to exist and have the same object IDs-- Limbo (#2) and the
superuser you create in the beginning (#1). Thus, the griefer can get 50% of the information they
need to hijack the admin account (the admin's username) just by navigating to `sheet/1`!
> Security Note: Normally, users do not have the ability to see object IDs within the game (it's restricted to superusers only). Exposing the game's object IDs to the public like this enables griefers to perform what is known as an [account enumeration attack](http://www.sans.edu/research/security-laboratory/article/attacks-browsing) in the efforts of hijacking your superuser account. Consider this: in every Evennia installation, there are two objects that we can *always* expect to exist and have the same object IDs-- Limbo (#2) and the superuser you create in the beginning (#1). Thus, the griefer can get 50% of the information they need to hijack the admin account (the admin's username) just by navigating to `sheet/1`!
Next we create `views.py`, the view file that `urls.py` refers to.
@ -103,20 +73,12 @@ def sheet(request, object_id):
return render(request, 'character/sheet.html', {'character': character})
```
As explained earlier, the URL pattern parser in `urls.py` parses the URL and passes `object_id` to
our view function `sheet`. We do a database search for the object using this number. We also make
sure such an object exists and that it is actually a Character. The view function is also handed a
`request` object. This gives us information about the request, such as if a logged-in user viewed it
- we won't use that information here but it is good to keep in mind.
As explained earlier, the URL pattern parser in `urls.py` parses the URL and passes `object_id` to our view function `sheet`. We do a database search for the object using this number. We also make sure such an object exists and that it is actually a Character. The view function is also handed a `request` object. This gives us information about the request, such as if a logged-in user viewed it - we won't use that information here but it is good to keep in mind.
On the last line, we call the `render` function. Apart from the `request` object, the `render`
function takes a path to an html template and a dictionary with extra data you want to pass into
said template. As extra data we pass the Character object we just found. In the template it will be
available as the variable "character".
function takes a path to an html template and a dictionary with extra data you want to pass into said template. As extra data we pass the Character object we just found. In the template it will be available as the variable "character".
The html template is created as `templates/character/sheet.html` under your `character` app folder.
You may have to manually create both `template` and its subfolder `character`. Here's the template
to create:
The html template is created as `templates/character/sheet.html` under your `character` app folder. You may have to manually create both `template` and its subfolder `character`. Here's the template to create:
````html
{% extends "base.html" %}
@ -167,32 +129,19 @@ to create:
{% endblock %}
````
In Django templates, `{% ... %}` denotes special in-template "functions" that Django understands.
The `{{ ... }}` blocks work as "slots". They are replaced with whatever value the code inside the
block returns.
In Django templates, `{% ... %}` denotes special in-template "functions" that Django understands. The `{{ ... }}` blocks work as "slots". They are replaced with whatever value the code inside the block returns.
The first line, `{% extends "base.html" %}`, tells Django that this template extends the base
template that Evennia is using. The base template is provided by the theme. Evennia comes with the
open-source third-party theme `prosimii`. You can find it and its `base.html` in
The first line, `{% extends "base.html" %}`, tells Django that this template extends the base template that Evennia is using. The base template is provided by the theme. Evennia comes with the open-source third-party theme `prosimii`. You can find it and its `base.html` in
`evennia/web/templates/prosimii`. Like other templates, these can be overwritten.
The next line is `{% block content %}`. The `base.html` file has `block`s, which are placeholders
that templates can extend. The main block, and the one we use, is named `content`.
We can access the `character` variable anywhere in the template because we passed it in the `render`
call at the end of `view.py`. That means we also have access to the Character's `db` attributes,
much like you would in normal Python code. You don't have the ability to call functions with
arguments in the template-- in fact, if you need to do any complicated logic, you should do it in
`view.py` and pass the results as more variables to the template. But you still have a great deal of
flexibility in how you display the data.
We can access the `character` variable anywhere in the template because we passed it in the `render` call at the end of `view.py`. That means we also have access to the Character's `db` attributes, much like you would in normal Python code. You don't have the ability to call functions with arguments in the template-- in fact, if you need to do any complicated logic, you should do it in `view.py` and pass the results as more variables to the template. But you still have a great deal of flexibility in how you display the data.
We can do a little bit of logic here as well. We use the `{% for %} ... {% endfor %}` and `{% if %}
... {% else %} ... {% endif %}` structures to change how the template renders depending on how many
skills the user has, or if the user is approved (assuming your game has an approval system).
We can do a little bit of logic here as well. We use the `{% for %} ... {% endfor %}` and `{% if %} ... {% else %} ... {% endif %}` structures to change how the template renders depending on how many skills the user has, or if the user is approved (assuming your game has an approval system).
The last file we need to edit is the master URLs file. This is needed in order to smoothly integrate
the URLs from your new `character` app with the URLs from Evennia's existing pages. Find the file
`web/website/urls.py` and update its `patterns` list as follows:
The last file we need to edit is the master URLs file. This is needed in order to smoothly integrate the URLs from your new `character` app with the URLs from Evennia's existing pages. Find the file `web/website/urls.py` and update its `patterns` list as follows:
```python
# web/website/urls.py
@ -207,11 +156,9 @@ Now reload the server with `evennia reload` and visit the page in your browser.
changed your defaults, you should be able to find the sheet for character `#1` at
`http://localhost:4001/character/sheet/1/`
Try updating the stats in-game and refresh the page in your browser. The results should show
immediately.
Try updating the stats in-game and refresh the page in your browser. The results should show immediately.
As an optional final step, you can also change your character typeclass to have a method called
'get_absolute_url'.
As an optional final step, you can also change your character typeclass to have a method called 'get_absolute_url'.
```python
# typeclasses/characters.py
@ -221,9 +168,7 @@ As an optional final step, you can also change your character typeclass to have
return reverse('character:sheet', kwargs={'object_id':self.id})
```
Doing so will give you a 'view on site' button in the top right of the Django Admin Objects
changepage that links to your new character sheet, and allow you to get the link to a character's
page by using `{{ object.get_absolute_url }}` in any template where you have a given object.
changepage that links to your new character sheet, and allow you to get the link to a character's page by using `{{ object.get_absolute_url }}` in any template where you have a given object.
*Now that you've made a basic page and app with Django, you may want to read the full Django
tutorial to get a better idea of what it can do. [You can find Django's tutorial
*Now that you've made a basic page and app with Django, you may want to read the full Django tutorial to get a better idea of what it can do. [You can find Django's tutorial
here](https://docs.djangoproject.com/en/4.1/intro/tutorial01/).*

View file

@ -1,10 +1,9 @@
# Help System Tutorial
# Web Help System Tutorial
**Before doing this tutorial you will probably want to read the intro in [Basic Web tutorial](Web- Tutorial).** Reading the three first parts of the [Django tutorial](https://docs.djangoproject.com/en/4.0/intro/tutorial01/) might help as well.
**Before doing this tutorial you will probably want to read the intro in the [Changing the Web page tutorial](./Web-Changing-Webpage.md).** Reading the three first parts of the [Django tutorial](https://docs.djangoproject.com/en/4.0/intro/tutorial01/) might help as well.
This tutorial will show you how to access the help system through your website. Both help commands
and regular help entries will be visible, depending on the logged-in user or an anonymous character.
This tutorial will show you how to access the help system through your website. Both help commands and regular help entries will be visible, depending on the logged-in user or an anonymous character.
This tutorial will show you how to:
@ -15,23 +14,16 @@ This tutorial will show you how to:
## Creating our app
The first step is to create our new Django *app*. An app in Django can contain pages and
mechanisms: your website may contain different apps. Actually, the website provided out-of-the-box
by Evennia has already three apps: a "webclient" app, to handle the entire webclient, a "website"
app to contain your basic pages, and a third app provided by Django to create a simple admin
interface. So we'll create another app in parallel, giving it a clear name to represent our help
system.
The first step is to create our new Django *app*. An app in Django can contain pages and mechanisms: your website may contain different apps. Actually, the website provided out-of-the-box by Evennia has already three apps: a "webclient" app, to handle the entire webclient, a "website" app to contain your basic pages, and a third app provided by Django to create a simple admin interface. So we'll create another app in parallel, giving it a clear name to represent our help system.
From your game directory, use the following command:
From your game directory, use the following commands:
cd web
evennia startapp help_system
> Note: calling the app "help" would have been more explicit, but this name is already used by
Django.
> Note: calling the app "help" would have been more explicit, but this name is already used by Django.
This will create a directory named `help_system` at the root of your game directory. It's a good
idea to keep things organized and move this directory in the "web" directory of your game. Your
game directory should look like:
This will create a directory named `help_system` under `mygame/web/`. We put it there to keep all web-related things together, but you can organize however you like. Here's how the structure looks:
mygame/
...
@ -39,13 +31,9 @@ game directory should look like:
help_system/
...
The "web/help_system" directory contains files created by Django. We'll use some of them, but if
you want to learn more about them all, you should read [the Django
tutorial](https://docs.djangoproject.com/en/4.1/intro/tutorial01/).
The "web/help_system" directory contains files created by Django. We'll use some of them, but if you want to learn more about them all, you should read [the Django tutorial](https://docs.djangoproject.com/en/4.1/intro/tutorial01/).
There is a last thing to be done: your folder has been added, but Django doesn't know about it, it
doesn't know it's a new app. We need to tell it, and we do so by editing a simple setting. Open
your "server/conf/settings.py" file and add, or edit, these lines:
There is a last thing to be done: your folder has been added, but Django doesn't know about it, it doesn't know it's a new app. We need to tell it, and we do so by editing a simple setting. Open your "server/conf/settings.py" file and add, or edit, these lines:
```python
# Web configuration
@ -54,30 +42,24 @@ INSTALLED_APPS += (
)
```
You can start Evennia if you want, and go to your website, probably at
[http://localhost:4001](http://localhost:4001) . You won't see anything different though: we added
the app but it's fairly empty.
You can start Evennia if you want, and go to your website, probably at [http://localhost:4001](http://localhost:4001) . You won't see anything different though: we added the app but it's fairly empty.
## Our new page
At this point, our new *app* contains mostly empty files that you can explore. In order to create
a page for our help system, we need to add:
At this point, our new *app* contains mostly empty files that you can explore. In order to create a page for our help system, we need to add:
- A *view*, dealing with the logic of our page.
- A *template* to display our new page.
- A new *URL* pointing to our page.
> We could get away by creating just a view and a new URL, but that's not a recommended way to work
with your website. Building on templates is so much more convenient.
> We could get away by creating just a view and a new URL, but that's not a recommended way to work with your website. Building on templates is so much more convenient.
### Create a view
A *view* in Django is a simple Python function placed in the "views.py" file in your app. It will
handle the behavior that is triggered when a user asks for this information by entering a *URL* (the
connection between *views* and *URLs* will be discussed later).
handle the behavior that is triggered when a user asks for this information by entering a *URL* (the connection between *views* and *URLs* will be discussed later).
So let's create our view. You can open the "web/help_system/views.py" file and paste the following
lines:
So let's create our view. You can open the "web/help_system/views.py" file and paste the following lines:
```python
from django.shortcuts import render
@ -87,16 +69,11 @@ def index(request):
return render(request, "help_system/index.html")
```
Our view handles all code logic. This time, there's not much: when this function is called, it will
render the template we will now create. But that's where we will do most of our work afterward.
Our view handles all code logic. This time, there's not much: when this function is called, it will render the template we will now create. But that's where we will do most of our work afterward.
### Create a template
The `render` function called into our *view* asks the *template* `help_system/index.html`. The
*templates* of our apps are stored in the app directory, "templates" sub-directory. Django may have
created the "templates" folder already. If not, create it yourself. In it, create another folder
"help_system", and inside of this folder, create a file named "index.html". Wow, that's some
hierarchy. Your directory structure (starting from `web`) should look like this:
The `render` function called into our *view* asks the *template* `help_system/index.html`. The *templates* of our apps are stored in the app directory, "templates" sub-directory. Django may have created the "templates" folder already. If not, create it yourself. In it, create another folder "help_system", and inside of this folder, create a file named "index.html". Wow, that's some hierarchy. Your directory structure (starting from `web`) should look like this:
web/
help_system/
@ -117,24 +94,17 @@ Open the "index.html" file and paste in the following lines:
Here's a little explanation line by line of what this template does:
1. It loads the "base.html" *template*. This describes the basic structure of all your pages, with
a menu at the top and a footer, and perhaps other information like images and things to be present
on each page. You can create templates that do not inherit from "base.html", but you should have a
good reason for doing so.
2. The "base.html" *template* defines all the structure of the page. What is left is to override
some sections of our pages. These sections are called *blocks*. On line 2, we override the block
named "blocktitle", which contains the title of our page.
3. Same thing here, we override the *block* named "content", which contains the main content of our
web page. This block is bigger, so we define it on several lines.
1. It loads the "base.html" *template*. This describes the basic structure of all your pages, with a menu at the top and a footer, and perhaps other information like images and things to be present on each page. You can create templates that do not inherit from "base.html", but you should have a good reason for doing so.
2. The "base.html" *template* defines all the structure of the page. What is left is to override some sections of our pages. These sections are called *blocks*. On line 2, we override the block named "blocktitle", which contains the title of our page.
3. Same thing here, we override the *block* named "content", which contains the main content of our web page. This block is bigger, so we define it on several lines.
4. This is perfectly normal HTML code to display a level-2 heading.
5. And finally we close the *block* named "content".
### Create a new URL
Last step to add our page: we need to add a *URL* leading to it... otherwise users won't be able to
access it. The URLs of our apps are stored in the app's directory "urls.py" file.
Last step to add our page: we need to add a *URL* leading to it... otherwise users won't be able to access it. The URLs of our apps are stored in the app's directory "urls.py" file.
Open the `web/help_system/urls.py` file (you might have to create it) and make it look like this.
Open the `web/help_system/urls.py` file (you might have to create it) and make it look like this:
```python
# URL patterns for the help_system app
@ -147,13 +117,9 @@ urlpatterns = [
]
```
The `urlpatterns` variable is what Django/Evennia looks for to figure out how to
direct a user entering an URL in their browser to the view-code you have
written.
The `urlpatterns` variable is what Django/Evennia looks for to figure out how to direct a user entering an URL in their browser to the view-code you have written.
Last we need to tie this into the main namespace for your game. Edit the file
`mygame/web/urls.py`. In it you will find the `urlpatterns` list again.
Add a new `path` to the end of the list.
Last we need to tie this into the main namespace for your game. Edit the file `mygame/web/urls.py`. In it you will find the `urlpatterns` list again. Add a new `path` to the end of the list.
```python
# mygame/web/urls.py
@ -177,21 +143,14 @@ urlpatterns = [
When a user will ask for a specific *URL* on your site, Django will:
1. Read the list of custom patterns defined in "web/urls.py". There's one pattern here, which
describes to Django that all URLs beginning by 'help/' should be sent to the 'help_system' app. The
'help/' part is removed.
2. Then Django will check the "web.help_system/urls.py" file. It contains only one URL, which is
empty (`^$`).
1. Read the list of custom patterns defined in "web/urls.py". There's one pattern here, which describes to Django that all URLs beginning by 'help/' should be sent to the 'help_system' app. The 'help/' part is removed.
2. Then Django will check the "web.help_system/urls.py" file. It contains only one URL, which is empty (`^$`).
In other words, if the URL is '/help/', then Django will execute our defined view.
### Let's see it work
You can now reload or start Evennia. Open a tab in your browser and go to
[http://localhost:4001/help/](http://localhost:4001/help/) . If everything goes well, you should
see your new page... which isn't empty since Evennia uses our "base.html" *template*. In the
content of our page, there's only a heading that reads "help index". Notice that the title of our
page is "mygame - Help index" ("mygame" is replaced by the name of your game).
You can now reload or start Evennia. Open a tab in your browser and go to [http://localhost:4001/help/](http://localhost:4001/help/) . If everything goes well, you should see your new page... which isn't empty since Evennia uses our "base.html" *template*. In the content of our page, there's only a heading that reads "help index". Notice that the title of our page is "mygame - Help index" ("mygame" is replaced by the name of your game).
From now on, it will be easier to move forward and add features.
@ -211,30 +170,17 @@ The first one would link to the second.
> Should we create two URLs?
The answer is... maybe. It depends on what you want to do. We have our help index accessible
through the "/help/" URL. We could have the detail of a help entry accessible through "/help/desc"
(to see the detail of the "desc" command). The problem is that our commands or help topics may
contain special characters that aren't to be present in URLs. There are different ways around this
problem. I have decided to use a *GET variable* here, which would create URLs like this:
The answer is... maybe. It depends on what you want to do. We have our help index accessible through the "/help/" URL. We could have the detail of a help entry accessible through "/help/desc" (to see the detail of the "desc" command). The problem is that our commands or help topics may contain special characters that aren't to be present in URLs. There are different ways around this problem. I have decided to use a *GET variable* here, which would create URLs like this:
/help?name=desc
If you use this system, you don't have to add a new URL: GET and POST variables are accessible
through our requests and we'll see how soon enough.
If you use this system, you don't have to add a new URL: GET and POST variables are accessible through our requests and we'll see how soon enough.
## Handling logged-in users
One of our requirements is to have a help system tailored to our accounts. If an account with admin
access logs in, the page should display a lot of commands that aren't accessible to common users.
And perhaps even some additional help topics.
One of our requirements is to have a help system tailored to our accounts. If an account with admin access logs in, the page should display a lot of commands that aren't accessible to common users. And perhaps even some additional help topics.
Fortunately, it's fairly easy to get the logged in account in our view (remember that we'll do most
of our coding there). The *request* object, passed to our function, contains a `user` attribute.
This attribute will always be there: we cannot test whether it's `None` or not, for instance. But
when the request comes from a user that isn't logged in, the `user` attribute will contain an
anonymous Django user. We then can use the `is_anonymous` method to see whether the user is logged-
in or not. Last gift by Evennia, if the user is logged in, `request.user` contains a reference to
an account object, which will help us a lot in coupling the game and online system.
Fortunately, it's fairly easy to get the logged in account in our view (remember that we'll do most of our coding there). The *request* object, passed to our function, contains a `user` attribute. This attribute will always be there: we cannot test whether it's `None` or not, for instance. But when the request comes from a user that isn't logged in, the `user` attribute will contain an anonymous Django user. We then can use the `is_anonymous` method to see whether the user is logged-in or not. Last gift by Evennia, if the user is logged in, `request.user` contains a reference to an account object, which will help us a lot in coupling the game and online system.
So we might end up with something like:
@ -246,8 +192,7 @@ def index(request):
character = user.character
```
> Note: this code works when your MULTISESSION_MODE is set to 0 or 1. When it's above, you would
have something like:
> Note: this code works when your MULTISESSION_MODE is set to 0 or 1. When it's above, you would have something like:
```python
def index(request):
@ -259,16 +204,14 @@ def index(request):
In this second case, it will select the first character of the account.
But what if the user's not logged in? Again, we have different solutions. One of the most simple
is to create a character that will behave as our default character for the help system. You can
create it through your game: connect to it and enter:
But what if the user's not logged in? Again, we have different solutions. One of the most simple is to create a character that will behave as our default character for the help system. You can create it through your game: connect to it and enter:
@charcreate anonymous
The system should answer:
Created new character anonymous. Use @ic anonymous to enter the game as this character.
Created new character anonymous. Use @ic anonymous to enter the game as this character.
So in our view, we could have something like this:
```python
@ -283,16 +226,13 @@ def index(request):
character = Character.objects.get(db_key="anonymous")
```
This time, we have a valid character no matter what: remember to adapt this code if you're running
in multisession mode above 1.
This time, we have a valid character no matter what: remember to adapt this code if you're running in multisession mode above 1.
## The full system
What we're going to do is to browse through all commands and help entries, and list all the commands
that can be seen by this character (either our 'anonymous' character, or our logged-in character).
What we're going to do is to browse through all commands and help entries, and list all the commands that can be seen by this character (either our 'anonymous' character, or our logged-in character).
The code is longer, but it presents the entire concept in our view. Edit the
"web/help_system/views.py" file and paste into it:
The code is longer, but it presents the entire concept in our view. Edit the "web/help_system/views.py" file and paste into it:
```python
from django.http import Http404
@ -386,26 +326,17 @@ def _get_topics(character):
That's a bit more complicated here, but all in all, it can be divided in small chunks:
- The `index` function is our view:
- It begins by getting the character as we saw in the previous section.
- It gets the help topics (commands and help entries) accessible to this character. It's another
function that handles that part.
- If there's a *GET variable* "name" in our URL (like "/help?name=drop"), it will retrieve it. If
it's not a valid topic's name, it returns a *404*. Otherwise, it renders the template called
"detail.html", to display the detail of our topic.
- If there's no *GET variable* "name", render "index.html", to display the list of topics.
- The `_get_topics` is a private function. Its sole mission is to retrieve the commands a character
can execute, and the help entries this same character can see. This code is more Evennia-specific
than Django-specific, it will not be detailed in this tutorial. Just notice that all help topics
are stored in a dictionary. This is to simplify our job when displaying them in our templates.
- It begins by getting the character as we saw in the previous section.
- It gets the help topics (commands and help entries) accessible to this character. It's another function that handles that part.
- If there's a *GET variable* "name" in our URL (like "/help?name=drop"), it will retrieve it. If it's not a valid topic's name, it returns a *404*. Otherwise, it renders the template called "detail.html", to display the detail of our topic.
- If there's no *GET variable* "name", render "index.html", to display the list of topics.
- The `_get_topics` is a private function. Its sole mission is to retrieve the commands a character can execute, and the help entries this same character can see. This code is more Evennia-specific than Django-specific, it will not be detailed in this tutorial. Just notice that all help topics are stored in a dictionary. This is to simplify our job when displaying them in our templates.
Notice that, in both cases when we asked to render a *template*, we passed to `render` a third
argument which is the dictionary of variables used in our templates. We can pass variables this
way, and we will use them in our templates.
Notice that, in both cases when we asked to render a *template*, we passed to `render` a third argument which is the dictionary of variables used in our templates. We can pass variables this way, and we will use them in our templates.
### The index template
Let's look at our full "index" *template*. You can open the
"web/help_system/templates/help_sstem/index.html" file and paste the following into it:
Let's look at our full "index" *template*. You can open the "web/help_system/templates/help_sstem/index.html" file and paste the following into it:
```
{% extends "base.html" %}
@ -436,17 +367,12 @@ This template is definitely more detailed. What it does is:
1. Browse through all categories.
2. For all categories, display a level-2 heading with the name of the category.
3. All topics in a category (remember, they can be either commands or help entries) are displayed in
a table. The trickier part may be that, when the loop is above 5, it will create a new line. The
table will have 5 columns at the most per row.
4. For every cell in the table, we create a link redirecting to the detail page (see below). The
URL would look something like "help?name=say". We use `urlencode` to ensure special characters are
properly escaped.
3. All topics in a category (remember, they can be either commands or help entries) are displayed in a table. The trickier part may be that, when the loop is above 5, it will create a new line. The table will have 5 columns at the most per row.
4. For every cell in the table, we create a link redirecting to the detail page (see below). The URL would look something like "help?name=say". We use `urlencode` to ensure special characters are properly escaped.
### The detail template
It's now time to show the detail of a topic (command or help entry). You can create the file
"web/help_system/templates/help_system/detail.html". You can paste into it the following code:
It's now time to show the detail of a topic (command or help entry). You can create the file "web/help_system/templates/help_system/detail.html". You can paste into it the following code:
```
{% extends "base.html" %}
@ -458,26 +384,17 @@ It's now time to show the detail of a topic (command or help entry). You can cr
{% endblock %}
```
This template is much easier to read. Some *filters* might be unknown to you, but they are just
used to format here.
This template is much easier to read. Some *filters* might be unknown to you, but they are just used to format here.
### Put it all together
Remember to reload or start Evennia, and then go to
[http://localhost:4001/help](http://localhost:4001/help/). You should see the list of commands and
topics accessible by all characters. Try to login (click the "login" link in the menu of your
website) and go to the same page again. You should now see a more detailed list of commands and
help entries. Click on one to see its detail.
Remember to reload or start Evennia, and then go to [http://localhost:4001/help](http://localhost:4001/help/). You should see the list of commands and topics accessible by all characters. Try to login (click the "login" link in the menu of your website) and go to the same page again. You should now see a more detailed list of commands and help entries. Click on one to see its detail.
## To improve this feature
As always, a tutorial is here to help you feel comfortable adding new features and code by yourself.
Here are some ideas of things to improve this little feature:
As always, a tutorial is here to help you feel comfortable adding new features and code by yourself. Here are some ideas of things to improve this little feature:
- Links at the bottom of the detail template to go back to the index might be useful.
- A link in the main menu to link to this page would be great... for the time being you have to
enter the URL, users won't guess it's there.
- A link in the main menu to link to this page would be great... for the time being you have to enter the URL, users won't guess it's there.
- Colors aren't handled at this point, which isn't exactly surprising. You could add it though.
- Linking help entries between one another won't be simple, but it would be great. For instance, if
you see a help entry about how to use several commands, it would be great if these commands were
themselves links to display their details.
- Linking help entries between one another won't be simple, but it would be great. For instance, if you see a help entry about how to use several commands, it would be great if these commands were themselves links to display their details.

View file

@ -192,11 +192,12 @@ WEBSOCKET_CLIENT_URL = "wss://fqdn:4002"
Also, on Freenode visit the #letsencrypt channel for assistance from the community. For an additional resource, Let's Encrypt has a very active [community forum](https://community.letsencrypt.org/).
[A blog where someone sets up Let's Encrypt](https://www.digitalocean.com/community/tutorials/how- to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04)
[A blog where someone sets up Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04)
The only process missing from all of the above documentation is how to pass verification. This is how Let's Encrypt verifies that you have control over your domain (not necessarily ownership, it's Domain Validation (DV)). This can be done either with configuring a certain path on your web server or through a TXT record in your DNS. Which one you will want to do is a personal preference, but can also be based on your hosting choice. In a controlled/cPanel environment, you will most likely have to use DNS verification.
### Relevant SSL Proxy Setup Information
- [Apache webserver configuration](./Config-Apache-Proxy.md) (optional)
- [HAProxy Config](./Config-HAProxy.md)

View file

@ -325,7 +325,7 @@ to accounts respectively.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.admin.CmdEmit.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['remit', 'pemit']</em><a class="headerlink" href="#evennia.commands.default.admin.CmdEmit.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['pemit', 'remit']</em><a class="headerlink" href="#evennia.commands.default.admin.CmdEmit.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -356,7 +356,7 @@ to accounts respectively.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.admin.CmdEmit.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'remit pemit', 'category': 'admin', 'key': 'emit', 'no_prefix': ' remit pemit', 'tags': '', 'text': '\n admin command for emitting message to multiple objects\n\n Usage:\n emit[/switches] [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n remit [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n pemit [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n\n Switches:\n room - limit emits to rooms only (default)\n accounts - limit emits to accounts only\n contents - send to the contents of matched objects too\n\n Emits a message to the selected objects or to\n your immediate surroundings. If the object is a room,\n send to its contents. remit and pemit are just\n limited forms of emit, for sending to rooms and\n to accounts respectively.\n '}</em><a class="headerlink" href="#evennia.commands.default.admin.CmdEmit.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'pemit remit', 'category': 'admin', 'key': 'emit', 'no_prefix': ' pemit remit', 'tags': '', 'text': '\n admin command for emitting message to multiple objects\n\n Usage:\n emit[/switches] [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n remit [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n pemit [&lt;obj&gt;, &lt;obj&gt;, ... =] &lt;message&gt;\n\n Switches:\n room - limit emits to rooms only (default)\n accounts - limit emits to accounts only\n contents - send to the contents of matched objects too\n\n Emits a message to the selected objects or to\n your immediate surroundings. If the object is a room,\n send to its contents. remit and pemit are just\n limited forms of emit, for sending to rooms and\n to accounts respectively.\n '}</em><a class="headerlink" href="#evennia.commands.default.admin.CmdEmit.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -146,7 +146,7 @@ skipping, reloading etc.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.batchprocess.CmdBatchCommands.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['batchcmd', 'batchcommand']</em><a class="headerlink" href="#evennia.commands.default.batchprocess.CmdBatchCommands.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['batchcommand', 'batchcmd']</em><a class="headerlink" href="#evennia.commands.default.batchprocess.CmdBatchCommands.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -177,7 +177,7 @@ skipping, reloading etc.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.batchprocess.CmdBatchCommands.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'batchcmd batchcommand', 'category': 'building', 'key': 'batchcommands', 'no_prefix': ' batchcmd batchcommand', 'tags': '', 'text': '\n build from batch-command file\n\n Usage:\n batchcommands[/interactive] &lt;python.path.to.file&gt;\n\n Switch:\n interactive - this mode will offer more control when\n executing the batch file, like stepping,\n skipping, reloading etc.\n\n Runs batches of commands from a batch-cmd text file (*.ev).\n\n '}</em><a class="headerlink" href="#evennia.commands.default.batchprocess.CmdBatchCommands.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'batchcommand batchcmd', 'category': 'building', 'key': 'batchcommands', 'no_prefix': ' batchcommand batchcmd', 'tags': '', 'text': '\n build from batch-command file\n\n Usage:\n batchcommands[/interactive] &lt;python.path.to.file&gt;\n\n Switch:\n interactive - this mode will offer more control when\n executing the batch file, like stepping,\n skipping, reloading etc.\n\n Runs batches of commands from a batch-cmd text file (*.ev).\n\n '}</em><a class="headerlink" href="#evennia.commands.default.batchprocess.CmdBatchCommands.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -1353,7 +1353,7 @@ server settings.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdTypeclass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;type', '&#64;swap', '&#64;typeclasses', '&#64;parent', '&#64;update']</em><a class="headerlink" href="#evennia.commands.default.building.CmdTypeclass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;typeclasses', '&#64;swap', '&#64;update', '&#64;type', '&#64;parent']</em><a class="headerlink" href="#evennia.commands.default.building.CmdTypeclass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -1384,7 +1384,7 @@ server settings.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdTypeclass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;type &#64;swap &#64;typeclasses &#64;parent &#64;update', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass type swap typeclasses parent update', 'tags': '', 'text': &quot;\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] &lt;object&gt; [= typeclass.path]\n typeclass/prototype &lt;object&gt; = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object. This will also\n reset cmdsets!\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.building.CmdTypeclass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;typeclasses &#64;swap &#64;update &#64;type &#64;parent', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass typeclasses swap update type parent', 'tags': '', 'text': &quot;\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] &lt;object&gt; [= typeclass.path]\n typeclass/prototype &lt;object&gt; = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object. This will also\n reset cmdsets!\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.building.CmdTypeclass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -1539,7 +1539,7 @@ If object is not specified, the current location is examined.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdExamine.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;exam', '&#64;ex']</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;ex', '&#64;exam']</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -1807,7 +1807,7 @@ the cases, see the module doc.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdExamine.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;exam &#64;ex', 'category': 'building', 'key': '&#64;examine', 'no_prefix': 'examine exam ex', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [&lt;object&gt;[/attrname]]\n examine [*&lt;account&gt;[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n script - examine a Script\n channel - examine a Channel\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;ex &#64;exam', 'category': 'building', 'key': '&#64;examine', 'no_prefix': 'examine ex exam', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [&lt;object&gt;[/attrname]]\n examine [*&lt;account&gt;[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n script - examine a Script\n channel - examine a Channel\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -276,7 +276,7 @@ for everyone to use, you need build privileges and the alias command.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdNick.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['nicks', 'nickname']</em><a class="headerlink" href="#evennia.commands.default.general.CmdNick.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['nickname', 'nicks']</em><a class="headerlink" href="#evennia.commands.default.general.CmdNick.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -308,7 +308,7 @@ for everyone to use, you need build privileges and the alias command.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdNick.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'nicks nickname', 'category': 'general', 'key': 'nick', 'no_prefix': ' nicks nickname', 'tags': '', 'text': '\n define a personal alias/nick by defining a string to\n match and replace it with another on the fly\n\n Usage:\n nick[/switches] &lt;string&gt; [= [replacement_string]]\n nick[/switches] &lt;template&gt; = &lt;replacement_template&gt;\n nick/delete &lt;string&gt; or number\n nicks\n\n Switches:\n inputline - replace on the inputline (default)\n object - replace on object-lookup\n account - replace on account-lookup\n list - show all defined aliases (also &quot;nicks&quot; works)\n delete - remove nick by index in /list\n clearall - clear all nicks\n\n Examples:\n nick hi = say Hello, I\'m Sarah!\n nick/object tom = the tall man\n nick build $1 $2 = create/drop $1;$2\n nick tell $1 $2=page $1=$2\n nick tm?$1=page tallman=$1\n nick tm\\=$1=page tallman=$1\n\n A \'nick\' is a personal string replacement. Use $1, $2, ... to catch arguments.\n Put the last $-marker without an ending space to catch all remaining text. You\n can also use unix-glob matching for the left-hand side &lt;string&gt;:\n\n * - matches everything\n ? - matches 0 or 1 single characters\n [abcd] - matches these chars in any order\n [!abcd] - matches everything not among these chars\n \\= - escape literal \'=\' you want in your &lt;string&gt;\n\n Note that no objects are actually renamed or changed by this command - your nicks\n are only available to you. If you want to permanently add keywords to an object\n for everyone to use, you need build privileges and the alias command.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdNick.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'nickname nicks', 'category': 'general', 'key': 'nick', 'no_prefix': ' nickname nicks', 'tags': '', 'text': '\n define a personal alias/nick by defining a string to\n match and replace it with another on the fly\n\n Usage:\n nick[/switches] &lt;string&gt; [= [replacement_string]]\n nick[/switches] &lt;template&gt; = &lt;replacement_template&gt;\n nick/delete &lt;string&gt; or number\n nicks\n\n Switches:\n inputline - replace on the inputline (default)\n object - replace on object-lookup\n account - replace on account-lookup\n list - show all defined aliases (also &quot;nicks&quot; works)\n delete - remove nick by index in /list\n clearall - clear all nicks\n\n Examples:\n nick hi = say Hello, I\'m Sarah!\n nick/object tom = the tall man\n nick build $1 $2 = create/drop $1;$2\n nick tell $1 $2=page $1=$2\n nick tm?$1=page tallman=$1\n nick tm\\=$1=page tallman=$1\n\n A \'nick\' is a personal string replacement. Use $1, $2, ... to catch arguments.\n Put the last $-marker without an ending space to catch all remaining text. You\n can also use unix-glob matching for the left-hand side &lt;string&gt;:\n\n * - matches everything\n ? - matches 0 or 1 single characters\n [abcd] - matches these chars in any order\n [!abcd] - matches everything not among these chars\n \\= - escape literal \'=\' you want in your &lt;string&gt;\n\n Note that no objects are actually renamed or changed by this command - your nicks\n are only available to you. If you want to permanently add keywords to an object\n for everyone to use, you need build privileges and the alias command.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdNick.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -331,7 +331,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdInventory.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['i', 'inv']</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['inv', 'i']</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -362,7 +362,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdInventory.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'no_prefix': ' i inv', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'no_prefix': ' inv i', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -606,7 +606,7 @@ placing it in their inventory.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdSay.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&quot;', &quot;'&quot;]</em><a class="headerlink" href="#evennia.commands.default.general.CmdSay.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = [&quot;'&quot;, '&quot;']</em><a class="headerlink" href="#evennia.commands.default.general.CmdSay.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -637,7 +637,7 @@ placing it in their inventory.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdSay.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&quot; \'', 'category': 'general', 'key': 'say', 'no_prefix': ' &quot; \'', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say &lt;message&gt;\n\n Talk to those in your current location.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdSay.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '\' &quot;', 'category': 'general', 'key': 'say', 'no_prefix': ' \' &quot;', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say &lt;message&gt;\n\n Talk to those in your current location.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdSay.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -781,7 +781,7 @@ which permission groups you are a member of.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdAccess.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hierarchy', 'groups']</em><a class="headerlink" href="#evennia.commands.default.general.CmdAccess.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['groups', 'hierarchy']</em><a class="headerlink" href="#evennia.commands.default.general.CmdAccess.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -812,7 +812,7 @@ which permission groups you are a member of.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdAccess.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hierarchy groups', 'category': 'general', 'key': 'access', 'no_prefix': ' hierarchy groups', 'tags': '', 'text': '\n show your current game access\n\n Usage:\n access\n\n This command shows you the permission hierarchy and\n which permission groups you are a member of.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdAccess.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'groups hierarchy', 'category': 'general', 'key': 'access', 'no_prefix': ' groups hierarchy', 'tags': '', 'text': '\n show your current game access\n\n Usage:\n access\n\n This command shows you the permission hierarchy and\n which permission groups you are a member of.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdAccess.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -691,7 +691,7 @@ See <a href="#id11"><span class="problematic" id="id12">|</span></a>luhttps://ww
<dl class="py attribute">
<dt id="evennia.commands.default.system.CmdTasks.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;delays', '&#64;task']</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;task', '&#64;delays']</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -737,7 +737,7 @@ to all the variables defined therein.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.system.CmdTasks.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;delays &#64;task', 'category': 'system', 'key': '&#64;tasks', 'no_prefix': 'tasks delays task', 'tags': '', 'text': &quot;\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;task &#64;delays', 'category': 'system', 'key': '&#64;tasks', 'no_prefix': 'tasks task delays', 'tags': '', 'text': &quot;\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -963,7 +963,7 @@ main test suite started with</p>
<p>Test the batch processor.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.tests.TestBatchProcess.red_button">
<code class="sig-name descname">red_button</code><em class="property"> = &lt;module 'evennia.contrib.tutorials.red_button.red_button' from '/tmp/tmpyr3967rh/5b8cb35ce40bf9b76a93bf6936ccba9338f10230/evennia/contrib/tutorials/red_button/red_button.py'&gt;</em><a class="headerlink" href="#evennia.commands.default.tests.TestBatchProcess.red_button" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">red_button</code><em class="property"> = &lt;module 'evennia.contrib.tutorials.red_button.red_button' from '/tmp/tmph75u8g23/1ebaad4fc9ba310ba41ca3008648e5c7e554e548/evennia/contrib/tutorials/red_button/red_button.py'&gt;</em><a class="headerlink" href="#evennia.commands.default.tests.TestBatchProcess.red_button" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">

View file

@ -130,7 +130,7 @@ connect “account name” “pass word”</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedConnect.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['con', 'conn', 'co']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['conn', 'co', 'con']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -165,7 +165,7 @@ there is no object yet before the account has logged in)</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedConnect.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'con conn co', 'category': 'general', 'key': 'connect', 'no_prefix': ' con conn co', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect &quot;account name&quot; &quot;pass word&quot;\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'conn co con', 'category': 'general', 'key': 'connect', 'no_prefix': ' conn co con', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect &quot;account name&quot; &quot;pass word&quot;\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -189,7 +189,7 @@ create “account name” “pass word”</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedCreate.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['cre', 'cr']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedCreate.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['cr', 'cre']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedCreate.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -226,7 +226,7 @@ create “account name” “pass word”</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedCreate.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'cre cr', 'category': 'general', 'key': 'create', 'no_prefix': ' cre cr', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create &lt;accountname&gt; &lt;password&gt;\n create &quot;account name&quot; &quot;pass word&quot;\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedCreate.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'cr cre', 'category': 'general', 'key': 'create', 'no_prefix': ' cr cre', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create &lt;accountname&gt; &lt;password&gt;\n create &quot;account name&quot; &quot;pass word&quot;\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedCreate.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -349,7 +349,7 @@ for simplicity. It shows a pane of info.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedHelp.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['h', '?']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedHelp.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['?', 'h']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedHelp.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -375,7 +375,7 @@ for simplicity. It shows a pane of info.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedHelp.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'h ?', 'category': 'general', 'key': 'help', 'no_prefix': ' h ?', 'tags': '', 'text': '\n get help when in unconnected-in state\n\n Usage:\n help\n\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '? h', 'category': 'general', 'key': 'help', 'no_prefix': ' ? h', 'tags': '', 'text': '\n get help when in unconnected-in state\n\n Usage:\n help\n\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -147,7 +147,7 @@ the module given by settings.CONNECTION_SCREEN_MODULE.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['con', 'conn', 'co']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['conn', 'co', 'con']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -177,7 +177,7 @@ there is no object yet before the account has logged in)</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'con conn co', 'category': 'general', 'key': 'connect', 'no_prefix': ' con conn co', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect &lt;email&gt; &lt;password&gt;\n\n Use the create command to first create an account before logging in.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'conn co con', 'category': 'general', 'key': 'connect', 'no_prefix': ' conn co con', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect &lt;email&gt; &lt;password&gt;\n\n Use the create command to first create an account before logging in.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -199,7 +199,7 @@ there is no object yet before the account has logged in)</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['cre', 'cr']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['cr', 'cre']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -235,7 +235,7 @@ name enclosed in quotes:</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'cre cr', 'category': 'general', 'key': 'create', 'no_prefix': ' cre cr', 'tags': '', 'text': '\n Create a new account.\n\n Usage (at login screen):\n create &quot;accountname&quot; &lt;email&gt; &lt;password&gt;\n\n This creates a new account account.\n\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'cr cre', 'category': 'general', 'key': 'create', 'no_prefix': ' cr cre', 'tags': '', 'text': '\n Create a new account.\n\n Usage (at login screen):\n create &quot;accountname&quot; &lt;email&gt; &lt;password&gt;\n\n This creates a new account account.\n\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedCreate.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -343,7 +343,7 @@ for simplicity. It shows a pane of info.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['h', '?']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['?', 'h']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -369,7 +369,7 @@ for simplicity. It shows a pane of info.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'h ?', 'category': 'general', 'key': 'help', 'no_prefix': ' h ?', 'tags': '', 'text': '\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '? h', 'category': 'general', 'key': 'help', 'no_prefix': ' ? h', 'tags': '', 'text': '\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -124,7 +124,7 @@
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.ingame_python.commands.CmdCallback.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;calls', '&#64;callback', '&#64;callbacks']</em><a class="headerlink" href="#evennia.contrib.base_systems.ingame_python.commands.CmdCallback.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;callbacks', '&#64;callback', '&#64;calls']</em><a class="headerlink" href="#evennia.contrib.base_systems.ingame_python.commands.CmdCallback.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -205,7 +205,7 @@ on user permission.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.ingame_python.commands.CmdCallback.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;calls &#64;callback &#64;callbacks', 'category': 'building', 'key': '&#64;call', 'no_prefix': 'call calls callback callbacks', 'tags': '', 'text': '\n Command to edit callbacks.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.ingame_python.commands.CmdCallback.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;callbacks &#64;callback &#64;calls', 'category': 'building', 'key': '&#64;call', 'no_prefix': 'call callbacks callback calls', 'tags': '', 'text': '\n Command to edit callbacks.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.ingame_python.commands.CmdCallback.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -219,7 +219,7 @@ the operation will be general or on the room.</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['q', 'abort', 'quit', 'chicken out']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['chicken out', 'q', 'abort', 'quit']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -243,7 +243,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'q abort quit chicken out', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' q abort quit chicken out', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'chicken out q abort quit', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' chicken out q abort quit', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -379,7 +379,7 @@ shout</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = [';', 'whisper', 'shout']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = [';', 'shout', 'whisper']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -408,7 +408,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '; whisper shout', 'category': 'general', 'key': 'say', 'no_prefix': ' ; whisper shout', 'tags': '', 'text': '\n Perform an communication action.\n\n Usage:\n say &lt;text&gt;\n whisper\n shout\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '; shout whisper', 'category': 'general', 'key': 'say', 'no_prefix': ' ; shout whisper', 'tags': '', 'text': '\n Perform an communication action.\n\n Usage:\n say &lt;text&gt;\n whisper\n shout\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdSpeak.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -436,7 +436,7 @@ emote /me points to /box and /lever.</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['pose', ':']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = [':', 'pose']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -475,7 +475,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'pose :', 'category': 'general', 'key': 'emote', 'no_prefix': ' pose :', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use &quot;...&quot; to enact speech.\n\n Usage:\n emote &lt;emote&gt;\n :&lt;emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': ': pose', 'category': 'general', 'key': 'emote', 'no_prefix': ' : pose', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use &quot;...&quot; to enact speech.\n\n Usage:\n emote &lt;emote&gt;\n :&lt;emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -498,7 +498,7 @@ looks and what actions is available.</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ex', 'e', 'examine', 'unfocus']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['examine', 'unfocus', 'ex', 'e']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -527,7 +527,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ex e examine unfocus', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' ex e examine unfocus', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus &lt;obj&gt;\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'examine unfocus ex e', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' examine unfocus ex e', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus &lt;obj&gt;\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdFocus.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -589,7 +589,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdGet.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['give', 'inventory', 'i', 'inv']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGet.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['inventory', 'inv', 'give', 'i']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGet.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -613,7 +613,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdGet.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'give inventory i inv', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' give inventory i inv', 'tags': '', 'text': '\n Use focus / examine instead.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGet.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'inventory inv give i', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' inventory inv give i', 'tags': '', 'text': '\n Use focus / examine instead.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGet.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -634,7 +634,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;dig', '&#64;open']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;open', '&#64;dig']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -657,7 +657,7 @@ to all the variables defined therein.</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;dig &#64;open', 'category': 'general', 'key': 'open', 'no_prefix': ' dig open', 'tags': '', 'text': '\n Interact with an object in focus.\n\n Usage:\n &lt;action&gt; [arg]\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;open &#64;dig', 'category': 'general', 'key': 'open', 'no_prefix': ' open dig', 'tags': '', 'text': '\n Interact with an object in focus.\n\n Usage:\n &lt;action&gt; [arg]\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdRerouter.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -753,7 +753,7 @@ try to influence the other part in the deal.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.barter.barter.CmdStatus.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['deal', 'offers']</em><a class="headerlink" href="#evennia.contrib.game_systems.barter.barter.CmdStatus.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['offers', 'deal']</em><a class="headerlink" href="#evennia.contrib.game_systems.barter.barter.CmdStatus.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -779,7 +779,7 @@ try to influence the other part in the deal.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.barter.barter.CmdStatus.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'deal offers', 'category': 'trading', 'key': 'status', 'no_prefix': ' deal offers', 'tags': '', 'text': &quot;\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n &quot;}</em><a class="headerlink" href="#evennia.contrib.game_systems.barter.barter.CmdStatus.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'offers deal', 'category': 'trading', 'key': 'status', 'no_prefix': ' offers deal', 'tags': '', 'text': &quot;\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n &quot;}</em><a class="headerlink" href="#evennia.contrib.game_systems.barter.barter.CmdStatus.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -630,7 +630,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.clothing.clothing.CmdInventory.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['i', 'inv']</em><a class="headerlink" href="#evennia.contrib.game_systems.clothing.clothing.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['inv', 'i']</em><a class="headerlink" href="#evennia.contrib.game_systems.clothing.clothing.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -661,7 +661,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.clothing.clothing.CmdInventory.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'no_prefix': ' i inv', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.clothing.clothing.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'no_prefix': ' inv i', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.clothing.clothing.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -680,7 +680,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hold', 'wait']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['wait', 'hold']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -706,7 +706,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_basic.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -575,7 +575,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hold', 'wait']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['wait', 'hold']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -595,7 +595,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -698,7 +698,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hold', 'wait']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['wait', 'hold']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -718,7 +718,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_items.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -477,7 +477,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hold', 'wait']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['wait', 'hold']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -497,7 +497,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_magic.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -937,7 +937,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['hold', 'wait']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['wait', 'hold']</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -957,7 +957,7 @@ if there are still any actions you can take.</p>
<dl class="py attribute">
<dt id="evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}</em><a class="headerlink" href="#evennia.contrib.game_systems.turnbattle.tb_range.CmdPass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -430,7 +430,7 @@ there is no room above/below you, your movement will fail.</p>
<dl class="py attribute">
<dt id="evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['fly', 'dive']</em><a class="headerlink" href="#evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['dive', 'fly']</em><a class="headerlink" href="#evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -453,7 +453,7 @@ to all the variables defined therein.</p>
<dl class="py attribute">
<dt id="evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'fly dive', 'category': 'general', 'key': 'fly or dive', 'no_prefix': ' fly dive', 'tags': '', 'text': '\n Fly or Dive up and down.\n\n Usage:\n fly\n dive\n\n Will fly up one room or dive down one room at your current position. If\n there is no room above/below you, your movement will fail.\n\n '}</em><a class="headerlink" href="#evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'dive fly', 'category': 'general', 'key': 'fly or dive', 'no_prefix': ' dive fly', 'tags': '', 'text': '\n Fly or Dive up and down.\n\n Usage:\n fly\n dive\n\n Will fly up one room or dive down one room at your current position. If\n there is no room above/below you, your movement will fail.\n\n '}</em><a class="headerlink" href="#evennia.contrib.grid.xyzgrid.commands.CmdFlyAndDive.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -334,7 +334,7 @@ everyone but the person rolling.</p>
<dl class="py attribute">
<dt id="evennia.contrib.rpg.dice.dice.CmdDice.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;dice', 'roll']</em><a class="headerlink" href="#evennia.contrib.rpg.dice.dice.CmdDice.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['roll', '&#64;dice']</em><a class="headerlink" href="#evennia.contrib.rpg.dice.dice.CmdDice.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -360,7 +360,7 @@ everyone but the person rolling.</p>
<dl class="py attribute">
<dt id="evennia.contrib.rpg.dice.dice.CmdDice.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;dice roll', 'category': 'general', 'key': 'dice', 'no_prefix': ' dice roll', 'tags': '', 'text': &quot;\n roll dice\n\n Usage:\n dice[/switch] &lt;nr&gt;d&lt;sides&gt; [modifier] [success condition]\n\n Switch:\n hidden - tell the room the roll is being done, but don't show the result\n secret - don't inform the room about neither roll nor result\n\n Examples:\n dice 3d6 + 4\n dice 1d100 - 2 &lt; 50\n\n This will roll the given number of dice with given sides and modifiers.\n So e.g. 2d6 + 3 means to 'roll a 6-sided die 2 times and add the result,\n then add 3 to the total'.\n Accepted modifiers are +, -, * and /.\n A success condition is given as normal Python conditionals\n (&lt;,&gt;,&lt;=,&gt;=,==,!=). So e.g. 2d6 + 3 &gt; 10 means that the roll will succeed\n only if the final result is above 8. If a success condition is given, the\n outcome (pass/fail) will be echoed along with how much it succeeded/failed\n with. The hidden/secret switches will hide all or parts of the roll from\n everyone but the person rolling.\n &quot;}</em><a class="headerlink" href="#evennia.contrib.rpg.dice.dice.CmdDice.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'roll &#64;dice', 'category': 'general', 'key': 'dice', 'no_prefix': ' roll dice', 'tags': '', 'text': &quot;\n roll dice\n\n Usage:\n dice[/switch] &lt;nr&gt;d&lt;sides&gt; [modifier] [success condition]\n\n Switch:\n hidden - tell the room the roll is being done, but don't show the result\n secret - don't inform the room about neither roll nor result\n\n Examples:\n dice 3d6 + 4\n dice 1d100 - 2 &lt; 50\n\n This will roll the given number of dice with given sides and modifiers.\n So e.g. 2d6 + 3 means to 'roll a 6-sided die 2 times and add the result,\n then add 3 to the total'.\n Accepted modifiers are +, -, * and /.\n A success condition is given as normal Python conditionals\n (&lt;,&gt;,&lt;=,&gt;=,==,!=). So e.g. 2d6 + 3 &gt; 10 means that the roll will succeed\n only if the final result is above 8. If a success condition is given, the\n outcome (pass/fail) will be echoed along with how much it succeeded/failed\n with. The hidden/secret switches will hide all or parts of the roll from\n everyone but the person rolling.\n &quot;}</em><a class="headerlink" href="#evennia.contrib.rpg.dice.dice.CmdDice.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -709,7 +709,7 @@ a different language.</p>
<dl class="py attribute">
<dt id="evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&quot;', &quot;'&quot;]</em><a class="headerlink" href="#evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = [&quot;'&quot;, '&quot;']</em><a class="headerlink" href="#evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -740,7 +740,7 @@ a different language.</p>
<dl class="py attribute">
<dt id="evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&quot; \'', 'category': 'general', 'key': 'say', 'no_prefix': ' &quot; \'', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say &lt;message&gt;\n\n Talk to those in your current location.\n '}</em><a class="headerlink" href="#evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '\' &quot;', 'category': 'general', 'key': 'say', 'no_prefix': ' \' &quot;', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say &lt;message&gt;\n\n Talk to those in your current location.\n '}</em><a class="headerlink" href="#evennia.contrib.rpg.rpsystem.rpsystem.CmdSay.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -485,7 +485,7 @@ boost INT Wizard Goblin</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['foil', 'boost']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['boost', 'foil']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -519,7 +519,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'foil boost', 'category': 'combat', 'key': 'stunt', 'no_prefix': ' foil boost', 'tags': '', 'text': '\n Perform a combat stunt, that boosts an ally against a target, or\n foils an enemy, giving them disadvantage against an ally.\n\n Usage:\n boost [ability] &lt;recipient&gt; &lt;target&gt;\n foil [ability] &lt;recipient&gt; &lt;target&gt;\n boost [ability] &lt;target&gt; (same as boost me &lt;target&gt;)\n foil [ability] &lt;target&gt; (same as foil &lt;target&gt; me)\n\n Example:\n boost STR me Goblin\n boost DEX Goblin\n foil STR Goblin me\n foil INT Goblin\n boost INT Wizard Goblin\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'boost foil', 'category': 'combat', 'key': 'stunt', 'no_prefix': ' boost foil', 'tags': '', 'text': '\n Perform a combat stunt, that boosts an ally against a target, or\n foils an enemy, giving them disadvantage against an ally.\n\n Usage:\n boost [ability] &lt;recipient&gt; &lt;target&gt;\n foil [ability] &lt;recipient&gt; &lt;target&gt;\n boost [ability] &lt;target&gt; (same as boost me &lt;target&gt;)\n foil [ability] &lt;target&gt; (same as foil &lt;target&gt; me)\n\n Example:\n boost STR me Goblin\n boost DEX Goblin\n foil STR Goblin me\n foil INT Goblin\n boost INT Wizard Goblin\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.combat_twitch.CmdStunt.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -200,7 +200,7 @@ self.args).</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.commands.CmdInventory.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['i', 'inv']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['inv', 'i']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -224,7 +224,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.commands.CmdInventory.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'no_prefix': ' i inv', 'tags': '', 'text': '\n View your inventory\n\n Usage:\n inventory\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'no_prefix': ' inv i', 'tags': '', 'text': '\n View your inventory\n\n Usage:\n inventory\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -301,7 +301,7 @@ unwear &lt;item&gt;</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.commands.CmdRemove.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['unwear', 'unwield']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdRemove.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['unwield', 'unwear']</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdRemove.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
@ -325,7 +325,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.evadventure.commands.CmdRemove.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'unwear unwield', 'category': 'general', 'key': 'remove', 'no_prefix': ' unwear unwield', 'tags': '', 'text': '\n Remove a remove a weapon/shield, armor or helmet.\n\n Usage:\n remove &lt;item&gt;\n unwield &lt;item&gt;\n unwear &lt;item&gt;\n\n To remove an item from the backpack, use |wdrop|n instead.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdRemove.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'unwield unwear', 'category': 'general', 'key': 'remove', 'no_prefix': ' unwield unwear', 'tags': '', 'text': '\n Remove a remove a weapon/shield, armor or helmet.\n\n Usage:\n remove &lt;item&gt;\n unwield &lt;item&gt;\n unwear &lt;item&gt;\n\n To remove an item from the backpack, use |wdrop|n instead.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.evadventure.commands.CmdRemove.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -161,7 +161,7 @@ such as when closing the lid and un-blinding a character.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['push', 'press button', 'press']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['press', 'press button', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -190,7 +190,7 @@ check if the lid is open or closed.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'push press button press', 'category': 'general', 'key': 'push button', 'no_prefix': ' push press button press', 'tags': '', 'text': '\n Push the red button (lid closed)\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press press button push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press press button push', 'tags': '', 'text': '\n Push the red button (lid closed)\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -260,7 +260,7 @@ check if the lid is open or closed.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['break lid', 'smash lid', 'smash']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['smash lid', 'smash', 'break lid']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -287,7 +287,7 @@ break.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'break lid smash lid smash', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' break lid smash lid smash', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'smash lid smash break lid', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' smash lid smash break lid', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -387,7 +387,7 @@ be mutually exclusive.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['push', 'press button', 'press']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['press', 'press button', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -416,7 +416,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'push press button press', 'category': 'general', 'key': 'push button', 'no_prefix': ' push press button press', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press press button push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press press button push', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -514,7 +514,7 @@ be mutually exclusive.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['feel', 'examine', 'l', 'listen', 'get', 'ex']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['ex', 'examine', 'get', 'l', 'listen', 'feel']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -540,7 +540,7 @@ be mutually exclusive.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'feel examine l listen get ex', 'category': 'general', 'key': 'look', 'no_prefix': ' feel examine l listen get ex', 'tags': '', 'text': &quot;\n Looking around in darkness\n\n Usage:\n look &lt;obj&gt;\n\n ... not that there's much to see in the dark.\n\n &quot;}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ex examine get l listen feel', 'category': 'general', 'key': 'look', 'no_prefix': ' ex examine get l listen feel', 'tags': '', 'text': &quot;\n Looking around in darkness\n\n Usage:\n look &lt;obj&gt;\n\n ... not that there's much to see in the dark.\n\n &quot;}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdBlindLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -433,7 +433,7 @@ of the object. We overload it with our own version.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['light', 'burn']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['burn', 'light']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -460,7 +460,7 @@ to sit on a “lightable” object, we operate only on self.obj.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'light burn', 'category': 'tutorialworld', 'key': 'on', 'no_prefix': ' light burn', 'tags': '', 'text': '\n Creates light where there was none. Something to burn.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'burn light', 'category': 'tutorialworld', 'key': 'on', 'no_prefix': ' burn light', 'tags': '', 'text': '\n Creates light where there was none. Something to burn.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -564,7 +564,7 @@ shift green root up/down</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['move', 'push', 'shiftroot', 'pull']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['push', 'move', 'pull', 'shiftroot']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -600,7 +600,7 @@ yellow/green - horizontal roots</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'move push shiftroot pull', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' move push shiftroot pull', 'tags': '', 'text': '\n Shifts roots around.\n\n Usage:\n shift blue root left/right\n shift red root left/right\n shift yellow root up/down\n shift green root up/down\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'push move pull shiftroot', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' push move pull shiftroot', 'tags': '', 'text': '\n Shifts roots around.\n\n Usage:\n shift blue root left/right\n shift red root left/right\n shift yellow root up/down\n shift green root up/down\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdShiftRoot.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -617,7 +617,7 @@ yellow/green - horizontal roots</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['push button', 'press button', 'button']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['push button', 'button', 'press button']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -643,7 +643,7 @@ yellow/green - horizontal roots</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'push button press button button', 'category': 'tutorialworld', 'key': 'press', 'no_prefix': ' push button press button button', 'tags': '', 'text': '\n Presses a button.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'push button button press button', 'category': 'tutorialworld', 'key': 'press', 'no_prefix': ' push button button press button', 'tags': '', 'text': '\n Presses a button.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdPressButton.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -787,7 +787,7 @@ parry - forgoes your attack but will make you harder to hit on next</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['chop', 'pierce', 'stab', 'kill', 'parry', 'slash', 'defend', 'bash', 'hit', 'fight', 'thrust']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['fight', 'chop', 'slash', 'hit', 'pierce', 'parry', 'thrust', 'kill', 'bash', 'defend', 'stab']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -813,7 +813,7 @@ parry - forgoes your attack but will make you harder to hit on next</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'chop pierce stab kill parry slash defend bash hit fight thrust', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' chop pierce stab kill parry slash defend bash hit fight thrust', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab &lt;enemy&gt;\n slash &lt;enemy&gt;\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'fight chop slash hit pierce parry thrust kill bash defend stab', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' fight chop slash hit pierce parry thrust kill bash defend stab', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab &lt;enemy&gt;\n slash &lt;enemy&gt;\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdAttack.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -824,7 +824,7 @@ if they fall off the bridge.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['h', '?']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['?', 'h']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -850,7 +850,7 @@ if they fall off the bridge.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'h ?', 'category': 'tutorial world', 'key': 'help', 'no_prefix': ' h ?', 'tags': '', 'text': '\n Overwritten help command while on the bridge.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '? h', 'category': 'tutorial world', 'key': 'help', 'no_prefix': ' ? h', 'tags': '', 'text': '\n Overwritten help command while on the bridge.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdBridgeHelp.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -976,7 +976,7 @@ to find something.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['feel', 'search', 'fiddle', 'l', 'feel around']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['search', 'fiddle', 'feel around', 'l', 'feel']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -1004,7 +1004,7 @@ random chance of eventually finding a light source.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'feel search fiddle l feel around', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' feel search fiddle l feel around', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'search fiddle feel around l feel', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' search fiddle feel around l feel', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdLookDark.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -216,7 +216,7 @@ git evennia pull - Pull the latest evennia code.</p>
<dl class="py attribute">
<dt id="evennia.contrib.utils.git_integration.git_integration.CmdGitEvennia.directory">
<code class="sig-name descname">directory</code><em class="property"> = '/tmp/tmpyr3967rh/5b8cb35ce40bf9b76a93bf6936ccba9338f10230/evennia'</em><a class="headerlink" href="#evennia.contrib.utils.git_integration.git_integration.CmdGitEvennia.directory" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">directory</code><em class="property"> = '/tmp/tmph75u8g23/1ebaad4fc9ba310ba41ca3008648e5c7e554e548/evennia'</em><a class="headerlink" href="#evennia.contrib.utils.git_integration.git_integration.CmdGitEvennia.directory" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -277,7 +277,7 @@ git pull - Pull the latest code from your current branch.</p>
<dl class="py attribute">
<dt id="evennia.contrib.utils.git_integration.git_integration.CmdGit.directory">
<code class="sig-name descname">directory</code><em class="property"> = '/tmp/tmpyr3967rh/5b8cb35ce40bf9b76a93bf6936ccba9338f10230/evennia/game_template'</em><a class="headerlink" href="#evennia.contrib.utils.git_integration.git_integration.CmdGit.directory" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">directory</code><em class="property"> = '/tmp/tmph75u8g23/1ebaad4fc9ba310ba41ca3008648e5c7e554e548/evennia/game_template'</em><a class="headerlink" href="#evennia.contrib.utils.git_integration.git_integration.CmdGit.directory" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">

View file

@ -344,7 +344,7 @@ indentation.</p>
<dl class="py attribute">
<dt id="evennia.utils.eveditor.CmdEditorGroup.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = [':I', ':y', ':&gt;', ':p', ':w', ':DD', ':fi', ':u', ':uu', ':echo', ':j', ':dd', ':::', ':r', ':UU', ':!', ':&lt;', ':wq', ':x', ':fd', ':f', ':=', '::', ':q!', ':s', ':h', ':A', ':i', ':', ':S', ':dw', ':q']</em><a class="headerlink" href="#evennia.utils.eveditor.CmdEditorGroup.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = [':f', ':u', ':r', ':=', ':p', ':I', ':dd', ':UU', ':dw', ':fd', ':s', ':uu', ':', ':q!', ':x', ':j', ':fi', ':q', ':i', ':echo', ':DD', ':y', ':&gt;', ':wq', ':h', ':!', ':&lt;', ':A', ':::', ':S', '::', ':w']</em><a class="headerlink" href="#evennia.utils.eveditor.CmdEditorGroup.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -372,7 +372,7 @@ efficient presentation.</p>
<dl class="py attribute">
<dt id="evennia.utils.eveditor.CmdEditorGroup.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': ':I :y :&gt; :p :w :DD :fi :u :uu :echo :j :dd ::: :r :UU :! :&lt; :wq :x :fd :f := :: :q! :s :h :A :i : :S :dw :q', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :I :y :&gt; :p :w :DD :fi :u :uu :echo :j :dd ::: :r :UU :! :&lt; :wq :x :fd :f := :: :q! :s :h :A :i : :S :dw :q', 'tags': '', 'text': '\n Commands for the editor\n '}</em><a class="headerlink" href="#evennia.utils.eveditor.CmdEditorGroup.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': ':f :u :r := :p :I :dd :UU :dw :fd :s :uu : :q! :x :j :fi :q :i :echo :DD :y :&gt; :wq :h :! :&lt; :A ::: :S :: :w', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :f :u :r := :p :I :dd :UU :dw :fd :s :uu : :q! :x :j :fi :q :i :echo :DD :y :&gt; :wq :h :! :&lt; :A ::: :S :: :w', 'tags': '', 'text': '\n Commands for the editor\n '}</em><a class="headerlink" href="#evennia.utils.eveditor.CmdEditorGroup.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -939,7 +939,7 @@ single question.</p>
<dl class="py attribute">
<dt id="evennia.utils.evmenu.CmdYesNoQuestion.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['y', 'abort', 'a', 'yes', 'n', '__nomatch_command', 'no']</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['y', 'a', 'no', '__nomatch_command', 'n', 'yes', 'abort']</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -965,7 +965,7 @@ single question.</p>
<dl class="py attribute">
<dt id="evennia.utils.evmenu.CmdYesNoQuestion.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'y abort a yes n __nomatch_command no', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' y abort a yes n __nomatch_command no', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'y a no __nomatch_command n yes abort', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' y a no __nomatch_command n yes abort', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -145,7 +145,7 @@ the <strong>caller.msg()</strong> construct every time the page is updated.</p>
<dl class="py attribute">
<dt id="evennia.utils.evmore.CmdMore.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['previous', 'abort', 'a', 'q', 'e', 'p', 't', 'quit', 'next', 'n', 'end', 'top']</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['q', 't', 'quit', 'a', 'p', 'end', 'next', 'n', 'top', 'e', 'previous', 'abort']</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -171,7 +171,7 @@ the <strong>caller.msg()</strong> construct every time the page is updated.</p>
<dl class="py attribute">
<dt id="evennia.utils.evmore.CmdMore.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'previous abort a q e p t quit next n end top', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' previous abort a q e p t quit next n end top', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'q t quit a p end next n top e previous abort', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' q t quit a p end next n top e previous abort', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -300,7 +300,7 @@
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Add-a-wiki.html">Add a wiki on your website</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Character-Generation.html">Web Character Generation</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Character-View-Tutorial.html">Web Character View Tutorial</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Help-System-Tutorial.html">Help System Tutorial</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Help-System-Tutorial.html">Web Help System Tutorial</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Extending-the-REST-API.html">Extending the REST API</a></li>
<li class="toctree-l3"><a class="reference internal" href="Howtos/Web-Tweeting-Game-Stats.html">Automatically Tweet game stats</a></li>
</ul>

Binary file not shown.

File diff suppressed because one or more lines are too long