mirror of
https://github.com/evennia/evennia.git
synced 2026-03-23 00:06:30 +01:00
Updated HTML docs
This commit is contained in:
parent
a551188691
commit
781788f2e5
2063 changed files with 215958 additions and 250783 deletions
213
docs/1.0-dev/Coding/Coding-Introduction.html
Normal file
213
docs/1.0-dev/Coding/Coding-Introduction.html
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Coding Introduction — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Coding Introduction</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="coding-introduction">
|
||||
<h1>Coding Introduction<a class="headerlink" href="#coding-introduction" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia allows for a lot of freedom when designing your game - but to code efficiently you still
|
||||
need to adopt some best practices as well as find a good place to start to learn.</p>
|
||||
<p>Here are some pointers to get you going.</p>
|
||||
<div class="section" id="start-with-the-tutorial">
|
||||
<h2>Start with the tutorial<a class="headerlink" href="#start-with-the-tutorial" title="Permalink to this headline">¶</a></h2>
|
||||
<p>It’s highly recommended that you jump in on the <a class="reference internal" href="../Howto/Starting/Starting-Part1.html"><span class="doc">Starting Tutorial</span></a>. Even if
|
||||
you only the beginning or some part of it, it covers much of the things needed to get started.</p>
|
||||
</div>
|
||||
<div class="section" id="python">
|
||||
<h2>Python<a class="headerlink" href="#python" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Evennia is developed using Python. Even if you are more of a designer than a coder, it is wise to
|
||||
learn how to read and understand basic Python code. If you are new to Python, or need a refresher,
|
||||
take a look at our <a class="reference internal" href="../Howto/Starting/Part1/Python-basic-introduction.html"><span class="doc">Python introduction</span></a>.</p>
|
||||
</div>
|
||||
<div class="section" id="explore-evennia-interactively">
|
||||
<h2>Explore Evennia interactively<a class="headerlink" href="#explore-evennia-interactively" title="Permalink to this headline">¶</a></h2>
|
||||
<p>When new to Evennia it can be hard to find things or figure out what is available. Evennia offers a
|
||||
special interactive python shell that allows you to experiment and try out things. It’s recommended
|
||||
to use <a class="reference external" href="http://ipython.org/">ipython</a> for this since the vanilla python prompt is very limited. Here
|
||||
are some simple commands to get started:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># [open a new console/terminal]</span>
|
||||
<span class="c1"># [activate your evennia virtualenv in this console/terminal]</span>
|
||||
<span class="n">pip</span> <span class="n">install</span> <span class="n">ipython</span> <span class="c1"># [only needed the first time]</span>
|
||||
<span class="n">cd</span> <span class="n">mygame</span>
|
||||
<span class="n">evennia</span> <span class="n">shell</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will open an Evennia-aware python shell (using ipython). From within this shell, try</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="n">evennia</span><span class="o">.<</span><span class="n">TAB</span><span class="o">></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>That is, enter <code class="docutils literal notranslate"><span class="pre">evennia.</span></code> and press the <code class="docutils literal notranslate"><span class="pre"><TAB></span></code> key. This will show you all the resources made
|
||||
available at the top level of Evennia’s “flat API”. See the <a class="reference internal" href="../Evennia-API.html"><span class="doc">flat API</span></a> page for more
|
||||
info on how to explore it efficiently.</p>
|
||||
<p>You can complement your exploration by peeking at the sections of the much more detailed
|
||||
<a class="reference internal" href="../Components/Components-Overview.html"><span class="doc">Evennia Component overview</span></a>. The <a class="reference internal" href="../Howto/Howto-Overview.html"><span class="doc">Tutorials</span></a> section also contains a growing collection
|
||||
of system- or implementation-specific help.</p>
|
||||
</div>
|
||||
<div class="section" id="use-a-python-syntax-checker">
|
||||
<h2>Use a python syntax checker<a class="headerlink" href="#use-a-python-syntax-checker" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Evennia works by importing your own modules and running them as part of the server. Whereas Evennia
|
||||
should just gracefully tell you what errors it finds, it can nevertheless be a good idea for you to
|
||||
check your code for simple syntax errors <em>before</em> you load it into the running server. There are
|
||||
many python syntax checkers out there. A fast and easy one is
|
||||
<a class="reference external" href="https://pypi.python.org/pypi/pyflakes">pyflakes</a>, a more verbose one is
|
||||
<a class="reference external" href="http://www.pylint.org/">pylint</a>. You can also check so that your code looks up to snuff using
|
||||
<a class="reference external" href="https://pypi.python.org/pypi/pep8">pep8</a>. Even with a syntax checker you will not be able to catch
|
||||
every possible problem - some bugs or problems will only appear when you actually run the code. But
|
||||
using such a checker can be a good start to weed out the simple problems.</p>
|
||||
</div>
|
||||
<div class="section" id="plan-before-you-code">
|
||||
<h2>Plan before you code<a class="headerlink" href="#plan-before-you-code" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Before you start coding away at your dream game, take a look at our <a class="reference internal" href="../Howto/Starting/Part2/Game-Planning.html"><span class="doc">Game Planning</span></a>
|
||||
page. It might hopefully help you avoid some common pitfalls and time sinks.</p>
|
||||
</div>
|
||||
<div class="section" id="code-in-your-game-folder-not-in-the-evennia-repository">
|
||||
<h2>Code in your game folder, not in the evennia/ repository<a class="headerlink" href="#code-in-your-game-folder-not-in-the-evennia-repository" title="Permalink to this headline">¶</a></h2>
|
||||
<p>As part of the Evennia setup you will create a game folder to host your game code. This is your
|
||||
home. You should <em>never</em> need to modify anything in the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> library (anything you download
|
||||
from us, really). You import useful functionality from here and if you see code you like, copy&paste
|
||||
it out into your game folder and edit it there.</p>
|
||||
<p>If you find that Evennia doesn’t support some functionality you need, make a <a class="reference external" href="https://github.com/evennia/evennia/issues/new/choose">Feature
|
||||
Request</a> about it. Same goes for [bugs][bug]. If you add features or fix bugs
|
||||
yourself, please consider <a class="reference internal" href="../Contributing.html"><span class="doc">Contributing</span></a> your changes upstream!</p>
|
||||
</div>
|
||||
<div class="section" id="learn-to-read-tracebacks">
|
||||
<h2>Learn to read tracebacks<a class="headerlink" href="#learn-to-read-tracebacks" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Python is very good at reporting when and where things go wrong. A <em>traceback</em> shows everything you
|
||||
need to know about crashing code. The text can be pretty long, but you usually are only interested
|
||||
in the last bit, where it says what the error is and at which module and line number it happened -
|
||||
armed with this info you can resolve most problems.</p>
|
||||
<p>Evennia will usually not show the full traceback in-game though. Instead the server outputs errors
|
||||
to the terminal/console from which you started Evennia in the first place. If you want more to show
|
||||
in-game you can add <code class="docutils literal notranslate"><span class="pre">IN_GAME_ERRORS</span> <span class="pre">=</span> <span class="pre">True</span></code> to your settings file. This will echo most (but not all)
|
||||
tracebacks both in-game as well as to the terminal/console. This is a potential security problem
|
||||
though, so don’t keep this active when your game goes into production.</p>
|
||||
<blockquote>
|
||||
<div><p>A common confusing error is finding that objects in-game are suddenly of the type <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>
|
||||
rather than your custom typeclass. This happens when you introduce a critical Syntax error to the
|
||||
module holding your custom class. Since such a module is not valid Python, Evennia can’t load it at
|
||||
all. Instead of crashing, Evennia will then print the full traceback to the terminal/console and
|
||||
temporarily fall back to the safe <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> until you fix the problem and reload.</p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="docs-are-here-to-help-you">
|
||||
<h2>Docs are here to help you<a class="headerlink" href="#docs-are-here-to-help-you" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Some people find reading documentation extremely dull and shun it out of principle. That’s your
|
||||
call, but reading docs really <em>does</em> help you, promise! Evennia’s documentation is pretty thorough
|
||||
and knowing what is possible can often give you a lot of new cool game ideas. That said, if you
|
||||
can’t find the answer in the docs, don’t be shy to ask questions! The <a class="reference external" href="https://sites.google.com/site/evenniaserver/discussions">discussion
|
||||
group</a> and the <a class="reference external" href="http://webchat.freenode.net/?channels=evennia">irc
|
||||
chat</a> are also there for you.</p>
|
||||
</div>
|
||||
<div class="section" id="the-most-important-point">
|
||||
<h2>The most important point<a class="headerlink" href="#the-most-important-point" title="Permalink to this headline">¶</a></h2>
|
||||
<p>And finally, of course, have fun!</p>
|
||||
<p><a class="reference external" href="https://github.com/evennia/evennia/issues/new?title=Bug%3a+%3Cdescriptive+title+here%3E&body=%23%23%23%23+Steps+to+reproduce+the+issue%3a%0D%0A%0D%0A1.+%0D%0A2.+%0D%0A3.+%0D%0A%0D%0A%23%23%23%23+What+I+expect+to+see+and+what+I+actually+see+%28tracebacks%2c+error+messages+etc%29%3a%0D%0A%0D%0A%0D%0A%0D%0A%23%23%23%23+Extra+information%2c+such+as+Evennia+revision%2frepo%2fbranch%2c+operating+system+and+ideas+for+how+to+solve%3a%0D%0A%0D%0A">bug</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Coding Introduction</a><ul>
|
||||
<li><a class="reference internal" href="#start-with-the-tutorial">Start with the tutorial</a></li>
|
||||
<li><a class="reference internal" href="#python">Python</a></li>
|
||||
<li><a class="reference internal" href="#explore-evennia-interactively">Explore Evennia interactively</a></li>
|
||||
<li><a class="reference internal" href="#use-a-python-syntax-checker">Use a python syntax checker</a></li>
|
||||
<li><a class="reference internal" href="#plan-before-you-code">Plan before you code</a></li>
|
||||
<li><a class="reference internal" href="#code-in-your-game-folder-not-in-the-evennia-repository">Code in your game folder, not in the evennia/ repository</a></li>
|
||||
<li><a class="reference internal" href="#learn-to-read-tracebacks">Learn to read tracebacks</a></li>
|
||||
<li><a class="reference internal" href="#docs-are-here-to-help-you">Docs are here to help you</a></li>
|
||||
<li><a class="reference internal" href="#the-most-important-point">The most important point</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Coding-Introduction.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Coding-Introduction.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Coding Introduction</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
147
docs/1.0-dev/Coding/Coding-Overview.html
Normal file
147
docs/1.0-dev/Coding/Coding-Overview.html
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Coding and development help — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</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="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" 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. If you are an experienced coder, much of this will be familiar
|
||||
to you, but some things may still be useful.</p>
|
||||
<div class="section" id="find-your-way">
|
||||
<h2>Find your way<a class="headerlink" href="#find-your-way" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="../Howto/Starting/Part1/Gamedir-Overview.html"><span class="doc">Directory-Overview</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Quirks.html"><span class="doc">Quirks of Evennia</span></a></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="setting-up-a-workflow">
|
||||
<h2>Setting up a workflow<a class="headerlink" href="#setting-up-a-workflow" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="Setting-up-PyCharm.html"><span class="doc">Setting up PyCharm</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Version-Control.html"><span class="doc">Using Version-Control</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Updating-Your-Game.html"><span class="doc">Updating Evennia sources</span></a></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="coding-away">
|
||||
<h2>Coding away<a class="headerlink" href="#coding-away" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="Coding-Introduction.html"><span class="doc">Coding Introduction</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Debugging.html"><span class="doc">Ways to Debug</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Unit-Testing.html"><span class="doc">Adding unit-tests</span></a></p></li>
|
||||
<li><p><a class="reference internal" href="Flat-API.html"><span class="doc">Things to remember when importing from evennia</span></a></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="advanced-concepts">
|
||||
<h2>Advanced concepts<a class="headerlink" href="#advanced-concepts" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="Continuous-Integration.html"><span class="doc">Continuous Integration</span></a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="Using-Travis.html"><span class="doc">Using Travis</span></a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="Profiling.html"><span class="doc">Profiling</span></a></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><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="#find-your-way">Find your way</a></li>
|
||||
<li><a class="reference internal" href="#setting-up-a-workflow">Setting up a workflow</a></li>
|
||||
<li><a class="reference internal" href="#coding-away">Coding away</a></li>
|
||||
<li><a class="reference internal" href="#advanced-concepts">Advanced concepts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Coding-Overview.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Coding-Overview.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Coding and development help</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
428
docs/1.0-dev/Coding/Continuous-Integration.html
Normal file
428
docs/1.0-dev/Coding/Continuous-Integration.html
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Continuous Integration — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous Integration</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="continuous-integration">
|
||||
<h1>Continuous Integration<a class="headerlink" href="#continuous-integration" title="Permalink to this headline">¶</a></h1>
|
||||
<p>One of the advantages of Evennia over traditional MUSH development systems is that Evennia is
|
||||
capable of integrating into enterprise level integration environments and source control. Because of
|
||||
this, it can also be the subject of automation for additional convenience, allowing a more
|
||||
streamlined development environment.</p>
|
||||
<div class="section" id="what-is-continuous-integration">
|
||||
<h2>What is Continuous Integration?<a class="headerlink" href="#what-is-continuous-integration" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference external" href="https://www.thoughtworks.com/continuous-integration">Continuous Integration (CI)</a> is a development
|
||||
practice that requires developers to integrate code into a shared repository several times a day.
|
||||
Each check-in is then verified by an automated build, allowing teams to detect problems early.</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>
|
||||
</div>
|
||||
<div class="section" id="preparation">
|
||||
<h2>Preparation<a class="headerlink" href="#preparation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>To prepare a CI environment for your <code class="docutils literal notranslate"><span class="pre">MU*</span></code>, it will be necessary to set up some prerequisite
|
||||
software for your server.</p>
|
||||
<p>Among those you will need:</p>
|
||||
<ul class="simple">
|
||||
<li><p>A Continuous Integration Environment.</p>
|
||||
<ul>
|
||||
<li><p>I recommend <a class="reference external" href="https://www.jetbrains.com/teamcity/">TeamCity</a> which has an in-depth <a class="reference external" href="https://confluence.jetbrains.com/display/TCD8/Installing+and+Configuring+the+TeamCity+Server">Setup
|
||||
Guide</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="Version-Control.html"><span class="doc">Source Control</span></a></p>
|
||||
<ul>
|
||||
<li><p>This could be Git or SVN or any other available SC.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="linux-teamcity-setup">
|
||||
<h2>Linux TeamCity Setup<a class="headerlink" href="#linux-teamcity-setup" title="Permalink to this headline">¶</a></h2>
|
||||
<p>For this part of the guide, an example setup will be provided for administrators running a TeamCity
|
||||
build integration environment on Linux.</p>
|
||||
<p>After meeting the preparation steps for your specific environment, log on to your teamcity interface
|
||||
at <code class="docutils literal notranslate"><span class="pre">http://<your</span> <span class="pre">server>:8111/</span></code>.</p>
|
||||
<p>Create a new project named “Evennia” and in it construct a new template called continuous-
|
||||
integration.</p>
|
||||
<div class="section" id="a-quick-overview">
|
||||
<h3>A Quick Overview<a class="headerlink" href="#a-quick-overview" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Templates are fancy objects in TeamCity that allow an administrator to define build steps that are
|
||||
shared between one or more build projects. Assigning a VCS Root (Source Control) is unnecessary at
|
||||
this stage, primarily you’ll be worrying about the build steps and your default parameters (both
|
||||
visible on the tabs to the left.)</p>
|
||||
</div>
|
||||
<div class="section" id="template-setup">
|
||||
<h3>Template Setup<a class="headerlink" href="#template-setup" title="Permalink to this headline">¶</a></h3>
|
||||
<p>In this template, you’ll be outlining the steps necessary to build your specific game. (A number of
|
||||
sample scripts are provided under this section below!) Click Build Steps and prepare your general
|
||||
flow. For this example, we will be doing a few basic example steps:</p>
|
||||
<ul class="simple">
|
||||
<li><p>Transforming the Settings.py file</p>
|
||||
<ul>
|
||||
<li><p>We do this to update ports or other information that make your production environment unique
|
||||
from your development environment.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>Making migrations and migrating the game database.</p></li>
|
||||
<li><p>Publishing the game files.</p></li>
|
||||
<li><p>Reloading the server.</p></li>
|
||||
</ul>
|
||||
<p>For each step we’ll being use the “Command Line Runner” (a fancy name for a shell script executor).</p>
|
||||
<ul>
|
||||
<li><p>Create a build step with the name: Transform Configuration</p></li>
|
||||
<li><p>For the script add:</p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Replaces the game configuration with one </span>
|
||||
<span class="c1"># appropriate for this deployment.</span>
|
||||
|
||||
<span class="nv">CONFIG</span><span class="o">=</span><span class="s2">"%system.teamcity.build.checkoutDir%/server/conf/settings.py"</span>
|
||||
<span class="nv">MYCONF</span><span class="o">=</span><span class="s2">"%system.teamcity.build.checkoutDir%/server/conf/my.cnf"</span>
|
||||
|
||||
sed -e <span class="s1">'s/TELNET_PORTS = [4000]/TELNET_PORTS = [%game.ports%]/g'</span> <span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span> > <span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>.tmp <span class="o">&&</span> mv
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
</ul>
|
||||
<p>“$CONFIG”.tmp “$CONFIG”
|
||||
sed -e ‘s/WEBSERVER_PORTS = [(4001, 4002)]/WEBSERVER_PORTS = [%game.webports%]/g’ “$CONFIG” >
|
||||
“$CONFIG”.tmp && mv “$CONFIG”.tmp “$CONFIG”</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span># settings.py MySQL DB configuration
|
||||
echo Configuring Game Database...
|
||||
echo "" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
echo "# MySQL Database Configuration" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
|
||||
echo "DATABASES = {" >> "$CONFIG"
|
||||
echo " 'default': {" >> "$CONFIG"
|
||||
echo " 'ENGINE': 'django.db.backends.mysql'," >> "$CONFIG"
|
||||
echo " 'OPTIONS': {" >> "$CONFIG"
|
||||
echo " 'read_default_file': 'server/conf/my.cnf'," >> "$CONFIG"
|
||||
echo " }," >> "$CONFIG"
|
||||
echo " }" >> "$CONFIG"
|
||||
echo "}" >> "$CONFIG"
|
||||
|
||||
# Create the My.CNF file.
|
||||
echo "[client]" >> "$MYCONF"
|
||||
echo "database = %mysql.db%" >> "$MYCONF"
|
||||
echo "user = %mysql.user%" >> "$MYCONF"
|
||||
echo "password = %mysql.pass%" >> "$MYCONF"
|
||||
echo "default-character-set = utf8" >> "$MYCONF"
|
||||
```
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you look at the parameters side of the page after saving this script, you’ll notice that some new
|
||||
parameters have been populated for you. This is because we’ve included new teamcity configuration
|
||||
parameters that are populated when the build itself is ran. When creating projects that inherit this
|
||||
template, we’ll be able to fill in or override those parameters for project-specific configuration.</p>
|
||||
<ul>
|
||||
<li><p>Go ahead and create another build step called “Make Database Migration”</p>
|
||||
<ul class="simple">
|
||||
<li><p>If you’re using SQLLite on your game, it will be prudent to change working directory on this
|
||||
step to: %game.dir%</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>In this script include:</p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Update the DB migration</span>
|
||||
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
||||
<span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
mkdir <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
evennia makemigrations
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
<li><p>Create yet another build step, this time named: “Execute Database Migration”:</p>
|
||||
<ul>
|
||||
<li><p>If you’re using SQLLite on your game, it will be prudent to change working directory on this
|
||||
step to: %game.dir%</p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Apply the database migration.</span>
|
||||
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
||||
<span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
mkdir <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
evennia migrate
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Our next build step is where we actually publish our build. Up until now, all work on game has been
|
||||
done in a ‘work’ directory on TeamCity’s build agent. From that directory we will now copy our files
|
||||
to where our game actually exists on the local server.</p>
|
||||
<ul>
|
||||
<li><p>Create a new build step called “Publish Build”:</p>
|
||||
<ul>
|
||||
<li><p>If you’re using SQLLite on your game, be sure to order this step ABOVE the Database Migration
|
||||
steps. The build order will matter!</p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Publishes the build to the proper build directory.</span>
|
||||
|
||||
<span class="nv">DIRECTORY</span><span class="o">=</span><span class="s2">"%game.dir%"</span>
|
||||
|
||||
<span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
||||
<span class="c1"># Control will enter here if $DIRECTORY doesn't exist.</span>
|
||||
mkdir <span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
<span class="c1"># Copy all the files.</span>
|
||||
cp -ruv %teamcity.build.checkoutDir%/* <span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
chmod -R <span class="m">775</span> <span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Finally the last script will reload our game for us.</p>
|
||||
<ul>
|
||||
<li><p>Create a new script called “Reload Game”:</p>
|
||||
<ul>
|
||||
<li><p>The working directory on this build step will be: %game.dir%</p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Apply the database migration.</span>
|
||||
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
<span class="nv">PIDDIR</span><span class="o">=</span><span class="s2">"server/server.pid"</span>
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
||||
<span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
mkdir <span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
<span class="c1"># Check that the server is running.</span>
|
||||
<span class="k">if</span> <span class="o">[</span> -d <span class="s2">"</span><span class="nv">$PIDDIR</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
||||
<span class="c1"># Control will enter here if the game is running.</span>
|
||||
evennia reload
|
||||
<span class="k">fi</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Now the template is ready for use! It would be useful this time to revisit the parameters page and
|
||||
set the evenv parameter to the directory where your virtualenv exists: IE “/srv/mush/evenv”.</p>
|
||||
</div>
|
||||
<div class="section" id="creating-the-project">
|
||||
<h3>Creating the Project<a class="headerlink" href="#creating-the-project" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Now it’s time for the last few steps to set up a CI environment.</p>
|
||||
<ul class="simple">
|
||||
<li><p>Return to the Evennia Project overview/administration page.</p></li>
|
||||
<li><p>Create a new Sub-Project called “Production”</p>
|
||||
<ul>
|
||||
<li><p>This will be the category that holds our actual game.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>Create a new Build Configuration in Production with the name of your MUSH.</p>
|
||||
<ul>
|
||||
<li><p>Base this configuration off of the continuous-integration template we made earlier.</p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>In the build configuration, enter VCS roots and create a new VCS root that points to the
|
||||
branch/version control that you are using.</p></li>
|
||||
<li><p>Go to the parameters page and fill in the undefined parameters for your specific configuration.</p></li>
|
||||
<li><p>If you wish for the CI to run every time a commit is made, go to the VCS triggers and add one for
|
||||
“On Every Commit”.</p></li>
|
||||
</ul>
|
||||
<p>And you’re done! At this point, you can return to the project overview page and queue a new build
|
||||
for your game. If everything was set up correctly, the build will complete successfully. Additional
|
||||
build steps could be added or removed at this point, adding some features like Unit Testing or more!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Continuous Integration</a><ul>
|
||||
<li><a class="reference internal" href="#what-is-continuous-integration">What is Continuous Integration?</a></li>
|
||||
<li><a class="reference internal" href="#preparation">Preparation</a></li>
|
||||
<li><a class="reference internal" href="#linux-teamcity-setup">Linux TeamCity Setup</a><ul>
|
||||
<li><a class="reference internal" href="#a-quick-overview">A Quick Overview</a></li>
|
||||
<li><a class="reference internal" href="#template-setup">Template Setup</a></li>
|
||||
<li><a class="reference internal" href="#creating-the-project">Creating the Project</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Continuous-Integration.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous Integration</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
384
docs/1.0-dev/Coding/Debugging.html
Normal file
384
docs/1.0-dev/Coding/Debugging.html
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Debugging — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" 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. 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>
|
||||
<div class="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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span><span class="n">set_trace</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</td></tr></table></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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><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">'auto'</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>
|
||||
</td></tr></table></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 (it’s ignored by <code class="docutils literal notranslate"><span class="pre">pdb</span></code>).</p>
|
||||
</div>
|
||||
<div class="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, let’s 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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19</pre></div></td><td class="code"><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="sd">"""</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"> """</span>
|
||||
|
||||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"test"</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"># <--- 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">"You've found {}."</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>
|
||||
</td></tr></table></div>
|
||||
<p>If you type <code class="docutils literal notranslate"><span class="pre">test</span></code> in your game, everything will freeze. You won’t get any feedback from the game,
|
||||
and you won’t be able to enter any command (nor anyone else). It’s 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">></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">-></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>
|
||||
<div class="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">"test"</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="k">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"># <--- start of debugger</span>
|
||||
<span class="mi">48</span> <span class="o">-></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">"You've found </span><span class="si">{}</span><span class="s2">."</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 didn’t 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 what’s around in code. Notice that
|
||||
there is a little arrow (<code class="docutils literal notranslate"><span class="pre">-></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 (we’ll
|
||||
soon see how).</p>
|
||||
</div>
|
||||
<div class="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"><</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">></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">''</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"><</span><span class="n">Character</span><span class="p">:</span> <span class="n">XXX</span><span class="o">></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>, you’ll 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">'obj'</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 haven’t 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>
|
||||
</div>
|
||||
<div class="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>It’s 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">"'CmdTest' object has no attribute 'search'"</span>
|
||||
<span class="o">></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">-></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 there’s 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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><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>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<div class="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 it’s 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, that’s the error we have fixed… or hope to have. Let’s 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">></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">-></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">></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">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</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. Let’s 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>Let’s 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 you’ll have an error in the game this time. Let’s 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>Let’s execute this line right away:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></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">-></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">></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">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</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"><</span><span class="n">Character</span><span class="p">:</span> <span class="n">barkeep</span><span class="o">></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. Let’s 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">'get_display_name() takes exactly 2 arguments (1 given)'</span>
|
||||
<span class="o">></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">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</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 don’t understand.</p></li>
|
||||
<li><p>Put a breaking point <strong>BEFORE</strong> the error occurs.</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>
|
||||
</div>
|
||||
<div class="section" id="stepping-through-a-function">
|
||||
<h3>Stepping through a function<a class="headerlink" href="#stepping-through-a-function" title="Permalink to this headline">¶</a></h3>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">n</span></code> is useful, but it will avoid stepping inside of functions if it can. But most of the time, when
|
||||
we have an error we don’t understand, it’s because we use functions or methods in a way that wasn’t
|
||||
intended by the developer of the API. Perhaps using wrong arguments, or calling the function in a
|
||||
situation that would cause a bug. When we have a line in the debugger that calls a function or
|
||||
method, we can “step” to examine it further. For instance, in the previous example, when <code class="docutils literal notranslate"><span class="pre">pdb</span></code> was
|
||||
about to execute <code class="docutils literal notranslate"><span class="pre">obj</span> <span class="pre">=</span> <span class="pre">self.caller.search(self.args)</span></code>, we may want to see what happens inside of
|
||||
the <code class="docutils literal notranslate"><span class="pre">search</span></code> method.</p>
|
||||
<p>To do so, use the <code class="docutils literal notranslate"><span class="pre">step</span></code> (or <code class="docutils literal notranslate"><span class="pre">s</span></code>) command. This command will show you the definition of the
|
||||
function/method and you can then use <code class="docutils literal notranslate"><span class="pre">n</span></code> as before to see it line-by-line. In our little example,
|
||||
stepping through a function or method isn’t that useful, but when you have an impressive set of
|
||||
commands, functions and so on, it might really be handy to examine some feature and make sure they
|
||||
operate as planned.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="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 it’s 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>
|
||||
<p>| Pdb/PuDB command | To do what |
|
||||
| ———– | ———- |
|
||||
| list (or l) | 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
|
||||
this directly). |
|
||||
| print (or p) | Display one or several variables. |
|
||||
| <code class="docutils literal notranslate"><span class="pre">!</span></code> | Run Python code (using a <code class="docutils literal notranslate"><span class="pre">!</span></code> is often optional). |
|
||||
| continue (or c) | Continue execution and terminate the debugger for this time. |
|
||||
| next (or n) | Execute the current line and goes to the next one. |
|
||||
| step (or s) | Step inside of a function or method to examine it. |
|
||||
| <code class="docutils literal notranslate"><span class="pre"><RETURN></span></code> | Repeat the last command (don’t type <code class="docutils literal notranslate"><span class="pre">n</span></code> repeatedly, just type it once and then press
|
||||
<code class="docutils literal notranslate"><span class="pre"><RETURN></span></code> to repeat it). |</p>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><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>
|
||||
<li><a class="reference internal" href="#stepping-through-a-function">Stepping through a function</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>
|
||||
|
||||
<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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Debugging.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
137
docs/1.0-dev/Coding/Flat-API.html
Normal file
137
docs/1.0-dev/Coding/Flat-API.html
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Things to remember about the flat API — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Things to remember about the flat API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="things-to-remember-about-the-flat-api">
|
||||
<h1>Things to remember about the flat API<a class="headerlink" href="#things-to-remember-about-the-flat-api" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The flat API is a series of ‘shortcuts’ on the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> main library root (defined in
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code>). Its componentas are documented <a class="reference internal" href="../Evennia-API.html"><span class="doc">as part of the auto-documentation</span></a>.</p>
|
||||
<div class="section" id="to-remember-when-importing-from-evennia">
|
||||
<h2>To remember when importing from <code class="docutils literal notranslate"><span class="pre">evennia</span></code><a class="headerlink" href="#to-remember-when-importing-from-evennia" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Properties on the root of the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> package are <em>not</em> modules in their own right. They are just
|
||||
shortcut properties stored in the <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> module. That means that you cannot use dot-
|
||||
notation to <code class="docutils literal notranslate"><span class="pre">import</span></code> nested module-names over <code class="docutils literal notranslate"><span class="pre">evennia</span></code>. The rule of thumb is that you cannot use
|
||||
<code class="docutils literal notranslate"><span class="pre">import</span></code> for more than one level down. Hence you can do</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">import</span> <span class="nn">evennia</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="n">evennia</span><span class="o">.</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdLook</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>or import one level down</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">default_cmds</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdLook</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>but you <em>cannot</em> import two levels down</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia.default_cmds</span> <span class="kn">import</span> <span class="n">CmdLook</span> <span class="c1"># error!</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>This will give you an <code class="docutils literal notranslate"><span class="pre">ImportError</span></code> telling you that the module <code class="docutils literal notranslate"><span class="pre">default_cmds</span></code> cannot be found -
|
||||
this is becasue <code class="docutils literal notranslate"><span class="pre">default_cmds</span></code> is just a <em>variable</em> stored in <code class="docutils literal notranslate"><span class="pre">evennia.__init__.py</span></code>; this cannot be
|
||||
imported from. If you really want full control over which level of package you import you can always
|
||||
bypass the root package and import directly from from the real location. For example
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia.DefaultObject</span></code> is a shortcut to <code class="docutils literal notranslate"><span class="pre">evennia.objects.objects.DefaultObject</span></code>. Using this full
|
||||
path will have the import mechanism work normally. See <code class="docutils literal notranslate"><span class="pre">evennia/__init__.py</span></code> to see where the
|
||||
package imports from.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Things to remember about the flat API</a><ul>
|
||||
<li><a class="reference internal" href="#to-remember-when-importing-from-evennia">To remember when importing from <code class="docutils literal notranslate"><span class="pre">evennia</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Flat-API.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Flat-API.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Things to remember about the flat API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
227
docs/1.0-dev/Coding/Profiling.html
Normal file
227
docs/1.0-dev/Coding/Profiling.html
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Profiling — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Profiling</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="profiling">
|
||||
<h1>Profiling<a class="headerlink" href="#profiling" title="Permalink to this headline">¶</a></h1>
|
||||
<p><em>This is considered an advanced topic mainly of interest to server developers.</em></p>
|
||||
<div class="section" id="introduction">
|
||||
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
||||
<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 Knuth’s <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, don’t 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>
|
||||
</div>
|
||||
<div class="section" id="simple-timer-tests">
|
||||
<h2>Simple timer tests<a class="headerlink" href="#simple-timer-tests" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Python’s <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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7</pre></div></td><td class="code"><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">"for i in range(100):</span><span class="se">\n</span><span class="s2"> a.append(i)"</span><span class="p">,</span> <span class="n">setup</span><span class="o">=</span><span class="s2">"a = []"</span><span class="p">)</span>
|
||||
<span class="o"><<<</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">"a = [i for i in range(100)]"</span><span class="p">)</span>
|
||||
<span class="o"><<<</span> <span class="mf">5.358283996582031</span>
|
||||
</pre></div>
|
||||
</td></tr></table></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>
|
||||
</div>
|
||||
<div class="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 Evennia’s 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-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="o">--</span><span class="n">profiler</span> <span class="n">start</span>
|
||||
</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/Start-Stop-Reload.html"><span class="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 don’t 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 Manager’s 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">@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>
|
||||
</div>
|
||||
<div class="section" id="analyzing-the-profile">
|
||||
<h2>Analyzing the profile<a class="headerlink" href="#analyzing-the-profile" title="Permalink to this headline">¶</a></h2>
|
||||
<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>We recommend the
|
||||
<a class="reference external" href="http://www.vrplumber.com/programming/runsnakerun/">Runsnake</a> visualizer to see the processor usage
|
||||
of different processes in a graphical form. 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 pyprof2calltree 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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="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>
|
||||
<blockquote>
|
||||
<div><p>Warning: You should not run the Dummyrunner on a production database. It will spawn many objects
|
||||
and also needs to run with general permissions.</p>
|
||||
</div></blockquote>
|
||||
<p>To launch the Dummyrunner, first start your server normally (with or without profiling, as above).
|
||||
Then start a new terminal/console window and active your virtualenv there too. In the new terminal,
|
||||
try to connect 10 dummy players:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="o">--</span><span class="n">dummyrunner</span> <span class="mi">10</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The first time you do this you will most likely get a warning from Dummyrunner. It will tell you to
|
||||
copy an import string to the end of your settings file. Quit the Dummyrunner (<code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code>) and follow
|
||||
the instructions. Restart Evennia and try <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">--dummyrunner</span> <span class="pre">10</span></code> again. Make sure to remove that
|
||||
extra settings line when running a public server.</p>
|
||||
<p>The actions perform by the dummies is controlled by a settings file. The default Dummyrunner
|
||||
settings file is <code class="docutils literal notranslate"><span class="pre">evennia/server/server/profiling/dummyrunner_settings.py</span></code> but you shouldn’t modify
|
||||
this directly. Rather create/copy the default file to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/</span></code> and modify it there. To
|
||||
make sure to use your file over the default, add the following line to your settings file:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">DUMMYRUNNER_SETTINGS_MODULE</span> <span class="o">=</span> <span class="s2">"server/conf/dummyrunner_settings.py"</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<blockquote>
|
||||
<div><p>Hint: Don’t start with too many dummies. The Dummyrunner defaults to taxing the server much more
|
||||
intensely than an equal number of human players. A good dummy number to start with is 10-100.</p>
|
||||
</div></blockquote>
|
||||
<p>Once you have the dummyrunner running, stop it with <code class="docutils literal notranslate"><span class="pre">Ctrl-C</span></code>.</p>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><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="#introduction">Introduction</a></li>
|
||||
<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></li>
|
||||
<li><a class="reference internal" href="#analyzing-the-profile">Analyzing the profile</a></li>
|
||||
<li><a class="reference internal" href="#the-dummyrunner">The Dummyrunner</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Profiling.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Profiling.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Profiling</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
222
docs/1.0-dev/Coding/Quirks.html
Normal file
222
docs/1.0-dev/Coding/Quirks.html
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Quirks — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Quirks</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="quirks">
|
||||
<h1>Quirks<a class="headerlink" href="#quirks" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This is a list of various quirks or common stumbling blocks that people often ask about or report
|
||||
when using (or trying to use) Evennia. They are not bugs.</p>
|
||||
<div class="section" id="forgetting-to-use-reload-to-see-changes-to-your-typeclasses">
|
||||
<h2>Forgetting to use @reload to see changes to your typeclasses<a class="headerlink" href="#forgetting-to-use-reload-to-see-changes-to-your-typeclasses" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Firstly: Reloading the server is a safe and usually quick operation which will <em>not</em> disconnect any
|
||||
accounts.</p>
|
||||
<p>New users tend to forget this step. When editing source code (such as when tweaking typeclasses and
|
||||
commands or adding new commands to command sets) you need to either use the in-game <code class="docutils literal notranslate"><span class="pre">@reload</span></code>
|
||||
command or, from the command line do <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">evennia.py</span> <span class="pre">reload</span></code> before you see your changes.</p>
|
||||
</div>
|
||||
<div class="section" id="web-admin-to-create-new-account">
|
||||
<h2>Web admin to create new Account<a class="headerlink" href="#web-admin-to-create-new-account" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you use the default login system and are trying to use the Web admin to create a new Player
|
||||
account, you need to consider which <code class="docutils literal notranslate"><span class="pre">MULTIACCOUNT_MODE</span></code> you are in. If you are in
|
||||
<code class="docutils literal notranslate"><span class="pre">MULTIACCOUNT_MODE</span></code> <code class="docutils literal notranslate"><span class="pre">0</span></code> or <code class="docutils literal notranslate"><span class="pre">1</span></code>, the login system expects each Account to also have a Character
|
||||
object named the same as the Account - there is no character creation screen by default. If using
|
||||
the normal mud login screen, a Character with the same name is automatically created and connected
|
||||
to your Account. From the web interface you must do this manually.</p>
|
||||
<p>So, when creating the Account, make sure to also create the Character <em>from the same form</em> as you
|
||||
create the Account from. This should set everything up for you. Otherwise you need to manually set
|
||||
the “account” property on the Character and the “character” property on the Account to point to each
|
||||
other. You must also set the lockstring of the Character to allow the Account to “puppet” this
|
||||
particular character.</p>
|
||||
</div>
|
||||
<div class="section" id="mutable-attributes-and-their-connection-to-the-database">
|
||||
<h2>Mutable attributes and their connection to the database<a class="headerlink" href="#mutable-attributes-and-their-connection-to-the-database" title="Permalink to this headline">¶</a></h2>
|
||||
<p>When storing a mutable object (usually a list or a dictionary) in an Attribute</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="nb">object</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">mylist</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>you should know that the connection to the database is retained also if you later extract that
|
||||
Attribute into another variable (what is stored and retrieved is actually a <code class="docutils literal notranslate"><span class="pre">PackedList</span></code> or a
|
||||
<code class="docutils literal notranslate"><span class="pre">PackedDict</span></code> that works just like their namesakes except they save themselves to the database when
|
||||
changed). So if you do</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">alist</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">mylist</span>
|
||||
<span class="n">alist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>this updates the database behind the scenes, so both <code class="docutils literal notranslate"><span class="pre">alist</span></code> and <code class="docutils literal notranslate"><span class="pre">object.db.mylist</span></code> are now
|
||||
<code class="docutils literal notranslate"><span class="pre">[1,2,3,4]</span></code></p>
|
||||
<p>If you don’t want this, Evennia provides a way to stably disconnect the mutable from the database by
|
||||
use of <code class="docutils literal notranslate"><span class="pre">evennia.utils.dbserialize.deserialize</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3
|
||||
4</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia.utils.dbserialize</span> <span class="kn">import</span> <span class="n">deserialize</span>
|
||||
|
||||
<span class="n">blist</span> <span class="o">=</span> <span class="n">deserialize</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">mylist</span><span class="p">)</span>
|
||||
<span class="n">blist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>The property <code class="docutils literal notranslate"><span class="pre">blist</span></code> is now <code class="docutils literal notranslate"><span class="pre">[1,2,3,4]</span></code> whereas <code class="docutils literal notranslate"><span class="pre">object.db.mylist</span></code> remains unchanged. If you want to
|
||||
update the database you’d need to explicitly re-assign the updated data to the <code class="docutils literal notranslate"><span class="pre">mylist</span></code> Attribute.</p>
|
||||
</div>
|
||||
<div class="section" id="commands-are-matched-by-name-or-alias">
|
||||
<h2>Commands are matched by name <em>or</em> alias<a class="headerlink" href="#commands-are-matched-by-name-or-alias" title="Permalink to this headline">¶</a></h2>
|
||||
<p>When merging <a class="reference internal" href="../Components/Commands.html"><span class="doc">command sets</span></a> it’s important to remember that command objects are identified
|
||||
<em>both</em> by key <em>or</em> alias. So if you have a command with a key <code class="docutils literal notranslate"><span class="pre">look</span></code> and an alias <code class="docutils literal notranslate"><span class="pre">ls</span></code>, introducing
|
||||
another command with a key <code class="docutils literal notranslate"><span class="pre">ls</span></code> will be assumed by the system to be <em>identical</em> to the first one.
|
||||
This usually means merging cmdsets will overload one of them depending on priority. Whereas this is
|
||||
logical once you know how command objects are handled, it may be confusing if you are just looking
|
||||
at the command strings thinking they are parsed as-is.</p>
|
||||
</div>
|
||||
<div class="section" id="objects-turning-to-defaultobject">
|
||||
<h2>Objects turning to <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code><a class="headerlink" href="#objects-turning-to-defaultobject" title="Permalink to this headline">¶</a></h2>
|
||||
<p>A common confusing error for new developers is finding that one or more objects in-game are suddenly
|
||||
of the type <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> rather than the typeclass you wanted it to be. This happens when you
|
||||
introduce a critical Syntax error to the module holding your custom class. Since such a module is
|
||||
not valid Python, Evennia can’t load it at all to get to the typeclasses within. To keep on running,
|
||||
Evennia will solve this by printing the full traceback to the terminal/console and temporarily fall
|
||||
back to the safe <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> until you fix the problem and reload. Most errors of this kind will
|
||||
be caught by any good text editors. Keep an eye on the terminal/console during a reload to catch
|
||||
such errors - you may have to scroll up if your window is small.</p>
|
||||
</div>
|
||||
<div class="section" id="overriding-of-magic-methods">
|
||||
<h2>Overriding of magic methods<a class="headerlink" href="#overriding-of-magic-methods" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Python implements a system of <a class="reference external" href="https://docs.python.org/3/reference/datamodel.html#emulating-container-types">magic
|
||||
methods</a>, usually
|
||||
prefixed and suffixed by double-underscores (<code class="docutils literal notranslate"><span class="pre">__example__</span></code>) that allow object instances to have
|
||||
certain operations performed on them without needing to do things like turn them into strings or
|
||||
numbers first– for example, is <code class="docutils literal notranslate"><span class="pre">obj1</span></code> greater than or equal to <code class="docutils literal notranslate"><span class="pre">obj2</span></code>?</p>
|
||||
<p>Neither object is a number, but given <code class="docutils literal notranslate"><span class="pre">obj1.size</span> <span class="pre">==</span> <span class="pre">"small"</span></code> and <code class="docutils literal notranslate"><span class="pre">obj2.size</span> <span class="pre">==</span> <span class="pre">"large"</span></code>, how might
|
||||
one compare these two arbitrary English adjective strings to figure out which is greater than the
|
||||
other? By defining the <code class="docutils literal notranslate"><span class="pre">__ge__</span></code> (greater than or equal to) magic method on the object class in which
|
||||
you figure out which word has greater significance, perhaps through use of a mapping table
|
||||
(<code class="docutils literal notranslate"><span class="pre">{'small':0,</span> <span class="pre">'large':10}</span></code>) or other lookup and comparing the numeric values of each.</p>
|
||||
<p>Evennia extensively makes use of magic methods on typeclasses to do things like initialize objects,
|
||||
check object existence or iterate over objects in an inventory or container. If you override or
|
||||
interfere with the return values from the methods Evennia expects to be both present and working, it
|
||||
can result in very inconsistent and hard-to-diagnose errors.</p>
|
||||
<p>The moral of the story– it can be dangerous to tinker with magic methods on typeclassed objects.
|
||||
Try to avoid doing so.</p>
|
||||
</div>
|
||||
<div class="section" id="known-upstream-bugs">
|
||||
<h2>Known upstream bugs<a class="headerlink" href="#known-upstream-bugs" title="Permalink to this headline">¶</a></h2>
|
||||
<ul>
|
||||
<li><p>There is currently (Autumn 2017) a bug in the <code class="docutils literal notranslate"><span class="pre">zope.interface</span></code> installer on some Linux Ubuntu
|
||||
distributions (notably Ubuntu 16.04 LTS). Zope is a dependency of Twisted. The error manifests in
|
||||
the server not starting with an error that <code class="docutils literal notranslate"><span class="pre">zope.interface</span></code> is not found even though <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">list</span></code>
|
||||
shows it’s installed. The reason is a missing empty <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> file at the root of the zope
|
||||
package. If the virtualenv is named “evenv” as suggested in the <a class="reference internal" href="../Setup/Setup-Quickstart.html"><span class="doc">Setup Quickstart</span></a>
|
||||
instructions, use the following command to fix it:</p>
|
||||
<div class="highlight-shell notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span>touch evenv/local/lib/python2.7/site-packages/zope/__init__.py
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>This will create the missing file and things should henceforth work correctly.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Quirks</a><ul>
|
||||
<li><a class="reference internal" href="#forgetting-to-use-reload-to-see-changes-to-your-typeclasses">Forgetting to use @reload to see changes to your typeclasses</a></li>
|
||||
<li><a class="reference internal" href="#web-admin-to-create-new-account">Web admin to create new Account</a></li>
|
||||
<li><a class="reference internal" href="#mutable-attributes-and-their-connection-to-the-database">Mutable attributes and their connection to the database</a></li>
|
||||
<li><a class="reference internal" href="#commands-are-matched-by-name-or-alias">Commands are matched by name <em>or</em> alias</a></li>
|
||||
<li><a class="reference internal" href="#objects-turning-to-defaultobject">Objects turning to <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code></a></li>
|
||||
<li><a class="reference internal" href="#overriding-of-magic-methods">Overriding of magic methods</a></li>
|
||||
<li><a class="reference internal" href="#known-upstream-bugs">Known upstream bugs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Quirks.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Quirks.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Quirks</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
226
docs/1.0-dev/Coding/Setting-up-PyCharm.html
Normal file
226
docs/1.0-dev/Coding/Setting-up-PyCharm.html
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Setting up PyCharm — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Setting up PyCharm</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="setting-up-pycharm">
|
||||
<h1>Setting up PyCharm<a class="headerlink" href="#setting-up-pycharm" title="Permalink to this headline">¶</a></h1>
|
||||
</div>
|
||||
<div class="section" id="directions-for-setting-up-pycharm-with-evennia">
|
||||
<h1>Directions for setting up PyCharm with Evennia<a class="headerlink" href="#directions-for-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 developer’s 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 you’re 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 evennia’s core code or the scripts inside your virtualenv, you’ll
|
||||
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">></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>
|
||||
<div class="section" id="setting-up-the-project-interpreter">
|
||||
<h2>Setting up the project interpreter<a class="headerlink" href="#setting-up-the-project-interpreter" title="Permalink to this headline">¶</a></h2>
|
||||
<p>It’s a good idea to do 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">></span> <span class="pre">Settings...</span> <span class="pre">></span> <span class="pre">Project:</span> <span class="pre">\<mygame\></span> <span class="pre">></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">></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>
|
||||
</div>
|
||||
<div class="section" id="attaching-pycharm-debugger-to-evennia">
|
||||
<h2>Attaching PyCharm debugger to Evennia<a class="headerlink" href="#attaching-pycharm-debugger-to-evennia" 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">></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=\<mygame\>\server\logs\server.log</span> <span class="pre">--python=\<evennia</span> <span class="pre">repo\>\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 server.py
|
||||
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"</span> <span class="pre">--nodaemon</span></code>. This is an
|
||||
example for windows, I don’t have a working mac/linux box.
|
||||
<img alt="Example process filter configuration" src="https://i.imgur.com/vkSheR8.png" /></p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="setting-up-an-evennia-run-configuration">
|
||||
<h2>Setting up an Evennia run configuration<a class="headerlink" href="#setting-up-an-evennia-run-configuration" 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">></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">\<yourrepo\>\evenv\Scripts\evennia_launcher.py</span></code> (substitute your virtualenv if
|
||||
it’s 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 you’ll 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 you’ll
|
||||
be able start it again.</p>
|
||||
</div>
|
||||
<div class="section" id="alternative-run-configuration-utilizing-logfiles-as-source-of-data">
|
||||
<h2>Alternative run configuration - utilizing logfiles as source of data<a class="headerlink" href="#alternative-run-configuration-utilizing-logfiles-as-source-of-data" title="Permalink to this headline">¶</a></h2>
|
||||
<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">></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">></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 don’t 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 it’s 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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Setting up PyCharm</a></li>
|
||||
<li><a class="reference internal" href="#directions-for-setting-up-pycharm-with-evennia">Directions for setting up PyCharm with Evennia</a><ul>
|
||||
<li><a class="reference internal" href="#setting-up-the-project-interpreter">Setting up the project interpreter</a></li>
|
||||
<li><a class="reference internal" href="#attaching-pycharm-debugger-to-evennia">Attaching PyCharm debugger to Evennia</a></li>
|
||||
<li><a class="reference internal" href="#setting-up-an-evennia-run-configuration">Setting up an Evennia run configuration</a></li>
|
||||
<li><a class="reference internal" href="#alternative-run-configuration-utilizing-logfiles-as-source-of-data">Alternative run configuration - utilizing logfiles as source of data</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Setting-up-PyCharm.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Setting-up-PyCharm.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Setting up PyCharm</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
600
docs/1.0-dev/Coding/Unit-Testing.html
Normal file
600
docs/1.0-dev/Coding/Unit-Testing.html
Normal file
|
|
@ -0,0 +1,600 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Unit Testing — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Unit Testing</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" 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="http://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>
|
||||
<div class="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-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">test</span> <span class="n">evennia</span>
|
||||
</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-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">test</span> <span class="n">evennia</span><span class="o">.</span><span class="n">commands</span><span class="o">.</span><span class="n">default</span>
|
||||
</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 haven’t introduced an
|
||||
unexpected bug.</p>
|
||||
</div>
|
||||
<div class="section" id="running-tests-with-custom-settings-file">
|
||||
<h2>Running tests with custom settings file<a class="headerlink" href="#running-tests-with-custom-settings-file" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you have implemented your own tests for your game (see below) you can run them from your game dir
|
||||
with</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>
|
||||
</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>Those tests will all be run using the default settings. 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-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>
|
||||
</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>
|
||||
</div>
|
||||
<div class="section" id="writing-new-tests">
|
||||
<h2>Writing new tests<a class="headerlink" href="#writing-new-tests" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Evennia’s test suite makes use of Django unit test system, which in turn relies on Python’s
|
||||
<em>unittest</em> module.</p>
|
||||
<blockquote>
|
||||
<div><p>If you want to help out writing unittests for Evennia, take a look at Evennia’s <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.</p>
|
||||
</div></blockquote>
|
||||
<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 Evennia’s <code class="docutils literal notranslate"><span class="pre">tests.py</span></code> modules to see how they look.</p>
|
||||
<p>Inside a testing file, a <code class="docutils literal notranslate"><span class="pre">unittest.TestCase</span></code> class is used to test a single aspect or component in
|
||||
various ways. Each test case contains one or more <em>test methods</em> - these define the actual tests to
|
||||
run. You can name the test methods anything you want as long as the name starts with “<code class="docutils literal notranslate"><span class="pre">test_</span></code>”.
|
||||
Your <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class can also have a method <code class="docutils literal notranslate"><span class="pre">setUp()</span></code>. This is run before each test, setting up and
|
||||
storing whatever preparations the test methods need. Conversely, a <code class="docutils literal notranslate"><span class="pre">tearDown()</span></code> method can
|
||||
optionally do cleanup after each test.</p>
|
||||
<p>To test the results, you use special methods of the <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class. Many of those start with
|
||||
“<code class="docutils literal notranslate"><span class="pre">assert</span></code>”, such as <code class="docutils literal notranslate"><span class="pre">assertEqual</span></code> or <code class="docutils literal notranslate"><span class="pre">assertTrue</span></code>.</p>
|
||||
<p>Example of a <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="kn">import</span> <span class="nn">unittest</span>
|
||||
|
||||
<span class="c1"># the function we want to test</span>
|
||||
<span class="kn">from</span> <span class="nn">mypath</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">"This tests a function myfunc."</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="s2">"test method. Makes sure return value is as expected."</span>
|
||||
<span class="n">expected_return</span> <span class="o">=</span> <span class="s2">"This is me being nice."</span>
|
||||
<span class="n">actual_return</span> <span class="o">=</span> <span class="n">myfunc</span><span class="p">()</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="s2">"test method. Calls with a keyword argument."</span>
|
||||
<span class="n">expected_return</span> <span class="o">=</span> <span class="s2">"This is me being baaaad."</span>
|
||||
<span class="n">actual_return</span> <span class="o">=</span> <span class="n">myfunc</span><span class="p">(</span><span class="n">bad</span><span class="o">=</span><span class="bp">True</span><span class="p">)</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>
|
||||
</td></tr></table></div>
|
||||
<p>You might also want to read the <a class="reference external" href="http://docs.python.org/library/unittest.html">documentation for the unittest
|
||||
module</a>.</p>
|
||||
<div class="section" id="using-the-evenniatest-class">
|
||||
<h3>Using the EvenniaTest class<a class="headerlink" href="#using-the-evenniatest-class" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Evennia offers a custom TestCase, the <code class="docutils literal notranslate"><span class="pre">evennia.utils.test_resources.EvenniaTest</span></code> class. This class
|
||||
initiates a range of useful properties on themselves for testing Evennia systems. Examples are
|
||||
<code class="docutils literal notranslate"><span class="pre">.account</span></code> and <code class="docutils literal notranslate"><span class="pre">.session</span></code> representing a mock connected Account and its Session and <code class="docutils literal notranslate"><span class="pre">.char1</span></code> and
|
||||
<code class="docutils literal notranslate"><span class="pre">char2</span></code> representing Characters complete with a location in the test database. These are all useful
|
||||
when testing Evennia system requiring any of the default Evennia typeclasses as inputs. See the full
|
||||
definition of the <code class="docutils literal notranslate"><span class="pre">EvenniaTest</span></code> class in
|
||||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia/utils/test_resources.py">evennia/utils/test_resources.py</a>.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10</pre></div></td><td class="code"><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="k">def</span> <span class="nf">test_object_search</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="c1"># char1 and char2 are both created in room1</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="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>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<div class="section" id="testing-in-game-commands">
|
||||
<h3>Testing in-game Commands<a class="headerlink" href="#testing-in-game-commands" title="Permalink to this headline">¶</a></h3>
|
||||
<p>In-game Commands are a special case. Tests for the default commands are put in
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/commands/default/tests.py</span></code>. This uses a custom <code class="docutils literal notranslate"><span class="pre">CommandTest</span></code> class that inherits from
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia.utils.test_resources.EvenniaTest</span></code> described above. <code class="docutils literal notranslate"><span class="pre">CommandTest</span></code> supplies extra convenience
|
||||
functions for executing commands and check that their return values (calls of <code class="docutils literal notranslate"><span class="pre">msg()</span></code> returns
|
||||
expected values. It uses Characters and Sessions generated on the <code class="docutils literal notranslate"><span class="pre">EvenniaTest</span></code> class to call each
|
||||
class).</p>
|
||||
<p>Each command tested should have its own <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class. Inherit this class from the <code class="docutils literal notranslate"><span class="pre">CommandTest</span></code>
|
||||
class in the same module to get access to the command-specific utilities mentioned.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11</pre></div></td><td class="code"><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">CommandTest</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands.default</span> <span class="kn">import</span> <span class="n">general</span>
|
||||
<span class="k">class</span> <span class="nc">TestSet</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
|
||||
<span class="s2">"tests the look command by simple call, using Char2 as a target"</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">general</span><span class="o">.</span><span class="n">CmdLook</span><span class="p">(),</span> <span class="s2">"Char2"</span><span class="p">,</span> <span class="s2">"Char2(#7)"</span><span class="p">)</span>
|
||||
<span class="s2">"tests the look command by simple call, with target as room"</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="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">general</span><span class="o">.</span><span class="n">CmdLook</span><span class="p">(),</span> <span class="s2">"Room"</span><span class="p">,</span>
|
||||
<span class="s2">"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">"</span>
|
||||
<span class="s2">"You see: Obj(#4), Obj2(#5), Char2(#7)"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<div class="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/New-Models.html"><span class="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 Evennia’s 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 [stackexchange
|
||||
answer](http://stackoverflow.com/questions/502916/django-how-to-create-a-model-dynamically-just-for-
|
||||
testing#503435) is currently untested! Please report your findings.</p>
|
||||
</div></blockquote>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
||||
24
|
||||
25
|
||||
26
|
||||
27
|
||||
28
|
||||
29
|
||||
30
|
||||
31
|
||||
32
|
||||
33
|
||||
34
|
||||
35
|
||||
36
|
||||
37
|
||||
38
|
||||
39
|
||||
40
|
||||
41
|
||||
42
|
||||
43
|
||||
44</pre></div></td><td class="code"><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">EvenniaTest</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">'contrib.mycontrib.tests'</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">"default"</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ENGINE"</span><span class="p">:</span> <span class="s2">"django.db.backends.sqlite3"</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">"1_7.W001"</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">EvenniaTest</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="bp">False</span>
|
||||
<span class="n">call_command</span><span class="p">(</span><span class="s1">'syncdb'</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="bp">False</span>
|
||||
<span class="n">call_command</span><span class="p">(</span><span class="s1">'syncdb'</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>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<div class="section" id="a-note-on-adding-new-tests">
|
||||
<h3>A note on adding new tests<a class="headerlink" href="#a-note-on-adding-new-tests" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Having an extensive tests suite is very important for avoiding code degradation as Evennia is
|
||||
developed. Only a small fraction of the Evennia codebase is covered by test suites at this point.
|
||||
Writing new tests is not hard, it’s more a matter of finding the time to do so. So adding new tests
|
||||
is really an area where everyone can contribute, also with only limited Python skills.</p>
|
||||
</div>
|
||||
<div class="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 don’t 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"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3
|
||||
4</pre></div></td><td class="code"><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">'test_without_migrations'</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="testing-for-game-development-mini-tutorial">
|
||||
<h2>Testing for Game development (mini-tutorial)<a class="headerlink" href="#testing-for-game-development-mini-tutorial" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Unit testing can be of paramount importance to game developers. When starting with a new game, it is
|
||||
recommended to look into unit testing as soon as possible; an already huge game is much harder to
|
||||
write tests for. The benefits of testing a game aren’t different from the ones regarding library
|
||||
testing. For example it is easy to introduce bugs that affect previously working code. Testing is
|
||||
there to ensure your project behaves the way it should and continue to do so.</p>
|
||||
<p>If you have never used unit testing (with Python or another language), you might want to check the
|
||||
<a class="reference external" href="https://docs.python.org/2/library/unittest.html">official Python documentation about unit testing</a>,
|
||||
particularly the first section dedicated to a basic example.</p>
|
||||
<div class="section" id="basic-testing-using-evennia">
|
||||
<h3>Basic testing using Evennia<a class="headerlink" href="#basic-testing-using-evennia" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Evennia’s test runner can be used to launch tests in your game directory (let’s call it ‘mygame’).
|
||||
Evennia’s test runner does a few useful things beyond the normal Python unittest module:</p>
|
||||
<ul class="simple">
|
||||
<li><p>It creates and sets up an empty database, with some useful objects (accounts, characters and
|
||||
rooms, among others).</p></li>
|
||||
<li><p>It provides simple ways to test commands, which can be somewhat tricky at times, if not tested
|
||||
properly.</p></li>
|
||||
</ul>
|
||||
<p>Therefore, you should use the command-line to execute the test runner, while specifying your own
|
||||
game directories (not the one containing evennia). Go to your game directory (referred as ‘mygame’
|
||||
in this section) and execute the test runner:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</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="n">test</span> <span class="n">commands</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This command will execute Evennia’s test runner using your own settings file. It will set up a dummy
|
||||
database of your choice and look into the ‘commands’ package defined in your game directory
|
||||
(<code class="docutils literal notranslate"><span class="pre">mygame/commands</span></code> in this example) to find tests. The test module’s name should begin with ‘test’
|
||||
and contain one or more <code class="docutils literal notranslate"><span class="pre">TestCase</span></code>. A full example can be found below.</p>
|
||||
</div>
|
||||
<div class="section" id="a-simple-example">
|
||||
<h3>A simple example<a class="headerlink" href="#a-simple-example" title="Permalink to this headline">¶</a></h3>
|
||||
<p>In your game directory, go to <code class="docutils literal notranslate"><span class="pre">commands</span></code> and create a new file <code class="docutils literal notranslate"><span class="pre">tests.py</span></code> inside (it could be named
|
||||
anything starting with <code class="docutils literal notranslate"><span class="pre">test</span></code>). We will start by making a test that has nothing to do with Commands,
|
||||
just to show how unit testing works:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># mygame/commands/tests.py</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">unittest</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">TestString</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="sd">"""Unittest for strings (just a basic example)."""</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">test_upper</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Test the upper() str method."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s1">'foo'</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="s1">'FOO'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>This example, inspired from the Python documentation, is used to test the ‘upper()’ method of the
|
||||
‘str’ class. Not very useful, but it should give you a basic idea of how tests are used.</p>
|
||||
<p>Let’s execute that test to see if it works.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">evennia</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="n">test</span> <span class="n">commands</span>
|
||||
|
||||
<span class="n">TESTING</span><span class="p">:</span> <span class="n">Using</span> <span class="n">specified</span> <span class="n">settings</span> <span class="n">file</span> <span class="s1">'server.conf.settings'</span><span class="o">.</span>
|
||||
|
||||
<span class="p">(</span><span class="n">Obs</span><span class="p">:</span> <span class="n">Evennia</span><span class="s1">'s full test suite may not pass if the settings are very</span>
|
||||
<span class="n">different</span> <span class="kn">from</span> <span class="nn">the</span> <span class="n">default</span><span class="o">.</span> <span class="n">Use</span> <span class="s1">'test .'</span> <span class="k">as</span> <span class="n">arguments</span> <span class="n">to</span> <span class="n">run</span> <span class="n">only</span> <span class="n">tests</span>
|
||||
<span class="n">on</span> <span class="n">the</span> <span class="n">game</span> <span class="nb">dir</span><span class="o">.</span><span class="p">)</span>
|
||||
|
||||
<span class="n">Creating</span> <span class="n">test</span> <span class="n">database</span> <span class="k">for</span> <span class="n">alias</span> <span class="s1">'default'</span><span class="o">...</span>
|
||||
<span class="o">.</span>
|
||||
<span class="o">----------------------------------------------------------------------</span>
|
||||
<span class="n">Ran</span> <span class="mi">1</span> <span class="n">test</span> <span class="ow">in</span> <span class="mf">0.001</span><span class="n">s</span>
|
||||
|
||||
<span class="n">OK</span>
|
||||
<span class="n">Destroying</span> <span class="n">test</span> <span class="n">database</span> <span class="k">for</span> <span class="n">alias</span> <span class="s1">'default'</span><span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We specified the <code class="docutils literal notranslate"><span class="pre">commands</span></code> package to the evennia test command since that’s where we put our test
|
||||
file. In this case we could just as well just said <code class="docutils literal notranslate"><span class="pre">.</span></code> to search all of <code class="docutils literal notranslate"><span class="pre">mygame</span></code> for testing files.
|
||||
If we have a lot of tests it may be useful to test only a single set at a time though. We get an
|
||||
information text telling us we are using our custom settings file (instead of Evennia’s default
|
||||
file) and then the test runs. The test passes! Change the “FOO” string to something else in the test
|
||||
to see how it looks when it fails.</p>
|
||||
</div>
|
||||
<div class="section" id="testing-commands">
|
||||
<h3>Testing commands<a class="headerlink" href="#testing-commands" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>This is not correct anymore.</p>
|
||||
</div>
|
||||
<p>This section will test the proper execution of the ‘abilities’ command, as described in the DELETED
|
||||
tutorial to create the ‘abilities’ command, we will need it to test it.</p>
|
||||
<p>Testing commands in Evennia is a bit more complex than the simple testing example we have seen.
|
||||
Luckily, Evennia supplies a special test class to do just that … we just need to inherit from it
|
||||
and use it properly. This class is called ‘CommandTest’ and is defined in the
|
||||
‘evennia.commands.default.tests’ package. To create a test for our ‘abilities’ command, we just
|
||||
need to create a class that inherits from ‘CommandTest’ and add methods.</p>
|
||||
<p>We could create a new test file for this but for now we just append to the <code class="docutils literal notranslate"><span class="pre">tests.py</span></code> file we
|
||||
already have in <code class="docutils literal notranslate"><span class="pre">commands</span></code> from before.</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># bottom of mygame/commands/tests.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands.default.tests</span> <span class="kn">import</span> <span class="n">CommandTest</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">commands.command</span> <span class="kn">import</span> <span class="n">CmdAbilities</span>
|
||||
<span class="kn">from</span> <span class="nn">typeclasses.characters</span> <span class="kn">import</span> <span class="n">Character</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">TestAbilities</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
|
||||
|
||||
<span class="n">character_typeclass</span> <span class="o">=</span> <span class="n">Character</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">test_simple</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">CmdAbilities</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"STR: 5, AGI: 4, MAG: 2"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<ul class="simple">
|
||||
<li><p>Line 1-4: we do some importing. ‘CommandTest’ is going to be our base class for our test, so we
|
||||
need it. We also import our command (‘CmdAbilities’ in this case). Finally we import the
|
||||
‘Character’ typeclass. We need it, since ‘CommandTest’ doesn’t use ‘Character’, but
|
||||
‘DefaultCharacter’, which means the character calling the command won’t have the abilities we have
|
||||
written in the ‘Character’ typeclass.</p></li>
|
||||
<li><p>Line 6-8: that’s the body of our test. Here, a single command is tested in an entire class.
|
||||
Default commands are usually grouped by category in a single class. There is no rule, as long as
|
||||
you know where you put your tests. Note that we set the ‘character_typeclass’ class attribute to
|
||||
Character. As explained above, if you didn’t do that, the system would create a ‘DefaultCharacter’
|
||||
object, not a ‘Character’. You can try to remove line 4 and 8 to see what happens when running the
|
||||
test.</p></li>
|
||||
<li><p>Line 10-11: our unique testing method. Note its name: it should begin by ‘test_’. Apart from
|
||||
that, the method is quite simple: it’s an instance method (so it takes the ‘self’ argument) but no
|
||||
other arguments are needed. Line 11 uses the ‘call’ method, which is defined in ‘CommandTest’.
|
||||
It’s a useful method that compares a command against an expected result. It would be like comparing
|
||||
two strings with ‘assertEqual’, but the ‘call’ method does more things, including testing the
|
||||
command in a realistic way (calling its hooks in the right order, so you don’t have to worry about
|
||||
that).</p></li>
|
||||
</ul>
|
||||
<p>Line 11 can be understood as: test the ‘abilities’ command (first parameter), with no argument
|
||||
(second parameter), and check that the character using it receives his/her abilities (third
|
||||
parameter).</p>
|
||||
<p>Let’s run our new test:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">evennia</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="n">test</span> <span class="n">commands</span>
|
||||
<span class="p">[</span><span class="o">...</span><span class="p">]</span>
|
||||
<span class="n">Creating</span> <span class="n">test</span> <span class="n">database</span> <span class="k">for</span> <span class="n">alias</span> <span class="s1">'default'</span><span class="o">...</span>
|
||||
<span class="o">..</span>
|
||||
<span class="o">----------------------------------------------------------------------</span>
|
||||
<span class="n">Ran</span> <span class="mi">2</span> <span class="n">tests</span> <span class="ow">in</span> <span class="mf">0.156</span><span class="n">s</span>
|
||||
|
||||
<span class="n">OK</span>
|
||||
<span class="n">Destroying</span> <span class="n">test</span> <span class="n">database</span> <span class="k">for</span> <span class="n">alias</span> <span class="s1">'default'</span><span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Two tests were executed, since we have kept ‘TestString’ from last time. In case of failure, you
|
||||
will get much more information to help you fix the bug.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><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-tests-with-custom-settings-file">Running tests with custom settings file</a></li>
|
||||
<li><a class="reference internal" href="#writing-new-tests">Writing new tests</a><ul>
|
||||
<li><a class="reference internal" href="#using-the-evenniatest-class">Using the EvenniaTest class</a></li>
|
||||
<li><a class="reference internal" href="#testing-in-game-commands">Testing in-game Commands</a></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-adding-new-tests">A note on adding new tests</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>
|
||||
<li><a class="reference internal" href="#testing-for-game-development-mini-tutorial">Testing for Game development (mini-tutorial)</a><ul>
|
||||
<li><a class="reference internal" href="#basic-testing-using-evennia">Basic testing using Evennia</a></li>
|
||||
<li><a class="reference internal" href="#a-simple-example">A simple example</a></li>
|
||||
<li><a class="reference internal" href="#testing-commands">Testing commands</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Unit-Testing.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Unit Testing</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
236
docs/1.0-dev/Coding/Updating-Your-Game.html
Normal file
236
docs/1.0-dev/Coding/Updating-Your-Game.html
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Updating Your Game — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Updating Your Game</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="updating-your-game">
|
||||
<h1>Updating Your Game<a class="headerlink" href="#updating-your-game" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Fortunately, it’s extremely easy to keep your Evennia server up-to-date. If you haven’t already, see
|
||||
the <a class="reference internal" href="../Setup/Setup-Quickstart.html"><span class="doc">Getting Started guide</span></a> and get everything running.</p>
|
||||
<div class="section" id="updating-with-the-latest-evennia-code-changes">
|
||||
<h2>Updating with the latest Evennia code changes<a class="headerlink" href="#updating-with-the-latest-evennia-code-changes" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Very commonly we make changes to the Evennia code to improve things. There are many ways to get told
|
||||
when to update: You can subscribe to the RSS feed or manually check up on the feeds from
|
||||
http://www.evennia.com. You can also simply fetch the latest regularly.</p>
|
||||
<p>When you’re wanting to apply updates, simply <code class="docutils literal notranslate"><span class="pre">cd</span></code> to your cloned <code class="docutils literal notranslate"><span class="pre">evennia</span></code> root directory and type:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">git</span> <span class="n">pull</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>assuming you’ve got the command line client. If you’re using a graphical client, you will probably
|
||||
want to navigate to the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> directory and either right click and find your client’s pull
|
||||
function, or use one of the menus (if applicable).</p>
|
||||
<p>You can review the latest changes with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">git</span> <span class="n">log</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or the equivalent in the graphical client. You can also see the latest changes online
|
||||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/CHANGELOG.md">here</a>.</p>
|
||||
<p>You will always need to do <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reload</span></code> (or <code class="docutils literal notranslate"><span class="pre">reload</span></code> from -in-game) from your game-dir to have
|
||||
the new code affect your game. If you want to be really sure you should run a full <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">reboot</span></code>
|
||||
so that both Server and Portal can restart (this will disconnect everyone though, so if you know the
|
||||
Portal has had no updates you don’t have to do that).</p>
|
||||
</div>
|
||||
<div class="section" id="upgrading-evennia-dependencies">
|
||||
<h2>Upgrading Evennia dependencies<a class="headerlink" href="#upgrading-evennia-dependencies" title="Permalink to this headline">¶</a></h2>
|
||||
<p>On occasion we update the versions of third-party libraries Evennia depend on (or we may add a new
|
||||
dependency). This will be announced on the mailing list/forum. If you run into errors when starting
|
||||
Evennia, always make sure you have the latest versions of everything. In some cases, like for
|
||||
Django, starting the server may also give warning saying that you are using a working, but too-old
|
||||
version that should not be used in production.</p>
|
||||
<p>Upgrading <code class="docutils literal notranslate"><span class="pre">evennia</span></code> will automatically fetch all the latest packages that it now need. First <code class="docutils literal notranslate"><span class="pre">cd</span></code> to
|
||||
your cloned <code class="docutils literal notranslate"><span class="pre">evennia</span></code> folder. Make sure your <code class="docutils literal notranslate"><span class="pre">virtualenv</span></code> is active and use</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="o">--</span><span class="n">upgrade</span> <span class="o">-</span><span class="n">e</span> <span class="o">.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Remember the period (<code class="docutils literal notranslate"><span class="pre">.</span></code>) at the end - that applies the upgrade to the current location (your
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia</span></code> dir).</p>
|
||||
<blockquote>
|
||||
<div><p>The <code class="docutils literal notranslate"><span class="pre">-e</span></code> means that we are <em>linking</em> the evennia sources rather than copying them into the
|
||||
environment. This means we can most of the time just update the sources (with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code>) and see
|
||||
those changes directly applied to our installed <code class="docutils literal notranslate"><span class="pre">evennia</span></code> package. Without installing/upgrading the
|
||||
package with <code class="docutils literal notranslate"><span class="pre">-e</span></code>, we would have to remember to upgrade the package every time we downloaded any new
|
||||
source-code changes.</p>
|
||||
</div></blockquote>
|
||||
<p>Follow the upgrade output to make sure it finishes without errors. To check what packages are
|
||||
currently available in your python environment after the upgrade, use</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="nb">list</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show you the version of all installed packages. The <code class="docutils literal notranslate"><span class="pre">evennia</span></code> package will also show the
|
||||
location of its source code.</p>
|
||||
</div>
|
||||
<div class="section" id="migrating-the-database-schema">
|
||||
<h2>Migrating the Database Schema<a class="headerlink" href="#migrating-the-database-schema" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Whenever we change the database layout of Evennia upstream (such as when we add new features) you
|
||||
will need to <em>migrate</em> your existing database. When this happens it will be clearly noted in the
|
||||
<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code> (it will say something to the effect of “Run migrations”). Database changes will also be
|
||||
announced on the Evennia <a class="reference external" href="https://groups.google.com/forum/#%21forum/evennia">mailing list</a>.</p>
|
||||
<p>When the database schema changes, you just go to your game folder and run</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span> <span class="n">migrate</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<blockquote>
|
||||
<div><p>Hint: If the <code class="docutils literal notranslate"><span class="pre">evennia</span></code> command is not found, you most likely need to activate your
|
||||
<a class="reference external" href="Glossary.html#virtualenv">virtualenv</a>.</p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="resetting-your-database">
|
||||
<h2>Resetting your database<a class="headerlink" href="#resetting-your-database" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Should you ever want to start over completely from scratch, there is no need to re-download Evennia
|
||||
or anything like that. You just need to clear your database. Once you are done, you just rebuild it
|
||||
from scratch by running</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">migrate</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The first step in wiping your database is to stop Evennia completely with</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">stop</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you run the default <code class="docutils literal notranslate"><span class="pre">SQlite3</span></code> database (to change this you need to edit your <code class="docutils literal notranslate"><span class="pre">settings.py</span></code> file),
|
||||
the database is actually just a normal file in <code class="docutils literal notranslate"><span class="pre">mygame/server/</span></code> called <code class="docutils literal notranslate"><span class="pre">evennia.db3</span></code>. <em>Simply delete
|
||||
that file</em> - that’s it. Now run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">migrate</span></code> to recreate a new, fresh one.</p>
|
||||
<p>If you run some other database system you can instead flush the database:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">flush</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will empty the database. However, it will not reset the internal counters of the database, so
|
||||
you will start with higher dbref values. If this is okay, this is all you need.</p>
|
||||
<p>Django also offers an easy way to start the database’s own management should we want more direct
|
||||
control:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span> <span class="n">dbshell</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In e.g. MySQL you can then do something like this (assuming your MySQL database is named “Evennia”:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mysql</span><span class="o">></span> <span class="n">DROP</span> <span class="n">DATABASE</span> <span class="n">Evennia</span><span class="p">;</span>
|
||||
<span class="n">mysql</span><span class="o">></span> <span class="n">exit</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<blockquote>
|
||||
<div><p>NOTE: Under Windows OS, in order to access SQLite dbshell you need to <a class="reference external" href="https://www.sqlite.org/download.html">download the SQLite
|
||||
command-line shell program</a>. It’s a single executable file
|
||||
(sqlite3.exe) that you should place in the root of either your MUD folder or Evennia’s (it’s the
|
||||
same, in both cases Django will find it).</p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="more-about-schema-migrations">
|
||||
<h2>More about schema migrations<a class="headerlink" href="#more-about-schema-migrations" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If and when an Evennia update modifies the database <em>schema</em> (that is, the under-the-hood details as
|
||||
to how data is stored in the database), you must update your existing database correspondingly to
|
||||
match the change. If you don’t, the updated Evennia will complain that it cannot read the database
|
||||
properly. Whereas schema changes should become more and more rare as Evennia matures, it may still
|
||||
happen from time to time.</p>
|
||||
<p>One way one could handle this is to apply the changes manually to your database using the database’s
|
||||
command line. This often means adding/removing new tables or fields as well as possibly convert
|
||||
existing data to match what the new Evennia version expects. It should be quite obvious that this
|
||||
quickly becomes cumbersome and error-prone. If your database doesn’t contain anything critical yet
|
||||
it’s probably easiest to simply reset it and start over rather than to bother converting.</p>
|
||||
<p>Enter <em>migrations</em>. Migrations keeps track of changes in the database schema and applies them
|
||||
automatically for you. Basically, whenever the schema changes we distribute small files called
|
||||
“migrations” with the source. Those tell the system exactly how to implement the change so you don’t
|
||||
have to do so manually. When a migration has been added we will tell you so on Evennia’s mailing
|
||||
lists and in commit messages -
|
||||
you then just run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">migrate</span></code> to be up-to-date again.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Updating Your Game</a><ul>
|
||||
<li><a class="reference internal" href="#updating-with-the-latest-evennia-code-changes">Updating with the latest Evennia code changes</a></li>
|
||||
<li><a class="reference internal" href="#upgrading-evennia-dependencies">Upgrading Evennia dependencies</a></li>
|
||||
<li><a class="reference internal" href="#migrating-the-database-schema">Migrating the Database Schema</a></li>
|
||||
<li><a class="reference internal" href="#resetting-your-database">Resetting your database</a></li>
|
||||
<li><a class="reference internal" href="#more-about-schema-migrations">More about schema migrations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Updating-Your-Game.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Updating-Your-Game.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Updating Your Game</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
140
docs/1.0-dev/Coding/Using-Travis.html
Normal file
140
docs/1.0-dev/Coding/Using-Travis.html
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Using Travis — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Using Travis</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="using-travis">
|
||||
<h1>Using Travis<a class="headerlink" href="#using-travis" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia uses <a class="reference external" href="http://travis-ci.org/">Travis CI</a> to check that it’s building successfully after every
|
||||
commit to its Github repository (you can for example see the <code class="docutils literal notranslate"><span class="pre">build:</span> <span class="pre">passing</span></code> badge at the top of
|
||||
Evennia’s <a class="reference external" href="https://github.com/evennia/evennia">Readme file</a>). If your game is open source on Github
|
||||
you may also use Travis for free. See [the Travis docs](http://docs.travis-ci.com/user/getting-
|
||||
started/) for how to get started.</p>
|
||||
<p>After logging in you will get to point Travis to your repository on github. One further thing you
|
||||
need to set up yourself is a Travis config file named <code class="docutils literal notranslate"><span class="pre">.travis.yml</span></code> (note the initial period <code class="docutils literal notranslate"><span class="pre">.</span></code>).
|
||||
This should be created in the root of your game directory. The idea with this file is that it
|
||||
describes what Travis needs to import and build in order to create an instance of Evennia from
|
||||
scratch and then run validation tests on it. Here is an example:</p>
|
||||
<div class="highlight-yaml notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="nt">language</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">python</span>
|
||||
<span class="nt">python</span><span class="p">:</span>
|
||||
<span class="p p-Indicator">-</span> <span class="s">"2.7"</span>
|
||||
<span class="nt">install</span><span class="p">:</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">git clone https://github.com/evennia/evennia.git</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd evennia</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">pip install -e .</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd $TRAVIS_BUILD_DIR</span>
|
||||
<span class="nt">script</span><span class="p">:</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">evennia migrate</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">evennia test evennia</span>
|
||||
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">evennia test</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>This will tell travis how to download Evennia, install it, set up a database and then run the test
|
||||
suite.
|
||||
You need to add this file to git (<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">add</span> <span class="pre">.travis.yml</span></code>) and then commit your changes before Travis
|
||||
will be able to see it.</p>
|
||||
<p>For properly testing your game you of course also need to write unittests. [We have a page](Unit-
|
||||
Testing) on how we set those up for Evennia, you should be able to refer to that for making tests
|
||||
fitting your game.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<p class="logo"><a href="../index.html">
|
||||
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
|
||||
</a></p>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Using-Travis.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Using-Travis.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Using Travis</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
557
docs/1.0-dev/Coding/Version-Control.html
Normal file
557
docs/1.0-dev/Coding/Version-Control.html
Normal file
|
|
@ -0,0 +1,557 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Version Control — Evennia 1.0-dev documentation</title>
|
||||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Version Control</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="version-control">
|
||||
<h1>Version Control<a class="headerlink" href="#version-control" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Version control software allows you to track the changes you make to your code, as well as being
|
||||
able to easily backtrack these changes, share your development efforts and more. Even if you are not
|
||||
contributing to Evennia itself, and only wish to develop your own MU* using Evennia, having a
|
||||
version control system in place is a good idea (and standard coding practice). For an introduction
|
||||
to the concept, start with the Wikipedia article
|
||||
<a class="reference external" href="http://en.wikipedia.org/wiki/Version_control">here</a>. Evennia uses the version control system
|
||||
<a class="reference external" href="https://git-scm.com/">Git</a> and this is what will be covered henceforth. Note that this page also
|
||||
deals with commands for Linux operating systems, and the steps below may vary for other systems,
|
||||
however where possible links will be provided for alternative instructions.</p>
|
||||
<p>For more 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>
|
||||
<div class="section" id="setting-up-git">
|
||||
<h2>Setting up Git<a class="headerlink" href="#setting-up-git" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you have gotten Evennia installed, you will have Git already and can skip to <strong>Step 2</strong> below.
|
||||
Otherwise you will need to install Git on your platform. You can find expanded instructions for
|
||||
installation <a class="reference external" href="http://git-scm.com/book/en/Getting-Started-Installing-Git">here</a>.</p>
|
||||
<div class="section" id="step-1-install-git">
|
||||
<h3>Step 1: Install Git<a class="headerlink" href="#step-1-install-git" title="Permalink to this headline">¶</a></h3>
|
||||
<ul>
|
||||
<li><p><strong>Fedora Linux</strong></p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">yum</span> <span class="n">install</span> <span class="n">git</span><span class="o">-</span><span class="n">core</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><strong>Debian Linux</strong> <em>(Ubuntu, Linux Mint, etc.)</em></p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">apt</span><span class="o">-</span><span class="n">get</span> <span class="n">install</span> <span class="n">git</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><strong>Windows</strong>: It is recommended to use <a class="reference external" href="http://msysgit.github.io/">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="http://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>
|
||||
</div>
|
||||
<div class="section" id="step-2-define-user-e-mail-settings-for-git">
|
||||
<h3>Step 2: Define user/e-mail Settings for Git<a class="headerlink" href="#step-2-define-user-e-mail-settings-for-git" title="Permalink to this headline">¶</a></h3>
|
||||
<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>
|
||||
<blockquote>
|
||||
<div><p>Note that your commit information will be visible to everyone if you ever contribute to Evennia or
|
||||
use an online service like github to host your code. So if you are not comfortable with using your
|
||||
real, full name online, put a nickname here.</p>
|
||||
</div></blockquote>
|
||||
<ol>
|
||||
<li><p>Set the default name for git to use when you commit:</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">user</span><span class="o">.</span><span class="n">name</span> <span class="s2">"Your Name Here"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p>Set the default email for git to use when you commit:</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">user</span><span class="o">.</span><span class="n">email</span> <span class="s2">"your_email@example.com"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="putting-your-game-folder-under-version-control">
|
||||
<h2>Putting your game folder under version control<a class="headerlink" href="#putting-your-game-folder-under-version-control" title="Permalink to this headline">¶</a></h2>
|
||||
<blockquote>
|
||||
<div><p>Note: The game folder’s version control is completely separate from Evennia’s repository.</p>
|
||||
</div></blockquote>
|
||||
<p>After you have set up your game you will have created a new folder to host your particular game
|
||||
(let’s call this folder <code class="docutils literal notranslate"><span class="pre">mygame</span></code> for now).</p>
|
||||
<p>This folder is <em>not</em> under version control at this point.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">init</span> <span class="n">mygame</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Your mygame folder is now ready for version control! Now add all the content and make a first
|
||||
commit:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cd</span> <span class="n">mygame</span>
|
||||
<span class="n">git</span> <span class="n">add</span> <span class="o">*</span>
|
||||
<span class="n">git</span> <span class="n">commit</span> <span class="o">-</span><span class="n">m</span> <span class="s2">"Initial commit"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Read on for help on what these commands do.</p>
|
||||
<div class="section" id="tracking-files">
|
||||
<h3>Tracking files<a class="headerlink" href="#tracking-files" title="Permalink to this headline">¶</a></h3>
|
||||
<p>When working on your code or fix bugs in your local branches you may end up creating new files. If
|
||||
you do you must tell Git to track them by using the add command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">add</span> <span class="o"><</span><span class="n">filename</span><span class="o">></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can check the current status of version control with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">status</span></code>. This will show if you have
|
||||
any modified, added or otherwise changed files. Some files, like database files, logs and temporary
|
||||
PID files are usually <em>not</em> tracked in version control. These should either not show up or have a
|
||||
question mark in front of them.</p>
|
||||
</div>
|
||||
<div class="section" id="controlling-tracking">
|
||||
<h3>Controlling tracking<a class="headerlink" href="#controlling-tracking" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You will notice that some files are not covered by your git version control, notably your settings
|
||||
file (<code class="docutils literal notranslate"><span class="pre">mygame/server/conf/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 controlled by the hidden file <code class="docutils literal notranslate"><span class="pre">mygame/.gitignore</span></code>. Evennia creates this file as part of the
|
||||
creation of your game directory. Everything matched in this file will be ignored by GIT. If you want
|
||||
to, for example, include your settings file for collaborators to access, remove that entry in
|
||||
<code class="docutils literal notranslate"><span class="pre">.gitignore</span></code>.</p>
|
||||
<blockquote>
|
||||
<div><p>Note: 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 you’ll confuse yourself so that after a few commits and reverts don’t know what is in your
|
||||
database or not. If you want to backup your database, do so by simply copying the file on your hard
|
||||
drive to a backup-name.</p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="committing-your-code">
|
||||
<h3>Committing your Code<a class="headerlink" href="#committing-your-code" title="Permalink to this headline">¶</a></h3>
|
||||
<blockquote>
|
||||
<div><p>Committing means storing the current snapshot of your code within git. This creates a “save point”
|
||||
or “history” of your development process. You can later jump back and forth in your history, for
|
||||
example to figure out just when a bug was introduced or see what results the code used to produce
|
||||
compared to now.</p>
|
||||
</div></blockquote>
|
||||
<p>It’s usually a good idea to commit your changes often. Committing is fast and local only - you will
|
||||
never commit anything online at this point. To commit your changes, use</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">commit</span> <span class="o">--</span><span class="nb">all</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will save all changes you made since last commit. The command will open a text editor where you
|
||||
can add a message detailing the changes you’ve made. Make it brief but informative. You can see the
|
||||
history of commits with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code>. If you don’t want to use the editor you can set the message
|
||||
directly by using the <code class="docutils literal notranslate"><span class="pre">-m</span></code> flag:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">commit</span> <span class="o">--</span><span class="nb">all</span> <span class="o">-</span><span class="n">m</span> <span class="s2">"This fixes a bug in the combat code."</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="changing-your-mind">
|
||||
<h3>Changing your mind<a class="headerlink" href="#changing-your-mind" title="Permalink to this headline">¶</a></h3>
|
||||
<p>If you have non-committed changes that you realize you want to throw away, you can do the following:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">checkout</span> <span class="o"><</span><span class="n">file</span> <span class="n">to</span> <span class="n">revert</span><span class="o">></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will revert the file to the state it was in at your last <code class="docutils literal notranslate"><span class="pre">commit</span></code>, throwing away the changes
|
||||
you did to it since. It’s a good way to make wild experiments without having to remember just what
|
||||
you changed. If you do <code class="docutils literal notranslate"> <span class="pre">git</span> <span class="pre">checkout</span> <span class="pre">.</span></code> you will throw away <em>all</em> changes since the last commit.</p>
|
||||
</div>
|
||||
<div class="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 push it to your own remote repository on GitHub.</p>
|
||||
<ol class="simple">
|
||||
<li><p>Make sure you have your game directory setup under git version control as described above. Make
|
||||
sure to commit any changes.</p></li>
|
||||
<li><p>Create a new, empty repository on Github. Github explains how
|
||||
<a class="reference external" href="https://help.github.com/articles/create-a-repo/">here</a> (do <em>not</em> “Initialize the repository with a
|
||||
README” or else you’ll create unrelated histories).</p></li>
|
||||
<li><p>From your local game dir, do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">remote</span> <span class="pre">add</span> <span class="pre">origin</span> <span class="pre"><github</span> <span class="pre">URL></span></code> where <code class="docutils literal notranslate"><span class="pre"><github</span> <span class="pre">URL></span></code> is the URL
|
||||
to your online repo. This tells your game dir that it should be pushing to the remote online dir.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">remote</span> <span class="pre">-v</span></code> to verify the online dir.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span> <span class="pre">origin</span> <span class="pre">master</span></code> now pushes your game dir online so you can see it on github.com.</p></li>
|
||||
</ol>
|
||||
<p>You can commit your work locally (<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">commit</span> <span class="pre">--all</span> <span class="pre">-m</span> <span class="pre">"Make</span> <span class="pre">a</span> <span class="pre">change</span> <span class="pre">that</span> <span class="pre">..."</span></code>) as many times as
|
||||
you want. When you want to push those changes to your online repo, you do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code>. You can also
|
||||
<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">clone</span> <span class="pre"><url_to_online_repo></span></code> from your online repo to somewhere else (like your production
|
||||
server) and henceforth do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code> to update that to the latest thing you pushed.</p>
|
||||
<p>Note that GitHub’s repos are, by default publicly visible by all. Creating a publicly visible online
|
||||
clone might not be what you want for all parts of your development process - you may prefer a more
|
||||
private venue when sharing your revolutionary work with your team. If that’s the case you can change
|
||||
your repository to “Private” in the github settings. Then your code will only be visible to those
|
||||
you specifically grant access.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="forking-evennia">
|
||||
<h2>Forking Evennia<a class="headerlink" href="#forking-evennia" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This helps you set up an online <em>fork</em> of Evennia so you can easily commit fixes and help with
|
||||
upstream development.</p>
|
||||
<div class="section" id="step-1-fork-the-evennia-master-repository">
|
||||
<h3>Step 1: Fork the evennia/master repository<a class="headerlink" href="#step-1-fork-the-evennia-master-repository" title="Permalink to this headline">¶</a></h3>
|
||||
<blockquote>
|
||||
<div><p>Before proceeding with the following step, make sure you have registered and created an account on
|
||||
<a class="reference external" href="https://github.com/">GitHub.com</a>. This is necessary in order to create a fork of Evennia’s master
|
||||
repository, and to push your commits to your fork either for yourself or for contributing to
|
||||
Evennia.</p>
|
||||
</div></blockquote>
|
||||
<p>A <em>fork</em> is a clone of the master repository that you can make your own commits and changes to. At
|
||||
the top of <a class="reference external" href="https://github.com/evennia/evennia">this page</a>, click the “Fork” button, as it appears
|
||||
below. <img alt="https://github-images.s3.amazonaws.com/help/bootcamp/Bootcamp-Fork.png" src="https://github-images.s3.amazonaws.com/help/bootcamp/Bootcamp-Fork.png" /></p>
|
||||
</div>
|
||||
<div class="section" id="step-2-clone-your-fork">
|
||||
<h3>Step 2: Clone your fork<a class="headerlink" href="#step-2-clone-your-fork" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The fork only exists online as of yet. In a terminal, change your directory to the folder you wish
|
||||
to develop in. From this directory run the following command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">clone</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">yourusername</span><span class="o">/</span><span class="n">evennia</span><span class="o">.</span><span class="n">git</span>
|
||||
</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.</p>
|
||||
</div>
|
||||
<div class="section" id="step-3-configure-remotes">
|
||||
<h3>Step 3: Configure remotes<a class="headerlink" href="#step-3-configure-remotes" title="Permalink to this headline">¶</a></h3>
|
||||
<p>A <em>remote</em> is a repository stored on another computer, in this case on GitHub’s server. When a
|
||||
repository is cloned, it has a default remote called <code class="docutils literal notranslate"><span class="pre">origin</span></code>. This points to your fork on GitHub,
|
||||
not the original repository it was forked from. To easily keep track of the original repository
|
||||
(that is, Evennia’s official repository), you need to add another remote. The standard name for this
|
||||
remote is “upstream”.</p>
|
||||
<p>Below we change the active directory to the newly cloned “evennia” directory and then assign the
|
||||
original Evennia repository to a remote called “upstream”:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cd</span> <span class="n">evennia</span>
|
||||
<span class="n">git</span> <span class="n">remote</span> <span class="n">add</span> <span class="n">upstream</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">evennia</span><span class="o">/</span><span class="n">evennia</span><span class="o">.</span><span class="n">git</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you also want to access Evennia’s <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch (the bleeding edge development branch) do the
|
||||
following:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">fetch</span> <span class="n">upstream</span> <span class="n">develop</span>
|
||||
<span class="n">git</span> <span class="n">checkout</span> <span class="n">develop</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You should now have the upstream branch available locally. You can use this instead of <code class="docutils literal notranslate"><span class="pre">master</span></code>
|
||||
below if you are contributing new features rather than bug fixes.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="working-with-your-fork">
|
||||
<h2>Working with your fork<a class="headerlink" href="#working-with-your-fork" title="Permalink to this headline">¶</a></h2>
|
||||
<blockquote>
|
||||
<div><p>A <em>branch</em> is a separate instance of your code. Changes you do to code in a branch does not affect
|
||||
that in other branches (so if you for example add/commit a file to one branch and then switches to
|
||||
another branch, that file will be gone until you switch back to the first branch again). One can
|
||||
switch between branches at will and create as many branches as one needs for a given project. The
|
||||
content of branches can also be merged together or deleted without affecting other branches. This is
|
||||
not only a common way to organize development but also to test features without messing with
|
||||
existing code.</p>
|
||||
</div></blockquote>
|
||||
<p>The default <em>branch</em> of git is called the “master” branch. As a rule of thumb, you should <em>never</em>
|
||||
make modifications directly to your local copy of the master branch. Rather keep the master clean
|
||||
and only update it by pulling our latest changes to it. Any work you do should instead happen in a
|
||||
local, other branches.</p>
|
||||
<div class="section" id="making-a-work-branch">
|
||||
<h3>Making a work branch<a class="headerlink" href="#making-a-work-branch" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">checkout</span> <span class="o">-</span><span class="n">b</span> <span class="n">myfixes</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This command will checkout and automatically create the new branch <code class="docutils literal notranslate"><span class="pre">myfixes</span></code> on your machine. If you
|
||||
stared out in the master branch, <em>myfixes</em> will be a perfect copy of the master branch. You can see
|
||||
which branch you are on with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">branch</span></code> and change between different branches with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">checkout</span> <span class="pre"><branchname></span></code>.</p>
|
||||
<p>Branches are fast and cheap to create and manage. It is common practice to create a new branch for
|
||||
every bug you want to work on or feature you want to create, then create a <em>pull request</em> for that
|
||||
branch to be merged upstream (see below). Not only will this organize your work, it will also make
|
||||
sure that <em>your</em> master branch version of Evennia is always exactly in sync with the upstream
|
||||
version’s master branch.</p>
|
||||
</div>
|
||||
<div class="section" id="updating-with-upstream-changes">
|
||||
<h3>Updating with upstream changes<a class="headerlink" href="#updating-with-upstream-changes" title="Permalink to this headline">¶</a></h3>
|
||||
<p>When Evennia’s official repository updates, first make sure to commit all your changes to your
|
||||
branch and then checkout the “clean” master branch:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">commit</span> <span class="o">--</span><span class="nb">all</span>
|
||||
<span class="n">git</span> <span class="n">checkout</span> <span class="n">master</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Pull the latest changes from upstream:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">pull</span> <span class="n">upstream</span> <span class="n">master</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This should sync your local master branch with upstream Evennia’s master branch. Now we go back to
|
||||
our own work-branch (let’s say it’s still called “myfixes”) and <em>merge</em> the updated master into our
|
||||
branch.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">checkout</span> <span class="n">myfixes</span>
|
||||
<span class="n">git</span> <span class="n">merge</span> <span class="n">master</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If everything went well, your <code class="docutils literal notranslate"><span class="pre">myfixes</span></code> branch will now have the latest version of Evennia merged
|
||||
with whatever changes you have done. Use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">log</span></code> to see what has changed. You may need to restart
|
||||
the server or run <code class="docutils literal notranslate"><span class="pre">manage.py</span> <span class="pre">migrate</span></code> if the database schema changed (this will be seen in the
|
||||
commit log and on the mailing list). See the <a class="reference external" href="http://git-scm.com/documentation">Git manuals</a> for
|
||||
learning more about useful day-to-day commands, and special situations such as dealing with merge
|
||||
collisions.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="sharing-your-code-publicly">
|
||||
<h2>Sharing your Code Publicly<a class="headerlink" href="#sharing-your-code-publicly" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Up to this point your <code class="docutils literal notranslate"><span class="pre">myfixes</span></code> branch only exists on your local computer. No one else can see it.
|
||||
If you want a copy of this branch to also appear in your online fork on GitHub, make sure to have
|
||||
checked out your “myfixes” branch and then run the following:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">push</span> <span class="o">-</span><span class="n">u</span> <span class="n">origin</span> <span class="n">myfixes</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will create a new <em>remote branch</em> named “myfixes” in your online repository (which is refered
|
||||
to as “origin” by default); the <code class="docutils literal notranslate"><span class="pre">-u</span></code> flag makes sure to set this to the default push location.
|
||||
Henceforth you can just use <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code> from your myfixes branch to push your changes online. This is
|
||||
a great way to keep your source backed-up and accessible. Remember though that by default your
|
||||
repository will be public so everyone will be able to browse and download your code (same way as you
|
||||
can with Evennia itself). If you want secrecy you can change your repository to “Private” in the
|
||||
Github settings. Note though that if you do, you might have trouble contributing to Evennia (since
|
||||
we can’t see the code you want to share).</p>
|
||||
<p><em>Note: If you hadn’t setup a public key on GitHub or aren’t asked for a username/password, you might
|
||||
get an error <code class="docutils literal notranslate"><span class="pre">403:</span> <span class="pre">Forbidden</span> <span class="pre">Access</span></code> at this stage. In that case, 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 credentials there:</em></p>
|
||||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3</pre></div></td><td class="code"><div class="highlight"><pre><span></span>machine github.com
|
||||
login <my_github_username>
|
||||
password <my_github_password>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</div>
|
||||
<div class="section" id="committing-fixes-to-evennia">
|
||||
<h2>Committing fixes to Evennia<a class="headerlink" href="#committing-fixes-to-evennia" title="Permalink to this headline">¶</a></h2>
|
||||
<p><em>Contributing</em> can mean both bug-fixes or adding new features to Evennia. Please note that if your
|
||||
change is not already listed and accepted in the <a class="reference external" href="https://github.com/evennia/evennia/issues">Issue
|
||||
Tracker</a>, it is recommended that you first hit the
|
||||
developer mailing list or IRC chat to see beforehand if your feature is deemed suitable to include
|
||||
as a core feature in the engine. When it comes to bug-fixes, other developers may also have good
|
||||
input on how to go about resolving the issue.</p>
|
||||
<p>To contribute you need to have <a class="reference external" href="Coding/Version-Control.html#forking-evennia">forked Evennia</a> first. As described
|
||||
above you should do your modification in a separate local branch (not in the master branch). This
|
||||
branch is what you then present to us (as a <em>Pull request</em>, PR, see below). We can then merge your
|
||||
change into the upstream master and you then do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code> to update master usual. Now that the
|
||||
master is updated with your fixes, you can safely delete your local work branch. Below we describe
|
||||
this work flow.</p>
|
||||
<p>First update the Evennia master branch to the latest Evennia version:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">checkout</span> <span class="n">master</span>
|
||||
<span class="n">git</span> <span class="n">pull</span> <span class="n">upstream</span> <span class="n">master</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Next, create a new branch to hold your contribution. Let’s call it the “fixing_strange_bug” branch:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">checkout</span> <span class="o">-</span><span class="n">b</span> <span class="n">fixing_strange_bug</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It is wise to make separate branches for every fix or series of fixes you want to contribute. You
|
||||
are now in your new <code class="docutils literal notranslate"><span class="pre">fixing_strange_bug</span></code> branch. You can list all branches with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">branch</span></code> and
|
||||
jump between branches with <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">checkout</span> <span class="pre"><branchname></span></code>. Code and test things in here, committing as
|
||||
you go:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">commit</span> <span class="o">--</span><span class="nb">all</span> <span class="o">-</span><span class="n">m</span> <span class="s2">"Fix strange bug in look command. Resolves #123."</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can make multiple commits if you want, depending on your work flow and progress. Make sure to
|
||||
always make clear and descriptive commit messages so it’s easy to see what you intended. To refer
|
||||
to, say, issue number 123, write <code class="docutils literal notranslate"><span class="pre">#123</span></code>, it will turn to a link on GitHub. If you include the text
|
||||
“Resolves #123”, that issue will be auto-closed on GitHub if your commit gets merged into main
|
||||
Evennia.</p>
|
||||
<blockquote>
|
||||
<div><p>If you refer to in-game commands that start with <code class="docutils literal notranslate"><span class="pre">@</span></code>(such as <code class="docutils literal notranslate"><span class="pre">@examine</span></code>), please put them in
|
||||
backticks `, for example `@examine`. The reason for this is that GitHub uses <code class="docutils literal notranslate"><span class="pre">@username</span></code> to refer
|
||||
to GitHub users, so if you forget the ticks, any user happening to be named <code class="docutils literal notranslate"><span class="pre">examine</span></code> will get a
|
||||
notification ….</p>
|
||||
</div></blockquote>
|
||||
<p>If you implement multiple separate features/bug-fixes, split them into different branches if they
|
||||
are very different and should be handled as separate PRs. You can do any number of commits to your
|
||||
branch as you work. Once you are at a stage where you want to show the world what you did you might
|
||||
want to consider making it clean for merging into Evennia’s master branch by using <a class="reference external" href="https://www.git-scm.com/book/en/v2/Git-Branching-Rebasing">git
|
||||
rebase</a> (this is not always necessary,
|
||||
and if it sounds too hard, say so and we’ll handle it on our end).</p>
|
||||
<p>Once you are ready, push your work to your online Evennia fork on github, in a new remote branch:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">push</span> <span class="o">-</span><span class="n">u</span> <span class="n">origin</span> <span class="n">fixing_strange_bug</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">-u</span></code> flag is only needed the first time - this tells GIT to create a remote branch. If you
|
||||
already created the remote branch earlier, just stand in your <code class="docutils literal notranslate"><span class="pre">fixing_strange_bug</span></code> branch and do
|
||||
<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">push</span></code>.</p>
|
||||
<p>Now you should tell the Evennia developers that they should consider merging your brilliant changes
|
||||
into Evennia proper. <a class="reference external" href="https://github.com/evennia/evennia/pulls">Create a pull request</a> and follow
|
||||
the instructions. Make sure to specifically select your <code class="docutils literal notranslate"><span class="pre">fixing_strange_bug</span></code> branch to be the source
|
||||
of the merge. Evennia developers will then be able to examine your request and merge it if it’s
|
||||
deemed suitable.</p>
|
||||
<p>Once your changes have been merged into Evennia your local <code class="docutils literal notranslate"><span class="pre">fixing_strange_bug</span></code> can be deleted
|
||||
(since your changes are now available in the “clean” Evennia repository). Do</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">branch</span> <span class="o">-</span><span class="n">D</span> <span class="n">fixing_strange_bug</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>to delete your work branch. Update your master branch (<code class="docutils literal notranslate"><span class="pre">checkout</span> <span class="pre">master</span></code> and then <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">pull</span></code>) and
|
||||
you should get your fix back, now as a part of official Evennia!</p>
|
||||
</div>
|
||||
<div class="section" id="git-tips-and-tricks">
|
||||
<h2>GIT tips and tricks<a class="headerlink" href="#git-tips-and-tricks" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Some of the GIT commands can feel a little long and clunky if you need to do them often. Luckily you
|
||||
can create aliases for those. Here are some useful commands to run:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git st </span>
|
||||
<span class="c1"># - view brief status info</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">st</span> <span class="s1">'status -s'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Above, you only need to ever enter the <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">config</span> <span class="pre">...</span></code> command once - you have then added the new
|
||||
alias. Afterwards, just do <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">st</span></code> to get status info. All the examples below follow the same
|
||||
template.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git cl </span>
|
||||
<span class="c1"># - clone a repository</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">cl</span> <span class="n">clone</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git cma "commit message" </span>
|
||||
<span class="c1"># - commit all changes without opening editor for message</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">cma</span> <span class="s1">'commit -a -m'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git ca</span>
|
||||
<span class="c1"># - amend text to your latest commit message</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">ca</span> <span class="s1">'commit --amend'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git fl</span>
|
||||
<span class="c1"># - file log; shows diffs of files in latest commits</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">fl</span> <span class="s1">'log -u'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git co [branchname]</span>
|
||||
<span class="c1"># - checkout </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">co</span> <span class="n">checkout</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git br <branchname></span>
|
||||
<span class="c1"># - create branch</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">br</span> <span class="n">branch</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git ls</span>
|
||||
<span class="c1"># - view log tree</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">ls</span> <span class="s1">'log --pretty=format:"%C(green)%h\ %C(yellow)[</span><span class="si">%a</span><span class="s1">d]%Cred</span><span class="si">%d</span><span class="se">\</span>
|
||||
<span class="s1">%Creset</span><span class="si">%s</span><span class="s1">%Cblue\ [</span><span class="si">%c</span><span class="s1">n]" --decorate --date=relative --graph'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git diff</span>
|
||||
<span class="c1"># - show current uncommitted changes</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">diff</span> <span class="s1">'diff --word-diff'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># git grep <query></span>
|
||||
<span class="c1"># - search (grep) codebase for a search criterion</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">grep</span> <span class="s1">'grep -Ii'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To get a further feel for GIT there is also <a class="reference external" href="https://www.youtube.com/watch?v=1ffBJ4sVUb4#t=1m58s">a good YouTube talk about
|
||||
it</a> - it’s 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>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Version Control</a><ul>
|
||||
<li><a class="reference internal" href="#setting-up-git">Setting up Git</a><ul>
|
||||
<li><a class="reference internal" href="#step-1-install-git">Step 1: Install Git</a></li>
|
||||
<li><a class="reference internal" href="#step-2-define-user-e-mail-settings-for-git">Step 2: Define user/e-mail Settings for Git</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#putting-your-game-folder-under-version-control">Putting your game folder under version control</a><ul>
|
||||
<li><a class="reference internal" href="#tracking-files">Tracking files</a></li>
|
||||
<li><a class="reference internal" href="#controlling-tracking">Controlling tracking</a></li>
|
||||
<li><a class="reference internal" href="#committing-your-code">Committing your Code</a></li>
|
||||
<li><a class="reference internal" href="#changing-your-mind">Changing your mind</a></li>
|
||||
<li><a class="reference internal" href="#pushing-your-code-online">Pushing your code online</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#forking-evennia">Forking Evennia</a><ul>
|
||||
<li><a class="reference internal" href="#step-1-fork-the-evennia-master-repository">Step 1: Fork the evennia/master repository</a></li>
|
||||
<li><a class="reference internal" href="#step-2-clone-your-fork">Step 2: Clone your fork</a></li>
|
||||
<li><a class="reference internal" href="#step-3-configure-remotes">Step 3: Configure remotes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#working-with-your-fork">Working with your fork</a><ul>
|
||||
<li><a class="reference internal" href="#making-a-work-branch">Making a work branch</a></li>
|
||||
<li><a class="reference internal" href="#updating-with-upstream-changes">Updating with upstream changes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#sharing-your-code-publicly">Sharing your Code Publicly</a></li>
|
||||
<li><a class="reference internal" href="#committing-fixes-to-evennia">Committing fixes to Evennia</a></li>
|
||||
<li><a class="reference internal" href="#git-tips-and-tricks">GIT tips and tricks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Version-Control.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Version-Control.html">1.0-dev (develop branch)</a></li>
|
||||
<li><a href="../../0.9.1/index.html">0.9.1 (master branch)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Version Control</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2020, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue