<p>This is a small tutorial for customizing your character objects, using the example of letting users
turn on and off ANSI color parsing as an example. <codeclass="docutils literal notranslate"><spanclass="pre">@options</span><spanclass="pre">NOCOLOR=True</span></code> will now do what this
tutorial shows, but the tutorial subject can be applied to other toggles you may want, as well.</p>
<p>In the Building guide’s <aclass="reference external"href="Concepts/TextTags.html#coloured-text">Colors</a> page you can learn how to add color to your
<li><p>Define your own default character typeclass, inheriting from Evennia’s default.</p></li>
<li><p>Set an attribute on the character to control markup on/off.</p></li>
<li><p>Set your custom character class to be the default for new accounts.</p></li>
<li><p>Overload the <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method on the typeclass and change how it uses markup.</p></li>
<li><p>Create a custom command to allow users to change their setting.</p></li>
<p>Create a new module in <codeclass="docutils literal notranslate"><spanclass="pre">mygame/typeclasses</span></code> named, for example, <codeclass="docutils literal notranslate"><spanclass="pre">mycharacter.py</span></code>. Alternatively you
can simply add a new class to ‘mygamegame/typeclasses/characters.py’.</p>
<p>In your new module(or characters.py), create a new <aclass="reference internal"href="../Components/Typeclasses.html"><spanclass="doc">Typeclass</span></a> inheriting from
<codeclass="docutils literal notranslate"><spanclass="pre">evennia.DefaultCharacter</span></code>. We will also import <codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.ansi</span></code>, which we will use later.</p>
<p>Above we set a simple config value as an <aclass="reference internal"href="../Components/Attributes.html"><spanclass="doc">Attribute</span></a>.</p>
<p>Let’s make sure that new characters are created of this type. Edit your
<codeclass="docutils literal notranslate"><spanclass="pre">mygame/server/conf/settings.py</span></code> file and add/change <codeclass="docutils literal notranslate"><spanclass="pre">BASE_CHARACTER_TYPECLASS</span></code> to point to your new
character class. Observe that this will only affect <em>new</em> characters, not those already created. You
have to convert already created characters to the new typeclass by using the <codeclass="docutils literal notranslate"><spanclass="pre">@typeclass</span></code> command
(try on a secondary character first though, to test that everything works - you don’t want to render
<p><codeclass="docutils literal notranslate"><spanclass="pre">@typeclass</span></code> changes Bob’s typeclass and runs all its creation hooks all over again. The <codeclass="docutils literal notranslate"><spanclass="pre">/reset</span></code>
switch clears all attributes and properties back to the default for the new typeclass - this is
useful in this case to avoid ending up with an object having a “mixture” of properties from the old
typeclass and the new one. <codeclass="docutils literal notranslate"><spanclass="pre">/force</span></code> might be needed if you edit the typeclass and want to update the
object despite the actual typeclass name not having changed.</p>
<h2>Overload the <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method<aclass="headerlink"href="#overload-the-msg-method"title="Permalink to this headline">¶</a></h2>
<p>Next we need to overload the <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method. What we want is to check the configuration value before
calling the main function. The original <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> method call is seen in <codeclass="docutils literal notranslate"><spanclass="pre">evennia/objects/objects.py</span></code>
<spanclass="k">if</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">db</span><spanclass="o">.</span><spanclass="n">config_color</span><spanclass="ow">is</span><spanclass="ow">not</span><spanclass="kc">None</span><spanclass="p">:</span><spanclass="c1"># this would mean it was not set</span>
<p>Above we create a custom version of the <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method. If the configuration Attribute is set, it
strips the ANSI from the text it is about to send, and then calls the parent <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> as usual. You
need to <codeclass="docutils literal notranslate"><spanclass="pre">@reload</span></code> before your changes become visible.</p>
<p>There we go! Just flip the attribute <codeclass="docutils literal notranslate"><spanclass="pre">config_color</span></code> to False and your users will not see any color.
As superuser (assuming you use the Typeclass <codeclass="docutils literal notranslate"><spanclass="pre">ColorableCharacter</span></code>) you can test this with the <codeclass="docutils literal notranslate"><spanclass="pre">@py</span></code>
<p>For completeness, let’s add a custom command so users can turn off their color display themselves if
they want.</p>
<p>In <codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands</span></code>, create a new file, call it for example <codeclass="docutils literal notranslate"><spanclass="pre">configcmds.py</span></code> (it’s likely that
you’ll want to add other commands for configuration down the line). You can also copy/rename the
<spanclass="c1"># send a message with a tiny bit of formatting, just for fun</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Color was turned |won|W."</span><spanclass="p">)</span>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"Color was turned off."</span><spanclass="p">)</span>
<p>Lastly, we make this command available to the user by adding it to the default <codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code> in
<codeclass="docutils literal notranslate"><spanclass="pre">mygame/commands/default_cmdsets.py</span></code> and reloading the server. Make sure you also import the
text)). The <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method supports the <codeclass="docutils literal notranslate"><spanclass="pre">xterm256</span></code> keyword for manually activating/deactiving
xterm256. It should be easy to expand the above example to allow players to customize xterm256
regardless of if Evennia thinks their client supports it or not.</p>
<p>To get a better understanding of how <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> works with keywords, you can try this as superuser:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span><spanclass="nd">@py</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"|123Dark blue with xterm256, bright blue with ANSI"</span><spanclass="p">,</span><spanclass="n">xterm256</span><spanclass="o">=</span><spanclass="kc">True</span><spanclass="p">)</span>
<spanclass="nd">@py</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"|gThis should be uncolored"</span><spanclass="p">,</span><spanclass="n">nomarkup</span><spanclass="o">=</span><spanclass="kc">True</span><spanclass="p">)</span>