<h1>Traits<aclass="headerlink"href="#traits"title="Permalink to this headline">¶</a></h1>
<p>Contribution by Griatch 2020, based on code by Whitenoise and Ainneve contribs, 2014</p>
<p>A <codeclass="docutils literal notranslate"><spanclass="pre">Trait</span></code> represents a modifiable property on (usually) a Character. They can
be used to represent everything from attributes (str, agi etc) to skills
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.
Traits differ from normal Attributes in that they track their changes and limit
themselves to particular value-ranges. One can add/subtract from them easily and
they can even change dynamically at a particular rate (like you being poisoned or
healed).</p>
<p>Traits use Evennia Attributes under the hood, making them persistent (they survive
a server reload/reboot).</p>
<sectionid="installation">
<h2>Installation<aclass="headerlink"href="#installation"title="Permalink to this headline">¶</a></h2>
<p>Traits are always added to a typeclass, such as the Character class.</p>
<p>There are two ways to set up Traits on a typeclass. The first sets up the <codeclass="docutils literal notranslate"><spanclass="pre">TraitHandler</span></code>
as a property <codeclass="docutils literal notranslate"><spanclass="pre">.traits</span></code> on your class and you then access traits as e.g. <codeclass="docutils literal notranslate"><spanclass="pre">.traits.strength</span></code>.
The other alternative uses a <codeclass="docutils literal notranslate"><spanclass="pre">TraitProperty</span></code>, which makes the trait available directly
as e.g. <codeclass="docutils literal notranslate"><spanclass="pre">.strength</span></code>. This solution also uses the <codeclass="docutils literal notranslate"><spanclass="pre">TraitHandler</span></code>, but you don’t need to
define it explicitly. You can combine both styles if you like.</p>
<sectionid="traits-with-traithandler">
<h3>Traits with TraitHandler<aclass="headerlink"href="#traits-with-traithandler"title="Permalink to this headline">¶</a></h3>
<p>Here’s an example for adding the TraitHandler to the Character class:</p>
<p>When adding the trait, you supply the name of the property (<codeclass="docutils literal notranslate"><spanclass="pre">hunting</span></code>) along
with a more human-friendly name (“Hunting Skill”). The latter will show if you
print the trait etc. The <codeclass="docutils literal notranslate"><spanclass="pre">trait_type</span></code> is important, this specifies which type
of trait this is (see below).</p>
</section>
<sectionid="traitproperties">
<h3>TraitProperties<aclass="headerlink"href="#traitproperties"title="Permalink to this headline">¶</a></h3>
<p>Using <codeclass="docutils literal notranslate"><spanclass="pre">TraitProperties</span></code> makes the trait available directly on the class, much like Django model
fields. The drawback is that you must make sure that the name of your Traits don’t collide with any
<div><p>Note that the property-name will become the name of the trait and you don’t supply <codeclass="docutils literal notranslate"><spanclass="pre">trait_key</span></code>
separately.</p>
</div></blockquote>
<blockquote>
<div><p>The <codeclass="docutils literal notranslate"><spanclass="pre">.traits</span></code> TraitHandler will still be created (it’s used under the
hood. But it will only be created when the TraitProperty has been accessed at least once,
so be careful if mixing the two styles. If you want to make sure <codeclass="docutils literal notranslate"><spanclass="pre">.traits</span></code> is always available,
add the <codeclass="docutils literal notranslate"><spanclass="pre">TraitHandler</span></code> manually like shown earlier - the <codeclass="docutils literal notranslate"><spanclass="pre">TraitProperty</span></code> will by default use
the same handler (<codeclass="docutils literal notranslate"><spanclass="pre">.traits</span></code>).</p>
</div></blockquote>
</section>
</section>
<sectionid="using-traits">
<h2>Using traits<aclass="headerlink"href="#using-traits"title="Permalink to this headline">¶</a></h2>
<p>A trait is added to the traithandler (if you use <codeclass="docutils literal notranslate"><spanclass="pre">TraitProperty</span></code> the handler is just created under
the hood) after which one can access it as a property on the handler (similarly to how you can do
.db.attrname for Attributes in Evennia).</p>
<p>All traits have a <em>read-only</em> field <codeclass="docutils literal notranslate"><spanclass="pre">.value</span></code>. This is only used to read out results, you never
manipulate it directly (if you try, it will just remain unchanged). The <codeclass="docutils literal notranslate"><spanclass="pre">.value</span></code> is calculated based
on combining fields, like <codeclass="docutils literal notranslate"><spanclass="pre">.base</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">.mod</span></code> - which fields are available and how they relate to
<h2>Trait types<aclass="headerlink"href="#trait-types"title="Permalink to this headline">¶</a></h2>
<p>All default traits have a read-only <codeclass="docutils literal notranslate"><spanclass="pre">.value</span></code> property that shows the relevant or
‘current’ value of the trait. Exactly what this means depends on the type of trait.</p>
<p>Traits can also be combined to do arithmetic with their .value, if both have a
<p>The static trait has a <codeclass="docutils literal notranslate"><spanclass="pre">base</span></code> value and an optional <codeclass="docutils literal notranslate"><spanclass="pre">mod</span></code>-ifier. A typical use
of a static trait would be a Strength stat or Skill value. That is, something
that varies slowly or not at all, and which may be modified in-place.</p>
<p>A counter describes a value that can move from a base. The <codeclass="docutils literal notranslate"><spanclass="pre">.current</span></code> property
is the thing usually modified. It starts at the <codeclass="docutils literal notranslate"><spanclass="pre">.base</span></code>. One can also add a
modifier, which will both be added to the base and to current (forming
<codeclass="docutils literal notranslate"><spanclass="pre">.value</span></code>). The min/max of the range are optional, a boundary set to None will
remove it. A suggested use for a Counter Trait would be to track skill values.</p>
<h4>.descs<aclass="headerlink"href="#descs"title="Permalink to this headline">¶</a></h4>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">descs</span></code> property is a dict <codeclass="docutils literal notranslate"><spanclass="pre">{upper_bound:text_description}</span></code>. This allows for easily
storing a more human-friendly description of the current value in the
interval. Here is an example for skill values between 0 and 10:</p>
<p>The keys must be supplied from smallest to largest. Any values below the lowest and above the
highest description will be considered to be included in the closest description slot.
By calling <codeclass="docutils literal notranslate"><spanclass="pre">.desc()</span></code> on the Counter, you will get the text matching the current <codeclass="docutils literal notranslate"><spanclass="pre">value</span></code>.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># (could also have passed descs= to traits.add())</span>
<p>Note that when retrieving the <codeclass="docutils literal notranslate"><spanclass="pre">current</span></code>, the result will always be of the same
type as the <codeclass="docutils literal notranslate"><spanclass="pre">.base</span></code> even <codeclass="docutils literal notranslate"><spanclass="pre">rate</span></code> is a non-integer value. So if <codeclass="docutils literal notranslate"><spanclass="pre">base</span></code> is an <codeclass="docutils literal notranslate"><spanclass="pre">int</span></code>
(default)<codeclass="docutils literal notranslate"><spanclass="pre">,</span><spanclass="pre">the</span></code>current<codeclass="docutils literal notranslate"><spanclass="pre">value</span><spanclass="pre">will</span><spanclass="pre">also</span><spanclass="pre">be</span><spanclass="pre">rounded</span><spanclass="pre">the</span><spanclass="pre">closest</span><spanclass="pre">full</span><spanclass="pre">integer.</span><spanclass="pre">If</span><spanclass="pre">you</span><spanclass="pre">want</span><spanclass="pre">to</span><spanclass="pre">see</span><spanclass="pre">the</span><spanclass="pre">exact</span></code>current<codeclass="docutils literal notranslate"><spanclass="pre">value,</span><spanclass="pre">set</span></code>base<codeclass="docutils literal notranslate"><spanclass="pre">to</span><spanclass="pre">a</span><spanclass="pre">float</span><spanclass="pre">-</span><spanclass="pre">you</span><spanclass="pre">will</span><spanclass="pre">then</span><spanclass="pre">need</span><spanclass="pre">to</span><spanclass="pre">use</span></code>round()` yourself on the result if you want integers.</p>
</section>
<sectionid="percent">
<h4>.percent()<aclass="headerlink"href="#percent"title="Permalink to this headline">¶</a></h4>
<p>If both min and max are defined, the <codeclass="docutils literal notranslate"><spanclass="pre">.percent()</span></code> method of the trait will
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">.current</span></code> value will start from a full gauge. The .max property is
read-only and is set by <codeclass="docutils literal notranslate"><spanclass="pre">.base</span></code> + <codeclass="docutils literal notranslate"><spanclass="pre">.mod</span></code>. So contrary to a <codeclass="docutils literal notranslate"><spanclass="pre">Counter</span></code>, the
<codeclass="docutils literal notranslate"><spanclass="pre">.mod</span></code> modifier only applies to the max value of the gauge and not the current
value. The minimum bound defaults to 0 if not set explicitly.</p>
<p>This trait is useful for showing commonly depletable resources like health,
<p>The Gauge trait is subclass of the Counter, so you have access to the same
methods and properties where they make sense. So gauges can also have a
<codeclass="docutils literal notranslate"><spanclass="pre">.descs</span></code> dict to describe the intervals in text, and can use <codeclass="docutils literal notranslate"><spanclass="pre">.percent()</span></code> to
get how filled it is as a percentage etc.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">.rate</span></code> is particularly relevant for gauges - useful for everything
from poison slowly draining your health, to resting gradually increasing it.</p>
</section>
<sectionid="trait">
<h3>Trait<aclass="headerlink"href="#trait"title="Permalink to this headline">¶</a></h3>
<p>A single value of any type.</p>
<p>This is the ‘base’ Trait, meant to inherit from if you want to invent
trait-types from scratch (most of the time you’ll probably inherit from some of
the more advanced trait-type classes though).</p>
<p>Unlike other Trait-types, the single <codeclass="docutils literal notranslate"><spanclass="pre">.value</span></code> property of the base <codeclass="docutils literal notranslate"><spanclass="pre">Trait</span></code> can
be editied. The value can hold any data that can be stored in an Attribute. If
it’s an integer/float you can do arithmetic with it, but otherwise this acts just
<h2>Expanding with your own Traits<aclass="headerlink"href="#expanding-with-your-own-traits"title="Permalink to this headline">¶</a></h2>
<p>A Trait is a class inhering from <codeclass="docutils literal notranslate"><spanclass="pre">evennia.contrib.rpg.traits.Trait</span></code> (or from one of
the existing Trait classes).</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># in a file, say, 'mygame/world/traits.py'</span>
<p>Reload the server and you should now be able to use your trait:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="o">></span><spanclass="n">obj</span><spanclass="o">.</span><spanclass="n">traits</span><spanclass="o">.</span><spanclass="n">add</span><spanclass="p">(</span><spanclass="s2">"mood"</span><spanclass="p">,</span><spanclass="s2">"A dark mood"</span><spanclass="p">,</span><spanclass="n">rage</span><spanclass="o">=</span><spanclass="mi">30</span><spanclass="p">,</span><spanclass="n">trait_type</span><spanclass="o">=</span><spanclass="s1">'rage'</span><spanclass="p">)</span>
<spanclass="n">rage</span><spanclass="o">=</span><spanclass="n">TraitProperty</span><spanclass="p">(</span><spanclass="s2">"A dark mood"</span><spanclass="p">,</span><spanclass="n">rage</span><spanclass="o">=</span><spanclass="mi">30</span><spanclass="p">,</span><spanclass="n">trait_type</span><spanclass="o">=</span><spanclass="s1">'rage'</span><spanclass="p">)</span>
</pre></div>
</div>
<hrclass="docutils"/>
<p><small>This document page is generated from <codeclass="docutils literal notranslate"><spanclass="pre">evennia/contrib/rpg/traits/README.md</span></code>. Changes to this
file will be overwritten, so edit that file rather than this one.</small></p>