Updated HTML docs.

This commit is contained in:
Evennia docbuilder action 2022-11-21 23:20:49 +00:00
parent 88477386fe
commit 4d7c3b369a
25 changed files with 1018 additions and 69 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: d9a7ba5d71a8c97b082c6fe60a8738b0
config: 7f5c6e9a2dce018f158867201e0039f0
tags: 645f666f9bcd5a90fca523b33c5a78b7

View file

@ -0,0 +1,520 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Extending the REST API &#8212; Evennia 1.0-dev documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Extending the REST API</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Extending the REST API</a><ul>
<li><a class="reference internal" href="#creating-your-own-viewset">Creating your own viewset</a></li>
<li><a class="reference internal" href="#setting-up-the-urls">Setting up the urls</a></li>
<li><a class="reference internal" href="#adding-a-new-detail">Adding a new detail</a></li>
<li><a class="reference internal" href="#creating-a-serializer">Creating a Serializer</a></li>
<li><a class="reference internal" href="#using-your-serializer">Using your serializer</a></li>
<li><a class="reference internal" href="#customizing-api-permissions">Customizing API permissions</a></li>
<li><a class="reference internal" href="#next-steps">Next Steps</a></li>
</ul>
</li>
</ul>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Howtos/Extending-the-REST-API.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="Extending-the-REST-API.html">1.0-dev (develop branch)</a></li>
<ul>
<li><a href="../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="extending-the-rest-api">
<h1>Extending the REST API<a class="headerlink" href="#extending-the-rest-api" title="Permalink to this headline"></a></h1>
<blockquote>
<div><p><em>This tutorial assumes you have a basic understanding of the <code class="docutils literal notranslate"><span class="pre">web</span></code> folder structure. If you dont, please read <a class="reference external" href="https://www.evennia.com/docs/1.0-dev/Components/Website.html">the page on the website</a> and make sure you understand it before you come back!</em></p>
</div></blockquote>
<p>For this guide, well be adding an <code class="docutils literal notranslate"><span class="pre">inventory</span></code> action to the <code class="docutils literal notranslate"><span class="pre">characters</span></code> endpoint, showing all objects being <em>worn</em> and <em>carried</em> by a character.</p>
<blockquote>
<div><p>“worn versus carried” isnt built into core Evennia, but its a common thing to add. This guide uses a <code class="docutils literal notranslate"><span class="pre">.db.worn</span></code> attribute to identify gear, but will explain how to reference your own mechanic too.</p>
</div></blockquote>
<p>The first thing you should do is review the <a class="reference external" href="https://www.evennia.com/docs/1.0-dev/Components/Web-API.html">REST API</a> documentation page. Its not very long, but it covers how to turn the API on and which parts of django you should be familiar with.</p>
<p>Once youve read that and successfully visited <code class="docutils literal notranslate"><span class="pre">/api/characters/</span></code>, its time to get started!</p>
<section id="creating-your-own-viewset">
<h2>Creating your own viewset<a class="headerlink" href="#creating-your-own-viewset" title="Permalink to this headline"></a></h2>
<p>The first thing youll need to do is define your own views module. Create a blank file: <code class="docutils literal notranslate"><span class="pre">mygame/web/api/views.py</span></code></p>
<blockquote>
<div><p>A <em>view</em> is the python code that tells django what data to put on a page, while a <em>template</em> tells django how to display that data. For more in-depth information, you can read the django documentation. (<a class="reference external" href="https://docs.djangoproject.com/en/4.1/topics/http/views/">docs for views</a>, <a class="reference external" href="https://docs.djangoproject.com/en/4.1/topics/templates/">docs for templates</a>)</p>
</div></blockquote>
<p>The default REST API endpoints are controlled by classes in <code class="docutils literal notranslate"><span class="pre">evennia/web/api/views.py</span></code> - you could copy that entire file directly and use it, but were going to focus on changing the minimum.</p>
<p>To start, well reimplement the default <code class="docutils literal notranslate"><span class="pre">characters</span></code> endpoint: a child view of the <code class="docutils literal notranslate"><span class="pre">objects</span></code> endpoint that can only access characters.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">mygame/web/api/views.py</span>
<span class="sd">Customized views for the REST API</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># we&#39;ll need these from django&#39;s rest framework to make our view work</span>
<span class="kn">from</span> <span class="nn">rest_framework.decorators</span> <span class="kn">import</span> <span class="n">action</span>
<span class="kn">from</span> <span class="nn">rest_framework.response</span> <span class="kn">import</span> <span class="n">Response</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">status</span>
<span class="c1"># this implements all the basic Evennia Object endpoint logic, so we&#39;re inheriting from it</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.views</span> <span class="kn">import</span> <span class="n">ObjectDBViewSet</span>
<span class="c1"># and we need this to filter our character view</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
<span class="c1"># our own custom view</span>
<span class="k">class</span> <span class="nc">CharacterViewSet</span><span class="p">(</span><span class="n">ObjectDBViewSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A customized Character view that adds an inventory detail</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">DefaultCharacter</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all_family</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="setting-up-the-urls">
<h2>Setting up the urls<a class="headerlink" href="#setting-up-the-urls" title="Permalink to this headline"></a></h2>
<p>Now that we have a viewset of our own, we can create our own urls module and change the <code class="docutils literal notranslate"><span class="pre">characters</span></code> endpoint path to point to ours.</p>
<blockquote>
<div><p>Evennias <a class="reference external" href="https://www.evennia.com/docs/1.0-dev/Components/Website.html">Game website</a> page demonstrates how to use the <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> module for the main website - if you havent gone over that page yet, now is a good time.</p>
</div></blockquote>
<p>The API routing is more complicated than the website or webclient routing, so you need to copy the entire module from evennia into your game instead of patching on changes. Copy the file from <code class="docutils literal notranslate"><span class="pre">evennia/web/api/urls.py</span></code> to your folder, <code class="docutils literal notranslate"><span class="pre">mygame/web/api/urls.py</span></code> and open it in your editor.</p>
<p>Import your new views module, then find and update the <code class="docutils literal notranslate"><span class="pre">characters</span></code> path to use your own viewset.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/api/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="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">TemplateView</span>
<span class="kn">from</span> <span class="nn">rest_framework.schemas</span> <span class="kn">import</span> <span class="n">get_schema_view</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.root</span> <span class="kn">import</span> <span class="n">APIRootRouter</span>
<span class="kn">from</span> <span class="nn">evennia.web.api</span> <span class="kn">import</span> <span class="n">views</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span> <span class="k">as</span> <span class="n">my_views</span> <span class="c1"># &lt;--- NEW</span>
<span class="n">app_name</span> <span class="o">=</span> <span class="s2">&quot;api&quot;</span>
<span class="n">router</span> <span class="o">=</span> <span class="n">APIRootRouter</span><span class="p">()</span>
<span class="n">router</span><span class="o">.</span><span class="n">trailing_slash</span> <span class="o">=</span> <span class="s2">&quot;/?&quot;</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;accounts&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">AccountDBViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;account&quot;</span><span class="p">)</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;objects&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">ObjectDBViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;object&quot;</span><span class="p">)</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;characters&quot;</span><span class="p">,</span> <span class="n">my_views</span><span class="o">.</span><span class="n">CharacterViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;character&quot;</span><span class="p">)</span> <span class="c1"># &lt;--- MODIFIED</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;exits&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">ExitViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;exit&quot;</span><span class="p">)</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;rooms&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">RoomViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;room&quot;</span><span class="p">)</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;scripts&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">ScriptDBViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;script&quot;</span><span class="p">)</span>
<span class="n">router</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;helpentries&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">HelpViewSet</span><span class="p">,</span> <span class="n">basename</span><span class="o">=</span><span class="s2">&quot;helpentry&quot;</span><span class="p">)</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">router</span><span class="o">.</span><span class="n">urls</span>
<span class="n">urlpatterns</span> <span class="o">+=</span> <span class="p">[</span>
<span class="c1"># openapi schema</span>
<span class="n">path</span><span class="p">(</span>
<span class="s2">&quot;openapi&quot;</span><span class="p">,</span>
<span class="n">get_schema_view</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Evennia API&quot;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Evennia OpenAPI Schema&quot;</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s2">&quot;1.0&quot;</span><span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">&quot;openapi&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="c1"># redoc auto-doc (based on openapi schema)</span>
<span class="n">path</span><span class="p">(</span>
<span class="s2">&quot;redoc/&quot;</span><span class="p">,</span>
<span class="n">TemplateView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(</span>
<span class="n">template_name</span><span class="o">=</span><span class="s2">&quot;rest_framework/redoc.html&quot;</span><span class="p">,</span> <span class="n">extra_context</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;schema_url&quot;</span><span class="p">:</span> <span class="s2">&quot;api:openapi&quot;</span><span class="p">}</span>
<span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">&quot;redoc&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">]</span>
</pre></div>
</div>
<p>Weve almost got it pointing at our new view now. The last step is to add your own API urls - <code class="docutils literal notranslate"><span class="pre">web.api.urls</span></code> - to your web root url module. Otherwise it will continue pointing to the default API router and well never see our changes.</p>
<p>Open <code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code> in your editor and add a new path for “api/”, pointing to <code class="docutils literal notranslate"><span class="pre">web.api.urls</span></code>. The final file should look something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/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>
<span class="c1"># default evennia patterns</span>
<span class="kn">from</span> <span class="nn">evennia.web.urls</span> <span class="kn">import</span> <span class="n">urlpatterns</span> <span class="k">as</span> <span class="n">evennia_default_urlpatterns</span>
<span class="c1"># add patterns</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># website</span>
<span class="n">path</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s2">&quot;web.website.urls&quot;</span><span class="p">)),</span>
<span class="c1"># webclient</span>
<span class="n">path</span><span class="p">(</span><span class="s2">&quot;webclient/&quot;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s2">&quot;web.webclient.urls&quot;</span><span class="p">)),</span>
<span class="c1"># web admin</span>
<span class="n">path</span><span class="p">(</span><span class="s2">&quot;admin/&quot;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s2">&quot;web.admin.urls&quot;</span><span class="p">)),</span>
<span class="c1"># the new API path</span>
<span class="n">path</span><span class="p">(</span><span class="s2">&quot;api/&quot;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s2">&quot;web.api.urls&quot;</span><span class="p">)),</span>
<span class="p">]</span>
<span class="c1"># &#39;urlpatterns&#39; must be named such for django to find it.</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">urlpatterns</span> <span class="o">+</span> <span class="n">evennia_default_urlpatterns</span>
</pre></div>
</div>
<p>Restart your evennia game - <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reboot</span></code> from the command line for a full restart of the game AND portal - and try to get <code class="docutils literal notranslate"><span class="pre">/api/characters/</span></code> again. If it works exactly like before, youre ready to move on to the next step!</p>
</section>
<section id="adding-a-new-detail">
<h2>Adding a new detail<a class="headerlink" href="#adding-a-new-detail" title="Permalink to this headline"></a></h2>
<p>Head back over to your character view class - its time to start adding our inventory.</p>
<p>The usual “page” in a REST API is called an <em>endpoint</em> and is what you typically access. e.g. <code class="docutils literal notranslate"><span class="pre">/api/characters/</span></code> is the “characters” endpoint, and <code class="docutils literal notranslate"><span class="pre">/api/characters/:id</span></code> is the endpoint for individual characters.</p>
<blockquote>
<div><p>The <code class="docutils literal notranslate"><span class="pre">:</span></code> in an API path means that its a variable - you dont directly access that exact path. Instead, youd take your character ID (e.g. 1) and use that instead: <code class="docutils literal notranslate"><span class="pre">/api/characters/1</span></code></p>
</div></blockquote>
<p>However, an endpoint can also have one or more <em>detail</em> views, which function like a sub-point. Well be adding <em>inventory</em> as a detail to our character endpoint, which will look like <code class="docutils literal notranslate"><span class="pre">/api/characters/:id/inventory</span></code></p>
<p>With the django REST framework, adding a new detail is as simple as adding a decorated method to the view set class - the <code class="docutils literal notranslate"><span class="pre">&#64;action</span></code> decorator. Since checking your inventory is just data retrieval, well only want to permit the <code class="docutils literal notranslate"><span class="pre">GET</span></code> method, and were adding this action as an API detail, so our decorator will look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@action</span><span class="p">(</span><span class="n">detail</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;get&quot;</span><span class="p">])</span>
</pre></div>
</div>
<blockquote>
<div><p>There are situations where you might want a detail or endpoint that isnt just data retrieval: for example, <em>buy</em> or <em>sell</em> on an auction-house listing. In those cases, you would use <em>put</em> or <em>post</em> instead. For further reading on what you can do with <code class="docutils literal notranslate"><span class="pre">&#64;action</span></code> and ViewSets, visit <a class="reference external" href="https://www.django-rest-framework.org/api-guide/viewsets/">the django REST framework documentation</a></p>
</div></blockquote>
<p>When adding a function as a detail action, the name of our function will be the same as the detail. Since we want an <code class="docutils literal notranslate"><span class="pre">inventory</span></code> action well define an <code class="docutils literal notranslate"><span class="pre">inventory</span></code> function.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">mygame/web/api/views.py</span>
<span class="sd">Customized views for the REST API</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># we&#39;ll need these from django&#39;s rest framework to make our view work</span>
<span class="kn">from</span> <span class="nn">rest_framework.decorators</span> <span class="kn">import</span> <span class="n">action</span>
<span class="kn">from</span> <span class="nn">rest_framework.response</span> <span class="kn">import</span> <span class="n">Response</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">status</span>
<span class="c1"># this implements all the basic Evennia Object endpoint logic, so we&#39;re inheriting from it</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.views</span> <span class="kn">import</span> <span class="n">ObjectDBViewSet</span>
<span class="c1"># and we need this to filter our character view</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
<span class="c1"># our own custom view</span>
<span class="k">class</span> <span class="nc">CharacterViewSet</span><span class="p">(</span><span class="n">ObjectDBViewSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A customized Character view that adds an inventory detail</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">DefaultCharacter</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all_family</span><span class="p">()</span>
<span class="c1"># !! NEW</span>
<span class="nd">@action</span><span class="p">(</span><span class="n">detail</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;get&quot;</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">inventory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="s2">&quot;your inventory&quot;</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_200_OK</span> <span class="p">)</span>
</pre></div>
</div>
<p>Get your characters ID - its the same as your dbref but without the # - and then <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reboot</span></code> again. Now you should be able to call your new characters action: <code class="docutils literal notranslate"><span class="pre">/api/characters/1/inventory</span></code> (assuming youre looking at character #1) and itll return the string “your inventory”</p>
</section>
<section id="creating-a-serializer">
<h2>Creating a Serializer<a class="headerlink" href="#creating-a-serializer" title="Permalink to this headline"></a></h2>
<p>A simple string isnt very useful, though. What we want is the characters actual inventory - and for that, we need to set up our own serializer.</p>
<p>Generally speaking, a <em>serializer</em> turns a set of data into a specially formatted string that can be sent in a data stream - usually JSON. Django REST serializers are special classes and functions which take python objects and convert them into API-ready formats. So, just like for the viewset, django and evennia have done a lot of the heavy lifting for us already.</p>
<blockquote>
<div><p>You can get a more in-depth look at django serializers on <a class="reference external" href="https://www.django-rest-framework.org/api-guide/serializers/">the django REST framework serializer docs</a></p>
</div></blockquote>
<p>Instead of writing our own serializer, well inherit from evennias pre-existing serializers and extend them for our own purpose. To do that, create a new file <code class="docutils literal notranslate"><span class="pre">mygame/web/api/serializers.py</span></code> and start by adding in the imports youll need.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># the base serializing library for the framework</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">serializers</span>
<span class="c1"># the handy classes Evennia already prepared for us</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.serializers</span> <span class="kn">import</span> <span class="n">TypeclassSerializerMixin</span><span class="p">,</span> <span class="n">SimpleObjectDBSerializer</span>
<span class="c1"># and the DefaultObject typeclass, for the necessary db model information</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
</pre></div>
</div>
<p>Next, well be defining our own serializer class. Since its for retrieving inventory data, well name it appropriately.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">InventorySerializer</span><span class="p">(</span><span class="n">TypeclassSerializerMixin</span><span class="p">,</span> <span class="n">serializers</span><span class="o">.</span><span class="n">ModelSerializer</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializing an inventory</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># these define the groups of items</span>
<span class="n">worn</span> <span class="o">=</span> <span class="n">serializers</span><span class="o">.</span><span class="n">SerializerMethodField</span><span class="p">()</span>
<span class="n">carried</span> <span class="o">=</span> <span class="n">serializers</span><span class="o">.</span><span class="n">SerializerMethodField</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">DefaultObject</span>
<span class="n">fields</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;id&quot;</span><span class="p">,</span> <span class="c1"># required field</span>
<span class="c1"># add these to match the properties you defined</span>
<span class="s2">&quot;worn&quot;</span><span class="p">,</span>
<span class="s2">&quot;carried&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="n">read_only_fields</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;id&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">Meta</span></code> class defines which fields will be used in the final serialized string. The <code class="docutils literal notranslate"><span class="pre">id</span></code> field is from the base ModelSerializer, but youll notice that the two others - <code class="docutils literal notranslate"><span class="pre">worn</span></code> and <code class="docutils literal notranslate"><span class="pre">carried</span></code> - are defined as properties to <code class="docutils literal notranslate"><span class="pre">SerializerMethodField</span></code>. That tells the framework to look for matching method names in the form <code class="docutils literal notranslate"><span class="pre">get_X</span></code> when serializing.</p>
<p>Which is why our next step is to add those methods! We defined the properties <code class="docutils literal notranslate"><span class="pre">worn</span></code> and <code class="docutils literal notranslate"><span class="pre">carried</span></code>, so the methods well add are <code class="docutils literal notranslate"><span class="pre">get_worn</span></code> and <code class="docutils literal notranslate"><span class="pre">get_carried</span></code>. Theyll be static methods - that is, they dont include <code class="docutils literal notranslate"><span class="pre">self</span></code> - since they dont need to reference the serializer class itself.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># these methods filter the character&#39;s contents based on the `worn` attribute</span>
<span class="k">def</span> <span class="nf">get_worn</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializes only worn objects in the target&#39;s inventory.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">worn</span> <span class="o">=</span> <span class="p">[</span><span class="n">obj</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">character</span><span class="o">.</span><span class="n">contents</span> <span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn</span><span class="p">]</span>
<span class="k">return</span> <span class="n">SimpleObjectDBSerializer</span><span class="p">(</span><span class="n">worn</span><span class="p">,</span> <span class="n">many</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">data</span>
<span class="k">def</span> <span class="nf">get_carried</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializes only non-worn objects in the target&#39;s inventory.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">carried</span> <span class="o">=</span> <span class="p">[</span><span class="n">obj</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">character</span><span class="o">.</span><span class="n">contents</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn</span><span class="p">]</span>
<span class="k">return</span> <span class="n">SimpleObjectDBSerializer</span><span class="p">(</span><span class="n">carried</span><span class="p">,</span> <span class="n">many</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">data</span>
</pre></div>
</div>
<p>For this guide, were assuming that whether an object is being worn or not is stored in the <code class="docutils literal notranslate"><span class="pre">worn</span></code> db attribute and filtering based on that attribute. This can easily be done differently to match your own games mechanics: filtering based on a tag, calling a custom method on your character that returns the right list, etc.</p>
<p>If you want to add in more details - grouping carried items by typing, or dividing up armor vs weapons, youd just need to add or change the properties, fields, and methods.</p>
<blockquote>
<div><p>Remember: <code class="docutils literal notranslate"><span class="pre">worn</span> <span class="pre">=</span> <span class="pre">serializers.SerializerMethodField()</span></code> is how the API knows to use <code class="docutils literal notranslate"><span class="pre">get_worn</span></code>, and <code class="docutils literal notranslate"><span class="pre">Meta.fields</span></code> is the list of fields that will actually make it into the final JSON.</p>
</div></blockquote>
<p>Your final file should look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/api/serializers.py</span>
<span class="c1"># the base serializing library for the framework</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">serializers</span>
<span class="c1"># the handy classes Evennia already prepared for us</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.serializers</span> <span class="kn">import</span> <span class="n">TypeclassSerializerMixin</span><span class="p">,</span> <span class="n">SimpleObjectDBSerializer</span>
<span class="c1"># and the DefaultObject typeclass, for the necessary db model information</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
<span class="k">class</span> <span class="nc">InventorySerializer</span><span class="p">(</span><span class="n">TypeclassSerializerMixin</span><span class="p">,</span> <span class="n">serializers</span><span class="o">.</span><span class="n">ModelSerializer</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializing an inventory</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># these define the groups of items</span>
<span class="n">worn</span> <span class="o">=</span> <span class="n">serializers</span><span class="o">.</span><span class="n">SerializerMethodField</span><span class="p">()</span>
<span class="n">carried</span> <span class="o">=</span> <span class="n">serializers</span><span class="o">.</span><span class="n">SerializerMethodField</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">DefaultObject</span>
<span class="n">fields</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;id&quot;</span><span class="p">,</span> <span class="c1"># required field</span>
<span class="c1"># add these to match the properties you defined</span>
<span class="s2">&quot;worn&quot;</span><span class="p">,</span>
<span class="s2">&quot;carried&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="n">read_only_fields</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;id&quot;</span><span class="p">]</span>
<span class="c1"># these methods filter the character&#39;s contents based on the `worn` attribute</span>
<span class="k">def</span> <span class="nf">get_worn</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializes only worn objects in the target&#39;s inventory.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">worn</span> <span class="o">=</span> <span class="p">[</span><span class="n">obj</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">character</span><span class="o">.</span><span class="n">contents</span> <span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn</span><span class="p">]</span>
<span class="k">return</span> <span class="n">SimpleObjectDBSerializer</span><span class="p">(</span><span class="n">worn</span><span class="p">,</span> <span class="n">many</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">data</span>
<span class="k">def</span> <span class="nf">get_carried</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Serializes only non-worn objects in the target&#39;s inventory.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">carried</span> <span class="o">=</span> <span class="p">[</span><span class="n">obj</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">character</span><span class="o">.</span><span class="n">contents</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn</span><span class="p">]</span>
<span class="k">return</span> <span class="n">SimpleObjectDBSerializer</span><span class="p">(</span><span class="n">carried</span><span class="p">,</span> <span class="n">many</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">data</span>
</pre></div>
</div>
</section>
<section id="using-your-serializer">
<h2>Using your serializer<a class="headerlink" href="#using-your-serializer" title="Permalink to this headline"></a></h2>
<p>Now lets go back to our views file, <code class="docutils literal notranslate"><span class="pre">mygame/web/api/views.py</span></code>. Add our new serializer with the rest of the imports:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.serializers</span> <span class="kn">import</span> <span class="n">InventorySerializer</span>
</pre></div>
</div>
<p>Then, update our <code class="docutils literal notranslate"><span class="pre">inventory</span></code> detail to use our serializer.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="nd">@action</span><span class="p">(</span><span class="n">detail</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;get&quot;</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">inventory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">()</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span> <span class="n">InventorySerializer</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_200_OK</span> <span class="p">)</span>
</pre></div>
</div>
<p>Your views file should now look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">mygame/web/api/views.py</span>
<span class="sd">Customized views for the REST API</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># we&#39;ll need these from django&#39;s rest framework to make our view work</span>
<span class="kn">from</span> <span class="nn">rest_framework.decorators</span> <span class="kn">import</span> <span class="n">action</span>
<span class="kn">from</span> <span class="nn">rest_framework.response</span> <span class="kn">import</span> <span class="n">Response</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">status</span>
<span class="c1"># this implements all the basic Evennia Object endpoint logic, so we&#39;re inheriting from it</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.views</span> <span class="kn">import</span> <span class="n">ObjectDBViewSet</span>
<span class="c1"># and we need this to filter our character view</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
<span class="kn">from</span> <span class="nn">.serializers</span> <span class="kn">import</span> <span class="n">InventorySerializer</span> <span class="c1"># &lt;--- NEW</span>
<span class="c1"># our own custom view</span>
<span class="k">class</span> <span class="nc">CharacterViewSet</span><span class="p">(</span><span class="n">ObjectDBViewSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A customized Character view that adds an inventory detail</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">DefaultCharacter</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all_family</span><span class="p">()</span>
<span class="nd">@action</span><span class="p">(</span><span class="n">detail</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;get&quot;</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">inventory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span> <span class="n">InventorySerializer</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_200_OK</span> <span class="p">)</span> <span class="c1"># &lt;--- MODIFIED</span>
</pre></div>
</div>
<p>Thatll use our new serializer to get our characters inventory. Except… not quite.</p>
<p>Go ahead and try it: <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reboot</span></code> and then <code class="docutils literal notranslate"><span class="pre">/api/characters/1/inventory</span></code> like before. Instead of returning the string “your inventory”, you should get an error saying you dont have permission. Dont worry - that means its successfully referencing the new serializer. We just havent given it permission to access the objects yet.</p>
</section>
<section id="customizing-api-permissions">
<h2>Customizing API permissions<a class="headerlink" href="#customizing-api-permissions" title="Permalink to this headline"></a></h2>
<p>Evennia comes with its own custom API permissions class, connecting the API permissions to the in-game permission hierarchy and locks system. Since were trying to access the objects data now, we need to pass the <code class="docutils literal notranslate"><span class="pre">has_object_permission</span></code> check as well as the general permission check - and that default permission class hardcodes actions into the object permission checks.</p>
<p>Since weve added a new action - <code class="docutils literal notranslate"><span class="pre">inventory</span></code> - to our characters endpoint, we need to use our own custom permissions on our characters endpoint as well. Create one more module file: <code class="docutils literal notranslate"><span class="pre">mygame/web/api/permissions.py</span></code></p>
<p>Like with the previous classes, well be inheriting from the original and extending it to take advantage of all the work Evennia already does for us.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/api/permissions.py</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.permissions</span> <span class="kn">import</span> <span class="n">EvenniaPermission</span>
<span class="k">class</span> <span class="nc">CharacterPermission</span><span class="p">(</span><span class="n">EvenniaPermission</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">has_object_permission</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks object-level permissions after has_permission</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># our new permission check</span>
<span class="k">if</span> <span class="n">view</span><span class="o">.</span><span class="n">action</span> <span class="o">==</span> <span class="s2">&quot;inventory&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_locks</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">view_locks</span><span class="p">)</span>
<span class="c1"># if it&#39;s not an inventory action, run through all the default checks</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">has_object_permission</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
</pre></div>
</div>
<p>Thats the whole permission class! For our final step, we need to use it in our characters view by importing it and setting the <code class="docutils literal notranslate"><span class="pre">permission_classes</span></code> property.</p>
<p>Once youve done that, your final <code class="docutils literal notranslate"><span class="pre">views.py</span></code> should look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">mygame/web/api/views.py</span>
<span class="sd">Customized views for the REST API</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># we&#39;ll need these from django&#39;s rest framework to make our view work</span>
<span class="kn">from</span> <span class="nn">rest_framework.decorators</span> <span class="kn">import</span> <span class="n">action</span>
<span class="kn">from</span> <span class="nn">rest_framework.response</span> <span class="kn">import</span> <span class="n">Response</span>
<span class="kn">from</span> <span class="nn">rest_framework</span> <span class="kn">import</span> <span class="n">status</span>
<span class="c1"># this implements all the basic Evennia Object endpoint logic, so we&#39;re inheriting from it</span>
<span class="kn">from</span> <span class="nn">evennia.web.api.views</span> <span class="kn">import</span> <span class="n">ObjectDBViewSet</span>
<span class="c1"># and we need this to filter our character view</span>
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span>
<span class="kn">from</span> <span class="nn">.serializers</span> <span class="kn">import</span> <span class="n">InventorySerializer</span>
<span class="kn">from</span> <span class="nn">.permissions</span> <span class="kn">import</span> <span class="n">CharacterPermission</span> <span class="c1"># &lt;--- NEW</span>
<span class="c1"># our own custom view</span>
<span class="k">class</span> <span class="nc">CharacterViewSet</span><span class="p">(</span><span class="n">ObjectDBViewSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A customized Character view that adds an inventory detail</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">permission_classes</span> <span class="o">=</span> <span class="p">[</span><span class="n">CharacterPermission</span><span class="p">]</span> <span class="c1"># &lt;--- NEW</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">DefaultCharacter</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all_family</span><span class="p">()</span>
<span class="nd">@action</span><span class="p">(</span><span class="n">detail</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;get&quot;</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">inventory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">()</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span> <span class="n">InventorySerializer</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_200_OK</span> <span class="p">)</span>
</pre></div>
</div>
<p>One last <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reboot</span></code> - now you should be able to get <code class="docutils literal notranslate"><span class="pre">/api/characters/1/inventory</span></code> and see everything your character has, neatly divided into “worn” and “carried”.</p>
</section>
<section id="next-steps">
<h2>Next Steps<a class="headerlink" href="#next-steps" title="Permalink to this headline"></a></h2>
<p>Thats it! Youve learned how to customize your own REST endpoint for Evennia, add new endpoint details, and serialize data from your games objects for the REST API. With those tools, you can take any in-game data you want and make it available - or even modifiable - with the API.</p>
<p>If you want a challenge, try taking what you learned and implementing a new <code class="docutils literal notranslate"><span class="pre">desc</span></code> detail that will let you <code class="docutils literal notranslate"><span class="pre">GET</span></code> the existing character desc <em>or</em> <code class="docutils literal notranslate"><span class="pre">PUT</span></code> a new desc. (Tip: check out how evennias REST permissions module works, and the <code class="docutils literal notranslate"><span class="pre">set_attribute</span></code> methods in the default evennia REST API views.)</p>
<blockquote>
<div><p>For a more in-depth look at the django REST framework, you can go through <a class="reference external" href="https://www.django-rest-framework.org/tutorial/1-serialization/">their tutorial</a> or straight to <a class="reference external" href="https://www.django-rest-framework.org/api-guide/requests/">the django REST framework API docs</a></p>
</div></blockquote>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Extending the REST API</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2022, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,429 @@
# Extending the REST API
> *This tutorial assumes you have a basic understanding of the `web` folder structure. If you don't, please read [the page on the website](https://www.evennia.com/docs/1.0-dev/Components/Website.html) and make sure you understand it before you come back!*
For this guide, we'll be adding an `inventory` action to the `characters` endpoint, showing all objects being _worn_ and _carried_ by a character.
> "worn versus carried" isn't built into core Evennia, but it's a common thing to add. This guide uses a `.db.worn` attribute to identify gear, but will explain how to reference your own mechanic too.
The first thing you should do is review the [REST API](https://www.evennia.com/docs/1.0-dev/Components/Web-API.html) documentation page. It's not very long, but it covers how to turn the API on and which parts of django you should be familiar with.
Once you've read that and successfully visited `/api/characters/`, it's time to get started!
## Creating your own viewset
The first thing you'll need to do is define your own views module. Create a blank file: `mygame/web/api/views.py`
> A *view* is the python code that tells django what data to put on a page, while a *template* tells django how to display that data. For more in-depth information, you can read the django documentation. ([docs for views](https://docs.djangoproject.com/en/4.1/topics/http/views/), [docs for templates](https://docs.djangoproject.com/en/4.1/topics/templates/))
The default REST API endpoints are controlled by classes in `evennia/web/api/views.py` - you could copy that entire file directly and use it, but we're going to focus on changing the minimum.
To start, we'll reimplement the default `characters` endpoint: a child view of the `objects` endpoint that can only access characters.
```python
"""
mygame/web/api/views.py
Customized views for the REST API
"""
# we'll need these from django's rest framework to make our view work
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
# this implements all the basic Evennia Object endpoint logic, so we're inheriting from it
from evennia.web.api.views import ObjectDBViewSet
# and we need this to filter our character view
from evennia.objects.objects import DefaultCharacter
# our own custom view
class CharacterViewSet(ObjectDBViewSet):
"""
A customized Character view that adds an inventory detail
"""
queryset = DefaultCharacter.objects.all_family()
```
## Setting up the urls
Now that we have a viewset of our own, we can create our own urls module and change the `characters` endpoint path to point to ours.
> Evennia's [Game website](https://www.evennia.com/docs/1.0-dev/Components/Website.html) page demonstrates how to use the `urls.py` module for the main website - if you haven't gone over that page yet, now is a good time.
The API routing is more complicated than the website or webclient routing, so you need to copy the entire module from evennia into your game instead of patching on changes. Copy the file from `evennia/web/api/urls.py` to your folder, `mygame/web/api/urls.py` and open it in your editor.
Import your new views module, then find and update the `characters` path to use your own viewset.
```python
# mygame/web/api/urls.py
from django.urls import path
from django.views.generic import TemplateView
from rest_framework.schemas import get_schema_view
from evennia.web.api.root import APIRootRouter
from evennia.web.api import views
from . import views as my_views # <--- NEW
app_name = "api"
router = APIRootRouter()
router.trailing_slash = "/?"
router.register(r"accounts", views.AccountDBViewSet, basename="account")
router.register(r"objects", views.ObjectDBViewSet, basename="object")
router.register(r"characters", my_views.CharacterViewSet, basename="character") # <--- MODIFIED
router.register(r"exits", views.ExitViewSet, basename="exit")
router.register(r"rooms", views.RoomViewSet, basename="room")
router.register(r"scripts", views.ScriptDBViewSet, basename="script")
router.register(r"helpentries", views.HelpViewSet, basename="helpentry")
urlpatterns = router.urls
urlpatterns += [
# openapi schema
path(
"openapi",
get_schema_view(title="Evennia API", description="Evennia OpenAPI Schema", version="1.0"),
name="openapi",
),
# redoc auto-doc (based on openapi schema)
path(
"redoc/",
TemplateView.as_view(
template_name="rest_framework/redoc.html", extra_context={"schema_url": "api:openapi"}
),
name="redoc",
),
]
```
We've almost got it pointing at our new view now. The last step is to add your own API urls - `web.api.urls` - to your web root url module. Otherwise it will continue pointing to the default API router and we'll never see our changes.
Open `mygame/web/urls.py` in your editor and add a new path for "api/", pointing to `web.api.urls`. The final file should look something like this:
```python
# mygame/web/urls.py
from django.urls import path, include
# default evennia patterns
from evennia.web.urls import urlpatterns as evennia_default_urlpatterns
# add patterns
urlpatterns = [
# website
path("", include("web.website.urls")),
# webclient
path("webclient/", include("web.webclient.urls")),
# web admin
path("admin/", include("web.admin.urls")),
# the new API path
path("api/", include("web.api.urls")),
]
# 'urlpatterns' must be named such for django to find it.
urlpatterns = urlpatterns + evennia_default_urlpatterns
```
Restart your evennia game - `evennia reboot` from the command line for a full restart of the game AND portal - and try to get `/api/characters/` again. If it works exactly like before, you're ready to move on to the next step!
## Adding a new detail
Head back over to your character view class - it's time to start adding our inventory.
The usual "page" in a REST API is called an *endpoint* and is what you typically access. e.g. `/api/characters/` is the "characters" endpoint, and `/api/characters/:id` is the endpoint for individual characters.
> The `:` in an API path means that it's a variable - you don't directly access that exact path. Instead, you'd take your character ID (e.g. 1) and use that instead: `/api/characters/1`
However, an endpoint can also have one or more *detail* views, which function like a sub-point. We'll be adding *inventory* as a detail to our character endpoint, which will look like `/api/characters/:id/inventory`
With the django REST framework, adding a new detail is as simple as adding a decorated method to the view set class - the `@action` decorator. Since checking your inventory is just data retrieval, we'll only want to permit the `GET` method, and we're adding this action as an API detail, so our decorator will look like this:
```python
@action(detail=True, methods=["get"])
```
> There are situations where you might want a detail or endpoint that isn't just data retrieval: for example, *buy* or *sell* on an auction-house listing. In those cases, you would use *put* or *post* instead. For further reading on what you can do with `@action` and ViewSets, visit [the django REST framework documentation](https://www.django-rest-framework.org/api-guide/viewsets/)
When adding a function as a detail action, the name of our function will be the same as the detail. Since we want an `inventory` action we'll define an `inventory` function.
```python
"""
mygame/web/api/views.py
Customized views for the REST API
"""
# we'll need these from django's rest framework to make our view work
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
# this implements all the basic Evennia Object endpoint logic, so we're inheriting from it
from evennia.web.api.views import ObjectDBViewSet
# and we need this to filter our character view
from evennia.objects.objects import DefaultCharacter
# our own custom view
class CharacterViewSet(ObjectDBViewSet):
"""
A customized Character view that adds an inventory detail
"""
queryset = DefaultCharacter.objects.all_family()
# !! NEW
@action(detail=True, methods=["get"])
def inventory(self, request, pk=None):
return Response("your inventory", status=status.HTTP_200_OK )
```
Get your character's ID - it's the same as your dbref but without the # - and then `evennia reboot` again. Now you should be able to call your new characters action: `/api/characters/1/inventory` (assuming you're looking at character #1) and it'll return the string "your inventory"
## Creating a Serializer
A simple string isn't very useful, though. What we want is the character's actual inventory - and for that, we need to set up our own serializer.
Generally speaking, a *serializer* turns a set of data into a specially formatted string that can be sent in a data stream - usually JSON. Django REST serializers are special classes and functions which take python objects and convert them into API-ready formats. So, just like for the viewset, django and evennia have done a lot of the heavy lifting for us already.
> You can get a more in-depth look at django serializers on [the django REST framework serializer docs](https://www.django-rest-framework.org/api-guide/serializers/)
Instead of writing our own serializer, we'll inherit from evennia's pre-existing serializers and extend them for our own purpose. To do that, create a new file `mygame/web/api/serializers.py` and start by adding in the imports you'll need.
```python
# the base serializing library for the framework
from rest_framework import serializers
# the handy classes Evennia already prepared for us
from evennia.web.api.serializers import TypeclassSerializerMixin, SimpleObjectDBSerializer
# and the DefaultObject typeclass, for the necessary db model information
from evennia.objects.objects import DefaultObject
```
Next, we'll be defining our own serializer class. Since it's for retrieving inventory data, we'll name it appropriately.
```python
class InventorySerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
"""
Serializing an inventory
"""
# these define the groups of items
worn = serializers.SerializerMethodField()
carried = serializers.SerializerMethodField()
class Meta:
model = DefaultObject
fields = [
"id", # required field
# add these to match the properties you defined
"worn",
"carried",
]
read_only_fields = ["id"]
```
The `Meta` class defines which fields will be used in the final serialized string. The `id` field is from the base ModelSerializer, but you'll notice that the two others - `worn` and `carried` - are defined as properties to `SerializerMethodField`. That tells the framework to look for matching method names in the form `get_X` when serializing.
Which is why our next step is to add those methods! We defined the properties `worn` and `carried`, so the methods we'll add are `get_worn` and `get_carried`. They'll be static methods - that is, they don't include `self` - since they don't need to reference the serializer class itself.
```python
# these methods filter the character's contents based on the `worn` attribute
def get_worn(character):
"""
Serializes only worn objects in the target's inventory.
"""
worn = [obj for obj in character.contents if obj.db.worn]
return SimpleObjectDBSerializer(worn, many=True).data
def get_carried(character):
"""
Serializes only non-worn objects in the target's inventory.
"""
carried = [obj for obj in character.contents if not obj.db.worn]
return SimpleObjectDBSerializer(carried, many=True).data
```
For this guide, we're assuming that whether an object is being worn or not is stored in the `worn` db attribute and filtering based on that attribute. This can easily be done differently to match your own game's mechanics: filtering based on a tag, calling a custom method on your character that returns the right list, etc.
If you want to add in more details - grouping carried items by typing, or dividing up armor vs weapons, you'd just need to add or change the properties, fields, and methods.
> Remember: `worn = serializers.SerializerMethodField()` is how the API knows to use `get_worn`, and `Meta.fields` is the list of fields that will actually make it into the final JSON.
Your final file should look like this:
```python
# mygame/web/api/serializers.py
# the base serializing library for the framework
from rest_framework import serializers
# the handy classes Evennia already prepared for us
from evennia.web.api.serializers import TypeclassSerializerMixin, SimpleObjectDBSerializer
# and the DefaultObject typeclass, for the necessary db model information
from evennia.objects.objects import DefaultObject
class InventorySerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
"""
Serializing an inventory
"""
# these define the groups of items
worn = serializers.SerializerMethodField()
carried = serializers.SerializerMethodField()
class Meta:
model = DefaultObject
fields = [
"id", # required field
# add these to match the properties you defined
"worn",
"carried",
]
read_only_fields = ["id"]
# these methods filter the character's contents based on the `worn` attribute
def get_worn(character):
"""
Serializes only worn objects in the target's inventory.
"""
worn = [obj for obj in character.contents if obj.db.worn]
return SimpleObjectDBSerializer(worn, many=True).data
def get_carried(character):
"""
Serializes only non-worn objects in the target's inventory.
"""
carried = [obj for obj in character.contents if not obj.db.worn]
return SimpleObjectDBSerializer(carried, many=True).data
```
## Using your serializer
Now let's go back to our views file, `mygame/web/api/views.py`. Add our new serializer with the rest of the imports:
```python
from .serializers import InventorySerializer
```
Then, update our `inventory` detail to use our serializer.
```python
@action(detail=True, methods=["get"])
def inventory(self, request, pk=None):
obj = self.get_object()
return Response( InventorySerializer(obj).data, status=status.HTTP_200_OK )
```
Your views file should now look like this:
```python
"""
mygame/web/api/views.py
Customized views for the REST API
"""
# we'll need these from django's rest framework to make our view work
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
# this implements all the basic Evennia Object endpoint logic, so we're inheriting from it
from evennia.web.api.views import ObjectDBViewSet
# and we need this to filter our character view
from evennia.objects.objects import DefaultCharacter
from .serializers import InventorySerializer # <--- NEW
# our own custom view
class CharacterViewSet(ObjectDBViewSet):
"""
A customized Character view that adds an inventory detail
"""
queryset = DefaultCharacter.objects.all_family()
@action(detail=True, methods=["get"])
def inventory(self, request, pk=None):
return Response( InventorySerializer(obj).data, status=status.HTTP_200_OK ) # <--- MODIFIED
```
That'll use our new serializer to get our character's inventory. Except... not quite.
Go ahead and try it: `evennia reboot` and then `/api/characters/1/inventory` like before. Instead of returning the string "your inventory", you should get an error saying you don't have permission. Don't worry - that means it's successfully referencing the new serializer. We just haven't given it permission to access the objects yet.
## Customizing API permissions
Evennia comes with its own custom API permissions class, connecting the API permissions to the in-game permission hierarchy and locks system. Since we're trying to access the object's data now, we need to pass the `has_object_permission` check as well as the general permission check - and that default permission class hardcodes actions into the object permission checks.
Since we've added a new action - `inventory` - to our characters endpoint, we need to use our own custom permissions on our characters endpoint as well. Create one more module file: `mygame/web/api/permissions.py`
Like with the previous classes, we'll be inheriting from the original and extending it to take advantage of all the work Evennia already does for us.
```python
# mygame/web/api/permissions.py
from evennia.web.api.permissions import EvenniaPermission
class CharacterPermission(EvenniaPermission):
def has_object_permission(self, request, view, obj):
"""
Checks object-level permissions after has_permission
"""
# our new permission check
if view.action == "inventory":
return self.check_locks(obj, request.user, self.view_locks)
# if it's not an inventory action, run through all the default checks
return super().has_object_permission(request, view, obj)
```
That's the whole permission class! For our final step, we need to use it in our characters view by importing it and setting the `permission_classes` property.
Once you've done that, your final `views.py` should look like this:
```python
"""
mygame/web/api/views.py
Customized views for the REST API
"""
# we'll need these from django's rest framework to make our view work
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
# this implements all the basic Evennia Object endpoint logic, so we're inheriting from it
from evennia.web.api.views import ObjectDBViewSet
# and we need this to filter our character view
from evennia.objects.objects import DefaultCharacter
from .serializers import InventorySerializer
from .permissions import CharacterPermission # <--- NEW
# our own custom view
class CharacterViewSet(ObjectDBViewSet):
"""
A customized Character view that adds an inventory detail
"""
permission_classes = [CharacterPermission] # <--- NEW
queryset = DefaultCharacter.objects.all_family()
@action(detail=True, methods=["get"])
def inventory(self, request, pk=None):
obj = self.get_object()
return Response( InventorySerializer(obj).data, status=status.HTTP_200_OK )
```
One last `evennia reboot` - now you should be able to get `/api/characters/1/inventory` and see everything your character has, neatly divided into "worn" and "carried".
## Next Steps
That's it! You've learned how to customize your own REST endpoint for Evennia, add new endpoint details, and serialize data from your game's objects for the REST API. With those tools, you can take any in-game data you want and make it available - or even modifiable - with the API.
If you want a challenge, try taking what you learned and implementing a new `desc` detail that will let you `GET` the existing character desc _or_ `PUT` a new desc. (Tip: check out how evennia's REST permissions module works, and the `set_attribute` methods in the default evennia REST API views.)
> For a more in-depth look at the django REST framework, you can go through [their tutorial](https://www.django-rest-framework.org/tutorial/1-serialization/) or straight to [the django REST framework API docs](https://www.django-rest-framework.org/api-guide/requests/)

View file

@ -317,7 +317,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"> = ['pemit', 'remit']</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"> = ['remit', 'pemit']</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">
@ -348,7 +348,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': '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>
<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>
<dd></dd></dl>
</dd></dl>

View file

@ -138,7 +138,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"> = ['batchcommand', 'batchcmd']</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"> = ['batchcmd', 'batchcommand']</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">
@ -169,7 +169,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': '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>
<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>
<dd></dd></dl>
</dd></dl>

View file

@ -592,7 +592,7 @@ You can specify the /force switch to bypass this confirmation.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdDestroy.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;del', '&#64;delete']</em><a class="headerlink" href="#evennia.commands.default.building.CmdDestroy.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;delete', '&#64;del']</em><a class="headerlink" href="#evennia.commands.default.building.CmdDestroy.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -633,7 +633,7 @@ You can specify the /force switch to bypass this confirmation.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdDestroy.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;del &#64;delete', 'category': 'building', 'key': '&#64;destroy', 'no_prefix': 'destroy del delete', 'tags': '', 'text': '\n permanently delete objects\n\n Usage:\n destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]\n\n Switches:\n override - The destroy command will usually avoid accidentally\n destroying account objects. This switch overrides this safety.\n force - destroy without confirmation.\n Examples:\n destroy house, roof, door, 44-78\n destroy 5-10, flower, 45\n destroy/force north\n\n Destroys one or many objects. If dbrefs are used, a range to delete can be\n given, e.g. 4-10. Also the end points will be deleted. This command\n displays a confirmation before destroying, to make sure of your choice.\n You can specify the /force switch to bypass this confirmation.\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdDestroy.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;delete &#64;del', 'category': 'building', 'key': '&#64;destroy', 'no_prefix': 'destroy delete del', 'tags': '', 'text': '\n permanently delete objects\n\n Usage:\n destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]\n\n Switches:\n override - The destroy command will usually avoid accidentally\n destroying account objects. This switch overrides this safety.\n force - destroy without confirmation.\n Examples:\n destroy house, roof, door, 44-78\n destroy 5-10, flower, 45\n destroy/force north\n\n Destroys one or many objects. If dbrefs are used, a range to delete can be\n given, e.g. 4-10. Also the end points will be deleted. This command\n displays a confirmation before destroying, to make sure of your choice.\n You can specify the /force switch to bypass this confirmation.\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdDestroy.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -1345,7 +1345,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;swap', '&#64;typeclasses', '&#64;type', '&#64;update', '&#64;parent']</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;update', '&#64;parent', '&#64;type', '&#64;swap', '&#64;typeclasses']</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">
@ -1376,7 +1376,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;swap &#64;typeclasses &#64;type &#64;update &#64;parent', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass swap typeclasses type update 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>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;update &#64;parent &#64;type &#64;swap &#64;typeclasses', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass update parent type swap typeclasses', '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>

File diff suppressed because one or more lines are too long

View file

@ -268,7 +268,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">
@ -300,7 +300,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>
@ -773,7 +773,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">
@ -804,7 +804,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

@ -902,7 +902,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/tmp5j5rru7h/a15a8ae42888846c44f33882b196663ac29d8cb3/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/tmprbs5hb8l/260e96e503b60ff031dae46edba66e3040274ab5/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

@ -122,7 +122,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"> = ['con', 'co', 'conn']</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">
@ -157,7 +157,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': 'con co conn', 'category': 'general', 'key': 'connect', 'no_prefix': ' con co conn', '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>
@ -286,7 +286,7 @@ All it does is display the connect screen.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'look']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['look', 'l']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -312,7 +312,7 @@ All it does is display the connect screen.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.unloggedin.CmdUnconnectedLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l look', 'category': 'general', 'key': '__unloggedin_look_command', 'no_prefix': ' l look', 'tags': '', 'text': '\n look when in unlogged-in state\n\n Usage:\n look\n\n This is an unconnected version of the look command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'look l', 'category': 'general', 'key': '__unloggedin_look_command', 'no_prefix': ' look l', 'tags': '', 'text': '\n look when in unlogged-in state\n\n Usage:\n look\n\n This is an unconnected version of the look command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -335,7 +335,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">
@ -361,7 +361,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

@ -139,7 +139,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"> = ['con', 'co', 'conn']</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">
@ -169,7 +169,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': 'con co conn', 'category': 'general', 'key': 'connect', 'no_prefix': ' con co conn', '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>
@ -291,7 +291,7 @@ All it does is display the connect screen.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'look']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['look', 'l']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -317,7 +317,7 @@ All it does is display the connect screen.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l look', 'category': 'general', 'key': '__unloggedin_look_command', 'no_prefix': ' l look', 'tags': '', 'text': '\n This is an unconnected version of the `look` command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'look l', 'category': 'general', 'key': '__unloggedin_look_command', 'no_prefix': ' look l', 'tags': '', 'text': '\n This is an unconnected version of the `look` command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -335,7 +335,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">
@ -361,7 +361,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

@ -116,7 +116,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;callback', '&#64;callbacks', '&#64;calls']</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;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>
<dd></dd></dl>
<dl class="py attribute">
@ -197,7 +197,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;callback &#64;callbacks &#64;calls', 'category': 'building', 'key': '&#64;call', 'no_prefix': 'call callback callbacks 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>
<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>
<dd></dd></dl>
</dd></dl>

View file

@ -160,7 +160,7 @@ aliases to an already joined channel.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['chanalias', 'aliaschan']</em><a class="headerlink" href="#evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['aliaschan', 'chanalias']</em><a class="headerlink" href="#evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -191,7 +191,7 @@ aliases to an already joined channel.</p>
<dl class="py attribute">
<dt id="evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'chanalias aliaschan', 'category': 'comms', 'key': 'addcom', 'no_prefix': ' chanalias aliaschan', 'tags': '', 'text': '\n Add a channel alias and/or subscribe to a channel\n\n Usage:\n addcom [alias=] &lt;channel&gt;\n\n Joins a given channel. If alias is given, this will allow you to\n refer to the channel by this alias rather than the full channel\n name. Subsequent calls of this command can be used to add multiple\n aliases to an already joined channel.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'aliaschan chanalias', 'category': 'comms', 'key': 'addcom', 'no_prefix': ' aliaschan chanalias', 'tags': '', 'text': '\n Add a channel alias and/or subscribe to a channel\n\n Usage:\n addcom [alias=] &lt;channel&gt;\n\n Joins a given channel. If alias is given, this will allow you to\n refer to the channel by this alias rather than the full channel\n name. Subsequent calls of this command can be used to add multiple\n aliases to an already joined channel.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.mux_comms_cmds.mux_comms_cmds.CmdAddCom.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -211,7 +211,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"> = ['abort', 'quit', 'chicken out', 'q']</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"> = ['q', 'chicken out', '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">
@ -235,7 +235,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': 'abort quit chicken out q', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' abort quit chicken out q', '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': 'q chicken out abort quit', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' q chicken out 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>
@ -371,7 +371,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"> = ['shout', ';', 'whisper']</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"> = ['whisper', ';', 'shout']</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">
@ -400,7 +400,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': '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>
<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>
<dd></dd></dl>
</dd></dl>
@ -490,7 +490,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"> = ['e', 'ex', 'unfocus', 'examine']</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', 'e', 'ex']</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">
@ -519,7 +519,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': 'e ex unfocus examine', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' e ex unfocus examine', '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 e ex', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' examine unfocus e ex', '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>
@ -581,7 +581,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"> = ['inv', 'inventory', 'i', 'give']</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"> = ['inv', 'give', 'inventory', '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">
@ -605,7 +605,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': 'inv inventory i give', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' inv inventory i give', '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': 'inv give inventory i', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' inv give inventory 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>
@ -626,7 +626,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;open', '&#64;dig']</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;dig', '&#64;open']</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">
@ -649,7 +649,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;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>
<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>
<dd></dd></dl>
</dd></dl>

View file

@ -745,7 +745,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">
@ -771,7 +771,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

@ -305,7 +305,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">
@ -331,7 +331,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

@ -506,7 +506,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"> = ['ex', 'get', 'listen', 'feel', 'l', 'examine']</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"> = ['get', 'feel', 'l', 'listen', 'examine', 'ex']</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">
@ -532,7 +532,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': 'ex get listen feel l examine', 'category': 'general', 'key': 'look', 'no_prefix': ' ex get listen feel l examine', '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': 'get feel l listen examine ex', 'category': 'general', 'key': 'look', 'no_prefix': ' get feel l listen examine 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>
<dd></dd></dl>
</dd></dl>

View file

@ -556,7 +556,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"> = ['push', 'move', '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"> = ['pull', 'push', 'shiftroot', 'move']</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">
@ -592,7 +592,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': 'push move shiftroot pull', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' push move 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': 'pull push shiftroot move', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' pull push shiftroot move', '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>
@ -609,7 +609,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"> = ['button', 'press button', 'push 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">
@ -635,7 +635,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': 'button press button push button', 'category': 'tutorialworld', 'key': 'press', 'no_prefix': ' button press button push 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>
@ -779,7 +779,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"> = ['defend', 'thrust', 'fight', 'hit', 'parry', 'stab', 'bash', 'chop', 'slash', 'pierce', 'kill']</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"> = ['chop', 'fight', 'kill', 'hit', 'bash', 'thrust', 'defend', 'pierce', 'parry', 'slash', '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">
@ -805,7 +805,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': 'defend thrust fight hit parry stab bash chop slash pierce kill', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' defend thrust fight hit parry stab bash chop slash pierce kill', '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': 'chop fight kill hit bash thrust defend pierce parry slash stab', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' chop fight kill hit bash thrust defend pierce parry slash 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

@ -816,7 +816,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">
@ -842,7 +842,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>
@ -968,7 +968,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"> = ['search', 'feel', '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"> = ['feel', 'l', 'search', 'fiddle', 'feel around']</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">
@ -996,7 +996,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': 'search feel fiddle l feel around', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' search feel 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': 'feel l search fiddle feel around', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' feel l search fiddle 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>
<dd></dd></dl>
</dd></dl>

View file

@ -208,7 +208,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/tmp5j5rru7h/a15a8ae42888846c44f33882b196663ac29d8cb3/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/tmprbs5hb8l/260e96e503b60ff031dae46edba66e3040274ab5/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">
@ -269,7 +269,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/tmp5j5rru7h/a15a8ae42888846c44f33882b196663ac29d8cb3/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/tmprbs5hb8l/260e96e503b60ff031dae46edba66e3040274ab5/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

@ -336,7 +336,7 @@ indentation.</p>
<dl class="py attribute">
<dt id="evennia.utils.eveditor.CmdEditorGroup.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = [':y', ':s', ':!', ':echo', ':wq', ':uu', ':q!', ':h', ':I', ':fd', ':q', ':', ':w', ':DD', ':i', ':x', ':S', ':&gt;', ':u', ':&lt;', '::', ':r', ':dd', ':A', ':j', ':f', ':UU', ':fi', ':p', ':=', ':::', ':dw']</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"> = [':wq', ':h', ':', ':echo', ':q', ':I', ':&lt;', ':u', ':r', ':s', ':::', ':f', ':&gt;', ':=', ':i', ':q!', ':dw', ':w', ':A', ':p', ':y', ':fd', ':DD', ':j', '::', ':uu', ':fi', ':x', ':S', ':UU', ':!', ':dd']</em><a class="headerlink" href="#evennia.utils.eveditor.CmdEditorGroup.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -364,7 +364,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': ':y :s :! :echo :wq :uu :q! :h :I :fd :q : :w :DD :i :x :S :&gt; :u :&lt; :: :r :dd :A :j :f :UU :fi :p := ::: :dw', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :y :s :! :echo :wq :uu :q! :h :I :fd :q : :w :DD :i :x :S :&gt; :u :&lt; :: :r :dd :A :j :f :UU :fi :p := ::: :dw', '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': ':wq :h : :echo :q :I :&lt; :u :r :s ::: :f :&gt; := :i :q! :dw :w :A :p :y :fd :DD :j :: :uu :fi :x :S :UU :! :dd', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :wq :h : :echo :q :I :&lt; :u :r :s ::: :f :&gt; := :i :q! :dw :w :A :p :y :fd :DD :j :: :uu :fi :x :S :UU :! :dd', '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

@ -931,7 +931,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"> = ['yes', 'abort', 'a', 'y', '__nomatch_command', 'no', 'n']</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"> = ['yes', '__nomatch_command', 'a', 'y', 'no', 'abort', 'n']</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -957,7 +957,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': 'yes abort a y __nomatch_command no n', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' yes abort a y __nomatch_command no n', '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': 'yes __nomatch_command a y no abort n', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' yes __nomatch_command a y no abort n', '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

@ -137,7 +137,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"> = ['e', 'quit', 'p', 't', 'abort', 'a', 'previous', 'end', 'next', 'q', 'top', 'n']</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"> = ['p', 'q', 'top', 't', 'previous', 'a', 'end', 'e', 'quit', 'next', 'abort', 'n']</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -163,7 +163,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': 'e quit p t abort a previous end next q top n', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' e quit p t abort a previous end next q top n', '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': 'p q top t previous a end e quit next abort n', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' p q top t previous a end e quit next abort n', '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>

Binary file not shown.

File diff suppressed because one or more lines are too long