Add legacy 2.x docs

This commit is contained in:
Griatch 2023-12-20 18:06:19 +01:00
parent df0a1a4f59
commit 07cfac0bfa
2288 changed files with 531353 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,253 @@
<!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>Coding and development help &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Evennia Code Style" href="Evennia-Code-Style.html" />
<link rel="prev" title="Zones" href="../Concepts/Zones.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Evennia-Code-Style.html" title="Evennia Code Style"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../Concepts/Zones.html" title="Zones"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Coding and development help</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Coding and development help</a><ul>
<li><a class="reference internal" href="#evennia-changelog">Evennia Changelog</a><ul>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="../Concepts/Zones.html"
title="previous chapter">Zones</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Evennia-Code-Style.html"
title="next chapter">Evennia Code Style</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Coding-Overview.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="coding-and-development-help">
<h1>Coding and development help<a class="headerlink" href="#coding-and-development-help" title="Permalink to this headline"></a></h1>
<p>This documentation aims to help you set up a sane development environment to
make your game, also if you never coded before.</p>
<p>See also the <a class="reference internal" href="../Howtos/Beginner-Tutorial/Beginner-Tutorial-Overview.html"><span class="doc std std-doc">Beginner Tutorial</span></a>.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Evennia-Code-Style.html">Evennia Code Style</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Evennia-Code-Style.html#main-code-style-specification">Main code style specification</a></li>
<li class="toctree-l2"><a class="reference internal" href="Evennia-Code-Style.html#code-docstrings">Code Docstrings</a></li>
<li class="toctree-l2"><a class="reference internal" href="Evennia-Code-Style.html#default-command-docstrings">Default Command Docstrings</a></li>
<li class="toctree-l2"><a class="reference internal" href="Evennia-Code-Style.html#tools-for-auto-linting">Tools for auto-linting</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Default-Command-Syntax.html">Default Command Syntax</a></li>
<li class="toctree-l1"><a class="reference internal" href="Version-Control.html">Coding using Version Control</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Version-Control.html#setting-up-git">Setting up Git</a></li>
<li class="toctree-l2"><a class="reference internal" href="Version-Control.html#common-git-commands">Common Git commands</a></li>
<li class="toctree-l2"><a class="reference internal" href="Version-Control.html#putting-your-game-dir-under-version-control">Putting your game dir under version control</a></li>
<li class="toctree-l2"><a class="reference internal" href="Version-Control.html#contributing-to-evennia">Contributing to Evennia</a></li>
<li class="toctree-l2"><a class="reference internal" href="Version-Control.html#troubleshooting">Troubleshooting</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Debugging.html">Debugging</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Debugging.html#debugging-evennia">Debugging Evennia</a></li>
<li class="toctree-l2"><a class="reference internal" href="Debugging.html#a-simple-example-using-pdb">A simple example using pdb</a></li>
<li class="toctree-l2"><a class="reference internal" href="Debugging.html#cheat-sheet-of-pdb-pudb-commands">Cheat-sheet of pdb/pudb commands</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Unit-Testing.html">Unit Testing</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Unit-Testing.html#running-the-evennia-test-suite">Running the Evennia test suite</a></li>
<li class="toctree-l2"><a class="reference internal" href="Unit-Testing.html#running-custom-game-dir-unit-tests">Running custom game-dir unit tests</a></li>
<li class="toctree-l2"><a class="reference internal" href="Unit-Testing.html#writing-new-unit-tests">Writing new unit tests</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Profiling.html">Profiling</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Profiling.html#simple-timer-tests">Simple timer tests</a></li>
<li class="toctree-l2"><a class="reference internal" href="Profiling.html#using-cprofile">Using cProfile</a></li>
<li class="toctree-l2"><a class="reference internal" href="Profiling.html#the-dummyrunner">The Dummyrunner</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Continuous-Integration.html">Continuous Integration (CI)</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Continuous-Integration.html#continuous-integration-guides">Continuous-Integration guides</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Setting-up-PyCharm.html">Setting up PyCharm with Evennia</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Setting-up-PyCharm.html#debug-evennia-from-inside-pycharm">Debug Evennia from inside PyCharm</a></li>
<li class="toctree-l2"><a class="reference internal" href="Setting-up-PyCharm.html#run-evennia-from-inside-pycharm">Run Evennia from inside PyCharm</a></li>
</ul>
</li>
</ul>
</div>
<section id="evennia-changelog">
<h2>Evennia Changelog<a class="headerlink" href="#evennia-changelog" title="Permalink to this headline"></a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Changelog.html">Changelog</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#main-branch">Main branch</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-2-3-0">Evennia 2.3.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-2-2-0">Evennia 2.2.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-2-1-0">Evennia 2.1.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-2-0-1">Evennia 2.0.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-2-0-0">Evennia 2.0.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-3-0">Evennia 1.3.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-2-1">Evennia 1.2.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-2-0">Evennia 1.2.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-1-1">Evennia 1.1.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-1-0">Evennia 1.1.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-0-2">Evennia 1.0.2</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-0-1">Evennia 1.0.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-1-0-0">Evennia 1.0.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-0-9-5">Evennia 0.9.5</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-0-9">Evennia 0.9</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#evennia-0-8">Evennia 0.8</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Changelog.html#overview-changelogs">Overview-Changelogs</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#sept-2017">Sept 2017:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#feb-2017">Feb 2017:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#dec-2016">Dec 2016:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#may-2016">May 2016:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#feb-2016">Feb 2016:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#sept-2015">Sept 2015:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#feb-2015">Feb 2015:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#sept-2014">Sept 2014:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#jan-2014">Jan 2014:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#nov-2013">Nov 2013:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#may-2013">May 2013:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#oct-2012">Oct 2012:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#march-2012">March 2012:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#nov-2011">Nov 2011:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#aug-2011">Aug 2011:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#may-2011">May 2011:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#aug-2010">Aug 2010:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#may-2010">May 2010:</a></li>
<li class="toctree-l2"><a class="reference internal" href="Changelog.html#april-2010">April 2010:</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Changelog.html#older">Older</a></li>
</ul>
</div>
<div class="toctree-wrapper compound">
</div>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Evennia-Code-Style.html" title="Evennia Code Style"
>next</a> |</li>
<li class="right" >
<a href="../Concepts/Zones.html" title="Zones"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Coding and development help</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,166 @@
<!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>Continuous Integration (CI) &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Setting up PyCharm with Evennia" href="Setting-up-PyCharm.html" />
<link rel="prev" title="Profiling" href="Profiling.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Setting-up-PyCharm.html" title="Setting up PyCharm with Evennia"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Profiling.html" title="Profiling"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Continuous Integration (CI)</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Continuous Integration (CI)</a><ul>
<li><a class="reference internal" href="#continuous-integration-guides">Continuous-Integration guides</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Profiling.html"
title="previous chapter">Profiling</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Setting-up-PyCharm.html"
title="next chapter">Setting up PyCharm with Evennia</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Continuous-Integration.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="continuous-integration-ci">
<h1>Continuous Integration (CI)<a class="headerlink" href="#continuous-integration-ci" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Continuous_integration">Continuous Integration (CI)</a> is a development practice that requires developers to integrate code into a shared repository. Each check-in is then verified by an automated build, allowing teams to detect problems early. This can be set up to safely deploy data to a production server only after tests have passed, for example.</p>
<p>For Evennia, continuous integration allows an automated build process to:</p>
<ul class="simple">
<li><p>Pull down a latest build from Source Control.</p></li>
<li><p>Run migrations on the backing SQL database.</p></li>
<li><p>Automate additional unique tasks for that project.</p></li>
<li><p>Run unit tests.</p></li>
<li><p>Publish those files to the server directory</p></li>
<li><p>Reload the game.</p></li>
</ul>
<section id="continuous-integration-guides">
<h2>Continuous-Integration guides<a class="headerlink" href="#continuous-integration-guides" title="Permalink to this headline"></a></h2>
<p>Evennia itself is making heavy use of <a class="reference external" href="https://github.com/features/actions">github actions</a>. This is integrated with Github and is probably the one to go for most people, especially if your code is on Github already. You can see and analyze how Evennias actions are running <a class="reference external" href="https://github.com/evennia/evennia/actions">here</a>.</p>
<p>There are however a lot of tools and services providing CI functionality. <a class="reference external" href="https://www.atlassian.com/continuous-delivery/continuous-integration/tools">Here is a blog overview</a> (external link).</p>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Setting-up-PyCharm.html" title="Setting up PyCharm with Evennia"
>next</a> |</li>
<li class="right" >
<a href="Profiling.html" title="Profiling"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Continuous Integration (CI)</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,398 @@
<!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>Debugging &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Unit Testing" href="Unit-Testing.html" />
<link rel="prev" title="Coding using Version Control" href="Version-Control.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Unit-Testing.html" title="Unit Testing"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Version-Control.html" title="Coding using Version Control"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Debugging</a><ul>
<li><a class="reference internal" href="#debugging-evennia">Debugging Evennia</a></li>
<li><a class="reference internal" href="#a-simple-example-using-pdb">A simple example using pdb</a><ul>
<li><a class="reference internal" href="#listing-surrounding-lines-of-code">Listing surrounding lines of code</a></li>
<li><a class="reference internal" href="#examining-variables">Examining variables</a></li>
<li><a class="reference internal" href="#executing-the-current-line">Executing the current line</a></li>
<li><a class="reference internal" href="#letting-the-program-run">Letting the program run</a></li>
</ul>
</li>
<li><a class="reference internal" href="#cheat-sheet-of-pdb-pudb-commands">Cheat-sheet of pdb/pudb commands</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Version-Control.html"
title="previous chapter">Coding using Version Control</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Unit-Testing.html"
title="next chapter">Unit Testing</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Debugging.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="debugging">
<h1>Debugging<a class="headerlink" href="#debugging" title="Permalink to this headline"></a></h1>
<p>Sometimes, an error is not trivial to resolve. A few simple <code class="docutils literal notranslate"><span class="pre">print</span></code> statements is not enough to find the cause of the issue. The traceback is not informative or even non-existing.</p>
<p>Running a <em>debugger</em> can then be very helpful and save a lot of time. Debugging means running Evennia under control of a special <em>debugger</em> program. This allows you to stop the action at a given point, view the current state and step forward through the program to see how its logic works.</p>
<p>Evennia natively supports these debuggers:</p>
<ul class="simple">
<li><p><a class="reference external" href="https://docs.python.org/2/library/pdb.html">Pdb</a> is a part of the Python distribution and
available out-of-the-box.</p></li>
<li><p><a class="reference external" href="https://pypi.org/project/pudb/">PuDB</a> is a third-party debugger that has a slightly more
graphical, curses-based user interface than pdb. It is installed with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">pudb</span></code>.</p></li>
</ul>
<section id="debugging-evennia">
<h2>Debugging Evennia<a class="headerlink" href="#debugging-evennia" title="Permalink to this headline"></a></h2>
<p>To run Evennia with the debugger, follow these steps:</p>
<ol>
<li><p>Find the point in the code where you want to have more insight. Add the following line at that
point.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span><span class="n">set_trace</span><span class="p">()</span>
</pre></div>
</div>
</li>
<li><p>(Re-)start Evennia in interactive (foreground) mode with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code>. This is important - without this step the debugger will not start correctly - it will start in this interactive terminal.</p></li>
<li><p>Perform the steps that will trigger the line where you added the <code class="docutils literal notranslate"><span class="pre">set_trace()</span></code> call. The debugger will start in the terminal from which Evennia was interactively started.</p></li>
</ol>
<p>The <code class="docutils literal notranslate"><span class="pre">evennia.set_trace</span></code> function takes the following arguments:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span><span class="o">.</span><span class="n">set_trace</span><span class="p">(</span><span class="n">debugger</span><span class="o">=</span><span class="s1">&#39;auto&#39;</span><span class="p">,</span> <span class="n">term_size</span><span class="o">=</span><span class="p">(</span><span class="mi">140</span><span class="p">,</span> <span class="mi">40</span><span class="p">))</span>
</pre></div>
</div>
<p>Here, <code class="docutils literal notranslate"><span class="pre">debugger</span></code> is one of <code class="docutils literal notranslate"><span class="pre">pdb</span></code>, <code class="docutils literal notranslate"><span class="pre">pudb</span></code> or <code class="docutils literal notranslate"><span class="pre">auto</span></code>. If <code class="docutils literal notranslate"><span class="pre">auto</span></code>, use <code class="docutils literal notranslate"><span class="pre">pudb</span></code> if available, otherwise use <code class="docutils literal notranslate"><span class="pre">pdb</span></code>. The <code class="docutils literal notranslate"><span class="pre">term_size</span></code> tuple sets the viewport size for <code class="docutils literal notranslate"><span class="pre">pudb</span></code> only (its ignored by <code class="docutils literal notranslate"><span class="pre">pdb</span></code>).</p>
</section>
<section id="a-simple-example-using-pdb">
<h2>A simple example using pdb<a class="headerlink" href="#a-simple-example-using-pdb" title="Permalink to this headline"></a></h2>
<p>The debugger is useful in different cases, but to begin with, lets see it working in a command.
Add the following test command (which has a range of deliberate errors) and also add it to your
default cmdset. Then restart Evennia in interactive mode with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># In file commands/command.py</span>
<span class="k">class</span> <span class="nc">CmdTest</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A test command just to test pdb.</span>
<span class="sd"> Usage:</span>
<span class="sd"> test</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;test&quot;</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span> <span class="n">set_trace</span><span class="p">()</span> <span class="c1"># &lt;--- start of debugger</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;ve found </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
</pre></div>
</div>
<p>If you type <code class="docutils literal notranslate"><span class="pre">test</span></code> in your game, everything will freeze. You wont get any feedback from the game, and you wont be able to enter any command (nor anyone else). Its because the debugger has started in your console, and you will find it here. Below is an example with <code class="docutils literal notranslate"><span class="pre">pdb</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
<span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> notes where it has stopped execution and, what line is about to be executed (in our case, <code class="docutils literal notranslate"><span class="pre">obj</span> <span class="pre">=</span> <span class="pre">self.search(self.args)</span></code>), and ask what you would like to do.</p>
<section id="listing-surrounding-lines-of-code">
<h3>Listing surrounding lines of code<a class="headerlink" href="#listing-surrounding-lines-of-code" title="Permalink to this headline"></a></h3>
<p>When you have the <code class="docutils literal notranslate"><span class="pre">pdb</span></code> prompt <code class="docutils literal notranslate"><span class="pre">(Pdb)</span></code>, you can type in different commands to explore the code. The first one you should know is <code class="docutils literal notranslate"><span class="pre">list</span></code> (you can type <code class="docutils literal notranslate"><span class="pre">l</span></code> for short):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">l</span>
<span class="mi">43</span>
<span class="mi">44</span> <span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;test&quot;</span>
<span class="mi">45</span>
<span class="mi">46</span> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="mi">47</span> <span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span> <span class="n">set_trace</span><span class="p">()</span> <span class="c1"># &lt;--- start of debugger</span>
<span class="mi">48</span> <span class="o">-&gt;</span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="mi">49</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;ve found </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
<span class="mi">50</span>
<span class="mi">51</span> <span class="c1"># -------------------------------------------------------------</span>
<span class="mi">52</span> <span class="c1">#</span>
<span class="mi">53</span> <span class="c1"># The default commands inherit from</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>Okay, this didnt do anything spectacular, but when you become more confident with <code class="docutils literal notranslate"><span class="pre">pdb</span></code> and find yourself in lots of different files, you sometimes need to see whats around in code. Notice that there is a little arrow (<code class="docutils literal notranslate"><span class="pre">-&gt;</span></code>) before the line that is about to be executed.</p>
<p>This is important: <strong>about to be</strong>, not <strong>has just been</strong>. You need to tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to go on (well soon see how).</p>
</section>
<section id="examining-variables">
<h3>Examining variables<a class="headerlink" href="#examining-variables" title="Permalink to this headline"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> allows you to examine variables (or really, to run any Python instruction). It is very useful to know the values of variables at a specific line. To see a variable, just type its name (as if you were in the Python interpreter:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span>
<span class="o">&lt;</span><span class="n">commands</span><span class="o">.</span><span class="n">command</span><span class="o">.</span><span class="n">CmdTest</span> <span class="nb">object</span> <span class="n">at</span> <span class="mh">0x045A0990</span><span class="o">&gt;</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
<span class="sa">u</span><span class="s1">&#39;&#39;</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="o">&lt;</span><span class="n">Character</span><span class="p">:</span> <span class="n">XXX</span><span class="o">&gt;</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>If you try to see the variable <code class="docutils literal notranslate"><span class="pre">obj</span></code>, youll get an error:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
<span class="o">***</span> <span class="ne">NameError</span><span class="p">:</span> <span class="n">name</span> <span class="s1">&#39;obj&#39;</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">defined</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>That figures, since at this point, we havent created the variable yet.</p>
<blockquote>
<div><p>Examining variable in this way is quite powerful. You can even run Python code and keep on
executing, which can help to check that your fix is actually working when you have identified an
error. If you have variable names that will conflict with <code class="docutils literal notranslate"><span class="pre">pdb</span></code> commands (like a <code class="docutils literal notranslate"><span class="pre">list</span></code>
variable), you can prefix your variable with <code class="docutils literal notranslate"><span class="pre">!</span></code>, to tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> that what follows is Python code.</p>
</div></blockquote>
</section>
<section id="executing-the-current-line">
<h3>Executing the current line<a class="headerlink" href="#executing-the-current-line" title="Permalink to this headline"></a></h3>
<p>Its time we asked <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to execute the current line. To do so, use the <code class="docutils literal notranslate"><span class="pre">next</span></code> command. You can
shorten it by just typing <code class="docutils literal notranslate"><span class="pre">n</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
<span class="ne">AttributeError</span><span class="p">:</span> <span class="s2">&quot;&#39;CmdTest&#39; object has no attribute &#39;search&#39;&quot;</span>
<span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">Pdb</span></code> is complaining that you try to call the <code class="docutils literal notranslate"><span class="pre">search</span></code> method on a command… whereas theres no <code class="docutils literal notranslate"><span class="pre">search</span></code> method on commands. The character executing the command is in <code class="docutils literal notranslate"><span class="pre">self.caller</span></code>, so we might change our line:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="letting-the-program-run">
<h3>Letting the program run<a class="headerlink" href="#letting-the-program-run" title="Permalink to this headline"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> is waiting to execute the same instruction… it provoked an error but its ready to try again, just in case. We have fixed it in theory, but we need to reload, so we need to enter a command. To tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to terminate and keep on running the program, use the <code class="docutils literal notranslate"><span class="pre">continue</span></code> (or <code class="docutils literal notranslate"><span class="pre">c</span></code>) command:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">c</span>
<span class="o">...</span>
</pre></div>
</div>
<p>You see an error being caught, thats the error we have fixed… or hope to have. Lets reload the game and try again. You need to run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code> again and then run <code class="docutils literal notranslate"><span class="pre">test</span></code> to get into the command again.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> is about to run the line again.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
<span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;ve found </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>This time the line ran without error. Lets see what is in the <code class="docutils literal notranslate"><span class="pre">obj</span></code> variable:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="nb">print</span> <span class="n">obj</span>
<span class="kc">None</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>We have entered the <code class="docutils literal notranslate"><span class="pre">test</span></code> command without parameter, so no object could be found in the search
(<code class="docutils literal notranslate"><span class="pre">self.args</span></code> is an empty string).</p>
<p>Lets allow the command to continue and try to use an object name as parameter (although, we should
fix that bug too, it would be better):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">c</span>
<span class="o">...</span>
</pre></div>
</div>
<p>Notice that youll have an error in the game this time. Lets try with a valid parameter. I have another character, <code class="docutils literal notranslate"><span class="pre">barkeep</span></code>, in this room:</p>
<p><code class="docutils literal notranslate"><span class="pre">test</span> <span class="pre">barkeep</span></code></p>
<p>And again, the command freezes, and we have the debugger opened in the console.</p>
<p>Lets execute this line right away:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
<span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;ve found </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
<span class="o">&lt;</span><span class="n">Character</span><span class="p">:</span> <span class="n">barkeep</span><span class="o">&gt;</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>At least this time we have found the object. Lets process…</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
<span class="ne">TypeError</span><span class="p">:</span> <span class="s1">&#39;get_display_name() takes exactly 2 arguments (1 given)&#39;</span>
<span class="o">&gt;</span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
<span class="o">-&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;ve found </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
</pre></div>
</div>
<p>As an exercise, fix this error, reload and run the debugger again. Nothing better than some experimenting!</p>
<p>Your debugging will often follow the same strategy:</p>
<ol class="simple">
<li><p>Receive an error you dont understand.</p></li>
<li><p>Put a breaking point <strong>BEFORE</strong> the error occurs.</p></li>
<li><p>Run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code></p></li>
<li><p>Run the code again and see the debugger open.</p></li>
<li><p>Run the program line by line, examining variables, checking the logic of instructions.</p></li>
<li><p>Continue and try again, each step a bit further toward the truth and the working feature.</p></li>
</ol>
</section>
</section>
<section id="cheat-sheet-of-pdb-pudb-commands">
<h2>Cheat-sheet of pdb/pudb commands<a class="headerlink" href="#cheat-sheet-of-pdb-pudb-commands" title="Permalink to this headline"></a></h2>
<p>PuDB and Pdb share the same commands. The only real difference is how its presented. The <code class="docutils literal notranslate"><span class="pre">look</span></code>
command is not needed much in <code class="docutils literal notranslate"><span class="pre">pudb</span></code> since it displays the code directly in its user interface.</p>
<table class="colwidths-auto docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Pdb/PuDB command</p></th>
<th class="head"><p>To do what</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>list (or l)</p></td>
<td><p>List the lines around the point of execution (not needed for <code class="docutils literal notranslate"><span class="pre">pudb</span></code>, it will show</p></td>
</tr>
<tr class="row-odd"><td><p>this directly).</p></td>
<td><p></p></td>
</tr>
<tr class="row-even"><td><p>print (or p)</p></td>
<td><p>Display one or several variables.</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">!</span></code></p></td>
<td><p>Run Python code (using a <code class="docutils literal notranslate"><span class="pre">!</span></code> is often optional).</p></td>
</tr>
<tr class="row-even"><td><p>continue (or c)</p></td>
<td><p>Continue execution and terminate the debugger for this time.</p></td>
</tr>
<tr class="row-odd"><td><p>next (or n)</p></td>
<td><p>Execute the current line and goes to the next one.</p></td>
</tr>
<tr class="row-even"><td><p>step (or s)</p></td>
<td><p>Step inside of a function or method to examine it.</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">&lt;RETURN&gt;</span></code></p></td>
<td><p>Repeat the last command (dont type <code class="docutils literal notranslate"><span class="pre">n</span></code> repeatedly, just type it once and then press</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">&lt;RETURN&gt;</span></code> to repeat it).</p></td>
<td><p></p></td>
</tr>
</tbody>
</table>
<p>If you want to learn more about debugging with Pdb, you will find an <a class="reference external" href="https://pymotw.com/3/pdb/">interesting tutorial on that topic here</a>.</p>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Unit-Testing.html" title="Unit Testing"
>next</a> |</li>
<li class="right" >
<a href="Version-Control.html" title="Coding using Version Control"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,156 @@
<!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>Default Command Syntax &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Soft Code" href="Soft-Code.html" />
<link rel="prev" title="Evennia Code Style" href="Evennia-Code-Style.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Soft-Code.html" title="Soft Code"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Evennia-Code-Style.html" title="Evennia Code Style"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Default Command Syntax</a></li>
</ul>
</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="Evennia-Code-Style.html"
title="previous chapter">Evennia Code Style</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Soft-Code.html"
title="next chapter">Soft Code</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Default-Command-Syntax.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="default-command-syntax">
<h1>Default Command Syntax<a class="headerlink" href="#default-command-syntax" title="Permalink to this headline"></a></h1>
<p>Evennia allows for any command syntax.</p>
<p>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. See the <a class="reference internal" href="../Components/Commands.html"><span class="doc std std-doc">Command</span></a> documentation for how to do this.</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>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">command</span><span class="p">[</span><span class="o">/</span><span class="n">switches</span><span class="p">]</span> <span class="nb">object</span> <span class="p">[</span><span class="o">=</span> <span class="n">options</span><span class="p">]</span>
</pre></div>
</div>
<p>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
MUX syntax has grown organically over a long time and is, frankly, rather arcane in places. All in
all the default command syntax should at most be referred to as “MUX-like” or “MUX-inspired”.</p>
<div class="toctree-wrapper compound">
</div>
</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="Soft-Code.html" title="Soft Code"
>next</a> |</li>
<li class="right" >
<a href="Evennia-Code-Style.html" title="Evennia Code Style"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Default Command Syntax</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,411 @@
<!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>Evennia Code Style &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Default Command Syntax" href="Default-Command-Syntax.html" />
<link rel="prev" title="Coding and development help" href="Coding-Overview.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Default-Command-Syntax.html" title="Default Command Syntax"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Coding-Overview.html" title="Coding and development help"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Evennia Code Style</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Evennia Code Style</a><ul>
<li><a class="reference internal" href="#main-code-style-specification">Main code style specification</a></li>
<li><a class="reference internal" href="#code-docstrings">Code Docstrings</a><ul>
<li><a class="reference internal" href="#module-docstrings">Module docstrings</a></li>
<li><a class="reference internal" href="#class-docstrings">Class docstrings</a></li>
<li><a class="reference internal" href="#function-method-docstrings">Function / method docstrings</a></li>
</ul>
</li>
<li><a class="reference internal" href="#default-command-docstrings">Default Command Docstrings</a></li>
<li><a class="reference internal" href="#tools-for-auto-linting">Tools for auto-linting</a><ul>
<li><a class="reference internal" href="#black">black</a></li>
<li><a class="reference internal" href="#pycharm">PyCharm</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Coding-Overview.html"
title="previous chapter">Coding and development help</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Default-Command-Syntax.html"
title="next chapter">Default Command Syntax</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Evennia-Code-Style.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="evennia-code-style">
<h1>Evennia Code Style<a class="headerlink" href="#evennia-code-style" title="Permalink to this headline"></a></h1>
<p>All code submitted or committed to the Evennia project should aim to follow the
guidelines outlined in <a class="reference external" href="http://www.python.org/dev/peps/pep-0008">Python PEP 8</a>. Keeping the code style uniform
makes it much easier for people to collaborate and read the code.</p>
<p>A good way to check if your code follows PEP8 is to use the <a class="reference external" href="https://pypi.python.org/pypi/pep8">PEP8 tool</a>
on your sources.</p>
<section id="main-code-style-specification">
<h2>Main code style specification<a class="headerlink" href="#main-code-style-specification" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>4-space indentation, NO TABS!</p></li>
<li><p>Unix line endings.</p></li>
<li><p>100 character line widths</p></li>
<li><p>CamelCase is only used for classes, nothing else.</p></li>
<li><p>All non-global variable names and all function names are to be
lowercase, words separated by underscores. Variable names should
always be more than two letters long.</p></li>
<li><p>Module-level global variables (only) are to be in CAPITAL letters.</p></li>
<li><p>Imports should be done in this order:</p>
<ul>
<li><p>Python modules (builtins and standard library)</p></li>
<li><p>Twisted modules</p></li>
<li><p>Django modules</p></li>
<li><p>Evennia library modules (<code class="docutils literal notranslate"><span class="pre">evennia</span></code>)</p></li>
<li><p>Evennia contrib modules (<code class="docutils literal notranslate"><span class="pre">evennia.contrib</span></code>)</p></li>
</ul>
</li>
<li><p>All modules, classes, functions and methods should have doc strings formatted
as outlined below.</p></li>
<li><p>All default commands should have a consistent docstring formatted as
outlined below.</p></li>
</ul>
</section>
<section id="code-docstrings">
<h2>Code Docstrings<a class="headerlink" href="#code-docstrings" title="Permalink to this headline"></a></h2>
<p>All modules, classes, functions and methods should have docstrings
formatted with <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html">Google style</a> -inspired indents, using
<a class="reference external" href="https://help.github.com/articles/github-flavored-markdown/">Markdown</a> formatting where needed. Evennias <code class="docutils literal notranslate"><span class="pre">api2md</span></code>
parser will use this to create pretty API documentation.</p>
<section id="module-docstrings">
<h3>Module docstrings<a class="headerlink" href="#module-docstrings" title="Permalink to this headline"></a></h3>
<p>Modules should all start with at least a few lines of docstring at
their top describing the contents and purpose of the module.</p>
<p>Example of module docstring (top of file):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">This module handles the creation of `Objects` that</span>
<span class="sd">are useful in the game ...</span>
<span class="sd">&quot;&quot;&quot;</span>
</pre></div>
</div>
<p>Sectioning (<code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">title</span></code>, <code class="docutils literal notranslate"><span class="pre">##</span> <span class="pre">subtile</span></code> etc) should not be used in
freeform docstrings - this will confuse the sectioning of the auto
documentation page and the auto-api will create this automatically.
Write just the section name bolded on its own line to mark a section.
Beyond sections markdown should be used as needed to format
the text.</p>
<p>Code examples should use <a class="reference external" href="https://help.github.com/articles/github-flavored-markdown/#syntax-highlighting">multi-line syntax highlighting</a>
to mark multi-line code blocks, using the “python” identifier. Just
indenting code blocks (common in markdown) will not produce the
desired look.</p>
<p>When using any code tags (inline or blocks) its recommended that you
dont let the code extend wider than about 70 characters or it will
need to be scrolled horizontally in the wiki (this does not affect any
other text, only code).</p>
</section>
<section id="class-docstrings">
<h3>Class docstrings<a class="headerlink" href="#class-docstrings" title="Permalink to this headline"></a></h3>
<p>The root class docstring should describe the over-arching use of the
class. It should usually not describe the exact call sequence nor list
important methods, this tends to be hard to keep updated as the API
develops. Dont use section markers (<code class="docutils literal notranslate"><span class="pre">#</span></code>, <code class="docutils literal notranslate"><span class="pre">##</span></code> etc).</p>
<p>Example of class docstring:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This class describes the creation of `Objects`. It is useful</span>
<span class="sd"> in many situations, such as ...</span>
<span class="sd"> &quot;&quot;&quot;</span>
</pre></div>
</div>
</section>
<section id="function-method-docstrings">
<h3>Function / method docstrings<a class="headerlink" href="#function-method-docstrings" title="Permalink to this headline"></a></h3>
<p>Example of function or method docstring:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
<span class="k">def</span> <span class="nf">funcname</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is a brief introduction to the function/class/method</span>
<span class="sd"> Args:</span>
<span class="sd"> a (str): This is a string argument that we can talk about</span>
<span class="sd"> over multiple lines.</span>
<span class="sd"> b (int or str): Another argument.</span>
<span class="sd"> c (list): A list argument.</span>
<span class="sd"> d (bool, optional): An optional keyword argument.</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> test (list): A test keyword.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The result of the function.</span>
<span class="sd"> Raises:</span>
<span class="sd"> RuntimeException: If there is a critical error,</span>
<span class="sd"> this is raised.</span>
<span class="sd"> IOError: This is only raised if there is a</span>
<span class="sd"> problem with the database.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This is an example function. If `d=True`, something</span>
<span class="sd"> amazing will happen.</span>
<span class="sd"> &quot;&quot;&quot;</span>
</pre></div>
</div>
<p>The syntax is very “loose” but the indentation matters. That is, you
should end the block headers (like <code class="docutils literal notranslate"><span class="pre">Args:</span></code>) with a line break followed by
an indent. When you need to break a line you should start the next line
with another indent. For consistency with the code we recommend all
indents to be 4 spaces wide (no tabs!).</p>
<p>Here are all the supported block headers:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Args</span>
<span class="sd"> argname (freeform type): Description endind with period.</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> argname (freeform type): Description.</span>
<span class="sd"> Returns/Yields:</span>
<span class="sd"> type: Description.</span>
<span class="sd"> Raises:</span>
<span class="sd"> Exceptiontype: Description.</span>
<span class="sd"> Notes/Note/Examples/Example:</span>
<span class="sd"> Freeform text.</span>
<span class="sd"> &quot;&quot;&quot;</span>
</pre></div>
</div>
<p>Parts marked with “freeform” means that you can in principle put any
text there using any formatting except for sections markers (<code class="docutils literal notranslate"><span class="pre">#</span></code>, <code class="docutils literal notranslate"><span class="pre">##</span></code>
etc). You must also keep indentation to mark which block you are part
of. You should normally use the specified format rather than the
freeform counterpart (this will produce nicer output) but in some
cases the freeform may produce a more compact and readable result
(such as when describing an <code class="docutils literal notranslate"><span class="pre">*args</span></code> or <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> statement in general
terms). The first <code class="docutils literal notranslate"><span class="pre">self</span></code> argument of class methods should never be
documented.</p>
<p>Note that</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Args:</span>
<span class="sd"> argname (type, optional): Description.</span>
<span class="sd">&quot;&quot;&quot;</span>
</pre></div>
</div>
<p>and</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Keyword Args:</span>
<span class="sd"> sargname (type): Description.</span>
<span class="sd">&quot;&quot;&quot;</span>
</pre></div>
</div>
<p>mean the same thing! Which one is used depends on the function or
method documented, but there are no hard rules; If there is a large
<code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> block in the function, using the <code class="docutils literal notranslate"><span class="pre">Keyword</span> <span class="pre">Args:</span></code> block may be a
good idea, for a small number of arguments though, just using <code class="docutils literal notranslate"><span class="pre">Args:</span></code>
and marking keywords as <code class="docutils literal notranslate"><span class="pre">optional</span></code> will shorten the docstring and make
it easier to read.</p>
</section>
</section>
<section id="default-command-docstrings">
<h2>Default Command Docstrings<a class="headerlink" href="#default-command-docstrings" title="Permalink to this headline"></a></h2>
<p>These represent a special case since Commands in Evennia use their class
docstrings to represent the in-game help entry for that command.</p>
<p>All the commands in the <em>default command</em> sets should have their doc-strings
formatted on a similar form. For contribs, this is loosened, but if there is
no particular reason to use a different form, one should aim to use the same
style for contrib-command docstrings as well.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Short header</span>
<span class="sd"> Usage:</span>
<span class="sd"> key[/switches, if any] &lt;mandatory args&gt; [optional] choice1||choice2||choice3</span>
<span class="sd"> Switches:</span>
<span class="sd"> switch1 - description</span>
<span class="sd"> switch2 - description</span>
<span class="sd"> Examples:</span>
<span class="sd"> Usage example and output</span>
<span class="sd"> Longer documentation detailing the command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
</pre></div>
</div>
<ul class="simple">
<li><p>Two spaces are used for <em>indentation</em> in all default commands.</p></li>
<li><p>Square brackets <code class="docutils literal notranslate"><span class="pre">[</span> <span class="pre">]</span></code> surround <em>optional, skippable arguments</em>.</p></li>
<li><p>Angled brackets <code class="docutils literal notranslate"><span class="pre">&lt;</span> <span class="pre">&gt;</span></code> surround a <em>description</em> of what to write rather than the exact syntax.</p></li>
<li><p>Explicit choices are separated by <code class="docutils literal notranslate"><span class="pre">|</span></code>. To avoid this being parsed as a color code, use <code class="docutils literal notranslate"><span class="pre">||</span></code> (this
will come out as a single <code class="docutils literal notranslate"><span class="pre">|</span></code>) or put spaces around the character (“<code class="docutils literal notranslate"><span class="pre">|</span></code>”) if theres plenty of room.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">Switches</span></code> and <code class="docutils literal notranslate"><span class="pre">Examples</span></code> blocks are optional and based on the Command.</p></li>
</ul>
<p>Here is the <code class="docutils literal notranslate"><span class="pre">nick</span></code> command as an example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Define a personal alias/nick</span>
<span class="sd"> Usage:</span>
<span class="sd"> nick[/switches] &lt;nickname&gt; = [&lt;string&gt;]</span>
<span class="sd"> alias &#39;&#39;</span>
<span class="sd"> Switches:</span>
<span class="sd"> object - alias an object</span>
<span class="sd"> account - alias an account</span>
<span class="sd"> clearall - clear all your aliases</span>
<span class="sd"> list - show all defined aliases (also &quot;nicks&quot; works)</span>
<span class="sd"> Examples:</span>
<span class="sd"> nick hi = say Hello, I&#39;m Sarah!</span>
<span class="sd"> nick/object tom = the tall man</span>
<span class="sd"> A &#39;nick&#39; is a personal shortcut you create for your own use [...]</span>
<span class="sd"> &quot;&quot;&quot;</span>
</pre></div>
</div>
<p>For commands that <em>require arguments</em>, the policy is for it to return a <code class="docutils literal notranslate"><span class="pre">Usage:</span></code>
string if the command is entered without any arguments. So for such commands,
the Command body should contain something to the effect of</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: nick[/switches] &lt;nickname&gt; = [&lt;string&gt;]&quot;</span><span class="p">)</span>
<span class="k">return</span>
</pre></div>
</div>
</section>
<section id="tools-for-auto-linting">
<h2>Tools for auto-linting<a class="headerlink" href="#tools-for-auto-linting" title="Permalink to this headline"></a></h2>
<section id="black">
<h3>black<a class="headerlink" href="#black" title="Permalink to this headline"></a></h3>
<p>Automatic pep8 compliant formatting and linting can be performed using the
<code class="docutils literal notranslate"><span class="pre">black</span></code> formatter:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>black --line-length 100
</pre></div>
</div>
</section>
<section id="pycharm">
<h3>PyCharm<a class="headerlink" href="#pycharm" title="Permalink to this headline"></a></h3>
<p>The Python IDE <a class="reference external" href="https://www.jetbrains.com/pycharm/">Pycharm</a> can auto-generate empty doc-string stubs. The
default is to use <code class="docutils literal notranslate"><span class="pre">reStructuredText</span></code> form, however. To change to Evennias
Google-style docstrings, follow <a class="reference external" href="https://www.jetbrains.com/help/pycharm/2016.3/python-integrated-tools.html">this guide</a>.</p>
</section>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Default-Command-Syntax.html" title="Default Command Syntax"
>next</a> |</li>
<li class="right" >
<a href="Coding-Overview.html" title="Coding and development help"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Evennia Code Style</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,342 @@
<!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>Profiling &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Continuous Integration (CI)" href="Continuous-Integration.html" />
<link rel="prev" title="Unit Testing" href="Unit-Testing.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Continuous-Integration.html" title="Continuous Integration (CI)"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Unit-Testing.html" title="Unit Testing"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Profiling</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Profiling</a><ul>
<li><a class="reference internal" href="#simple-timer-tests">Simple timer tests</a></li>
<li><a class="reference internal" href="#using-cprofile">Using cProfile</a><ul>
<li><a class="reference internal" href="#analyzing-the-profile">Analyzing the profile</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-dummyrunner">The Dummyrunner</a><ul>
<li><a class="reference internal" href="#dummyrunner-hints">Dummyrunner hints</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Unit-Testing.html"
title="previous chapter">Unit Testing</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Continuous-Integration.html"
title="next chapter">Continuous Integration (CI)</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Profiling.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="profiling">
<h1>Profiling<a class="headerlink" href="#profiling" title="Permalink to this headline"></a></h1>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>This is considered an advanced topic. Its mainly of interest to server developers.</p>
</div>
<p>Sometimes it can be useful to try to determine just how efficient a particular piece of code is, or to figure out if one could speed up things more than they are. There are many ways to test the performance of Python and the running server.</p>
<p>Before digging into this section, remember Donald Knuths <a class="reference external" href="https://en.wikipedia.org/wiki/Program_optimization#When_to_optimize">words of wisdom</a>:</p>
<blockquote>
<div><p><em>[…]about 97% of the time: Premature optimization is the root of all evil</em>.</p>
</div></blockquote>
<p>That is, dont start to try to optimize your code until you have actually identified a need to do so. This means your code must actually be working before you start to consider optimization. Optimization will also often make your code more complex and harder to read. Consider readability and maintainability and you may find that a small gain in speed is just not worth it.</p>
<section id="simple-timer-tests">
<h2>Simple timer tests<a class="headerlink" href="#simple-timer-tests" title="Permalink to this headline"></a></h2>
<p>Pythons <code class="docutils literal notranslate"><span class="pre">timeit</span></code> module is very good for testing small things. For example, in
order to test if it is faster to use a <code class="docutils literal notranslate"><span class="pre">for</span></code> loop or a list comprehension you
could use the following code:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">import</span> <span class="nn">timeit</span>
<span class="c1"># Time to do 1000000 for loops</span>
<span class="n">timeit</span><span class="o">.</span><span class="n">timeit</span><span class="p">(</span><span class="s2">&quot;for i in range(100):</span><span class="se">\n</span><span class="s2"> a.append(i)&quot;</span><span class="p">,</span> <span class="n">setup</span><span class="o">=</span><span class="s2">&quot;a = []&quot;</span><span class="p">)</span>
<span class="o">&lt;&lt;&lt;</span> <span class="mf">10.70982813835144</span>
<span class="c1"># Time to do 1000000 list comprehensions</span>
<span class="n">timeit</span><span class="o">.</span><span class="n">timeit</span><span class="p">(</span><span class="s2">&quot;a = [i for i in range(100)]&quot;</span><span class="p">)</span>
<span class="o">&lt;&lt;&lt;</span> <span class="mf">5.358283996582031</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">setup</span></code> keyword is used to set up things that should not be included in the time measurement, like <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">=</span> <span class="pre">[]</span></code> in the first call.</p>
<p>By default the <code class="docutils literal notranslate"><span class="pre">timeit</span></code> function will re-run the given test 1000000 times and returns the <em>total time</em> to do so (so <em>not</em> the average per test). A hint is to not use this default for testing something that includes database writes - for that you may want to use a lower number of repeats (say 100 or 1000) using the <code class="docutils literal notranslate"><span class="pre">number=100</span></code> keyword.</p>
<p>In the example above, we see that this number of calls, using a list comprehension is about twice as fast as building a list using <code class="docutils literal notranslate"><span class="pre">.append()</span></code>.</p>
</section>
<section id="using-cprofile">
<h2>Using cProfile<a class="headerlink" href="#using-cprofile" title="Permalink to this headline"></a></h2>
<p>Python comes with its own profiler, named cProfile (this is for cPython, no tests have been done with <code class="docutils literal notranslate"><span class="pre">pypy</span></code> at this point). Due to the way Evennias processes are handled, there is no point in using the normal way to start the profiler (<code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">cProfile</span> <span class="pre">evennia.py</span></code>). Instead you start the profiler through the launcher:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia --profiler start
</pre></div>
</div>
<p>This will start Evennia with the Server component running (in daemon mode) under cProfile. You could instead try <code class="docutils literal notranslate"><span class="pre">--profile</span></code> with the <code class="docutils literal notranslate"><span class="pre">portal</span></code> argument to profile the Portal (you would then need to <a class="reference internal" href="../Setup/Running-Evennia.html"><span class="doc std std-doc">start the Server separately</span></a>).</p>
<p>Please note that while the profiler is running, your process will use a lot more memory than usual. Memory usage is even likely to climb over time. So dont leave it running perpetually but monitor it carefully (for example using the <code class="docutils literal notranslate"><span class="pre">top</span></code> command on Linux or the Task Managers memory display on Windows).</p>
<p>Once you have run the server for a while, you need to stop it so the profiler can give its report. Do <em>not</em> kill the program from your task manager or by sending it a kill signal - this will most likely also mess with the profiler. Instead either use <code class="docutils literal notranslate"><span class="pre">evennia.py</span> <span class="pre">stop</span></code> or (which may be even better), use <code class="docutils literal notranslate"><span class="pre">&#64;shutdown</span></code> from inside the game.</p>
<p>Once the server has fully shut down (this may be a lot slower than usual) you will find that profiler has created a new file <code class="docutils literal notranslate"><span class="pre">mygame/server/logs/server.prof</span></code>.</p>
<section id="analyzing-the-profile">
<h3>Analyzing the profile<a class="headerlink" href="#analyzing-the-profile" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">server.prof</span></code> file is a binary file. There are many ways to analyze and display its contents, all of which has only been tested in Linux (If you are a Windows/Mac user, let us know what works).</p>
<p>You can look at the contents of the profile file with Pythons in-built <code class="docutils literal notranslate"><span class="pre">pstats</span></code> module in the evennia shell (its recommended you install <code class="docutils literal notranslate"><span class="pre">ipython</span></code> with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">ipython</span></code> in your virtualenv first, for prettier output):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia shell
</pre></div>
</div>
<p>Then in the shell</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pstats</span>
<span class="kn">from</span> <span class="nn">pstats</span> <span class="kn">import</span> <span class="n">SortKey</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="s1">&#39;server/log/server.prof&#39;</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">strip_dirs</span><span class="p">()</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">()</span>
</pre></div>
</div>
<p>See the <a class="reference external" href="https://docs.python.org/3/library/profile.html#instant-user-s-manual">Python profiling documentation</a> for more information.</p>
<p>You can also visualize the data in various ways.</p>
<ul class="simple">
<li><p><a class="reference external" href="https://pypi.org/project/RunSnakeRun/">Runsnake</a> visualizes the profile to
give a good overview. Install with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">runsnakerun</span></code>. Note that this
may require a C compiler and be quite slow to install.</p></li>
<li><p>For more detailed listing of usage time, you can use
<a class="reference external" href="http://kcachegrind.sourceforge.net/html/Home.html">KCachegrind</a>. To make
KCachegrind work with Python profiles you also need the wrapper script
<a class="reference external" href="https://pypi.python.org/pypi/pyprof2calltree/">pyprof2calltree</a>. You can get
<code class="docutils literal notranslate"><span class="pre">pyprof2calltree</span></code> via <code class="docutils literal notranslate"><span class="pre">pip</span></code> whereas KCacheGrind is something you need to get
via your package manager or their homepage.</p></li>
</ul>
<p>How to analyze and interpret profiling data is not a trivial issue and depends on what you are profiling for. Evennia being an asynchronous server can also confuse profiling. Ask on the mailing list if you need help and be ready to be able to supply your <code class="docutils literal notranslate"><span class="pre">server.prof</span></code> file for comparison, along with the exact conditions under which it was obtained.</p>
</section>
</section>
<section id="the-dummyrunner">
<h2>The Dummyrunner<a class="headerlink" href="#the-dummyrunner" title="Permalink to this headline"></a></h2>
<p>It is difficult to test “actual” game performance without having players in your game. For this reason Evennia comes with the <em>Dummyrunner</em> system. The Dummyrunner is a stress-testing system: a separate program that logs into your game with simulated players (aka “bots” or “dummies”). Once connected, these dummies will semi-randomly perform various tasks from a list of possible actions. Use <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code> to stop the Dummyrunner.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>You should not run the Dummyrunner on a production database. It
will spawn many objects and also needs to run with general permissions.
</pre></div>
</div>
<p>This is the recommended process for using the dummy runner:</p>
</div>
<ol>
<li><p>Stop your server completely with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">stop</span></code>.</p></li>
<li><p>At <em>the end</em> of your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf.settings.py</span></code> file, add the line</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> from evennia.server.profiling.settings_mixin import *
</pre></div>
</div>
<p>This will override your settings and disable Evennias rate limiters and DoS-protections, which would otherwise block mass-connecting clients from one IP. Notably, it will also change to a different (faster) password hasher.</p>
</li>
<li><p>(recommended): Build a new database. If you use default Sqlite3 and want to
keep your existing database, just rename <code class="docutils literal notranslate"><span class="pre">mygame/server/evennia.db3</span></code> to
<code class="docutils literal notranslate"><span class="pre">mygame/server/evennia.db3_backup</span></code> and run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">migrate</span></code> and <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">start</span></code> to create a new superuser as usual.</p></li>
<li><p>(recommended) Log into the game as your superuser. This is just so you
can manually check response. If you kept an old database, you will <em>not</em>
be able to connect with an <em>existing</em> user since the password hasher changed!</p></li>
<li><p>Start the dummyrunner with 10 dummy users from the terminal with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> evennia --dummyrunner 10
</pre></div>
</div>
<p>Use <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code> (or <code class="docutils literal notranslate"><span class="pre">Cmd-C</span></code>) to stop it.</p>
</li>
</ol>
<p>If you want to see what the dummies are actually doing you can run with a single dummy:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia --dummyrunner 1
</pre></div>
</div>
<p>The inputs/outputs from the dummy will then be printed. By default the runner uses the looker profile, which just logs in and sends the look command over and over. To change the settings, copy the file <code class="docutils literal notranslate"><span class="pre">evennia/server/profiling/dummyrunner_settings.py</span></code> to your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/</span></code> directory, then add this line to your settings file to use it in the new location:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>DUMMYRUNNER_SETTINGS_MODULE = &quot;server/conf/dummyrunner_settings.py&quot;
</pre></div>
</div>
<p>The dummyrunner settings file is a python code module in its own right - it defines the actions available to the dummies. These are just tuples of command strings (like “look here”) for the dummy to send to the server along with a probability of them happening. The dummyrunner looks for a global variable <code class="docutils literal notranslate"><span class="pre">ACTIONS</span></code>, a list of tuples, where the first two elements define the commands for logging in/out of the server.</p>
<p>Below is a simplified minimal setup (the default settings file adds a lot more functionality and info):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># minimal dummyrunner setup file</span>
<span class="c1"># Time between each dummyrunner &quot;tick&quot;, in seconds. Each dummy will be called</span>
<span class="c1"># with this frequency.</span>
<span class="n">TIMESTEP</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1"># Chance of a dummy actually performing an action on a given tick. This</span>
<span class="c1"># spreads out usage randomly, like it would be in reality.</span>
<span class="n">CHANCE_OF_ACTION</span> <span class="o">=</span> <span class="mf">0.5</span>
<span class="c1"># Chance of a currently unlogged-in dummy performing its login action every</span>
<span class="c1"># tick. This emulates not all accounts logging in at exactly the same time.</span>
<span class="n">CHANCE_OF_LOGIN</span> <span class="o">=</span> <span class="mf">0.01</span>
<span class="c1"># Which telnet port to connect to. If set to None, uses the first default</span>
<span class="c1"># telnet port of the running server.</span>
<span class="n">TELNET_PORT</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># actions</span>
<span class="k">def</span> <span class="nf">c_login</span><span class="p">(</span><span class="n">client</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Character-</span><span class="si">{</span><span class="n">client</span><span class="o">.</span><span class="n">gid</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">pwd</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;23fwsf23sdfw23wef23&quot;</span>
<span class="k">return</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;create </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">pwd</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="sa">f</span><span class="s2">&quot;connect </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">pwd</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">c_logout</span><span class="p">(</span><span class="n">client</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s2">&quot;quit&quot;</span><span class="p">,</span> <span class="p">)</span>
<span class="k">def</span> <span class="nf">c_look</span><span class="p">(</span><span class="n">client</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s2">&quot;look here&quot;</span><span class="p">,</span> <span class="s2">&quot;look me&quot;</span><span class="p">)</span>
<span class="c1"># this is read by dummyrunner.</span>
<span class="n">ACTIONS</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">c_login</span><span class="p">,</span>
<span class="n">c_logout</span><span class="p">,</span>
<span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">c_look</span><span class="p">)</span> <span class="c1"># (probability, command-generator)</span>
<span class="p">)</span>
</pre></div>
</div>
<p>At the bottom of the default file are a few default profiles you can test out by just setting the <code class="docutils literal notranslate"><span class="pre">PROFILE</span></code> variable to one of the options.</p>
<section id="dummyrunner-hints">
<h3>Dummyrunner hints<a class="headerlink" href="#dummyrunner-hints" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>Dont start with too many dummies. The Dummyrunner taxes the server much more
than real users tend to do. Start with 10-100 to begin with.</p></li>
<li><p>Stress-testing can be fun, but also consider what a realistic number of
users would be for your game.</p></li>
<li><p>Note in the dummyrunner output how many commands/s are being sent to the
server by all dummies. This is usually a lot higher than what youd
realistically expect to see from the same number of users.</p></li>
<li><p>The default settings sets up a lag measure to measaure the round-about
message time. It updates with an average every 30 seconds. It can be worth to
have this running for a small number of dummies in one terminal before adding
more by starting another dummyrunner in another terminal - the first one will
act as a measure of how lag changes with different loads. Also verify the
lag-times by entering commands manually in-game.</p></li>
<li><p>Check the CPU usage of your server using <code class="docutils literal notranslate"><span class="pre">top/htop</span></code> (linux). In-game, use the
<code class="docutils literal notranslate"><span class="pre">server</span></code> command.</p></li>
<li><p>You can run the server with <code class="docutils literal notranslate"><span class="pre">--profiler</span> <span class="pre">start</span></code> to test it with dummies. Note
that the profiler will itself affect server performance, especially memory
consumption.</p></li>
<li><p>Generally, the dummyrunner system makes for a decent test of general
performance; but it is of course hard to actually mimic human user behavior.
For this, actual real-game testing is required.</p></li>
</ul>
</section>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Continuous-Integration.html" title="Continuous Integration (CI)"
>next</a> |</li>
<li class="right" >
<a href="Unit-Testing.html" title="Unit Testing"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Profiling</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,331 @@
<!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>Evennia 1.0 Release Notes &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Contribs" href="../Contribs/Contribs-Overview.html" />
<link rel="prev" title="Changelog" href="Changelog.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="../Contribs/Contribs-Overview.html" title="Contribs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Changelog.html" title="Changelog"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Evennia 1.0 Release Notes</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Evennia 1.0 Release Notes</a><ul>
<li><a class="reference internal" href="#minimum-requirements">Minimum requirements</a></li>
<li><a class="reference internal" href="#major-new-features">Major new features</a></li>
<li><a class="reference internal" href="#contribs">Contribs</a></li>
<li><a class="reference internal" href="#translations">Translations</a></li>
<li><a class="reference internal" href="#utils">Utils</a></li>
<li><a class="reference internal" href="#locks">Locks</a></li>
<li><a class="reference internal" href="#hook-changes">Hook changes</a></li>
<li><a class="reference internal" href="#command-changes">Command changes</a></li>
<li><a class="reference internal" href="#coding-improvement-highlights">Coding improvement highlights</a></li>
<li><a class="reference internal" href="#other">Other</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Changelog.html"
title="previous chapter">Changelog</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../Contribs/Contribs-Overview.html"
title="next chapter">Contribs</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Release-Notes-1.0.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="evennia-1-0-release-notes">
<h1>Evennia 1.0 Release Notes<a class="headerlink" href="#evennia-1-0-release-notes" title="Permalink to this headline"></a></h1>
<p>This summarizes the changes. See the <a class="reference internal" href="Changelog.html"><span class="doc std std-doc">Changelog</span></a> for the full list.</p>
<ul class="simple">
<li><p>Main development now on <code class="docutils literal notranslate"><span class="pre">main</span></code> branch. <code class="docutils literal notranslate"><span class="pre">master</span></code> branch remains, but will not be updated anymore.</p></li>
</ul>
<section id="minimum-requirements">
<h2>Minimum requirements<a class="headerlink" href="#minimum-requirements" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Python 3.10 is now required minimum. Ubuntu LTS now installs with 3.10. Evennia 1.0 is also tested with Python 3.11 - this is the recommended version for Linux/Mac. Windows users may want to stay on Python 3.10 unless they are okay with installing a C++ compiler.</p></li>
<li><p>Twisted 22.10+</p></li>
<li><p>Django 4.1+</p></li>
</ul>
</section>
<section id="major-new-features">
<h2>Major new features<a class="headerlink" href="#major-new-features" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Evennia is now on PyPi and is installable as <a class="reference internal" href="../Setup/Installation.html"><span class="doc std std-doc">pip install evennia</span></a>.</p></li>
<li><p>A completely revamped documentation at <a class="reference external" href="https://www.evennia.com/docs/latest">https://www.evennia.com/docs/latest</a>. The old wiki and readmedocs pages will close.</p></li>
<li><p>Evennia 1.0 now has a REST API which allows you access game objects using CRUD operations GET/POST etc. See [The Web-API docs][Web-API] for more information.</p></li>
<li><p><a class="reference internal" href="../Setup/Channels-to-Discord.html"><span class="doc std std-doc">Evennia&lt;&gt;Discord Integration</span></a> between Evennia channels and Discord servers.</p></li>
<li><p><a class="reference internal" href="../Components/Scripts.html"><span class="doc std std-doc">Script</span></a> overhaul: Scripts timer component independent from script object deletion; can now start/stop timer without deleting Script. The <code class="docutils literal notranslate"><span class="pre">.persistent</span></code> flag now only controls if timer survives reload - Script has to be removed with <code class="docutils literal notranslate"><span class="pre">.delete()</span></code> like other typeclassed entities. This makes Scripts even more useful as general storage entities.</p></li>
<li><p>The <a class="reference internal" href="../Components/FuncParser.html"><span class="doc std std-doc">FuncParser</span></a> centralizes and vastly improves all in-string function calls, such as <code class="docutils literal notranslate"><span class="pre">say</span> <span class="pre">the</span> <span class="pre">result</span> <span class="pre">is</span> <span class="pre">$eval(3</span> <span class="pre">*</span> <span class="pre">7)</span></code> and say the result <code class="docutils literal notranslate"><span class="pre">the</span> <span class="pre">result</span> <span class="pre">is</span> <span class="pre">21</span></code>. The parser completely replaces the old <code class="docutils literal notranslate"><span class="pre">parse_inlinefunc</span></code>. The new parser can handle both arguments and kwargs and are also used for in-prototype parsing as well as director stance messaging, such as using <code class="docutils literal notranslate"><span class="pre">$You()</span></code> to represent yourself in a string and having the result come out differently depending on who see you.</p></li>
<li><p><a class="reference internal" href="../Components/Channels.html"><span class="doc std std-doc">Channels</span></a> New Channel-System using the <code class="docutils literal notranslate"><span class="pre">channel</span></code> command and nicks. The old <code class="docutils literal notranslate"><span class="pre">ChannelHandler</span></code> was removed and the customization and operation of channels have been simplified a lot. The old command syntax commands are now available as a contrib.</p></li>
<li><p><a class="reference internal" href="../Components/Help-System.html"><span class="doc std std-doc">Help System</span></a> was refactored.</p>
<ul>
<li><p>A new type of <code class="docutils literal notranslate"><span class="pre">FileHelp</span></code> system allows you to add in-game help files as external Python files. This means there are three ways to add help entries in Evennia: 1) Auto-generated from Commands code. 2) Manually added to the database from the <code class="docutils literal notranslate"><span class="pre">sethelp</span></code> command in-game and 3) Created as external Python files that Evennia loads and makes available in-game.</p></li>
<li><p>We now use <code class="docutils literal notranslate"><span class="pre">lunr</span></code> search indexing for better <code class="docutils literal notranslate"><span class="pre">help</span></code> matching and suggestions. Also improve
the main help commands default listing output.</p></li>
<li><p>Help command now uses <code class="docutils literal notranslate"><span class="pre">view</span></code> lock to determine if cmd/entry shows in index and <code class="docutils literal notranslate"><span class="pre">read</span></code> lock to determine if it can be read. It used to be <code class="docutils literal notranslate"><span class="pre">view</span></code> in the role of the latter.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sethelp</span></code> command now warns if shadowing other help-types when creating a new entry.</p></li>
<li><p>Make <code class="docutils literal notranslate"><span class="pre">help</span></code> index output clickable for webclient/clients with MXP (PR by davewiththenicehat)</p></li>
</ul>
</li>
<li><p>Rework of the <a class="reference internal" href="../Components/Website.html"><span class="doc std std-doc">Web</span></a> setup, into a much more consistent structure and update to latest Django. The <code class="docutils literal notranslate"><span class="pre">mygame/web/static_overrides</span></code> and <code class="docutils literal notranslate"><span class="pre">-template_overrides</span></code> were removed. The folders are now just <code class="docutils literal notranslate"><span class="pre">mygame/web/static</span></code> and <code class="docutils literal notranslate"><span class="pre">/templates</span></code> and handle the automatic copying of data behind the scenes. <code class="docutils literal notranslate"><span class="pre">app.css</span></code> to <code class="docutils literal notranslate"><span class="pre">website.css</span></code> for consistency. The old <code class="docutils literal notranslate"><span class="pre">prosimii-css</span></code> files were removed.</p></li>
<li><p><a class="reference internal" href="../Components/Attributes.html#using-attributeproperty"><span class="std std-doc">AttributeProperty</span></a>/<a class="reference internal" href="../Components/Tags.html"><span class="doc std std-doc">TagProperty</span></a> along with <code class="docutils literal notranslate"><span class="pre">AliasProperty</span></code> and <code class="docutils literal notranslate"><span class="pre">PermissionProperty</span></code> to allow managing Attributes, Tags, Aliases and Permissios on typeclasses in the same way as Django fields. This dramatically reduces the need to assign Attributes/Tags in <code class="docutils literal notranslate"><span class="pre">at_create_object</span></code> hook.</p></li>
<li><p>The old <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span></code> was divided into smaller settings, for better controlling what happens when a user connects, if a character should be auto-created, and how many characters they can control at the same time. See <a class="reference internal" href="../Concepts/Connection-Styles.html"><span class="doc std std-doc">Connection-Styles</span></a> for a detailed explanation.</p></li>
<li><p>Evennia now supports custom <code class="docutils literal notranslate"><span class="pre">evennia</span></code> launcher commands (e.g. <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">mycmd</span> <span class="pre">foo</span> <span class="pre">bar</span></code>). Add new commands as callables accepting <code class="docutils literal notranslate"><span class="pre">*args</span></code>, as <code class="docutils literal notranslate"><span class="pre">settings.EXTRA_LAUNCHER_COMMANDS</span> <span class="pre">=</span> <span class="pre">{'mycmd':</span> <span class="pre">'path.to.callable',</span> <span class="pre">...}</span></code>.</p></li>
</ul>
</section>
<section id="contribs">
<h2>Contribs<a class="headerlink" href="#contribs" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">contrib</span></code> folder structure was changed from 0.9.5. All contribs are now in sub-folders and organized into categories. All import paths must be updated. See <a class="reference internal" href="../Contribs/Contribs-Overview.html"><span class="doc std std-doc">Contribs overview</span></a>.</p>
<ul class="simple">
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Traits.html"><span class="doc std std-doc">Traits contrib</span></a>, converted and expanded from Ainneve project. (whitenoise, Griatch)</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Crafting.html"><span class="doc std std-doc">Crafting contrib</span></a>, adding a full crafting subsystem (Griatch)</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-XYZGrid.html"><span class="doc std std-doc">XYZGrid contrib</span></a>, adding x,y,z grid coordinates with in-game map and pathfinding. Controlled outside of the game via custom evennia launcher command (Griatch)</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Cooldowns.html"><span class="doc std std-doc">Command cooldown contrib</span></a> contrib for making it easier to manage commands using
dynamic cooldowns between uses (owllex)</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Godotwebsocket.html"><span class="doc std std-doc">Godot Protocol contrib</span></a> for connecting to Evennia from a client written in the open-source game engine <a class="reference external" href="https://godotengine.org/">Godot</a> (ChrisLR).</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Name-Generator.html"><span class="doc std std-doc">name_generator contrib</span></a> for building random real-world based or fantasy-names based on phonetic rules (InspectorCaracal)</p></li>
<li><p>New <a class="reference internal" href="../Contribs/Contrib-Buffs.html"><span class="doc std std-doc">Buffs contrib</span></a> for managing temporary and permanent RPG status buffs effects (tegiminis)</p></li>
<li><p>The existing <a class="reference internal" href="../Contribs/Contrib-RPSystem.html"><span class="doc std std-doc">RPSystem contrib</span></a> was refactored and saw a speed boost (InspectorCaracal, other contributors)</p></li>
</ul>
</section>
<section id="translations">
<h2>Translations<a class="headerlink" href="#translations" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>New Latin (la) translation (jamalainm)</p></li>
<li><p>New German (de) translation (Zhuraj)</p></li>
<li><p>Updated Italian translation (rpolve)</p></li>
<li><p>Updated Swedish translation</p></li>
</ul>
</section>
<section id="utils">
<h2>Utils<a class="headerlink" href="#utils" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>New <code class="docutils literal notranslate"><span class="pre">utils.format_grid</span></code> for easily displaying long lists of items in a block. This is now used for the default help display.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">utils.repeat</span></code> and <code class="docutils literal notranslate"><span class="pre">utils.unrepeat</span></code> as shortcuts to TickerHandler add/remove, similar
to how <code class="docutils literal notranslate"><span class="pre">utils.delay</span></code> is a shortcut for TaskHandler add.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">utils/verb_conjugation</span></code> for automatic verb conjugation (English only). This
is useful for implementing actor-stance emoting for sending a string to different targets.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">utils.evmenu.ask_yes_no</span></code> is a helper function that makes it easy to ask a yes/no question
to the user and respond to their input. This complements the existing <code class="docutils literal notranslate"><span class="pre">get_input</span></code> helper.</p></li>
<li><p>New <code class="docutils literal notranslate"><span class="pre">tasks</span></code> command for managing tasks started with <code class="docutils literal notranslate"><span class="pre">utils.delay</span></code> (PR by davewiththenicehat)</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">.deserialize()</span></code> method to <code class="docutils literal notranslate"><span class="pre">_Saver*</span></code> structures to help completely
decouple structures from database without needing separate import.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">run_in_main_thread</span></code> as a helper for those wanting to code server code
from a web view.</p></li>
<li><p>Update <code class="docutils literal notranslate"><span class="pre">evennia.utils.logger</span></code> to use Twisteds new logging API. No change in Evennia API
except more standard aliases logger.error/info/exception/debug etc can now be used.</p></li>
<li><p>Made <code class="docutils literal notranslate"><span class="pre">utils.iter_to_str</span></code> format prettier strings, using Oxford comma.</p></li>
<li><p>Move <code class="docutils literal notranslate"><span class="pre">create_*</span></code> functions into db managers, leaving <code class="docutils literal notranslate"><span class="pre">utils.create</span></code> only being
wrapper functions (consistent with <code class="docutils literal notranslate"><span class="pre">utils.search</span></code>). No change of api otherwise.</p></li>
</ul>
</section>
<section id="locks">
<h2>Locks<a class="headerlink" href="#locks" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>New <code class="docutils literal notranslate"><span class="pre">search:</span></code> lock type used to completely hide an object from being found by
the <code class="docutils literal notranslate"><span class="pre">DefaultObject.search</span></code> (<code class="docutils literal notranslate"><span class="pre">caller.search</span></code>) method. (CloudKeeper)</p></li>
<li><p>New default for <code class="docutils literal notranslate"><span class="pre">holds()</span></code> lockfunc - changed from default of <code class="docutils literal notranslate"><span class="pre">True</span></code> to default of <code class="docutils literal notranslate"><span class="pre">False</span></code> in order to disallow dropping nonsensical things (such as things you dont hold).</p></li>
</ul>
</section>
<section id="hook-changes">
<h2>Hook changes<a class="headerlink" href="#hook-changes" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Changed all <code class="docutils literal notranslate"><span class="pre">at_before/after_*</span></code> hooks to <code class="docutils literal notranslate"><span class="pre">at_pre/post_*</span></code> for consistency
across Evennia (the old names still work but are deprecated)</p></li>
<li><p>New <code class="docutils literal notranslate"><span class="pre">at_pre_object_leave(obj,</span> <span class="pre">destination)</span></code> method on <code class="docutils literal notranslate"><span class="pre">Objects</span></code>.</p></li>
<li><p>New <code class="docutils literal notranslate"><span class="pre">at_server_init()</span></code> hook called before all other startup hooks for all
startup modes. Used for more generic overriding (volund)</p></li>
<li><p>New <code class="docutils literal notranslate"><span class="pre">at_pre_object_receive(obj,</span> <span class="pre">source_location)</span></code> method on Objects. Called on
destination, mimicking behavior of <code class="docutils literal notranslate"><span class="pre">at_pre_move</span></code> hook - returning False will abort move.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Object.normalize_name</span></code> and <code class="docutils literal notranslate"><span class="pre">.validate_name</span></code> added to (by default) enforce latinify
on character name and avoid potential exploits using clever Unicode chars (trhr)</p></li>
<li><p>Make <code class="docutils literal notranslate"><span class="pre">object.search</span></code> support stacks=0 keyword - if <code class="docutils literal notranslate"><span class="pre">&gt;0</span></code>, the method will return
N identical matches instead of triggering a multi-match error.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">tags.has()</span></code> method for checking if an object has a tag or tags (PR by ChrisLR)</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">Msg.db_receiver_external</span></code> field to allowe external, string-id message-receivers.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">$pron()</span></code> and <code class="docutils literal notranslate"><span class="pre">$You()</span></code> inlinefuncs for pronoun parsing in actor-stance strings using <code class="docutils literal notranslate"><span class="pre">msg_contents</span></code>.</p></li>
</ul>
</section>
<section id="command-changes">
<h2>Command changes<a class="headerlink" href="#command-changes" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Change default multi-match syntax from <code class="docutils literal notranslate"><span class="pre">1-obj</span></code>, <code class="docutils literal notranslate"><span class="pre">2-obj</span></code> to <code class="docutils literal notranslate"><span class="pre">obj-1</span></code>, <code class="docutils literal notranslate"><span class="pre">obj-2</span></code>, which seems to be what most expect.</p></li>
<li><p>Split <code class="docutils literal notranslate"><span class="pre">return_appearance</span></code> hook with helper methods and have it use a template
string in order to make it easier to override.</p></li>
<li><p>Command executions now done on copies to make sure <code class="docutils literal notranslate"><span class="pre">yield</span></code> dont cause crossovers. Add
<code class="docutils literal notranslate"><span class="pre">Command.retain_instance</span></code> flag for reusing the same command instance.</p></li>
<li><p>Allow sending messages with <code class="docutils literal notranslate"><span class="pre">page/tell</span></code> without a <code class="docutils literal notranslate"><span class="pre">=</span></code> if target name contains no spaces.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">typeclass</span></code> command will now correctly search the correct database-table for the target
obj (avoids mistakenly assigning an AccountDB-typeclass to a Character etc).</p></li>
<li><p>Merged <code class="docutils literal notranslate"><span class="pre">script</span></code> and <code class="docutils literal notranslate"><span class="pre">scripts</span></code> commands into one, for both managing global- and
on-object Scripts. Moved <code class="docutils literal notranslate"><span class="pre">CmdScripts</span></code> and <code class="docutils literal notranslate"><span class="pre">CmdObjects</span></code> to <code class="docutils literal notranslate"><span class="pre">commands/default/building.py</span></code>.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">channel</span></code> commands replace all old channel-related commands, such as <code class="docutils literal notranslate"><span class="pre">cset</span></code> etc</p></li>
<li><p>Expand <code class="docutils literal notranslate"><span class="pre">examine</span></code> commands code to much more extensible and modular. Show
attribute categories and value types (when not strings).</p>
<ul>
<li><p>Add ability to examine <code class="docutils literal notranslate"><span class="pre">/script</span></code> and <code class="docutils literal notranslate"><span class="pre">/channel</span></code> entities with <code class="docutils literal notranslate"><span class="pre">examine</span></code> command.</p></li>
</ul>
</li>
<li><p>Add support for <code class="docutils literal notranslate"><span class="pre">$dbref()</span></code> and <code class="docutils literal notranslate"><span class="pre">$search</span></code> when assigning an Attribute value
with the <code class="docutils literal notranslate"><span class="pre">set</span></code> command. This allows assigning real objects from in-game.</p></li>
<li><p>Have <code class="docutils literal notranslate"><span class="pre">type/force</span></code> default to <code class="docutils literal notranslate"><span class="pre">update</span></code>-mode rather than <code class="docutils literal notranslate"><span class="pre">reset</span></code>mode and add more verbose
warning when using reset mode.</p></li>
</ul>
</section>
<section id="coding-improvement-highlights">
<h2>Coding improvement highlights<a class="headerlink" href="#coding-improvement-highlights" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>The db pickle-serializer now checks for methods <code class="docutils literal notranslate"><span class="pre">__serialize_dbobjs__</span></code> and <code class="docutils literal notranslate"><span class="pre">__deserialize_dbobjs__</span></code> to allow custom packing/unpacking of nested dbobjs, to allow storing in Attribute. See <a class="reference internal" href="../Components/Attributes.html"><span class="doc std std-doc">Attributes</span></a> documentation.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> mixin to default game folder template as an easy, ready-made
way to override features on all ObjectDB-inheriting objects easily.
source location, mimicking behavior of <code class="docutils literal notranslate"><span class="pre">at_pre_move</span></code> hook - returning False will abort move.</p></li>
<li><p>New Unit test parent classes, for use both in Evenia core and in mygame. Restructured unit tests to always honor default settings.</p></li>
</ul>
</section>
<section id="other">
<h2>Other<a class="headerlink" href="#other" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Homogenize manager search methods to always return querysets and not sometimes querysets and sometimes lists.</p></li>
<li><p>Attribute/NAttribute got a homogenous representation, using intefaces, both
<code class="docutils literal notranslate"><span class="pre">AttributeHandler</span></code> and <code class="docutils literal notranslate"><span class="pre">NAttributeHandler</span></code> has same api now.</p></li>
<li><p>Added <code class="docutils literal notranslate"><span class="pre">content_types</span></code> indexing to DefaultObjects ContentsHandler. (volund)</p></li>
<li><p>Made most of the networking classes such as Protocols and the SessionHandlers
replaceable via <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> for modding enthusiasts. (volund)</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">initial_setup.py</span></code> file can now be substituted in <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> to customize
initial game database state. (volund)</p></li>
<li><p>Make IP throttle use Django-based cache system for optional persistence (PR by strikaco)</p></li>
<li><p>In modules given by <code class="docutils literal notranslate"><span class="pre">settings.PROTOTYPE_MODULES</span></code>, spawner will now first look for a global
list <code class="docutils literal notranslate"><span class="pre">PROTOTYPE_LIST</span></code> of dicts before loading all dicts in the module as prototypes.
concept of a dynamically created <code class="docutils literal notranslate"><span class="pre">ChannelCmdSet</span></code>.</p></li>
<li><p>Prototypes now allow setting <code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code> directly to a prototype-dict.
This makes it easier when dynamically building in-module prototypes.</p></li>
<li><p>Make <code class="docutils literal notranslate"><span class="pre">&#64;lazy_property</span></code> decorator create read/delete-protected properties. This is because its used for handlers, and e.g. self.locks=[] is a common beginner mistake.</p></li>
<li><p>Change <code class="docutils literal notranslate"><span class="pre">settings.COMMAND_DEFAULT_ARG_REGEX</span></code> default from <code class="docutils literal notranslate"><span class="pre">None</span></code> to a regex meaning that
a space or <code class="docutils literal notranslate"><span class="pre">/</span></code> must separate the cmdname and args. This better fits common expectations.</p></li>
<li><p>Add <code class="docutils literal notranslate"><span class="pre">settings.MXP_ENABLED=True</span></code> and <code class="docutils literal notranslate"><span class="pre">settings.MXP_OUTGOING_ONLY=True</span></code> as sane defaults, to avoid known security issues with players entering MXP links.</p></li>
<li><p>Made <code class="docutils literal notranslate"><span class="pre">MonitorHandler.add/remove</span></code> support <code class="docutils literal notranslate"><span class="pre">category</span></code> for monitoring Attributes with a category (before only key was used, ignoring category entirely).</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../Contribs/Contribs-Overview.html" title="Contribs"
>next</a> |</li>
<li class="right" >
<a href="Changelog.html" title="Changelog"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Evennia 1.0 Release Notes</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,238 @@
<!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>Setting up PyCharm with Evennia &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Changelog" href="Changelog.html" />
<link rel="prev" title="Continuous Integration (CI)" href="Continuous-Integration.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Changelog.html" title="Changelog"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Continuous-Integration.html" title="Continuous Integration (CI)"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Setting up PyCharm with Evennia</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Setting up PyCharm with Evennia</a><ul>
<li><a class="reference internal" href="#debug-evennia-from-inside-pycharm">Debug Evennia from inside PyCharm</a></li>
<li><a class="reference internal" href="#run-evennia-from-inside-pycharm">Run Evennia from inside PyCharm</a><ul>
<li><a class="reference internal" href="#alternative-config-utilizing-logfiles-as-source-of-data">Alternative config - utilizing logfiles as source of data</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Continuous-Integration.html"
title="previous chapter">Continuous Integration (CI)</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Changelog.html"
title="next chapter">Changelog</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Setting-up-PyCharm.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="setting-up-pycharm-with-evennia">
<h1>Setting up PyCharm with Evennia<a class="headerlink" href="#setting-up-pycharm-with-evennia" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="https://www.jetbrains.com/pycharm/">PyCharm</a> is a Python developers IDE from Jetbrains available for Windows, Mac and Linux. It is a commercial product but offer free trials, a scaled-down community edition and also generous licenses for OSS projects like Evennia.</p>
<blockquote>
<div><p>This page was originally tested on Windows (so use Windows-style path examples), but should work the same for all platforms.</p>
</div></blockquote>
<p>First, install Evennia on your local machine with [[Getting Started]]. If youre new to PyCharm, loading your project is as easy as selecting the <code class="docutils literal notranslate"><span class="pre">Open</span></code> option when PyCharm starts, and browsing to your game folder (the one created with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">--init</span></code>). We refer to it as <code class="docutils literal notranslate"><span class="pre">mygame</span></code> here.</p>
<p>If you want to be able to examine evennias core code or the scripts inside your virtualenv, youll
need to add them to your project too:</p>
<ol class="simple">
<li><p>Go to <code class="docutils literal notranslate"><span class="pre">File</span> <span class="pre">&gt;</span> <span class="pre">Open...</span></code></p></li>
<li><p>Select the folder (i.e. the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> root)</p></li>
<li><p>Select “Open in current window” and “Add to currently opened projects”</p></li>
</ol>
<p>Its a good idea to set up the interpreter this before attempting anything further. The rest of this page assumes your project is already configured in PyCharm.</p>
<ol class="simple">
<li><p>Go to <code class="docutils literal notranslate"><span class="pre">File</span> <span class="pre">&gt;</span> <span class="pre">Settings...</span> <span class="pre">&gt;</span> <span class="pre">Project:</span> <span class="pre">\&lt;mygame\&gt;</span> <span class="pre">&gt;</span> <span class="pre">Project</span> <span class="pre">Interpreter</span></code></p></li>
<li><p>Click the Gear symbol <code class="docutils literal notranslate"><span class="pre">&gt;</span> <span class="pre">Add</span> <span class="pre">local</span></code></p></li>
<li><p>Navigate to your <code class="docutils literal notranslate"><span class="pre">evenv/scripts</span> <span class="pre">directory</span></code>, and select Python.exe</p></li>
</ol>
<p>Enjoy seeing all your imports checked properly, setting breakpoints, and live variable watching!</p>
<section id="debug-evennia-from-inside-pycharm">
<h2>Debug Evennia from inside PyCharm<a class="headerlink" href="#debug-evennia-from-inside-pycharm" title="Permalink to this headline"></a></h2>
<ol class="simple">
<li><p>Launch Evennia in your preferred way (usually from a console/terminal)</p></li>
<li><p>Open your project in PyCharm</p></li>
<li><p>In the PyCharm menu, select <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">&gt;</span> <span class="pre">Attach</span> <span class="pre">to</span> <span class="pre">Local</span> <span class="pre">Process...</span></code></p></li>
<li><p>From the list, pick the <code class="docutils literal notranslate"><span class="pre">twistd</span></code> process with the <code class="docutils literal notranslate"><span class="pre">server.py</span></code> parameter (Example: <code class="docutils literal notranslate"><span class="pre">twistd.exe</span> <span class="pre">--nodaemon</span> <span class="pre">--logfile=\&lt;mygame\&gt;\server\logs\server.log</span> <span class="pre">--python=\&lt;evennia</span> <span class="pre">repo\&gt;\evennia\server\server.py</span></code>)</p></li>
</ol>
<p>Of course you can attach to the <code class="docutils literal notranslate"><span class="pre">portal</span></code> process as well. If you want to debug the Evennia launcher
or runner for some reason (or just learn how they work!), see Run Configuration below.</p>
<blockquote>
<div><p>NOTE: Whenever you reload Evennia, the old Server process will die and a new one start. So when you restart you have to detach from the old and then reattach to the new process that was created.</p>
</div></blockquote>
<blockquote>
<div><p>To make the process less tedious you can apply a filter in settings to show only the <a class="reference external" href="http://server.py">server.py</a> process in the list. To do that navigate to: <code class="docutils literal notranslate"><span class="pre">Settings/Preferences</span> <span class="pre">|</span> <span class="pre">Build,</span> <span class="pre">Execution,</span> <span class="pre">Deployment</span> <span class="pre">|</span> <span class="pre">Python</span> <span class="pre">Debugger</span></code> and then in <code class="docutils literal notranslate"><span class="pre">Attach</span> <span class="pre">to</span> <span class="pre">process</span></code> field put in: <code class="docutils literal notranslate"><span class="pre">twistd.exe&quot;</span> <span class="pre">--nodaemon</span></code>. This is an example for windows, I dont have a working mac/linux box.</p>
</div></blockquote>
<p><img alt="Example process filter configuration" src="https://i.imgur.com/vkSheR8.png" /></p>
</section>
<section id="run-evennia-from-inside-pycharm">
<h2>Run Evennia from inside PyCharm<a class="headerlink" href="#run-evennia-from-inside-pycharm" title="Permalink to this headline"></a></h2>
<p>This configuration allows you to launch Evennia from inside PyCharm. Besides convenience, it also allows suspending and debugging the evennia_launcher or evennia_runner at points earlier than you could by running them externally and attaching. In fact by the time the server and/or portal are running the launcher will have exited already.</p>
<ol class="simple">
<li><p>Go to <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">&gt;</span> <span class="pre">Edit</span> <span class="pre">Configutations...</span></code></p></li>
<li><p>Click the plus-symbol to add a new configuration and choose Python</p></li>
<li><p>Add the script: <code class="docutils literal notranslate"><span class="pre">\&lt;yourrepo\&gt;\evenv\Scripts\evennia_launcher.py</span></code> (substitute your virtualenv if its not named <code class="docutils literal notranslate"><span class="pre">evenv</span></code>)</p></li>
<li><p>Set script parameters to: <code class="docutils literal notranslate"><span class="pre">start</span> <span class="pre">-l</span></code> (-l enables console logging)</p></li>
<li><p>Ensure the chosen interpreter is from your virtualenv</p></li>
<li><p>Set Working directory to your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> folder (not evenv nor evennia)</p></li>
<li><p>You can refer to the PyCharm documentation for general info, but youll want to set at least a config name (like “MyMUD start” or similar).</p></li>
</ol>
<p>Now set up a “stop” configuration by following the same steps as above, but set your Script parameters to: stop (and name the configuration appropriately).</p>
<p>A dropdown box holding your new configurations should appear next to your PyCharm run button. Select MyMUD start and press the debug icon to begin debugging. Depending on how far you let the program run, you may need to run your “MyMUD stop” config to actually stop the server, before youll be able start it again.</p>
<section id="alternative-config-utilizing-logfiles-as-source-of-data">
<h3>Alternative config - utilizing logfiles as source of data<a class="headerlink" href="#alternative-config-utilizing-logfiles-as-source-of-data" title="Permalink to this headline"></a></h3>
<p>This configuration takes a bit different approach as instead of focusing on getting the data back through logfiles. Reason for that is this way you can easily separate data streams, for example you rarely want to follow both server and portal at the same time, and this will allow it. This will also make sure to stop the evennia before starting it, essentially working as reload command (it will also include instructions how to disable that part of functionality). We will start by defining a configuration that will stop evennia. This assumes that <code class="docutils literal notranslate"><span class="pre">upfire</span></code> is your pycharm project name, and also the game name, hence the <code class="docutils literal notranslate"><span class="pre">upfire/upfire</span></code> path.</p>
<ol class="simple">
<li><p>Go to <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">&gt;</span> <span class="pre">Edit</span> <span class="pre">Configutations...</span></code>\</p></li>
<li><p>Click the plus-symbol to add a new configuration and choose the python interpreter to use (should be project default)</p></li>
<li><p>Name the configuration as “stop evennia” and fill rest of the fields accordingly to the image:
<img alt="Stop run configuration" src="https://i.imgur.com/gbkXhlG.png" /></p></li>
<li><p>Press <code class="docutils literal notranslate"><span class="pre">Apply</span></code></p></li>
</ol>
<p>Now we will define the start/reload command that will make sure that evennia is not running already, and then start the server in one go.</p>
<ol class="simple">
<li><p>Go to <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">&gt;</span> <span class="pre">Edit</span> <span class="pre">Configutations...</span></code>\</p></li>
<li><p>Click the plus-symbol to add a new configuration and choose the python interpreter to use (should be project default)</p></li>
<li><p>Name the configuration as “start evennia” and fill rest of the fields accordingly to the image:
<img alt="Start run configuration" src="https://i.imgur.com/5YEjeHq.png" /></p></li>
<li><p>Navigate to the <code class="docutils literal notranslate"><span class="pre">Logs</span></code> tab and add the log files you would like to follow. The picture shows
adding <code class="docutils literal notranslate"><span class="pre">portal.log</span></code> which will show itself in <code class="docutils literal notranslate"><span class="pre">portal</span></code> tab when running:
<img alt="Configuring logs following" src="https://i.imgur.com/gWYuOWl.png" /></p></li>
<li><p>Skip the following steps if you dont want the launcher to stop evennia before starting.</p></li>
<li><p>Head back to <code class="docutils literal notranslate"><span class="pre">Configuration</span></code> tab and press the <code class="docutils literal notranslate"><span class="pre">+</span></code> sign at the bottom, under <code class="docutils literal notranslate"><span class="pre">Before</span> <span class="pre">launch....</span></code>
and select <code class="docutils literal notranslate"><span class="pre">Run</span> <span class="pre">another</span> <span class="pre">configuration</span></code> from the submenu that will pop up.</p></li>
<li><p>Click <code class="docutils literal notranslate"><span class="pre">stop</span> <span class="pre">evennia</span></code> and make sure that its added to the list like on the image above.</p></li>
<li><p>Click <code class="docutils literal notranslate"><span class="pre">Apply</span></code> and close the run configuration window.</p></li>
</ol>
<p>You are now ready to go, and if you will fire up <code class="docutils literal notranslate"><span class="pre">start</span> <span class="pre">evennia</span></code> configuration you should see
following in the bottom panel:
<img alt="Example of running alternative configuration" src="https://i.imgur.com/nTfpC04.png" />
and you can click through the tabs to check appropriate logs, or even the console output as it is
still running in interactive mode.</p>
</section>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Changelog.html" title="Changelog"
>next</a> |</li>
<li class="right" >
<a href="Continuous-Integration.html" title="Continuous Integration (CI)"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Setting up PyCharm with Evennia</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,204 @@
<!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>Soft Code &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Coding using Version Control" href="Version-Control.html" />
<link rel="prev" title="Default Command Syntax" href="Default-Command-Syntax.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Version-Control.html" title="Coding using Version Control"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Default-Command-Syntax.html" title="Default Command Syntax"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="Default-Command-Syntax.html" accesskey="U">Default Command Syntax</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Soft Code</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Soft Code</a><ul>
<li><a class="reference internal" href="#examples-of-softcode">Examples of Softcode</a></li>
<li><a class="reference internal" href="#problems-with-softcode">Problems with Softcode</a></li>
<li><a class="reference internal" href="#changing-times">Changing Times</a></li>
<li><a class="reference internal" href="#our-solution">Our Solution</a></li>
<li><a class="reference internal" href="#your-solution">Your Solution</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Default-Command-Syntax.html"
title="previous chapter">Default Command Syntax</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Version-Control.html"
title="next chapter">Coding using Version Control</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Soft-Code.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<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 simple programming language that was created for in-game development on TinyMUD derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea was that by providing a stripped down, minimalistic language for in-game use, you could allow quick and easy building and game development to happen without builders having to learn the hardcode language for those servers (C/C++). There is an added benefit of not having to have to hand out shell access to all developers. Permissions in softcode 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>
<section id="examples-of-softcode">
<h2>Examples of Softcode<a class="headerlink" href="#examples-of-softcode" title="Permalink to this headline"></a></h2>
<p>Here is a simple Hello World! command:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="w"> </span>@set<span class="w"> </span><span class="nv">me</span><span class="o">=</span>HELLO_WORLD.C:<span class="nv">$hello</span>:@pemit<span class="w"> </span>%#<span class="o">=</span>Hello<span class="w"> </span>World!
</pre></div>
</div>
<p>Pasting this into a MUD client, sending it to a MUX/MUSH server and typing hello will theoretically yield Hello World!, assuming certain flags are not set on your account object.</p>
<p>Setting attributes in Softcode is done via <code class="docutils literal notranslate"><span class="pre">&#64;set</span></code>. Softcode also allows the use of the ampersand (<code class="docutils literal notranslate"><span class="pre">&amp;</span></code>) symbol. This shorter version looks like this:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="p">&amp;</span>HELLO_WORLD.C<span class="w"> </span><span class="nv">me</span><span class="o">=</span><span class="nv">$hello</span>:@pemit<span class="w"> </span>%#<span class="o">=</span>Hello<span class="w"> </span>World!
</pre></div>
</div>
<p>We could also read the text from an attribute which is retrieved when emitting:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="p">&amp;</span>HELLO_VALUE.D<span class="w"> </span><span class="nv">me</span><span class="o">=</span>Hello<span class="w"> </span>World
<span class="w"> </span><span class="p">&amp;</span>HELLO_WORLD.C<span class="w"> </span><span class="nv">me</span><span class="o">=</span><span class="nv">$hello</span>:@pemit<span class="w"> </span>%#<span class="o">=[</span>v<span class="o">(</span>HELLO_VALUE.D<span class="o">)]</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">v()</span></code> function returns the <code class="docutils literal notranslate"><span class="pre">HELLO_VALUE.D</span></code> attribute on the object that the command resides (<code class="docutils literal notranslate"><span class="pre">me</span></code>, which is yourself in this case). This should yield the same output as the first example.</p>
<p>If you are curious about how MUSH/MUX Softcode works, take a look at some external resources:</p>
<ul class="simple">
<li><p><a class="reference external" href="https://wiki.tinymux.org/index.php/Softcode">https://wiki.tinymux.org/index.php/Softcode</a></p></li>
<li><p><a class="reference external" href="https://www.duh.com/discordia/mushman/man2x1">https://www.duh.com/discordia/mushman/man2x1</a></p></li>
</ul>
</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 those are not designed properly.</p>
<p>Also, Softcode is not a standardized language. Different servers each have their own slight variations. Code tools and resources are also limited to the documentation from those servers.</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, 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 without shell access. However, the rise of modern code collaboration tools (such as private github/gitlab repos) has made it trivial to collaborate on code.</p>
</section>
<section id="our-solution">
<h2>Our Solution<a class="headerlink" href="#our-solution" title="Permalink to this headline"></a></h2>
<p>Evennia shuns in-game softcode for on-disk Python modules. Python is a popular, mature and professional programming language. 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; 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 (aka Softcode). Advanced coding in Evennia is primarily intended to be done outside the game, in full-fledged Python modules (what MUSH would call hardcode). Advanced building is best handled by extending Evennias command system with your own sophisticated building commands.</p>
<p>In Evennia you develop your MU like you would any piece of modern software - using your favorite code editor/IDE and online code sharing tools.</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.</p>
<p>In default Evennia, the <span class="xref myst">Funcparser</span> system allows for simple remapping of text on-demand without becomeing a full softcode language. The <span class="xref myst">contribs</span> has several tools and utililities to start from when adding more complex in-game building.</p>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Version-Control.html" title="Coding using Version Control"
>next</a> |</li>
<li class="right" >
<a href="Default-Command-Syntax.html" title="Default Command Syntax"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="Default-Command-Syntax.html" >Default Command Syntax</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Soft Code</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,448 @@
<!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>Unit Testing &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Profiling" href="Profiling.html" />
<link rel="prev" title="Debugging" href="Debugging.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Profiling.html" title="Profiling"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Debugging.html" title="Debugging"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Unit Testing</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Unit Testing</a><ul>
<li><a class="reference internal" href="#running-the-evennia-test-suite">Running the Evennia test suite</a></li>
<li><a class="reference internal" href="#running-custom-game-dir-unit-tests">Running custom game-dir unit tests</a></li>
<li><a class="reference internal" href="#writing-new-unit-tests">Writing new unit tests</a><ul>
<li><a class="reference internal" href="#using-the-evennia-testing-classes">Using the Evennia testing classes</a><ul>
<li><a class="reference internal" href="#classes-for-testing-your-game-dir">Classes for testing your game dir</a></li>
<li><a class="reference internal" href="#classes-for-testing-evennia-core">Classes for testing Evennia core</a></li>
</ul>
</li>
<li><a class="reference internal" href="#unit-testing-contribs-with-custom-models">Unit testing contribs with custom models</a></li>
<li><a class="reference internal" href="#a-note-on-making-the-test-runner-faster">A note on making the test runner faster</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Debugging.html"
title="previous chapter">Debugging</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Profiling.html"
title="next chapter">Profiling</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Unit-Testing.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="unit-testing">
<h1>Unit Testing<a class="headerlink" href="#unit-testing" title="Permalink to this headline"></a></h1>
<p><em>Unit testing</em> means testing components of a program in isolation from each other to make sure every part works on its own before using it with others. Extensive testing helps avoid new updates causing unexpected side effects as well as alleviates general code rot (a more comprehensive wikipedia article on unit testing can be found <a class="reference external" href="https://en.wikipedia.org/wiki/Unit_test">here</a>).</p>
<p>A typical unit test set calls some function or method with a given input, looks at the result and makes sure that this result looks as expected. Rather than having lots of stand-alone test programs, Evennia makes use of a central <em>test runner</em>. This is a program that gathers all available tests all over the Evennia source code (called <em>test suites</em>) and runs them all in one go. Errors and tracebacks are reported.</p>
<p>By default Evennia only tests itself. But you can also add your own tests to your game code and have Evennia run those for you.</p>
<section id="running-the-evennia-test-suite">
<h2>Running the Evennia test suite<a class="headerlink" href="#running-the-evennia-test-suite" title="Permalink to this headline"></a></h2>
<p>To run the full Evennia test suite, go to your game folder and issue the command</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test evennia
</pre></div>
</div>
<p>This will run all the evennia tests using the default settings. You could also run only a subset of
all tests by specifying a subpackage of the library:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test evennia.commands.default
</pre></div>
</div>
<p>A temporary database will be instantiated to manage the tests. If everything works out you will see
how many tests were run and how long it took. If something went wrong you will get error messages.
If you contribute to Evennia, this is a useful sanity check to see you havent introduced an
unexpected bug.</p>
</section>
<section id="running-custom-game-dir-unit-tests">
<h2>Running custom game-dir unit tests<a class="headerlink" href="#running-custom-game-dir-unit-tests" title="Permalink to this headline"></a></h2>
<p>If you have implemented your own tests for your game you can run them from your game dir
with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py .
</pre></div>
</div>
<p>The period (<code class="docutils literal notranslate"><span class="pre">.</span></code>) means to run all tests found in the current directory and all subdirectories. You
could also specify, say, <code class="docutils literal notranslate"><span class="pre">typeclasses</span></code> or <code class="docutils literal notranslate"><span class="pre">world</span></code> if you wanted to just run tests in those subdirs.</p>
<p>An important thing to note is that those tests will all be run using the <em>default Evennia settings</em>.
To run the tests with your own settings file you must use the <code class="docutils literal notranslate"><span class="pre">--settings</span></code> option:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py .
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">--settings</span></code> option of Evennia takes a file name in the <code class="docutils literal notranslate"><span class="pre">mygame/server/conf</span></code> folder. It is
normally used to swap settings files for testing and development. In combination with <code class="docutils literal notranslate"><span class="pre">test</span></code>, it
forces Evennia to use this settings file over the default one.</p>
<p>You can also test specific things by giving their path</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py world.tests.YourTest
</pre></div>
</div>
</section>
<section id="writing-new-unit-tests">
<h2>Writing new unit tests<a class="headerlink" href="#writing-new-unit-tests" title="Permalink to this headline"></a></h2>
<p>Evennias test suite makes use of Django unit test system, which in turn relies on Pythons
<em>unittest</em> module.</p>
<p>To make the test runner find the tests, they must be put in a module named <code class="docutils literal notranslate"><span class="pre">test*.py</span></code> (so <code class="docutils literal notranslate"><span class="pre">test.py</span></code>,
<code class="docutils literal notranslate"><span class="pre">tests.py</span></code> etc). Such a test module will be found wherever it is in the package. It can be a good
idea to look at some of Evennias <code class="docutils literal notranslate"><span class="pre">tests.py</span></code> modules to see how they look.</p>
<p>Inside the module you need to put a class inheriting (at any distance) from <code class="docutils literal notranslate"><span class="pre">unittest.TestCase</span></code>. Each
method on that class that starts with <code class="docutils literal notranslate"><span class="pre">test_</span></code> will be run separately as a unit test. There
are two special, optional methods <code class="docutils literal notranslate"><span class="pre">setUp</span></code> and <code class="docutils literal notranslate"><span class="pre">tearDown</span></code> that will (if you define them) run before
<em>every</em> test. This can be useful for setting up and deleting things.</p>
<p>To actually test things, you use special <code class="docutils literal notranslate"><span class="pre">assert...</span></code> methods on the class. Most common on is
<code class="docutils literal notranslate"><span class="pre">assertEqual</span></code>, which makes sure a result is what you expect it to be.</p>
<p>Heres an example of the principle. Lets assume you put this in <code class="docutils literal notranslate"><span class="pre">mygame/world/tests.py</span></code>
and want to test a function in <code class="docutils literal notranslate"><span class="pre">mygame/world/myfunctions.py</span></code></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># in a module tests.py somewhere i your game dir</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
<span class="c1"># the function we want to test</span>
<span class="kn">from</span> <span class="nn">.myfunctions</span> <span class="kn">import</span> <span class="n">myfunc</span>
<span class="k">class</span> <span class="nc">TestObj</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="s2">&quot;This tests a function myfunc.&quot;</span>
<span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;done before every of the test_ * methods below&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span> <span class="o">=</span> <span class="n">create_object</span><span class="p">(</span><span class="s2">&quot;mytestobject&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">tearDown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;done after every test_* method below &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">test_return_value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;test method. Makes sure return value is as expected.&quot;&quot;&quot;</span>
<span class="n">actual_return</span> <span class="o">=</span> <span class="n">myfunc</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">)</span>
<span class="n">expected_return</span> <span class="o">=</span> <span class="s2">&quot;This is the good object &#39;mytestobject&#39;.&quot;</span>
<span class="c1"># test</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">expected_return</span><span class="p">,</span> <span class="n">actual_return</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_alternative_call</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;test method. Calls with a keyword argument.&quot;&quot;&quot;</span>
<span class="n">actual_return</span> <span class="o">=</span> <span class="n">myfunc</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span> <span class="n">bad</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">expected_return</span> <span class="o">=</span> <span class="s2">&quot;This is the baaad object &#39;mytestobject&#39;.&quot;</span>
<span class="c1"># test</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">expected_return</span><span class="p">,</span> <span class="n">actual_return</span><span class="p">)</span>
</pre></div>
</div>
<p>To test this, run</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py .
</pre></div>
</div>
<p>to run the entire test module</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py world.tests
</pre></div>
</div>
<p>or a specific class:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py world.tests.TestObj
</pre></div>
</div>
<p>You can also run a specific test:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>evennia test --settings settings.py world.tests.TestObj.test_alternative_call
</pre></div>
</div>
<p>You might also want to read the <a class="reference external" href="https://docs.python.org/library/unittest.html">Python documentation for the unittest module</a>.</p>
<section id="using-the-evennia-testing-classes">
<h3>Using the Evennia testing classes<a class="headerlink" href="#using-the-evennia-testing-classes" title="Permalink to this headline"></a></h3>
<p>Evennia offers many custom testing classes that helps with testing Evennia features.
They are all found in <a class="reference internal" href="../api/evennia.utils.test_resources.html#evennia-utils-test-resources"><span class="std std-ref">evennia.utils.test_resources</span></a>. Note that
these classes implement the <code class="docutils literal notranslate"><span class="pre">setUp</span></code> and <code class="docutils literal notranslate"><span class="pre">tearDown</span></code> already, so if you want to add stuff in them
yourself you should remember to use e.g. <code class="docutils literal notranslate"><span class="pre">super().setUp()</span></code> in your code.</p>
<section id="classes-for-testing-your-game-dir">
<h4>Classes for testing your game dir<a class="headerlink" href="#classes-for-testing-your-game-dir" title="Permalink to this headline"></a></h4>
<p>These all use whatever setting you pass to them and works well for testing code in your game dir.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">EvenniaTest</span></code> - this sets up a full object environment for your test. All the created entities
can be accesses as properties on the class:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">.account</span></code> - A fake <a class="reference internal" href="../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount" title="evennia.accounts.accounts.DefaultAccount"><span class="xref myst py py-class">Account</span></a> named “TestAccount”.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.account2</span></code> - Another account named “TestAccount2”</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">char1</span></code> - A <a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultCharacter" title="evennia.objects.objects.DefaultCharacter"><span class="xref myst py py-class">Character</span></a> linked to <code class="docutils literal notranslate"><span class="pre">.account</span></code>, named <code class="docutils literal notranslate"><span class="pre">Char</span></code>.
This has Developer permissions but is not a superuser.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.char2</span></code> - Another character linked to <code class="docutils literal notranslate"><span class="pre">account</span></code>, named <code class="docutils literal notranslate"><span class="pre">Char2</span></code>. This has base permissions (player).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.obj1</span></code> - A regular <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">Object</span></a> named “Obj”.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.obj2</span></code> - Another object named “Obj2”.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.room1</span></code> - A <a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultRoom" title="evennia.objects.objects.DefaultRoom"><span class="xref myst py py-class">Room</span></a> named “Room”. Both characters and both
objects are located inside this room. It has a description of “room_desc”.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.room2</span></code> - Another room named “Room2”. It is empty and has no set description.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.exit</span></code> - An exit named “out” that leads from <code class="docutils literal notranslate"><span class="pre">.room1</span></code> to <code class="docutils literal notranslate"><span class="pre">.room2</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.script</span></code> - A <a class="reference internal" href="../api/evennia.scripts.scripts.html#evennia.scripts.scripts.DefaultScript" title="evennia.scripts.scripts.DefaultScript"><span class="xref myst py py-class">Script</span></a> named “Script”. Its an inert script
without a timing component.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">.session</span></code> - A fake <a class="reference internal" href="../api/evennia.server.serversession.html#evennia.server.serversession.ServerSession" title="evennia.server.serversession.ServerSession"><span class="xref myst py py-class">Session</span></a> that mimics a player
connecting to the game. It is used by <code class="docutils literal notranslate"><span class="pre">.account1</span></code> and has a sessid of 1.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">EvenniaCommandTest</span></code> - has the same environment like <code class="docutils literal notranslate"><span class="pre">EvenniaTest</span></code> but also adds a special
<a class="reference internal" href="../api/evennia.utils.test_resources.html#evennia.utils.test_resources.EvenniaCommandTestMixin.call" title="evennia.utils.test_resources.EvenniaCommandTestMixin.call"><span class="xref myst py py-meth">.call()</span></a> method specifically for
testing Evennia <a class="reference internal" href="../Components/Commands.html"><span class="doc std std-doc">Commands</span></a>. It allows you to compare what the command <em>actually</em>
returns to the player with what you expect. Read the <code class="docutils literal notranslate"><span class="pre">call</span></code> api doc for more info.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">EvenniaTestCase</span></code> - This is identical to the regular Python <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class, its
just there for naming symmetry with <code class="docutils literal notranslate"><span class="pre">BaseEvenniaTestCase</span></code> below.</p></li>
</ul>
<p>Heres an example of using <code class="docutils literal notranslate"><span class="pre">EvenniaTest</span></code></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in a test module</span>
<span class="kn">from</span> <span class="nn">evennia.utils.test_resources</span> <span class="kn">import</span> <span class="n">EvenniaTest</span>
<span class="k">class</span> <span class="nc">TestObject</span><span class="p">(</span><span class="n">EvenniaTest</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Remember that the testing class creates char1 and char2 inside room1 ...&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">test_object_search_character</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Check that char1 can search for char2 by name&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="o">.</span><span class="n">key</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_location_search</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Check so that char1 can find the current location by name&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">key</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">location</span><span class="p">)</span>
<span class="c1"># ...</span>
</pre></div>
</div>
<p>This example tests a custom command.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia.commands.default.tests</span> <span class="kn">import</span> <span class="n">EvenniaCommandTest</span>
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">command</span> <span class="k">as</span> <span class="n">mycommand</span>
<span class="k">class</span> <span class="nc">TestSet</span><span class="p">(</span><span class="n">EvenniaCommandTest</span><span class="p">):</span>
<span class="s2">&quot;tests the look command by simple call, using Char2 as a target&quot;</span>
<span class="k">def</span> <span class="nf">test_mycmd_char</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">call</span><span class="p">(</span><span class="n">mycommand</span><span class="o">.</span><span class="n">CmdMyLook</span><span class="p">(),</span> <span class="s2">&quot;Char2&quot;</span><span class="p">,</span> <span class="s2">&quot;Char2(#7)&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_mycmd_room</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="s2">&quot;tests the look command by simple call, with target as room&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">mycommand</span><span class="o">.</span><span class="n">CmdMyLook</span><span class="p">(),</span> <span class="s2">&quot;Room&quot;</span><span class="p">,</span>
<span class="s2">&quot;Room(#1)</span><span class="se">\n</span><span class="s2">room_desc</span><span class="se">\n</span><span class="s2">Exits: out(#3)</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;You see: Obj(#4), Obj2(#5), Char2(#7)&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>When using <code class="docutils literal notranslate"><span class="pre">.call</span></code>, you dont need to specify the entire string; you can just give the beginning
of it and if it matches, thats enough. Use <code class="docutils literal notranslate"><span class="pre">\n</span></code> to denote line breaks and (this is a special for
the <code class="docutils literal notranslate"><span class="pre">.call</span></code> helper), <code class="docutils literal notranslate"><span class="pre">||</span></code> to indicate multiple uses of <code class="docutils literal notranslate"><span class="pre">.msg()</span></code> in the Command. The <code class="docutils literal notranslate"><span class="pre">.call</span></code> helper
has a lot of arguments for mimicing different ways of calling a Command, so make sure to
<a class="reference internal" href="../api/evennia.utils.test_resources.html#evennia.utils.test_resources.EvenniaCommandTestMixin.call" title="evennia.utils.test_resources.EvenniaCommandTestMixin.call"><span class="xref myst py py-meth">read the API docs for .call()</span></a>.</p>
</section>
<section id="classes-for-testing-evennia-core">
<h4>Classes for testing Evennia core<a class="headerlink" href="#classes-for-testing-evennia-core" title="Permalink to this headline"></a></h4>
<p>These are used for testing Evennia itself. They provide the same resources as the classes
above but enforce Evennias default settings found in <code class="docutils literal notranslate"><span class="pre">evennia/settings_default.py</span></code>, ignoring
any settings changes in your game dir.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">BaseEvenniaTest</span></code> - all the default objects above but with enforced default settings</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">BaseEvenniaCommandTest</span></code> - for testing Commands, but with enforced default settings</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">BaseEvenniaTestCase</span></code> - no default objects, only enforced default settings</p></li>
</ul>
<p>There are also two special mixin classes. These are uses in the classes above, but may also
be useful if you want to mix your own testing classes:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">EvenniaTestMixin</span></code> - A class mixin that creates all test environment objects.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">EvenniaCommandMixin</span></code> - A class mixin that adds the <code class="docutils literal notranslate"><span class="pre">.call()</span></code> Command-tester helper.</p></li>
</ul>
<p>If you want to help out writing unittests for Evennia, take a look at Evennias <a class="reference external" href="https://coveralls.io/github/evennia/evennia">coveralls.io
page</a>. There you see which modules have any form of
test coverage and which does not. All help is appreciated!</p>
</section>
</section>
<section id="unit-testing-contribs-with-custom-models">
<h3>Unit testing contribs with custom models<a class="headerlink" href="#unit-testing-contribs-with-custom-models" title="Permalink to this headline"></a></h3>
<p>A special case is if you were to create a contribution to go to the <code class="docutils literal notranslate"><span class="pre">evennia/contrib</span></code> folder that
uses its <a class="reference internal" href="../Concepts/Models.html"><span class="doc std std-doc">own database models</span></a>. The problem with this is that Evennia (and Django) will
only recognize models in <code class="docutils literal notranslate"><span class="pre">settings.INSTALLED_APPS</span></code>. If a user wants to use your contrib, they will
be required to add your models to their settings file. But since contribs are optional you cannot
add the model to Evennias central <code class="docutils literal notranslate"><span class="pre">settings_default.py</span></code> file - this would always create your
optional models regardless of if the user wants them. But at the same time a contribution is a part
of the Evennia distribution and its unit tests should be run with all other Evennia tests using
<code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">test</span> <span class="pre">evennia</span></code>.</p>
<p>The way to do this is to only temporarily add your models to the <code class="docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code> directory when the test runs. here is an example of how to do it.</p>
<blockquote>
<div><p>Note that this solution, derived from this <a class="reference external" href="http://stackoverflow.com/questions/502916/django-how-to-create-a-model-dynamically-just-for-testing#503435">stackexchange answer</a> is currently untested! Please report your findings.</p>
</div></blockquote>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># a file contrib/mycontrib/tests.py</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">import</span> <span class="nn">django</span>
<span class="kn">from</span> <span class="nn">evennia.utils.test_resources</span> <span class="kn">import</span> <span class="n">BaseEvenniaTest</span>
<span class="n">OLD_DEFAULT_SETTINGS</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">INSTALLED_APPS</span>
<span class="n">DEFAULT_SETTINGS</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="n">INSTALLED_APPS</span><span class="o">=</span><span class="p">(</span>
<span class="s1">&#39;contrib.mycontrib.tests&#39;</span><span class="p">,</span>
<span class="p">),</span>
<span class="n">DATABASES</span><span class="o">=</span><span class="p">{</span>
<span class="s2">&quot;default&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ENGINE&quot;</span><span class="p">:</span> <span class="s2">&quot;django.db.backends.sqlite3&quot;</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="n">SILENCED_SYSTEM_CHECKS</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;1_7.W001&quot;</span><span class="p">],</span>
<span class="p">)</span>
<span class="k">class</span> <span class="nc">TestMyModel</span><span class="p">(</span><span class="n">BaseEvenniaTest</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">settings</span><span class="o">.</span><span class="n">configured</span><span class="p">:</span>
<span class="n">settings</span><span class="o">.</span><span class="n">configure</span><span class="p">(</span><span class="o">**</span><span class="n">DEFAULT_SETTINGS</span><span class="p">)</span>
<span class="n">django</span><span class="o">.</span><span class="n">setup</span><span class="p">()</span>
<span class="kn">from</span> <span class="nn">django.core.management</span> <span class="kn">import</span> <span class="n">call_command</span>
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">loading</span>
<span class="n">loading</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">loaded</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">call_command</span><span class="p">(</span><span class="s1">&#39;syncdb&#39;</span><span class="p">,</span> <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">tearDown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">settings</span><span class="o">.</span><span class="n">configure</span><span class="p">(</span><span class="o">**</span><span class="n">OLD_DEFAULT_SETTINGS</span><span class="p">)</span>
<span class="n">django</span><span class="o">.</span><span class="n">setup</span><span class="p">()</span>
<span class="kn">from</span> <span class="nn">django.core.management</span> <span class="kn">import</span> <span class="n">call_command</span>
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">loading</span>
<span class="n">loading</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">loaded</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">call_command</span><span class="p">(</span><span class="s1">&#39;syncdb&#39;</span><span class="p">,</span> <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># test cases below ...</span>
<span class="k">def</span> <span class="nf">test_case</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># test case here</span>
</pre></div>
</div>
</section>
<section id="a-note-on-making-the-test-runner-faster">
<h3>A note on making the test runner faster<a class="headerlink" href="#a-note-on-making-the-test-runner-faster" title="Permalink to this headline"></a></h3>
<p>If you have custom models with a large number of migrations, creating the test database can take a very long time. If you dont require migrations to run for your tests, you can disable them with the
django-test-without-migrations package. To install it, simply:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ pip install django-test-without-migrations
</pre></div>
</div>
<p>Then add it to your <code class="docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code> in your <code class="docutils literal notranslate"><span class="pre">server.conf.settings.py</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">INSTALLED_APPS</span> <span class="o">=</span> <span class="p">(</span>
<span class="c1"># ...</span>
<span class="s1">&#39;test_without_migrations&#39;</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<p>After doing so, you can then run tests without migrations by adding the <code class="docutils literal notranslate"><span class="pre">--nomigrations</span></code> argument:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">test</span> <span class="o">--</span><span class="n">settings</span> <span class="n">settings</span><span class="o">.</span><span class="n">py</span> <span class="o">--</span><span class="n">nomigrations</span> <span class="o">.</span>
</pre></div>
</div>
</section>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Profiling.html" title="Profiling"
>next</a> |</li>
<li class="right" >
<a href="Debugging.html" title="Debugging"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Unit Testing</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -0,0 +1,502 @@
<!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>Coding using Version Control &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<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="Debugging" href="Debugging.html" />
<link rel="prev" title="Soft Code" href="Soft-Code.html" />
</head><body>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</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"
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="Debugging.html" title="Debugging"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Soft-Code.html" title="Soft Code"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Coding using Version Control</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Coding using Version Control</a><ul>
<li><a class="reference internal" href="#setting-up-git">Setting up Git</a></li>
<li><a class="reference internal" href="#common-git-commands">Common Git commands</a><ul>
<li><a class="reference internal" href="#git-init"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">init</span></code></a></li>
<li><a class="reference internal" href="#git-add"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">add</span></code></a></li>
<li><a class="reference internal" href="#git-commit"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code></a></li>
<li><a class="reference internal" href="#git-status-git-diff-and-git-log"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">status</span></code>, <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">diff</span></code> and <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code></a></li>
<li><a class="reference internal" href="#git-branch-checkout-and-merge"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">branch</span></code>, <code class="docutils literal notranslate"><span class="pre">checkout</span></code> and <code class="docutils literal notranslate"><span class="pre">merge</span></code></a></li>
<li><a class="reference internal" href="#git-glone-git-push-and-git-pull"><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">glone</span></code>, <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> and <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code></a></li>
<li><a class="reference internal" href="#other-git-commands">Other git commands</a></li>
</ul>
</li>
<li><a class="reference internal" href="#putting-your-game-dir-under-version-control">Putting your game dir under version control</a><ul>
<li><a class="reference internal" href="#pushing-your-code-online">Pushing your code online</a></li>
</ul>
</li>
<li><a class="reference internal" href="#contributing-to-evennia">Contributing to Evennia</a><ul>
<li><a class="reference internal" href="#fixing-an-evennia-bug-or-feature">Fixing an Evennia bug or feature</a></li>
</ul>
</li>
<li><a class="reference internal" href="#troubleshooting">Troubleshooting</a><ul>
<li><a class="reference internal" href="#getting-403-forbidden-access">Getting 403: Forbidden access</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Soft-Code.html"
title="previous chapter">Soft Code</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Debugging.html"
title="next chapter">Debugging</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Coding/Version-Control.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="coding-using-version-control">
<h1>Coding using Version Control<a class="headerlink" href="#coding-using-version-control" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Version_control">Version control</a> allows you to track changes to your code. You can save snapshots of your progress which means you can roll back undo things easily. Version control also allows you to easily back up your code to an online <em>repository</em> such as Github. It also allows you to collaborate with others on the same code without clashing or worry about who changed what.</p>
<aside class="sidebar">
<p class="sidebar-title">Do it!</p>
<p>Its <em>strongly</em> recommended that you <a class="reference internal" href="#putting-your-game-dir-under-version-control"><span class="std std-doc">put your game folder under version control</span></a>. Using git is is also the way to contribue to Evennia itself.</p>
</aside>
<p>Evennia uses the most commonly used version control system, <a class="reference external" href="https://git-scm.com/">Git</a> . For additional help on using Git, please refer to the <a class="reference external" href="https://help.github.com/articles/set-up-git#platform-all">Official GitHub documentation</a>.</p>
<section id="setting-up-git">
<h2>Setting up Git<a class="headerlink" href="#setting-up-git" title="Permalink to this headline"></a></h2>
<ul>
<li><p><strong>Fedora Linux</strong></p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> yum install git-core
</pre></div>
</div>
</li>
<li><p><strong>Debian Linux</strong> <em>(Ubuntu, Linux Mint, etc.)</em></p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> apt-get install git
</pre></div>
</div>
</li>
<li><p><strong>Windows</strong>: It is recommended to use <a class="reference external" href="https://gitforwindows.org/">Git for Windows</a>.</p></li>
<li><p><strong>Mac</strong>: Mac platforms offer two methods for installation, one via MacPorts, which you can find out about <a class="reference external" href="https://git-scm.com/book/en/Getting-Started-Installing-Git#Installing-on-Mac">here</a>, or you can use the <a class="reference external" href="https://sourceforge.net/projects/git-osx-installer/">Git OSX Installer</a>.</p></li>
</ul>
<blockquote>
<div><p>You can find expanded instructions for installation <a class="reference external" href="https://git-scm.com/book/en/Getting-Started-Installing-Git">here</a>.</p>
</div></blockquote>
<aside class="sidebar">
<p class="sidebar-title">Git user nickname</p>
<p>If you ever make your code available online (or contribute to Evennia), your name will be visible to those reading the code-commit history. So if you are not comfortable with using your real, full name online, put a nickname (or your github handler) here.</p>
</aside>
<p>To avoid a common issue later, you will need to set a couple of settings; first you will need to tell Git your username, followed by your e-mail address, so that when you commit code later you will be properly credited.</p>
<ol>
<li><p>Set the default name for git to use when you commit:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> git config --global user.name &quot;Your Name Here&quot;
</pre></div>
</div>
</li>
<li><p>Set the default email for git to use when you commit:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> git config --global user.email &quot;your_email@example.com&quot;
</pre></div>
</div>
</li>
</ol>
<blockquote>
<div><p>To get a running start with Git, heres <a class="reference external" href="https://www.youtube.com/watch?v=1ffBJ4sVUb4#t=1m58s">a good YouTube talk about it</a>. Its a bit long but it will help you understand the underlying ideas behind GIT (which in turn makes it a lot more intuitive to use).</p>
</div></blockquote>
</section>
<section id="common-git-commands">
<h2>Common Git commands<a class="headerlink" href="#common-git-commands" title="Permalink to this headline"></a></h2>
<aside class="sidebar">
<p class="sidebar-title">Git repository</p>
<p>This is just a fancy name for the folder you have designated to be under version control. We will make your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> game folder into such a repository. The Evennia code is also in a (separate) git repository.</p>
</aside>
<p>Git can be controlled via a GUI. But its often easier to use the base terminal/console commands, since it makes it clear if something goes wrong.</p>
<p>All these actions need to be done from inside the <em>git repository</em> .</p>
<p>Git may seem daunting at first. But when working with git, youll be using the same 2-3 commands 99% of the time. And you can make git <em>aliases</em> to have them be even easier to remember.</p>
<section id="git-init">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">init</span></code><a class="headerlink" href="#git-init" title="Permalink to this headline"></a></h3>
<p>This initializes a folder/directory on your drive as a git repository</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git init .
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">.</span></code> means to apply to the current directory. If you are inside <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, this makes your game dir into a git repository. Thats all there is to it, really. You only need to do this once.</p>
</section>
<section id="git-add">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">add</span></code><a class="headerlink" href="#git-add" title="Permalink to this headline"></a></h3>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git add &lt;file&gt;
</pre></div>
</div>
<p>This tells Git to start to <em>track</em> the file under version control. You need to do this when you create a new file. You can also add all files in your current directory:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git add .
</pre></div>
</div>
<p>Or</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git add *
</pre></div>
</div>
<p>All files in the current directory are now tracked by Git. You only need to do this once for every file you want to track.</p>
</section>
<section id="git-commit">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code><a class="headerlink" href="#git-commit" title="Permalink to this headline"></a></h3>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git commit -a -m &quot;This is the initial commit&quot;
</pre></div>
</div>
<p>This <em>commits</em> your changes. It stores a snapshot of all (<code class="docutils literal notranslate"><span class="pre">-a</span></code>) your code at the current time, adding a message <code class="docutils literal notranslate"><span class="pre">-m</span></code> so you know what you did. Later you can <em>check out</em> your code the way it was at a given time. The message is mandatory and you will thank yourself later if write clear and descriptive log messages. If you dont add <code class="docutils literal notranslate"><span class="pre">-m</span></code>, a text editor opens for you to write the message instead.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code> is something youll be using all the time, so it can be useful to make a <em>git alias</em> for it:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git config --global alias.cma &#39;commit -a -m&#39;
</pre></div>
</div>
<p>After youve run this, you can commit much simpler, like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git cma &quot;This is the initial commit&quot;
</pre></div>
</div>
<p>Much easier to remember!</p>
</section>
<section id="git-status-git-diff-and-git-log">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">status</span></code>, <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">diff</span></code> and <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code><a class="headerlink" href="#git-status-git-diff-and-git-log" title="Permalink to this headline"></a></h3>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git status -s
</pre></div>
</div>
<p>This gives a short (<code class="docutils literal notranslate"><span class="pre">-s</span></code>) of the files that changes since your last <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code>.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git diff --word-diff`
</pre></div>
</div>
<p>This shows exactly what changed in each file since you last made a <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code>. The <code class="docutils literal notranslate"><span class="pre">--word-diff</span></code> option means it will mark if a single word changed on a line.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git log
</pre></div>
</div>
<p>This shows the log of all <code class="docutils literal notranslate"><span class="pre">commits</span></code> done. Each log will show you who made the change, the commit-message and a unique <em>hash</em> (like <code class="docutils literal notranslate"><span class="pre">ba214f12ab12e123...</span></code>) that uniquely describes that commit.</p>
<p>You can make the <code class="docutils literal notranslate"><span class="pre">log</span></code> command more succinct with some more options:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>ls=log --pretty=format:%C(green)%h\ %C(yellow)[%ad]%Cred%d\ %Creset%s%Cblue\ [%an] --decorate --date=relative
</pre></div>
</div>
<p>This adds coloration and another fancy effects (use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">help</span> <span class="pre">log</span></code> to see what they mean).</p>
<p>Lets add aliases:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git config --global alias.st &#39;status -s&#39;
git config --global alias.df &#39;diff --word-diff&#39;
git config --global alias.ls &#39;log --pretty=format:%C(green)%h\ %C(yellow)[%ad]%Cred%d\ %Creset%s%Cblue\ [%an] --decorate --date=relative&#39;
</pre></div>
</div>
<p>You can now use the much shorter</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git st # short status
git dif # diff with word-marking
git ls # log with pretty formatting
</pre></div>
</div>
<p>for these useful functions.</p>
</section>
<section id="git-branch-checkout-and-merge">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">branch</span></code>, <code class="docutils literal notranslate"><span class="pre">checkout</span></code> and <code class="docutils literal notranslate"><span class="pre">merge</span></code><a class="headerlink" href="#git-branch-checkout-and-merge" title="Permalink to this headline"></a></h3>
<p>Git allows you to work with <em>branches</em>. These are separate development paths your code may take, completely separate from each other. You can later <em>merge</em> the code from a branch back into another branch. Evennias <code class="docutils literal notranslate"><span class="pre">main</span></code> and <code class="docutils literal notranslate"><span class="pre">develop</span></code> branches are examples of this.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git branch -b branchaname
</pre></div>
</div>
<p>This creates a new branch, exactly identical to the branch you were on. It also moves you to that branch.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git branch -D branchname
</pre></div>
</div>
<p>Deletes a branch.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git branch
</pre></div>
</div>
<p>Shows all your branches, marking which one you are currently on.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout branchname
</pre></div>
</div>
<p>This checks out another branch. As long as you are in a branch all <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code>s will commit the code to that branch only.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout .
</pre></div>
</div>
<p>This checks out your <em>current branch</em> and has the effect of throwing away all your changes since your last commit. This is like undoing what you did since the last save point.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout b2342bc21c124
</pre></div>
</div>
<p>This checks out a particular <em>commit</em>, identified by the hash you find with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code>. This open a temporary branch where the code is as it was when you made this commit. As an example, you can use this to check where a bug was introduced. Check out an existing branch to go back to your normal timeline, or use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">branch</span> <span class="pre">-b</span> <span class="pre">newbranch</span></code> to break this code off into a new branch you can continue working from.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git merge branchname
</pre></div>
</div>
<p>This <em>merges</em> the code from <code class="docutils literal notranslate"><span class="pre">branchname</span></code> into the branch you are currently in. Doing so may lead to <em>merge conflicts</em> if the same code changed in different ways in the two branches. See <a class="reference external" href="https://phoenixnap.com/kb/how-to-resolve-merge-conflicts-in-git">how to resolve merge conflicts in git</a> for more help.</p>
</section>
<section id="git-glone-git-push-and-git-pull">
<h3><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">glone</span></code>, <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> and <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code><a class="headerlink" href="#git-glone-git-push-and-git-pull" title="Permalink to this headline"></a></h3>
<p>All of these other commands have dealt with code only sitting in your local repository-folder. These commands instead allows you to exchange code with a <em>remote</em> repository - usually one that is online (like on github).</p>
<blockquote>
<div><p>How you actually set up a remote repository is described <a class="reference internal" href="#pushing-your-code-online"><span class="std std-doc">in the next section</span></a>.</p>
</div></blockquote>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git clone repository/path
</pre></div>
</div>
<p>This copies the remote repository to your current location. If you used the <a class="reference internal" href="../Setup/Installation-Git.html"><span class="doc std std-doc">Git installation instructions</span></a> to install Evennia, this is what you used to get your local copy of the Evennia repository.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git pull
</pre></div>
</div>
<p>Once you cloned or otherwise set up a remote repository, using <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code> will re-sync the remote with what you have locally. If what you download clashes with local changes, git will force you to <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code> your changes before you can continue with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code>.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git push
</pre></div>
</div>
<p>This uploads your local changes <em>of your current branch</em> to the same-named branch on the remote repository. To be able to do this you must have write-permissions to the remote repository.</p>
</section>
<section id="other-git-commands">
<h3>Other git commands<a class="headerlink" href="#other-git-commands" title="Permalink to this headline"></a></h3>
<p>There are <em>many</em> other git commands. Read up on them online:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git reflog
</pre></div>
</div>
<p>Shows hashes of individual git actions. This allows you to go back in the git event history itself.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git reset
</pre></div>
</div>
<p>Force reset a branch to an earlier commit. This could throw away some history, so be careful.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git grep -n -I -i &lt;query&gt;
</pre></div>
</div>
<p>Quickly search for a phrase/text in all files tracked by git. Very useful to quickly find where things are. Set up an alias <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">gr</span></code> with</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">config</span> <span class="o">--</span><span class="k">global</span> <span class="n">alias</span><span class="o">.</span><span class="n">gr</span> <span class="s1">&#39;grep -n -I -i&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="putting-your-game-dir-under-version-control">
<h2>Putting your game dir under version control<a class="headerlink" href="#putting-your-game-dir-under-version-control" title="Permalink to this headline"></a></h2>
<p>This makes use of the git commands listed in the previous section.</p>
<aside class="sidebar">
<p class="sidebar-title">git aliases</p>
<p>If you set up the git aliases for commands suggested in the previous section, you can use them instead!</p>
</aside>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cd mygame
git init .
git add *
git commit -a -m &quot;Initial commit&quot;
</pre></div>
</div>
<p>Your game-dir is now tracked by git.</p>
<p>You will notice that some files are not covered by your git version control, notably your secret-settings file (<code class="docutils literal notranslate"><span class="pre">mygame/server/conf/secret_settings.py</span></code>) and your sqlite3 database file <code class="docutils literal notranslate"><span class="pre">mygame/server/evennia.db3</span></code>. This is intentional and controlled from the file <code class="docutils literal notranslate"><span class="pre">mygame/.gitignore</span></code>.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>You should <em>never</em> put your sqlite3 database file into git by removing its entry
in <code class="docutils literal notranslate"><span class="pre">.gitignore</span></code>. GIT is for backing up your code, not your database. That way
lies madness and a good chance youll confuse yourself. Make one mistake or local change and after a few commits and reverts you will have lost track of what is in your database or not. If you want to backup your SQlite3 database, do so by simply copying the database file to a safe location.</p>
</div>
<section id="pushing-your-code-online">
<h3>Pushing your code online<a class="headerlink" href="#pushing-your-code-online" title="Permalink to this headline"></a></h3>
<p>So far your code is only located on your private machine. A good idea is to back it up online. The easiest way to do this is to <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> it to your own remote repository on GitHub. So for this you need a (free) Github account.</p>
<p>If you dont want your code to be publicly visible, Github also allows you set up a <em>private</em> repository, only visible to you.</p>
<p>Create a new, empty repository on Github. <a class="reference external" href="https://help.github.com/articles/create-a-repo/">Github explains how here</a> . <em>Dont</em> allow it to add a README, license etc, that will just clash with what we upload later.</p>
<aside class="sidebar">
<p class="sidebar-title">Origin</p>
<p>We label the remote repository origin. This is the git default and means we wont need to specify it explicitly later.</p>
</aside>
<p>Make sure you are in your local game dir (previously initialized as a git repo).</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git remote add origin &lt;github URL&gt;
</pre></div>
</div>
<p>This tells Git that there is a remote repository at <code class="docutils literal notranslate"><span class="pre">&lt;github</span> <span class="pre">URL&gt;</span></code>. See the github docs as to which URL to use. Verify that the remote works with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">remote</span> <span class="pre">-v</span></code></p>
<p>Now we push to the remote (labeled origin which is the default):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git push
</pre></div>
</div>
<p>Depending on how you set up your authentication with github, you may be asked to enter your github username and password. If you set up SSH authentication, this command will just work.</p>
<p>You use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> to upload your local changes so the remote repository is in sync with your local one. If you edited a file online using the Github editor (or a collaborator pushed code), you use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code> to sync in the other direction.</p>
</section>
</section>
<section id="contributing-to-evennia">
<h2>Contributing to Evennia<a class="headerlink" href="#contributing-to-evennia" title="Permalink to this headline"></a></h2>
<p>If you want to help contributing to Evennia you must do so by <em>forking</em> - making your own remote copy of the Evennia repository on Github. So for this, you need a (free) Github account. Doing so is a completely separate process from <a class="reference internal" href="#putting-your-game-dir-under-version-control"><span class="std std-doc">putting your game dir under version control</span></a> (which you should also do!).</p>
<p>At the top right of <a class="reference external" href="https://github.com/evennia/evennia">the evennia github page</a>, click the “Fork” button:</p>
<p><img alt="fork button" src="../_images/fork_button.png" /></p>
<p>This will create a new online fork Evennia under your github account.</p>
<p>The fork only exists online as of yet. In a terminal, <code class="docutils literal notranslate"><span class="pre">cd</span></code> to the folder you wish to develop in. This folder should <em>not</em> be your game dir, nor the place you cloned Evennia into if you used the <a class="reference internal" href="../Setup/Installation-Git.html"><span class="doc std std-doc">Git installation</span></a>.</p>
<p>From this directory run the following command:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git clone https://github.com/yourusername/evennia.git evennia
</pre></div>
</div>
<p>This will download your fork to your computer. It creates a new folder <code class="docutils literal notranslate"><span class="pre">evennia/</span></code> at your current location. If you installed Evennia using the <a class="reference internal" href="../Setup/Installation-Git.html"><span class="doc std std-doc">Git installation</span></a>, this folder will be identical in content to the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> folder you cloned during that installation. The difference is that this repo is connected to your remote fork and not to the original <em>upstream</em> Evennia.</p>
<p>When we cloned our fork, git automatically set up a remote repository labeled <code class="docutils literal notranslate"><span class="pre">origin</span></code> pointing to it. So if we do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code> and <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code>, well push to our fork.</p>
<p>We now want to add a second remote repository linked to the original Evennia repo. We will label this remote repository <code class="docutils literal notranslate"><span class="pre">upstream</span></code>:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>cd evennia
git remote add upstream https://github.com/evennia/evennia.git
</pre></div>
</div>
<p>If you also want to access Evennias <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch (the bleeding edge development) do the following:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git fetch upstream develop
git checkout develop
</pre></div>
</div>
<p>Use</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout main
git checkout develop
</pre></div>
</div>
<p>to switch between the branches.</p>
<p>To pull the latest from upstream Evennia, just checkout the branch you want and do</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git pull upstream
</pre></div>
</div>
<aside class="sidebar">
<p class="sidebar-title">Pushing to upstream</p>
<p>You cant do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span> <span class="pre">upstream</span></code> unless you have write-access to the upstream Evennia repository. So there is no risk of you accidentally pushing your own code into the main, public repository.</p>
</aside>
<section id="fixing-an-evennia-bug-or-feature">
<h3>Fixing an Evennia bug or feature<a class="headerlink" href="#fixing-an-evennia-bug-or-feature" title="Permalink to this headline"></a></h3>
<p>This should be done in your fork of Evennia. You should <em>always</em> do this in a <em>separate git branch</em> based off the Evennia branch you want to improve.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout main (or develop)
git branch -b myfixbranch
</pre></div>
</div>
<p>Now fix whatever needs fixing. Abide by the <a class="reference internal" href="Evennia-Code-Style.html"><span class="doc std std-doc">Evennia code style</span></a>. You can <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span></code> commit your changes along the way as normal.</p>
<p>Upstream Evennia is not standing still, so you want to make sure that your work is up-to-date with upstream changes. Make sure to first commit your <code class="docutils literal notranslate"><span class="pre">myfixbranch</span></code> changes, then</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git checkout main (or develop)
git pull upstream
git checkout myfixbranch
git merge main (or develop)
</pre></div>
</div>
<p>Up to this point your <code class="docutils literal notranslate"><span class="pre">myfixbranch</span></code> branch only exists on your local computer. No
one else can see it.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>git push
</pre></div>
</div>
<p>This will automatically create a matching <code class="docutils literal notranslate"><span class="pre">myfixbranch</span></code> in your forked version of Evennia and push to it. On github you will be able to see appear it in the <code class="docutils literal notranslate"><span class="pre">branches</span></code> dropdown. You can keep pushing to your remote <code class="docutils literal notranslate"><span class="pre">myfixbranch</span></code> as much as you like.</p>
<p>Once you feel you have something to share, you need to <a class="reference external" href="https://github.com/evennia/evennia/pulls">create a pull request</a> (PR):
This is a formal request for upstream Evennia to adopt and pull your code into the main repository.</p>
<ol class="simple">
<li><p>Click <code class="docutils literal notranslate"><span class="pre">New</span> <span class="pre">pull</span> <span class="pre">request</span></code></p></li>
<li><p>Choose <code class="docutils literal notranslate"><span class="pre">compare</span> <span class="pre">across</span> <span class="pre">forks</span></code></p></li>
<li><p>Select your fork from dropdown list of <code class="docutils literal notranslate"><span class="pre">head</span> <span class="pre">repository</span></code> repos. Pick the right branch to <code class="docutils literal notranslate"><span class="pre">compare</span></code>.</p></li>
<li><p>On the Evennia side (to the left) make sure to pick the right <code class="docutils literal notranslate"><span class="pre">base</span></code> branch: If you want to contribute a change to the <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch, you must pick <code class="docutils literal notranslate"><span class="pre">develop</span></code> as the <code class="docutils literal notranslate"><span class="pre">base</span></code>.</p></li>
<li><p>Then click <code class="docutils literal notranslate"><span class="pre">Create</span> <span class="pre">pull</span> <span class="pre">request</span></code> and fill in as much information as you can in the form.</p></li>
<li><p>Optional: Once you saved your PR, you can go into your code (on github) and add some per-line comments; this can help reviewers by explaining complex code or decisions you made.</p></li>
</ol>
<p>Now you just need to wait for your code to be reviewed. Expect to get feedback and be asked to make changes, add more documentation etc. Getting as PR merged can take a few iterations.</p>
<aside class="sidebar">
<p class="sidebar-title">Not all PRs can merge</p>
<p>While most PRs get merged, Evennia cant <strong>guarantee</strong> that your PR code will be deemed suitable to merge into upstream Evennia. For this reason its a good idea to check in with the community <em>before</em> you spend a lot of time on a large piece of code (fixing bugs is always a safe bet though!)</p>
</aside>
</section>
</section>
<section id="troubleshooting">
<h2>Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permalink to this headline"></a></h2>
<section id="getting-403-forbidden-access">
<h3>Getting 403: Forbidden access<a class="headerlink" href="#getting-403-forbidden-access" title="Permalink to this headline"></a></h3>
<p>Some users have experienced this on <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> to their remote repository. They are not asked for username/password (and dont have a ssh key set up).</p>
<p>Some users have reported that the workaround is to create a file <code class="docutils literal notranslate"><span class="pre">.netrc</span></code> under your home directory and add your github credentials there:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>machine<span class="w"> </span>github.com
login<span class="w"> </span>&lt;my_github_username&gt;
password<span class="w"> </span>&lt;my_github_password&gt;
</pre></div>
</div>
</section>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Debugging.html" title="Debugging"
>next</a> |</li>
<li class="right" >
<a href="Soft-Code.html" title="Soft Code"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Coding using Version Control</a></li>
</ul>
</div>
<div class="admonition important">
<p class="first admonition-title">Note</p>
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>