Updated HTML docs.

This commit is contained in:
Evennia docbuilder action 2022-11-20 00:44:59 +00:00
parent c758f0d402
commit 57f411a6fa
95 changed files with 1370 additions and 2035 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: 2a039604581b49aee649bfc0adbfc647
config: c0024f80050e9e2b9dfd653b5cfcd067
tags: 645f666f9bcd5a90fca523b33c5a78b7

View file

@ -1,137 +0,0 @@
<!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>&lt;no title&gt; &#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="">&lt;no title&gt;</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>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../../_sources/.vale/write-good/README.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="README.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">
<p>Based on <a class="reference external" href="https://github.com/btford/write-good">write-good</a>.</p>
<blockquote>
<div><p>Naive linter for English prose for developers who cant write good and wanna learn to do other stuff good too.</p>
</div></blockquote>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">The</span> <span class="n">MIT</span> <span class="n">License</span> <span class="p">(</span><span class="n">MIT</span><span class="p">)</span>
<span class="n">Copyright</span> <span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="mi">2014</span> <span class="n">Brian</span> <span class="n">Ford</span>
<span class="n">Permission</span> <span class="ow">is</span> <span class="n">hereby</span> <span class="n">granted</span><span class="p">,</span> <span class="n">free</span> <span class="n">of</span> <span class="n">charge</span><span class="p">,</span> <span class="n">to</span> <span class="nb">any</span> <span class="n">person</span> <span class="n">obtaining</span> <span class="n">a</span> <span class="n">copy</span>
<span class="n">of</span> <span class="n">this</span> <span class="n">software</span> <span class="ow">and</span> <span class="n">associated</span> <span class="n">documentation</span> <span class="n">files</span> <span class="p">(</span><span class="n">the</span> <span class="s2">&quot;Software&quot;</span><span class="p">),</span> <span class="n">to</span> <span class="n">deal</span>
<span class="ow">in</span> <span class="n">the</span> <span class="n">Software</span> <span class="n">without</span> <span class="n">restriction</span><span class="p">,</span> <span class="n">including</span> <span class="n">without</span> <span class="n">limitation</span> <span class="n">the</span> <span class="n">rights</span>
<span class="n">to</span> <span class="n">use</span><span class="p">,</span> <span class="n">copy</span><span class="p">,</span> <span class="n">modify</span><span class="p">,</span> <span class="n">merge</span><span class="p">,</span> <span class="n">publish</span><span class="p">,</span> <span class="n">distribute</span><span class="p">,</span> <span class="n">sublicense</span><span class="p">,</span> <span class="ow">and</span><span class="o">/</span><span class="ow">or</span> <span class="n">sell</span>
<span class="n">copies</span> <span class="n">of</span> <span class="n">the</span> <span class="n">Software</span><span class="p">,</span> <span class="ow">and</span> <span class="n">to</span> <span class="n">permit</span> <span class="n">persons</span> <span class="n">to</span> <span class="n">whom</span> <span class="n">the</span> <span class="n">Software</span> <span class="ow">is</span>
<span class="n">furnished</span> <span class="n">to</span> <span class="n">do</span> <span class="n">so</span><span class="p">,</span> <span class="n">subject</span> <span class="n">to</span> <span class="n">the</span> <span class="n">following</span> <span class="n">conditions</span><span class="p">:</span>
<span class="n">The</span> <span class="n">above</span> <span class="n">copyright</span> <span class="n">notice</span> <span class="ow">and</span> <span class="n">this</span> <span class="n">permission</span> <span class="n">notice</span> <span class="n">shall</span> <span class="n">be</span> <span class="n">included</span> <span class="ow">in</span> <span class="nb">all</span>
<span class="n">copies</span> <span class="ow">or</span> <span class="n">substantial</span> <span class="n">portions</span> <span class="n">of</span> <span class="n">the</span> <span class="n">Software</span><span class="o">.</span>
<span class="n">THE</span> <span class="n">SOFTWARE</span> <span class="n">IS</span> <span class="n">PROVIDED</span> <span class="s2">&quot;AS IS&quot;</span><span class="p">,</span> <span class="n">WITHOUT</span> <span class="n">WARRANTY</span> <span class="n">OF</span> <span class="n">ANY</span> <span class="n">KIND</span><span class="p">,</span> <span class="n">EXPRESS</span> <span class="n">OR</span>
<span class="n">IMPLIED</span><span class="p">,</span> <span class="n">INCLUDING</span> <span class="n">BUT</span> <span class="n">NOT</span> <span class="n">LIMITED</span> <span class="n">TO</span> <span class="n">THE</span> <span class="n">WARRANTIES</span> <span class="n">OF</span> <span class="n">MERCHANTABILITY</span><span class="p">,</span>
<span class="n">FITNESS</span> <span class="n">FOR</span> <span class="n">A</span> <span class="n">PARTICULAR</span> <span class="n">PURPOSE</span> <span class="n">AND</span> <span class="n">NONINFRINGEMENT</span><span class="o">.</span> <span class="n">IN</span> <span class="n">NO</span> <span class="n">EVENT</span> <span class="n">SHALL</span> <span class="n">THE</span>
<span class="n">AUTHORS</span> <span class="n">OR</span> <span class="n">COPYRIGHT</span> <span class="n">HOLDERS</span> <span class="n">BE</span> <span class="n">LIABLE</span> <span class="n">FOR</span> <span class="n">ANY</span> <span class="n">CLAIM</span><span class="p">,</span> <span class="n">DAMAGES</span> <span class="n">OR</span> <span class="n">OTHER</span>
<span class="n">LIABILITY</span><span class="p">,</span> <span class="n">WHETHER</span> <span class="n">IN</span> <span class="n">AN</span> <span class="n">ACTION</span> <span class="n">OF</span> <span class="n">CONTRACT</span><span class="p">,</span> <span class="n">TORT</span> <span class="n">OR</span> <span class="n">OTHERWISE</span><span class="p">,</span> <span class="n">ARISING</span> <span class="n">FROM</span><span class="p">,</span>
<span class="n">OUT</span> <span class="n">OF</span> <span class="n">OR</span> <span class="n">IN</span> <span class="n">CONNECTION</span> <span class="n">WITH</span> <span class="n">THE</span> <span class="n">SOFTWARE</span> <span class="n">OR</span> <span class="n">THE</span> <span class="n">USE</span> <span class="n">OR</span> <span class="n">OTHER</span> <span class="n">DEALINGS</span> <span class="n">IN</span> <span class="n">THE</span>
<span class="n">SOFTWARE</span><span class="o">.</span>
</pre></div>
</div>
</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="">&lt;no title&gt;</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

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Coding Utils" href="Coding-Utils.html" />
<link rel="next" title="Inputfuncs" href="Inputfuncs.html" />
<link rel="prev" title="Batch Code Processor" href="Batch-Code-Processor.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Coding-Utils.html" title="Coding Utils"
<a href="Inputfuncs.html" title="Inputfuncs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Batch-Code-Processor.html" title="Batch Code Processor"
@ -76,8 +76,8 @@
<p class="topless"><a href="Batch-Code-Processor.html"
title="previous chapter">Batch Code Processor</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Coding-Utils.html"
title="next chapter">Coding Utils</a></p>
<p class="topless"><a href="Inputfuncs.html"
title="next chapter">Inputfuncs</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -301,7 +301,7 @@ mode instead, see its readme for install instructions.</p></li>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Coding-Utils.html" title="Coding Utils"
<a href="Inputfuncs.html" title="Inputfuncs"
>next</a> |</li>
<li class="right" >
<a href="Batch-Code-Processor.html" title="Batch Code Processor"

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Core Concepts" href="../Concepts/Concepts-Overview.html" />
<link rel="prev" title="Web Client" href="Webclient.html" />
<link rel="prev" title="Evennia REST API" href="Web-API.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="../Concepts/Concepts-Overview.html" title="Core Concepts"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Webclient.html" title="Web Client"
<a href="Web-API.html" title="Evennia REST API"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -81,8 +81,8 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Webclient.html"
title="previous chapter">Web Client</a></p>
<p class="topless"><a href="Web-API.html"
title="previous chapter">Evennia REST API</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../Concepts/Concepts-Overview.html"
title="next chapter">Core Concepts</a></p>
@ -231,7 +231,7 @@ over <a class="reference internal" href="../Howtos/Web-Character-Generation.html
<a href="../Concepts/Concepts-Overview.html" title="Core Concepts"
>next</a> |</li>
<li class="right" >
<a href="Webclient.html" title="Web Client"
<a href="Web-API.html" title="Evennia REST API"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="EvEditor" href="EvEditor.html" />
<link rel="prev" title="Batch Command Processor" href="Batch-Command-Processor.html" />
<link rel="prev" title="Outputfuncs" href="Outputfuncs.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="EvEditor.html" title="EvEditor"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Batch-Command-Processor.html" title="Batch Command Processor"
<a href="Outputfuncs.html" title="Outputfuncs"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -94,8 +94,8 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Batch-Command-Processor.html"
title="previous chapter">Batch Command Processor</a></p>
<p class="topless"><a href="Outputfuncs.html"
title="previous chapter">Outputfuncs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="EvEditor.html"
title="next chapter">EvEditor</a></p>
@ -433,7 +433,7 @@ instructions.</p>
<a href="EvEditor.html" title="EvEditor"
>next</a> |</li>
<li class="right" >
<a href="Batch-Command-Processor.html" title="Batch Command Processor"
<a href="Outputfuncs.html" title="Outputfuncs"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Commands" href="Commands.html" />
<link rel="prev" title="Permissions" href="Permissions.html" />
<link rel="prev" title="Portal And Server" href="Portal-And-Server.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Commands.html" title="Commands"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Permissions.html" title="Permissions"
<a href="Portal-And-Server.html" title="Portal And Server"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -61,8 +61,8 @@
</div>
<script>$('#searchbox').show(0);</script>
<h4>Previous topic</h4>
<p class="topless"><a href="Permissions.html"
title="previous chapter">Permissions</a></p>
<p class="topless"><a href="Portal-And-Server.html"
title="previous chapter">Portal And Server</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Commands.html"
title="next chapter">Commands</a></p>
@ -129,7 +129,7 @@
<a href="Commands.html" title="Commands"
>next</a> |</li>
<li class="right" >
<a href="Permissions.html" title="Permissions"
<a href="Portal-And-Server.html" title="Portal And Server"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -62,11 +62,10 @@
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Core Components</a><ul>
<li><a class="reference internal" href="#database-entites">Database entites</a></li>
<li><a class="reference internal" href="#basic-entites">Basic entites</a></li>
<li><a class="reference internal" href="#commands">Commands</a></li>
<li><a class="reference internal" href="#utils-and-tools">Utils and tools</a></li>
<li><a class="reference internal" href="#web-components">Web components</a></li>
<li><a class="reference internal" href="#server-and-network">Server and network</a></li>
</ul>
</li>
</ul>
@ -110,8 +109,9 @@
<section class="tex2jax_ignore mathjax_ignore" id="core-components">
<h1>Core Components<a class="headerlink" href="#core-components" title="Permalink to this headline"></a></h1>
<p>These are the building blocks out of which Evennia is built. This documentation is complementary to, and often goes deeper than, the doc-strings of each component in the <a class="reference internal" href="../Evennia-API.html"><span class="doc std std-doc">API</span></a>.</p>
<section id="database-entites">
<h2>Database entites<a class="headerlink" href="#database-entites" title="Permalink to this headline"></a></h2>
<section id="basic-entites">
<h2>Basic entites<a class="headerlink" href="#basic-entites" title="Permalink to this headline"></a></h2>
<p>These are base pieces used to make an Evennia game. Most are long-lived and are persisted in the database.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Typeclasses.html">Typeclasses</a><ul>
@ -218,11 +218,13 @@
<li class="toctree-l2"><a class="reference internal" href="Permissions.html#quelling">Quelling</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Portal-And-Server.html">Portal And Server</a></li>
</ul>
</div>
</section>
<section id="commands">
<h2>Commands<a class="headerlink" href="#commands" title="Permalink to this headline"></a></h2>
<p>Evennias Command system handle everything sent to the server by the user.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Command-System.html">Command System</a></li>
@ -271,11 +273,19 @@
<li class="toctree-l2"><a class="reference internal" href="Batch-Command-Processor.html#assorted-notes">Assorted notes</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Inputfuncs.html">Inputfuncs</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#adding-your-own-inputfuncs">Adding your own inputfuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#default-inputfuncs">Default inputfuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#unmonitor">unmonitor</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Outputfuncs.html">Outputfuncs</a></li>
</ul>
</div>
</section>
<section id="utils-and-tools">
<h2>Utils and tools<a class="headerlink" href="#utils-and-tools" title="Permalink to this headline"></a></h2>
<p>Evennia provides a library of code resources to help the creation of a game.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Coding-Utils.html">Coding Utils</a><ul>
@ -350,6 +360,7 @@
</section>
<section id="web-components">
<h2>Web components<a class="headerlink" href="#web-components" title="Permalink to this headline"></a></h2>
<p>Evennia is also its own webserver, with a website and in-browser webclient you can expand on.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Website.html">Game website</a><ul>
@ -359,9 +370,12 @@
<li class="toctree-l2"><a class="reference internal" href="Website.html#user-forms">User forms</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Web-API.html">Evennia REST API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Web-API.html#usage">Usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="Web-API.html#customizing-the-api">Customizing the API</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html">Web Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#customizing-the-web-client">Customizing the web client</a></li>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#evennia-web-client-api-from-evennia-js">Evennia Web Client API (from evennia.js)</a></li>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#plugin-manager-api-from-webclient-gui-js">Plugin Manager API (from webclient_gui.js)</a></li>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#plugin-callbacks-api">Plugin callbacks API</a></li>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#writing-your-own-plugins">Writing your own Plugins</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Web-Admin.html">The Web Admin</a><ul>
@ -370,37 +384,13 @@
<li class="toctree-l2"><a class="reference internal" href="Web-Admin.html#customizing-the-web-admin">Customizing the web admin</a></li>
</ul>
</li>
</ul>
</div>
</section>
<section id="server-and-network">
<h2>Server and network<a class="headerlink" href="#server-and-network" title="Permalink to this headline"></a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Portal-And-Server.html">Portal And Server</a></li>
<li class="toctree-l1"><a class="reference internal" href="Inputfuncs.html">Inputfuncs</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#adding-your-own-inputfuncs">Adding your own inputfuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#default-inputfuncs">Default inputfuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="Inputfuncs.html#unmonitor">unmonitor</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Outputfuncs.html">Outputfuncs</a></li>
<li class="toctree-l1"><a class="reference internal" href="Server.html">Server component</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webserver.html">Webserver</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Webserver.html#basic-webserver-data-flow">Basic Webserver data flow</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html">Web Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#customizing-the-web-client">Customizing the web client</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#evennia-web-client-api-from-evennia-js">Evennia Web Client API (from evennia.js)</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#plugin-manager-api-from-webclient-gui-js">Plugin Manager API (from webclient_gui.js)</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#plugin-callbacks-api">Plugin callbacks API</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#example-default-plugins-plugins-js">Example/Default Plugins (plugins/*.js)</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#a-side-note-on-html-messages-vrs-text2html-messages">A side note on html messages vrs text2html messages</a></li>
<li class="toctree-l1"><a class="reference internal" href="Webclient.html#writing-your-own-plugins">Writing your own Plugins</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Webclient.html#goldenlayout">GoldenLayout</a></li>
<li class="toctree-l1"><a class="reference internal" href="Web-API.html">Evennia REST API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Web-API.html#usage">Usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="Web-API.html#customizing-the-api">Customizing the API</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Bootstrap-Components-and-Utilities.html">Bootstrap Components and Utilities</a><ul>
@ -408,11 +398,6 @@
<li class="toctree-l2"><a class="reference internal" href="Bootstrap-Components-and-Utilities.html#components">Components</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Signals.html">Signals</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Signals.html#attaching-a-handler-to-a-signal">Attaching a handler to a signal</a></li>
<li class="toctree-l2"><a class="reference internal" href="Signals.html#available-signals">Available signals</a></li>
</ul>
</li>
</ul>
</div>
</section>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Outputfuncs" href="Outputfuncs.html" />
<link rel="prev" title="Portal And Server" href="Portal-And-Server.html" />
<link rel="prev" title="Batch Command Processor" href="Batch-Command-Processor.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Outputfuncs.html" title="Outputfuncs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Portal-And-Server.html" title="Portal And Server"
<a href="Batch-Command-Processor.html" title="Batch Command Processor"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -84,8 +84,8 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Portal-And-Server.html"
title="previous chapter">Portal And Server</a></p>
<p class="topless"><a href="Batch-Command-Processor.html"
title="previous chapter">Batch Command Processor</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Outputfuncs.html"
title="next chapter">Outputfuncs</a></p>
@ -320,7 +320,7 @@ add more. By default the following fields/attributes can be monitored:</p>
<a href="Outputfuncs.html" title="Outputfuncs"
>next</a> |</li>
<li class="right" >
<a href="Portal-And-Server.html" title="Portal And Server"
<a href="Batch-Command-Processor.html" title="Batch Command Processor"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Server component" href="Server.html" />
<link rel="next" title="Coding Utils" href="Coding-Utils.html" />
<link rel="prev" title="Inputfuncs" href="Inputfuncs.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Server.html" title="Server component"
<a href="Coding-Utils.html" title="Coding Utils"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Inputfuncs.html" title="Inputfuncs"
@ -64,8 +64,8 @@
<p class="topless"><a href="Inputfuncs.html"
title="previous chapter">Inputfuncs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Server.html"
title="next chapter">Server component</a></p>
<p class="topless"><a href="Coding-Utils.html"
title="next chapter">Coding Utils</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -117,7 +117,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Server.html" title="Server component"
<a href="Coding-Utils.html" title="Coding Utils"
>next</a> |</li>
<li class="right" >
<a href="Inputfuncs.html" title="Inputfuncs"

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Command System" href="Command-System.html" />
<link rel="next" title="Portal And Server" href="Portal-And-Server.html" />
<link rel="prev" title="Help System" href="Help-System.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Command-System.html" title="Command System"
<a href="Portal-And-Server.html" title="Portal And Server"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Help-System.html" title="Help System"
@ -81,8 +81,8 @@
<p class="topless"><a href="Help-System.html"
title="previous chapter">Help System</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Command-System.html"
title="next chapter">Command System</a></p>
<p class="topless"><a href="Portal-And-Server.html"
title="next chapter">Portal And Server</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -319,7 +319,7 @@ affectable by locks.</p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Command-System.html" title="Command System"
<a href="Portal-And-Server.html" title="Portal And Server"
>next</a> |</li>
<li class="right" >
<a href="Help-System.html" title="Help System"

View file

@ -17,8 +17,8 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Inputfuncs" href="Inputfuncs.html" />
<link rel="prev" title="The Web Admin" href="Web-Admin.html" />
<link rel="next" title="Command System" href="Command-System.html" />
<link rel="prev" title="Permissions" href="Permissions.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -30,10 +30,10 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Inputfuncs.html" title="Inputfuncs"
<a href="Command-System.html" title="Command System"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Web-Admin.html" title="The Web Admin"
<a href="Permissions.html" title="Permissions"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -61,11 +61,11 @@
</div>
<script>$('#searchbox').show(0);</script>
<h4>Previous topic</h4>
<p class="topless"><a href="Web-Admin.html"
title="previous chapter">The Web Admin</a></p>
<p class="topless"><a href="Permissions.html"
title="previous chapter">Permissions</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Inputfuncs.html"
title="next chapter">Inputfuncs</a></p>
<p class="topless"><a href="Command-System.html"
title="next chapter">Command System</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -100,13 +100,9 @@
<h1>Portal And Server<a class="headerlink" href="#portal-and-server" title="Permalink to this headline"></a></h1>
<p>Evennia consists of two processes, known as <em>Portal</em> and <em>Server</em>. They can be controlled from
inside the game or from the command line as described <a class="reference internal" href="../Setup/Start-Stop-Reload.html"><span class="doc std std-doc">here</span></a>.</p>
<p>If you are new to the concept, the main purpose of separating the two is to have accounts connect to
the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the
Server part) without Accounts getting disconnected.</p>
<p>![portal and server layout](https://474a3b9f-a-62cb3a1a-s-
<a class="reference external" href="http://sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png">sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png</a>)</p>
<p>The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection.
This allows the two programs to communicate seamlessly.</p>
<p>If you are new to the concept, the main purpose of separating the two is to have accounts connect to the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the Server part) without Accounts getting disconnected.</p>
<p>![portal and server layout](https://474a3b9f-a-62cb3a1a-s- <a class="reference external" href="http://sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png">sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png</a>)</p>
<p>The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection. This allows the two programs to communicate seamlessly.</p>
</section>
@ -125,10 +121,10 @@ This allows the two programs to communicate seamlessly.</p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Inputfuncs.html" title="Inputfuncs"
<a href="Command-System.html" title="Command System"
>next</a> |</li>
<li class="right" >
<a href="Web-Admin.html" title="The Web Admin"
<a href="Permissions.html" title="Permissions"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -1,136 +0,0 @@
<!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>Server component &#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" />
<link rel="next" title="Webserver" href="Webserver.html" />
<link rel="prev" title="Outputfuncs" href="Outputfuncs.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="right" >
<a href="Webserver.html" title="Webserver"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Outputfuncs.html" title="Outputfuncs"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Server component</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>
<h4>Previous topic</h4>
<p class="topless"><a href="Outputfuncs.html"
title="previous chapter">Outputfuncs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Webserver.html"
title="next chapter">Webserver</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Components/Server.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="Server.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="server-component">
<h1>Server component<a class="headerlink" href="#server-component" title="Permalink to this headline"></a></h1>
<p>TODO: This is currently in <a class="reference internal" href="Portal-And-Server.html"><span class="doc std std-doc">Portal-and-Server</span></a>.</p>
</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="right" >
<a href="Webserver.html" title="Webserver"
>next</a> |</li>
<li class="right" >
<a href="Outputfuncs.html" title="Outputfuncs"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Server component</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

@ -17,8 +17,8 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="The Web Admin" href="Web-Admin.html" />
<link rel="prev" title="Game website" href="Website.html" />
<link rel="next" title="Bootstrap Components and Utilities" href="Bootstrap-Components-and-Utilities.html" />
<link rel="prev" title="Webserver" href="Webserver.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -30,10 +30,10 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-Admin.html" title="The Web Admin"
<a href="Bootstrap-Components-and-Utilities.html" title="Bootstrap Components and Utilities"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Website.html" title="Game website"
<a href="Webserver.html" title="Webserver"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -70,11 +70,11 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Website.html"
title="previous chapter">Game website</a></p>
<p class="topless"><a href="Webserver.html"
title="previous chapter">Webserver</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Web-Admin.html"
title="next chapter">The Web Admin</a></p>
<p class="topless"><a href="Bootstrap-Components-and-Utilities.html"
title="next chapter">Bootstrap Components and Utilities</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -236,10 +236,10 @@ copy over <code class="docutils literal notranslate"><span class="pre">evennia/w
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-Admin.html" title="The Web Admin"
<a href="Bootstrap-Components-and-Utilities.html" title="Bootstrap Components and Utilities"
>next</a> |</li>
<li class="right" >
<a href="Website.html" title="Game website"
<a href="Webserver.html" title="Webserver"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -17,8 +17,8 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Portal And Server" href="Portal-And-Server.html" />
<link rel="prev" title="Evennia REST API" href="Web-API.html" />
<link rel="next" title="Webserver" href="Webserver.html" />
<link rel="prev" title="Web Client" href="Webclient.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -30,10 +30,10 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Portal-And-Server.html" title="Portal And Server"
<a href="Webserver.html" title="Webserver"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Web-API.html" title="Evennia REST API"
<a href="Webclient.html" title="Web Client"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -79,11 +79,11 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Web-API.html"
title="previous chapter">Evennia REST API</a></p>
<p class="topless"><a href="Webclient.html"
title="previous chapter">Web Client</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Portal-And-Server.html"
title="next chapter">Portal And Server</a></p>
<p class="topless"><a href="Webserver.html"
title="next chapter">Webserver</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -283,10 +283,10 @@ following to your <code class="docutils literal notranslate"><span class="pre">m
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Portal-And-Server.html" title="Portal And Server"
<a href="Webserver.html" title="Webserver"
>next</a> |</li>
<li class="right" >
<a href="Web-API.html" title="Evennia REST API"
<a href="Webclient.html" title="Web Client"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -17,8 +17,8 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Bootstrap Components and Utilities" href="Bootstrap-Components-and-Utilities.html" />
<link rel="prev" title="Webserver" href="Webserver.html" />
<link rel="next" title="The Web Admin" href="Web-Admin.html" />
<link rel="prev" title="Game website" href="Website.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -30,10 +30,10 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Bootstrap-Components-and-Utilities.html" title="Bootstrap Components and Utilities"
<a href="Web-Admin.html" title="The Web Admin"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Webserver.html" title="Webserver"
<a href="Website.html" title="Game website"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -64,25 +64,27 @@
<ul>
<li><a class="reference internal" href="#">Web Client</a><ul>
<li><a class="reference internal" href="#customizing-the-web-client">Customizing the web client</a></li>
</ul>
</li>
<li><a class="reference internal" href="#evennia-web-client-api-from-evennia-js">Evennia Web Client API (from evennia.js)</a></li>
<li><a class="reference internal" href="#plugin-manager-api-from-webclient-gui-js">Plugin Manager API (from webclient_gui.js)</a></li>
<li><a class="reference internal" href="#plugin-callbacks-api">Plugin callbacks API</a></li>
<li><a class="reference internal" href="#example-default-plugins-plugins-js">Example/Default Plugins (plugins/*.js)</a></li>
<li><a class="reference internal" href="#a-side-note-on-html-messages-vrs-text2html-messages">A side note on html messages vrs text2html messages</a></li>
<li><a class="reference internal" href="#plugin-callbacks-api">Plugin callbacks API</a><ul>
<li><a class="reference internal" href="#example-default-plugins-plugins-js">Example/Default Plugins (<code class="docutils literal notranslate"><span class="pre">plugins/*.js</span></code>)</a></li>
<li><a class="reference internal" href="#a-side-note-on-html-messages-vs-text2html-messages">A side note on html messages vs text2html messages</a></li>
</ul>
</li>
<li><a class="reference internal" href="#writing-your-own-plugins">Writing your own Plugins</a><ul>
<li><a class="reference internal" href="#goldenlayout">GoldenLayout</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Webserver.html"
title="previous chapter">Webserver</a></p>
<p class="topless"><a href="Website.html"
title="previous chapter">Game website</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Bootstrap-Components-and-Utilities.html"
title="next chapter">Bootstrap Components and Utilities</a></p>
<p class="topless"><a href="Web-Admin.html"
title="next chapter">The Web Admin</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -149,9 +151,8 @@ your browser cache, and see if your edit shows up.</strong></p>
<code class="docutils literal notranslate"><span class="pre">evennia/web/templates/webclient/base.html</span></code> to
<code class="docutils literal notranslate"><span class="pre">mygame/web/templates/webclient/base.html</span></code> and editing it to add your new plugin.</p>
</section>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="evennia-web-client-api-from-evennia-js">
<h1>Evennia Web Client API (from evennia.js)<a class="headerlink" href="#evennia-web-client-api-from-evennia-js" title="Permalink to this headline"></a></h1>
<section id="evennia-web-client-api-from-evennia-js">
<h2>Evennia Web Client API (from evennia.js)<a class="headerlink" href="#evennia-web-client-api-from-evennia-js" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.init(</span> <span class="pre">opts</span> <span class="pre">)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.connect()</span></code></p></li>
@ -161,8 +162,8 @@ your browser cache, and see if your edit shows up.</strong></p>
<li><p><code class="docutils literal notranslate"><span class="pre">log()</span></code></p></li>
</ul>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="plugin-manager-api-from-webclient-gui-js">
<h1>Plugin Manager API (from webclient_gui.js)<a class="headerlink" href="#plugin-manager-api-from-webclient-gui-js" title="Permalink to this headline"></a></h1>
<section id="plugin-manager-api-from-webclient-gui-js">
<h2>Plugin Manager API (from webclient_gui.js)<a class="headerlink" href="#plugin-manager-api-from-webclient-gui-js" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">options</span></code> Object, Stores key/value state that can be used by plugins to coordinate behavior.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">plugins</span></code> Object, key/value list of the all the loaded plugins.</p></li>
@ -174,8 +175,8 @@ your browser cache, and see if your edit shows up.</strong></p>
</li>
</ul>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="plugin-callbacks-api">
<h1>Plugin callbacks API<a class="headerlink" href="#plugin-callbacks-api" title="Permalink to this headline"></a></h1>
<section id="plugin-callbacks-api">
<h2>Plugin callbacks API<a class="headerlink" href="#plugin-callbacks-api" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">init()</span></code> The only required callback</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">boolean</span> <span class="pre">onKeydown(event)</span></code> This plugin listens for Keydown events</p></li>
@ -197,24 +198,20 @@ true will short-circuit the execution, so no other plugins lower in the base.htm
their callback for this event called. This enables things like the up/down arrow keys for the
history.js plugin to always occur before the default_in.js plugin adds that key to the current input
buffer.</p>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="example-default-plugins-plugins-js">
<h1>Example/Default Plugins (plugins/*.js)<a class="headerlink" href="#example-default-plugins-plugins-js" title="Permalink to this headline"></a></h1>
<section id="example-default-plugins-plugins-js">
<h3>Example/Default Plugins (<code class="docutils literal notranslate"><span class="pre">plugins/*.js</span></code>)<a class="headerlink" href="#example-default-plugins-plugins-js" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">clienthelp.js</span></code> Defines onOptionsUI from the options2 plugin. This is a mostly empty plugin to
add some “How To” information for your game.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">default_in.js</span></code> Defines onKeydown. <enter> key or mouse clicking the arrow will send the currently
typed text.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">default_in.js</span></code> Defines onKeydown. <code class="docutils literal notranslate"><span class="pre">&lt;enter&gt;</span></code> key or mouse clicking the arrow will send the currently typed text.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">default_out.js</span></code> Defines onText, onPrompt, and onUnknownCmd. Generates HTML output for the user.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">default_unload.js</span></code> Defines onBeforeUnload. Prompts the user to confirm that they meant to
leave/close the game.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">font.js</span></code> Defines onOptionsUI. The plugin adds the ability to select your font and font size.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">goldenlayout_default_config.js</span></code> Not actually a plugin, defines a global variable that
goldenlayout uses to determine its window layout, known tag routing, etc.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">goldenlayout.js</span></code> Defines onKeydown, onText and custom functions. A very powerful “tabbed” window
manager for drag-n-drop windows, text routing and more.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">history.js</span></code> Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow
keys to peruse.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">goldenlayout.js</span></code> Defines onKeydown, onText and custom functions. A very powerful “tabbed” window manager for drag-n-drop windows, text routing and more.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">history.js</span></code> Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow keys to peruse.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">hotbuttons.js</span></code> Defines onGotOptions. A Disabled-by-default plugin that defines a button bar with
user-assignable commands.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">html.js</span></code> A basic plugin to allow the client to handle “raw html” messages from the server, this
@ -225,32 +222,21 @@ window for a side-by-side web/text interface, mostly an example of how to build
<li><p><code class="docutils literal notranslate"><span class="pre">message_routing.js</span></code> Defines onOptionsUI, onText, onKeydown. This goldenlayout-only plugin
implements regex matching to allow users to “tag” arbitrary text that matches, so that it gets
routed to proper windows. Similar to “Spawn” functions for other clients.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">multimedia.js</span></code> An basic plugin to allow the client to handle “image” “audio” and “video” messages
from the server and display them as inline HTML.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">multimedia.js</span></code> An basic plugin to allow the client to handle “image” “audio” and “video” messages from the server and display them as inline HTML.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">notifications.js</span></code> Defines onText. Generates browser notification events for each new message
while the tab is hidden.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">oob.js</span></code> Defines onSend. Allows the user to test/send Out Of Band json messages to the server.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">options.js</span></code> Defines most callbacks. Provides a popup-based UI to coordinate options settings with the server.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">options2.js</span></code> Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab.
Integrates with other plugins via the custom onOptionsUI callback.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">options2.js</span></code> Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab. Integrates with other plugins via the custom onOptionsUI callback.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">popups.js</span></code> Provides default popups/Dialog UI for other plugins to use.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">text2html.js</span></code> Provides a new message handler type: <code class="docutils literal notranslate"><span class="pre">text2html</span></code>, similar to the multimedia and html
plugins. This plugin provides a way to offload rendering the regular pipe-styled ASCII messages
to the client. This allows the server to do less work, while also allowing the client a place to
customize this conversion process. To use this plugin you will need to override the current commands
in Evennia, changing any place where a raw text output message is generated and turn it into a
<code class="docutils literal notranslate"><span class="pre">text2html</span></code> message. For example: <code class="docutils literal notranslate"><span class="pre">target.msg(&quot;my</span> <span class="pre">text&quot;)</span></code> becomes: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=(&quot;my</span> <span class="pre">text&quot;))</span></code>
(even better, use a webclient pane routing tag: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=(&quot;my</span> <span class="pre">text&quot;,</span> <span class="pre">{&quot;type&quot;:</span> <span class="pre">&quot;sometag&quot;}))</span></code>)
<code class="docutils literal notranslate"><span class="pre">text2html</span></code> messages should format and behave identically to the server-side generated text2html() output.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">text2html.js</span></code> Provides a new message handler type: <code class="docutils literal notranslate"><span class="pre">text2html</span></code>, similar to the multimedia and html plugins. This plugin provides a way to offload rendering the regular pipe-styled ASCII messages to the client. This allows the server to do less work, while also allowing the client a place to customize this conversion process. To use this plugin you will need to override the current commands in Evennia, changing any place where a raw text output message is generated and turn it into a <code class="docutils literal notranslate"><span class="pre">text2html</span></code> message. For example: <code class="docutils literal notranslate"><span class="pre">target.msg(&quot;my</span> <span class="pre">text&quot;)</span></code> becomes: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=(&quot;my</span> <span class="pre">text&quot;))</span></code> (even better, use a webclient pane routing tag: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=(&quot;my</span> <span class="pre">text&quot;,</span> <span class="pre">{&quot;type&quot;:</span> <span class="pre">&quot;sometag&quot;}))</span></code>) <code class="docutils literal notranslate"><span class="pre">text2html</span></code> messages should format and behave identically to the server-side generated text2html() output.</p></li>
</ul>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="a-side-note-on-html-messages-vrs-text2html-messages">
<h1>A side note on html messages vrs text2html messages<a class="headerlink" href="#a-side-note-on-html-messages-vrs-text2html-messages" title="Permalink to this headline"></a></h1>
<section id="a-side-note-on-html-messages-vs-text2html-messages">
<h3>A side note on html messages vs text2html messages<a class="headerlink" href="#a-side-note-on-html-messages-vs-text2html-messages" title="Permalink to this headline"></a></h3>
<p>So…lets say you have a desire to make your webclient output more like standard webpages…
For telnet clients, you could collect a bunch of text lines together, with ASCII formatted borders, etc.
Then send the results to be rendered client-side via the text2html plugin.</p>
<p>But for webclients, you could format a message directly with the html plugin to render the whole thing as an
HTML table, like so:</p>
For telnet clients, you could collect a bunch of text lines together, with ASCII formatted borders, etc. Then send the results to be rendered client-side via the text2html plugin.</p>
<p>But for webclients, you could format a message directly with the html plugin to render the whole thing as an HTML table, like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="c1"># Server Side Python Code:</span>
<span class="k">if</span> <span class="n">target</span><span class="o">.</span><span class="n">is_webclient</span><span class="p">():</span>
@ -276,13 +262,14 @@ HTML table, like so:</p>
</pre></div>
</div>
</section>
<section class="tex2jax_ignore mathjax_ignore" id="writing-your-own-plugins">
<h1>Writing your own Plugins<a class="headerlink" href="#writing-your-own-plugins" title="Permalink to this headline"></a></h1>
</section>
<section id="writing-your-own-plugins">
<h2>Writing your own Plugins<a class="headerlink" href="#writing-your-own-plugins" title="Permalink to this headline"></a></h2>
<p>So, you love the functionality of the webclient, but your game has specific
types of text that need to be separated out into their own space, visually.
The Goldenlayout plugin framework can help with this.</p>
<section id="goldenlayout">
<h2>GoldenLayout<a class="headerlink" href="#goldenlayout" title="Permalink to this headline"></a></h2>
<h3>GoldenLayout<a class="headerlink" href="#goldenlayout" title="Permalink to this headline"></a></h3>
<p>GoldenLayout is a web framework that allows web developers and their users to create their own
tabbed/windowed layouts. Windows/tabs can be click-and-dragged from location to location by
clicking on their titlebar and dragging until the “frame lines” appear. Dragging a window onto
@ -376,8 +363,7 @@ base.html.</p>
<span class="nb">type</span><span class="o">=</span><span class="s2">&quot;text/javascript&quot;</span><span class="o">&gt;&lt;/</span><span class="n">script</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>Remember, plugins are load-order dependent, so make sure the new <code class="docutils literal notranslate"><span class="pre">&lt;script&gt;</span></code> tag comes before the
goldenlayout.js</p>
<p>Remember, plugins are load-order dependent, so make sure the new <code class="docutils literal notranslate"><span class="pre">&lt;script&gt;</span></code> tag comes before the <code class="docutils literal notranslate"><span class="pre">goldenlayout.js</span></code>.</p>
<p>Next, create a new plugin file <code class="docutils literal notranslate"><span class="pre">mygame/web/static/webclient/js/plugins/myplugin.js</span></code> and
edit it.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>let myplugin = (function () {
@ -405,9 +391,10 @@ edit it.</p>
window.plugin_handler.add(&quot;myplugin&quot;, myplugin);
</pre></div>
</div>
<p>You can then add “mycomponent” to an items componentName in your goldenlayout_default_config.js.</p>
<p>You can then add “mycomponent” to an items <code class="docutils literal notranslate"><span class="pre">componentName</span></code> in your <code class="docutils literal notranslate"><span class="pre">goldenlayout_default_config.js</span></code>.</p>
<p>Make sure to stop your server, evennia collectstatic, and restart your server. Then make sure to clear your browser cache before loading the webclient page.</p>
</section>
</section>
</section>
@ -426,10 +413,10 @@ window.plugin_handler.add(&quot;myplugin&quot;, myplugin);
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Bootstrap-Components-and-Utilities.html" title="Bootstrap Components and Utilities"
<a href="Web-Admin.html" title="The Web Admin"
>next</a> |</li>
<li class="right" >
<a href="Webserver.html" title="Webserver"
<a href="Website.html" title="Game website"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -17,8 +17,8 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Web Client" href="Webclient.html" />
<link rel="prev" title="Server component" href="Server.html" />
<link rel="next" title="Evennia REST API" href="Web-API.html" />
<link rel="prev" title="The Web Admin" href="Web-Admin.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -30,10 +30,10 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Webclient.html" title="Web Client"
<a href="Web-API.html" title="Evennia REST API"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Server.html" title="Server component"
<a href="Web-Admin.html" title="The Web Admin"
accesskey="P">previous</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-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
@ -72,11 +72,11 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Server.html"
title="previous chapter">Server component</a></p>
<p class="topless"><a href="Web-Admin.html"
title="previous chapter">The Web Admin</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Webclient.html"
title="next chapter">Web Client</a></p>
<p class="topless"><a href="Web-API.html"
title="next chapter">Evennia REST API</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -196,10 +196,10 @@ come back or you reload it manually in your browser.</p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Webclient.html" title="Web Client"
<a href="Web-API.html" title="Evennia REST API"
>next</a> |</li>
<li class="right" >
<a href="Server.html" title="Server component"
<a href="Web-Admin.html" title="The Web Admin"
>previous</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-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Evennia REST API" href="Web-API.html" />
<link rel="next" title="Web Client" href="Webclient.html" />
<link rel="prev" title="Signals" href="Signals.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-API.html" title="Evennia REST API"
<a href="Webclient.html" title="Web Client"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Signals.html" title="Signals"
@ -87,8 +87,8 @@
<p class="topless"><a href="Signals.html"
title="previous chapter">Signals</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Web-API.html"
title="next chapter">Evennia REST API</a></p>
<p class="topless"><a href="Webclient.html"
title="next chapter">Web Client</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -517,7 +517,7 @@ on the Django website - it covers all you need.</p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Web-API.html" title="Evennia REST API"
<a href="Webclient.html" title="Web Client"
>next</a> |</li>
<li class="right" >
<a href="Signals.html" title="Signals"

View file

@ -123,24 +123,105 @@ equipment by people who are blind or have otherwise diminished eyesight.</p>
<p>So a good rule of thumb is to use colour to enhance your game but dont <em>rely</em> on it to display
critical information. If you are coding the game, you can add functionality to let users disable
colours as they please, as described <a class="reference internal" href="../Howtos/Manually-Configuring-Color.html"><span class="doc std std-doc">here</span></a>.</p>
<p>To see which colours your client support, use the default <code class="docutils literal notranslate"><span class="pre">&#64;color</span></code> command. This will list all
available colours for ANSI and Xterm256 along with the codes you use for them. You can find a list
of all the parsed <code class="docutils literal notranslate"><span class="pre">ANSI</span></code>-colour codes in <code class="docutils literal notranslate"><span class="pre">evennia/utils/ansi.py</span></code>.</p>
<p>Evennia supports two color standards:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">ANSI</span></code> - 16 foreground colors + 8 background colors. Widely supported.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Xterm256</span></code> - 128 RGB colors, 32 greyscales. Not always supported in old clients.</p></li>
</ul>
<p>To see which colours your client support, use the default <code class="docutils literal notranslate"><span class="pre">color</span></code> command. This will list all
available colours for ANSI and Xterm256 along with the codes you use for them. The
central ansi/xterm256 parser is located in <a class="reference internal" href="../api/evennia.utils.ansi.html#evennia-utils-ansi"><span class="std std-ref">evennia/utils/ansi.py</span></a>.</p>
<section id="ansi-colours">
<h2>ANSI colours<a class="headerlink" href="#ansi-colours" title="Permalink to this headline"></a></h2>
<p>Evennia supports the <code class="docutils literal notranslate"><span class="pre">ANSI</span></code> standard for text. This is by far the most supported MUD-color standard,
available in all but the most ancient mud clients. The ANSI colours are <strong>r</strong>ed, <strong>g</strong>reen,
<strong>y</strong>ellow, <strong>b</strong>lue, <strong>m</strong>agenta, <strong>c</strong>yan, <strong>w</strong>hite and black. They are abbreviated by their
first letter except for black which is abbreviated with the letter <strong>x</strong>. In ANSI there are “bright”
and “normal” (darker) versions of each color, adding up to a total of 16 colours to use for
foreground text. There are also 8 “background” colours. These have no bright alternative in ANSI
(but Evennia uses the <a class="reference internal" href="#xterm256-colours"><span class="std std-doc">Xterm256</span></a> extension behind the scenes to offer
them anyway).</p>
<p>Evennia supports the <code class="docutils literal notranslate"><span class="pre">ANSI</span></code> standard for text. This is by far the most supported MUD-color standard, available in all but the most ancient mud clients.</p>
<p>To colour your text you put special tags in it. Evennia will parse these and convert them to the
correct markup for the client used. If the users client/console/display supports ANSI colour, they
will see the text in the specified colour, otherwise the tags will be stripped (uncolored text).
This works also for non-terminal clients, such as the webclient. For the webclient, Evennia will
translate the codes to HTML RGB colors.</p>
will see the text in the specified colour, otherwise the tags will be stripped (uncolored text).</p>
<p>For the webclient, Evennia will translate the codes to CSS tags.</p>
<table class="colwidths-auto docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Tag</p></th>
<th class="head"><p>Effect</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>|n</p></td>
<td><p>end all color formatting, including background colors.</p></td>
</tr>
<tr class="row-odd"><td><p>|r</p></td>
<td><p>bright red foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|g</p></td>
<td><p>bright green foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|y</p></td>
<td><p>bright yellow foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|b</p></td>
<td><p>bright blue foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|m</p></td>
<td><p>bright magentaforeground color</p></td>
</tr>
<tr class="row-even"><td><p>|c</p></td>
<td><p>bright cyan foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|w</p></td>
<td><p>bright white foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|x</p></td>
<td><p>bright black (dark grey) foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|R</p></td>
<td><p>normal red foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|G</p></td>
<td><p>normal green foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|Y</p></td>
<td><p>normal yellow foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|B</p></td>
<td><p>normal blue foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|M</p></td>
<td><p>normal magentaforeground color</p></td>
</tr>
<tr class="row-even"><td><p>|C</p></td>
<td><p>normal cyan foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|W</p></td>
<td><p>normal white (light grey) foreground color</p></td>
</tr>
<tr class="row-even"><td><p>|X</p></td>
<td><p>normal black foreground color</p></td>
</tr>
<tr class="row-odd"><td><p>|[#</p></td>
<td><p>background colours, e.g. |[c for bright cyan background and |[C a normal cyan background.</p></td>
</tr>
<tr class="row-even"><td><p>|!#</p></td>
<td><p>foreground color that inherits brightness from previous tags. Always uppcase, like |!R</p></td>
</tr>
<tr class="row-odd"><td><p>|h</p></td>
<td><p>make any following foreground ANSI colors bright (no effect on Xterm colors). Use with |!#. Technically, |h|G == |g.</p></td>
</tr>
<tr class="row-even"><td><p>|H</p></td>
<td><p>negates the effects of |h, return foreground to normal (no effect on Xterm colors)</p></td>
</tr>
<tr class="row-odd"><td><p>|/</p></td>
<td><p>line break. Use instead of Python \n when adding strings from in-game.</p></td>
</tr>
<tr class="row-even"><td><p>|-</p></td>
<td><p>tab character when adding strings in-game. Can vay per client, so usually better with spaces.</p></td>
</tr>
<tr class="row-odd"><td><p>|_</p></td>
<td><p>a space. Only needed to avoid auto-cropping at the end of a in-game input</p></td>
</tr>
<tr class="row-even"><td><p>|*</p></td>
<td><p>invert the current text/background colours, like a marker. See note below.</p></td>
</tr>
</tbody>
</table>
<p>Here is an example of the tags in action:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> |rThis text is bright red.|n This is normal text.
|RThis is a dark red text.|n This is normal text.
@ -148,59 +229,21 @@ translate the codes to HTML RGB colors.</p>
|b|[yThis is bright blue text on yellow background.|n This is normal text.
</pre></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">|n</span></code> - this tag will turn off all color formatting, including background colors.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|#</span></code>- markup marks the start of foreground color. The case defines if the text is “bright” or
“normal”. So <code class="docutils literal notranslate"><span class="pre">|g</span></code> is a bright green and <code class="docutils literal notranslate"><span class="pre">|G</span></code> is “normal” (darker) green.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|[#</span></code> is used to add a background colour to the text. The case again specifies if it is “bright”
or “normal”, so <code class="docutils literal notranslate"><span class="pre">|[c</span></code> starts a bright cyan background and <code class="docutils literal notranslate"><span class="pre">|[C</span></code> a darker cyan background.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|!#</span></code> is used to add foreground color without any enforced brightness/normal information.
These are normal-intensity and are thus always given as uppercase, such as
<code class="docutils literal notranslate"><span class="pre">|!R</span></code> for red. The difference between e.g. <code class="docutils literal notranslate"><span class="pre">|!R</span></code> and <code class="docutils literal notranslate"><span class="pre">|R</span></code> is that
<code class="docutils literal notranslate"><span class="pre">|!R</span></code> will “inherit” the brightness setting from previously set color tags, whereas <code class="docutils literal notranslate"><span class="pre">|R</span></code> will
always reset to the normal-intensity red. The <code class="docutils literal notranslate"><span class="pre">|#</span></code> format contains an implicit <code class="docutils literal notranslate"><span class="pre">|h</span></code>/<code class="docutils literal notranslate"><span class="pre">|H</span></code> tag in it:
disabling highlighting when switching to a normal color, and enabling it for bright ones. So <code class="docutils literal notranslate"><span class="pre">|btest</span> <span class="pre">|!Rtest2</span></code> will result in a bright red <code class="docutils literal notranslate"><span class="pre">test2</span></code> since the brightness setting from <code class="docutils literal notranslate"><span class="pre">|b</span></code> “bleeds over”.
You could use this to for example quickly switch the intensity of a multitude of color tags. There
is no background-color equivalent to <code class="docutils literal notranslate"><span class="pre">|!</span></code> style tags.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|h</span></code> is used to make any following foreground ANSI colors bright (it has no effect on Xterm
colors). This is only relevant to use with <code class="docutils literal notranslate"><span class="pre">|!</span></code> type tags and will be valid until the next <code class="docutils literal notranslate"><span class="pre">|n</span></code>,
<code class="docutils literal notranslate"><span class="pre">|H</span></code> or normal (upper-case) <code class="docutils literal notranslate"><span class="pre">|#</span></code> tag. This tag will never affect background colors, those have to be
set bright/normal explicitly. Technically, <code class="docutils literal notranslate"><span class="pre">|h|!G</span></code> is identical to <code class="docutils literal notranslate"><span class="pre">|g</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|H</span></code> negates the effects <code class="docutils literal notranslate"><span class="pre">|h</span></code> and returns all ANSI foreground colors (<code class="docutils literal notranslate"><span class="pre">|!</span></code> and <code class="docutils literal notranslate"><span class="pre">|</span></code> types) to
normal intensity. It has no effect on background and Xterm colors.</p></li>
</ul>
<blockquote>
<div><p>Note: The ANSI standard does not actually support bright backgrounds like <code class="docutils literal notranslate"><span class="pre">|[r</span></code> - the standard
only supports “normal” intensity backgrounds. To get around this Evennia instead implements these
as <a class="reference internal" href="#xterm256-colours"><span class="std std-doc">Xterm256 colours</span></a> behind the scenes. If the client does not support
Xterm256 the ANSI colors will be used instead and there will be no visible difference between using
upper- and lower-case background tags.</p>
</div></blockquote>
<p>If you want to display an ANSI marker as output text (without having any effect), you need to escape
it by preceding its <code class="docutils literal notranslate"><span class="pre">|</span></code> with another <code class="docutils literal notranslate"><span class="pre">|</span></code>:</p>
<p>Note: The ANSI standard does not actually support bright backgrounds like <code class="docutils literal notranslate"><span class="pre">|[r</span></code> - the standard
only supports “normal” intensity backgrounds. To get around this Evennia implements these as <a class="reference internal" href="#xterm256-colours"><span class="std std-doc">Xterm256 colours</span></a> behind the scenes. If the client does not support
Xterm256 the ANSI colors will be used instead and there will be no visible difference between using upper- and lower-case background tags.</p>
<p>If you want to display an ANSI marker as output text (without having any effect), you need to escape it by preceding its <code class="docutils literal notranslate"><span class="pre">|</span></code> with another <code class="docutils literal notranslate"><span class="pre">|</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">say</span> <span class="n">The</span> <span class="o">||</span><span class="n">r</span> <span class="n">ANSI</span> <span class="n">marker</span> <span class="n">changes</span> <span class="n">text</span> <span class="n">color</span> <span class="n">to</span> <span class="n">bright</span> <span class="n">red</span><span class="o">.</span>
</pre></div>
</div>
<p>This will output the raw <code class="docutils literal notranslate"><span class="pre">|r</span></code> without any color change. This can also be necessary if you are doing
ansi art that uses <code class="docutils literal notranslate"><span class="pre">|</span></code> with a letter directly following it.</p>
<p>Use the command</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@color ansi
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>color ansi
</pre></div>
</div>
<p>to get a list of all supported ANSI colours and the tags used to produce them.</p>
<p>A few additional ANSI codes are supported:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">|/</span></code> A line break. You cannot put the normal Python <code class="docutils literal notranslate"><span class="pre">\n</span></code> line breaks in text entered inside the
game (Evennia will filter this for security reasons). This is what you use instead: use the <code class="docutils literal notranslate"><span class="pre">|/</span></code>
marker to format text with line breaks from the game command line.</p></li>
<li><p>`` This will translate into a <code class="docutils literal notranslate"><span class="pre">TAB</span></code> character. This will not always show (or show differently) to
the client since it depends on their local settings. Its often better to use multiple spaces.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|_</span></code> This is a space. You can usually use the normal space character, but if the space is <em>at the
end of the line</em>, Evennia will likely crop it. This tag will not be cropped but always result in a
space.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|*</span></code> This will invert the current text/background colours. Can be useful to mark things (but see
below).</p></li>
</ul>
<section id="caveats-of">
<h3>Caveats of <code class="docutils literal notranslate"><span class="pre">|*</span></code><a class="headerlink" href="#caveats-of" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">|*</span></code> tag (inverse video) is an old ANSI standard and should usually not be used for more than to
@ -240,48 +283,89 @@ manually instead.</p>
</section>
<section id="xterm256-colours">
<h3>Xterm256 Colours<a class="headerlink" href="#xterm256-colours" title="Permalink to this headline"></a></h3>
<p>The <em>Xterm256</em> standard is a colour scheme that supports 256 colours for text and/or background.
While this offers many more possibilities than traditional ANSI colours, be wary that too many text
<p>The <em>Xterm256</em> standard is a colour scheme that supports 256 colours for text and/or background. It can be combined freely with ANSI colors (above), but some ANSI tags dont affect Xterm256 tags.</p>
<p>While this offers many more possibilities than traditional ANSI colours, be wary that too many text
colors will be confusing to the eye. Also, not all clients support Xterm256 - these will instead see
the closest equivalent ANSI color. You can mix Xterm256 tags with ANSI tags as you please.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>|555 This is pure white text.|n This is normal text.
|230 This is olive green text.
|[300 This text has a dark red background.
|005|[054 This is dark blue text on a bright cyan background.
|=a This is a greyscale value, equal to black.
|=m This is a greyscale value, midway between white and black.
|=z This is a greyscale value, equal to white.
|[=m This is a background greyscale value.
</pre></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">|###</span></code> - markup consists of three digits, each an integer from 0 to 5. The three digits describe
the amount of <strong>r</strong>ed, <strong>g</strong>reen and <strong>b</strong>lue (RGB) components used in the colour. So <code class="docutils literal notranslate"><span class="pre">|500</span></code> means
maximum red and none of the other colours - the result is a bright red. <code class="docutils literal notranslate"><span class="pre">|520</span></code> is red with a touch
of green - the result is orange. As opposed to ANSI colors, Xterm256 syntax does not worry about
bright/normal intensity, a brighter (lighter) color is just achieved by upping all RGB values with
the same amount.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|[###</span></code> - this works the same way but produces a coloured background.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|=#</span></code> - markup produces the xterm256 gray scale tones, where <code class="docutils literal notranslate"><span class="pre">#</span></code> is a letter from <code class="docutils literal notranslate"><span class="pre">a</span></code> (black) to
<code class="docutils literal notranslate"><span class="pre">z</span></code> (white). This offers many more nuances of gray than the normal <code class="docutils literal notranslate"><span class="pre">|###</span></code> markup (which only has
four gray tones between solid black and white (<code class="docutils literal notranslate"><span class="pre">|000</span></code>, <code class="docutils literal notranslate"><span class="pre">|111</span></code>, <code class="docutils literal notranslate"><span class="pre">|222</span></code>, <code class="docutils literal notranslate"><span class="pre">|333</span></code> and <code class="docutils literal notranslate"><span class="pre">|444</span></code>)).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">|[=#</span></code> - this works in the same way but produces background gray scale tones.</p></li>
</ul>
<table class="colwidths-auto docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Tag</p></th>
<th class="head"><p>Effect</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>|###</p></td>
<td><p>foreground RGB (red/green/blue), each from 0 to 5.</p></td>
</tr>
<tr class="row-odd"><td><p>|[###</p></td>
<td><p>background RGB</p></td>
</tr>
<tr class="row-even"><td><p>|=#</p></td>
<td><p>a-z foreground greyscale, where <code class="docutils literal notranslate"><span class="pre">a</span></code> is black and <code class="docutils literal notranslate"><span class="pre">z</span></code> is white.</p></td>
</tr>
<tr class="row-odd"><td><p>|[=#</p></td>
<td><p>a-z background greyscale</p></td>
</tr>
</tbody>
</table>
<p>Some examples:</p>
<table class="colwidths-auto docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Tag</p></th>
<th class="head"><p>Effect</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>|500</p></td>
<td><p>bright red</p></td>
</tr>
<tr class="row-odd"><td><p>|050</p></td>
<td><p>bright green</p></td>
</tr>
<tr class="row-even"><td><p>|005</p></td>
<td><p>bright blue</p></td>
</tr>
<tr class="row-odd"><td><p>|520</p></td>
<td><p>red + a little green = orange</p></td>
</tr>
<tr class="row-even"><td><p>|555</p></td>
<td><p>pure white foreground</p></td>
</tr>
<tr class="row-odd"><td><p>|230</p></td>
<td><p>olive green foreground</p></td>
</tr>
<tr class="row-even"><td><p>|[300</p></td>
<td><p>text with a dark red background</p></td>
</tr>
<tr class="row-odd"><td><p>|005|[054</p></td>
<td><p>dark blue text on a bright cyan background</p></td>
</tr>
<tr class="row-even"><td><p>|=a</p></td>
<td><p>greyscale foreground, equal to black</p></td>
</tr>
<tr class="row-odd"><td><p>|=m</p></td>
<td><p>greyscale foreground, midway between white and black.</p></td>
</tr>
<tr class="row-even"><td><p>|=z</p></td>
<td><p>greyscale foreground, equal to white</p></td>
</tr>
<tr class="row-odd"><td><p>|[=m</p></td>
<td><p>greyscale background</p></td>
</tr>
</tbody>
</table>
<p>Xterm256 dont use bright/normal intensity like ANSI does; intensity is just varied by increasing/decreasing all RGB values by the same amount.</p>
<p>If you have a client that supports Xterm256, you can use</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@color xterm256
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>color xterm256
</pre></div>
</div>
<p>to get a table of all the 256 colours and the codes that produce them. If the table looks broken up
into a few blocks of colors, it means Xterm256 is not supported and ANSI are used as a replacement.
You can use the <code class="docutils literal notranslate"><span class="pre">&#64;options</span></code> command to see if xterm256 is active for you. This depends on if your
client told Evennia what it supports - if not, and you know what your client supports, you may have
to activate some features manually.</p>
into a few blocks of colors, it means Xterm256 is not supported and ANSI are used as a replacement. You can use the <code class="docutils literal notranslate"><span class="pre">options</span></code> command to see if xterm256 is active for you. This depends on if your client told Evennia what it supports - if not, and you know what your client supports, you may have to activate some features manually.</p>
</section>
</section>
<section id="more-reading">
<h2>More reading<a class="headerlink" href="#more-reading" title="Permalink to this headline"></a></h2>
<p>There is an <a class="reference internal" href="../Howtos/Understanding-Color-Tags.html"><span class="doc std std-doc">Understanding Color Tags</span></a> tutorial which expands on the
use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context.</p>
<p>There is an <a class="reference internal" href="../Howtos/Understanding-Color-Tags.html"><span class="doc std std-doc">Understanding Color Tags</span></a> tutorial which expands on the use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context.</p>
</section>
</section>

View file

@ -110,12 +110,7 @@
<section class="tex2jax_ignore mathjax_ignore" id="soft-code">
<h1>Soft Code<a class="headerlink" href="#soft-code" title="Permalink to this headline"></a></h1>
<p>Softcode is a very simple programming language that was created for in-game development on TinyMUD
derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea is that by providing a stripped
down, minimalistic language for in-game use, you can allow quick and easy building and game
development to happen without having to learn C/C++. There is an added benefit of not having to have
to hand out shell access to all developers, and permissions can be used to alleviate many security
problems.</p>
<p>Softcode is a very simple programming language that was created for in-game development on TinyMUD derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea is that by providing a stripped down, minimalistic language for in-game use, you can allow quick and easy building and game development to happen without having to learn C/C++. There is an added benefit of not having to have to hand out shell access to all developers, and permissions can be used to alleviate many security problems.</p>
<p>Writing and installing softcode is done through a MUD client. Thus it is not a formatted language.
Each softcode function is a single line of varying size. Some functions can be a half of a page long
or more which is obviously not very readable nor (easily) maintainable over time.</p>
@ -147,25 +142,13 @@ This shorter version looks like this:</p>
</section>
<section id="problems-with-softcode">
<h2>Problems with Softcode<a class="headerlink" href="#problems-with-softcode" title="Permalink to this headline"></a></h2>
<p>Softcode is excellent at what it was intended for: <em>simple things</em>. It is a great tool for making an
interactive object, a room with ambiance, simple global commands, simple economies and coded
systems. However, once you start to try to write something like a complex combat system or a higher
end economy, youre likely to find yourself buried under a mountain of functions that span multiple
objects across your entire code.</p>
<p>Not to mention, softcode is not an inherently fast language. It is not compiled, it is parsed with
each calling of a function. While MUX and MUSH parsers have jumped light years ahead of where they
once were they can still stutter under the weight of more complex systems if not designed properly.</p>
<p>Softcode is excellent at what it was intended for: <em>simple things</em>. It is a great tool for making an interactive object, a room with ambiance, simple global commands, simple economies and coded systems. However, once you start to try to write something like a complex combat system or a higher end economy, youre likely to find yourself buried under a mountain of functions that span multiple objects across your entire code.</p>
<p>Not to mention, softcode is not an inherently fast language. It is not compiled, it is parsed with each calling of a function. While MUX and MUSH parsers have jumped light years ahead of where they once were they can still stutter under the weight of more complex systems if not designed properly.</p>
</section>
<section id="changing-times">
<h2>Changing Times<a class="headerlink" href="#changing-times" title="Permalink to this headline"></a></h2>
<p>Now that starting text-based games is easy and an option for even the most technically inarticulate,
new projects are a dime a dozen. People are starting new MUDs every day with varying levels of
commitment and ability. Because of this shift from fewer, larger, well-staffed games to a bunch of
small, one or two developer games, some of the benefit of softcode fades.</p>
<p>Softcode is great in that it allows a mid to large sized staff all work on the same game without
stepping on one anothers toes. As mentioned before, shell access is not necessary to develop a MUX
or a MUSH. However, now that we are seeing a lot more small, one or two-man shops, the issue of
shell access and stepping on each others toes is a lot less.</p>
<p>Now that starting text-based games is easy and an option for even the most technically inarticulate, new projects are a dime a dozen. People are starting new MUDs every day with varying levels of commitment and ability. Because of this shift from fewer, larger, well-staffed games to a bunch of small, one or two developer games, some of the benefit of softcode fades.</p>
<p>Softcode is great in that it allows a mid to large sized staff all work on the same game without stepping on one anothers toes. As mentioned before, shell access is not necessary to develop a MUX or a MUSH. However, now that we are seeing a lot more small, one or two-man shops, the issue of shell access and stepping on each others toes is a lot less.</p>
</section>
<section id="our-solution">
<h2>Our Solution<a class="headerlink" href="#our-solution" title="Permalink to this headline"></a></h2>
@ -173,22 +156,12 @@ shell access and stepping on each others toes is a lot less.</p>
professional programming language. You code it using the conveniences of modern text editors.
Evennia developers have access to the entire library of Python modules out there in the wild - not
to mention the vast online help resources available. Python code is not bound to one-line functions
on objects but complex systems may be organized neatly into real source code modules, sub-modules,
or even broken out into entire Python packages as desired.</p>
<p>So what is <em>not</em> included in Evennia is a MUX/MOO-like online player-coding system. Advanced coding
in Evennia is primarily intended to be done outside the game, in full-fledged Python modules.
Advanced building is best handled by extending Evennias command system with your own sophisticated
building commands. We feel that with a small development team you are better off using a
professional source-control system (svn, git, bazaar, mercurial etc) anyway.</p>
on objects but complex systems may be organized neatly into real source code modules, sub-modules, or even broken out into entire Python packages as desired.</p>
<p>So what is <em>not</em> included in Evennia is a MUX/MOO-like online player-coding system. Advanced coding in Evennia is primarily intended to be done outside the game, in full-fledged Python modules. Advanced building is best handled by extending Evennias command system with your own sophisticated building commands. We feel that with a small development team you are better off using a professional source-control system (svn, git, bazaar, mercurial etc) anyway.</p>
</section>
<section id="your-solution">
<h2>Your Solution<a class="headerlink" href="#your-solution" title="Permalink to this headline"></a></h2>
<p>Adding advanced and flexible building commands to your game is easy and will probably be enough to
satisfy most creative builders. However, if you really, <em>really</em> want to offer online coding, there
is of course nothing stopping you from adding that to Evennia, no matter our recommendations. You
could even re-implement MUX softcode in Python should you be very ambitious. The
<a class="reference internal" href="../Contribs/Contrib-Ingame-Python.html"><span class="doc std std-doc">in-game-python</span></a> is an optional
pseudo-softcode plugin aimed at developers wanting to script their game from inside it.</p>
<p>Adding advanced and flexible building commands to your game is easy and will probably be enough to satisfy most creative builders. However, if you really, <em>really</em> want to offer online coding, there is of course nothing stopping you from adding that to Evennia, no matter our recommendations. You could even re-implement MUX softcode in Python should you be very ambitious. The <a class="reference internal" href="../Contribs/Contrib-Ingame-Python.html"><span class="doc std std-doc">in-game-python</span></a> is an optional pseudo-softcode plugin aimed at developers wanting to script their game from inside it.</p>
</section>
</section>

View file

@ -106,14 +106,8 @@
<section class="tex2jax_ignore mathjax_ignore" id="using-mux-as-a-standard">
<h1>Using MUX as a Standard<a class="headerlink" href="#using-mux-as-a-standard" title="Permalink to this headline"></a></h1>
<p>Evennia allows for any command syntax. If you like the way DikuMUDs, LPMuds or MOOs handle things,
you could emulate that with Evennia. If you are ambitious you could even design a whole new style,
perfectly fitting your own dreams of the ideal game.</p>
<p>We do offer a default however. The default Evennia setup tends to <em>resemble</em>
<a class="reference external" href="https://www.tinymux.org/">MUX2</a>, and its cousins <a class="reference external" href="https://www.pennmush.org">PennMUSH</a>,
<a class="reference external" href="https://github.com/TinyMUSH/TinyMUSH/wiki">TinyMUSH</a>, and <a class="reference external" href="http://www.rhostmush.com/">RhostMUSH</a>.
While the reason for this similarity is partly historical, these codebases offer very mature feature
sets for administration and building.</p>
<p>Evennia allows for any command syntax. If you like the way DikuMUDs, LPMuds or MOOs handle things, you could emulate that with Evennia. If you are ambitious you could even design a whole new style, perfectly fitting your own dreams of the ideal game.</p>
<p>We do offer a default however. The default Evennia setup tends to <em>resemble</em> <a class="reference external" href="https://www.tinymux.org/">MUX2</a>, and its cousins <a class="reference external" href="https://www.pennmush.org">PennMUSH</a>, <a class="reference external" href="https://github.com/TinyMUSH/TinyMUSH/wiki">TinyMUSH</a>, and <a class="reference external" href="http://www.rhostmush.com/">RhostMUSH</a>. While the reason for this similarity is partly historical, these codebases offer very mature feature sets for administration and building.</p>
<p>Evennia is <em>not</em> a MUX system though. It works very differently in many ways. For example, Evennia
deliberately lacks an online softcode language (a policy explained on our <a class="reference internal" href="Soft-Code.html"><span class="doc std std-doc">softcode policy
page</span></a>). Evennia also does not shy from using its own syntax when deemed appropriate: the

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Character Creator contrib" href="Contrib-Character-Creator.html" />
<link rel="next" title="Character Creator" href="Contrib-Character-Creator.html" />
<link rel="prev" title="XYZgrid" href="Contrib-XYZGrid.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Character-Creator.html" title="Character Creator contrib"
<a href="Contrib-Character-Creator.html" title="Character Creator"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"
@ -110,7 +110,7 @@
title="previous chapter">XYZgrid</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Character-Creator.html"
title="next chapter">Character Creator contrib</a></p>
title="next chapter">Character Creator</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -577,7 +577,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Character-Creator.html" title="Character Creator contrib"
<a href="Contrib-Character-Creator.html" title="Character Creator"
>next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"

View file

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Character Creator contrib &#8212; Evennia 1.0-dev documentation</title>
<title>Character Creator &#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>
@ -37,7 +37,7 @@
accesskey="P">previous</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-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Character Creator contrib</a></li>
<li class="nav-item nav-item-this"><a href="">Character Creator</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
@ -62,7 +62,7 @@
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Character Creator contrib</a><ul>
<li><a class="reference internal" href="#">Character Creator</a><ul>
<li><a class="reference internal" href="#installation">Installation</a><ul>
<li><a class="reference internal" href="#example">Example:</a></li>
</ul>
@ -120,8 +120,8 @@
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="character-creator-contrib">
<h1>Character Creator contrib<a class="headerlink" href="#character-creator-contrib" title="Permalink to this headline"></a></h1>
<section class="tex2jax_ignore mathjax_ignore" id="character-creator">
<h1>Character Creator<a class="headerlink" href="#character-creator" title="Permalink to this headline"></a></h1>
<p>Commands for managing and initiating an in-game character-creation menu.</p>
<p>Contribution by InspectorCaracal, 2022</p>
<section id="installation">
@ -253,7 +253,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
>previous</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-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Character Creator contrib</a></li>
<li class="nav-item nav-item-this"><a href="">Character Creator</a></li>
</ul>
<div class="develop">develop branch</div>
</div>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Health Bar" href="Contrib-Health-Bar.html" />
<link rel="prev" title="Character Creator contrib" href="Contrib-Character-Creator.html" />
<link rel="prev" title="Character Creator" href="Contrib-Character-Creator.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Contrib-Health-Bar.html" title="Health Bar"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-Character-Creator.html" title="Character Creator contrib"
<a href="Contrib-Character-Creator.html" title="Character Creator"
accesskey="P">previous</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-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
@ -74,7 +74,7 @@
<h4>Previous topic</h4>
<p class="topless"><a href="Contrib-Character-Creator.html"
title="previous chapter">Character Creator contrib</a></p>
title="previous chapter">Character Creator</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Health-Bar.html"
title="next chapter">Health Bar</a></p>
@ -192,7 +192,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<a href="Contrib-Health-Bar.html" title="Health Bar"
>next</a> |</li>
<li class="right" >
<a href="Contrib-Character-Creator.html" title="Character Creator contrib"
<a href="Contrib-Character-Creator.html" title="Character Creator"
>previous</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-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>

View file

@ -521,7 +521,7 @@ and rule implementation like character traits, dice rolling and emoting.</em></p
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Buffs.html">Buffs</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Character-Creator.html">Character Creator contrib</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Character-Creator.html">Character Creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Dice.html">Dice roller</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Health-Bar.html">Health Bar</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-RPSystem.html">Roleplaying base system for Evennia</a></li>

View file

@ -122,14 +122,13 @@
you are working on, make a post to the <a class="reference external" href="https://github.com/evennia/evennia/discussions">discussions forum</a>.</p></li>
<li><p>If you want more direct discussions with developers and other users, drop
into our very friendly <a class="reference external" href="https://discord.com/invite/AJJpcRUhtF">Discord channel</a>.</p></li>
<li><p>If you think the documentation is not clear enough, create a <a class="reference external" href="https://github.com/evennia/evennia/issues">documentation issue</a></p></li>
<li><p>If you think the documentation is not clear enough, create a <a class="reference external" href="https://github.com/evennia/evennia/issues">documentation issue</a>.</p></li>
<li><p>If you have trouble with a missing feature or a problem you think is a bug,
<a class="reference external" href="https://github.com/evennia/evennia/issues">request or report it</a>.</p></li>
<a class="reference external" href="https://github.com/evennia/evennia/issues">request, or report it</a>.</p></li>
</ul>
<section id="community-and-spreading-the-word">
<h2>Community and Spreading the word<a class="headerlink" href="#community-and-spreading-the-word" title="Permalink to this headline"></a></h2>
<p>Being active and helpful in the <a class="reference external" href="https://github.com/evennia/evennia/discussions">forums</a> or <a class="reference external" href="https://discord.com/invite/AJJpcRUhtF">chat</a> is already a big
help.</p>
<p>Being active and helpful in the <a class="reference external" href="https://github.com/evennia/evennia/discussions">discssion forums</a> or <a class="reference external" href="https://discord.com/invite/AJJpcRUhtF">chat</a> is already a big help.</p>
<p>Consider writing about Evennia on your blog or in your favorite (relevant)
forum. Write a review somewhere (good or bad, we like feedback either way). Rate
it on listings. Talk about it to your friends … that kind of thing.</p>
@ -142,8 +141,7 @@ great help!</p>
<ul class="simple">
<li><p>Easiest is to just <a class="reference external" href="https://github.com/evennia/evennia/issues">report documentation issues</a> as you find them. If
we dont know about them, we cant fix them!</p></li>
<li><p>If you want to help edit the docs directly, <a class="reference internal" href="Contributing-Docs.html"><span class="doc std std-doc">check here</span></a>
on how to do it.</p></li>
<li><p>If you want to help editing the docs directly, <a class="reference internal" href="Contributing-Docs.html"><span class="doc std std-doc">check here</span></a> on how to do it.</p></li>
<li><p>If you have knowledge to share, how about writing a new <a class="reference internal" href="Howtos/Howtos-Overview.html"><span class="doc std std-doc">Tutorial</span></a>?</p></li>
</ul>
</section>
@ -151,7 +149,7 @@ on how to do it.</p></li>
<h2>Helping with code<a class="headerlink" href="#helping-with-code" title="Permalink to this headline"></a></h2>
<p>If you find bugs, or have a feature-request, <a class="reference external" href="https://github.com/evennia/evennia/issues">make an issue</a> for it. If
its not in an issue, the issue will most likely be forgotten.</p>
<p>Even if you dont feel confident with tackling a <a class="reference external" href="https://github.com/evennia/evennia/issues">bug or feature</a>, just
<p>Even if you dont feel confident with tackling a bug or feature, just
correcting typos, adjusting formatting or simply <em>using</em> the thing and reporting
when stuff doesnt make sense helps us a lot.</p>
<ul class="simple">
@ -166,17 +164,14 @@ is normal and nothing to worry about).</p></li>
<h3>Using a Forked reposity<a class="headerlink" href="#using-a-forked-reposity" title="Permalink to this headline"></a></h3>
<p>The most elegant way to contribute code to Evennia is to use GitHub to create a
<em>fork</em> of the Evennia repository and make your changes to that. Refer to the
<a class="reference internal" href="Coding/Version-Control.html#forking-evennia"><span class="std std-doc">Forking Evennia</span></a> version control instructions
for detailed instructions.</p>
<a class="reference internal" href="Coding/Version-Control.html#forking-evennia"><span class="std std-doc">Forking Evennia</span></a> version control instructions for detailed instructions.</p>
<p>Once you have a fork set up, you can not only work on your own game in a
separate branch, you can also commit your fixes to Evennia itself.</p>
<ul class="simple">
<li><p>Make separate branches for all Evennia additions you do - dont edit your
local <code class="docutils literal notranslate"><span class="pre">master</span></code> or <code class="docutils literal notranslate"><span class="pre">develop</span></code> branches directly. It will make your life a lot
easier.</p></li>
local <code class="docutils literal notranslate"><span class="pre">master</span></code> or <code class="docutils literal notranslate"><span class="pre">develop</span></code> branches directly. It will make your life a lot easier.</p></li>
<li><p>If you have a change that you think is suitable for the main Evennia
repository, issue a <a class="reference external" href="https://github.com/evennia/evennia/pulls">Pull Request</a>. This will let Evennia
devs know you have stuff to share.</p></li>
repository, issue a <a class="reference external" href="https://github.com/evennia/evennia/pulls">Pull Request</a>. This will let Evennia devs know you have stuff to share.</p></li>
<li><p>Bug fixes should generally be done against the <code class="docutils literal notranslate"><span class="pre">master</span></code> branch of Evennia,
while new features/contribs should go into the <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch. If you are
unsure, just pick one and well figure it out.</p></li>

View file

@ -67,9 +67,9 @@
<li><a class="reference internal" href="#i-dont-know-or-dont-want-to-do-any-programming-i-just-want-to-run-a-game">I dont know (or dont want to do) any programming - I just want to run a game!</a></li>
<li><a class="reference internal" href="#i-know-basic-python-or-i-am-willing-to-learn">I know basic Python, or I am willing to learn</a></li>
<li><a class="reference internal" href="#i-know-my-python-stuff-and-i-am-willing-to-use-it">I know my Python stuff and I am willing to use it!</a></li>
<li><a class="reference internal" href="#where-to-from-here">Where to from here?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#where-to-from-here">Where to from here?</a></li>
</ul>
</li>
</ul>
@ -126,8 +126,7 @@ might just be starting to think about it, or you might have lugged around that <
your mind for years … you know <em>just</em> how good it would be, if you could only make it come to
reality. We know how you feel. That is, after all, why Evennia came to be.</p>
<p>Evennia is a MU*-building system: a bare-bones Python codebase and server intended to
be highly extendable for any style of game. “Bare-bones” in this context means that we try to impose
as few game-specific things on you as possible. For convenience offer basic building
be highly extendable for any style of game. “Bare-bones” in this context means that we try to impose as few game-specific things on you as possible. For convenience offer basic building
blocks like objects, characters, rooms, default commands for building and administration etc, we
dont prescribe any combat rules, mob AI, races, skills, character classes or other things that will
be different from game to game anyway.</p>
@ -136,19 +135,9 @@ behind-the-scenes administration stuff that all online games need whether they l
Evennia is <em>fully persistent</em>, that means things you drop on the ground somewhere will still be
there a dozen server reboots later. Through Django we support a large variety of different database
systems (a database is created for you automatically if you use the defaults).</p>
<p>We also include a growing list of <em>optional</em> <a class="reference internal" href="Contribs/Contribs-Overview.html"><span class="doc std std-doc">contribs</span></a> you can use for your game
would you want something to build from.</p>
<p>Using the full power of Python throughout the server offers some distinct advantages. All your
coding, from object definitions and custom commands to AI scripts and economic systems is done in
normal Python modules rather than some ad-hoc scripting language. The fact that you script the game
in the same high-level language that you code it in allows for very powerful and custom game
implementations indeed.</p>
<p>Out of the box, Evennia gives you a talker-type of game; you can walk around, chat, build rooms and objects,
do basic roleplaying and administration. The server ships with a default set of player commands that are
similar to the MUX command set. We <em>do not</em> aim specifically to be a MUX server, but we had to pick some
default to go with (see <a class="reference internal" href="Concepts/Soft-Code.html"><span class="doc std std-doc">this</span></a> for more about our original motivations). Its easy to
remove or add commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on.
Or why not create a new and better command system of your own design.</p>
<p>We also include a growing list of <em>optional</em> <a class="reference internal" href="Contribs/Contribs-Overview.html"><span class="doc std std-doc">contribs</span></a> you can use for your game would you want something to build from.</p>
<p>Using the full power of Python throughout the server offers some distinct advantages. All your coding, from object definitions and custom commands to AI scripts and economic systems is done in normal Python modules rather than some ad-hoc scripting language. The fact that you script the game in the same high-level language that you code it in allows for very powerful and custom game implementations indeed.</p>
<p>Out of the box, Evennia gives you a talker-type of game; you can walk around, chat, build rooms and objects, do basic roleplaying and administration. The server ships with a default set of player commands that are similar to the MUX command set. We <em>do not</em> aim specifically to be a MUX server, but we had to pick some default to go with (see <a class="reference internal" href="Concepts/Soft-Code.html"><span class="doc std std-doc">this</span></a> for more about our original motivations). Its easy to remove or add commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on. Or why not create a new and better command system of your own design.</p>
<section id="can-i-test-it-somewhere">
<h2>Can I test it somewhere?<a class="headerlink" href="#can-i-test-it-somewhere" title="Permalink to this headline"></a></h2>
<p>Evennias demo server can be found at <a class="reference external" href="https://demo.evennia.com">https://demo.evennia.com</a>. If you prefer to
@ -164,36 +153,19 @@ gotten as far as to start the server and connect to it with the client of your c
you need to know depending on your skills and needs.</p>
<section id="i-dont-know-or-dont-want-to-do-any-programming-i-just-want-to-run-a-game">
<h3>I dont know (or dont want to do) any programming - I just want to run a game!<a class="headerlink" href="#i-dont-know-or-dont-want-to-do-any-programming-i-just-want-to-run-a-game" title="Permalink to this headline"></a></h3>
<p>Evennia comes with a default set of commands for the Python newbies and for those who need to get a
game running <em>now</em>. Stock Evennia is enough for running a simple Talker-type game - you can build
and describe rooms and basic objects, have chat channels, do emotes and other things suitable for a
social or free-form MU*. Combat, mobs and other game elements are not included, so youll have a
very basic game indeed if you are not willing to do at least <em>some</em> coding.</p>
<p>Evennia comes with a default set of commands for the Python newbies and for those who need to get a game running <em>now</em>. Stock Evennia is enough for running a simple Talker-type game - you can build and describe rooms and basic objects, have chat channels, do emotes and other things suitable for a social or free-form MU*. Combat, mobs and other game elements are not included, so youll have a very basic game indeed if you are not willing to do at least <em>some</em> coding.</p>
</section>
<section id="i-know-basic-python-or-i-am-willing-to-learn">
<h3>I know basic Python, or I am willing to learn<a class="headerlink" href="#i-know-basic-python-or-i-am-willing-to-learn" title="Permalink to this headline"></a></h3>
<p>Evennias source code is extensively documented and is <a class="reference external" href="https://github.com/evennia/evennia">viewable
online</a>. We also have a comprehensive <a class="reference external" href="https://evennia.com/docs">online
manual</a> with lots of examples. But while Python is
considered a very easy programming language to get into, you do have a learning curve to climb if
you are new to programming. Evennias <a class="reference internal" href="Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.html"><span class="doc std std-doc">Starting-tutorial</span></a> has a <a class="reference internal" href="Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.html"><span class="doc std std-doc">basic introduction
to Python</span></a> but you should probably also sit down
with a full Python beginners tutorial at some point (there are plenty of them on
the web if you look around). See also our <a class="reference internal" href="Links.html"><span class="doc std std-doc">link
page</span></a> for some reading suggestions. To efficiently code your dream game in
Evennia you dont need to be a Python guru, but you do need to be able to read example code
containing at least these basic Python features:</p>
<p>Evennias source code is <a class="reference external" href="https://www.evennia.com/docs/latest">extensively documented</a>. But while Python is considered a very easy programming language to get into, you do have a learning curve to climb if you are new to programming. Evennias <a class="reference internal" href="Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.html"><span class="doc std std-doc">Starting-tutorial</span></a> has a <a class="reference internal" href="Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.html"><span class="doc std std-doc">basic introduction to Python</span></a> but you should probably also sit down with a full Python beginners tutorial at some point (there are plenty of them on the web if you look around). See also our <a class="reference internal" href="Links.html"><span class="doc std std-doc">link page</span></a> for some reading suggestions.</p>
<p>To code your dream game in Evennia you dont need to be a Python guru, but you do need to be able to read example code containing at least these basic Python features:</p>
<ul class="simple">
<li><p>Importing and using python <a class="reference external" href="https://docs.python.org/3.7/tutorial/modules.html">modules</a></p></li>
<li><p>Using <a class="reference external" href="https://www.tutorialspoint.com/python/python_variable_types.htm">variables</a>, <a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#if-statements">conditional
statements</a>,
<a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#for-statements">loops</a> and
<a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#defining-functions">functions</a></p></li>
<li><p>Using <a class="reference external" href="https://docs.python.org/tutorial/datastructures.html">lists, dictionaries and list
comprehensions</a></p></li>
<li><p>Using <a class="reference external" href="https://www.tutorialspoint.com/python/python_variable_types.htm">variables</a>, <a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#if-statements">conditional statements</a>,
<a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#for-statements">loops</a> and <a class="reference external" href="https://docs.python.org/tutorial/controlflow.html#defining-functions">functions</a></p></li>
<li><p>Using <a class="reference external" href="https://docs.python.org/tutorial/datastructures.html">lists, dictionaries and list comprehensions</a></p></li>
<li><p>Doing <a class="reference external" href="https://docs.python.org/tutorial/introduction.html#strings">string handling and formatting</a></p></li>
<li><p>Have a basic understanding of <a class="reference external" href="https://www.tutorialspoint.com/python/python_classes_objects.htm">object-oriented
programming</a>, using
<li><p>Have a basic understanding of <a class="reference external" href="https://www.tutorialspoint.com/python/python_classes_objects.htm">object-oriented programming</a>, using
<a class="reference external" href="https://docs.python.org/tutorial/classes.html">Classes</a>, their methods and properties</p></li>
</ul>
<p>Obviously, the more things you feel comfortable with, the easier time youll have to find your way.
@ -203,38 +175,15 @@ definitely build a whole advanced and customized game from extending Evennias
</section>
<section id="i-know-my-python-stuff-and-i-am-willing-to-use-it">
<h3>I know my Python stuff and I am willing to use it!<a class="headerlink" href="#i-know-my-python-stuff-and-i-am-willing-to-use-it" title="Permalink to this headline"></a></h3>
<p>Even if you started out as a Python beginner, you will likely get to this point after working on
your game for a while. With more general knowledge in Python the full power of Evennia opens up for
you. Apart from modifying commands, objects and scripts, you can develop everything from advanced
mob AI and economic systems, through sophisticated combat and social mini games, to redefining how
commands, players, rooms or channels themselves work. Since you code your game by importing normal
Python modules, there are few limits to what you can accomplish.</p>
<p>Even if you started out as a Python beginner, you will likely get to this point after working on your game for a while. With more general knowledge in Python the full power of Evennia opens up for you. Apart from modifying commands, objects and scripts, you can develop everything from advanced mob AI and economic systems, through sophisticated combat and social mini games, to redefining how commands, players, rooms or channels themselves work. Since you code your game by importing normal Python modules, there are few limits to what you can accomplish.</p>
<p>If you <em>also</em> happen to know some web programming (HTML, CSS, Javascript) there is also a web
presence (a website and a mud web client) to play around with …</p>
</section>
<section id="where-to-from-here">
<h3>Where to from here?<a class="headerlink" href="#where-to-from-here" title="Permalink to this headline"></a></h3>
<p>From here you can continue browsing the <a class="reference internal" href="index.html"><span class="doc std std-doc">online documentation</span></a> to
find more info about Evennia. Or you can jump into the <a class="reference internal" href="Howtos/Howtos-Overview.html"><span class="doc std std-doc">Tutorials</span></a> and get your hands
dirty with code right away. You can also read the lead developers <a class="reference external" href="https://evennia.blogspot.com/">dev blog</a> for many tidbits and snippets about Evennias development and
structure.</p>
<p>Some more hints:</p>
<ol class="simple">
<li><p>Get engaged in the community. Make an introductory post to our <a class="reference external" href="https://groups.google.com/forum/#%21forum/evennia">mailing
list/forum</a> and get to know people. Its also
highly recommended you hop onto our <a class="reference external" href="https://webchat.freenode.net/?channels=evennia&amp;uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">Developer
chat</a>
on IRC. This allows you to chat directly with other developers new and old as well as with the devs
of Evennia itself. This chat is logged (you can find links on <a class="reference external" href="https://www.evennia.com">https://www.evennia.com</a>) and can also
be searched from the same place for discussion topics you are interested in.</p></li>
<li><p>Read the <a class="reference internal" href="Howtos/Beginner-Tutorial/Part2/Beginner-Tutorial-Game-Planning.html"><span class="doc std std-doc">Game Planning</span></a> wiki page. It gives some ideas for your work flow and the
state of mind you should aim for - including cutting down the scope of your game for its first
release.</p></li>
<li><p>Do the <a class="reference internal" href="Howtos/Tutorial-for-basic-MUSH-like-game.html"><span class="doc std std-doc">Tutorial for basic MUSH-like game</span></a> carefully from
beginning to end and try to understand what does what. Even if you are not interested in a MUSH for
your own game, you will end up with a small (very small) game that you can build or learn from.</p></li>
</ol>
</section>
<section id="where-to-from-here">
<h2>Where to from here?<a class="headerlink" href="#where-to-from-here" title="Permalink to this headline"></a></h2>
<p>Its recommended you jump into the <a class="reference internal" href="Howtos/Beginner-Tutorial/Beginner-Tutorial-Intro.html"><span class="doc std std-doc">Beginner Tutorial</span></a>. You can either follow it or jump around to lessons that seem interesting. You can also read the lead developers <a class="reference external" href="https://www.evennia.com/devblog/index.html">dev blog</a> for many tidbits and snippets about Evennias development and structure.</p>
<p>Sometimes its easier to ask for help. Get engaged in the Evennia community by joining our <a class="reference external" href="https://discord.gg/AJJpcRUhtF">Discord</a> for direct support. Make an introductory post to our <a class="reference external" href="https://github.com/evennia/evennia/discussions">Discussion forum</a> and say hi!.</p>
</section>
</section>

View file

@ -295,6 +295,7 @@ Click here to expand a list of all Beginner-Tutorial sections (all parts).
<li class="toctree-l3"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html">6. Overview of the Evennia library</a><ul>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#where-is-it">6.1. Where is it?</a></li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#an-example-of-exploring-the-library">6.2. An example of exploring the library</a></li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#conclusions">6.3. Conclusions</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html">7. Making objects persistent</a><ul>
@ -305,7 +306,8 @@ Click here to expand a list of all Beginner-Tutorial sections (all parts).
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#typeclasses">7.2. Typeclasses</a><ul>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#examining-and-defaults">7.2.1. Examining and defaults</a></li>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#examining-objects">7.2.1. Examining objects</a></li>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#default-typeclasses">7.2.2. Default typeclasses</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#modifying-ourselves">7.3. Modifying ourselves</a><ul>
@ -447,6 +449,7 @@ Click here to expand a list of all Beginner-Tutorial sections (all parts).
<li class="toctree-l3"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html">6. Overview of the Evennia library</a><ul>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#where-is-it">6.1. Where is it?</a></li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#an-example-of-exploring-the-library">6.2. An example of exploring the library</a></li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Evennia-Library-Overview.html#conclusions">6.3. Conclusions</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html">7. Making objects persistent</a><ul>
@ -457,7 +460,8 @@ Click here to expand a list of all Beginner-Tutorial sections (all parts).
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#typeclasses">7.2. Typeclasses</a><ul>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#examining-and-defaults">7.2.1. Examining and defaults</a></li>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#examining-objects">7.2.1. Examining objects</a></li>
<li class="toctree-l5"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#default-typeclasses">7.2.2. Default typeclasses</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="Part1/Beginner-Tutorial-Learning-Typeclasses.html#modifying-ourselves">7.3. Modifying ourselves</a><ul>

View file

@ -113,9 +113,9 @@
<section class="tex2jax_ignore mathjax_ignore" id="adding-custom-commands">
<h1><span class="section-number">8. </span>Adding custom commands<a class="headerlink" href="#adding-custom-commands" title="Permalink to this headline"></a></h1>
<p>In this lesson well learn how to create our own Evennia <em>Commands</em>. If you are new to Python youll also learn some more basics about how to manipulate strings and get information out of Evennia.</p>
<p>In this lesson well learn how to create our own Evennia <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a> If you are new to Python youll also learn some more basics about how to manipulate strings and get information out of Evennia.</p>
<p>A Command is something that handles the input from a user and causes a result to happen.
An example is <code class="docutils literal notranslate"><span class="pre">look</span></code>, which examines your current location and tells how it looks like and
An example is <code class="docutils literal notranslate"><span class="pre">look</span></code>, which examines your current location and tells you what it looks like and
what is in it.</p>
<aside class="sidebar">
<p class="sidebar-title">Commands are not typeclassed</p>
@ -124,19 +124,9 @@ CommandSets are not <code class="docutils literal notranslate"><span class="pre"
database. They are “just” normal Python classes.</p>
</aside>
<p>In Evennia, a Command is a Python <em>class</em>. If you are unsure about what a class is, review the
previous lessons! A Command inherits from <code class="docutils literal notranslate"><span class="pre">evennia.Command</span></code> or from one of the alternative command-
classes, such as <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> which is what most default commands use.</p>
<p>All Commands are in turn grouped in another class called a <em>Command Set</em>. Think of a Command Set
as a bag holding many different commands. One CmdSet could for example hold all commands for
combat, another for building etc. By default, Evennia groups all character-commands into one
big cmdset.</p>
<p>Command-Sets are then associated with objects, for example with your Character. Doing so makes the
commands in that cmdset available to the object. So, to summarize:</p>
<ul class="simple">
<li><p>Commands are classes</p></li>
<li><p>A group of Commands is stored in a CmdSet</p></li>
<li><p>CmdSets are stored on objects - this defines which commands are available to that object.</p></li>
</ul>
<a class="reference internal" href="Beginner-Tutorial-Python-classes-and-objects.html"><span class="doc std std-doc">previous lesson about it</span></a>! A Command inherits from <code class="docutils literal notranslate"><span class="pre">evennia.Command</span></code> or from one of the alternative command- classes, such as <code class="docutils literal notranslate"><span class="pre">MuxCommand</span></code> which is what most default commands use.</p>
<p>All Commands are grouped in another class called a <em>Command Set</em>. Think of a Command Set as a bag holding many different commands. One CmdSet could for example hold all commands for combat, another for building etc.</p>
<p>Command-Sets are then associated with objects, for example with your Character. Doing so makes the commands in that cmdset available to the object. By default, Evennia groups all character-commands into one big cmdset called the <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>. It sits on <code class="docutils literal notranslate"><span class="pre">DefaultCharacter</span></code> (and thus, through inheritance, on <code class="docutils literal notranslate"><span class="pre">typeclasses.characters.Character</span></code>).</p>
<section id="creating-a-custom-command">
<h2><span class="section-number">8.1. </span>Creating a custom command<a class="headerlink" href="#creating-a-custom-command" title="Permalink to this headline"></a></h2>
<p>Open <code class="docutils literal notranslate"><span class="pre">mygame/commands/command.py</span></code>:</p>
@ -158,17 +148,13 @@ commands in that cmdset available to the object. So, to summarize:</p>
</pre></div>
</div>
<p>Ignoring the docstrings (which you can read if you want), this is the only really active code in the module.</p>
<p>We can see that we import <code class="docutils literal notranslate"><span class="pre">Command</span></code> from <code class="docutils literal notranslate"><span class="pre">evennia</span></code> and use the <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">...</span> <span class="pre">as</span> <span class="pre">...</span></code> form to rename it
to <code class="docutils literal notranslate"><span class="pre">BaseCommand</span></code>. This is so we can let our child class also be named <code class="docutils literal notranslate"><span class="pre">Command</span></code> for reference. The class
itself doesnt do anything, it just has <code class="docutils literal notranslate"><span class="pre">pass</span></code>. So in the same way as <code class="docutils literal notranslate"><span class="pre">Object</span></code> in the previous lesson, this
class is identical to its parent.</p>
<p>We can see that we import <code class="docutils literal notranslate"><span class="pre">Command</span></code> from <code class="docutils literal notranslate"><span class="pre">evennia</span></code> and use the <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">...</span> <span class="pre">as</span> <span class="pre">...</span></code> form to rename it to <code class="docutils literal notranslate"><span class="pre">BaseCommand</span></code>. This is so we can let our child class also be named <code class="docutils literal notranslate"><span class="pre">Command</span></code> to make it easier to reference. The class itself doesnt do anything, it just has <code class="docutils literal notranslate"><span class="pre">pass</span></code>. So in the same way as <code class="docutils literal notranslate"><span class="pre">Object</span></code> and <code class="docutils literal notranslate"><span class="pre">Character</span></code> in the previous lessons, this class is identical to its parent.</p>
<blockquote>
<div><p>The commented out <code class="docutils literal notranslate"><span class="pre">default_cmds</span></code> gives us access to Evennias default commands for easy overriding. Well try
that a little later.</p>
<div><p>The commented out <code class="docutils literal notranslate"><span class="pre">default_cmds</span></code> gives us access to Evennias default commands for easy overriding. Well try that a little later.</p>
</div></blockquote>
<p>We could modify this module directly, but to train imports well work in a separate module. Open a new file
<code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code> and add the following code:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<p>We could modify this module directly, but lets work in a separate module just for the heck of it. Open a new file <code class="docutils literal notranslate"><span class="pre">mygame/commands/mycommands.py</span></code> and add the following code:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/commands/mycommands.py</span>
<span class="kn">from</span> <span class="nn">commands.command</span> <span class="kn">import</span> <span class="n">Command</span>
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
@ -194,15 +180,12 @@ what you will use to call this command later.</p>
</pre></div>
</div>
<p>Our <code class="docutils literal notranslate"><span class="pre">EchoCmdSet</span></code> class must have an <code class="docutils literal notranslate"><span class="pre">at_cmdset_creation</span></code> method, named exactly
like this - this is what Evennia will be looking for when setting up the cmdset later, so
if you didnt set it up, it will use the parents version, which is empty. Inside we add the
command class to the cmdset by <code class="docutils literal notranslate"><span class="pre">self.add()</span></code>. If you wanted to add more commands to this CmdSet you
could just add more lines of <code class="docutils literal notranslate"><span class="pre">self.add</span></code> after this.</p>
<p>Our <code class="docutils literal notranslate"><span class="pre">EchoCmdSet</span></code> class must have an <code class="docutils literal notranslate"><span class="pre">at_cmdset_creation</span></code> method, named exactly like this - this is what Evennia will be looking for when setting up the cmdset later, so if you didnt set it up, it will use the parents version, which is empty. Inside we add the command class to the cmdset by <code class="docutils literal notranslate"><span class="pre">self.add()</span></code>. If you wanted to add more commands to this CmdSet you could just add more lines of <code class="docutils literal notranslate"><span class="pre">self.add</span></code> after this.</p>
<p>Finally, lets add this command to ourselves so we can try it out. In-game you can experiment with <code class="docutils literal notranslate"><span class="pre">py</span></code> again:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.cmdset.add(&quot;commands.mycommands.MyCmdSet&quot;)
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py me.cmdset.add(&quot;commands.mycommands.MyCmdSet&quot;)
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">me.cmdset</span></code> is the store of all cmdsets stored on us. By giving the path to our CmdSet class, it will be added.</p>
<p>Now try</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; echo
Command echo has no defined `func()` - showing on-command variables:
@ -210,9 +193,7 @@ Command echo has no defined `func()` - showing on-command variables:
...
</pre></div>
</div>
<p>You should be getting a long list of outputs. The reason for this is that your <code class="docutils literal notranslate"><span class="pre">echo</span></code> function is not really
“doing” anything yet and the default function is then to show all useful resources available to you when you
use your Command. Lets look at some of those listed:</p>
<p><code class="docutils literal notranslate"><span class="pre">echo</span></code> works! You should be getting a long list of outputs. The reason for this is that your <code class="docutils literal notranslate"><span class="pre">echo</span></code> function is not really “doing” anything yet and the default function is then to show all useful resources available to you when you use your Command. Lets look at some of those listed:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Command echo has no defined `func()` - showing on-command variables:
obj (&lt;class &#39;typeclasses.characters.Character&#39;&gt;): YourName
lockhandler (&lt;class &#39;evennia.locks.lockhandler.LockHandler&#39;&gt;): cmd:all()
@ -244,17 +225,13 @@ command string given (self.cmdstring): echo
current cmdset (self.cmdset): ChannelCmdSet
</pre></div>
</div>
<p>These are all properties you can access with <code class="docutils literal notranslate"><span class="pre">.</span></code> on the Command instance, such as <code class="docutils literal notranslate"><span class="pre">.key</span></code>, <code class="docutils literal notranslate"><span class="pre">.args</span></code> and so on.
Evennia makes these available to you and they will be different every time a command is run. The most
important ones we will make use of now are:</p>
<p>These are all properties you can access with <code class="docutils literal notranslate"><span class="pre">.</span></code> on the Command instance, such as <code class="docutils literal notranslate"><span class="pre">.key</span></code>, <code class="docutils literal notranslate"><span class="pre">.args</span></code> and so on. Evennia makes these available to you and they will be different every time a command is run. The most important ones we will make use of now are:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">caller</span></code> - this is you, the person calling the command.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">args</span></code> - this is all arguments to the command. Now its empty, but if you tried <code class="docutils literal notranslate"><span class="pre">echo</span> <span class="pre">foo</span> <span class="pre">bar</span></code> youd find
that this would be <code class="docutils literal notranslate"><span class="pre">&quot;</span> <span class="pre">foo</span> <span class="pre">bar&quot;</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">args</span></code> - this is all arguments to the command. Now its empty, but if you tried <code class="docutils literal notranslate"><span class="pre">echo</span> <span class="pre">foo</span> <span class="pre">bar</span></code> youd find that this would be <code class="docutils literal notranslate"><span class="pre">&quot;</span> <span class="pre">foo</span> <span class="pre">bar&quot;</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">obj</span></code> - this is object on which this Command (and CmdSet) “sits”. So you, in this case.</p></li>
</ul>
<p>The reason our command doesnt do anything yet is because its missing a <code class="docutils literal notranslate"><span class="pre">func</span></code> method. This is what Evennia
looks for to figure out what a Command actually does. Modify your <code class="docutils literal notranslate"><span class="pre">CmdEcho</span></code> class:</p>
<p>The reason our command doesnt do anything yet is because its missing a <code class="docutils literal notranslate"><span class="pre">func</span></code> method. This is what Evennia looks for to figure out what a Command actually does. Modify your <code class="docutils literal notranslate"><span class="pre">CmdEcho</span></code> class:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
@ -273,14 +250,13 @@ looks for to figure out what a Command actually does. Modify your <code class="d
<span class="c1"># ...</span>
</pre></div>
</div>
<p>First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also
automatically become the in-game help entry! Next we add the <code class="docutils literal notranslate"><span class="pre">func</span></code> method. It has one active line where it
makes use of some of those variables we found the Command offers to us. If you did the
<a class="reference internal" href="Beginner-Tutorial-Python-basic-introduction.html"><span class="doc std std-doc">basic Python tutorial</span></a>, you will recognize <code class="docutils literal notranslate"><span class="pre">.msg</span></code> - this will send a message
to the object it is attached to us - in this case <code class="docutils literal notranslate"><span class="pre">self.caller</span></code>, that is, us. We grab <code class="docutils literal notranslate"><span class="pre">self.args</span></code> and includes
that in the message.</p>
<p>Since we havent changed <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code>, that will work as before. Reload and re-add this command to ourselves to
try out the new version:</p>
<p>First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also automatically become the in-game help entry!</p>
<aside class="sidebar">
<p class="sidebar-title">Use Command.msg </p>
<p>In a Command class, the <code class="docutils literal notranslate"><span class="pre">self.msg()</span></code> acts as a convenient shortcut for <code class="docutils literal notranslate"><span class="pre">self.caller.msg()</span></code>. Not only is it shorter, it also has some advantages because the command can include more metadata with the message. So using <code class="docutils literal notranslate"><span class="pre">self.msg()</span></code> is usually better. For this tutorial though, <code class="docutils literal notranslate"><span class="pre">self.caller.msg()</span></code> is more explicit in showing what is going on.</p>
</aside>
<p>Next we add the <code class="docutils literal notranslate"><span class="pre">func</span></code> method. It has one active line where it makes use of some of those variables the Command class offers to us. If you did the <a class="reference internal" href="Beginner-Tutorial-Python-basic-introduction.html"><span class="doc std std-doc">basic Python tutorial</span></a>, you will recognize <code class="docutils literal notranslate"><span class="pre">.msg</span></code> - this will send a message to the object it is attached to us - in this case <code class="docutils literal notranslate"><span class="pre">self.caller</span></code>, that is, us. We grab <code class="docutils literal notranslate"><span class="pre">self.args</span></code> and includes that in the message.</p>
<p>Since we havent changed <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code>, that will work as before. Reload and re-add this command to ourselves to try out the new version:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; reload
&gt; py self.cmdset.add(&quot;commands.mycommands.MyCmdSet&quot;)
&gt; echo
@ -292,14 +268,12 @@ Echo: &#39;&#39;
Echo: &#39; Woo Tang!&#39;
</pre></div>
</div>
<p>Note that there is an extra space before <code class="docutils literal notranslate"><span class="pre">Woo!</span></code>. That is because self.args contains the <em>everything</em> after
the command name, including spaces. Evennia will happily understand if you skip that space too:</p>
<p>Note that there is an extra space before <code class="docutils literal notranslate"><span class="pre">Woo!</span></code>. That is because self.args contains <em>everything</em> after the command name, including spaces. Evennia will happily understand if you skip that space too:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; echoWoo Tang!
Echo: &#39;Woo Tang!&#39;
</pre></div>
</div>
<p>There are ways to force Evennia to <em>require</em> an initial space, but right now we want to just ignore it since
it looks a bit weird for our echo example. Tweak the code:</p>
<p>There are ways to force Evennia to <em>require</em> an initial space, but right now we want to just ignore it since it looks a bit weird for our echo example. Tweak the code:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">CmdEcho</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
@ -318,9 +292,7 @@ it looks a bit weird for our echo example. Tweak the code:</p>
<span class="c1"># ...</span>
</pre></div>
</div>
<p>The only difference is that we called <code class="docutils literal notranslate"><span class="pre">.strip()</span></code> on <code class="docutils literal notranslate"><span class="pre">self.args</span></code>. This is a helper method available on all
strings - it strips out all whitespace before and after the string. Now the Command-argument will no longer
have any space in front of it.</p>
<p>The only difference is that we called <code class="docutils literal notranslate"><span class="pre">.strip()</span></code> on <code class="docutils literal notranslate"><span class="pre">self.args</span></code>. This is a helper method available on all strings - it strips out all whitespace before and after the string. Now the Command-argument will no longer have any space in front of it.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; reload
&gt; py self.cmdset.add(&quot;commands.mycommands.MyCmdSet&quot;)
&gt; echo Woo Tang!
@ -331,7 +303,7 @@ Echo: &#39;Woo Tang!&#39;
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; help echo
</pre></div>
</div>
<p>You will get the docstring you put in your Command-class.</p>
<p>You will get the docstring you put in your Command-class!</p>
<section id="making-our-cmdset-persistent">
<h3><span class="section-number">8.1.1. </span>Making our cmdset persistent<a class="headerlink" href="#making-our-cmdset-persistent" title="Permalink to this headline"></a></h3>
<p>Its getting a little annoying to have to re-add our cmdset every time we reload, right? Its simple
@ -340,7 +312,7 @@ enough to make <code class="docutils literal notranslate"><span class="pre">echo
</pre></div>
</div>
<p>Now you can <code class="docutils literal notranslate"><span class="pre">reload</span></code> as much as you want and your code changes will be available directly without
needing to re-add the MyCmdSet again. To remove the cmdset again, do</p>
needing to re-add the MyCmdSet again. To remove the cmdset again, youd do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.cmdset.remove(&quot;commands.mycommands.MyCmdSet&quot;)
</pre></div>
</div>
@ -354,7 +326,7 @@ someone in the face! This is how we want it to work:</p>
You hit &lt;target&gt; with full force!
</pre></div>
</div>
<p>Not only that, we want the <target> to see</p>
<p>Not only that, we want the <code class="docutils literal notranslate"><span class="pre">&lt;target&gt;</span></code> to see</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You got hit by &lt;hitter&gt; with full force!
</pre></div>
</div>
@ -432,11 +404,9 @@ else:
the <code class="docutils literal notranslate"><span class="pre">else</span></code> condition is given, it will run if none of the other conditions was truthy. In Python
the <code class="docutils literal notranslate"><span class="pre">if..elif..else</span></code> structure also serves the same function as <code class="docutils literal notranslate"><span class="pre">case</span></code> in some other languages.</p>
</aside>
<ul>
<li><p><strong>Line 15</strong> has our first <em>conditional</em>, an <code class="docutils literal notranslate"><span class="pre">if</span></code> statement. This is written on the form <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">&lt;condition&gt;:</span></code> and only
if that condition is truthy will the indented code block under the <code class="docutils literal notranslate"><span class="pre">if</span></code> statement run. To learn what is truthy in
Python its usually easier to learn what is “falsy”:</p>
<ul class="simple">
<li><p><strong>Line 15</strong> has our first <em>conditional</em>, an <code class="docutils literal notranslate"><span class="pre">if</span></code> statement. This is written on the form <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">&lt;condition&gt;:</span></code> and only if that condition is truthy will the indented code block under the <code class="docutils literal notranslate"><span class="pre">if</span></code> statement run. To learn what is truthy in Python its usually easier to learn what is “falsy”:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">False</span></code> - this is a reserved boolean word in Python. The opposite is <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">None</span></code> - another reserved word. This represents nothing, a null-result or value.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">0</span></code> or <code class="docutils literal notranslate"><span class="pre">0.0</span></code></p></li>
@ -444,14 +414,12 @@ Python its usually easier to learn what is “falsy”:</p>
<li><p>Empty <em>iterables</em> we havent seen yet, like empty lists <code class="docutils literal notranslate"><span class="pre">[]</span></code>, empty tuples <code class="docutils literal notranslate"><span class="pre">()</span></code> and empty dicts <code class="docutils literal notranslate"><span class="pre">{}</span></code>.</p></li>
<li><p>Everything else is “truthy”.</p></li>
</ul>
<p>Line 16s condition is <code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">args</span></code>. The <code class="docutils literal notranslate"><span class="pre">not</span></code> <em>inverses</em> the result, so if <code class="docutils literal notranslate"><span class="pre">args</span></code> is the empty string (falsy), the
whole conditional becomes truthy. Lets continue in the code:</p>
</li>
<li><p><strong>Line 16</strong>s condition is <code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">args</span></code>. The <code class="docutils literal notranslate"><span class="pre">not</span></code> <em>inverses</em> the result, so if <code class="docutils literal notranslate"><span class="pre">args</span></code> is the empty string (falsy), the whole conditional becomes truthy. Lets continue in the code:</p></li>
<li><p><strong>Lines 16-17</strong>: This code will only run if the <code class="docutils literal notranslate"><span class="pre">if</span></code> statement is truthy, in this case if <code class="docutils literal notranslate"><span class="pre">args</span></code> is the empty string.</p></li>
<li><p><strong>Line 17</strong>: <code class="docutils literal notranslate"><span class="pre">return</span></code> is a reserved Python word that exits <code class="docutils literal notranslate"><span class="pre">func</span></code> immediately.</p></li>
<li><p><strong>Line 18</strong>: We use <code class="docutils literal notranslate"><span class="pre">self.caller.search</span></code> to look for the target in the current location.</p></li>
<li><p><strong>Lines 19-20</strong>: A feature of <code class="docutils literal notranslate"><span class="pre">.search</span></code> is that it will already inform <code class="docutils literal notranslate"><span class="pre">self.caller</span></code> if it couldnt find the target.
In that case, <code class="docutils literal notranslate"><span class="pre">target</span></code> will be <code class="docutils literal notranslate"><span class="pre">None</span></code> and we should just directly <code class="docutils literal notranslate"><span class="pre">return</span></code>.</p></li>
<li><p><strong>Lines 19-20</strong>: A feature of <code class="docutils literal notranslate"><span class="pre">.search</span></code> is that it will already inform <code class="docutils literal notranslate"><span class="pre">self.caller</span></code> if it couldnt find the target. In that case, <code class="docutils literal notranslate"><span class="pre">target</span></code> will be <code class="docutils literal notranslate"><span class="pre">None</span></code> and we should just directly <code class="docutils literal notranslate"><span class="pre">return</span></code>.</p></li>
<li><p><strong>Lines 21-22</strong>: At this point we have a suitable target and can send our punching strings to each.</p></li>
</ul>
<p>Finally we must also add this to a CmdSet. Lets add it to <code class="docutils literal notranslate"><span class="pre">MyCmdSet</span></code> which we made persistent earlier.</p>
@ -470,9 +438,7 @@ In that case, <code class="docutils literal notranslate"><span class="pre">targe
<p>With longer code snippets to try, it gets more and more likely youll
make an error and get a <code class="docutils literal notranslate"><span class="pre">traceback</span></code> when you reload. This will either appear
directly in-game or in your log (view it with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">-l</span></code> in a terminal).
Dont panic; tracebacks are your friends - they are to be read bottom-up and usually describe
exactly where your problem is. Refer to <code class="docutils literal notranslate"><span class="pre">The</span> <span class="pre">Python</span> <span class="pre">intro</span> <span class="pre">&lt;Python-basic-introduction.html&gt;</span></code>_ for
more hints. If you get stuck, reach out to the Evennia community for help.</p>
Dont panic; tracebacks are your friends - they are to be read bottom-up and usually describe exactly where your problem is. Refer to <a class="reference internal" href="Beginner-Tutorial-Python-basic-introduction.html"><span class="doc std std-doc">The Python introduction lesson</span></a> for more hints. If you get stuck, reach out to the Evennia community for help.</p>
</aside>
<p>Next we reload to let Evennia know of these code changes and try it out:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; reload
@ -494,8 +460,7 @@ You hit Smaug with full force!
</section>
<section id="summary">
<h2><span class="section-number">8.2. </span>Summary<a class="headerlink" href="#summary" title="Permalink to this headline"></a></h2>
<p>In this lesson we learned how to create our own Command, add it to a CmdSet and then to ourselves.
We also upset a dragon.</p>
<p>In this lesson we learned how to create our own Command, add it to a CmdSet and then to ourselves. We also upset a dragon.</p>
<p>In the next lesson well learn how to hit Smaug with different weapons. Well also
get into how we replace and extend Evennias default Commands.</p>
</section>

View file

@ -119,7 +119,7 @@
<h1><span class="section-number">1. </span>Using commands and building stuff<a class="headerlink" href="#using-commands-and-building-stuff" title="Permalink to this headline"></a></h1>
<p>In this lesson we will test out what we can do in-game out-of-the-box. Evennia ships with
<a class="reference internal" href="../../../Components/Default-Commands.html"><span class="doc std std-doc">around 90 default commands</span></a>, and while you can override those as you please,
they can be quite useful.</p>
the defaults can be quite useful.</p>
<p>Connect and log into your new game and you will end up in the “Limbo” location. This
is the only room in the game at this point. Lets explore the commands a little.</p>
<p>The default commands has syntax <a class="reference internal" href="../../../Concepts/Using-MUX-as-a-Standard.html"><span class="doc std std-doc">similar to MUX</span></a>:</p>

View file

@ -67,6 +67,7 @@
<li><a class="reference internal" href="#">6. Overview of the Evennia library</a><ul>
<li><a class="reference internal" href="#where-is-it">6.1. Where is it?</a></li>
<li><a class="reference internal" href="#an-example-of-exploring-the-library">6.2. An example of exploring the library</a></li>
<li><a class="reference internal" href="#conclusions">6.3. Conclusions</a></li>
</ul>
</li>
</ul>
@ -113,16 +114,13 @@
<p class="sidebar-title">API</p>
<p>API stands for <code class="docutils literal notranslate"><span class="pre">Application</span> <span class="pre">Programming</span> <span class="pre">Interface</span></code>, a description for how to access the resources of a program or library.</p>
</aside>
<p>A good place to start exploring Evennia is the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">Evenia-API frontpage</span></a>.
This page sums up the main components of Evennia with a short description of each. Try clicking through
to a few entries - once you get deep enough youll see full descriptions
of each component along with their documentation. You can also click <code class="docutils literal notranslate"><span class="pre">[source]</span></code> to see the full Python source
for each thing.</p>
<p>You can also browse <a class="reference external" href="https://github.com/evennia/evennia">the evennia repository on github</a>. This is exactly
what you can download from us. The github repo is also searchable.</p>
<p>Finally, you can clone the evennia repo to your own computer and read the sources locally. This is necessary
if you want to help with Evennias development itself. See the
<a class="reference internal" href="../../../Setup/Installation-Git.html"><span class="doc std std-doc">extended install instructions</span></a> if you want to do this.</p>
<p>There are several good ways to explore the Evennia library.</p>
<ul class="simple">
<li><p>This documentation contains the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">Evennia-API docs</span></a>, generated automatically from sources. Try clicking through to a few entries - once you get deep enough youll see full descriptions of each component along with their documentation. You can also click <code class="docutils literal notranslate"><span class="pre">[source]</span></code> to see the full Python source code for each thing.</p></li>
<li><p>There are <a class="reference internal" href="../../../Components/Components-Overview.html"><span class="doc std std-doc">separate doc pages for each component</span></a> if you want more detailed explanations.</p></li>
<li><p>You can browse <a class="reference external" href="https://github.com/evennia/evennia">the evennia repository on github</a>. This is exactly what you can download from us.</p></li>
<li><p>Finally, you can clone the evennia repo to your own computer and read the sources. This is necessary if you want to <em>really</em> understand whats going on, or help with Evennias development. See the <a class="reference internal" href="../../../Setup/Installation-Git.html"><span class="doc std std-doc">extended install instructions</span></a> if you want to do this.</p></li>
</ul>
<section id="where-is-it">
<h2><span class="section-number">6.1. </span>Where is it?<a class="headerlink" href="#where-is-it" title="Permalink to this headline"></a></h2>
<p>If Evennia is installed, you can import from it simply with</p>
@ -132,9 +130,8 @@ from evennia.some_module.other_module import SomeClass
</pre></div>
</div>
<p>and so on.</p>
<p>If you installed Evennia with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span></code>, the library folder will be installed deep inside your Python
installation. If you cloned the repo there will be a folder <code class="docutils literal notranslate"><span class="pre">evennia</span></code> on your hard drive there.</p>
<p>If you cloned the repo or read the code on <code class="docutils literal notranslate"><span class="pre">github</span></code> youll find this being the outermost structure:</p>
<p>If you installed Evennia with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span></code>, the library folder will be installed deep inside your Python installation; you are better off <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia">looking at it on github</a>. If you cloned it, you should have an <code class="docutils literal notranslate"><span class="pre">evennia</span></code> folder to look into.</p>
<p>Youll find this being the outermost structure:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia/
bin/
CHANGELOG.md
@ -150,7 +147,7 @@ the <em>actual</em> library, the thing covered by the API auto-docs and what you
<div><p>The <code class="docutils literal notranslate"><span class="pre">evennia/docs/</span></code> folder contains the sources for this documentation. See
<a class="reference internal" href="../../../Contributing-Docs.html"><span class="doc std std-doc">contributing to the docs</span></a> if you want to learn more about how this works.</p>
</div></blockquote>
<p>This the the structure of the Evennia library:</p>
<p>This is the structure of the Evennia library:</p>
<ul class="simple">
<li><p>evennia</p>
<ul>
@ -187,21 +184,29 @@ from here to <code class="docutils literal notranslate"><span class="pre">mygame
<p class="sidebar-title"><strong>init</strong>.py</p>
<p>The <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> file is a special Python filename used to represent a Python package. When you import <code class="docutils literal notranslate"><span class="pre">evennia</span></code> on its own, you import this file. When you do <code class="docutils literal notranslate"><span class="pre">evennia.foo</span></code> Python will first look for a property <code class="docutils literal notranslate"><span class="pre">.foo</span></code> in <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> and then for a module or folder of that name in the same location.</p>
</aside>
<p>While all the actual Evennia code is found in the various folders, the <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> represents the entire
package <code class="docutils literal notranslate"><span class="pre">evennia</span></code>. It contains “shortcuts” to code that is actually located elsewhere. Most of these shortcuts
are listed if you <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">scroll down a bit</span></a> on the Evennia-API page.</p>
<p>While all the actual Evennia code is found in the various folders, the <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> represents the entire package <code class="docutils literal notranslate"><span class="pre">evennia</span></code>. It contains “shortcuts” to code that is actually located elsewhere. Most of these shortcuts are listed if you <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">scroll down a bit</span></a> on the Evennia-API page.</p>
</section>
<section id="an-example-of-exploring-the-library">
<h2><span class="section-number">6.2. </span>An example of exploring the library<a class="headerlink" href="#an-example-of-exploring-the-library" title="Permalink to this headline"></a></h2>
<p>In the previous lesson we took a brief look at <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects</span></code> as an example of a Python module. Lets
open it again. Inside is the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class, which inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>.
Near the top of the module is this line:</p>
<p>In the <a class="reference internal" href="Beginner-Tutorial-Python-classes-and-objects.html#on-classes-and-objects"><span class="std std-doc">previous lesson</span></a> we took a brief look at <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects</span></code> as an example of a Python module. Lets open it again.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">module docstring</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> class docstring</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>We have the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class, which inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. Near the top of the module is this line:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from evennia import DefaultObject
</pre></div>
</div>
<p>We want to figure out just what this DefaultObject offers. Since this is imported directly from <code class="docutils literal notranslate"><span class="pre">evennia</span></code>, we
are actually importing from <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code>.</p>
<p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/__init__.py#159">Look at Line 159</a> of <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> and youll find this line:</p>
<p>We want to figure out just what this DefaultObject offers. Since this is imported directly from <code class="docutils literal notranslate"><span class="pre">evennia</span></code>, we are actually importing from <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code>.</p>
<p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/__init__.py#L160">Look at Line 160</a> of <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> and youll find this line:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from .objects.objects import DefaultObject
</pre></div>
</div>
@ -210,21 +215,22 @@ are actually importing from <code class="docutils literal notranslate"><span cla
<p>The first full-stop in <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">.objects.objects</span> <span class="pre">...</span></code> means that we are importing from the current location. This is called a <code class="docutils literal notranslate"><span class="pre">relative</span> <span class="pre">import</span></code>. By comparison, <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">evennia.objects.objects</span></code> is an <code class="docutils literal notranslate"><span class="pre">absolute</span> <span class="pre">import</span></code>. In this particular case, the two would give the same result.</p>
</aside>
<blockquote>
<div><p>You can also look at <a class="reference internal" href="../../../Evennia-API.html#typeclasses"><span class="std std-doc">the right section of the API frontpage</span></a> and click through
to the code that way.</p>
<div><p>You can also look at <a class="reference internal" href="../../../Evennia-API.html#typeclasses"><span class="std std-doc">the right section of the API frontpage</span></a> and click through to the code that way.</p>
</div></blockquote>
<p>The fact that <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> is imported into <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> here is what makes it possible to also import
it as <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">evennia</span> <span class="pre">import</span> <span class="pre">DefaultObject</span></code> even though the code for the class is not actually here.</p>
<p>So to find the code for <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> we need to look in <code class="docutils literal notranslate"><span class="pre">evennia/objects/objects.py</span></code>. Heres how
to look it up in the docs:</p>
<p>The fact that <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> is imported into <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> here is what makes it possible to also import it as <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">evennia</span> <span class="pre">import</span> <span class="pre">DefaultObject</span></code> even though the code for the class is not actually here.</p>
<p>So to find the code for <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> we need to look in <code class="docutils literal notranslate"><span class="pre">evennia/objects/objects.py</span></code>. Heres how to look it up in the docs:</p>
<ol class="simple">
<li><p>Open the <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">API frontpage</span></a></p></li>
<li><p>Locate the link to <a class="reference internal" href="../../../api/evennia.objects.objects.html"><span class="doc std std-doc">evennia.objects.objects</span></a> and click on it.
3 You are now in the python module. Scroll down (or search in your web browser) to find the <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> class.
4 You can now read what this does and what methods are on it. If you want to see the full source, click the
[source] link next to it.</p></li>
<li><p>Locate the link to <a class="reference internal" href="../../../api/evennia.objects.objects.html"><span class="doc std std-doc">evennia.objects.objects</span></a> and click on it.</p></li>
<li><p>You are now in the python module. Scroll down (or search in your web browser) to find the <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> class.</p></li>
<li><p>You can now read what this does and what methods are on it. If you want to see the full source, click the [source] link next to it.</p></li>
</ol>
</section>
<section id="conclusions">
<h2><span class="section-number">6.3. </span>Conclusions<a class="headerlink" href="#conclusions" title="Permalink to this headline"></a></h2>
<p>This is an important lesson. It teaches you how to find information for yourself. Knowing how to follow the class inheritance tree and navigate to things you need is a big part in learning a new library like Evennia.</p>
<p>Next well start to make use of what we have learned so far and combine it with the building blocks provided by Evennia.</p>
</section>
</section>

View file

@ -116,30 +116,24 @@
<section class="tex2jax_ignore mathjax_ignore" id="overview-of-your-new-game-dir">
<h1><span class="section-number">4. </span>Overview of your new Game Dir<a class="headerlink" href="#overview-of-your-new-game-dir" title="Permalink to this headline"></a></h1>
<p>Next we will take a little detour to look at the <em>Tutorial World</em>. This is a little solo adventure
that comes with Evennia, a showcase for some of the things that are possible.</p>
<p>Now we have run the game a bit and started with our forays into Python from inside Evennia.
It is time to start to look at how things look outside of the game. Lets do a tour of your game-dir
Like everywhere in the docs well assume its called <code class="docutils literal notranslate"><span class="pre">mygame</span></code>.</p>
<p>Until now we have run the game a bit and started playing with Python inside Evennia.
It is time to start to look at how things look outside of the game.</p>
<p>Lets do a tour of your game-dir (we assume its called <code class="docutils literal notranslate"><span class="pre">mygame</span></code>).</p>
<blockquote>
<div><p>When looking through files, ignore files ending with <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> and the
<code class="docutils literal notranslate"><span class="pre">__pycache__</span></code> folder if it exists. This is internal Python compilation files that you should never
need to touch. Files <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> is also often empty and can be ignored (they have to do with
Python package management).</p>
</div></blockquote>
<p>You may have noticed when we were building things in-game that we would often refer to code through
“python paths”, such as</p>
<p>You may have noticed when we were building things in-game that we would often refer to code through “python paths”, such as</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create/drop button:tutorial_examples.red_button.RedButton
</pre></div>
</div>
<p>This is a fundamental aspect of coding Evennia - <em>you create code and then you tell Evennia where that code is and when it should be used</em>. Above we told it to create a red button by pulling from specific code in the <code class="docutils literal notranslate"><span class="pre">contrib/</span></code> folder. The same principle is true everywhere. So its important to know where code is and how you point to it correctly.</p>
<aside class="sidebar">
<p class="sidebar-title">Python-paths</p>
<p>A python path uses . instead of / or <code class="docutils literal notranslate"><span class="pre">\\</span></code> and skips the <code class="docutils literal notranslate"><span class="pre">.py</span></code> ending of files. It can also point to the code contents of python files. Since Evennia is already looking for code in your game dir, your python paths can start from there. So a path <code class="docutils literal notranslate"><span class="pre">/home/foo/devel/mygame/commands/command.py</span></code> would translate to a Python-path <code class="docutils literal notranslate"><span class="pre">commands.command</span></code>.</p>
</aside>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create/drop button:tutorial_examples.red_button.RedButton
</pre></div>
</div>
<p>This is a fundamental aspect of coding Evennia - <em>you create code and then you tell Evennia where that
code is and when it should be used</em>. Above we told it to create a red button by pulling from specific code
in the <code class="docutils literal notranslate"><span class="pre">contribs/</span></code> folder but the same principle is true everywhere. So its important to know where code is
and how you point to it correctly.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/</span></code></p>
<ul>
@ -163,11 +157,8 @@ building, such as build scripts and rules modules that dont fit with one of t
</li>
</ul>
<blockquote>
<div><p>The <code class="docutils literal notranslate"><span class="pre">server/</span></code> subfolder should remain the way it is - Evennia expects this. But you could in
principle change the structure of the rest of your game dir as best fits your preference.
Maybe you dont need a world/ folder but prefer many folders with different aspects of your world?
Or a new folder rules for your RPG rules? This is fine. If you move things around you just need
to update Evennias default settings to point to the right places in the new structure.</p>
<div><p>The <code class="docutils literal notranslate"><span class="pre">server/</span></code> subfolder should remain the way it is - Evennia expects this. But you can change the structure of the rest of your game dir as best fits your preferences.
Maybe you dont want a single world/ folder but prefer many folders with different aspects of your world? A new folder rules for your RPG rules? Group your commands with your objects instead of having them separate? This is fine. If you move things around you just need to update Evennias default settings to point to the right places in the new structure.</p>
</div></blockquote>
<section id="commands">
<h2><span class="section-number">4.1. </span>commands/<a class="headerlink" href="#commands" title="Permalink to this headline"></a></h2>
@ -211,9 +202,8 @@ means that they must be extended with valid Python. You can also add logic to th
knows where they are and will read them to configure itself at startup.</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">settings.py</span></code> - this is by far the most important file. Its nearly empty by default, rather you
are expected to copy&amp;paste the changes you need from <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/default_settings.py">evennia/default_settings.py</a>.
The default settings file is extensively documented. Importing/accessing the values in the settings
file is done in a special way, like this:</p>
are expected to copy&amp;paste the changes you need from <a class="reference internal" href="../../../Setup/Settings-Default.html"><span class="doc std std-doc">evennia/default_settings.py</span></a>.
The default settings file is extensively documented. Importing/accessing the values in the settings file is done in a special way, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> from django.conf import settings
</pre></div>
</div>
@ -221,8 +211,7 @@ file is done in a special way, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> telnet_port = settings.TELNET_PORT
</pre></div>
</div>
<p>You cannot assign to the settings file dynamically; you must change the <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> file directly to
change a setting.</p>
<p>You cannot assign to the settings file dynamically; you must change the <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> file directly to change a setting. See <a class="reference internal" href="../../../Setup/Settings.html"><span class="doc std std-doc">Settings</span></a> documentation for more details.</p>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">secret_settings.py</span></code> - If you are making your code effort public, you may not want to share all settings online.
There may be server-specific secrets or just fine-tuning for your game systems that you prefer be kept secret
@ -284,14 +273,12 @@ an entire planet or an actual dungeon room.</p></li>
<a class="reference internal" href="../../../Components/Objects.html#exits"><span class="std std-doc">Exits</span></a> is another subclass of Object. Exits link one Room to another.</p></li>
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/typeclasses/scripts.py">scripts.py</a> (Python-path: <code class="docutils literal notranslate"><span class="pre">typeclasses.scripts</span></code>) -
<a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> are out-of-character objects. They have no location in-game and can serve as basis for
anything that needs database persistence, such as combat, weather, or economic systems. They also
have the ability to execute code repeatedly, on a timer.</p></li>
anything that needs database persistence, such as combat, weather, or economic systems. They also have the ability to execute code repeatedly, on a timer.</p></li>
</ul>
</section>
<section id="web">
<h3><span class="section-number">4.2.4. </span>web/<a class="headerlink" href="#web" title="Permalink to this headline"></a></h3>
<p>This folder contains folders for overriding the default web-presence of Evennia with your own designs.
Most of these folders are empty except for a README file or a subset of other empty folders.</p>
<p>This folder contains folders for overriding the default web-presence of Evennia with your own designs. Most of these folders are empty except for a README file or a subset of other empty folders. See <a class="reference internal" href="../../../Components/Components-Overview.html#web-components"><span class="std std-doc">the Web overview</span></a> for more details (well also get back to the web later in this beginner tutorial).</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">media/</span></code> - this empty folder is where you can place your own images or other media files you want the
web server to serve. If you are releasing your game with a lot of media (especially if you want videos) you
@ -316,10 +303,7 @@ people change and re-structure this in various ways to better fit their ideas.</
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/batch_cmds.ev">batch_cmds.ev</a> - This is an <code class="docutils literal notranslate"><span class="pre">.ev</span></code> file, which is essentially
just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The
<a class="reference internal" href="Beginner-Tutorial-Tutorial-World.html"><span class="doc std std-doc">Tutorial World</span></a> was built with such a batch-file.</p></li>
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/prototypes.py">prototypes.py</a> - A <a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc std std-doc">prototype</span></a> is a way
to easily vary objects without changing their base typeclass. For example, one could use prototypes to
tell that Two goblins, while both of the class Goblin (so they follow the same code logic), should have different
equipment, stats and looks.</p></li>
<li><p><a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/game_template/world/prototypes.py">prototypes.py</a> - A <a class="reference internal" href="../../../Components/Prototypes.html"><span class="doc std std-doc">prototype</span></a> is a way to easily vary objects without changing their base typeclass. For example, one could use prototypes to tell that Two goblins, while both of the class Goblin (so they follow the same code logic), should have different equipment, stats and looks.</p></li>
</ul>
</section>
</section>

View file

@ -72,7 +72,8 @@
</ul>
</li>
<li><a class="reference internal" href="#typeclasses">7.2. Typeclasses</a><ul>
<li><a class="reference internal" href="#examining-and-defaults">7.2.1. Examining and defaults</a></li>
<li><a class="reference internal" href="#examining-objects">7.2.1. Examining objects</a></li>
<li><a class="reference internal" href="#default-typeclasses">7.2.2. Default typeclasses</a></li>
</ul>
</li>
<li><a class="reference internal" href="#modifying-ourselves">7.3. Modifying ourselves</a><ul>
@ -170,25 +171,23 @@ open it:</p>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
<span class="k">class</span> <span class="nc">ObjectParent</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot; </span>
<span class="sd"> class docstring </span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultObject</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> class docstring</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>So we have a class <code class="docutils literal notranslate"><span class="pre">Object</span></code> that <em>inherits</em> from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, which we have imported from Evennia.
The class itself doesnt do anything (it just <code class="docutils literal notranslate"><span class="pre">pass</span></code>es) but that doesnt mean its useless. As weve seen,
it inherits all the functionality of its parent. Its in fact an <em>exact replica</em> of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> right now.
If we knew what kind of methods and resources were available on <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> we could add our own and
change the way it works!</p>
<blockquote>
<div><p>Hint: We will get back to this, but to learn what resources an Evennia parent like <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> offers,
easiest is to peek at its <a class="reference internal" href="../../../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">API documentation</span></a>. The docstring for
the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class can also help.</p>
</div></blockquote>
<p>One thing that Evennia classes offers and which you dont get with vanilla Python classes is <em>persistence</em>. As
youve found, Fluffy, Cuddly and Smaug are gone once we reload the server. Lets see if we can fix this.</p>
<p>So we have a class <code class="docutils literal notranslate"><span class="pre">Object</span></code> that <em>inherits</em> from <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> (which is empty) and <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, which we have imported from Evennia. The <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> acts as a place to put code you want all
of your <code class="docutils literal notranslate"><span class="pre">Objects</span></code> to have. Well focus on <code class="docutils literal notranslate"><span class="pre">Object</span></code> and <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> for now.</p>
<p>The class itself doesnt do anything (it just <code class="docutils literal notranslate"><span class="pre">pass</span></code>es) but that doesnt mean its useless. As weve seen, it inherits all the functionality of its parent. Its in fact an <em>exact replica</em> of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> right now. Once we know what kind of methods and resources are available on <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> we could add our own and change the way it works!</p>
<p>One thing that Evennia classes offers and which you dont get with vanilla Python classes is <em>persistence</em> - they survive a server reload since they are stored in the database.</p>
<p>Go back to <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code>. Change it as follows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="kn">from</span> <span class="nn">typeclasses.objects</span> <span class="kn">import</span> <span class="n">Object</span>
@ -218,15 +217,13 @@ youve found, Fluffy, Cuddly and Smaug are gone once we reload the server. Let
</pre></div>
</div>
<p>Dont forget to save. We removed <code class="docutils literal notranslate"><span class="pre">Monster.__init__</span></code> and made <code class="docutils literal notranslate"><span class="pre">Monster</span></code> inherit from Evennias <code class="docutils literal notranslate"><span class="pre">Object</span></code> (which in turn
inherits from Evennias <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, as we saw). By extension, this means that <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> also inherits
from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, just from further away!</p>
<p>Dont forget to save. We removed <code class="docutils literal notranslate"><span class="pre">Monster.__init__</span></code> and made <code class="docutils literal notranslate"><span class="pre">Monster</span></code> inherit from Evennias <code class="docutils literal notranslate"><span class="pre">Object</span></code> (which in turn inherits from Evennias <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, as we saw). By extension, this means that <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> also inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, just from further away!</p>
<section id="making-a-new-object-by-calling-the-class">
<h3><span class="section-number">7.1.1. </span>Making a new object by calling the class<a class="headerlink" href="#making-a-new-object-by-calling-the-class" title="Permalink to this headline"></a></h3>
<p>First reload the server as usual. We will need to create the dragon a little differently this time:</p>
<aside class="sidebar">
<p class="sidebar-title">Keyword arguments</p>
<p>Keyword arguments (like <code class="docutils literal notranslate"><span class="pre">db_key=&quot;Smaug&quot;</span></code>) is a way to name the input arguments to a function or method. They make things easier to read but also allows for conveniently setting defaults for values not given explicitly.</p>
<p><em>Keyword arguments</em> (like <code class="docutils literal notranslate"><span class="pre">db_key=&quot;Smaug&quot;</span></code>) is a way to name the input arguments to a function or method. They make things easier to read but also allows for conveniently setting defaults for values not given explicitly. We saw them previously in use for <code class="docutils literal notranslate"><span class="pre">.format()</span></code>.</p>
</aside>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py
&gt; from typeclasses.monsters import Dragon
@ -239,6 +236,10 @@ The world trembles.
</div>
<p>Smaug works the same as before, but we created him differently: first we used
<code class="docutils literal notranslate"><span class="pre">Dragon(db_key=&quot;Smaug&quot;,</span> <span class="pre">db_location=here)</span></code> to create the object, and then we used <code class="docutils literal notranslate"><span class="pre">smaug.save()</span></code> afterwards.</p>
<aside class="sidebar">
<p class="sidebar-title">here</p>
<p>The <code class="docutils literal notranslate"><span class="pre">here</span></code> used in <code class="docutils literal notranslate"><span class="pre">db_location=here</span></code> is a shortcut for your current location. This <code class="docutils literal notranslate"><span class="pre">here</span></code> (similar to <code class="docutils literal notranslate"><span class="pre">me</span></code>) is <em>only</em> available to use in the <code class="docutils literal notranslate"><span class="pre">py</span></code> command; you cant use it in other Python code you write unless you define it yourself.</p>
</aside>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; quit()
Python Console is closing.
&gt; look
@ -249,9 +250,7 @@ Python Console is closing.
&gt; look
</pre></div>
</div>
<p><em>Hes still there</em>… What we just did was to create a new entry in the database for Smaug. We gave the object
its name (key) and set its location to our current location (remember that <code class="docutils literal notranslate"><span class="pre">here</span></code> is just something available
in the <code class="docutils literal notranslate"><span class="pre">py</span></code> command, you cant use it elsewhere).</p>
<p><em>Hes still there</em>… What we just did was to create a new entry in the database for Smaug. We gave the object its name (key) and set its location to our current location.</p>
<p>To make use of Smaug in code we must first find him in the database. For an object in the current
location we can easily do this in <code class="docutils literal notranslate"><span class="pre">py</span></code> by using <code class="docutils literal notranslate"><span class="pre">me.search()</span></code>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py smaug = me.search(&quot;Smaug&quot;) ; smaug.firebreath()
@ -264,83 +263,103 @@ Smaug breathes fire!
<p>Creating Smaug like we did above is nice because its similar to how we created non-database
bound Python instances before. But you need to use <code class="docutils literal notranslate"><span class="pre">db_key</span></code> instead of <code class="docutils literal notranslate"><span class="pre">key</span></code> and you also have to
remember to call <code class="docutils literal notranslate"><span class="pre">.save()</span></code> afterwards. Evennia has a helper function that is more common to use,
called <code class="docutils literal notranslate"><span class="pre">create_object</span></code>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py fluffy = evennia.create_object(&#39;typeclases.monster.Monster&#39;, key=&quot;Fluffy&quot;, location=here)
called <code class="docutils literal notranslate"><span class="pre">create_object</span></code>. Lets recreate Cuddly this time:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py evennia.create_object(&#39;typeclasses.monster.Monster&#39;, key=&quot;Cuddly&quot;, location=here)
&gt; look
</pre></div>
</div>
<p>Boom, Fluffy should now be in the room with you, a little less scary than Smaug. You specify the
python-path to the code you want and then set the key and location. Evennia sets things up and saves for you.</p>
<p>If you want to find Fluffy from anywhere, you can use Evennias <code class="docutils literal notranslate"><span class="pre">search_object</span></code> helper:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; fluffy = evennia.search_object(&quot;Fluffy&quot;)[0] ; fluffy.move_around()
Fluffy is moving!
<p>Boom, Cuddly should now be in the room with you, a little less scary than Smaug. You specify the
python-path to the code you want and then set the key and location (if you had the <code class="docutils literal notranslate"><span class="pre">Monster</span></code> class already imported, you could have passed that too). Evennia sets things up and saves for you.</p>
<p>If you want to find Smaug from anywhere (not just in the same room), you can use Evennias <code class="docutils literal notranslate"><span class="pre">search_object</span></code> function:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; cuddly = evennia.search_object(&quot;Cuddly&quot;)[0] ; cuddly.move_around()
Cuddly is moving!
</pre></div>
</div>
<blockquote>
<div><p>The <code class="docutils literal notranslate"><span class="pre">[0]</span></code> is because <code class="docutils literal notranslate"><span class="pre">search_object</span></code> always returns a <em>list</em> of zero, one or more found objects. The <code class="docutils literal notranslate"><span class="pre">[0]</span></code>
means that we want the first element of this list (counting in Python always starts from 0). If there were
multiple Fluffies we could get the second one with <code class="docutils literal notranslate"><span class="pre">[1]</span></code>.</p>
<div><p>The <code class="docutils literal notranslate"><span class="pre">[0]</span></code> is because <code class="docutils literal notranslate"><span class="pre">search_object</span></code> always returns a <em>list</em> of zero, one or more found objects. The <code class="docutils literal notranslate"><span class="pre">[0]</span></code> means that we want the first element of this list (counting in Python always starts from 0). If there were multiple Cuddlies we could get the second one with <code class="docutils literal notranslate"><span class="pre">[1]</span></code>.</p>
</div></blockquote>
</section>
<section id="creating-using-create-command">
<h3><span class="section-number">7.1.3. </span>Creating using create-command<a class="headerlink" href="#creating-using-create-command" title="Permalink to this headline"></a></h3>
<p>Finally, you can also create a new Dragon using the familiar builder-commands we explored a few lessons ago:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; create/drop Cuddly:typeclasses.monsters.Monster
<p>Finally, you can also create a new dragon using the familiar builder-commands we explored a few lessons ago:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; create/drop Fluffy:typeclasses.monsters.Dragon
</pre></div>
</div>
<p>Cuddly is now in the room. After learning about how objects are created youll realize that all this command really
does is to parse your input, figure out that <code class="docutils literal notranslate"><span class="pre">/drop</span></code> means to “give the object the same location as the caller”,
and then do a call akin to</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia.create_object(&quot;typeclasses.monsters.Monster&quot;, key=&quot;Cuddly&quot;, location=here)
<p>Fluffy is now in the room. After learning about how objects are created youll realize that all this command really does is to parse your input, figure out that <code class="docutils literal notranslate"><span class="pre">/drop</span></code> means to “give the object the same location as the caller”, and then do a call very similar to</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia.create_object(&quot;typeclasses.monsters.Dragon&quot;, key=&quot;Cuddly&quot;, location=here)
</pre></div>
</div>
<p>Thats pretty much all there is to the mighty <code class="docutils literal notranslate"><span class="pre">create</span></code> command! The rest is just parsing for the command
to understand just what the user wants to create.</p>
<p>Thats pretty much all there is to the mighty <code class="docutils literal notranslate"><span class="pre">create</span></code> command! The rest is just parsing for the command to understand just what the user wants to create.</p>
</section>
</section>
<section id="typeclasses">
<h2><span class="section-number">7.2. </span>Typeclasses<a class="headerlink" href="#typeclasses" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">Object</span></code> (and <code class="docutils literal notranslate"><span class="pre">DefafultObject</span></code> class we inherited from above is what we refer to as a <em>Typeclass</em>. This
is an Evennia thing. The instance of a typeclass saves itself to the database when it is created, and after
that you can just search for it to get it back. We use the term <em>typeclass</em> or <em>typeclassed</em> to differentiate
these types of classes and objects from the normal Python classes, whose instances go away on a reload.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">Object</span></code> (and <code class="docutils literal notranslate"><span class="pre">DefafultObject</span></code> class we inherited from above is what we refer to as a <em>Typeclass</em>. This is an Evennia thing. The instance of a typeclass saves itself to the database when it is created, and after that you can just search for it to get it back.</p>
<p>We use the term <em>typeclass</em> or <em>typeclassed</em> to differentiate these types of classes and objects from the normal Python classes, whose instances go away on a reload.</p>
<p>The number of typeclasses in Evennia are so few they can be learned by heart:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultObject</span></code>: This is the parent of all in-game entities - everything with a location. Evennia makes
a few very useful child classes of this class:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code>: The default entity represening a player avatar in-game.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultRoom</span></code>: A location in the game world.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultExit</span></code>: A link between locations.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultAccount</span></code>: The OOC representation of a player, holds password and account info.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultChannel</span></code>: In-game channels. These could be used for all sorts of in-game communication.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultScript</span></code>: Out-of-game objects, with no presence in the game world. Anything you want to create that
needs to be persistent can be stored with these entities, such as combat state, economic systems or what have you.</p></li>
</ul>
<p>If you take a look in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code> youll find modules for each of these. Each contains an empty child
class ready that already inherits from the right parent, ready for you to modify or build from:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Object(DefaultObject)</span></code>, a class directly inheriting the basic in-game entity, this
works as a base for any object.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Character(DefaultCharacter)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/rooms.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Room(DefaultRoom)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/exits.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Exit(DefaultExit)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/accounts.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Account(DefaultAccount)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/channels.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Channel(DefaultChannel)</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/scripts.py</span></code> has <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Script(DefaultScript)</span></code></p></li>
</ul>
<blockquote>
<div><p>Notice that the classes in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code> are <em>not inheriting from each other</em>. For example,
<code class="docutils literal notranslate"><span class="pre">Character</span></code> is inheriting from <code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code> and not from <code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>.
So if you change <code class="docutils literal notranslate"><span class="pre">Object</span></code> you will not cause any change in the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class. If you want that you
can easily just change the child classes to inherit in that way instead; Evennia doesnt care.</p>
</div></blockquote>
<p>As seen with our <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> example, you dont <em>have</em> to modify these modules directly. You can just make your
own modules and import the base class.</p>
<section id="examining-and-defaults">
<h3><span class="section-number">7.2.1. </span>Examining and defaults<a class="headerlink" href="#examining-and-defaults" title="Permalink to this headline"></a></h3>
<table class="colwidths-auto docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Evennia base typeclass</p></th>
<th class="head"><p>mygame.typeclasses child</p></th>
<th class="head"><p>description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultObject</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code></p></td>
<td><p>Everything with a location</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code> (child of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>)</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.characters.Character</span></code></p></td>
<td><p>Player avatars</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultRoom</span></code> (child of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>)</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.rooms.Room</span></code></p></td>
<td><p>In-game locations</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultExit</span></code> (chld of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>)</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.exits.Exit</span></code></p></td>
<td><p>Links between rooms</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultAccount</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.accounts.Account</span></code></p></td>
<td><p>A player account</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultChannel</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.channels.Channel</span></code></p></td>
<td><p>In-game comms</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">evennia.DefaultScript</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">typeclasses.scripts.Script</span></code></p></td>
<td><p>Entities with no location</p></td>
</tr>
</tbody>
</table>
<p>The child classes under <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code> are meant for you to conveniently modify and
work with. Every class inheriting (at any distance) from a Evennia base typeclass is also considered a typeclass.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">somewhere</span> <span class="kn">import</span> <span class="n">Something</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultScript</span>
<span class="k">class</span> <span class="nc">MyOwnClass</span><span class="p">(</span><span class="n">Something</span><span class="p">):</span>
<span class="c1"># not inheriting from an Evennia core typeclass, so this </span>
<span class="c1"># is just a &#39;normal&#39; Python class inheriting from somewhere</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">MyOwnClass2</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
<span class="c1"># inherits from one of the core Evennia typeclasses, so </span>
<span class="c1"># this is also considered a &#39;typeclass&#39;.</span>
<span class="k">pass</span>
</pre></div>
</div>
<aside class="sidebar">
<p class="sidebar-title">Why invent the name typeclass?</p>
<p>We separate regular classes from typeclasses because while typeclasses act <em>almost</em> like normal Python classes, <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">there are some differences</span></a>. We will gloss over those differences for now, but they are worth to read up on when you want to do more advanced things later.</p>
</aside>
<p>Notice that the classes in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code> are <em>not inheriting from each other</em>. For example, <code class="docutils literal notranslate"><span class="pre">Character</span></code> is inheriting from <code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code> and not from <code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>. So if you change <code class="docutils literal notranslate"><span class="pre">Object</span></code> you will not cause any change in the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class. If you want that you can easily just change the child classes to inherit in that way instead; Evennia doesnt care.</p>
<p>As seen with our <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> example, you dont <em>have</em> to modify these modules directly. You can just make your own modules and import the base class.</p>
<section id="examining-objects">
<h3><span class="section-number">7.2.1. </span>Examining objects<a class="headerlink" href="#examining-objects" title="Permalink to this headline"></a></h3>
<p>When you do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; create/drop giantess:typeclasses.monsters.Monster
You create a new Monster: giantess.
@ -372,19 +391,17 @@ may be more useful to us:</p>
<li><p><strong>Name/key</strong> - The name of this thing. The value <code class="docutils literal notranslate"><span class="pre">(#14)</span></code> is probably different for you. This is the
unique primary key or <em>dbref</em> for this entity in the database.</p></li>
<li><p><strong>Typeclass</strong>: This show the typeclass we specified, and the path to it.</p></li>
<li><p><strong>Location</strong>: We are in Limbo. If you moved elsewhere youll see that instead. Also the <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> is shown.</p></li>
<li><p><strong>Permissions</strong>: <em>Permissions</em> are like the inverse to <em>Locks</em> - they are like keys to unlock access to other things.
The giantess have no such keys (maybe fortunately).</p></li>
<li><p><strong>Locks</strong>: Locks are the inverse of <em>Permissions</em> - specify what criterion <em>other</em> objects must fulfill in order to
access the <code class="docutils literal notranslate"><span class="pre">giantess</span></code> object. This uses a very flexible mini-language. For examine, the line <code class="docutils literal notranslate"><span class="pre">examine:perm(Builders)</span></code>
is read as “Only those with permission <em>Builder</em> or higher can <em>examine</em> this object”. Since we are the superuser
we pass (even bypass) such locks with ease.</p></li>
<li><p><strong>Persistent attributes</strong>: This allows for storing arbitrary, persistent data on the typeclassed entity. Well get
to those in the next section.</p></li>
<li><p><strong>Location</strong>: We are in Limbo. If you moved elsewhere youll see that instead. Also the <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> of Limbo is shown.</p></li>
<li><p><strong>Home</strong>: All objects with a location (inheriting from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>) must have a home location. This is a backup to move the object to if its current location is deleted.</p></li>
<li><p><strong>Permissions</strong>: <em>Permissions</em> are like the inverse to <em>Locks</em> - they are like keys to unlock access to other things. The giantess have no such keys (maybe fortunately). The <a class="reference internal" href="../../../Components/Permissions.html"><span class="doc std std-doc">Permissions</span></a> has more info.</p></li>
<li><p><strong>Locks</strong>: Locks are the inverse of <em>Permissions</em> - specify what criterion <em>other</em> objects must fulfill in order to access the <code class="docutils literal notranslate"><span class="pre">giantess</span></code> object. This uses a very flexible mini-language. For examine, the line <code class="docutils literal notranslate"><span class="pre">examine:perm(Builders)</span></code> is read as “Only those with permission <em>Builder</em> or higher can <em>examine</em> this object”. Since we are the superuser we pass (even bypass) such locks with ease. See the <a class="reference internal" href="../../../Components/Locks.html"><span class="doc std std-doc">Locks</span></a> documentation for more info.</p></li>
<li><p><strong>Persistent attributes</strong>: This allows for storing arbitrary, persistent data on the typeclassed entity. Well get to those in the next section.</p></li>
</ul>
<p>Note how the <strong>Typeclass</strong> line describes exactly where to find the code of this object? This is very useful for
understanding how any object in Evennia works.</p>
<p>What happens if we <em>dont</em> specify the typeclass though?</p>
<p>Note how the <strong>Typeclass</strong> line describes exactly where to find the code of this object? This is very useful for understanding how any object in Evennia works.</p>
</section>
<section id="default-typeclasses">
<h3><span class="section-number">7.2.2. </span>Default typeclasses<a class="headerlink" href="#default-typeclasses" title="Permalink to this headline"></a></h3>
<p>What happens if we create an object and <em>dont</em> specify its typeclass though?</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; create/drop box
You create a new Object: box.
</pre></div>
@ -401,20 +418,14 @@ You create a new Object: box.
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Typeclass: Object (typeclasses.objects.Object)
</pre></div>
</div>
<p>So when you didnt specify a typeclass, Evennia used a default, more specifically the (so far) empty <code class="docutils literal notranslate"><span class="pre">Object</span></code> class in
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects.py</span></code>. This is usually what you want, especially since you can tweak that class as much
as you like.</p>
<p>But the reason Evennia knows to fall back to this class is not hard-coded - its a setting. The default is
in <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/settings_default.py#L465">evennia/settings_default.py</a>,
with the name <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code>, which is set to <code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>.</p>
<p>So when you didnt specify a typeclass, Evennia used a default, more specifically the (so far) empty <code class="docutils literal notranslate"><span class="pre">Object</span></code> class in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/objects.py</span></code>. This is usually what you want, especially since you can tweak that class as much as you like.</p>
<p>But the reason Evennia knows to fall back to this class is not hard-coded - its a setting. The default is in <a class="reference internal" href="../../../Setup/Settings-Default.html"><span class="doc std std-doc">evennia/settings_default.py</span></a>, with the name <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code>, which is set to <code class="docutils literal notranslate"><span class="pre">typeclasses.objects.Object</span></code>.</p>
<aside class="sidebar">
<p class="sidebar-title">Changing things</p>
<p>While its tempting to change folders around to your liking, this can make it harder to follow tutorials and may confuse if you are asking others for help. So dont overdo it unless you really know what you are doing.</p>
<p>While its tempting to change folders around to your liking, this can make it harder to follow tutorials and may confuse if you are asking others for help. So dont overdo it unless you really know what you are doing.</p>
</aside>
<p>So if you wanted the creation commands and methods to default to some other class you could
add your own <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code> line to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>. The same is true for all the other
typeclasseses, like characters, rooms and accounts. This way you can change the
layout of your game dir considerably if you wanted. You just need to tell Evennia where everything is.</p>
add your own <code class="docutils literal notranslate"><span class="pre">BASE_OBJECT_TYPECLASS</span></code> line to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>. The same is true for all the other typeclasseses, like characters, rooms and accounts. This way you can change the layout of your game dir considerably if you wanted. You just need to tell Evennia where everything is.</p>
</section>
</section>
<section id="modifying-ourselves">
@ -432,8 +443,7 @@ layout of your game dir considerably if you wanted. You just need to tell Evenni
<span class="k">pass</span>
</pre></div>
</div>
<p>This looks quite familiar now - an empty class inheriting from the Evennia base typeclass. As you would expect,
this is also the default typeclass used for creating Characters if you dont specify it. You can verify it:</p>
<p>This looks quite familiar now - an empty class inheriting from the Evennia base typeclass (its even easier than <code class="docutils literal notranslate"><span class="pre">Object</span></code> since there is no equvalent <code class="docutils literal notranslate"><span class="pre">ParentObject</span></code> mixin class here). As you would expect, this is also the default typeclass used for creating Characters if you dont specify it. You can verify it:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; examine me
------------------------------------------------------------------------------
Name/key: YourName (#1)
@ -461,17 +471,15 @@ Non-Persistent attributes:
------------------------------------------------------------------------------
</pre></div>
</div>
<p>You got a lot longer output this time. You have a lot more going on than a simple Object. Here are some new fields of note:</p>
<p>Yes, the <code class="docutils literal notranslate"><span class="pre">examine</span></code> command understands <code class="docutils literal notranslate"><span class="pre">me</span></code>. You got a lot longer output this time. You have a lot more going on than a simple Object. Here are some new fields of note:</p>
<ul class="simple">
<li><p><strong>Session id(s)</strong>: This identifies the <em>Session</em> (that is, the individual connection to a players game client).</p></li>
<li><p><strong>Account</strong> shows, well the <code class="docutils literal notranslate"><span class="pre">Account</span></code> object associated with this Character and Session.</p></li>
<li><p><strong>Stored/Merged Cmdsets</strong> and <strong>Commands available</strong> is related to which <em>Commands</em> are stored on you. We will
get to them in the <a class="reference internal" href="Beginner-Tutorial-Adding-Commands.html"><span class="doc std std-doc">next lesson</span></a>. For now its enough to know these consitute all the
<li><p><strong>Stored/Merged Cmdsets</strong> and <strong>Commands available</strong> is related to which <em>Commands</em> are stored on you. We will get to them in the <a class="reference internal" href="Beginner-Tutorial-Adding-Commands.html"><span class="doc std std-doc">next lesson</span></a>. For now its enough to know these consitute all the
commands available to you at a given moment.</p></li>
<li><p><strong>Non-Persistent attributes</strong> are Attributes that are only stored temporarily and will go away on next reload.</p></li>
</ul>
<p>Look at the <strong>Typeclass</strong> field and youll find that it points to <code class="docutils literal notranslate"><span class="pre">typeclasses.character.Character</span></code> as expected.
So if we modify this class well also modify ourselves.</p>
<p>Look at the <strong>Typeclass</strong> field and youll find that it points to <code class="docutils literal notranslate"><span class="pre">typeclasses.character.Character</span></code> as expected. So if we modify this class well also modify ourselves.</p>
<section id="a-method-on-ourselves">
<h3><span class="section-number">7.3.1. </span>A method on ourselves<a class="headerlink" href="#a-method-on-ourselves" title="Permalink to this headline"></a></h3>
<p>Lets try something simple first. Back in <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code>:</p>
@ -481,15 +489,15 @@ So if we modify this class well also modify ourselves.</p>
<span class="sd"> (class docstring)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="nb">str</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">dex</span> <span class="o">=</span> <span class="mi">12</span>
<span class="nb">int</span> <span class="o">=</span> <span class="mi">15</span>
<span class="n">strength</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">dexterity</span> <span class="o">=</span> <span class="mi">12</span>
<span class="n">intelligence</span> <span class="o">=</span> <span class="mi">15</span>
<span class="k">def</span> <span class="nf">get_stats</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the main stats of this character</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">dex</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">int</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">strength</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">dexterity</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">intelligence</span>
</pre></div>
</div>
@ -505,9 +513,7 @@ So if we modify this class well also modify ourselves.</p>
<li><p>A <code class="docutils literal notranslate"><span class="pre">tuple</span></code> is written <code class="docutils literal notranslate"><span class="pre">(a,</span> <span class="pre">b,</span> <span class="pre">c,</span> <span class="pre">...)</span></code>. It cannot be modified once created.</p></li>
</ul>
</aside>
<p>We made a new method, gave it a docstring and had it <code class="docutils literal notranslate"><span class="pre">return</span></code> the RP-esque values we set. It comes back as a
<em>tuple</em> <code class="docutils literal notranslate"><span class="pre">(10,</span> <span class="pre">12,</span> <span class="pre">15)</span></code>. To get a specific value you could specify the <em>index</em> of the value you want,
starting from zero:</p>
<p>We made a new method, gave it a docstring and had it <code class="docutils literal notranslate"><span class="pre">return</span></code> the RP-esque values we set. It comes back as a <em>tuple</em> <code class="docutils literal notranslate"><span class="pre">(10,</span> <span class="pre">12,</span> <span class="pre">15)</span></code>. To get a specific value you could specify the <em>index</em> of the value you want, starting from zero:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py stats = self.get_stats() ; print(f&quot;Strength is {stats[0]}.&quot;)
Strength is 10.
</pre></div>
@ -516,15 +522,14 @@ Strength is 10.
<section id="attributes">
<h3><span class="section-number">7.3.2. </span>Attributes<a class="headerlink" href="#attributes" title="Permalink to this headline"></a></h3>
<p>So what happens when we increase our strength? This would be one way:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.str = self.str + 1
&gt; py self.str
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.strength = self.str + 1
&gt; py self.strength
11
</pre></div>
</div>
<p>Here we set the strength equal to its previous value + 1. A shorter way to write this is to use Pythons <code class="docutils literal notranslate"><span class="pre">+=</span></code>
operator:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.str += 1
&gt; py self.str
<p>Here we set the strength equal to its previous value + 1. A shorter way to write this is to use Pythons <code class="docutils literal notranslate"><span class="pre">+=</span></code> operator:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.strength += 1
&gt; py self.strength
12
&gt; py self.get_stats()
(12, 12, 15)
@ -536,12 +541,8 @@ operator:</p>
(10, 12, 15)
</pre></div>
</div>
<p>After a reload all our changes were forgotten. When we change properties like this, it only changes in memory,
not in the database (nor do we modify the python modules code). So when we reloaded, the fresh <code class="docutils literal notranslate"><span class="pre">Character</span></code>
class was loaded, and it still has the original stats we wrote to it.</p>
<p>In principle we could change the python code. But we dont want to do that manually every time. And more importantly
since we have the stats hardcoded in the class, <em>every</em> character instance in the game will have exactly the
same <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">dex</span></code> and <code class="docutils literal notranslate"><span class="pre">int</span></code> now! This is clearly not what we want.</p>
<p>After a reload all our changes were forgotten. When we change properties like this, it only changes in memory, not in the database (nor do we modify the python modules code). So when we reloaded, the fresh <code class="docutils literal notranslate"><span class="pre">Character</span></code> class was loaded, and it still has the original stats we wrote in it.</p>
<p>In principle we could change the python code. But we dont want to do that manually every time. And more importantly since we have the stats hardcoded in the class, <em>every</em> character instance in the game will have exactly the same <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">dex</span></code> and <code class="docutils literal notranslate"><span class="pre">int</span></code> now! This is clearly not what we want.</p>
<p>Evennia offers a special, persistent type of property for this, called an <code class="docutils literal notranslate"><span class="pre">Attribute</span></code>. Rework your
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
@ -554,42 +555,38 @@ same <code class="docutils literal notranslate"><span class="pre">str</span></co
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the main stats of this character</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dex</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">int</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">strength</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dexterity</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">intelligence</span>
</pre></div>
</div>
<aside class="sidebar">
<p class="sidebar-title">Spaces in Attribute name?</p>
<p>What if you want spaces in your Attribute name? Or you want to assign the name of the Attribute on-the fly? Then you can use <code class="docutils literal notranslate"><span class="pre">.attributes.add(name,</span> <span class="pre">value)</span></code> instead, for example <code class="docutils literal notranslate"><span class="pre">self.attributes.add(&quot;str&quot;,</span> <span class="pre">10)</span></code>.</p>
<p>What if you want spaces in your Attribute name? Or you want to assign the name of the Attribute on-the fly? Then you can use <code class="docutils literal notranslate"><span class="pre">.attributes.add(name,</span> <span class="pre">value)</span></code> instead, for example <code class="docutils literal notranslate"><span class="pre">self.attributes.add(&quot;emotional</span> <span class="pre">intelligence&quot;,</span> <span class="pre">10)</span></code>. You read it out again with <code class="docutils literal notranslate"><span class="pre">self.attributes.get(&quot;emotional</span> <span class="pre">intelligence&quot;</span></code>.</p>
</aside>
<p>We removed the hard-coded stats and added added <code class="docutils literal notranslate"><span class="pre">.db</span></code> for every stat. The <code class="docutils literal notranslate"><span class="pre">.db</span></code> handler makes the stat
into an an Evennia <code class="docutils literal notranslate"><span class="pre">Attribute</span></code>.</p>
<p>We removed the hard-coded stats and added added <code class="docutils literal notranslate"><span class="pre">.db</span></code> for every stat. The <code class="docutils literal notranslate"><span class="pre">.db</span></code> handler makes the stat into an an Evennia <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attribute</span></a>.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; reload
&gt; py self.get_stats()
(None, None, None)
</pre></div>
</div>
<p>Since we removed the hard-coded values, Evennia dont know what they should be (yet). So all we get back
is <code class="docutils literal notranslate"><span class="pre">None</span></code>, which is a Python reserved word to represent nothing, a no-value. This is different from a normal python
property:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.str
AttributeError: &#39;Character&#39; object has no attribute &#39;str&#39;
&gt; py self.db.str
<p>Since we removed the hard-coded values, Evennia dont know what they should be (yet). So all we get back is <code class="docutils literal notranslate"><span class="pre">None</span></code>, which is a Python reserved word to represent nothing, a no-value. This is different from a normal python property:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py me.strength
AttributeError: &#39;Character&#39; object has no attribute &#39;strength&#39;
&gt; py me.db.strength
(nothing will be displayed, because it&#39;s None)
</pre></div>
</div>
<p>Trying to get an unknown normal Python property will give an error. Getting an unknown Evennia <code class="docutils literal notranslate"><span class="pre">Attribute</span></code> will
never give an error, but only result in <code class="docutils literal notranslate"><span class="pre">None</span></code> being returned. This is often very practical.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.db.str, self.db.dex, self.db.int = 10, 12, 15
&gt; py self.get_stats()
<p>Trying to get an unknown normal Python property will give an error. Getting an unknown Evennia <code class="docutils literal notranslate"><span class="pre">Attribute</span></code> will never give an error, but only result in <code class="docutils literal notranslate"><span class="pre">None</span></code> being returned. This is often very practical.</p>
<p>Next, let us test out assigning those Attributes</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py me.db.strength, me.db.dexterity, me.db.intelligence = 10, 12, 15
&gt; py me.get_stats()
(10, 12, 15)
&gt; reload
&gt; py self.get_stats()
&gt; py me.get_stats()
(10, 12, 15)
</pre></div>
</div>
<p>Now we set the Attributes to the right values. We can see that things work the same as before, also after a
server reload. Lets modify the strength:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.db.str += 2
<p>Now we set the Attributes to the right values, and they survive a server reload! Lets modify the strength:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py self.db.strength += 2
&gt; py self.get_stats()
(12, 12, 15)
&gt; reload
@ -597,19 +594,12 @@ server reload. Lets modify the strength:</p>
(12, 12, 15)
</pre></div>
</div>
<p>Our change now survives a reload since Evennia automatically saves the Attribute to the database for us.</p>
<p>Also our change now survives a reload since Evennia automatically saves the Attribute to the database for us.</p>
</section>
<section id="setting-things-on-new-characters">
<h3><span class="section-number">7.3.3. </span>Setting things on new Characters<a class="headerlink" href="#setting-things-on-new-characters" title="Permalink to this headline"></a></h3>
<p>Things a looking better, but one thing remains strange - the stats start out with a value <code class="docutils literal notranslate"><span class="pre">None</span></code> and we
have to manually set them to something reasonable. In a later lesson we will investigate character-creation
in more detail. For now, lets give every new character some random stats to start with.</p>
<p>We want those stats to be set only once, when the object is first created. For the Character, this method
is called <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>.</p>
<aside class="sidebar">
<p class="sidebar-title"><strong>init</strong> vs at_object_creation</p>
<p>For the <code class="docutils literal notranslate"><span class="pre">Monster</span></code> class we used <code class="docutils literal notranslate"><span class="pre">__init__</span></code> to set up the class. We cant use this for a typeclass because it will be called more than once, at the very least after every reload and maybe more depending on caching. Even if you are familiar with Python, avoid touching <code class="docutils literal notranslate"><span class="pre">__init__</span></code> for typeclasses, the results will not be what you expect.</p>
</aside>
<p>Things are looking better, but one thing remains strange - the stats start out with a value <code class="docutils literal notranslate"><span class="pre">None</span></code> and we have to manually set them to something reasonable. In a later lesson we will investigate character-creation in more detail. For now, lets give every new character some random stats to start with.</p>
<p>We want those stats to be set only once, when the object is first created. For the Character, this method is called <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># up by the other imports</span>
<span class="kn">import</span> <span class="nn">random</span>
@ -619,15 +609,15 @@ is called <code class="docutils literal notranslate"><span class="pre">at_object
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dex</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">int</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">strength</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dexterity</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">intelligence</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_stats</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the main stats of this character</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dex</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">int</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">strength</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">dexterity</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">intelligence</span>
</pre></div>
</div>
<p>We imported a new module, <code class="docutils literal notranslate"><span class="pre">random</span></code>. This is part of Pythons standard library. We used <code class="docutils literal notranslate"><span class="pre">random.randint</span></code> to
@ -637,9 +627,11 @@ set a random value from 3 to 18 to each stat. Simple, but for some classical RPG
(12, 12, 15)
</pre></div>
</div>
<p>Hm, this is the same values we set before. They are not random. The reason for this is of course that, as said,
<code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> only runs <em>once</em>, the very first time a character is created. Our character object was already
created long before, so it will not be called again.</p>
<aside class="sidebar">
<p class="sidebar-title"><strong>init</strong> vs at_object_creation</p>
<p>For the <code class="docutils literal notranslate"><span class="pre">Monster</span></code> class we used <code class="docutils literal notranslate"><span class="pre">__init__</span></code> to set up the class. We cant use this for a typeclass because it will be called more than once, at the very least after every reload and maybe more depending on caching. Even if you are familiar with Python, avoid touching <code class="docutils literal notranslate"><span class="pre">__init__</span></code> for typeclasses, the results will not be what you expect.</p>
</aside>
<p>Hm, this is the same values we set before. They are not random. The reason for this is of course that, as said, <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> only runs <em>once</em>, the very first time a character is created. Our character object was already created long before, so it will not be called again.</p>
<p>Its simple enough to run it manually though:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; self.at_object_creation()
&gt; py self.get_stats()
@ -656,21 +648,22 @@ created long before, so it will not be called again.</p>
</section>
<section id="updating-all-characters-in-a-loop">
<h3><span class="section-number">7.3.4. </span>Updating all Characters in a loop<a class="headerlink" href="#updating-all-characters-in-a-loop" title="Permalink to this headline"></a></h3>
<p>Needless to say, for your game you are wise to have a feel for what you want to go into the <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> hook
before you create a lot of objects (characters in this case). But should it come to that you dont want to have to
go around and re-run the method on everyone manually. For the Python beginner, doing this will also give a chance to
try out Python <em>loops</em>. We try them out in multi-line Python mode:</p>
<aside class="sidebar">
<p class="sidebar-title">AttributeProperties</p>
<p>There is another way to define Attributes on a class, known as <a class="reference internal" href="../../../Components/Attributes.html#using-attributeproperty"><span class="std std-doc">AttributeProperties</span></a>. They can make it easier to maintain static default Attribute values on a typeclass. We will show them off when we make our game later in this tutorial series.</p>
</aside>
<p>Needless to say, you are wise to have a feel for what you want to go into the <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> hook <em>before</em> you create a lot of objects (characters in this case).</p>
<p>Luckily you only need to update objects once, and you dont have to go around and re-run the <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> method on everyone manually. For this well try out a Python <em>loop</em>. Lets go into multi-line Python mode:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py
&gt; for a in [1, 2, &quot;foo&quot;]: &gt; print(a)
&gt; for a in [1, 2, &quot;foo&quot;]:
&gt; print(a)
1
2
foo
</pre></div>
</div>
<p>A python <em>for-loop</em> allows us to loop over something. Above, we made a <em>list</em> of two numbers and a string. In
every iteration of the loop, the variable <code class="docutils literal notranslate"><span class="pre">a</span></code> becomes one element in turn, and we print that.</p>
<p>For our list, we want to loop over all Characters, and want to call <code class="docutils literal notranslate"><span class="pre">.at_object_creation</span></code> on each. This is how
this is done (still in python multi-line mode):</p>
<p>A python <em>for-loop</em> allows us to loop over something. Above, we made a <em>list</em> of two numbers and a string. In every iteration of the loop, the variable <code class="docutils literal notranslate"><span class="pre">a</span></code> becomes one element in turn, and we print that.</p>
<p>For our list, we want to loop over all Characters, and want to call <code class="docutils literal notranslate"><span class="pre">.at_object_creation</span></code> on each. This is how this is done (still in python multi-line mode):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; from typeclasses.characters import Character
&gt; for char in Character.objects.all()
&gt; char.at_object_creation()
@ -678,7 +671,7 @@ this is done (still in python multi-line mode):</p>
</div>
<aside class="sidebar">
<p class="sidebar-title">Database queries</p>
<p><code class="docutils literal notranslate"><span class="pre">Character.objects.all()</span></code> is an example of a database query expressed in Python. This will be converted into a database query under the hood. This syntax is part of <a class="reference external" href="https://docs.djangoproject.com/en/4.1/topics/db/queries/">Djangos query language</a>. You dont need to know Django to use Evennia, but if you ever need more specific database queries, this is always available when you need it.</p>
<p><code class="docutils literal notranslate"><span class="pre">Character.objects.all()</span></code> is an example of a database query expressed in Python. This will be converted into a database query under the hood. This syntax is part of <a class="reference external" href="https://docs.djangoproject.com/en/4.1/topics/db/queries/">Djangos query language</a>. You dont need to know Django to use Evennia, but if you ever need more specific database queries, this is always available when you need it. Well get back to database queries in a later lesson.</p>
</aside>
<p>We import the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class and then we use <code class="docutils literal notranslate"><span class="pre">.objects.all()</span></code> to get all <code class="docutils literal notranslate"><span class="pre">Character</span></code> instances. Simplified,
<code class="docutils literal notranslate"><span class="pre">.objects</span></code> is a resource from which one can <em>query</em> for all <code class="docutils literal notranslate"><span class="pre">Characters</span></code>. Using <code class="docutils literal notranslate"><span class="pre">.all()</span></code> gets us a listing
@ -693,19 +686,13 @@ Closing the Python console.
</section>
<section id="extra-credits">
<h2><span class="section-number">7.4. </span>Extra Credits<a class="headerlink" href="#extra-credits" title="Permalink to this headline"></a></h2>
<p>This principle is the same for other typeclasses. So using the tools explored in this lesson, try to expand
the default room with an <code class="docutils literal notranslate"><span class="pre">is_dark</span></code> flag. It can be either <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code>.
Have all new rooms start with <code class="docutils literal notranslate"><span class="pre">is_dark</span> <span class="pre">=</span> <span class="pre">False</span></code> and make it so that once you change it, it survives a reload.
<p>This principle is the same for other typeclasses. So using the tools explored in this lesson, try to expand the default room with an <code class="docutils literal notranslate"><span class="pre">is_dark</span></code> flag. It can be either <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code>. Have all new rooms start with <code class="docutils literal notranslate"><span class="pre">is_dark</span> <span class="pre">=</span> <span class="pre">False</span></code> and make it so that once you change it, it survives a reload.
Oh, and if you created any other rooms before, make sure they get the new flag too!</p>
</section>
<section id="conclusions">
<h2><span class="section-number">7.5. </span>Conclusions<a class="headerlink" href="#conclusions" title="Permalink to this headline"></a></h2>
<p>In this lesson we created database-persistent dragons by having their classes inherit from one <code class="docutils literal notranslate"><span class="pre">Object</span></code>, one
of Evennias <em>typeclasses</em>. We explored where Evennia looks for typeclasses if we dont specify the path
explicitly. We then modified ourselves - via the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class - to give us some simple RPG stats. This
led to the need to use Evennias <em>Attributes</em>, settable via <code class="docutils literal notranslate"><span class="pre">.db</span></code> and to use a for-loop to update ourselves.</p>
<p>Typeclasses are a fundamental part of Evennia and we will see a lot of more uses of them in the course of
this tutorial. But thats enough of them for now. Its time to take some action. Lets learn about <em>Commands</em>.</p>
<p>In this lesson we created database-persistent dragons by having their classes inherit from one <code class="docutils literal notranslate"><span class="pre">Object</span></code>, one of Evennias <em>typeclasses</em>. We explored where Evennia looks for typeclasses if we dont specify the path explicitly. We then modified ourselves - via the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class - to give us some simple RPG stats. This led to the need to use Evennias <em>Attributes</em>, settable via <code class="docutils literal notranslate"><span class="pre">.db</span></code> and to use a for-loop to update ourselves.</p>
<p>Typeclasses are a fundamental part of Evennia and we will see a lot of more uses of them in the course of this tutorial. But thats enough of them for now. Its time to take some action. Lets learn about <em>Commands</em>.</p>
</section>
</section>

View file

@ -200,6 +200,7 @@ these concepts in the context of Evennia before.</p>
<li class="toctree-l1"><a class="reference internal" href="Beginner-Tutorial-Evennia-Library-Overview.html">6. Overview of the Evennia library</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Beginner-Tutorial-Evennia-Library-Overview.html#where-is-it">6.1. Where is it?</a></li>
<li class="toctree-l2"><a class="reference internal" href="Beginner-Tutorial-Evennia-Library-Overview.html#an-example-of-exploring-the-library">6.2. An example of exploring the library</a></li>
<li class="toctree-l2"><a class="reference internal" href="Beginner-Tutorial-Evennia-Library-Overview.html#conclusions">6.3. Conclusions</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Beginner-Tutorial-Learning-Typeclasses.html">7. Making objects persistent</a><ul>

View file

@ -198,7 +198,7 @@ This is a good idea!
<aside class="sidebar">
<p class="sidebar-title">Functions and Methods</p>
<ul class="simple">
<li><p>Function: Something that performs and action when you <code class="docutils literal notranslate"><span class="pre">call</span></code> it with zero or more <code class="docutils literal notranslate"><span class="pre">arguments</span></code>. A function is stand-alone in a python module, like <code class="docutils literal notranslate"><span class="pre">print()</span></code></p></li>
<li><p>Function: Something that performs and action when you call it with zero or more <code class="docutils literal notranslate"><span class="pre">arguments</span></code>. A function is stand-alone in a python module, like <code class="docutils literal notranslate"><span class="pre">print()</span></code></p></li>
<li><p>Method: A function that sits “on” an object, like <code class="docutils literal notranslate"><span class="pre">obj.msg()</span></code>.</p></li>
</ul>
</aside>
@ -242,21 +242,24 @@ trouble, use the Evennia web client.</p>
</div>
<p>What happened here was that we <em>assigned</em> the string <code class="docutils literal notranslate"><span class="pre">&quot;awesome</span> <span class="pre">sauce&quot;</span></code> to a <em>variable</em> we chose
to name <code class="docutils literal notranslate"><span class="pre">a</span></code>. In the next statement, Python remembered what <code class="docutils literal notranslate"><span class="pre">a</span></code> was and we passed that into <code class="docutils literal notranslate"><span class="pre">format()</span></code>
to get the output. If you replaced the value of <code class="docutils literal notranslate"><span class="pre">a</span></code> with something else in between, <em>that</em> would be printed
instead.</p>
to get the output. If you replaced the value of <code class="docutils literal notranslate"><span class="pre">a</span></code> with something else in between, <em>that</em> would be printed instead.</p>
<p>Heres the stat-example again, moving the stats to variables (here we just set them, but in a real
game they may be changed over time, or modified by circumstance):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py stren, dext, intel = 13, 14, 8 ; print(&quot;STR: {}, DEX: {}, INT: {}&quot;.format(stren, dext, intel))
STR: 13, DEX: 14, INT: 8
</pre></div>
</div>
<p>The point is that even if the values of the stats change, the print() statement would not change - it just keeps
pretty-printing whatever is given to it.</p>
<p>The point is that even if the values of the stats change, the print() statement would not change - it just keeps pretty-printing whatever is given to it.</p>
<p>You can also use named markers, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> &gt; py print(&quot;STR: {stren}, INT: {intel}, STR again: {stren}&quot;.format(dext=10, intel=18, stren=9))
STR: 9, INT: 18, Str again: 9
</pre></div>
</div>
<p>the <code class="docutils literal notranslate"><span class="pre">key=value</span></code> pairs we add are called <em>keyword arguments</em> for the <code class="docutils literal notranslate"><span class="pre">format()</span></code> method. Each named argument will go to the matching <code class="docutils literal notranslate"><span class="pre">{key}</span></code> in the string. When using keywords, the order we add them doesnt matter. We have no <code class="docutils literal notranslate"><span class="pre">{dext}</span></code> and two <code class="docutils literal notranslate"><span class="pre">{stren}</span></code> in the string, and that works fine.</p>
</section>
<section id="f-strings">
<h3><span class="section-number">3.2.2. </span>f-strings<a class="headerlink" href="#f-strings" title="Permalink to this headline"></a></h3>
<p>Using <code class="docutils literal notranslate"><span class="pre">.format()</span></code> is convenient (and there is a <a class="reference external" href="https://www.w3schools.com/python/ref_string_format.asp">lot more</a>
you can do with it). But the <em>f-string</em> can be even more convenient. An
<p>Using <code class="docutils literal notranslate"><span class="pre">.format()</span></code> is convenient (and there is a <a class="reference external" href="https://www.w3schools.com/python/ref_string_format.asp">lot more</a> you can do with it). But the <em>f-string</em> can be even more convenient. An
f-string looks like a normal string … except there is an <code class="docutils literal notranslate"><span class="pre">f</span></code> front of it, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>f&quot;this is now an f-string.&quot;
</pre></div>
@ -266,7 +269,7 @@ f-string looks like a normal string … except there is an <code class="docutils
This is awesome sauce!
</pre></div>
</div>
<p>We could just insert that <code class="docutils literal notranslate"><span class="pre">a</span></code> variable directly into the f-string using <code class="docutils literal notranslate"><span class="pre">{a}</span></code>. Fewer parentheses to
<p>We insert that <code class="docutils literal notranslate"><span class="pre">a</span></code> variable directly into the f-string using <code class="docutils literal notranslate"><span class="pre">{a}</span></code>. Fewer parentheses to
remember and arguable easier to read as well.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py stren, dext, intel = 13, 14, 8 ; print(f&quot;STR: {stren}, DEX: {dext}, INT: {intel}&quot;)
STR: 13, DEX: 14, INT: 8
@ -291,7 +294,7 @@ gives the normal text color. You can also use RGB (Red-Green-Blue) values from 0
<div><p>If you dont see the expected color, your client or terminal may not support Xterm256 (or
color at all). Use the Evennia webclient.</p>
</div></blockquote>
<p>Use the commands <code class="docutils literal notranslate"><span class="pre">color</span> <span class="pre">ansi</span></code> or <code class="docutils literal notranslate"><span class="pre">color</span> <span class="pre">xterm</span></code> to see which colors are available. Experiment!</p>
<p>Use the commands <code class="docutils literal notranslate"><span class="pre">color</span> <span class="pre">ansi</span></code> or <code class="docutils literal notranslate"><span class="pre">color</span> <span class="pre">xterm</span></code> to see which colors are available. Experiment! You can also read a lot more in the <a class="reference internal" href="../../../Concepts/Colors.html"><span class="doc std std-doc">Colors</span></a> documentation.</p>
</section>
</section>
<section id="importing-code-from-other-modules">
@ -326,21 +329,15 @@ Hello World
<p>If you make some error (well cover how to handle errors below), fix the error in the module and
run the <code class="docutils literal notranslate"><span class="pre">reload</span></code> command in-game for your changes to take effect.</p>
<p>So importing <code class="docutils literal notranslate"><span class="pre">world.test</span></code> actually means importing <code class="docutils literal notranslate"><span class="pre">world/test.py</span></code>. Think of the period <code class="docutils literal notranslate"><span class="pre">.</span></code> as
replacing <code class="docutils literal notranslate"><span class="pre">/</span></code> (or <code class="docutils literal notranslate"><span class="pre">\</span></code> for Windows) in your path. The <code class="docutils literal notranslate"><span class="pre">.py</span></code> ending of <code class="docutils literal notranslate"><span class="pre">test.py</span></code> is also never
included in this “Python-path”, but <em>only</em> files with that ending can be imported this way.
Where is <code class="docutils literal notranslate"><span class="pre">mygame</span></code> in that Python-path? The answer is that Evennia has already told Python that
your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> folder is a good place to look for imports. So we dont include <code class="docutils literal notranslate"><span class="pre">mygame</span></code> in the
path - Evennia handles this for us.</p>
replacing <code class="docutils literal notranslate"><span class="pre">/</span></code> (or <code class="docutils literal notranslate"><span class="pre">\</span></code> for Windows) in your path.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">.py</span></code> ending of <code class="docutils literal notranslate"><span class="pre">test.py</span></code> is never included in this “Python-path”, but <em>only</em> files with that ending can be imported this way. Where is <code class="docutils literal notranslate"><span class="pre">mygame</span></code> in that Python-path? The answer is that Evennia has already told Python that your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> folder is a good place to look for imports. So we should not include <code class="docutils literal notranslate"><span class="pre">mygame</span></code> in the path - Evennia handles this for us.</p>
<p>When you import the module, the top “level” of it will execute. In this case, it will immediately
print “Hello World”.</p>
<p>Now try to run this a second time:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py import world.test
</pre></div>
</div>
<p>You will <em>not</em> see any output this second time or any subsequent times! This is not a bug. Rather
it is because of how Python importing works - it stores all imported modules and will
avoid importing them more than once. So your <code class="docutils literal notranslate"><span class="pre">print</span></code> will only run the first time, when the module
is first imported.</p>
<p>You will <em>not</em> see any output this or any subsequent times! This is not a bug. Rather it is because of how Python importing works - it stores all imported modules and will avoid importing them more than once. So your <code class="docutils literal notranslate"><span class="pre">print</span></code> will only run the first time, when the module is first imported.</p>
<p>Try this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; reload
</pre></div>
@ -354,8 +351,7 @@ Hello World!
import it anew. Youd have to do this every time you wanted the print to show though, which is
not very useful.</p>
<blockquote>
<div><p>Well get back to more advanced ways to import code in later tutorial sections - this is an
important topic. But for now, lets press on and resolve this particular problem.</p>
<div><p>Well get back to more advanced ways to import code in <a class="reference internal" href="Beginner-Tutorial-Python-classes-and-objects.html#importing-things"><span class="std std-doc">a later lesson</span></a> - this is an important topic. But for now, lets press on and resolve this particular problem.</p>
</div></blockquote>
<section id="our-first-own-function">
<h3><span class="section-number">3.3.1. </span>Our first own function<a class="headerlink" href="#our-first-own-function" title="Permalink to this headline"></a></h3>
@ -528,8 +524,8 @@ the room it is in.</p>
<aside class="sidebar">
<p class="sidebar-title">Creating objects</p>
<p>The <code class="docutils literal notranslate"><span class="pre">create</span></code> command was first used to create boxes in the
<code class="docutils literal notranslate"><span class="pre">Building</span> <span class="pre">Stuff</span> <span class="pre">&lt;Building-Quickstart&gt;</span></code>_ tutorial. Note how it
uses a “python-path” to describe where to load the mirrors code from.</p>
<a class="reference internal" href="Beginner-Tutorial-Building-Quickstart.html"><span class="doc std std-doc">Building Stuff</span></a> tutorial. You should now recognize
that it uses a “python-path” to tell Evennia where to load the mirrors code from.</p>
</aside>
<p>A mirror should appear in your location.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; look mirror
@ -585,7 +581,7 @@ when you want to do some quick testing. But you can also start a full multi-line
inside Evennia.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py
Evennia Interactive Python mode
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
Python 3.11.0 (default, Nov 22 2022, 11:21:55)
[GCC 8.2.0] on Linux
[py mode - quit() to exit]
</pre></div>
@ -600,14 +596,12 @@ Hello World
[py mode - quit() to exit]
</pre></div>
</div>
<p>Note that we didnt need to put <code class="docutils literal notranslate"><span class="pre">py</span></code> in front now. The system will also echo your input (thats the bit after
the <code class="docutils literal notranslate"><span class="pre">&gt;&gt;&gt;</span></code>). For brevity in this tutorual well turn the echo off. First exit <code class="docutils literal notranslate"><span class="pre">py</span></code> and then start again with the
<code class="docutils literal notranslate"><span class="pre">/noecho</span></code> flag.</p>
<p>Note that we didnt need to put <code class="docutils literal notranslate"><span class="pre">py</span></code> in front now. The system will also echo your input (thats the bit after the <code class="docutils literal notranslate"><span class="pre">&gt;&gt;&gt;</span></code>). For brevity in this tutorual well turn the echo off. First exit <code class="docutils literal notranslate"><span class="pre">py</span></code> and then start again with the <code class="docutils literal notranslate"><span class="pre">/noecho</span></code> flag.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; quit()
Closing the Python console.
&gt; py/noecho
Evennia Interactive Python mode (no echoing of prompts)
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
Python 3.11.0 (default, Nov 22 2022, 11:21:56)
[GCC 8.2.0] on Linux
[py mode - quit() to exit]
</pre></div>
@ -617,13 +611,13 @@ Python 3.7.1 (default, Oct 22 2018, 11:21:55)
<ul class="simple">
<li><p>Start with <code class="docutils literal notranslate"><span class="pre">py</span></code>.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">py/noecho</span></code> if you dont want your input to be echoed for every line.</p></li>
<li><p>All your inputs will now be interpreted as Python code.</p></li>
<li><p><em>All</em> your inputs will now be interpreted as Python code.</p></li>
<li><p>Exit with <code class="docutils literal notranslate"><span class="pre">quit()</span></code>.</p></li>
</ul>
</aside>
<p>We can now enter multi-line Python code:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; a = &quot;Test&quot;
&gt; print(f&quot;This is a {a}.&quot;}
&gt; print(f&quot;This is a {a}.&quot;)
This is a Test.
</pre></div>
</div>
@ -643,8 +637,7 @@ of the block with indention. So the next line must be manually indented (4 space
for Python to know its part of the function body.</p></li>
<li><p>We expand the <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> function with another argument <code class="docutils literal notranslate"><span class="pre">txt</span></code>. This allows us to send any text, not just
“Hello World” over and over.</p></li>
<li><p>To tell <code class="docutils literal notranslate"><span class="pre">py</span></code> that no more lines will be added to the function body, we end with an empty input. When
the normal prompt on how to exit returns, we know we are done.</p></li>
<li><p>To tell <code class="docutils literal notranslate"><span class="pre">py</span></code> that no more lines will be added to the function body, we end with an empty input. When the normal prompt returns, we know we are done.</p></li>
</ul>
<p>Now we have defined a new function. Lets try it out:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; hello_world(me, &quot;Hello world to me!&quot;)
@ -731,8 +724,7 @@ Python code, we need to save it in a Python module, like we did for <code class=
first function, fixed an error and even searched and talked to a mirror! Being able to access
python inside and outside of the game is an important skill for testing and debugging, but in
practice you will be writing most your code in Python modules.</p>
<p>To that end we also created a first new Python module in the <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> game dir, then imported and used it.
Now lets look at the rest of the stuff youve got going on inside that <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> folder …</p>
<p>To that end we also created a first new Python module in the <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> game dir, then imported and used it. Now lets look at the rest of the stuff youve got going on inside that <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> folder …</p>
</section>
</section>

View file

@ -119,16 +119,14 @@
We have also taken a look at what our game dir looks and what is where. Now well start to use it.</p>
<section id="importing-things">
<h2><span class="section-number">5.1. </span>Importing things<a class="headerlink" href="#importing-things" title="Permalink to this headline"></a></h2>
<p>No one writes something as big as an online game in one single huge file. Instead one breaks up the
code into separate files (modules). Each module is dedicated to different purposes. Not only does
it make things cleaner, organized and easier to understand. It also makes it easier to re-use code -
you just import the resources you need and know you only get just what you requested. This makes
it much easier to find errors and to know what code is good and which has issues.</p>
<p>In a <a class="reference internal" href="Beginner-Tutorial-Python-basic-introduction.html#importing-code-from-other-modules"><span class="std std-doc">previous lesson</span></a> we already learned how to import resources into our code. Now well dive a little deeper.</p>
<p>No one writes something as big as an online game in one single huge file. Instead one breaks up the code into separate files (modules). Each module is dedicated to different purposes. Not only does it make things cleaner, organized and easier to understand.</p>
<p>Splitting code also makes it easier to re-use - you just import the resources you need and know you only get just what you requested. This makes it easier to spot errors and to know what code is good and which has issues.</p>
<blockquote>
<div><p>Evennia itself uses your code in the same way - you just tell it where a particular type of code is,
and it will import and use it (often instead of its defaults).</p>
</div></blockquote>
<p>We have already successfully imported things, for example:</p>
<p>Heres a familiar example:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py import world.test ; world.test.hello_world(me)
Hello World!
</pre></div>
@ -156,10 +154,7 @@ not, make it so):</p>
<li><p>Anything on a line after a <code class="docutils literal notranslate"><span class="pre">#</span></code> is a <code class="docutils literal notranslate"><span class="pre">comment</span></code>, ignored by Python</p></li>
</ul>
</aside>
<p>The <em>python_path</em> describes the relation between Python resources, both between and inside
Python <em>modules</em> (that is, files ending with .py). A python-path separates each part of the
path <code class="docutils literal notranslate"><span class="pre">.</span></code> and always skips the <code class="docutils literal notranslate"><span class="pre">.py</span></code> file endings. Also, Evennia already knows to start looking
for python resources inside <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> so this should never be specified. Hence</p>
<p>To reiterate, the <em>python_path</em> describes the relation between Python resources, both between and inside Python <em>modules</em> (that is, files ending with .py). Paths use <code class="docutils literal notranslate"><span class="pre">.</span></code> and always skips the <code class="docutils literal notranslate"><span class="pre">.py</span></code> file endings. Also, Evennia already knows to start looking for python resources inside <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> so this should never be included.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>import world.test
</pre></div>
</div>
@ -169,7 +164,7 @@ this module to get to the function you want:</p>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">import</span></code> like this means that you have to specify the full <code class="docutils literal notranslate"><span class="pre">world.test</span></code> every time you want
to get to your function. Heres a more powerful form of import:</p>
to get to your function. Heres an alternative:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from world.test import hello_world
</pre></div>
</div>
@ -237,6 +232,12 @@ imports at the top, resources that are then used by all code in that module.</p>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
<span class="k">class</span> <span class="nc">ObjectParent</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> class docstring </span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> class docstring</span>
@ -246,28 +247,24 @@ imports at the top, resources that are then used by all code in that module.</p>
</div>
<aside class="sidebar">
<p class="sidebar-title">Docstrings vs Comments</p>
<p>A docstring is not the same as a comment (created by <code class="docutils literal notranslate"><span class="pre">#</span></code>). A docstring is not ignored by Python but is an integral part of the thing it is documenting (the module and the class in this case).</p>
<p>A docstring is not the same as a comment (created by <code class="docutils literal notranslate"><span class="pre">#</span></code>). A docstring is not ignored by Python but is an integral part of the thing it is documenting (the module and the class in this case). For example, we read docstrings to help text for <a class="reference internal" href="../../../Evennia-API.html"><span class="doc std std-doc">API documentation</span></a>; we could not do that with comments.</p>
</aside>
<p>The real file is much longer but we can ignore the multi-line strings (<code class="docutils literal notranslate"><span class="pre">&quot;&quot;&quot;</span> <span class="pre">...</span> <span class="pre">&quot;&quot;&quot;</span></code>). These serve
as documentation-strings, or <em>docstrings</em> for the module (at the top) and the <code class="docutils literal notranslate"><span class="pre">class</span></code> below.</p>
<p>Below the module doc string we have the import. In this case we are importing a resource
from the core <code class="docutils literal notranslate"><span class="pre">evennia</span></code> library itself. We will dive into this later, for now we just treat this
as a black box.</p>
<p>Next we have a <code class="docutils literal notranslate"><span class="pre">class</span></code> named <code class="docutils literal notranslate"><span class="pre">Object</span></code>, which <em>inherits</em> from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. This class doesnt
actually do anything on its own, its only code (except the docstring) is <code class="docutils literal notranslate"><span class="pre">pass</span></code> which means,
well, to pass and dont do anything.</p>
<p>We will get back to this module in the <a class="reference internal" href="Beginner-Tutorial-Learning-Typeclasses.html"><span class="doc std std-doc">next lesson</span></a>. First we need to do a
little detour to understand what a class, an object or instance is. These are fundamental
things to understand before you can use Evennia efficiently.</p>
<p>Next we have an empty <code class="docutils literal notranslate"><span class="pre">class</span></code> named <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code>. It doesnt do anything, its only code (except the docstring) is <code class="docutils literal notranslate"><span class="pre">pass</span></code> which means, well, to pass and dont do anything. Since it also doesnt <em>inherit</em> from anything, its just an empty container. We will not concern ourselves with it for this tutorial.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">class</span></code> named <code class="docutils literal notranslate"><span class="pre">Object</span></code>_ inherits_ from <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> and <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. Since we see that <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> is empty, what is interesting is <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>. Again, the <code class="docutils literal notranslate"><span class="pre">Object</span></code> class doesnt
actually do anything on its own right now, but because of it being a child of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>, its actually providing a lot of functionality! If this is confusing, read on.</p>
<p>We will get back to this module in the <a class="reference internal" href="Beginner-Tutorial-Learning-Typeclasses.html"><span class="doc std std-doc">next lesson</span></a>. First we need to do a little detour to understand what a class, an object or instance is. These are fundamental things to understand before you can use Evennia efficiently.</p>
<aside class="sidebar">
<p class="sidebar-title">OOP</p>
<p>Classes, objects, instances and inheritance are fundamental to Python. This and some other concepts are often clumped together under the term Object-Oriented-Programming (OOP).</p>
</aside>
<section id="classes-and-instances">
<h3><span class="section-number">5.2.1. </span>Classes and instances<a class="headerlink" href="#classes-and-instances" title="Permalink to this headline"></a></h3>
<p>A class can be seen as a template for a type of object. The class describes the basic functionality
of everyone of that class. For example, we could have a class <code class="docutils literal notranslate"><span class="pre">Monster</span></code> which has resources for moving itself
from room to room.</p>
<p>A class can be seen as a template for a type of object. The class describes the basic functionality of everyone of that class. For example, we could have a class <code class="docutils literal notranslate"><span class="pre">Monster</span></code> which has resources for moving itself from room to room.</p>
<p>Open a new file <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code>. Add the following simple class:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
@ -288,11 +285,11 @@ back to the <code class="docutils literal notranslate"><span class="pre">key</sp
<p class="sidebar-title">Terms</p>
<ul class="simple">
<li><p>A <code class="docutils literal notranslate"><span class="pre">class</span></code> is a code template describing a type of something</p></li>
<li><p>An <code class="docutils literal notranslate"><span class="pre">object</span></code> is an <code class="docutils literal notranslate"><span class="pre">instance</span></code> of a <code class="docutils literal notranslate"><span class="pre">class</span></code>. Like using a mold to cast in soldiers, one class can be <code class="docutils literal notranslate"><span class="pre">instantiated</span></code> into any number of object-instances.</p></li>
<li><p>An <code class="docutils literal notranslate"><span class="pre">object</span></code> is an <code class="docutils literal notranslate"><span class="pre">instance</span></code> of a <code class="docutils literal notranslate"><span class="pre">class</span></code>. Like using a mold to cast tin soldiers, one class can be <code class="docutils literal notranslate"><span class="pre">instantiated</span></code> into any number of object-instances. Each instance does not need to be identical (much like each tin soldier can be painted differently).</p></li>
</ul>
</aside>
<p>A class is just a template. Before it can be used, we must create an <em>instance</em> of the class. If
<code class="docutils literal notranslate"><span class="pre">Monster</span></code> is a class, then an instance is Fluffy, the individual red dragon. You instantiate
<code class="docutils literal notranslate"><span class="pre">Monster</span></code> is a class, then an instance is <code class="docutils literal notranslate"><span class="pre">Fluffy</span></code>, a specific dragon individual. You instantiate
by <em>calling</em> the class, much like you would a function:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>fluffy = Monster()
</pre></div>
@ -319,8 +316,7 @@ Monster is moving!
</pre></div>
</div>
<p>We now have two dragons and theyll hang around until with call <code class="docutils literal notranslate"><span class="pre">quit()</span></code> to exit this Python
instance. We can have them move as many times as we want. But no matter how many dragons we
create, they will all show the same printout since <code class="docutils literal notranslate"><span class="pre">key</span></code> is always fixed as “Monster”.</p>
instance. We can have them move as many times as we want. But no matter how many dragons we create, they will all show the same printout since <code class="docutils literal notranslate"><span class="pre">key</span></code> is always fixed as “Monster”.</p>
<p>Lets make the class a little more flexible:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
@ -358,13 +354,11 @@ fluffy.move_around()
Fluffy is moving!
</pre></div>
</div>
<p>Now we passed <code class="docutils literal notranslate"><span class="pre">&quot;Fluffy&quot;</span></code> as an argument to the class. This went into <code class="docutils literal notranslate"><span class="pre">__init__</span></code> and set <code class="docutils literal notranslate"><span class="pre">self.key</span></code>, which we
later used to print with the right name! Again, note that we didnt include <code class="docutils literal notranslate"><span class="pre">self</span></code> when calling.</p>
<p>Now we passed <code class="docutils literal notranslate"><span class="pre">&quot;Fluffy&quot;</span></code> as an argument to the class. This went into <code class="docutils literal notranslate"><span class="pre">__init__</span></code> and set <code class="docutils literal notranslate"><span class="pre">self.key</span></code>, which we later used to print with the right name!</p>
</section>
<section id="whats-so-good-about-objects">
<h3><span class="section-number">5.2.2. </span>Whats so good about objects?<a class="headerlink" href="#whats-so-good-about-objects" title="Permalink to this headline"></a></h3>
<p>So far all weve seen a class do is to behave our first <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> function but more complex. We
could just have made a function:</p>
<p>So far all weve seen a class do is to behave like our first <code class="docutils literal notranslate"><span class="pre">hello_world</span></code> function but being more complex. We could just have made a function:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">monster_move_around</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> is moving!&quot;</span><span class="p">)</span>
</pre></div>
@ -372,14 +366,13 @@ could just have made a function:</p>
<p>The difference between the function and an instance of a class (the object), is that the
object retains <em>state</em>. Once you called the function it forgets everything about what you called
it with last time. The object, on the other hand, remembers changes:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; fluffy.key = &quot;Cuddly&quot;
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; fluffy.key = &quot;Fluffy, the red dragon&quot;
&gt; fluffy.move_around()
Cuddly is moving!
Fluffy, the red dragon is moving!
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">fluffy</span></code> objects <code class="docutils literal notranslate"><span class="pre">key</span></code> was changed to “Cuddly” for as long as its around. This makes objects
extremely useful for representing and remembering collections of data - some of which can be other
objects in turn:</p>
<p>The <code class="docutils literal notranslate"><span class="pre">fluffy</span></code> objects <code class="docutils literal notranslate"><span class="pre">key</span></code> was changed for as long as its around. This makes objects extremely useful for representing and remembering collections of data - some of which can be other
objects in turn. Some examples:</p>
<ul class="simple">
<li><p>A player character with all its stats</p></li>
<li><p>A monster with HP</p></li>
@ -393,8 +386,7 @@ objects in turn:</p>
</section>
<section id="classes-can-have-children">
<h3><span class="section-number">5.2.3. </span>Classes can have children<a class="headerlink" href="#classes-can-have-children" title="Permalink to this headline"></a></h3>
<p>Classes can <em>inherit</em> from each other. A “child” class will inherit everything from its “parent” class. But if
the child adds something with the same name as its parent, it will <em>override</em> whatever it got from its parent.</p>
<p>Classes can <em>inherit</em> from each other. A “child” class will inherit everything from its “parent” class. But if the child adds something with the same name as its parent, it will <em>override</em> whatever it got from its parent.</p>
<p>Lets expand <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/monsters.py</span></code> with another class:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="k">class</span> <span class="nc">Monster</span><span class="p">:</span>
@ -411,7 +403,7 @@ the child adds something with the same name as its parent, it will <em>override<
<span class="k">class</span> <span class="nc">Dragon</span><span class="p">(</span><span class="n">Monster</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is a dragon-specific monster.</span>
<span class="sd"> This is a dragon monster.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">move_around</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -425,15 +417,14 @@ the child adds something with the same name as its parent, it will <em>override<
</pre></div>
</div>
<p>We added some docstrings for clarity. Its always a good idea to add doc strings; you can do so also for methods,
as exemplified for the new <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method.</p>
<p>We added some docstrings for clarity. Its always a good idea to add doc strings; you can do so also for methods, as exemplified for the new <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method.</p>
<p>We created the new class <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> but we also specified that <code class="docutils literal notranslate"><span class="pre">Monster</span></code> is the <em>parent</em> of <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> but adding
the parent in parenthesis. <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">Classname(Parent)</span></code> is the way to do this.</p>
<aside class="sidebar">
<p class="sidebar-title">Multi-inheritance</p>
<p>Its possible to add more comma-separated parents to a class. You should usually avoid this until you <code class="docutils literal notranslate"><span class="pre">really</span></code> know what you are doing. A single parent will be enough for almost every case youll need.</p>
</aside>
<p>Lets try out our new class. First <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and the do</p>
<p>Lets try out our new class. First <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and then:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py
&gt; from typeclasses.monsters import Dragon
&gt; smaug = Dragon(&quot;Smaug&quot;)
@ -443,12 +434,8 @@ Smaug flies through the air high above!
Smaug breathes fire!
</pre></div>
</div>
<p>Because we didnt implement <code class="docutils literal notranslate"><span class="pre">__init__</span></code> in <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>, we got the one from <code class="docutils literal notranslate"><span class="pre">Monster</span></code> instead. But since we
implemented our own <code class="docutils literal notranslate"><span class="pre">move_around</span></code> in <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>, it <em>overrides</em> the one in <code class="docutils literal notranslate"><span class="pre">Monster</span></code>. And <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> is only
available for <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>s of course. Having that on <code class="docutils literal notranslate"><span class="pre">Monster</span></code> would not have made much sense, since not every monster
can breathe fire.</p>
<p>One can also force a class to use resources from the parent even if you are overriding some of it. This is done
with the <code class="docutils literal notranslate"><span class="pre">super()</span></code> method. Modify your <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> class as follows:</p>
<p>Because we didnt (re)implement <code class="docutils literal notranslate"><span class="pre">__init__</span></code> in <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>, we got the one from <code class="docutils literal notranslate"><span class="pre">Monster</span></code>. We did implement our own <code class="docutils literal notranslate"><span class="pre">move_around</span></code> in <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>, so it <em>overrides</em> the one in <code class="docutils literal notranslate"><span class="pre">Monster</span></code>. And <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> is only available for <code class="docutils literal notranslate"><span class="pre">Dragon</span></code>s. Having that on <code class="docutils literal notranslate"><span class="pre">Monster</span></code> would not have made much sense, since not every monster can breathe fire.</p>
<p>One can also force a class to use resources from the parent even if you are overriding some of it. This is done with the <code class="docutils literal notranslate"><span class="pre">super()</span></code> method. Modify your <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> class as follows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">Dragon</span><span class="p">(</span><span class="n">Monster</span><span class="p">):</span>
@ -461,11 +448,10 @@ with the <code class="docutils literal notranslate"><span class="pre">super()</s
</pre></div>
</div>
<blockquote>
<div><p>Keep <code class="docutils literal notranslate"><span class="pre">Monster</span></code> and the <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method, <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">...</span></code> indicates the rest of the code is untouched.</p>
<div><p>Keep <code class="docutils literal notranslate"><span class="pre">Monster</span></code> and the <code class="docutils literal notranslate"><span class="pre">firebreath</span></code> method. The <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">...</span></code> above indicates the rest of the code is unchanged.</p>
</div></blockquote>
<p>The <code class="docutils literal notranslate"><span class="pre">super().move_around()</span></code> line means that we are calling <code class="docutils literal notranslate"><span class="pre">move_around()</span></code> on the parent of the class. So in this
case, we will call <code class="docutils literal notranslate"><span class="pre">Monster.move_around</span></code> first, before doing our own thing.</p>
<p>Now <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and then:</p>
<p>The <code class="docutils literal notranslate"><span class="pre">super().move_around()</span></code> line means that we are calling <code class="docutils literal notranslate"><span class="pre">move_around()</span></code> on the parent of the class. So in this case, we will call <code class="docutils literal notranslate"><span class="pre">Monster.move_around</span></code> first, before doing our own thing.</p>
<p>To see, <code class="docutils literal notranslate"><span class="pre">reload</span></code> the server and then:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&gt; py
&gt; from typeclasses.monsters import Dragon
&gt; smaug = Dragon(&quot;Smaug&quot;)
@ -474,19 +460,14 @@ Smaug is moving!
The world trembles.
</pre></div>
</div>
<p>We can see that <code class="docutils literal notranslate"><span class="pre">Monster.move_around()</span></code> is calls first and prints “Smaug is moving!”, followed by the extra bit
about the trembling world we added in the <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> class.</p>
<p>Inheritance is very powerful because it allows you to organize and re-use code while only adding the special things
you want to change. Evennia uses this concept a lot.</p>
<p>We can see that <code class="docutils literal notranslate"><span class="pre">Monster.move_around()</span></code> is called first and prints “Smaug is moving!”, followed by the extra bit about the trembling world from the <code class="docutils literal notranslate"><span class="pre">Dragon</span></code> class.</p>
<p>Inheritance is a powerful concept. It allows you to organize and re-use code while only adding the special things you want to change. Evennia uses this a lot.</p>
</section>
</section>
<section id="summary">
<h2><span class="section-number">5.3. </span>Summary<a class="headerlink" href="#summary" title="Permalink to this headline"></a></h2>
<p>We have created our first dragons from classes. We have learned a little about how you <em>instantiate</em> a class
into an <em>object</em>. We have seen some examples of <em>inheritance</em> and we tested to <em>override</em> a method in the parent
with one in the child class. We also used <code class="docutils literal notranslate"><span class="pre">super()</span></code> to good effect.</p>
<p>We have used pretty much raw Python so far. In the coming lessons well start to look at the extra bits that Evennia
provides. But first we need to learn just where to find everything.</p>
<p>We have created our first dragons from classes. We have learned a little about how you <em>instantiate</em> a class into an <em>object</em>. We have seen some examples of <em>inheritance</em> and we tested to <em>override</em> a method in the parent with one in the child class. We also used <code class="docutils literal notranslate"><span class="pre">super()</span></code> to good effect.</p>
<p>We have used pretty much raw Python so far. In the coming lessons well start to look at the extra bits that Evennia provides. But first we need to learn just where to find everything.</p>
</section>
</section>

View file

@ -140,7 +140,8 @@ Both if you are triumphant or if you use the <code class="docutils literal notra
</div>
<section id="gameplay">
<h2><span class="section-number">2.1. </span>Gameplay<a class="headerlink" href="#gameplay" title="Permalink to this headline"></a></h2>
<p><img alt="the castle off the moor" src="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/22916c25-6299-453d-a221-446ec839f567/da2pmzu-46d63c6d-9cdc-41dd-87d6-1106db5a5e1a.jpg/v1/fill/w_600,h_849,q_75,strp/the_castle_off_the_moor_by_griatch_art_da2pmzu-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3siaGVpZ2h0IjoiPD04NDkiLCJwYXRoIjoiXC9mXC8yMjkxNmMyNS02Mjk5LTQ1M2QtYTIyMS00NDZlYzgzOWY1NjdcL2RhMnBtenUtNDZkNjNjNmQtOWNkYy00MWRkLTg3ZDYtMTEwNmRiNWE1ZTFhLmpwZyIsIndpZHRoIjoiPD02MDAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.omuS3D1RmFiZCy9OSXiIita-HxVGrBok3_7asq0rflw" /></p>
<p><img alt="the castle off the moor" src="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/22916c25-6299-453d-a221-446ec839f567/da2pmzu-46d63c6d-9cdc-41dd-87d6-1106db5a5e1a.jpg/v1/fill/w_600,h_849,q_75,strp/the_castle_off_the_moor_by_griatch_art_da2pmzu-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3siaGVpZ2h0IjoiPD04NDkiLCJwYXRoIjoiXC9mXC8yMjkxNmMyNS02Mjk5LTQ1M2QtYTIyMS00NDZlYzgzOWY1NjdcL2RhMnBtenUtNDZkNjNjNmQtOWNkYy00MWRkLTg3ZDYtMTEwNmRiNWE1ZTFhLmpwZyIsIndpZHRoIjoiPD02MDAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.omuS3D1RmFiZCy9OSXiIita-HxVGrBok3_7asq0rflw" />
(image by Griatch)</p>
<p><em>To get into the mood of this miniature quest, imagine you are an adventurer out to find fame and
fortune. You have heard rumours of an old castle ruin by the coast. In its depth a warrior princess
was buried together with her powerful magical weapon - a valuable prize, if its true. Of course

View file

@ -123,7 +123,7 @@
<li><p>Windows: In the installer, make sure you select <code class="docutils literal notranslate"><span class="pre">add</span> <span class="pre">python</span> <span class="pre">to</span> <span class="pre">path</span></code>. If you have multiple versions of Python installed, use <code class="docutils literal notranslate"><span class="pre">py</span></code> command instead of <code class="docutils literal notranslate"><span class="pre">python</span></code> to have Windows automatically use the latest.</p></li>
</ul>
</li>
<li><p>Using a light-weight <a class="reference internal" href="Installation-Git.html#virtualenv"><span class="std std-doc">Python virtual environment</span></a> _ is optional, but <em>highly recommended</em> in order to keep your Evennia installation independent from the system libraries. This comes with Python.</p></li>
<li><p>Using a light-weight <a class="reference internal" href="Installation-Git.html#virtualenv"><span class="std std-doc">Python virtual environment</span></a> is optional, but <em>highly recommended</em> in order to keep your Evennia installation independent from the system libraries. Using virtualenvs is common Python praxis.</p></li>
<li><p>Dont install Evennia as administrator or superuser.</p></li>
<li><p>If you run into trouble, see <a class="reference internal" href="Installation-Troubleshooting.html"><span class="doc std std-doc">installation troubleshooting</span></a>.</p></li>
</ul>
@ -131,7 +131,7 @@
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install evennia
</pre></div>
</div>
<p>Optional: If you use a <span class="xref myst">contrib</span> that warns you that it needs additional packages, you can
<p>Optional: If you use a <a class="reference internal" href="../Contribs/Contribs-Overview.html"><span class="doc std std-doc">contrib</span></a> that warns you that it needs additional packages, you can
install all extra dependencies with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install evennia[extra]
</pre></div>
@ -140,23 +140,25 @@ install all extra dependencies with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pip install --upgrade evennia
</pre></div>
</div>
<p>Once installed, make sure the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command works. Use <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">-h</span></code> for usage help. If you are using a virtualenv, make sure its active whenever you need to use the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command.</p>
<blockquote>
<div><p>Windows users only: You now need to run <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">evennia</span></code> once. This should permanently make the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command available in your environment.</p>
</div></blockquote>
<p>Once installed, make sure the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command works. Use <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">-h</span></code> for usage help. If you are using a virtualenv, make sure its active whenever you need to use the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command later.</p>
<blockquote>
<div><p>You can also <a class="reference internal" href="Installation-Git.html"><span class="doc std std-doc">clone Evennia from github</span></a> or use <a class="reference internal" href="Installation-Docker.html"><span class="doc std std-doc">docker</span></a>. Some users have also experimented with <a class="reference internal" href="Installation-Android.html"><span class="doc std std-doc">installing Evennia on Android</span></a>.</p>
</div></blockquote>
<section id="initialize-a-new-game">
<h2>Initialize a new game<a class="headerlink" href="#initialize-a-new-game" title="Permalink to this headline"></a></h2>
<blockquote>
<div><p>Windows users: You need to first run <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">evennia</span></code> once. This should permanently add the evennia launcher to your environment, making the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command available.</p>
</div></blockquote>
<p>Use <code class="docutils literal notranslate"><span class="pre">cd</span></code> to enter a folder where you want to do your game development. Here (and in
the rest of the Evennia documentation) we call this folder <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, but you should of course
name your game whatever you like.</p>
<p>We will create a new “game dir” for you do create your game in. Here (and in
the rest of the Evennia documentation) we refer to this game dir as <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, but you should of course name your game whatever you like.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia --init mygame
</pre></div>
</div>
<p>This will create a new folder <code class="docutils literal notranslate"><span class="pre">mygame</span></code> (or whatever you chose) in your current location. This
contains empty templates and all the default settings needed to start the server.</p>
<blockquote>
<div><p>The game dir doesnt need to have the exact same name as your game. You can set the name of your game later by editing <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>.</p>
</div></blockquote>
</section>
<section id="start-the-new-game">
<h2>Start the new game<a class="headerlink" href="#start-the-new-game" title="Permalink to this headline"></a></h2>
@ -168,7 +170,7 @@ evennia migrate
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia start
</pre></div>
</div>
<p>Set your user-name and password when prompted. This will be the “god user” or “superuser” in-game. The email is optional.</p>
<p>Set your user-name and password when prompted. This will be the “god user” or “super user” in-game. The email is optional.</p>
<blockquote>
<div><p>You can also <a class="reference internal" href="Installation-Non-Interactive.html"><span class="doc std std-doc">automate</span></a> the creation of the super user.</p>
</div></blockquote>
@ -189,6 +191,7 @@ evennia migrate
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia stop
</pre></div>
</div>
<p>See <a class="reference internal" href="Start-Stop-Reload.html"><span class="doc std std-doc">Server start-stop-reload</span></a> page for more details.</p>
</section>
<section id="see-server-logs">
<h2>See server logs<a class="headerlink" href="#see-server-logs" title="Permalink to this headline"></a></h2>
@ -208,18 +211,17 @@ evennia migrate
</section>
<section id="server-configuration">
<h2>Server configuration<a class="headerlink" href="#server-configuration" title="Permalink to this headline"></a></h2>
<p>The server configuration file is <code class="docutils literal notranslate"><span class="pre">mygame/server/settings.py</span></code>. Its empty by default. Copy and change only the settings you want from the <a class="reference internal" href="Settings-Default.html"><span class="doc std std-doc">default settings file</span></a>.</p>
<p>The server configuration file is <code class="docutils literal notranslate"><span class="pre">mygame/server/settings.py</span></code>. Its empty by default. Copy and change only the settings you want from the <a class="reference internal" href="Settings-Default.html"><span class="doc std std-doc">default settings file</span></a>. See the <a class="reference internal" href="Settings.html"><span class="doc std std-doc">Settings</span></a> documentation for more info.</p>
</section>
<section id="register-with-the-evennia-game-index-optional">
<h2>Register with the Evennia Game Index (optional)<a class="headerlink" href="#register-with-the-evennia-game-index-optional" title="Permalink to this headline"></a></h2>
<p>You can let the world know that you are working on a new Evennia-based game by
registering your server with the <em>Evennia game index</em>. You dont have to be
open for players to do this - you just mark your game as closed and “pre-alpha”.</p>
registering your server with the <em>Evennia game index</em>.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia connections
</pre></div>
</div>
<p>See <a class="reference internal" href="Evennia-Game-Index.html"><span class="doc std std-doc">here</span></a> for more instructions and please <a class="reference external" href="http:///games.evennia.com">check out the index</a>
beforehand to make sure you dont pick a game name that is already taken - be nice!</p>
<p>Just follow the prompts. You dont have to be open for players to do this - you just mark your game as closed and “pre-alpha”.</p>
<p>See <a class="reference internal" href="Evennia-Game-Index.html"><span class="doc std std-doc">here</span></a> for more instructions and please <a class="reference external" href="http:///games.evennia.com">check out the index</a> beforehand to make sure you dont pick a game name that is already taken - be nice!</p>
</section>
<section id="the-next-steps">
<h2>The Next steps<a class="headerlink" href="#the-next-steps" title="Permalink to this headline"></a></h2>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Choosing An SQL Server" href="Choosing-An-SQL-Server.html" />
<link rel="prev" title="Game Settings and Configuration direcotry" href="Settings.html" />
<link rel="prev" title="Game Settings and Configuration directory" href="Settings.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Choosing-An-SQL-Server.html" title="Choosing An SQL Server"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Settings.html" title="Game Settings and Configuration direcotry"
<a href="Settings.html" title="Game Settings and Configuration directory"
accesskey="P">previous</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-1"><a href="Setup-Overview.html" accesskey="U">Server Setup and Life</a> &#187;</li>
@ -62,7 +62,7 @@
<script>$('#searchbox').show(0);</script>
<h4>Previous topic</h4>
<p class="topless"><a href="Settings.html"
title="previous chapter">Game Settings and Configuration direcotry</a></p>
title="previous chapter">Game Settings and Configuration directory</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Choosing-An-SQL-Server.html"
title="next chapter">Choosing An SQL Server</a></p>
@ -1337,7 +1337,7 @@ to change into <code class="docutils literal notranslate"><span class="pre">myga
<a href="Choosing-An-SQL-Server.html" title="Choosing An SQL Server"
>next</a> |</li>
<li class="right" >
<a href="Settings.html" title="Game Settings and Configuration direcotry"
<a href="Settings.html" title="Game Settings and Configuration directory"
>previous</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-1"><a href="Setup-Overview.html" >Server Setup and Life</a> &#187;</li>

View file

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Game Settings and Configuration direcotry &#8212; Evennia 1.0-dev documentation</title>
<title>Game Settings and Configuration directory &#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>
@ -37,7 +37,7 @@
accesskey="P">previous</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-1"><a href="Setup-Overview.html" accesskey="U">Server Setup and Life</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Game Settings and Configuration direcotry</a></li>
<li class="nav-item nav-item-this"><a href="">Game Settings and Configuration directory</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
@ -62,7 +62,7 @@
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Game Settings and Configuration direcotry</a><ul>
<li><a class="reference internal" href="#">Game Settings and Configuration directory</a><ul>
<li><a class="reference internal" href="#settings-file">Settings file</a></li>
<li><a class="reference internal" href="#other-files-in-the-server-conf-directory">Other files in the <code class="docutils literal notranslate"><span class="pre">server/conf</span></code> directory</a></li>
</ul>
@ -105,8 +105,8 @@
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="game-settings-and-configuration-direcotry">
<h1>Game Settings and Configuration direcotry<a class="headerlink" href="#game-settings-and-configuration-direcotry" title="Permalink to this headline"></a></h1>
<section class="tex2jax_ignore mathjax_ignore" id="game-settings-and-configuration-directory">
<h1>Game Settings and Configuration directory<a class="headerlink" href="#game-settings-and-configuration-directory" title="Permalink to this headline"></a></h1>
<p>Evennia runs out of the box without any changes to its settings. But there are several important
ways to customize the server and expand it with your own plugins.</p>
<p>All game-specific settings are located in the <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/</span></code> directory.</p>
@ -221,7 +221,7 @@ room).</p></li>
>previous</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-1"><a href="Setup-Overview.html" >Server Setup and Life</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Game Settings and Configuration direcotry</a></li>
<li class="nav-item nav-item-this"><a href="">Game Settings and Configuration directory</a></li>
</ul>
<div class="develop">develop branch</div>
</div>

View file

@ -62,8 +62,8 @@
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Server Setup and Life</a><ul>
<li><a class="reference internal" href="#installation-running">Installation &amp; running</a></li>
<li><a class="reference internal" href="#configuring">Configuring</a></li>
<li><a class="reference internal" href="#installation-and-running">Installation and running</a></li>
<li><a class="reference internal" href="#configuration">Configuration</a></li>
<li><a class="reference internal" href="#going-public">Going public</a></li>
</ul>
</li>
@ -108,8 +108,8 @@
<section class="tex2jax_ignore mathjax_ignore" id="server-setup-and-life">
<h1>Server Setup and Life<a class="headerlink" href="#server-setup-and-life" title="Permalink to this headline"></a></h1>
<p>This sums up all steps of maintaining your Evennia game from first installation to production release.</p>
<section id="installation-running">
<h2>Installation &amp; running<a class="headerlink" href="#installation-running" title="Permalink to this headline"></a></h2>
<section id="installation-and-running">
<h2>Installation and running<a class="headerlink" href="#installation-and-running" title="Permalink to this headline"></a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Installation.html">Installation</a><ul>
@ -176,11 +176,11 @@
</ul>
</div>
</section>
<section id="configuring">
<h2>Configuring<a class="headerlink" href="#configuring" title="Permalink to this headline"></a></h2>
<section id="configuration">
<h2>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Settings.html">Game Settings and Configuration direcotry</a><ul>
<li class="toctree-l1"><a class="reference internal" href="Settings.html">Game Settings and Configuration directory</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Settings.html#settings-file">Settings file</a></li>
<li class="toctree-l2"><a class="reference internal" href="Settings.html#other-files-in-the-server-conf-directory">Other files in the <code class="docutils literal notranslate"><span class="pre">server/conf</span></code> directory</a></li>
</ul>

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Game Settings and Configuration direcotry" href="Settings.html" />
<link rel="next" title="Game Settings and Configuration directory" href="Settings.html" />
<link rel="prev" title="Non-interactive setup" href="Installation-Non-Interactive.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Settings.html" title="Game Settings and Configuration direcotry"
<a href="Settings.html" title="Game Settings and Configuration directory"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Installation-Non-Interactive.html" title="Non-interactive setup"
@ -85,7 +85,7 @@
title="previous chapter">Non-interactive setup</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Settings.html"
title="next chapter">Game Settings and Configuration direcotry</a></p>
title="next chapter">Game Settings and Configuration directory</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -123,7 +123,7 @@ program. If the <code class="docutils literal notranslate"><span class="pre">eve
Evennia as described on the <a class="reference internal" href="Installation.html"><span class="doc std std-doc">Installation</span></a> page.</p>
<aside class="sidebar">
<p class="sidebar-title">evennia not found?</p>
<p>If you ever try the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command and get an error complaining that the command is not available, make sure your <a class="reference internal" href="../Glossary.html#virtualenv"><span class="std std-doc">virtualenv</span></a> is active.</p>
<p>If you ever try the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command and get an error complaining that the command is not available, make sure your <a class="reference internal" href="../Glossary.html#virtualenv"><span class="std std-doc">virtualenv</span></a> is active. On Windows you may need to to run <code class="docutils literal notranslate"><span class="pre">py</span> <span class="pre">-m</span> <span class="pre">evennia</span></code> once first.</p>
</aside>
<p>Below are described the various management options. Run</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia -h
@ -136,11 +136,7 @@ Evennia as described on the <a class="reference internal" href="Installation.htm
<p>to give you a menu with options.</p>
<section id="starting-evennia">
<h2>Starting Evennia<a class="headerlink" href="#starting-evennia" title="Permalink to this headline"></a></h2>
<p>Evennia consists of two components, the Evennia <a class="reference internal" href="../Components/Portal-And-Server.html"><span class="doc std std-doc">Portal and Server</span></a>. Briefly,
the <em>Server</em> is what is running the mud. It handles all game-specific things but doesnt care
exactly how players connect, only that they have. The <em>Portal</em> is a gateway to which players
connect. It knows everything about telnet, ssh, webclient protocols etc but very little about the
game. Both are required for a functioning mud.</p>
<p>Evennia consists of two components, the Evennia <a class="reference internal" href="../Components/Portal-And-Server.html"><span class="doc std std-doc">Portal and Server</span></a>. Briefly, the <em>Server</em> is what is running the mud. It handles all game-specific things but doesnt care exactly how players connect, only that they have. The <em>Portal</em> is a gateway to which players connect. It knows everything about telnet, ssh, webclient protocols etc but very little about the game. Both are required for a functioning game.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia start
</pre></div>
</div>
@ -153,37 +149,29 @@ game. Both are required for a functioning mud.</p>
</pre></div>
</div>
<blockquote>
<div><p>To stop viewing the log files, press <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code>.</p>
<div><p>To stop viewing the log files, press <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code> (<code class="docutils literal notranslate"><span class="pre">Cmd-C</span></code> on Mac).</p>
</div></blockquote>
</section>
<section id="reloading">
<h2>Reloading<a class="headerlink" href="#reloading" title="Permalink to this headline"></a></h2>
<p>The act of <em>reloading</em> means the Portal will tell the Server to shut down and then boot it back up
again. Everyone will get a message and the game will be briefly paused for all accounts as the
server
reboots. Since they are connected to the <em>Portal</em>, their connections are not lost.</p>
<p>Reloading is as close to a “warm reboot” you can get. It reinitializes all code of Evennia, but
doesnt kill “persistent” <a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a>. It also calls <code class="docutils literal notranslate"><span class="pre">at_server_reload()</span></code> hooks on all
objects so you
can save eventual temporary properties you want.</p>
<p>From in-game the <code class="docutils literal notranslate"><span class="pre">&#64;reload</span></code> command is used. You can also reload the server from outside the game:</p>
<p>The act of <em>reloading</em> means the Portal will tell the Server to shut down and then boot it back up again. Everyone will get a message and the game will be briefly paused for all accounts as the server reboots. Since they are connected to the <em>Portal</em>, their connections are not lost.</p>
<p>Reloading is as close to a “warm reboot” you can get. It reinitializes all code of Evennia, but doesnt kill “persistent” <a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a>. It also calls <code class="docutils literal notranslate"><span class="pre">at_server_reload()</span></code> hooks on all objects so you can save eventual temporary properties you want.</p>
<p>From in-game the <code class="docutils literal notranslate"><span class="pre">reload</span></code> command is used. You can also reload the server from outside the game:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia reload
</pre></div>
</div>
<p>Sometimes reloading from “the outside” is necessary in case you have added some sort of bug that
blocks in-game input.</p>
<p>Sometimes reloading from “the outside” is necessary in case you have added some sort of bug that blocks in-game input.</p>
</section>
<section id="stopping">
<h2>Stopping<a class="headerlink" href="#stopping" title="Permalink to this headline"></a></h2>
<p>A full shutdown closes Evennia completely, both Server and Portal. All accounts will be booted and
systems saved and turned off cleanly.</p>
<p>From inside the game you initiate a shutdown with the <code class="docutils literal notranslate"><span class="pre">&#64;shutdown</span></code> command. From command line you do</p>
<p>From inside the game you initiate a shutdown with the <code class="docutils literal notranslate"><span class="pre">shutdown</span></code> command. From command line you do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia stop
</pre></div>
</div>
<p>You will see messages of both Server and Portal closing down. All accounts will see the shutdown
message and then be disconnected. The same effect happens if you press <code class="docutils literal notranslate"><span class="pre">Ctrl+C</span></code> while the server
runs in interactive mode.</p>
message and then be disconnected.</p>
</section>
<section id="foreground-mode">
<h2>Foreground mode<a class="headerlink" href="#foreground-mode" title="Permalink to this headline"></a></h2>
@ -200,15 +188,13 @@ kill the process (not just the log-file view) with <code class="docutils literal
</pre></div>
</div>
<p>will start the <em>Portal</em> in interactive mode.</p>
<p>If you do <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code>/<code class="docutils literal notranslate"><span class="pre">Cmd-C</span></code> in foreground mode, the component will stop. Youll need to run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">start</span></code> to get the game going again.</p>
</section>
<section id="resetting">
<h2>Resetting<a class="headerlink" href="#resetting" title="Permalink to this headline"></a></h2>
<p><em>Resetting</em> is the equivalent of a “cold reboot” - the Server will shut down and then restarted
again, but will behave as if it was fully shut down. As opposed to a “real” shutdown, no accounts
will be disconnected during a
reset. A reset will however purge all non-persistent scripts and will call <code class="docutils literal notranslate"><span class="pre">at_server_shutdown()</span></code>
hooks. It can be a good way to clean unsafe scripts during development, for example.</p>
<p>From in-game the <code class="docutils literal notranslate"><span class="pre">&#64;reset</span></code> command is used. From the terminal:</p>
again, but will behave as if it was fully shut down. As opposed to a “real” shutdown, no accounts will be disconnected during a reset. A reset will however purge all non-persistent scripts and will call <code class="docutils literal notranslate"><span class="pre">at_server_shutdown()</span></code> hooks. It can be a good way to clean unsafe scripts during development, for example.</p>
<p>From in-game the <code class="docutils literal notranslate"><span class="pre">reset</span></code> command is used. From the terminal:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia reset
</pre></div>
</div>
@ -276,8 +262,7 @@ related to Evennia:</p>
<p>During development, you will usually modify code and then reload the server to see your changes.
This is done by Evennia re-importing your custom modules from disk. Usually bugs in a module will
just have you see a traceback in the game, in the log or on the command line. For some really
serious syntax errors though, your module might not even be recognized as valid Python. Evennia may
then fail to restart correctly.</p>
serious syntax errors though, your module might not even be recognized as valid Python. Evennia may then fail to restart correctly.</p>
<p>From inside the game you see a text about the Server restarting followed by an ever growing list of
“…”. Usually this only lasts a very short time (up to a few seconds). If it seems to go on, it
means the Portal is still running (you are still connected to the game) but the Server-component of
@ -310,7 +295,7 @@ In-game you should now get the message that the Server has successfully restarte
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Settings.html" title="Game Settings and Configuration direcotry"
<a href="Settings.html" title="Game Settings and Configuration directory"
>next</a> |</li>
<li class="right" >
<a href="Installation-Non-Interactive.html" title="Non-interactive setup"

View file

@ -1,27 +0,0 @@
Based on [write-good](https://github.com/btford/write-good).
> Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.
```
The MIT License (MIT)
Copyright (c) 2014 Brian Ford
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

View file

@ -2,7 +2,9 @@
These are the 'building blocks' out of which Evennia is built. This documentation is complementary to, and often goes deeper than, the doc-strings of each component in the [API](../Evennia-API.md).
## Database entites
## Basic entites
These are base pieces used to make an Evennia game. Most are long-lived and are persisted in the database.
```{toctree}
:maxdepth: 2
@ -20,11 +22,13 @@ Tags.md
Prototypes.md
Help-System.md
Permissions.md
Portal-And-Server.md
```
## Commands
Evennia's Command system handle everything sent to the server by the user.
```{toctree}
:maxdepth: 2
@ -36,11 +40,15 @@ Connection-Screen.md
Batch-Processors.md
Batch-Code-Processor.md
Batch-Command-Processor.md
Inputfuncs.md
Outputfuncs.md
```
## Utils and tools
Evennia provides a library of code resources to help the creation of a game.
```{toctree}
:maxdepth: 2
@ -59,30 +67,15 @@ Signals.md
## Web components
Evennia is also its own webserver, with a website and in-browser webclient you can expand on.
```{toctree}
:maxdepth: 2
Website.md
Web-API.md
Web-Admin.md
```
## Server and network
```{toctree}
:maxdepth: 2
Portal-And-Server.md
Inputfuncs.md
Outputfuncs.md
Server.md
Setup/Server-Conf.md
Webserver.md
Webclient.md
Web-Admin.md
Webserver.md
Web-API.md
Bootstrap-Components-and-Utilities.md
Signals.md
```
```

View file

@ -4,12 +4,8 @@
Evennia consists of two processes, known as *Portal* and *Server*. They can be controlled from
inside the game or from the command line as described [here](../Setup/Start-Stop-Reload.md).
If you are new to the concept, the main purpose of separating the two is to have accounts connect to
the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the
Server part) without Accounts getting disconnected.
If you are new to the concept, the main purpose of separating the two is to have accounts connect to the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the Server part) without Accounts getting disconnected.
![portal and server layout](https://474a3b9f-a-62cb3a1a-s-
sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png)
![portal and server layout](https://474a3b9f-a-62cb3a1a-s- sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png)
The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection.
This allows the two programs to communicate seamlessly.
The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection. This allows the two programs to communicate seamlessly.

View file

@ -1,3 +0,0 @@
# Server component
TODO: This is currently in [Portal-and-Server](./Portal-And-Server.md).

View file

@ -42,7 +42,7 @@ Example: To change the list of in-use plugins, you need to override base.html by
`evennia/web/templates/webclient/base.html` to
`mygame/web/templates/webclient/base.html` and editing it to add your new plugin.
# Evennia Web Client API (from evennia.js)
## Evennia Web Client API (from evennia.js)
* `Evennia.init( opts )`
* `Evennia.connect()`
* `Evennia.isConnected()`
@ -50,14 +50,14 @@ Example: To change the list of in-use plugins, you need to override base.html by
* `Evennia.emit( cmdname, args, kwargs )`
* `log()`
# Plugin Manager API (from webclient_gui.js)
## Plugin Manager API (from webclient_gui.js)
* `options` Object, Stores key/value 'state' that can be used by plugins to coordinate behavior.
* `plugins` Object, key/value list of the all the loaded plugins.
* `plugin_handler` Object
* `plugin_handler.add("name", plugin)`
* `plugin_handler.onSend(string)`
# Plugin callbacks API
## Plugin callbacks API
* `init()` -- The only required callback
* `boolean onKeydown(event)` This plugin listens for Keydown events
* `onBeforeUnload()` This plugin does something special just before the webclient page/tab is
@ -79,21 +79,19 @@ their callback for this event called. This enables things like the up/down arro
history.js plugin to always occur before the default_in.js plugin adds that key to the current input
buffer.
# Example/Default Plugins (plugins/*.js)
### Example/Default Plugins (`plugins/*.js`)
* `clienthelp.js` Defines onOptionsUI from the options2 plugin. This is a mostly empty plugin to
add some "How To" information for your game.
* `default_in.js` Defines onKeydown. <enter> key or mouse clicking the arrow will send the currently
typed text.
* `default_in.js` Defines onKeydown. `<enter>` key or mouse clicking the arrow will send the currently typed text.
* `default_out.js` Defines onText, onPrompt, and onUnknownCmd. Generates HTML output for the user.
* `default_unload.js` Defines onBeforeUnload. Prompts the user to confirm that they meant to
leave/close the game.
* `font.js` Defines onOptionsUI. The plugin adds the ability to select your font and font size.
* `goldenlayout_default_config.js` Not actually a plugin, defines a global variable that
goldenlayout uses to determine its window layout, known tag routing, etc.
* `goldenlayout.js` Defines onKeydown, onText and custom functions. A very powerful "tabbed" window
manager for drag-n-drop windows, text routing and more.
* `history.js` Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow
keys to peruse.
* `goldenlayout.js` Defines onKeydown, onText and custom functions. A very powerful "tabbed" window manager for drag-n-drop windows, text routing and more.
* `history.js` Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow keys to peruse.
* `hotbuttons.js` Defines onGotOptions. A Disabled-by-default plugin that defines a button bar with
user-assignable commands.
* `html.js` A basic plugin to allow the client to handle "raw html" messages from the server, this
@ -104,32 +102,22 @@ window for a side-by-side web/text interface, mostly an example of how to build
* `message_routing.js` Defines onOptionsUI, onText, onKeydown. This goldenlayout-only plugin
implements regex matching to allow users to "tag" arbitrary text that matches, so that it gets
routed to proper windows. Similar to "Spawn" functions for other clients.
* `multimedia.js` An basic plugin to allow the client to handle "image" "audio" and "video" messages
from the server and display them as inline HTML.
* `multimedia.js` An basic plugin to allow the client to handle "image" "audio" and "video" messages from the server and display them as inline HTML.
* `notifications.js` Defines onText. Generates browser notification events for each new message
while the tab is hidden.
* `oob.js` Defines onSend. Allows the user to test/send Out Of Band json messages to the server.
* `options.js` Defines most callbacks. Provides a popup-based UI to coordinate options settings with the server.
* `options2.js` Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab.
Integrates with other plugins via the custom onOptionsUI callback.
* `options2.js` Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab. Integrates with other plugins via the custom onOptionsUI callback.
* `popups.js` Provides default popups/Dialog UI for other plugins to use.
* `text2html.js` Provides a new message handler type: `text2html`, similar to the multimedia and html
plugins. This plugin provides a way to offload rendering the regular pipe-styled ASCII messages
to the client. This allows the server to do less work, while also allowing the client a place to
customize this conversion process. To use this plugin you will need to override the current commands
in Evennia, changing any place where a raw text output message is generated and turn it into a
`text2html` message. For example: `target.msg("my text")` becomes: `target.msg(text2html=("my text"))`
(even better, use a webclient pane routing tag: `target.msg(text2html=("my text", {"type": "sometag"}))`)
`text2html` messages should format and behave identically to the server-side generated text2html() output.
* `text2html.js` Provides a new message handler type: `text2html`, similar to the multimedia and html plugins. This plugin provides a way to offload rendering the regular pipe-styled ASCII messages to the client. This allows the server to do less work, while also allowing the client a place to customize this conversion process. To use this plugin you will need to override the current commands in Evennia, changing any place where a raw text output message is generated and turn it into a `text2html` message. For example: `target.msg("my text")` becomes: `target.msg(text2html=("my text"))` (even better, use a webclient pane routing tag: `target.msg(text2html=("my text", {"type": "sometag"}))`) `text2html` messages should format and behave identically to the server-side generated text2html() output.
# A side note on html messages vrs text2html messages
### A side note on html messages vs text2html messages
So...lets say you have a desire to make your webclient output more like standard webpages...
For telnet clients, you could collect a bunch of text lines together, with ASCII formatted borders, etc.
Then send the results to be rendered client-side via the text2html plugin.
For telnet clients, you could collect a bunch of text lines together, with ASCII formatted borders, etc. Then send the results to be rendered client-side via the text2html plugin.
But for webclients, you could format a message directly with the html plugin to render the whole thing as an HTML table, like so:
But for webclients, you could format a message directly with the html plugin to render the whole thing as an
HTML table, like so:
```
# Server Side Python Code:
@ -155,13 +143,13 @@ HTML table, like so:
target.msg( html2html=( "\n".join(table), {"type": "mytag"}) )
```
# Writing your own Plugins
## Writing your own Plugins
So, you love the functionality of the webclient, but your game has specific
types of text that need to be separated out into their own space, visually.
The Goldenlayout plugin framework can help with this.
## GoldenLayout
### GoldenLayout
GoldenLayout is a web framework that allows web developers and their users to create their own
tabbed/windowed layouts. Windows/tabs can be click-and-dragged from location to location by
@ -263,8 +251,7 @@ Next, add the new plugin to your copy of base.html:
<script src={% static "webclient/js/plugins/myplugin.js" %} language="javascript"
type="text/javascript"></script>
```
Remember, plugins are load-order dependent, so make sure the new `<script>` tag comes before the
goldenlayout.js
Remember, plugins are load-order dependent, so make sure the new `<script>` tag comes before the `goldenlayout.js`.
Next, create a new plugin file `mygame/web/static/webclient/js/plugins/myplugin.js` and
edit it.
@ -294,6 +281,6 @@ let myplugin = (function () {
})();
window.plugin_handler.add("myplugin", myplugin);
```
You can then add "mycomponent" to an item's componentName in your goldenlayout_default_config.js.
You can then add "mycomponent" to an item's `componentName` in your `goldenlayout_default_config.js`.
Make sure to stop your server, evennia collectstatic, and restart your server. Then make sure to clear your browser cache before loading the webclient page.

View file

@ -16,26 +16,52 @@ So a good rule of thumb is to use colour to enhance your game but don't *rely* o
critical information. If you are coding the game, you can add functionality to let users disable
colours as they please, as described [here](../Howtos/Manually-Configuring-Color.md).
To see which colours your client support, use the default `@color` command. This will list all
available colours for ANSI and Xterm256 along with the codes you use for them. You can find a list
of all the parsed `ANSI`-colour codes in `evennia/utils/ansi.py`.
Evennia supports two color standards:
- `ANSI` - 16 foreground colors + 8 background colors. Widely supported.
- `Xterm256` - 128 RGB colors, 32 greyscales. Not always supported in old clients.
To see which colours your client support, use the default `color` command. This will list all
available colours for ANSI and Xterm256 along with the codes you use for them. The
central ansi/xterm256 parser is located in [evennia/utils/ansi.py](evennia.utils.ansi).
## ANSI colours
Evennia supports the `ANSI` standard for text. This is by far the most supported MUD-color standard,
available in all but the most ancient mud clients. The ANSI colours are **r**ed, **g**reen,
**y**ellow, **b**lue, **m**agenta, **c**yan, **w**hite and black. They are abbreviated by their
first letter except for black which is abbreviated with the letter **x**. In ANSI there are "bright"
and "normal" (darker) versions of each color, adding up to a total of 16 colours to use for
foreground text. There are also 8 "background" colours. These have no bright alternative in ANSI
(but Evennia uses the [Xterm256](#xterm256-colours) extension behind the scenes to offer
them anyway).
Evennia supports the `ANSI` standard for text. This is by far the most supported MUD-color standard, available in all but the most ancient mud clients.
To colour your text you put special tags in it. Evennia will parse these and convert them to the
correct markup for the client used. If the user's client/console/display supports ANSI colour, they
will see the text in the specified colour, otherwise the tags will be stripped (uncolored text).
This works also for non-terminal clients, such as the webclient. For the webclient, Evennia will
translate the codes to HTML RGB colors.
For the webclient, Evennia will translate the codes to CSS tags.
| Tag | Effect |
| ---- | ----- |
| \|n | end all color formatting, including background colors. |
|\|r | bright red foreground color |
|\|g | bright green foreground color |
|\|y | bright yellow foreground color |
|\|b | bright blue foreground color |
|\|m | bright magentaforeground color |
|\|c | bright cyan foreground color |
|\|w | bright white foreground color |
|\|x | bright black (dark grey) foreground color |
|\|R | normal red foreground color |
|\|G | normal green foreground color |
|\|Y | normal yellow foreground color |
|\|B | normal blue foreground color |
|\|M | normal magentaforeground color |
|\|C | normal cyan foreground color |
|\|W | normal white (light grey) foreground color |
|\|X | normal black foreground color |
| \|\[# | background colours, e.g. \|\[c for bright cyan background and \|\[C a normal cyan background. |
| \|!# | foreground color that inherits brightness from previous tags. Always uppcase, like \|!R |
| \|h | make any following foreground ANSI colors bright (no effect on Xterm colors). Use with \|!#. Technically, \|h\|G == \|g. |
| \|H | negates the effects of \|h, return foreground to normal (no effect on Xterm colors) |
| \|/ | line break. Use instead of Python \\n when adding strings from in-game. |
| \|- | tab character when adding strings in-game. Can vay per client, so usually better with spaces. |
| \|_ | a space. Only needed to avoid auto-cropping at the end of a in-game input |
| \|* | invert the current text/background colours, like a marker. See note below. |
Here is an example of the tags in action:
@ -44,35 +70,11 @@ Here is an example of the tags in action:
|[rThis text has red background.|n This is normal text.
|b|[yThis is bright blue text on yellow background.|n This is normal text.
- `|n` - this tag will turn off all color formatting, including background colors.
- `|#`- markup marks the start of foreground color. The case defines if the text is "bright" or
"normal". So `|g` is a bright green and `|G` is "normal" (darker) green.
- `|[#` is used to add a background colour to the text. The case again specifies if it is "bright"
or "normal", so `|[c` starts a bright cyan background and `|[C` a darker cyan background.
- `|!#` is used to add foreground color without any enforced brightness/normal information.
These are normal-intensity and are thus always given as uppercase, such as
`|!R` for red. The difference between e.g. `|!R` and `|R` is that
`|!R` will "inherit" the brightness setting from previously set color tags, whereas `|R` will
always reset to the normal-intensity red. The `|#` format contains an implicit `|h`/`|H` tag in it:
disabling highlighting when switching to a normal color, and enabling it for bright ones. So `|btest
|!Rtest2` will result in a bright red `test2` since the brightness setting from `|b` "bleeds over".
You could use this to for example quickly switch the intensity of a multitude of color tags. There
is no background-color equivalent to `|!` style tags.
- `|h` is used to make any following foreground ANSI colors bright (it has no effect on Xterm
colors). This is only relevant to use with `|!` type tags and will be valid until the next `|n`,
`|H` or normal (upper-case) `|#` tag. This tag will never affect background colors, those have to be
set bright/normal explicitly. Technically, `|h|!G` is identical to `|g`.
- `|H` negates the effects `|h` and returns all ANSI foreground colors (`|!` and `|` types) to
'normal' intensity. It has no effect on background and Xterm colors.
Note: The ANSI standard does not actually support bright backgrounds like `|[r` - the standard
only supports "normal" intensity backgrounds. To get around this Evennia implements these as [Xterm256 colours](#xterm256-colours) behind the scenes. If the client does not support
Xterm256 the ANSI colors will be used instead and there will be no visible difference between using upper- and lower-case background tags.
> Note: The ANSI standard does not actually support bright backgrounds like `|[r` - the standard
only supports "normal" intensity backgrounds. To get around this Evennia instead implements these
as [Xterm256 colours](#xterm256-colours) behind the scenes. If the client does not support
Xterm256 the ANSI colors will be used instead and there will be no visible difference between using
upper- and lower-case background tags.
If you want to display an ANSI marker as output text (without having any effect), you need to escape
it by preceding its `|` with another `|`:
If you want to display an ANSI marker as output text (without having any effect), you need to escape it by preceding its `|` with another `|`:
```
say The ||r ANSI marker changes text color to bright red.
@ -83,22 +85,12 @@ ansi art that uses `|` with a letter directly following it.
Use the command
@color ansi
color ansi
to get a list of all supported ANSI colours and the tags used to produce them.
A few additional ANSI codes are supported:
- `|/` A line break. You cannot put the normal Python `\n` line breaks in text entered inside the
game (Evennia will filter this for security reasons). This is what you use instead: use the `|/`
marker to format text with line breaks from the game command line.
- `` This will translate into a `TAB` character. This will not always show (or show differently) to
the client since it depends on their local settings. It's often better to use multiple spaces.
- `|_` This is a space. You can usually use the normal space character, but if the space is *at the
end of the line*, Evennia will likely crop it. This tag will not be cropped but always result in a
space.
- `|*` This will invert the current text/background colours. Can be useful to mark things (but see
below).
### Caveats of `|*`
@ -140,44 +132,45 @@ manually instead.
### Xterm256 Colours
The _Xterm256_ standard is a colour scheme that supports 256 colours for text and/or background.
The _Xterm256_ standard is a colour scheme that supports 256 colours for text and/or background. It can be combined freely with ANSI colors (above), but some ANSI tags don't affect Xterm256 tags.
While this offers many more possibilities than traditional ANSI colours, be wary that too many text
colors will be confusing to the eye. Also, not all clients support Xterm256 - these will instead see
the closest equivalent ANSI color. You can mix Xterm256 tags with ANSI tags as you please.
|555 This is pure white text.|n This is normal text.
|230 This is olive green text.
|[300 This text has a dark red background.
|005|[054 This is dark blue text on a bright cyan background.
|=a This is a greyscale value, equal to black.
|=m This is a greyscale value, midway between white and black.
|=z This is a greyscale value, equal to white.
|[=m This is a background greyscale value.
| Tag | Effect |
| ---- | ---- |
| \|### | foreground RGB (red/green/blue), each from 0 to 5. |
| \|\[### | background RGB |
| \|=# | a-z foreground greyscale, where `a` is black and `z` is white. |
| \|\[=#| a-z background greyscale
- `|###` - markup consists of three digits, each an integer from 0 to 5. The three digits describe
the amount of **r**ed, **g**reen and **b**lue (RGB) components used in the colour. So `|500` means
maximum red and none of the other colours - the result is a bright red. `|520` is red with a touch
of green - the result is orange. As opposed to ANSI colors, Xterm256 syntax does not worry about
bright/normal intensity, a brighter (lighter) color is just achieved by upping all RGB values with
the same amount.
- `|[###` - this works the same way but produces a coloured background.
- `|=#` - markup produces the xterm256 gray scale tones, where `#` is a letter from `a` (black) to
`z` (white). This offers many more nuances of gray than the normal `|###` markup (which only has
four gray tones between solid black and white (`|000`, `|111`, `|222`, `|333` and `|444`)).
- `|[=#` - this works in the same way but produces background gray scale tones.
Some examples:
| Tag | Effect |
| ---- | ---- |
| \|500 | bright red |
| \|050 | bright green |
| \|005 | bright blue |
| \|520 | red + a little green = orange |
|\|555 | pure white foreground |
|\|230 | olive green foreground |
|\|\[300 | text with a dark red background |
|\|005\|\[054 | dark blue text on a bright cyan background |
|\|=a | greyscale foreground, equal to black |
| \|=m | greyscale foreground, midway between white and black.
| \|=z | greyscale foreground, equal to white |
| \|\[=m | greyscale background |
Xterm256 don't use bright/normal intensity like ANSI does; intensity is just varied by increasing/decreasing all RGB values by the same amount.
If you have a client that supports Xterm256, you can use
@color xterm256
color xterm256
to get a table of all the 256 colours and the codes that produce them. If the table looks broken up
into a few blocks of colors, it means Xterm256 is not supported and ANSI are used as a replacement.
You can use the `@options` command to see if xterm256 is active for you. This depends on if your
client told Evennia what it supports - if not, and you know what your client supports, you may have
to activate some features manually.
into a few blocks of colors, it means Xterm256 is not supported and ANSI are used as a replacement. You can use the `options` command to see if xterm256 is active for you. This depends on if your client told Evennia what it supports - if not, and you know what your client supports, you may have to activate some features manually.
## More reading
There is an [Understanding Color Tags](../Howtos/Understanding-Color-Tags.md) tutorial which expands on the
use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context.
There is an [Understanding Color Tags](../Howtos/Understanding-Color-Tags.md) tutorial which expands on the use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context.

View file

@ -1,12 +1,7 @@
# Soft Code
Softcode is a very simple programming language that was created for in-game development on TinyMUD
derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea is that by providing a stripped
down, minimalistic language for in-game use, you can allow quick and easy building and game
development to happen without having to learn C/C++. There is an added benefit of not having to have
to hand out shell access to all developers, and permissions can be used to alleviate many security
problems.
Softcode is a very simple programming language that was created for in-game development on TinyMUD derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea is that by providing a stripped down, minimalistic language for in-game use, you can allow quick and easy building and game development to happen without having to learn C/C++. There is an added benefit of not having to have to hand out shell access to all developers, and permissions can be used to alleviate many security problems.
Writing and installing softcode is done through a MUD client. Thus it is not a formatted language.
Each softcode function is a single line of varying size. Some functions can be a half of a page long
@ -47,27 +42,15 @@ If you are still curious about how Softcode works, take a look at some external
## Problems with Softcode
Softcode is excellent at what it was intended for: *simple things*. It is a great tool for making an
interactive object, a room with ambiance, simple global commands, simple economies and coded
systems. However, once you start to try to write something like a complex combat system or a higher
end economy, you're likely to find yourself buried under a mountain of functions that span multiple
objects across your entire code.
Softcode is excellent at what it was intended for: *simple things*. It is a great tool for making an interactive object, a room with ambiance, simple global commands, simple economies and coded systems. However, once you start to try to write something like a complex combat system or a higher end economy, you're likely to find yourself buried under a mountain of functions that span multiple objects across your entire code.
Not to mention, softcode is not an inherently fast language. It is not compiled, it is parsed with
each calling of a function. While MUX and MUSH parsers have jumped light years ahead of where they
once were they can still stutter under the weight of more complex systems if not designed properly.
Not to mention, softcode is not an inherently fast language. It is not compiled, it is parsed with each calling of a function. While MUX and MUSH parsers have jumped light years ahead of where they once were they can still stutter under the weight of more complex systems if not designed properly.
## Changing Times
Now that starting text-based games is easy and an option for even the most technically inarticulate,
new projects are a dime a dozen. People are starting new MUDs every day with varying levels of
commitment and ability. Because of this shift from fewer, larger, well-staffed games to a bunch of
small, one or two developer games, some of the benefit of softcode fades.
Now that starting text-based games is easy and an option for even the most technically inarticulate, new projects are a dime a dozen. People are starting new MUDs every day with varying levels of commitment and ability. Because of this shift from fewer, larger, well-staffed games to a bunch of small, one or two developer games, some of the benefit of softcode fades.
Softcode is great in that it allows a mid to large sized staff all work on the same game without
stepping on one another's toes. As mentioned before, shell access is not necessary to develop a MUX
or a MUSH. However, now that we are seeing a lot more small, one or two-man shops, the issue of
shell access and stepping on each other's toes is a lot less.
Softcode is great in that it allows a mid to large sized staff all work on the same game without stepping on one another's toes. As mentioned before, shell access is not necessary to develop a MUX or a MUSH. However, now that we are seeing a lot more small, one or two-man shops, the issue of shell access and stepping on each other's toes is a lot less.
## Our Solution
@ -75,20 +58,10 @@ Evennia shuns in-game softcode for on-disk Python modules. Python is a popular,
professional programming language. You code it using the conveniences of modern text editors.
Evennia developers have access to the entire library of Python modules out there in the wild - not
to mention the vast online help resources available. Python code is not bound to one-line functions
on objects but complex systems may be organized neatly into real source code modules, sub-modules,
or even broken out into entire Python packages as desired.
on objects but complex systems may be organized neatly into real source code modules, sub-modules, or even broken out into entire Python packages as desired.
So what is *not* included in Evennia is a MUX/MOO-like online player-coding system. Advanced coding
in Evennia is primarily intended to be done outside the game, in full-fledged Python modules.
Advanced building is best handled by extending Evennia's command system with your own sophisticated
building commands. We feel that with a small development team you are better off using a
professional source-control system (svn, git, bazaar, mercurial etc) anyway.
So what is *not* included in Evennia is a MUX/MOO-like online player-coding system. Advanced coding in Evennia is primarily intended to be done outside the game, in full-fledged Python modules. Advanced building is best handled by extending Evennia's command system with your own sophisticated building commands. We feel that with a small development team you are better off using a professional source-control system (svn, git, bazaar, mercurial etc) anyway.
## Your Solution
Adding advanced and flexible building commands to your game is easy and will probably be enough to
satisfy most creative builders. However, if you really, *really* want to offer online coding, there
is of course nothing stopping you from adding that to Evennia, no matter our recommendations. You
could even re-implement MUX' softcode in Python should you be very ambitious. The
[in-game-python](../Contribs/Contrib-Ingame-Python.md) is an optional
pseudo-softcode plugin aimed at developers wanting to script their game from inside it.
Adding advanced and flexible building commands to your game is easy and will probably be enough to satisfy most creative builders. However, if you really, *really* want to offer online coding, there is of course nothing stopping you from adding that to Evennia, no matter our recommendations. You could even re-implement MUX' softcode in Python should you be very ambitious. The [in-game-python](../Contribs/Contrib-Ingame-Python.md) is an optional pseudo-softcode plugin aimed at developers wanting to script their game from inside it.

View file

@ -1,15 +1,9 @@
# Using MUX as a Standard
Evennia allows for any command syntax. If you like the way DikuMUDs, LPMuds or MOOs handle things,
you could emulate that with Evennia. If you are ambitious you could even design a whole new style,
perfectly fitting your own dreams of the ideal game.
Evennia allows for any command syntax. If you like the way DikuMUDs, LPMuds or MOOs handle things, you could emulate that with Evennia. If you are ambitious you could even design a whole new style, perfectly fitting your own dreams of the ideal game.
We do offer a default however. The default Evennia setup tends to *resemble*
[MUX2](https://www.tinymux.org/), and its cousins [PennMUSH](https://www.pennmush.org),
[TinyMUSH](https://github.com/TinyMUSH/TinyMUSH/wiki), and [RhostMUSH](http://www.rhostmush.com/).
While the reason for this similarity is partly historical, these codebases offer very mature feature
sets for administration and building.
We do offer a default however. The default Evennia setup tends to *resemble* [MUX2](https://www.tinymux.org/), and its cousins [PennMUSH](https://www.pennmush.org), [TinyMUSH](https://github.com/TinyMUSH/TinyMUSH/wiki), and [RhostMUSH](http://www.rhostmush.com/). While the reason for this similarity is partly historical, these codebases offer very mature feature sets for administration and building.
Evennia is *not* a MUX system though. It works very differently in many ways. For example, Evennia
deliberately lacks an online softcode language (a policy explained on our [softcode policy

View file

@ -1,4 +1,4 @@
# Character Creator contrib
# Character Creator
Commands for managing and initiating an in-game character-creation menu.

View file

@ -6,14 +6,13 @@ If you cannot find what you are looking for in the documentation, here's what to
you are working on, make a post to the [discussions forum][forum].
- If you want more direct discussions with developers and other users, drop
into our very friendly [Discord channel][chat].
- If you think the documentation is not clear enough, create a [documentation issue][issues]
- If you think the documentation is not clear enough, create a [documentation issue][issues].
- If you have trouble with a missing feature or a problem you think is a bug,
[request or report it][issues].
[request, or report it][issues].
## Community and Spreading the word
Being active and helpful in the [forums][forum] or [chat][chat] is already a big
help.
Being active and helpful in the [discssion forums][forum] or [chat][chat] is already a big help.
Consider writing about Evennia on your blog or in your favorite (relevant)
forum. Write a review somewhere (good or bad, we like feedback either way). Rate
@ -27,8 +26,7 @@ great help!
- Easiest is to just [report documentation issues][issues] as you find them. If
we don't know about them, we can't fix them!
- If you want to help edit the docs directly, [check here](./Contributing-Docs.md)
on how to do it.
- If you want to help editing the docs directly, [check here](./Contributing-Docs.md) on how to do it.
- If you have knowledge to share, how about writing a new [Tutorial](Howtos/Howtos-Overview.md)?
## Helping with code
@ -36,7 +34,7 @@ great help!
If you find bugs, or have a feature-request, [make an issue][issues] for it. If
it's not in an issue, the issue will most likely be forgotten.
Even if you don't feel confident with tackling a [bug or feature][issues], just
Even if you don't feel confident with tackling a bug or feature, just
correcting typos, adjusting formatting or simply *using* the thing and reporting
when stuff doesn't make sense helps us a lot.
@ -51,18 +49,15 @@ when stuff doesn't make sense helps us a lot.
The most elegant way to contribute code to Evennia is to use GitHub to create a
*fork* of the Evennia repository and make your changes to that. Refer to the
[Forking Evennia](Coding/Version-Control.md#forking-evennia) version control instructions
for detailed instructions.
[Forking Evennia](Coding/Version-Control.md#forking-evennia) version control instructions for detailed instructions.
Once you have a fork set up, you can not only work on your own game in a
separate branch, you can also commit your fixes to Evennia itself.
- Make separate branches for all Evennia additions you do - don't edit your
local `master` or `develop` branches directly. It will make your life a lot
easier.
local `master` or `develop` branches directly. It will make your life a lot easier.
- If you have a change that you think is suitable for the main Evennia
repository, issue a [Pull Request][pullrequest]. This will let Evennia
devs know you have stuff to share.
repository, issue a [Pull Request][pullrequest]. This will let Evennia devs know you have stuff to share.
- Bug fixes should generally be done against the `master` branch of Evennia,
while new features/contribs should go into the `develop` branch. If you are
unsure, just pick one and we'll figure it out.

View file

@ -14,8 +14,7 @@ your mind for years ... you know *just* how good it would be, if you could only
reality. We know how you feel. That is, after all, why Evennia came to be.
Evennia is a MU\*-building system: a bare-bones Python codebase and server intended to
be highly extendable for any style of game. "Bare-bones" in this context means that we try to impose
as few game-specific things on you as possible. For convenience offer basic building
be highly extendable for any style of game. "Bare-bones" in this context means that we try to impose as few game-specific things on you as possible. For convenience offer basic building
blocks like objects, characters, rooms, default commands for building and administration etc, we
don't prescribe any combat rules, mob AI, races, skills, character classes or other things that will
be different from game to game anyway.
@ -26,21 +25,11 @@ Evennia is *fully persistent*, that means things you drop on the ground somewher
there a dozen server reboots later. Through Django we support a large variety of different database
systems (a database is created for you automatically if you use the defaults).
We also include a growing list of *optional* [contribs](Contribs/Contribs-Overview.md) you can use for your game
would you want something to build from.
We also include a growing list of *optional* [contribs](Contribs/Contribs-Overview.md) you can use for your game would you want something to build from.
Using the full power of Python throughout the server offers some distinct advantages. All your
coding, from object definitions and custom commands to AI scripts and economic systems is done in
normal Python modules rather than some ad-hoc scripting language. The fact that you script the game
in the same high-level language that you code it in allows for very powerful and custom game
implementations indeed.
Using the full power of Python throughout the server offers some distinct advantages. All your coding, from object definitions and custom commands to AI scripts and economic systems is done in normal Python modules rather than some ad-hoc scripting language. The fact that you script the game in the same high-level language that you code it in allows for very powerful and custom game implementations indeed.
Out of the box, Evennia gives you a 'talker'-type of game; you can walk around, chat, build rooms and objects,
do basic roleplaying and administration. The server ships with a default set of player commands that are
similar to the MUX command set. We *do not* aim specifically to be a MUX server, but we had to pick some
default to go with (see [this](Concepts/Soft-Code.md) for more about our original motivations). It's easy to
remove or add commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on.
Or why not create a new and better command system of your own design.
Out of the box, Evennia gives you a 'talker'-type of game; you can walk around, chat, build rooms and objects, do basic roleplaying and administration. The server ships with a default set of player commands that are similar to the MUX command set. We *do not* aim specifically to be a MUX server, but we had to pick some default to go with (see [this](Concepts/Soft-Code.md) for more about our original motivations). It's easy to remove or add commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on. Or why not create a new and better command system of your own design.
## Can I test it somewhere?
@ -59,36 +48,20 @@ you need to know depending on your skills and needs.
### I don't know (or don't want to do) any programming - I just want to run a game!
Evennia comes with a default set of commands for the Python newbies and for those who need to get a
game running *now*. Stock Evennia is enough for running a simple 'Talker'-type game - you can build
and describe rooms and basic objects, have chat channels, do emotes and other things suitable for a
social or free-form MU\*. Combat, mobs and other game elements are not included, so you'll have a
very basic game indeed if you are not willing to do at least *some* coding.
Evennia comes with a default set of commands for the Python newbies and for those who need to get a game running *now*. Stock Evennia is enough for running a simple 'Talker'-type game - you can build and describe rooms and basic objects, have chat channels, do emotes and other things suitable for a social or free-form MU\*. Combat, mobs and other game elements are not included, so you'll have a very basic game indeed if you are not willing to do at least *some* coding.
### I know basic Python, or I am willing to learn
Evennia's source code is extensively documented and is [viewable
online](https://github.com/evennia/evennia). We also have a comprehensive [online
manual](https://evennia.com/docs) with lots of examples. But while Python is
considered a very easy programming language to get into, you do have a learning curve to climb if
you are new to programming. Evennia's [Starting-tutorial](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.md) has a [basic introduction
to Python](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.md) but you should probably also sit down
with a full Python beginner's tutorial at some point (there are plenty of them on
the web if you look around). See also our [link
page](./Links.md) for some reading suggestions. To efficiently code your dream game in
Evennia you don't need to be a Python guru, but you do need to be able to read example code
containing at least these basic Python features:
Evennia's source code is [extensively documented](https://www.evennia.com/docs/latest). But while Python is considered a very easy programming language to get into, you do have a learning curve to climb if you are new to programming. Evennia's [Starting-tutorial](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.md) has a [basic introduction to Python](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.md) but you should probably also sit down with a full Python beginner's tutorial at some point (there are plenty of them on the web if you look around). See also our [link page](./Links.md) for some reading suggestions.
To code your dream game in Evennia you don't need to be a Python guru, but you do need to be able to read example code containing at least these basic Python features:
- Importing and using python [modules](https://docs.python.org/3.7/tutorial/modules.html)
- Using [variables](https://www.tutorialspoint.com/python/python_variable_types.htm), [conditional
statements](https://docs.python.org/tutorial/controlflow.html#if-statements),
[loops](https://docs.python.org/tutorial/controlflow.html#for-statements) and
[functions](https://docs.python.org/tutorial/controlflow.html#defining-functions)
- Using [lists, dictionaries and list
comprehensions](https://docs.python.org/tutorial/datastructures.html)
- Using [variables](https://www.tutorialspoint.com/python/python_variable_types.htm), [conditional statements](https://docs.python.org/tutorial/controlflow.html#if-statements),
[loops](https://docs.python.org/tutorial/controlflow.html#for-statements) and [functions](https://docs.python.org/tutorial/controlflow.html#defining-functions)
- Using [lists, dictionaries and list comprehensions](https://docs.python.org/tutorial/datastructures.html)
- Doing [string handling and formatting](https://docs.python.org/tutorial/introduction.html#strings)
- Have a basic understanding of [object-oriented
programming](https://www.tutorialspoint.com/python/python_classes_objects.htm), using
- Have a basic understanding of [object-oriented programming](https://www.tutorialspoint.com/python/python_classes_objects.htm), using
[Classes](https://docs.python.org/tutorial/classes.html), their methods and properties
Obviously, the more things you feel comfortable with, the easier time you'll have to find your way.
@ -98,35 +71,13 @@ definitely build a whole advanced and customized game from extending Evennia's e
### I know my Python stuff and I am willing to use it!
Even if you started out as a Python beginner, you will likely get to this point after working on
your game for a while. With more general knowledge in Python the full power of Evennia opens up for
you. Apart from modifying commands, objects and scripts, you can develop everything from advanced
mob AI and economic systems, through sophisticated combat and social mini games, to redefining how
commands, players, rooms or channels themselves work. Since you code your game by importing normal
Python modules, there are few limits to what you can accomplish.
Even if you started out as a Python beginner, you will likely get to this point after working on your game for a while. With more general knowledge in Python the full power of Evennia opens up for you. Apart from modifying commands, objects and scripts, you can develop everything from advanced mob AI and economic systems, through sophisticated combat and social mini games, to redefining how commands, players, rooms or channels themselves work. Since you code your game by importing normal Python modules, there are few limits to what you can accomplish.
If you *also* happen to know some web programming (HTML, CSS, Javascript) there is also a web
presence (a website and a mud web client) to play around with ...
### Where to from here?
## Where to from here?
From here you can continue browsing the [online documentation](./index.md) to
find more info about Evennia. Or you can jump into the [Tutorials](Howtos/Howtos-Overview.md) and get your hands
dirty with code right away. You can also read the lead developer's [dev blog](https://evennia.blogspot.com/) for many tidbits and snippets about Evennia's development and
structure.
It's recommended you jump into the [Beginner Tutorial](Howtos/Beginner-Tutorial/Beginner-Tutorial-Intro.md). You can either follow it or jump around to lessons that seem interesting. You can also read the lead developer's [dev blog](https://www.evennia.com/devblog/index.html) for many tidbits and snippets about Evennia's development and structure.
Some more hints:
1. Get engaged in the community. Make an introductory post to our [mailing
list/forum](https://groups.google.com/forum/#!forum/evennia) and get to know people. It's also
highly recommended you hop onto our [Developer
chat](https://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb)
on IRC. This allows you to chat directly with other developers new and old as well as with the devs
of Evennia itself. This chat is logged (you can find links on https://www.evennia.com) and can also
be searched from the same place for discussion topics you are interested in.
2. Read the [Game Planning](Howtos/Beginner-Tutorial/Part2/Beginner-Tutorial-Game-Planning.md) wiki page. It gives some ideas for your work flow and the
state of mind you should aim for - including cutting down the scope of your game for its first
release.
3. Do the [Tutorial for basic MUSH-like game](Howtos/Tutorial-for-basic-MUSH-like-game.md) carefully from
beginning to end and try to understand what does what. Even if you are not interested in a MUSH for
your own game, you will end up with a small (very small) game that you can build or learn from.
Sometimes it's easier to ask for help. Get engaged in the Evennia community by joining our [Discord](https://discord.gg/AJJpcRUhtF) for direct support. Make an introductory post to our [Discussion forum](https://github.com/evennia/evennia/discussions) and say hi!.

View file

@ -1,9 +1,9 @@
# Adding custom commands
In this lesson we'll learn how to create our own Evennia _Commands_. If you are new to Python you'll also learn some more basics about how to manipulate strings and get information out of Evennia.
In this lesson we'll learn how to create our own Evennia [Commands](../../../Components/Commands.md) If you are new to Python you'll also learn some more basics about how to manipulate strings and get information out of Evennia.
A Command is something that handles the input from a user and causes a result to happen.
An example is `look`, which examines your current location and tells how it looks like and
An example is `look`, which examines your current location and tells you what it looks like and
what is in it.
```{sidebar} Commands are not typeclassed
@ -14,20 +14,11 @@ database. They are "just" normal Python classes.
```
In Evennia, a Command is a Python _class_. If you are unsure about what a class is, review the
previous lessons! A Command inherits from `evennia.Command` or from one of the alternative command-
classes, such as `MuxCommand` which is what most default commands use.
[previous lesson about it](./Beginner-Tutorial-Python-classes-and-objects.md)! A Command inherits from `evennia.Command` or from one of the alternative command- classes, such as `MuxCommand` which is what most default commands use.
All Commands are in turn grouped in another class called a _Command Set_. Think of a Command Set
as a bag holding many different commands. One CmdSet could for example hold all commands for
combat, another for building etc. By default, Evennia groups all character-commands into one
big cmdset.
All Commands are grouped in another class called a _Command Set_. Think of a Command Set as a bag holding many different commands. One CmdSet could for example hold all commands for combat, another for building etc.
Command-Sets are then associated with objects, for example with your Character. Doing so makes the
commands in that cmdset available to the object. So, to summarize:
- Commands are classes
- A group of Commands is stored in a CmdSet
- CmdSets are stored on objects - this defines which commands are available to that object.
Command-Sets are then associated with objects, for example with your Character. Doing so makes the commands in that cmdset available to the object. By default, Evennia groups all character-commands into one big cmdset called the `CharacterCmdSet`. It sits on `DefaultCharacter` (and thus, through inheritance, on `typeclasses.characters.Character`).
## Creating a custom command
@ -53,18 +44,14 @@ class Command(BaseCommand):
Ignoring the docstrings (which you can read if you want), this is the only really active code in the module.
We can see that we import `Command` from `evennia` and use the `from ... import ... as ...` form to rename it
to `BaseCommand`. This is so we can let our child class also be named `Command` for reference. The class
itself doesn't do anything, it just has `pass`. So in the same way as `Object` in the previous lesson, this
class is identical to its parent.
We can see that we import `Command` from `evennia` and use the `from ... import ... as ...` form to rename it to `BaseCommand`. This is so we can let our child class also be named `Command` to make it easier to reference. The class itself doesn't do anything, it just has `pass`. So in the same way as `Object` and `Character` in the previous lessons, this class is identical to its parent.
> The commented out `default_cmds` gives us access to Evennia's default commands for easy overriding. We'll try
> that a little later.
> The commented out `default_cmds` gives us access to Evennia's default commands for easy overriding. We'll try that a little later.
We could modify this module directly, but to train imports we'll work in a separate module. Open a new file
`mygame/commands/mycommands.py` and add the following code:
We could modify this module directly, but let's work in a separate module just for the heck of it. Open a new file `mygame/commands/mycommands.py` and add the following code:
```python
# in mygame/commands/mycommands.py
from commands.command import Command
@ -95,15 +82,13 @@ class MyCmdSet(CmdSet):
```
Our `EchoCmdSet` class must have an `at_cmdset_creation` method, named exactly
like this - this is what Evennia will be looking for when setting up the cmdset later, so
if you didn't set it up, it will use the parent's version, which is empty. Inside we add the
command class to the cmdset by `self.add()`. If you wanted to add more commands to this CmdSet you
could just add more lines of `self.add` after this.
Our `EchoCmdSet` class must have an `at_cmdset_creation` method, named exactly like this - this is what Evennia will be looking for when setting up the cmdset later, so if you didn't set it up, it will use the parent's version, which is empty. Inside we add the command class to the cmdset by `self.add()`. If you wanted to add more commands to this CmdSet you could just add more lines of `self.add` after this.
Finally, let's add this command to ourselves so we can try it out. In-game you can experiment with `py` again:
> py self.cmdset.add("commands.mycommands.MyCmdSet")
> py me.cmdset.add("commands.mycommands.MyCmdSet")
The `me.cmdset` is the store of all cmdsets stored on us. By giving the path to our CmdSet class, it will be added.
Now try
@ -112,9 +97,7 @@ Now try
...
...
You should be getting a long list of outputs. The reason for this is that your `echo` function is not really
"doing" anything yet and the default function is then to show all useful resources available to you when you
use your Command. Let's look at some of those listed:
`echo` works! You should be getting a long list of outputs. The reason for this is that your `echo` function is not really "doing" anything yet and the default function is then to show all useful resources available to you when you use your Command. Let's look at some of those listed:
Command echo has no defined `func()` - showing on-command variables:
obj (<class 'typeclasses.characters.Character'>): YourName
@ -146,17 +129,13 @@ use your Command. Let's look at some of those listed:
command string given (self.cmdstring): echo
current cmdset (self.cmdset): ChannelCmdSet
These are all properties you can access with `.` on the Command instance, such as `.key`, `.args` and so on.
Evennia makes these available to you and they will be different every time a command is run. The most
important ones we will make use of now are:
These are all properties you can access with `.` on the Command instance, such as `.key`, `.args` and so on. Evennia makes these available to you and they will be different every time a command is run. The most important ones we will make use of now are:
- `caller` - this is 'you', the person calling the command.
- `args` - this is all arguments to the command. Now it's empty, but if you tried `echo foo bar` you'd find
that this would be `" foo bar"`.
- `args` - this is all arguments to the command. Now it's empty, but if you tried `echo foo bar` you'd find that this would be `" foo bar"`.
- `obj` - this is object on which this Command (and CmdSet) "sits". So you, in this case.
The reason our command doesn't do anything yet is because it's missing a `func` method. This is what Evennia
looks for to figure out what a Command actually does. Modify your `CmdEcho` class:
The reason our command doesn't do anything yet is because it's missing a `func` method. This is what Evennia looks for to figure out what a Command actually does. Modify your `CmdEcho` class:
```python
# ...
@ -177,15 +156,15 @@ class CmdEcho(Command):
# ...
```
First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also
automatically become the in-game help entry! Next we add the `func` method. It has one active line where it
makes use of some of those variables we found the Command offers to us. If you did the
[basic Python tutorial](./Beginner-Tutorial-Python-basic-introduction.md), you will recognize `.msg` - this will send a message
to the object it is attached to us - in this case `self.caller`, that is, us. We grab `self.args` and includes
that in the message.
First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also automatically become the in-game help entry!
Since we haven't changed `MyCmdSet`, that will work as before. Reload and re-add this command to ourselves to
try out the new version:
```{sidebar} Use Command.msg
In a Command class, the `self.msg()` acts as a convenient shortcut for `self.caller.msg()`. Not only is it shorter, it also has some advantages because the command can include more metadata with the message. So using `self.msg()` is usually better. For this tutorial though, `self.caller.msg()` is more explicit in showing what is going on.
```
Next we add the `func` method. It has one active line where it makes use of some of those variables the Command class offers to us. If you did the [basic Python tutorial](./Beginner-Tutorial-Python-basic-introduction.md), you will recognize `.msg` - this will send a message to the object it is attached to us - in this case `self.caller`, that is, us. We grab `self.args` and includes that in the message.
Since we haven't changed `MyCmdSet`, that will work as before. Reload and re-add this command to ourselves to try out the new version:
> reload
> py self.cmdset.add("commands.mycommands.MyCmdSet")
@ -197,14 +176,12 @@ Try to pass an argument:
> echo Woo Tang!
Echo: ' Woo Tang!'
Note that there is an extra space before `Woo!`. That is because self.args contains the _everything_ after
the command name, including spaces. Evennia will happily understand if you skip that space too:
Note that there is an extra space before `Woo!`. That is because self.args contains _everything_ after the command name, including spaces. Evennia will happily understand if you skip that space too:
> echoWoo Tang!
Echo: 'Woo Tang!'
There are ways to force Evennia to _require_ an initial space, but right now we want to just ignore it since
it looks a bit weird for our echo example. Tweak the code:
There are ways to force Evennia to _require_ an initial space, but right now we want to just ignore it since it looks a bit weird for our echo example. Tweak the code:
```python
# ...
@ -225,9 +202,7 @@ class CmdEcho(Command):
# ...
```
The only difference is that we called `.strip()` on `self.args`. This is a helper method available on all
strings - it strips out all whitespace before and after the string. Now the Command-argument will no longer
have any space in front of it.
The only difference is that we called `.strip()` on `self.args`. This is a helper method available on all strings - it strips out all whitespace before and after the string. Now the Command-argument will no longer have any space in front of it.
> reload
> py self.cmdset.add("commands.mycommands.MyCmdSet")
@ -238,7 +213,7 @@ Don't forget to look at the help for the echo command:
> help echo
You will get the docstring you put in your Command-class.
You will get the docstring you put in your Command-class!
### Making our cmdset persistent
@ -248,7 +223,7 @@ enough to make `echo` a _persistent_ change though:
> py self.cmdset.add("commands.mycommands.MyCmdSet", persistent=True)
Now you can `reload` as much as you want and your code changes will be available directly without
needing to re-add the MyCmdSet again. To remove the cmdset again, do
needing to re-add the MyCmdSet again. To remove the cmdset again, you'd do
> py self.cmdset.remove("commands.mycommands.MyCmdSet")
@ -262,7 +237,7 @@ someone in the face! This is how we want it to work:
> hit <target>
You hit <target> with full force!
Not only that, we want the <target> to see
Not only that, we want the `<target>` to see
You got hit by <hitter> with full force!
@ -324,9 +299,7 @@ the `else` condition is given, it will run if none of the other conditions was t
the `if..elif..else` structure also serves the same function as `case` in some other languages.
```
- **Line 15** has our first _conditional_, an `if` statement. This is written on the form `if <condition>:` and only
if that condition is 'truthy' will the indented code block under the `if` statement run. To learn what is truthy in
Python it's usually easier to learn what is "falsy":
- **Line 15** has our first _conditional_, an `if` statement. This is written on the form `if <condition>:` and only if that condition is 'truthy' will the indented code block under the `if` statement run. To learn what is truthy in Python it's usually easier to learn what is "falsy":
- `False` - this is a reserved boolean word in Python. The opposite is `True`.
- `None` - another reserved word. This represents nothing, a null-result or value.
- `0` or `0.0`
@ -334,13 +307,11 @@ the `if..elif..else` structure also serves the same function as `case` in some o
- Empty _iterables_ we haven't seen yet, like empty lists `[]`, empty tuples `()` and empty dicts `{}`.
- Everything else is "truthy".
Line 16's condition is `not args`. The `not` _inverses_ the result, so if `args` is the empty string (falsy), the
whole conditional becomes truthy. Let's continue in the code:
- **Line 16**'s condition is `not args`. The `not` _inverses_ the result, so if `args` is the empty string (falsy), the whole conditional becomes truthy. Let's continue in the code:
- **Lines 16-17**: This code will only run if the `if` statement is truthy, in this case if `args` is the empty string.
- **Line 17**: `return` is a reserved Python word that exits `func` immediately.
- **Line 18**: We use `self.caller.search` to look for the target in the current location.
- **Lines 19-20**: A feature of `.search` is that it will already inform `self.caller` if it couldn't find the target.
In that case, `target` will be `None` and we should just directly `return`.
- **Lines 19-20**: A feature of `.search` is that it will already inform `self.caller` if it couldn't find the target. In that case, `target` will be `None` and we should just directly `return`.
- **Lines 21-22**: At this point we have a suitable target and can send our punching strings to each.
Finally we must also add this to a CmdSet. Let's add it to `MyCmdSet` which we made persistent earlier.
@ -361,10 +332,7 @@ class MyCmdSet(CmdSet):
With longer code snippets to try, it gets more and more likely you'll
make an error and get a `traceback` when you reload. This will either appear
directly in-game or in your log (view it with `evennia -l` in a terminal).
Don't panic; tracebacks are your friends - they are to be read bottom-up and usually describe
exactly where your problem is. Refer to `The Python intro <Python-basic-introduction.html>`_ for
more hints. If you get stuck, reach out to the Evennia community for help.
Don't panic; tracebacks are your friends - they are to be read bottom-up and usually describe exactly where your problem is. Refer to [The Python introduction lesson](./Beginner-Tutorial-Python-basic-introduction.md) for more hints. If you get stuck, reach out to the Evennia community for help.
```
Next we reload to let Evennia know of these code changes and try it out:
@ -387,8 +355,7 @@ You won't see the second string. Only Smaug sees that (and is not amused).
## Summary
In this lesson we learned how to create our own Command, add it to a CmdSet and then to ourselves.
We also upset a dragon.
In this lesson we learned how to create our own Command, add it to a CmdSet and then to ourselves. We also upset a dragon.
In the next lesson we'll learn how to hit Smaug with different weapons. We'll also
get into how we replace and extend Evennia's default Commands.

View file

@ -2,7 +2,7 @@
In this lesson we will test out what we can do in-game out-of-the-box. Evennia ships with
[around 90 default commands](../../../Components/Default-Commands.md), and while you can override those as you please,
they can be quite useful.
the defaults can be quite useful.
Connect and log into your new game and you will end up in the "Limbo" location. This
is the only room in the game at this point. Let's explore the commands a little.

View file

@ -4,18 +4,11 @@
API stands for `Application Programming Interface`, a description for how to access the resources of a program or library.
```
A good place to start exploring Evennia is the [Evenia-API frontpage](../../../Evennia-API.md).
This page sums up the main components of Evennia with a short description of each. Try clicking through
to a few entries - once you get deep enough you'll see full descriptions
of each component along with their documentation. You can also click `[source]` to see the full Python source
for each thing.
You can also browse [the evennia repository on github](https://github.com/evennia/evennia). This is exactly
what you can download from us. The github repo is also searchable.
Finally, you can clone the evennia repo to your own computer and read the sources locally. This is necessary
if you want to help with Evennia's development itself. See the
[extended install instructions](../../../Setup/Installation-Git.md) if you want to do this.
There are several good ways to explore the Evennia library.
- This documentation contains the [Evennia-API docs](../../../Evennia-API.md), generated automatically from sources. Try clicking through to a few entries - once you get deep enough you'll see full descriptions of each component along with their documentation. You can also click `[source]` to see the full Python source code for each thing.
- There are [separate doc pages for each component](../../../Components/Components-Overview.md) if you want more detailed explanations.
- You can browse [the evennia repository on github](https://github.com/evennia/evennia). This is exactly what you can download from us.
- Finally, you can clone the evennia repo to your own computer and read the sources. This is necessary if you want to *really* understand what's going on, or help with Evennia's development. See the [extended install instructions](../../../Setup/Installation-Git.md) if you want to do this.
## Where is it?
@ -27,10 +20,9 @@ If Evennia is installed, you can import from it simply with
and so on.
If you installed Evennia with `pip install`, the library folder will be installed deep inside your Python
installation. If you cloned the repo there will be a folder `evennia` on your hard drive there.
If you installed Evennia with `pip install`, the library folder will be installed deep inside your Python installation; you are better off [looking at it on github](github:evennia). If you cloned it, you should have an `evennia` folder to look into.
If you cloned the repo or read the code on `github` you'll find this being the outermost structure:
You'll find this being the outermost structure:
evennia/
bin/
@ -46,7 +38,7 @@ the _actual_ library, the thing covered by the API auto-docs and what you get wh
> The `evennia/docs/` folder contains the sources for this documentation. See
> [contributing to the docs](../../../Contributing-Docs.md) if you want to learn more about how this works.
This the the structure of the Evennia library:
This is the structure of the Evennia library:
- evennia
- [`__init__.py`](../../../Evennia-API.md#shortcuts) - The "flat API" of Evennia resides here.
@ -76,22 +68,32 @@ The `__init__.py` file is a special Python filename used to represent a Python '
```
While all the actual Evennia code is found in the various folders, the `__init__.py` represents the entire
package `evennia`. It contains "shortcuts" to code that is actually located elsewhere. Most of these shortcuts
are listed if you [scroll down a bit](../../../Evennia-API.md) on the Evennia-API page.
While all the actual Evennia code is found in the various folders, the `__init__.py` represents the entire package `evennia`. It contains "shortcuts" to code that is actually located elsewhere. Most of these shortcuts are listed if you [scroll down a bit](../../../Evennia-API.md) on the Evennia-API page.
## An example of exploring the library
In the previous lesson we took a brief look at `mygame/typeclasses/objects` as an example of a Python module. Let's
open it again. Inside is the `Object` class, which inherits from `DefaultObject`.
Near the top of the module is this line:
In the [previous lesson](./Beginner-Tutorial-Python-classes-and-objects.md#on-classes-and-objects) we took a brief look at `mygame/typeclasses/objects` as an example of a Python module. Let's open it again.
```python
"""
module docstring
"""
from evennia import DefaultObject
class Object(DefaultObject):
"""
class docstring
"""
pass
```
We have the `Object` class, which inherits from `DefaultObject`. Near the top of the module is this line:
from evennia import DefaultObject
We want to figure out just what this DefaultObject offers. Since this is imported directly from `evennia`, we
are actually importing from `evennia/__init__.py`.
We want to figure out just what this DefaultObject offers. Since this is imported directly from `evennia`, we are actually importing from `evennia/__init__.py`.
[Look at Line 159](github:evennia/__init__.py#159) of `evennia/__init__.py` and you'll find this line:
[Look at Line 160](github:evennia/__init__.py#L160) of `evennia/__init__.py` and you'll find this line:
from .objects.objects import DefaultObject
@ -100,17 +102,19 @@ are actually importing from `evennia/__init__.py`.
The first full-stop in `from .objects.objects ...` means that we are importing from the current location. This is called a `relative import`. By comparison, `from evennia.objects.objects` is an `absolute import`. In this particular case, the two would give the same result.
```
> You can also look at [the right section of the API frontpage](../../../Evennia-API.md#typeclasses) and click through
> to the code that way.
> You can also look at [the right section of the API frontpage](../../../Evennia-API.md#typeclasses) and click through to the code that way.
The fact that `DefaultObject` is imported into `__init__.py` here is what makes it possible to also import
it as `from evennia import DefaultObject` even though the code for the class is not actually here.
The fact that `DefaultObject` is imported into `__init__.py` here is what makes it possible to also import it as `from evennia import DefaultObject` even though the code for the class is not actually here.
So to find the code for `DefaultObject` we need to look in `evennia/objects/objects.py`. Here's how
to look it up in the docs:
So to find the code for `DefaultObject` we need to look in `evennia/objects/objects.py`. Here's how to look it up in the docs:
1. Open the [API frontpage](../../../Evennia-API.md)
2. Locate the link to [evennia.objects.objects](../../../api/evennia.objects.objects.md) and click on it.
3 You are now in the python module. Scroll down (or search in your web browser) to find the `DefaultObject` class.
4 You can now read what this does and what methods are on it. If you want to see the full source, click the
\[source\] link next to it.
3. You are now in the python module. Scroll down (or search in your web browser) to find the `DefaultObject` class.
4. You can now read what this does and what methods are on it. If you want to see the full source, click the \[source\] link next to it.
## Conclusions
This is an important lesson. It teaches you how to find information for yourself. Knowing how to follow the class inheritance tree and navigate to things you need is a big part in learning a new library like Evennia.
Next we'll start to make use of what we have learned so far and combine it with the building blocks provided by Evennia.

View file

@ -1,31 +1,25 @@
# Overview of your new Game Dir
Next we will take a little detour to look at the _Tutorial World_. This is a little solo adventure
that comes with Evennia, a showcase for some of the things that are possible.
Until now we have 'run the game' a bit and started playing with Python inside Evennia.
It is time to start to look at how things look 'outside of the game'.
Now we have 'run the game' a bit and started with our forays into Python from inside Evennia.
It is time to start to look at how things look 'outside of the game'. Let's do a tour of your game-dir
Like everywhere in the docs we'll assume it's called `mygame`.
Let's do a tour of your game-dir (we assume it's called `mygame`).
> When looking through files, ignore files ending with `.pyc` and the
`__pycache__` folder if it exists. This is internal Python compilation files that you should never
> need to touch. Files `__init__.py` is also often empty and can be ignored (they have to do with
> Python package management).
You may have noticed when we were building things in-game that we would often refer to code through
"python paths", such as
You may have noticed when we were building things in-game that we would often refer to code through "python paths", such as
create/drop button:tutorial_examples.red_button.RedButton
This is a fundamental aspect of coding Evennia - _you create code and then you tell Evennia where that code is and when it should be used_. Above we told it to create a red button by pulling from specific code in the `contrib/` folder. The same principle is true everywhere. So it's important to know where code is and how you point to it correctly.
```{sidebar} Python-paths
A 'python path' uses '.' instead of '/' or '`\\`' and skips the `.py` ending of files. It can also point to the code contents of python files. Since Evennia is already looking for code in your game dir, your python paths can start from there. So a path `/home/foo/devel/mygame/commands/command.py` would translate to a Python-path `commands.command`.
```
create/drop button:tutorial_examples.red_button.RedButton
This is a fundamental aspect of coding Evennia - _you create code and then you tell Evennia where that
code is and when it should be used_. Above we told it to create a red button by pulling from specific code
in the `contribs/` folder but the same principle is true everywhere. So it's important to know where code is
and how you point to it correctly.
- `mygame/`
- `commands/` - This holds all your custom commands (user-input handlers). You both add your own
@ -42,11 +36,8 @@ and how you point to it correctly.
- `world/` - this is a "miscellaneous" folder holding everything related to the world you are
building, such as build scripts and rules modules that don't fit with one of the other folders.
> The `server/` subfolder should remain the way it is - Evennia expects this. But you could in
> principle change the structure of the rest of your game dir as best fits your preference.
> Maybe you don't need a world/ folder but prefer many folders with different aspects of your world?
> Or a new folder 'rules' for your RPG rules? This is fine. If you move things around you just need
> to update Evennia's default settings to point to the right places in the new structure.
> The `server/` subfolder should remain the way it is - Evennia expects this. But you can change the structure of the rest of your game dir as best fits your preferences.
> Maybe you don't want a single world/ folder but prefer many folders with different aspects of your world? A new folder 'rules' for your RPG rules? Group your commands with your objects instead of having them separate? This is fine. If you move things around you just need to update Evennia's default settings to point to the right places in the new structure.
## commands/
@ -91,9 +82,8 @@ Common for the settings is that you generally will never them directly via their
knows where they are and will read them to configure itself at startup.
- `settings.py` - this is by far the most important file. It's nearly empty by default, rather you
are expected to copy&paste the changes you need from [evennia/default_settings.py](github:evennia/default_settings.py).
The default settings file is extensively documented. Importing/accessing the values in the settings
file is done in a special way, like this:
are expected to copy&paste the changes you need from [evennia/default_settings.py](../../../Setup/Settings-Default.md).
The default settings file is extensively documented. Importing/accessing the values in the settings file is done in a special way, like this:
from django.conf import settings
@ -101,8 +91,7 @@ knows where they are and will read them to configure itself at startup.
telnet_port = settings.TELNET_PORT
You cannot assign to the settings file dynamically; you must change the `settings.py` file directly to
change a setting.
You cannot assign to the settings file dynamically; you must change the `settings.py` file directly to change a setting. See [Settings](../../../Setup/Settings.md) documentation for more details.
- `secret_settings.py` - If you are making your code effort public, you may not want to share all settings online.
There may be server-specific secrets or just fine-tuning for your game systems that you prefer be kept secret
from the players. Put such settings in here, it will override values in `settings.py` and not be included in
@ -162,13 +151,11 @@ be the same after a server reboot.
[Exits](../../../Components/Objects.md#exits) is another subclass of Object. Exits link one Room to another.
- [scripts.py](github:evennia/game_template/typeclasses/scripts.py) (Python-path: `typeclasses.scripts`) -
[Scripts](../../../Components/Scripts.md) are 'out-of-character' objects. They have no location in-game and can serve as basis for
anything that needs database persistence, such as combat, weather, or economic systems. They also
have the ability to execute code repeatedly, on a timer.
anything that needs database persistence, such as combat, weather, or economic systems. They also have the ability to execute code repeatedly, on a timer.
### web/
This folder contains folders for overriding the default web-presence of Evennia with your own designs.
Most of these folders are empty except for a README file or a subset of other empty folders.
This folder contains folders for overriding the default web-presence of Evennia with your own designs. Most of these folders are empty except for a README file or a subset of other empty folders. See [the Web overview](../../../Components/Components-Overview.md#web-components) for more details (we'll also get back to the web later in this beginner tutorial).
- `media/` - this empty folder is where you can place your own images or other media files you want the
web server to serve. If you are releasing your game with a lot of media (especially if you want videos) you
@ -192,8 +179,5 @@ people change and re-structure this in various ways to better fit their ideas.
- [batch_cmds.ev](github:evennia/game_template/world/batch_cmds.ev) - This is an `.ev` file, which is essentially
just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The
[Tutorial World](./Beginner-Tutorial-Tutorial-World.md) was built with such a batch-file.
- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes.md) is a way
to easily vary objects without changing their base typeclass. For example, one could use prototypes to
tell that Two goblins, while both of the class 'Goblin' (so they follow the same code logic), should have different
equipment, stats and looks.
- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes.md) is a way to easily vary objects without changing their base typeclass. For example, one could use prototypes to tell that Two goblins, while both of the class 'Goblin' (so they follow the same code logic), should have different equipment, stats and looks.

View file

@ -51,25 +51,25 @@ module docstring
"""
from evennia import DefaultObject
class Object(DefaultObject):
class ObjectParent:
"""
class docstring
"""
pass
class Object(ObjectParent, DefaultObject):
"""
class docstring
"""
pass
```
So we have a class `Object` that _inherits_ from `DefaultObject`, which we have imported from Evennia.
The class itself doesn't do anything (it just `pass`es) but that doesn't mean it's useless. As we've seen,
it inherits all the functionality of its parent. It's in fact an _exact replica_ of `DefaultObject` right now.
If we knew what kind of methods and resources were available on `DefaultObject` we could add our own and
change the way it works!
So we have a class `Object` that _inherits_ from `ObjectParent` (which is empty) and `DefaultObject`, which we have imported from Evennia. The `ObjectParent` acts as a place to put code you want all
of your `Objects` to have. We'll focus on `Object` and `DefaultObject` for now.
> Hint: We will get back to this, but to learn what resources an Evennia parent like `DefaultObject` offers,
> easiest is to peek at its [API documentation](evennia.objects.objects.DefaultObject). The docstring for
> the `Object` class can also help.
The class itself doesn't do anything (it just `pass`es) but that doesn't mean it's useless. As we've seen, it inherits all the functionality of its parent. It's in fact an _exact replica_ of `DefaultObject` right now. Once we know what kind of methods and resources are available on `DefaultObject` we could add our own and change the way it works!
One thing that Evennia classes offers and which you don't get with vanilla Python classes is _persistence_. As
you've found, Fluffy, Cuddly and Smaug are gone once we reload the server. Let's see if we can fix this.
One thing that Evennia classes offers and which you don't get with vanilla Python classes is _persistence_ - they survive a server reload since they are stored in the database.
Go back to `mygame/typeclasses/monsters.py`. Change it as follows:
@ -102,9 +102,7 @@ class Dragon(Monster):
```
Don't forget to save. We removed `Monster.__init__` and made `Monster` inherit from Evennia's `Object` (which in turn
inherits from Evennia's `DefaultObject`, as we saw). By extension, this means that `Dragon` also inherits
from `DefaultObject`, just from further away!
Don't forget to save. We removed `Monster.__init__` and made `Monster` inherit from Evennia's `Object` (which in turn inherits from Evennia's `DefaultObject`, as we saw). By extension, this means that `Dragon` also inherits from `DefaultObject`, just from further away!
### Making a new object by calling the class
@ -112,7 +110,7 @@ First reload the server as usual. We will need to create the dragon a little dif
```{sidebar} Keyword arguments
Keyword arguments (like `db_key="Smaug"`) is a way to name the input arguments to a function or method. They make things easier to read but also allows for conveniently setting defaults for values not given explicitly.
_Keyword arguments_ (like `db_key="Smaug"`) is a way to name the input arguments to a function or method. They make things easier to read but also allows for conveniently setting defaults for values not given explicitly. We saw them previously in use for `.format()`.
```
> py
@ -126,6 +124,10 @@ Keyword arguments (like `db_key="Smaug"`) is a way to name the input arguments
Smaug works the same as before, but we created him differently: first we used
`Dragon(db_key="Smaug", db_location=here)` to create the object, and then we used `smaug.save()` afterwards.
```{sidebar} here
The `here` used in `db_location=here` is a shortcut for your current location. This `here` (similar to `me`) is _only_ available to use in the `py` command; you can't use it in other Python code you write unless you define it yourself.
```
> quit()
Python Console is closing.
> look
@ -135,9 +137,7 @@ You should now see that Smaug _is in the room with you_. Woah!
> reload
> look
_He's still there_... What we just did was to create a new entry in the database for Smaug. We gave the object
its name (key) and set its location to our current location (remember that `here` is just something available
in the `py` command, you can't use it elsewhere).
_He's still there_... What we just did was to create a new entry in the database for Smaug. We gave the object its name (key) and set its location to our current location.
To make use of Smaug in code we must first find him in the database. For an object in the current
location we can easily do this in `py` by using `me.search()`:
@ -150,78 +150,79 @@ location we can easily do this in `py` by using `me.search()`:
Creating Smaug like we did above is nice because it's similar to how we created non-database
bound Python instances before. But you need to use `db_key` instead of `key` and you also have to
remember to call `.save()` afterwards. Evennia has a helper function that is more common to use,
called `create_object`:
called `create_object`. Let's recreate Cuddly this time:
> py fluffy = evennia.create_object('typeclases.monster.Monster', key="Fluffy", location=here)
> py evennia.create_object('typeclasses.monster.Monster', key="Cuddly", location=here)
> look
Boom, Fluffy should now be in the room with you, a little less scary than Smaug. You specify the
python-path to the code you want and then set the key and location. Evennia sets things up and saves for you.
Boom, Cuddly should now be in the room with you, a little less scary than Smaug. You specify the
python-path to the code you want and then set the key and location (if you had the `Monster` class already imported, you could have passed that too). Evennia sets things up and saves for you.
If you want to find Fluffy from anywhere, you can use Evennia's `search_object` helper:
If you want to find Smaug from anywhere (not just in the same room), you can use Evennia's `search_object` function:
> fluffy = evennia.search_object("Fluffy")[0] ; fluffy.move_around()
Fluffy is moving!
> cuddly = evennia.search_object("Cuddly")[0] ; cuddly.move_around()
Cuddly is moving!
> The `[0]` is because `search_object` always returns a _list_ of zero, one or more found objects. The `[0]`
means that we want the first element of this list (counting in Python always starts from 0). If there were
multiple Fluffies we could get the second one with `[1]`.
> The `[0]` is because `search_object` always returns a _list_ of zero, one or more found objects. The `[0]` means that we want the first element of this list (counting in Python always starts from 0). If there were multiple Cuddlies we could get the second one with `[1]`.
### Creating using create-command
Finally, you can also create a new Dragon using the familiar builder-commands we explored a few lessons ago:
Finally, you can also create a new dragon using the familiar builder-commands we explored a few lessons ago:
> create/drop Cuddly:typeclasses.monsters.Monster
> create/drop Fluffy:typeclasses.monsters.Dragon
Cuddly is now in the room. After learning about how objects are created you'll realize that all this command really
does is to parse your input, figure out that `/drop` means to "give the object the same location as the caller",
and then do a call akin to
Fluffy is now in the room. After learning about how objects are created you'll realize that all this command really does is to parse your input, figure out that `/drop` means to "give the object the same location as the caller", and then do a call very similar to
evennia.create_object("typeclasses.monsters.Monster", key="Cuddly", location=here)
evennia.create_object("typeclasses.monsters.Dragon", key="Cuddly", location=here)
That's pretty much all there is to the mighty `create` command! The rest is just parsing for the command
to understand just what the user wants to create.
That's pretty much all there is to the mighty `create` command! The rest is just parsing for the command to understand just what the user wants to create.
## Typeclasses
The `Object` (and `DefafultObject` class we inherited from above is what we refer to as a _Typeclass_. This
is an Evennia thing. The instance of a typeclass saves itself to the database when it is created, and after
that you can just search for it to get it back. We use the term _typeclass_ or _typeclassed_ to differentiate
these types of classes and objects from the normal Python classes, whose instances go away on a reload.
The `Object` (and `DefafultObject` class we inherited from above is what we refer to as a _Typeclass_. This is an Evennia thing. The instance of a typeclass saves itself to the database when it is created, and after that you can just search for it to get it back.
We use the term _typeclass_ or _typeclassed_ to differentiate these types of classes and objects from the normal Python classes, whose instances go away on a reload.
The number of typeclasses in Evennia are so few they can be learned by heart:
- `evennia.DefaultObject`: This is the parent of all in-game entities - everything with a location. Evennia makes
a few very useful child classes of this class:
- `evennia.DefaultCharacter`: The default entity represening a player avatar in-game.
- `evennia.DefaultRoom`: A location in the game world.
- `evennia.DefaultExit`: A link between locations.
- `evennia.DefaultAccount`: The OOC representation of a player, holds password and account info.
- `evennia.DefaultChannel`: In-game channels. These could be used for all sorts of in-game communication.
- `evennia.DefaultScript`: Out-of-game objects, with no presence in the game world. Anything you want to create that
needs to be persistent can be stored with these entities, such as combat state, economic systems or what have you.
If you take a look in `mygame/typeclasses/` you'll find modules for each of these. Each contains an empty child
class ready that already inherits from the right parent, ready for you to modify or build from:
| Evennia base typeclass | mygame.typeclasses child | description |
| --------------- | --------------| ------------- |
| `evennia.DefaultObject` | `typeclasses.objects.Object` | Everything with a location |
| `evennia.DefaultCharacter` (child of `DefaultObject`) | `typeclasses.characters.Character` | Player avatars |
| `evennia.DefaultRoom` (child of `DefaultObject`) | `typeclasses.rooms.Room` | In-game locations |
| `evennia.DefaultExit` (chld of `DefaultObject`) | `typeclasses.exits.Exit` | Links between rooms |
| `evennia.DefaultAccount` | `typeclasses.accounts.Account` | A player account |
| `evennia.DefaultChannel` | `typeclasses.channels.Channel` | In-game comms |
| `evennia.DefaultScript` | `typeclasses.scripts.Script` | Entities with no location |
- `mygame/typeclasses/objects.py` has `class Object(DefaultObject)`, a class directly inheriting the basic in-game entity, this
works as a base for any object.
- `mygame/typeclasses/characters.py` has `class Character(DefaultCharacter)`
- `mygame/typeclasses/rooms.py` has `class Room(DefaultRoom)`
- `mygame/typeclasses/exits.py` has `class Exit(DefaultExit)`
- `mygame/typeclasses/accounts.py` has `class Account(DefaultAccount)`
- `mygame/typeclasses/channels.py` has `class Channel(DefaultChannel)`
- `mygame/typeclasses/scripts.py` has `class Script(DefaultScript)`
The child classes under `mygame/typeclasses/` are meant for you to conveniently modify and
work with. Every class inheriting (at any distance) from a Evennia base typeclass is also considered a typeclass.
> Notice that the classes in `mygame/typeclasses/` are _not inheriting from each other_. For example,
> `Character` is inheriting from `evennia.DefaultCharacter` and not from `typeclasses.objects.Object`.
> So if you change `Object` you will not cause any change in the `Character` class. If you want that you
> can easily just change the child classes to inherit in that way instead; Evennia doesn't care.
```
from somewhere import Something
from evennia import DefaultScript
As seen with our `Dragon` example, you don't _have_ to modify these modules directly. You can just make your
own modules and import the base class.
class MyOwnClass(Something):
# not inheriting from an Evennia core typeclass, so this
# is just a 'normal' Python class inheriting from somewhere
pass
### Examining and defaults
class MyOwnClass2(DefaultScript):
# inherits from one of the core Evennia typeclasses, so
# this is also considered a 'typeclass'.
pass
```
```{sidebar} Why invent the name 'typeclass'?
We separate 'regular classes' from 'typeclasses' because while typeclasses act _almost_ like normal Python classes, [there are some differences](../../../Components/Typeclasses.md). We will gloss over those differences for now, but they are worth to read up on when you want to do more advanced things later.
```
Notice that the classes in `mygame/typeclasses/` are _not inheriting from each other_. For example, `Character` is inheriting from `evennia.DefaultCharacter` and not from `typeclasses.objects.Object`. So if you change `Object` you will not cause any change in the `Character` class. If you want that you can easily just change the child classes to inherit in that way instead; Evennia doesn't care.
As seen with our `Dragon` example, you don't _have_ to modify these modules directly. You can just make your own modules and import the base class.
### Examining objects
When you do
@ -253,20 +254,18 @@ may be more useful to us:
- **Name/key** - The name of this thing. The value `(#14)` is probably different for you. This is the
unique 'primary key' or _dbref_ for this entity in the database.
- **Typeclass**: This show the typeclass we specified, and the path to it.
- **Location**: We are in Limbo. If you moved elsewhere you'll see that instead. Also the `#dbref` is shown.
- **Permissions**: _Permissions_ are like the inverse to _Locks_ - they are like keys to unlock access to other things.
The giantess have no such keys (maybe fortunately).
- **Locks**: Locks are the inverse of _Permissions_ - specify what criterion _other_ objects must fulfill in order to
access the `giantess` object. This uses a very flexible mini-language. For examine, the line `examine:perm(Builders)`
is read as "Only those with permission _Builder_ or higher can _examine_ this object". Since we are the superuser
we pass (even bypass) such locks with ease.
- **Persistent attributes**: This allows for storing arbitrary, persistent data on the typeclassed entity. We'll get
to those in the next section.
- **Location**: We are in Limbo. If you moved elsewhere you'll see that instead. Also the `#dbref` of Limbo is shown.
- **Home**: All objects with a location (inheriting from `DefaultObject`) must have a home location. This is a backup to move the object to if its current location is deleted.
- **Permissions**: _Permissions_ are like the inverse to _Locks_ - they are like keys to unlock access to other things. The giantess have no such keys (maybe fortunately). The [Permissions](../../../Components/Permissions.md) has more info.
- **Locks**: Locks are the inverse of _Permissions_ - specify what criterion _other_ objects must fulfill in order to access the `giantess` object. This uses a very flexible mini-language. For examine, the line `examine:perm(Builders)` is read as "Only those with permission _Builder_ or higher can _examine_ this object". Since we are the superuser we pass (even bypass) such locks with ease. See the [Locks](../../../Components/Locks.md) documentation for more info.
- **Persistent attributes**: This allows for storing arbitrary, persistent data on the typeclassed entity. We'll get to those in the next section.
Note how the **Typeclass** line describes exactly where to find the code of this object? This is very useful for
understanding how any object in Evennia works.
Note how the **Typeclass** line describes exactly where to find the code of this object? This is very useful for understanding how any object in Evennia works.
What happens if we _don't_ specify the typeclass though?
### Default typeclasses
What happens if we create an object and _don't_ specify its typeclass though?
> create/drop box
You create a new Object: box.
@ -283,23 +282,17 @@ You will find that the **Typeclass** line now reads
Typeclass: Object (typeclasses.objects.Object)
So when you didn't specify a typeclass, Evennia used a default, more specifically the (so far) empty `Object` class in
`mygame/typeclasses/objects.py`. This is usually what you want, especially since you can tweak that class as much
as you like.
So when you didn't specify a typeclass, Evennia used a default, more specifically the (so far) empty `Object` class in `mygame/typeclasses/objects.py`. This is usually what you want, especially since you can tweak that class as much as you like.
But the reason Evennia knows to fall back to this class is not hard-coded - it's a setting. The default is
in [evennia/settings_default.py](https://github.com/evennia/evennia/blob/master/evennia/settings_default.py#L465),
with the name `BASE_OBJECT_TYPECLASS`, which is set to `typeclasses.objects.Object`.
But the reason Evennia knows to fall back to this class is not hard-coded - it's a setting. The default is in [evennia/settings_default.py](../../../Setup/Settings-Default.md), with the name `BASE_OBJECT_TYPECLASS`, which is set to `typeclasses.objects.Object`.
```{sidebar} Changing things
While it's tempting to change folders around to your liking, this can make it harder to follow tutorials and may confuse if you are asking others for help. So don't overdo it unless you really know what you are doing.
While it's tempting to change folders around to your liking, this can make it harder to follow tutorials and may confuse if you are asking others for help. So don't overdo it unless you really know what you are doing.
```
So if you wanted the creation commands and methods to default to some other class you could
add your own `BASE_OBJECT_TYPECLASS` line to `mygame/server/conf/settings.py`. The same is true for all the other
typeclasseses, like characters, rooms and accounts. This way you can change the
layout of your game dir considerably if you wanted. You just need to tell Evennia where everything is.
add your own `BASE_OBJECT_TYPECLASS` line to `mygame/server/conf/settings.py`. The same is true for all the other typeclasseses, like characters, rooms and accounts. This way you can change the layout of your game dir considerably if you wanted. You just need to tell Evennia where everything is.
## Modifying ourselves
@ -318,8 +311,8 @@ class Character(DefaultCharacter):
pass
```
This looks quite familiar now - an empty class inheriting from the Evennia base typeclass. As you would expect,
this is also the default typeclass used for creating Characters if you don't specify it. You can verify it:
This looks quite familiar now - an empty class inheriting from the Evennia base typeclass (it's even easier than `Object` since there is no equvalent `ParentObject` mixin class here). As you would expect, this is also the default typeclass used for creating Characters if you don't specify it. You can verify it:
> examine me
------------------------------------------------------------------------------
@ -347,16 +340,15 @@ this is also the default typeclass used for creating Characters if you don't spe
last_cmd = None
------------------------------------------------------------------------------
You got a lot longer output this time. You have a lot more going on than a simple Object. Here are some new fields of note:
Yes, the `examine` command understands `me`. You got a lot longer output this time. You have a lot more going on than a simple Object. Here are some new fields of note:
- **Session id(s)**: This identifies the _Session_ (that is, the individual connection to a player's game client).
- **Account** shows, well the `Account` object associated with this Character and Session.
- **Stored/Merged Cmdsets** and **Commands available** is related to which _Commands_ are stored on you. We will
get to them in the [next lesson](./Beginner-Tutorial-Adding-Commands.md). For now it's enough to know these consitute all the
- **Stored/Merged Cmdsets** and **Commands available** is related to which _Commands_ are stored on you. We will get to them in the [next lesson](./Beginner-Tutorial-Adding-Commands.md). For now it's enough to know these consitute all the
commands available to you at a given moment.
- **Non-Persistent attributes** are Attributes that are only stored temporarily and will go away on next reload.
Look at the **Typeclass** field and you'll find that it points to `typeclasses.character.Character` as expected.
So if we modify this class we'll also modify ourselves.
Look at the **Typeclass** field and you'll find that it points to `typeclasses.character.Character` as expected. So if we modify this class we'll also modify ourselves.
### A method on ourselves
@ -369,15 +361,15 @@ class Character(DefaultCharacter):
(class docstring)
"""
str = 10
dex = 12
int = 15
strength = 10
dexterity = 12
intelligence = 15
def get_stats(self):
"""
Get the main stats of this character
"""
return self.str, self.dex, self.int
return self.strength, self.dexterity, self.intelligence
```
@ -390,9 +382,7 @@ class Character(DefaultCharacter):
- A `list` is written `[a, b, c, d, ...]`. It can be modified after creation.
- A `tuple` is written `(a, b, c, ...)`. It cannot be modified once created.
```
We made a new method, gave it a docstring and had it `return` the RP-esque values we set. It comes back as a
_tuple_ `(10, 12, 15)`. To get a specific value you could specify the _index_ of the value you want,
starting from zero:
We made a new method, gave it a docstring and had it `return` the RP-esque values we set. It comes back as a _tuple_ `(10, 12, 15)`. To get a specific value you could specify the _index_ of the value you want, starting from zero:
> py stats = self.get_stats() ; print(f"Strength is {stats[0]}.")
Strength is 10.
@ -401,15 +391,14 @@ starting from zero:
So what happens when we increase our strength? This would be one way:
> py self.str = self.str + 1
> py self.str
> py self.strength = self.str + 1
> py self.strength
11
Here we set the strength equal to its previous value + 1. A shorter way to write this is to use Python's `+=`
operator:
Here we set the strength equal to its previous value + 1. A shorter way to write this is to use Python's `+=` operator:
> py self.str += 1
> py self.str
> py self.strength += 1
> py self.strength
12
> py self.get_stats()
(12, 12, 15)
@ -420,13 +409,9 @@ This looks correct! Try to change the values for dex and int too; it works fine.
> py self.get_stats()
(10, 12, 15)
After a reload all our changes were forgotten. When we change properties like this, it only changes in memory,
not in the database (nor do we modify the python module's code). So when we reloaded, the 'fresh' `Character`
class was loaded, and it still has the original stats we wrote to it.
After a reload all our changes were forgotten. When we change properties like this, it only changes in memory, not in the database (nor do we modify the python module's code). So when we reloaded, the 'fresh' `Character` class was loaded, and it still has the original stats we wrote in it.
In principle we could change the python code. But we don't want to do that manually every time. And more importantly
since we have the stats hardcoded in the class, _every_ character instance in the game will have exactly the
same `str`, `dex` and `int` now! This is clearly not what we want.
In principle we could change the python code. But we don't want to do that manually every time. And more importantly since we have the stats hardcoded in the class, _every_ character instance in the game will have exactly the same `str`, `dex` and `int` now! This is clearly not what we want.
Evennia offers a special, persistent type of property for this, called an `Attribute`. Rework your
`mygame/typeclasses/characters.py` like this:
@ -442,67 +427,56 @@ class Character(DefaultCharacter):
"""
Get the main stats of this character
"""
return self.db.str, self.db.dex, self.db.int
return self.db.strength, self.db.dexterity, self.db.intelligence
```
```{sidebar} Spaces in Attribute name?
What if you want spaces in your Attribute name? Or you want to assign the name of the Attribute on-the fly? Then you can use `.attributes.add(name, value)` instead, for example `self.attributes.add("str", 10)`.
What if you want spaces in your Attribute name? Or you want to assign the name of the Attribute on-the fly? Then you can use `.attributes.add(name, value)` instead, for example `self.attributes.add("emotional intelligence", 10)`. You read it out again with `self.attributes.get("emotional intelligence"`.
```
We removed the hard-coded stats and added added `.db` for every stat. The `.db` handler makes the stat
into an an Evennia `Attribute`.
We removed the hard-coded stats and added added `.db` for every stat. The `.db` handler makes the stat into an an Evennia [Attribute](../../../Components/Attributes.md).
> reload
> py self.get_stats()
(None, None, None)
Since we removed the hard-coded values, Evennia don't know what they should be (yet). So all we get back
is `None`, which is a Python reserved word to represent nothing, a no-value. This is different from a normal python
property:
Since we removed the hard-coded values, Evennia don't know what they should be (yet). So all we get back is `None`, which is a Python reserved word to represent nothing, a no-value. This is different from a normal python property:
> py self.str
AttributeError: 'Character' object has no attribute 'str'
> py self.db.str
> py me.strength
AttributeError: 'Character' object has no attribute 'strength'
> py me.db.strength
(nothing will be displayed, because it's None)
Trying to get an unknown normal Python property will give an error. Getting an unknown Evennia `Attribute` will
never give an error, but only result in `None` being returned. This is often very practical.
Trying to get an unknown normal Python property will give an error. Getting an unknown Evennia `Attribute` will never give an error, but only result in `None` being returned. This is often very practical.
> py self.db.str, self.db.dex, self.db.int = 10, 12, 15
> py self.get_stats()
Next, let us test out assigning those Attributes
> py me.db.strength, me.db.dexterity, me.db.intelligence = 10, 12, 15
> py me.get_stats()
(10, 12, 15)
> reload
> py self.get_stats()
> py me.get_stats()
(10, 12, 15)
Now we set the Attributes to the right values. We can see that things work the same as before, also after a
server reload. Let's modify the strength:
Now we set the Attributes to the right values, and they survive a server reload! Let's modify the strength:
> py self.db.str += 2
> py self.db.strength += 2
> py self.get_stats()
(12, 12, 15)
> reload
> py self.get_stats()
(12, 12, 15)
Our change now survives a reload since Evennia automatically saves the Attribute to the database for us.
Also our change now survives a reload since Evennia automatically saves the Attribute to the database for us.
### Setting things on new Characters
Things a looking better, but one thing remains strange - the stats start out with a value `None` and we
have to manually set them to something reasonable. In a later lesson we will investigate character-creation
in more detail. For now, let's give every new character some random stats to start with.
Things are looking better, but one thing remains strange - the stats start out with a value `None` and we have to manually set them to something reasonable. In a later lesson we will investigate character-creation in more detail. For now, let's give every new character some random stats to start with.
We want those stats to be set only once, when the object is first created. For the Character, this method
is called `at_object_creation`.
We want those stats to be set only once, when the object is first created. For the Character, this method is called `at_object_creation`.
```{sidebar} __init__ vs at_object_creation
For the `Monster` class we used `__init__` to set up the class. We can't use this for a typeclass because it will be called more than once, at the very least after every reload and maybe more depending on caching. Even if you are familiar with Python, avoid touching `__init__` for typeclasses, the results will not be what you expect.
```
```python
# up by the other imports
@ -514,15 +488,15 @@ class Character(DefaultCharacter):
"""
def at_object_creation(self):
self.db.str = random.randint(3, 18)
self.db.dex = random.randint(3, 18)
self.db.int = random.randint(3, 18)
self.db.strength = random.randint(3, 18)
self.db.dexterity = random.randint(3, 18)
self.db.intelligence = random.randint(3, 18)
def get_stats(self):
"""
Get the main stats of this character
"""
return self.db.str, self.db.dex, self.db.int
return self.db.strength, self.db.dexterity, self.db.intelligence
```
We imported a new module, `random`. This is part of Python's standard library. We used `random.randint` to
@ -532,9 +506,12 @@ set a random value from 3 to 18 to each stat. Simple, but for some classical RPG
> py self.get_stats()
(12, 12, 15)
Hm, this is the same values we set before. They are not random. The reason for this is of course that, as said,
`at_object_creation` only runs _once_, the very first time a character is created. Our character object was already
created long before, so it will not be called again.
```{sidebar} __init__ vs at_object_creation
For the `Monster` class we used `__init__` to set up the class. We can't use this for a typeclass because it will be called more than once, at the very least after every reload and maybe more depending on caching. Even if you are familiar with Python, avoid touching `__init__` for typeclasses, the results will not be what you expect.
```
Hm, this is the same values we set before. They are not random. The reason for this is of course that, as said, `at_object_creation` only runs _once_, the very first time a character is created. Our character object was already created long before, so it will not be called again.
It's simple enough to run it manually though:
@ -548,25 +525,28 @@ Lady luck didn't smile on us for this example; maybe you'll fare better. Evennia
> update self
> py self.get_stats()
(8, 16, 14)
### Updating all Characters in a loop
Needless to say, for your game you are wise to have a feel for what you want to go into the `at_object_creation` hook
before you create a lot of objects (characters in this case). But should it come to that you don't want to have to
go around and re-run the method on everyone manually. For the Python beginner, doing this will also give a chance to
try out Python _loops_. We try them out in multi-line Python mode:
```{sidebar} AttributeProperties
There is another way to define Attributes on a class, known as [AttributeProperties](../../../Components/Attributes.md#using-attributeproperty). They can make it easier to maintain static default Attribute values on a typeclass. We will show them off when we make our game later in this tutorial series.
```
Needless to say, you are wise to have a feel for what you want to go into the `at_object_creation` hook _before_ you create a lot of objects (characters in this case).
Luckily you only need to update objects once, and you don't have to go around and re-run the `at_object_creation` method on everyone manually. For this we'll try out a Python _loop_. Let's go into multi-line Python mode:
> py
> for a in [1, 2, "foo"]: > print(a)
> for a in [1, 2, "foo"]:
> print(a)
1
2
foo
A python _for-loop_ allows us to loop over something. Above, we made a _list_ of two numbers and a string. In
every iteration of the loop, the variable `a` becomes one element in turn, and we print that.
A python _for-loop_ allows us to loop over something. Above, we made a _list_ of two numbers and a string. In every iteration of the loop, the variable `a` becomes one element in turn, and we print that.
For our list, we want to loop over all Characters, and want to call `.at_object_creation` on each. This is how
this is done (still in python multi-line mode):
For our list, we want to loop over all Characters, and want to call `.at_object_creation` on each. This is how this is done (still in python multi-line mode):
> from typeclasses.characters import Character
> for char in Character.objects.all()
@ -574,7 +554,7 @@ this is done (still in python multi-line mode):
```{sidebar} Database queries
`Character.objects.all()` is an example of a database query expressed in Python. This will be converted into a database query under the hood. This syntax is part of [Django's query language](https://docs.djangoproject.com/en/4.1/topics/db/queries/). You don't need to know Django to use Evennia, but if you ever need more specific database queries, this is always available when you need it.
`Character.objects.all()` is an example of a database query expressed in Python. This will be converted into a database query under the hood. This syntax is part of [Django's query language](https://docs.djangoproject.com/en/4.1/topics/db/queries/). You don't need to know Django to use Evennia, but if you ever need more specific database queries, this is always available when you need it. We'll get back to database queries in a later lesson.
```
We import the `Character` class and then we use `.objects.all()` to get all `Character` instances. Simplified,
`.objects` is a resource from which one can _query_ for all `Characters`. Using `.all()` gets us a listing
@ -587,19 +567,13 @@ of all of them that we then immediately loop over. Boom, we just updated all Cha
## Extra Credits
This principle is the same for other typeclasses. So using the tools explored in this lesson, try to expand
the default room with an `is_dark` flag. It can be either `True` or `False`.
Have all new rooms start with `is_dark = False` and make it so that once you change it, it survives a reload.
This principle is the same for other typeclasses. So using the tools explored in this lesson, try to expand the default room with an `is_dark` flag. It can be either `True` or `False`. Have all new rooms start with `is_dark = False` and make it so that once you change it, it survives a reload.
Oh, and if you created any other rooms before, make sure they get the new flag too!
## Conclusions
In this lesson we created database-persistent dragons by having their classes inherit from one `Object`, one
of Evennia's _typeclasses_. We explored where Evennia looks for typeclasses if we don't specify the path
explicitly. We then modified ourselves - via the `Character` class - to give us some simple RPG stats. This
led to the need to use Evennia's _Attributes_, settable via `.db` and to use a for-loop to update ourselves.
In this lesson we created database-persistent dragons by having their classes inherit from one `Object`, one of Evennia's _typeclasses_. We explored where Evennia looks for typeclasses if we don't specify the path explicitly. We then modified ourselves - via the `Character` class - to give us some simple RPG stats. This led to the need to use Evennia's _Attributes_, settable via `.db` and to use a for-loop to update ourselves.
Typeclasses are a fundamental part of Evennia and we will see a lot of more uses of them in the course of
this tutorial. But that's enough of them for now. It's time to take some action. Let's learn about _Commands_.
Typeclasses are a fundamental part of Evennia and we will see a lot of more uses of them in the course of this tutorial. But that's enough of them for now. It's time to take some action. Let's learn about _Commands_.

View file

@ -74,7 +74,7 @@ is to use the `.format` _method_ of the string:
This is a good idea!
```{sidebar} Functions and Methods
- Function: Something that performs and action when you `call` it with zero or more `arguments`. A function is stand-alone in a python module, like `print()`
- Function: Something that performs and action when you call it with zero or more `arguments`. A function is stand-alone in a python module, like `print()`
- Method: A function that sits "on" an object, like `obj.msg()`.
```
@ -119,8 +119,7 @@ trouble, use the Evennia web client.
What happened here was that we _assigned_ the string `"awesome sauce"` to a _variable_ we chose
to name `a`. In the next statement, Python remembered what `a` was and we passed that into `format()`
to get the output. If you replaced the value of `a` with something else in between, _that_ would be printed
instead.
to get the output. If you replaced the value of `a` with something else in between, _that_ would be printed instead.
Here's the stat-example again, moving the stats to variables (here we just set them, but in a real
game they may be changed over time, or modified by circumstance):
@ -128,13 +127,18 @@ game they may be changed over time, or modified by circumstance):
> py stren, dext, intel = 13, 14, 8 ; print("STR: {}, DEX: {}, INT: {}".format(stren, dext, intel))
STR: 13, DEX: 14, INT: 8
The point is that even if the values of the stats change, the print() statement would not change - it just keeps
pretty-printing whatever is given to it.
The point is that even if the values of the stats change, the print() statement would not change - it just keeps pretty-printing whatever is given to it.
You can also use named markers, like this:
> py print("STR: {stren}, INT: {intel}, STR again: {stren}".format(dext=10, intel=18, stren=9))
STR: 9, INT: 18, Str again: 9
the `key=value` pairs we add are called _keyword arguments_ for the `format()` method. Each named argument will go to the matching `{key}` in the string. When using keywords, the order we add them doesn't matter. We have no `{dext}` and two `{stren}` in the string, and that works fine.
### f-strings
Using `.format()` is convenient (and there is a [lot more](https://www.w3schools.com/python/ref_string_format.asp)
you can do with it). But the _f-string_ can be even more convenient. An
Using `.format()` is convenient (and there is a [lot more](https://www.w3schools.com/python/ref_string_format.asp) you can do with it). But the _f-string_ can be even more convenient. An
f-string looks like a normal string ... except there is an `f` front of it, like this:
f"this is now an f-string."
@ -144,7 +148,7 @@ An f-string on its own is just like any other string. But let's redo the example
> py a = "awesome sauce" ; print(f"This is {a}!")
This is awesome sauce!
We could just insert that `a` variable directly into the f-string using `{a}`. Fewer parentheses to
We insert that `a` variable directly into the f-string using `{a}`. Fewer parentheses to
remember and arguable easier to read as well.
> py stren, dext, intel = 13, 14, 8 ; print(f"STR: {stren}, DEX: {dext}, INT: {intel}")
@ -168,7 +172,7 @@ gives the normal text color. You can also use RGB (Red-Green-Blue) values from 0
> If you don't see the expected color, your client or terminal may not support Xterm256 (or
color at all). Use the Evennia webclient.
Use the commands `color ansi` or `color xterm` to see which colors are available. Experiment!
Use the commands `color ansi` or `color xterm` to see which colors are available. Experiment! You can also read a lot more in the [Colors](../../../Concepts/Colors.md) documentation.
## Importing code from other modules
@ -209,11 +213,9 @@ If you make some error (we'll cover how to handle errors below), fix the error i
run the `reload` command in-game for your changes to take effect.
So importing `world.test` actually means importing `world/test.py`. Think of the period `.` as
replacing `/` (or `\` for Windows) in your path. The `.py` ending of `test.py` is also never
included in this "Python-path", but _only_ files with that ending can be imported this way.
Where is `mygame` in that Python-path? The answer is that Evennia has already told Python that
your `mygame` folder is a good place to look for imports. So we don't include `mygame` in the
path - Evennia handles this for us.
replacing `/` (or `\` for Windows) in your path.
The `.py` ending of `test.py` is never included in this "Python-path", but _only_ files with that ending can be imported this way. Where is `mygame` in that Python-path? The answer is that Evennia has already told Python that your `mygame` folder is a good place to look for imports. So we should not include `mygame` in the path - Evennia handles this for us.
When you import the module, the top "level" of it will execute. In this case, it will immediately
print "Hello World".
@ -222,10 +224,7 @@ Now try to run this a second time:
> py import world.test
You will *not* see any output this second time or any subsequent times! This is not a bug. Rather
it is because of how Python importing works - it stores all imported modules and will
avoid importing them more than once. So your `print` will only run the first time, when the module
is first imported.
You will *not* see any output this or any subsequent times! This is not a bug. Rather it is because of how Python importing works - it stores all imported modules and will avoid importing them more than once. So your `print` will only run the first time, when the module is first imported.
Try this:
@ -240,8 +239,7 @@ Now we see it again. The `reload` wiped the server's memory of what was imported
import it anew. You'd have to do this every time you wanted the print to show though, which is
not very useful.
> We'll get back to more advanced ways to import code in later tutorial sections - this is an
> important topic. But for now, let's press on and resolve this particular problem.
> We'll get back to more advanced ways to import code in [a later lesson](./Beginner-Tutorial-Python-classes-and-objects.md#importing-things) - this is an important topic. But for now, let's press on and resolve this particular problem.
### Our first own function
@ -434,8 +432,8 @@ On the game command-line, let's create a mirror:
```{sidebar} Creating objects
The `create` command was first used to create boxes in the
`Building Stuff <Building-Quickstart>`_ tutorial. Note how it
uses a "python-path" to describe where to load the mirror's code from.
[Building Stuff](./Beginner-Tutorial-Building-Quickstart.md) tutorial. You should now recognize
that it uses a "python-path" to tell Evennia where to load the mirror's code from.
```
A mirror should appear in your location.
@ -498,7 +496,7 @@ inside Evennia.
> py
Evennia Interactive Python mode
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
Python 3.11.0 (default, Nov 22 2022, 11:21:55)
[GCC 8.2.0] on Linux
[py mode - quit() to exit]
@ -512,15 +510,13 @@ commands).
Hello World
[py mode - quit() to exit]
Note that we didn't need to put `py` in front now. The system will also echo your input (that's the bit after
the `>>>`). For brevity in this tutorual we'll turn the echo off. First exit `py` and then start again with the
`/noecho` flag.
Note that we didn't need to put `py` in front now. The system will also echo your input (that's the bit after the `>>>`). For brevity in this tutorual we'll turn the echo off. First exit `py` and then start again with the `/noecho` flag.
> quit()
Closing the Python console.
> py/noecho
Evennia Interactive Python mode (no echoing of prompts)
Python 3.7.1 (default, Oct 22 2018, 11:21:55)
Python 3.11.0 (default, Nov 22 2022, 11:21:56)
[GCC 8.2.0] on Linux
[py mode - quit() to exit]
@ -528,14 +524,14 @@ the `>>>`). For brevity in this tutorual we'll turn the echo off. First exit `py
- Start with `py`.
- Use `py/noecho` if you don't want your input to be echoed for every line.
- All your inputs will now be interpreted as Python code.
- _All_ your inputs will now be interpreted as Python code.
- Exit with `quit()`.
```
We can now enter multi-line Python code:
> a = "Test"
> print(f"This is a {a}."}
> print(f"This is a {a}.")
This is a Test.
Let's try to define a function:
@ -554,8 +550,7 @@ Some important things above:
for Python to know it's part of the function body.
- We expand the `hello_world` function with another argument `txt`. This allows us to send any text, not just
"Hello World" over and over.
- To tell `py` that no more lines will be added to the function body, we end with an empty input. When
the normal prompt on how to exit returns, we know we are done.
- To tell `py` that no more lines will be added to the function body, we end with an empty input. When the normal prompt returns, we know we are done.
Now we have defined a new function. Let's try it out:
@ -645,5 +640,4 @@ first function, fixed an error and even searched and talked to a mirror! Being a
python inside and outside of the game is an important skill for testing and debugging, but in
practice you will be writing most your code in Python modules.
To that end we also created a first new Python module in the `mygame/` game dir, then imported and used it.
Now let's look at the rest of the stuff you've got going on inside that `mygame/` folder ...
To that end we also created a first new Python module in the `mygame/` game dir, then imported and used it. Now let's look at the rest of the stuff you've got going on inside that `mygame/` folder ...

View file

@ -5,16 +5,16 @@ We have also taken a look at what our game dir looks and what is where. Now we'l
## Importing things
No one writes something as big as an online game in one single huge file. Instead one breaks up the
code into separate files (modules). Each module is dedicated to different purposes. Not only does
it make things cleaner, organized and easier to understand. It also makes it easier to re-use code -
you just import the resources you need and know you only get just what you requested. This makes
it much easier to find errors and to know what code is good and which has issues.
In a [previous lesson](./Beginner-Tutorial-Python-basic-introduction.md#importing-code-from-other-modules) we already learned how to import resources into our code. Now we'll dive a little deeper.
No one writes something as big as an online game in one single huge file. Instead one breaks up the code into separate files (modules). Each module is dedicated to different purposes. Not only does it make things cleaner, organized and easier to understand.
Splitting code also makes it easier to re-use - you just import the resources you need and know you only get just what you requested. This makes it easier to spot errors and to know what code is good and which has issues.
> Evennia itself uses your code in the same way - you just tell it where a particular type of code is,
and it will import and use it (often instead of its defaults).
We have already successfully imported things, for example:
Here's a familiar example:
> py import world.test ; world.test.hello_world(me)
Hello World!
@ -44,10 +44,7 @@ def hello_world(who):
- Anything on a line after a `#` is a `comment`, ignored by Python
```
The _python_path_ describes the relation between Python resources, both between and inside
Python _modules_ (that is, files ending with .py). A python-path separates each part of the
path `.` and always skips the `.py` file endings. Also, Evennia already knows to start looking
for python resources inside `mygame/` so this should never be specified. Hence
To reiterate, the _python_path_ describes the relation between Python resources, both between and inside Python _modules_ (that is, files ending with .py). Paths use `.` and always skips the `.py` file endings. Also, Evennia already knows to start looking for python resources inside `mygame/` so this should never be included.
import world.test
@ -57,7 +54,7 @@ this module to get to the function you want:
world.test.hello_world(me)
Using `import` like this means that you have to specify the full `world.test` every time you want
to get to your function. Here's a more powerful form of import:
to get to your function. Here's an alternative:
from world.test import hello_world
@ -127,6 +124,12 @@ module docstring
"""
from evennia import DefaultObject
class ObjectParent:
"""
class docstring
"""
pass
class Object(DefaultObject):
"""
class docstring
@ -136,7 +139,7 @@ class Object(DefaultObject):
```{sidebar} Docstrings vs Comments
A docstring is not the same as a comment (created by `#`). A docstring is not ignored by Python but is an integral part of the thing it is documenting (the module and the class in this case).
A docstring is not the same as a comment (created by `#`). A docstring is not ignored by Python but is an integral part of the thing it is documenting (the module and the class in this case). For example, we read docstrings to help text for [API documentation](../../../Evennia-API.md); we could not do that with comments.
```
The real file is much longer but we can ignore the multi-line strings (`""" ... """`). These serve
as documentation-strings, or _docstrings_ for the module (at the top) and the `class` below.
@ -145,13 +148,12 @@ Below the module doc string we have the import. In this case we are importing a
from the core `evennia` library itself. We will dive into this later, for now we just treat this
as a black box.
Next we have a `class` named `Object`, which _inherits_ from `DefaultObject`. This class doesn't
actually do anything on its own, its only code (except the docstring) is `pass` which means,
well, to pass and don't do anything.
Next we have an empty `class` named `ObjectParent`. It doesn't do anything, its only code (except the docstring) is `pass` which means, well, to pass and don't do anything. Since it also doesn't _inherit_ from anything, it's just an empty container. We will not concern ourselves with it for this tutorial.
We will get back to this module in the [next lesson](./Beginner-Tutorial-Learning-Typeclasses.md). First we need to do a
little detour to understand what a 'class', an 'object' or 'instance' is. These are fundamental
things to understand before you can use Evennia efficiently.
The `class` named `Object`_ inherits_ from `ObjectParent` and `DefaultObject`. Since we see that `ObjectParent` is empty, what is interesting is `DefaultObject`. Again, the `Object` class doesn't
actually do anything on its own right now, but because of it being a child of `DefaultObject`, it's actually providing a lot of functionality! If this is confusing, read on.
We will get back to this module in the [next lesson](./Beginner-Tutorial-Learning-Typeclasses.md). First we need to do a little detour to understand what a 'class', an 'object' or 'instance' is. These are fundamental things to understand before you can use Evennia efficiently.
```{sidebar} OOP
Classes, objects, instances and inheritance are fundamental to Python. This and some other concepts are often clumped together under the term Object-Oriented-Programming (OOP).
@ -159,9 +161,7 @@ Classes, objects, instances and inheritance are fundamental to Python. This and
### Classes and instances
A 'class' can be seen as a 'template' for a 'type' of object. The class describes the basic functionality
of everyone of that class. For example, we could have a class `Monster` which has resources for moving itself
from room to room.
A 'class' can be seen as a 'template' for a 'type' of object. The class describes the basic functionality of everyone of that class. For example, we could have a class `Monster` which has resources for moving itself from room to room.
Open a new file `mygame/typeclasses/monsters.py`. Add the following simple class:
@ -185,11 +185,11 @@ back to the `key` on the class.
```{sidebar} Terms
- A `class` is a code template describing a 'type' of something
- An `object` is an `instance` of a `class`. Like using a mold to cast in soldiers, one class can be `instantiated` into any number of object-instances.
- An `object` is an `instance` of a `class`. Like using a mold to cast tin soldiers, one class can be `instantiated` into any number of object-instances. Each instance does not need to be identical (much like each tin soldier can be painted differently).
```
A class is just a template. Before it can be used, we must create an _instance_ of the class. If
`Monster` is a class, then an instance is Fluffy, the individual red dragon. You instantiate
`Monster` is a class, then an instance is `Fluffy`, a specific dragon individual. You instantiate
by _calling_ the class, much like you would a function:
fluffy = Monster()
@ -216,8 +216,7 @@ Let's create the sibling of Fluffy, Cuddly:
Monster is moving!
We now have two dragons and they'll hang around until with call `quit()` to exit this Python
instance. We can have them move as many times as we want. But no matter how many dragons we
create, they will all show the same printout since `key` is always fixed as "Monster".
instance. We can have them move as many times as we want. But no matter how many dragons we create, they will all show the same printout since `key` is always fixed as "Monster".
Let's make the class a little more flexible:
@ -259,13 +258,11 @@ Either way you'll need to go into `py` again:
fluffy.move_around()
Fluffy is moving!
Now we passed `"Fluffy"` as an argument to the class. This went into `__init__` and set `self.key`, which we
later used to print with the right name! Again, note that we didn't include `self` when calling.
Now we passed `"Fluffy"` as an argument to the class. This went into `__init__` and set `self.key`, which we later used to print with the right name!
### What's so good about objects?
So far all we've seen a class do is to behave our first `hello_world` function but more complex. We
could just have made a function:
So far all we've seen a class do is to behave like our first `hello_world` function but being more complex. We could just have made a function:
```python
def monster_move_around(key):
@ -276,13 +273,12 @@ The difference between the function and an instance of a class (the object), is
object retains _state_. Once you called the function it forgets everything about what you called
it with last time. The object, on the other hand, remembers changes:
> fluffy.key = "Cuddly"
> fluffy.key = "Fluffy, the red dragon"
> fluffy.move_around()
Cuddly is moving!
Fluffy, the red dragon is moving!
The `fluffy` object's `key` was changed to "Cuddly" for as long as it's around. This makes objects
extremely useful for representing and remembering collections of data - some of which can be other
objects in turn:
The `fluffy` object's `key` was changed for as long as it's around. This makes objects extremely useful for representing and remembering collections of data - some of which can be other
objects in turn. Some examples:
- A player character with all its stats
- A monster with HP
@ -295,8 +291,7 @@ objects in turn:
### Classes can have children
Classes can _inherit_ from each other. A "child" class will inherit everything from its "parent" class. But if
the child adds something with the same name as its parent, it will _override_ whatever it got from its parent.
Classes can _inherit_ from each other. A "child" class will inherit everything from its "parent" class. But if the child adds something with the same name as its parent, it will _override_ whatever it got from its parent.
Let's expand `mygame/typeclasses/monsters.py` with another class:
@ -316,7 +311,7 @@ class Monster:
class Dragon(Monster):
"""
This is a dragon-specific monster.
This is a dragon monster.
"""
def move_around(self):
@ -330,8 +325,7 @@ class Dragon(Monster):
```
We added some docstrings for clarity. It's always a good idea to add doc strings; you can do so also for methods,
as exemplified for the new `firebreath` method.
We added some docstrings for clarity. It's always a good idea to add doc strings; you can do so also for methods, as exemplified for the new `firebreath` method.
We created the new class `Dragon` but we also specified that `Monster` is the _parent_ of `Dragon` but adding
the parent in parenthesis. `class Classname(Parent)` is the way to do this.
@ -342,7 +336,7 @@ It's possible to add more comma-separated parents to a class. You should usually
```
Let's try out our new class. First `reload` the server and the do
Let's try out our new class. First `reload` the server and then:
> py
> from typeclasses.monsters import Dragon
@ -352,13 +346,9 @@ Let's try out our new class. First `reload` the server and the do
> smaug.firebreath()
Smaug breathes fire!
Because we didn't implement `__init__` in `Dragon`, we got the one from `Monster` instead. But since we
implemented our own `move_around` in `Dragon`, it _overrides_ the one in `Monster`. And `firebreath` is only
available for `Dragon`s of course. Having that on `Monster` would not have made much sense, since not every monster
can breathe fire.
Because we didn't (re)implement `__init__` in `Dragon`, we got the one from `Monster`. We did implement our own `move_around` in `Dragon`, so it _overrides_ the one in `Monster`. And `firebreath` is only available for `Dragon`s. Having that on `Monster` would not have made much sense, since not every monster can breathe fire.
One can also force a class to use resources from the parent even if you are overriding some of it. This is done
with the `super()` method. Modify your `Dragon` class as follows:
One can also force a class to use resources from the parent even if you are overriding some of it. This is done with the `super()` method. Modify your `Dragon` class as follows:
```python
@ -372,13 +362,12 @@ class Dragon(Monster):
# ...
```
> Keep `Monster` and the `firebreath` method, `# ...` indicates the rest of the code is untouched.
>
The `super().move_around()` line means that we are calling `move_around()` on the parent of the class. So in this
case, we will call `Monster.move_around` first, before doing our own thing.
> Keep `Monster` and the `firebreath` method. The `# ...` above indicates the rest of the code is unchanged.
Now `reload` the server and then:
The `super().move_around()` line means that we are calling `move_around()` on the parent of the class. So in this case, we will call `Monster.move_around` first, before doing our own thing.
To see, `reload` the server and then:
> py
> from typeclasses.monsters import Dragon
@ -387,18 +376,13 @@ Now `reload` the server and then:
Smaug is moving!
The world trembles.
We can see that `Monster.move_around()` is calls first and prints "Smaug is moving!", followed by the extra bit
about the trembling world we added in the `Dragon` class.
We can see that `Monster.move_around()` is called first and prints "Smaug is moving!", followed by the extra bit about the trembling world from the `Dragon` class.
Inheritance is very powerful because it allows you to organize and re-use code while only adding the special things
you want to change. Evennia uses this concept a lot.
Inheritance is a powerful concept. It allows you to organize and re-use code while only adding the special things you want to change. Evennia uses this a lot.
## Summary
We have created our first dragons from classes. We have learned a little about how you _instantiate_ a class
into an _object_. We have seen some examples of _inheritance_ and we tested to _override_ a method in the parent
with one in the child class. We also used `super()` to good effect.
We have created our first dragons from classes. We have learned a little about how you _instantiate_ a class into an _object_. We have seen some examples of _inheritance_ and we tested to _override_ a method in the parent with one in the child class. We also used `super()` to good effect.
We have used pretty much raw Python so far. In the coming lessons we'll start to look at the extra bits that Evennia
provides. But first we need to learn just where to find everything.
We have used pretty much raw Python so far. In the coming lessons we'll start to look at the extra bits that Evennia provides. But first we need to learn just where to find everything.

View file

@ -32,6 +32,7 @@ Only LOSERS and QUITTERS use the `give up` command.
## Gameplay
![the castle off the moor](https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/22916c25-6299-453d-a221-446ec839f567/da2pmzu-46d63c6d-9cdc-41dd-87d6-1106db5a5e1a.jpg/v1/fill/w_600,h_849,q_75,strp/the_castle_off_the_moor_by_griatch_art_da2pmzu-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3siaGVpZ2h0IjoiPD04NDkiLCJwYXRoIjoiXC9mXC8yMjkxNmMyNS02Mjk5LTQ1M2QtYTIyMS00NDZlYzgzOWY1NjdcL2RhMnBtenUtNDZkNjNjNmQtOWNkYy00MWRkLTg3ZDYtMTEwNmRiNWE1ZTFhLmpwZyIsIndpZHRoIjoiPD02MDAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.omuS3D1RmFiZCy9OSXiIita-HxVGrBok3_7asq0rflw)
(image by Griatch)
*To get into the mood of this miniature quest, imagine you are an adventurer out to find fame and
fortune. You have heard rumours of an old castle ruin by the coast. In its depth a warrior princess

View file

@ -8,7 +8,7 @@ Installing Evennia doesn't make anything visible online. Apart from installation
- Evennia requires [Python](https://www.python.org/downloads/) 3.9, 3.10 or 3.11 (recommended)
- Windows: In the installer, make sure you select `add python to path`. If you have multiple versions of Python installed, use `py` command instead of `python` to have Windows automatically use the latest.
- Using a light-weight [Python virtual environment](./Installation-Git.md#virtualenv) _ is optional, but _highly recommended_ in order to keep your Evennia installation independent from the system libraries. This comes with Python.
- Using a light-weight [Python virtual environment](./Installation-Git.md#virtualenv) is optional, but _highly recommended_ in order to keep your Evennia installation independent from the system libraries. Using virtualenvs is common Python praxis.
- Don't install Evennia as administrator or superuser.
- If you run into trouble, see [installation troubleshooting](./Installation-Troubleshooting.md).
@ -16,7 +16,7 @@ Evennia is managed from the terminal (console/Command Prompt on Windows). Once
pip install evennia
Optional: If you use a [contrib](Contribs) that warns you that it needs additional packages, you can
Optional: If you use a [contrib](../Contribs/Contribs-Overview.md) that warns you that it needs additional packages, you can
install all extra dependencies with
pip install evennia[extra]
@ -25,23 +25,23 @@ To update Evennia later, do
pip install --upgrade evennia
Once installed, make sure the `evennia` command works. Use `evennia -h` for usage help. If you are using a virtualenv, make sure it's active whenever you need to use the `evennia` command.
> Windows users only: You now need to run `python -m evennia` once. This should permanently make the `evennia` command available in your environment.
Once installed, make sure the `evennia` command works. Use `evennia -h` for usage help. If you are using a virtualenv, make sure it's active whenever you need to use the `evennia` command later.
> You can also [clone Evennia from github](./Installation-Git.md) or use [docker](./Installation-Docker.md). Some users have also experimented with [installing Evennia on Android](./Installation-Android.md).
## Initialize a new game
> Windows users: You need to first run `python -m evennia` once. This should permanently add the evennia launcher to your environment, making the `evennia` command available.
Use `cd` to enter a folder where you want to do your game development. Here (and in
the rest of the Evennia documentation) we call this folder `mygame`, but you should of course
name your game whatever you like.
We will create a new "game dir" for you do create your game in. Here (and in
the rest of the Evennia documentation) we refer to this game dir as `mygame`, but you should of course name your game whatever you like.
evennia --init mygame
This will create a new folder `mygame` (or whatever you chose) in your current location. This
contains empty templates and all the default settings needed to start the server.
> The game dir doesn't need to have the exact same name as your game. You can set the name of your game later by editing `mygame/server/conf/settings.py`.
## Start the new game
@ -52,7 +52,7 @@ This will create the default database (Sqlite3). The database file ends up as `m
evennia start
Set your user-name and password when prompted. This will be the "god user" or "superuser" in-game. The email is optional.
Set your user-name and password when prompted. This will be the "god user" or "super user" in-game. The email is optional.
> You can also [automate](./Installation-Non-Interactive.md) the creation of the super user.
@ -76,6 +76,8 @@ Full stop of the server (use `evennia start` to restart):
evennia stop
See [Server start-stop-reload](./Start-Stop-Reload.md) page for more details.
## See server logs
Log files are in `mygame/server/logs`. You can tail them live with
@ -92,21 +94,20 @@ You can start viewing the log immediately by adding `-l/--log` to `evennia` comm
evennia start -l
## Server configuration
The server configuration file is `mygame/server/settings.py`. It's empty by default. Copy and change only the settings you want from the [default settings file](./Settings-Default.md).
The server configuration file is `mygame/server/settings.py`. It's empty by default. Copy and change only the settings you want from the [default settings file](./Settings-Default.md). See the [Settings](./Settings.md) documentation for more info.
## Register with the Evennia Game Index (optional)
You can let the world know that you are working on a new Evennia-based game by
registering your server with the _Evennia game index_. You don't have to be
open for players to do this - you just mark your game as closed and "pre-alpha".
registering your server with the _Evennia game index_.
evennia connections
See [here](./Evennia-Game-Index.md) for more instructions and please [check out the index](http:games.evennia.com)
beforehand to make sure you don't pick a game name that is already taken - be nice!
Just follow the prompts. You don't have to be open for players to do this - you just mark your game as closed and "pre-alpha".
See [here](./Evennia-Game-Index.md) for more instructions and please [check out the index](http:games.evennia.com) beforehand to make sure you don't pick a game name that is already taken - be nice!
## The Next steps

View file

@ -1,4 +1,4 @@
# Game Settings and Configuration direcotry
# Game Settings and Configuration directory
Evennia runs out of the box without any changes to its settings. But there are several important
ways to customize the server and expand it with your own plugins.

View file

@ -2,7 +2,7 @@
This sums up all steps of maintaining your Evennia game from first installation to production release.
## Installation & running
## Installation and running
```{toctree}
:maxdepth: 2
@ -17,7 +17,7 @@ Installation-Non-Interactive
Start-Stop-Reload
```
## Configuring
## Configuration
```{toctree}
:maxdepth: 2

View file

@ -6,7 +6,7 @@ program. If the `evennia` program is not available on the command line you must
Evennia as described on the [Installation](./Installation.md) page.
```{sidebar} evennia not found?
If you ever try the `evennia` command and get an error complaining that the command is not available, make sure your [virtualenv](../Glossary.md#virtualenv) is active.
If you ever try the `evennia` command and get an error complaining that the command is not available, make sure your [virtualenv](../Glossary.md#virtualenv) is active. On Windows you may need to to run `py -m evennia` once first.
```
Below are described the various management options. Run
@ -21,11 +21,7 @@ to give you a menu with options.
## Starting Evennia
Evennia consists of two components, the Evennia [Portal and Server](../Components/Portal-And-Server.md). Briefly,
the *Server* is what is running the mud. It handles all game-specific things but doesn't care
exactly how players connect, only that they have. The *Portal* is a gateway to which players
connect. It knows everything about telnet, ssh, webclient protocols etc but very little about the
game. Both are required for a functioning mud.
Evennia consists of two components, the Evennia [Portal and Server](../Components/Portal-And-Server.md). Briefly, the *Server* is what is running the mud. It handles all game-specific things but doesn't care exactly how players connect, only that they have. The *Portal* is a gateway to which players connect. It knows everything about telnet, ssh, webclient protocols etc but very little about the game. Both are required for a functioning game.
evennia start
@ -37,40 +33,32 @@ Will start following the logs of an already running server. When starting Evenni
evennia start -l
> To stop viewing the log files, press `Ctrl-C`.
> To stop viewing the log files, press `Ctrl-C` (`Cmd-C` on Mac).
## Reloading
The act of *reloading* means the Portal will tell the Server to shut down and then boot it back up
again. Everyone will get a message and the game will be briefly paused for all accounts as the
server
reboots. Since they are connected to the *Portal*, their connections are not lost.
The act of *reloading* means the Portal will tell the Server to shut down and then boot it back up again. Everyone will get a message and the game will be briefly paused for all accounts as the server reboots. Since they are connected to the *Portal*, their connections are not lost.
Reloading is as close to a "warm reboot" you can get. It reinitializes all code of Evennia, but
doesn't kill "persistent" [Scripts](../Components/Scripts.md). It also calls `at_server_reload()` hooks on all
objects so you
can save eventual temporary properties you want.
Reloading is as close to a "warm reboot" you can get. It reinitializes all code of Evennia, but doesn't kill "persistent" [Scripts](../Components/Scripts.md). It also calls `at_server_reload()` hooks on all objects so you can save eventual temporary properties you want.
From in-game the `@reload` command is used. You can also reload the server from outside the game:
From in-game the `reload` command is used. You can also reload the server from outside the game:
evennia reload
Sometimes reloading from "the outside" is necessary in case you have added some sort of bug that
blocks in-game input.
Sometimes reloading from "the outside" is necessary in case you have added some sort of bug that blocks in-game input.
## Stopping
A full shutdown closes Evennia completely, both Server and Portal. All accounts will be booted and
systems saved and turned off cleanly.
From inside the game you initiate a shutdown with the `@shutdown` command. From command line you do
From inside the game you initiate a shutdown with the `shutdown` command. From command line you do
evennia stop
You will see messages of both Server and Portal closing down. All accounts will see the shutdown
message and then be disconnected. The same effect happens if you press `Ctrl+C` while the server
runs in interactive mode.
message and then be disconnected.
## Foreground mode
@ -89,15 +77,14 @@ will start/restart the *Server* in interactive mode. This is required if you wan
will start the *Portal* in interactive mode.
If you do `Ctrl-C`/`Cmd-C` in foreground mode, the component will stop. You'll need to run `evennia start` to get the game going again.
## Resetting
*Resetting* is the equivalent of a "cold reboot" - the Server will shut down and then restarted
again, but will behave as if it was fully shut down. As opposed to a "real" shutdown, no accounts
will be disconnected during a
reset. A reset will however purge all non-persistent scripts and will call `at_server_shutdown()`
hooks. It can be a good way to clean unsafe scripts during development, for example.
again, but will behave as if it was fully shut down. As opposed to a "real" shutdown, no accounts will be disconnected during a reset. A reset will however purge all non-persistent scripts and will call `at_server_shutdown()` hooks. It can be a good way to clean unsafe scripts during development, for example.
From in-game the `@reset` command is used. From the terminal:
From in-game the `reset` command is used. From the terminal:
evennia reset
@ -170,8 +157,7 @@ related to Evennia:
During development, you will usually modify code and then reload the server to see your changes.
This is done by Evennia re-importing your custom modules from disk. Usually bugs in a module will
just have you see a traceback in the game, in the log or on the command line. For some really
serious syntax errors though, your module might not even be recognized as valid Python. Evennia may
then fail to restart correctly.
serious syntax errors though, your module might not even be recognized as valid Python. Evennia may then fail to restart correctly.
From inside the game you see a text about the Server restarting followed by an ever growing list of
"...". Usually this only lasts a very short time (up to a few seconds). If it seems to go on, it

View file

@ -12,6 +12,7 @@ evennia.contrib.rpg
:maxdepth: 6
evennia.contrib.rpg.buffs
evennia.contrib.rpg.character_creator
evennia.contrib.rpg.dice
evennia.contrib.rpg.health_bar
evennia.contrib.rpg.rpsystem

View file

@ -10,17 +10,17 @@
# Evennia Documentation
This is the manual of [Evennia](https://www.evennia.com), the open source Python
`MU*` creation system.
This is the manual of [Evennia](https://www.evennia.com), the open source Python `MU*` creation system. Use the Search bar on the left to find or discover interesting articles.
- [Evennia Introduction](./Evennia-Introduction.md)
- [How to contribute and get help](./Contributing.md)
- [Evennia Introduction](./Evennia-Introduction.md) - what is this?
- [Getting help and Contribute](./Contributing.md) - when you get stuck or want to chip in
## Setup
- [Installation](Setup/Installation.md)
- [Installation and running](Setup/Setup-Overview.md#installation-and-running) - getting started!
- [Starting, Stopping and Reloading](Setup/Start-Stop-Reload.md) - how to manage the Evennia server
- [Configurations](Setup/Setup-Overview.md) - how to run, maintain and release
- [Configuration](Setup/Setup-Overview.md#configuration) - how to set up your server the way you like it
- [Going public](Setup/Setup-Overview.md#going-public) - taking your game online
## Howtos and Tutorials

View file

@ -133,7 +133,7 @@ method. Otherwise all text will be returned to all connected sessions.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.account.CmdOOCLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ls', 'l']</em><a class="headerlink" href="#evennia.commands.default.account.CmdOOCLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'ls']</em><a class="headerlink" href="#evennia.commands.default.account.CmdOOCLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -164,7 +164,7 @@ method. Otherwise all text will be returned to all connected sessions.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.account.CmdOOCLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ls l', 'category': 'general', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n look while out-of-character\n\n Usage:\n look\n\n Look in the ooc state.\n '}</em><a class="headerlink" href="#evennia.commands.default.account.CmdOOCLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l ls', 'category': 'general', 'key': 'look', 'no_prefix': ' l ls', 'tags': '', 'text': '\n look while out-of-character\n\n Usage:\n look\n\n Look in the ooc state.\n '}</em><a class="headerlink" href="#evennia.commands.default.account.CmdOOCLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

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

View file

@ -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;delete', '&#64;del']</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;del', '&#64;delete']</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;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>
<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>
<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;type', '&#64;update', '&#64;swap', '&#64;typeclasses', '&#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;parent', '&#64;type', '&#64;typeclasses', '&#64;swap', '&#64;update']</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;type &#64;update &#64;swap &#64;typeclasses &#64;parent', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass type update swap typeclasses 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;parent &#64;type &#64;typeclasses &#64;swap &#64;update', 'category': 'building', 'key': '&#64;typeclass', 'no_prefix': 'typeclass parent type typeclasses swap update', 'tags': '', 'text': &quot;\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] &lt;object&gt; [= typeclass.path]\n typeclass/prototype &lt;object&gt; = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object. This will also\n reset cmdsets!\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.building.CmdTypeclass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -1531,7 +1531,7 @@ If object is not specified, the current location is examined.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdExamine.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;exam', '&#64;ex']</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;ex', '&#64;exam']</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -1799,7 +1799,7 @@ the cases, see the module doc.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdExamine.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;exam &#64;ex', 'category': 'building', 'key': '&#64;examine', 'no_prefix': 'examine exam ex', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [&lt;object&gt;[/attrname]]\n examine [*&lt;account&gt;[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n script - examine a Script\n channel - examine a Channel\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;ex &#64;exam', 'category': 'building', 'key': '&#64;examine', 'no_prefix': 'examine ex exam', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [&lt;object&gt;[/attrname]]\n examine [*&lt;account&gt;[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n script - examine a Script\n channel - examine a Channel\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdExamine.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -1833,7 +1833,7 @@ one is given.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdFind.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;search', '&#64;locate']</em><a class="headerlink" href="#evennia.commands.default.building.CmdFind.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;locate', '&#64;search']</em><a class="headerlink" href="#evennia.commands.default.building.CmdFind.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -1864,7 +1864,7 @@ one is given.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.building.CmdFind.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;search &#64;locate', 'category': 'building', 'key': '&#64;find', 'no_prefix': 'find search locate', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] &lt;name or dbref or *account&gt; [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdFind.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;locate &#64;search', 'category': 'building', 'key': '&#64;find', 'no_prefix': 'find locate search', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] &lt;name or dbref or *account&gt; [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}</em><a class="headerlink" href="#evennia.commands.default.building.CmdFind.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -175,7 +175,7 @@ look <a href="#id1"><span class="problematic" id="id2">*</span></a>&lt;account&g
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ls', 'l']</em><a class="headerlink" href="#evennia.commands.default.general.CmdLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'ls']</em><a class="headerlink" href="#evennia.commands.default.general.CmdLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -206,7 +206,7 @@ look <a href="#id1"><span class="problematic" id="id2">*</span></a>&lt;account&g
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ls l', 'category': 'general', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n look at location or object\n\n Usage:\n look\n look &lt;obj&gt;\n look *&lt;account&gt;\n\n Observes your location or objects in your vicinity.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l ls', 'category': 'general', 'key': 'look', 'no_prefix': ' l ls', 'tags': '', 'text': '\n look at location or object\n\n Usage:\n look\n look &lt;obj&gt;\n look *&lt;account&gt;\n\n Observes your location or objects in your vicinity.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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>
@ -323,7 +323,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdInventory.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['i', 'inv']</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['inv', 'i']</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -354,7 +354,7 @@ inv</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdInventory.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'no_prefix': ' i inv', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'no_prefix': ' inv i', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}</em><a class="headerlink" href="#evennia.commands.default.general.CmdInventory.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -709,7 +709,7 @@ automatically begin with your name.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdPose.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = [':', 'emote']</em><a class="headerlink" href="#evennia.commands.default.general.CmdPose.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['emote', ':']</em><a class="headerlink" href="#evennia.commands.default.general.CmdPose.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -750,7 +750,7 @@ space.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.general.CmdPose.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': ': emote', 'category': 'general', 'key': 'pose', 'no_prefix': ' : emote', 'tags': '', 'text': &quot;\n strike a pose\n\n Usage:\n pose &lt;pose text&gt;\n pose's &lt;pose text&gt;\n\n Example:\n pose is standing by the wall, smiling.\n -&gt; others will see:\n Tom is standing by the wall, smiling.\n\n Describe an action being taken. The pose text will\n automatically begin with your name.\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.general.CmdPose.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'emote :', 'category': 'general', 'key': 'pose', 'no_prefix': ' emote :', 'tags': '', 'text': &quot;\n strike a pose\n\n Usage:\n pose &lt;pose text&gt;\n pose's &lt;pose text&gt;\n\n Example:\n pose is standing by the wall, smiling.\n -&gt; others will see:\n Tom is standing by the wall, smiling.\n\n Describe an action being taken. The pose text will\n automatically begin with your name.\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.general.CmdPose.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

@ -683,7 +683,7 @@ See <a href="#id11"><span class="problematic" id="id12">|</span></a>luhttps://ww
<dl class="py attribute">
<dt id="evennia.commands.default.system.CmdTasks.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;task', '&#64;delays']</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['&#64;delays', '&#64;task']</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -729,7 +729,7 @@ to all the variables defined therein.</p>
<dl class="py attribute">
<dt id="evennia.commands.default.system.CmdTasks.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;task &#64;delays', 'category': 'system', 'key': '&#64;tasks', 'no_prefix': 'tasks task delays', 'tags': '', 'text': &quot;\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': '&#64;delays &#64;task', 'category': 'system', 'key': '&#64;tasks', 'no_prefix': 'tasks delays task', 'tags': '', 'text': &quot;\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n &quot;}</em><a class="headerlink" href="#evennia.commands.default.system.CmdTasks.search_index_entry" title="Permalink to this definition"></a></dt>
<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/tmpaa0y5s35/c75708a32c127fef812251e37f6506a15825f2e9/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/tmpw1d9jjt9/d1ddb80b222c7a337b18ad288cb9b4ee670e0959/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', 'co', 'conn']</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"> = ['co', 'conn', 'con']</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -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 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>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'co conn con', 'category': 'general', 'key': 'connect', 'no_prefix': ' co conn con', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect &quot;account name&quot; &quot;pass word&quot;\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}</em><a class="headerlink" href="#evennia.commands.default.unloggedin.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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', 'co', 'conn']</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"> = ['co', 'conn', 'con']</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -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 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>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'co conn con', 'category': 'general', 'key': 'connect', 'no_prefix': ' co conn con', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect &lt;email&gt; &lt;password&gt;\n\n Use the create command to first create an account before logging in.\n '}</em><a class="headerlink" href="#evennia.contrib.base_systems.email_login.email_login.CmdUnconnectedConnect.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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

@ -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"> = ['chicken out', 'q', 'quit', 'abort']</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"> = ['abort', 'quit', 'q', 'chicken out']</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': 'chicken out q quit abort', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' chicken out q quit abort', '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': 'abort quit q chicken out', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' abort quit q chicken out', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdGiveUp.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -256,7 +256,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ls', 'l']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'ls']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -290,7 +290,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ls l', 'category': 'evscaperoom', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n Look at the room, an object or the currently focused object\n\n Usage:\n look [obj]\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l ls', 'category': 'evscaperoom', 'key': 'look', 'no_prefix': ' l ls', 'tags': '', 'text': '\n Look at the room, an object or the currently focused object\n\n Usage:\n look [obj]\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdLook.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>
@ -428,7 +428,7 @@ emote /me points to /box and /lever.</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = [':', 'pose']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['pose', ':']</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -467,7 +467,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': ': pose', 'category': 'general', 'key': 'emote', 'no_prefix': ' : pose', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use &quot;...&quot; to enact speech.\n\n Usage:\n emote &lt;emote&gt;\n :&lt;emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'pose :', 'category': 'general', 'key': 'emote', 'no_prefix': ' pose :', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use &quot;...&quot; to enact speech.\n\n Usage:\n emote &lt;emote&gt;\n :&lt;emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}</em><a class="headerlink" href="#evennia.contrib.full_systems.evscaperoom.commands.CmdEmote.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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"> = ['ex', 'unfocus', 'e', '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"> = ['e', 'unfocus', 'examine', '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': 'ex unfocus e examine', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' ex unfocus e 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': 'e unfocus examine ex', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' e unfocus examine 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"> = ['i', 'inventory', 'inv', '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"> = ['give', 'inv', 'i', 'inventory']</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': 'i inventory inv give', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' i inventory inv 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': 'give inv i inventory', 'category': 'evscaperoom', 'key': 'get', 'no_prefix': ' give inv i inventory', '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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -340,7 +340,7 @@ look <a href="#id1"><span class="problematic" id="id2">*</span></a>&lt;account&g
<dl class="py attribute">
<dt id="evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ls', 'l']</em><a class="headerlink" href="#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'ls']</em><a class="headerlink" href="#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -360,7 +360,7 @@ look <a href="#id1"><span class="problematic" id="id2">*</span></a>&lt;account&g
<dl class="py attribute">
<dt id="evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ls l', 'category': 'general', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n look\n\n Usage:\n look\n look &lt;obj&gt;\n look &lt;room detail&gt;\n look *&lt;account&gt;\n\n Observes your location, details at your location or objects in your vicinity.\n '}</em><a class="headerlink" href="#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l ls', 'category': 'general', 'key': 'look', 'no_prefix': ' l ls', 'tags': '', 'text': '\n look\n\n Usage:\n look\n look &lt;obj&gt;\n look &lt;room detail&gt;\n look *&lt;account&gt;\n\n Observes your location, details at your location or objects in your vicinity.\n '}</em><a class="headerlink" href="#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.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"> = ['roll', '&#64;dice']</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"> = ['&#64;dice', 'roll']</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': '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>
<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>
<dd></dd></dl>
</dd></dl>

View file

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

View file

@ -153,7 +153,7 @@ such as when closing the lid and un-blinding a character.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['press button', 'press', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['press', 'press button', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -182,7 +182,7 @@ check if the lid is open or closed.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press button press push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press button press push', 'tags': '', 'text': '\n Push the red button (lid closed)\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press press button push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press press button push', 'tags': '', 'text': '\n Push the red button (lid closed)\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidClosed.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -252,7 +252,7 @@ check if the lid is open or closed.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['smash lid', 'break lid', 'smash']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['smash', 'break lid', 'smash lid']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -279,7 +279,7 @@ break.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'smash lid break lid smash', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' smash lid break lid smash', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'smash break lid smash lid', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' smash break lid smash lid', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdSmashGlass.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -379,7 +379,7 @@ be mutually exclusive.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['press button', 'press', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['press', 'press button', 'push']</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -408,7 +408,7 @@ set in self.parse())</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press button press push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press button press push', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'press press button push', 'category': 'general', 'key': 'push button', 'no_prefix': ' press press button push', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.red_button.red_button.CmdPushLidOpen.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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"> = ['get', 'ex', 'feel', 'examine', 'l', 'listen']</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"> = ['feel', 'l', 'examine', 'get', 'listen', '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': 'get ex feel examine l listen', 'category': 'general', 'key': 'look', 'no_prefix': ' get ex feel examine l listen', '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': 'feel l examine get listen ex', 'category': 'general', 'key': 'look', 'no_prefix': ' feel l examine get listen 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

@ -425,7 +425,7 @@ of the object. We overload it with our own version.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['burn', 'light']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['light', 'burn']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -452,7 +452,7 @@ to sit on a “lightable” object, we operate only on self.obj.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'burn light', 'category': 'tutorialworld', 'key': 'on', 'no_prefix': ' burn light', 'tags': '', 'text': '\n Creates light where there was none. Something to burn.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'light burn', 'category': 'tutorialworld', 'key': 'on', 'no_prefix': ' light burn', 'tags': '', 'text': '\n Creates light where there was none. Something to burn.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.objects.CmdLight.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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"> = ['pull', 'shiftroot', 'move', 'push']</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"> = ['move', 'shiftroot', 'pull', 'push']</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': 'pull shiftroot move push', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' pull shiftroot move push', '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': 'move shiftroot pull push', 'category': 'tutorialworld', 'key': 'shift', 'no_prefix': ' move shiftroot pull push', '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"> = ['pierce', 'hit', 'bash', 'defend', 'thrust', 'chop', 'slash', 'stab', 'fight', 'parry', '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"> = ['fight', 'defend', 'parry', 'hit', 'slash', 'thrust', 'kill', 'chop', 'stab', 'bash', 'pierce']</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': 'pierce hit bash defend thrust chop slash stab fight parry kill', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' pierce hit bash defend thrust chop slash stab fight parry 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': 'fight defend parry hit slash thrust kill chop stab bash pierce', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' fight defend parry hit slash thrust kill chop stab bash pierce', '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

@ -248,7 +248,7 @@ code except for adding in the details.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.aliases">
<code class="sig-name descname">aliases</code><em class="property"> = ['ls', 'l']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.aliases" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">aliases</code><em class="property"> = ['l', 'ls']</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.aliases" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
@ -263,7 +263,7 @@ code except for adding in the details.</p>
<dl class="py attribute">
<dt id="evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.search_index_entry">
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'ls l', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n looks at the room and on details\n\n Usage:\n look &lt;obj&gt;\n look &lt;room detail&gt;\n look *&lt;account&gt;\n\n Observes your location, details at your location or objects\n in your vicinity.\n\n Tutorial: This is a child of the default Look command, that also\n allows us to look at &quot;details&quot; in the room. These details are\n things to examine and offers some extra description without\n actually having to be actual database objects. It uses the\n return_detail() hook on TutorialRooms for this.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'l ls', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' l ls', 'tags': '', 'text': '\n looks at the room and on details\n\n Usage:\n look &lt;obj&gt;\n look &lt;room detail&gt;\n look *&lt;account&gt;\n\n Observes your location, details at your location or objects\n in your vicinity.\n\n Tutorial: This is a child of the default Look command, that also\n allows us to look at &quot;details&quot; in the room. These details are\n things to examine and offers some extra description without\n actually having to be actual database objects. It uses the\n return_detail() hook on TutorialRooms for this.\n '}</em><a class="headerlink" href="#evennia.contrib.tutorials.tutorial_world.rooms.CmdTutorialLook.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
@ -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"> = ['feel around', 'search', 'fiddle', 'feel', 'l']</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', 'fiddle', 'search', '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': 'feel around search fiddle feel l', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' feel around search fiddle feel l', '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 fiddle search feel around', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' feel l fiddle search 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/tmpaa0y5s35/c75708a32c127fef812251e37f6506a15825f2e9/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/tmpw1d9jjt9/d1ddb80b222c7a337b18ad288cb9b4ee670e0959/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/tmpaa0y5s35/c75708a32c127fef812251e37f6506a15825f2e9/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/tmpw1d9jjt9/d1ddb80b222c7a337b18ad288cb9b4ee670e0959/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"> = [':fd', ':dd', ':w', ':j', ':u', ':I', ':i', ':&gt;', ':q', ':r', ':=', ':wq', ':DD', ':q!', ':&lt;', ':h', ':fi', ':S', ':UU', ':uu', ':dw', ':x', ':y', ':', ':s', ':::', '::', ':A', ':p', ':!', ':echo', ':f']</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', ':u', ':x', ':i', ':uu', ':S', ':w', ':I', ':', ':echo', ':=', ':h', ':p', ':::', ':y', ':fi', ':q', ':j', ':f', '::', ':dw', ':q!', ':dd', ':UU', ':&gt;', ':r', ':A', ':&lt;', ':!', ':s', ':fd', ':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': ':fd :dd :w :j :u :I :i :&gt; :q :r := :wq :DD :q! :&lt; :h :fi :S :UU :uu :dw :x :y : :s ::: :: :A :p :! :echo :f', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :fd :dd :w :j :u :I :i :&gt; :q :r := :wq :DD :q! :&lt; :h :fi :S :UU :uu :dw :x :y : :s ::: :: :A :p :! :echo :f', '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 :u :x :i :uu :S :w :I : :echo := :h :p ::: :y :fi :q :j :f :: :dw :q! :dd :UU :&gt; :r :A :&lt; :! :s :fd :DD', 'category': 'general', 'key': ':editor_command_group', 'no_prefix': ' :wq :u :x :i :uu :S :w :I : :echo := :h :p ::: :y :fi :q :j :f :: :dw :q! :dd :UU :&gt; :r :A :&lt; :! :s :fd :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"> = ['no', 'n', 'y', 'a', '__nomatch_command', 'yes', 'abort']</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', 'no', 'n', 'abort', 'y', 'a', '__nomatch_command']</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': 'no n y a __nomatch_command yes abort', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' no n y a __nomatch_command yes abort', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}</em><a class="headerlink" href="#evennia.utils.evmenu.CmdYesNoQuestion.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'yes no n abort y a __nomatch_command', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' yes no n abort y a __nomatch_command', '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"> = ['t', 'quit', 'previous', 'end', 'n', 'next', 'p', 'a', 'e', 'top', 'q', 'abort']</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"> = ['quit', 'q', 'n', 'end', 'e', 'next', 't', 'top', 'abort', 'p', 'a', 'previous']</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': 't quit previous end n next p a e top q abort', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' t quit previous end n next p a e top q abort', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.search_index_entry" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">search_index_entry</code><em class="property"> = {'aliases': 'quit q n end e next t top abort p a previous', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' quit q n end e next t top abort p a previous', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}</em><a class="headerlink" href="#evennia.utils.evmore.CmdMore.search_index_entry" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>

View file

@ -111,18 +111,18 @@ or the original github wiki. You have been warned.</p>
</div>
<section class="tex2jax_ignore mathjax_ignore" id="evennia-documentation">
<h1>Evennia Documentation<a class="headerlink" href="#evennia-documentation" title="Permalink to this headline"></a></h1>
<p>This is the manual of <a class="reference external" href="https://www.evennia.com">Evennia</a>, the open source Python
<code class="docutils literal notranslate"><span class="pre">MU*</span></code> creation system.</p>
<p>This is the manual of <a class="reference external" href="https://www.evennia.com">Evennia</a>, the open source Python <code class="docutils literal notranslate"><span class="pre">MU*</span></code> creation system. Use the Search bar on the left to find or discover interesting articles.</p>
<ul class="simple">
<li><p><a class="reference internal" href="Evennia-Introduction.html"><span class="doc std std-doc">Evennia Introduction</span></a></p></li>
<li><p><a class="reference internal" href="Contributing.html"><span class="doc std std-doc">How to contribute and get help</span></a></p></li>
<li><p><a class="reference internal" href="Evennia-Introduction.html"><span class="doc std std-doc">Evennia Introduction</span></a> - what is this?</p></li>
<li><p><a class="reference internal" href="Contributing.html"><span class="doc std std-doc">Getting help and Contribute</span></a> - when you get stuck or want to chip in</p></li>
</ul>
<section id="setup">
<h2>Setup<a class="headerlink" href="#setup" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><a class="reference internal" href="Setup/Installation.html"><span class="doc std std-doc">Installation</span></a></p></li>
<li><p><a class="reference internal" href="Setup/Setup-Overview.html#installation-and-running"><span class="std std-doc">Installation and running</span></a> - getting started!</p></li>
<li><p><a class="reference internal" href="Setup/Start-Stop-Reload.html"><span class="doc std std-doc">Starting, Stopping and Reloading</span></a> - how to manage the Evennia server</p></li>
<li><p><a class="reference internal" href="Setup/Setup-Overview.html"><span class="doc std std-doc">Configurations</span></a> - how to run, maintain and release</p></li>
<li><p><a class="reference internal" href="Setup/Setup-Overview.html#configuration"><span class="std std-doc">Configuration</span></a> - how to set up your server the way you like it</p></li>
<li><p><a class="reference internal" href="Setup/Setup-Overview.html#going-public"><span class="std std-doc">Going public</span></a> - taking your game online</p></li>
</ul>
</section>
<section id="howtos-and-tutorials">
@ -166,13 +166,13 @@ or the original github wiki. You have been warned.</p>
<li class="toctree-l3"><a class="reference internal" href="Evennia-Introduction.html#i-dont-know-or-dont-want-to-do-any-programming-i-just-want-to-run-a-game">I dont know (or dont want to do) any programming - I just want to run a game!</a></li>
<li class="toctree-l3"><a class="reference internal" href="Evennia-Introduction.html#i-know-basic-python-or-i-am-willing-to-learn">I know basic Python, or I am willing to learn</a></li>
<li class="toctree-l3"><a class="reference internal" href="Evennia-Introduction.html#i-know-my-python-stuff-and-i-am-willing-to-use-it">I know my Python stuff and I am willing to use it!</a></li>
<li class="toctree-l3"><a class="reference internal" href="Evennia-Introduction.html#where-to-from-here">Where to from here?</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Evennia-Introduction.html#where-to-from-here">Where to from here?</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Setup/Setup-Overview.html">Server Setup and Life</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Setup/Setup-Overview.html#installation-running">Installation &amp; running</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Setup/Setup-Overview.html#installation-and-running">Installation and running</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Setup/Installation.html">Installation</a></li>
<li class="toctree-l3"><a class="reference internal" href="Setup/Installation-Git.html">Installing with GIT</a></li>
<li class="toctree-l3"><a class="reference internal" href="Setup/Installation-Docker.html">Installing with Docker</a></li>
@ -183,8 +183,8 @@ or the original github wiki. You have been warned.</p>
<li class="toctree-l3"><a class="reference internal" href="Setup/Start-Stop-Reload.html">Start Stop Reload</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Setup/Setup-Overview.html#configuring">Configuring</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Setup/Settings.html">Game Settings and Configuration direcotry</a></li>
<li class="toctree-l2"><a class="reference internal" href="Setup/Setup-Overview.html#configuration">Configuration</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Setup/Settings.html">Game Settings and Configuration directory</a></li>
<li class="toctree-l3"><a class="reference internal" href="Setup/Settings-Default.html">Evennia Default settings file</a></li>
<li class="toctree-l3"><a class="reference internal" href="Setup/Choosing-An-SQL-Server.html">Choosing An SQL Server</a></li>
<li class="toctree-l3"><a class="reference internal" href="Setup/Evennia-Game-Index.html">Evennia Game Index</a></li>
@ -271,7 +271,7 @@ or the original github wiki. You have been warned.</p>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Components/Components-Overview.html">Core Components</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#database-entites">Database entites</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#basic-entites">Basic entites</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Components/Typeclasses.html">Typeclasses</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Sessions.html">Sessions</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Accounts.html">Accounts</a></li>
@ -285,6 +285,7 @@ or the original github wiki. You have been warned.</p>
<li class="toctree-l3"><a class="reference internal" href="Components/Prototypes.html">Spawner and Prototypes</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Help-System.html">Help System</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Permissions.html">Permissions</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Portal-And-Server.html">Portal And Server</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#commands">Commands</a><ul>
@ -296,6 +297,8 @@ or the original github wiki. You have been warned.</p>
<li class="toctree-l3"><a class="reference internal" href="Components/Batch-Processors.html">Batch Processors</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Batch-Code-Processor.html">Batch Code Processor</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Batch-Command-Processor.html">Batch Command Processor</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Inputfuncs.html">Inputfuncs</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Outputfuncs.html">Outputfuncs</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#utils-and-tools">Utils and tools</a><ul>
@ -314,25 +317,11 @@ or the original github wiki. You have been warned.</p>
</li>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#web-components">Web components</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Components/Website.html">Game website</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Web-API.html">Evennia REST API</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Web-Admin.html">The Web Admin</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Components/Components-Overview.html#server-and-network">Server and network</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Components/Portal-And-Server.html">Portal And Server</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Inputfuncs.html">Inputfuncs</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Outputfuncs.html">Outputfuncs</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Server.html">Server component</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webserver.html">Webserver</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html">Web Client</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#evennia-web-client-api-from-evennia-js">Evennia Web Client API (from evennia.js)</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#plugin-manager-api-from-webclient-gui-js">Plugin Manager API (from webclient_gui.js)</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#plugin-callbacks-api">Plugin callbacks API</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#example-default-plugins-plugins-js">Example/Default Plugins (plugins/*.js)</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#a-side-note-on-html-messages-vrs-text2html-messages">A side note on html messages vrs text2html messages</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webclient.html#writing-your-own-plugins">Writing your own Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Web-Admin.html">The Web Admin</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Webserver.html">Webserver</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Web-API.html">Evennia REST API</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Bootstrap-Components-and-Utilities.html">Bootstrap Components and Utilities</a></li>
<li class="toctree-l3"><a class="reference internal" href="Components/Signals.html">Signals</a></li>
</ul>
</li>
</ul>
@ -479,7 +468,7 @@ or the original github wiki. You have been warned.</p>
</li>
<li class="toctree-l2"><a class="reference internal" href="Contribs/Contribs-Overview.html#rpg">rpg</a><ul>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-Buffs.html">Buffs</a></li>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-Character-Creator.html">Character Creator contrib</a></li>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-Character-Creator.html">Character Creator</a></li>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-Dice.html">Dice roller</a></li>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-Health-Bar.html">Health Bar</a></li>
<li class="toctree-l3"><a class="reference internal" href="Contribs/Contrib-RPSystem.html">Roleplaying base system for Evennia</a></li>

Binary file not shown.

File diff suppressed because one or more lines are too long