Updated HTML docs

This commit is contained in:
Evennia docbuilder action 2022-08-05 18:45:45 +00:00
parent e41f2ff6b2
commit 3e1506b2c2
104 changed files with 6668 additions and 348 deletions

View file

@ -0,0 +1,520 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Buffs &#8212; Evennia 1.0-dev documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Dice roller" href="Contrib-Dice.html" />
<link rel="prev" title="XYZgrid" href="Contrib-XYZGrid.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Dice.html" title="Dice roller"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Buffs</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="buffs">
<h1>Buffs<a class="headerlink" href="#buffs" title="Permalink to this headline"></a></h1>
<p>Contribution by Tegiminis 2022</p>
<p>A buff is a timed object, attached to a game entity. It is capable of modifying values, triggering code, or both.
It is a common design pattern in RPGs, particularly action games.</p>
<p>Features:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">BuffHandler</span></code>: A buff handler to apply to your objects.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">BaseBuff</span></code>: A buff class to extend from to create your own buffs.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">BuffableProperty</span></code>: A sample property class to show how to automatically check modifiers.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CmdBuff</span></code>: A command which applies buffs.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">samplebuffs.py</span></code>: Some sample buffs to learn from.</p></li>
</ul>
<section id="quick-start">
<h2>Quick Start<a class="headerlink" href="#quick-start" title="Permalink to this headline"></a></h2>
<p>Assign the handler to a property on the object, like so.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@lazy_property</span>
<span class="k">def</span> <span class="nf">buffs</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">BuffHandler</span><span class="p">:</span>
<span class="k">return</span> <span class="n">BuffHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
<p>You may then call the handler to add or manipulate buffs like so: <code class="docutils literal notranslate"><span class="pre">object.buffs</span></code>. See <strong>Using the Handler</strong>.</p>
<section id="customization">
<h3>Customization<a class="headerlink" href="#customization" title="Permalink to this headline"></a></h3>
<p>If you want to customize the handler, you can feed the constructor two arguments:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">dbkey</span></code>: The string you wish to use as the attribute key for the buff database. Defaults to “buffs”. This allows you to keep separate buff pools - for example, “buffs” and “perks”.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">autopause</span></code>: If you want this handler to automatically pause playtime buffs when its owning object is unpuppeted.</p></li>
</ul>
<blockquote>
<div><p><strong>Note</strong>: If you enable autopausing, you MUST initialize the property in your owning objects
<code class="docutils literal notranslate"><span class="pre">at_init</span></code> hook. Otherwise, a hot reload can cause playtime buffs to not update properly
on puppet/unpuppet. You have been warned!</p>
</div></blockquote>
<p>Lets say you want another handler for an object, <code class="docutils literal notranslate"><span class="pre">perks</span></code>, which has a separate database and
respects playtime buffs. Youd assign this new property as so:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">BuffableObject</span><span class="p">(</span><span class="n">Object</span><span class="p">):</span>
<span class="nd">@lazy_property</span>
<span class="k">def</span> <span class="nf">perks</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">BuffHandler</span><span class="p">:</span>
<span class="k">return</span> <span class="n">BuffHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dbkey</span><span class="o">=</span><span class="s1">&#39;perks&#39;</span><span class="p">,</span> <span class="n">autopause</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">at_init</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">perks</span>
</pre></div>
</div>
</section>
</section>
<section id="using-the-handler">
<h2>Using the Handler<a class="headerlink" href="#using-the-handler" title="Permalink to this headline"></a></h2>
<p>Heres how to make use of your new handler.</p>
<section id="apply-a-buff">
<h3>Apply a Buff<a class="headerlink" href="#apply-a-buff" title="Permalink to this headline"></a></h3>
<p>Call the handlers <code class="docutils literal notranslate"><span class="pre">add</span></code> method. This requires a class reference, and also contains a number of
optional arguments to customize the buffs duration, stacks, and so on. You can also store any arbitrary value
in the buffs cache by passing a dictionary through the <code class="docutils literal notranslate"><span class="pre">to_cache</span></code> optional argument. This will not overwrite the normal
values on the cache.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">StrengthBuff</span><span class="p">)</span> <span class="c1"># A single stack of StrengthBuff with normal duration</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">DexBuff</span><span class="p">,</span> <span class="n">stacks</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">duration</span><span class="o">=</span><span class="mi">60</span><span class="p">)</span> <span class="c1"># Three stacks of DexBuff, with a duration of 60 seconds</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">ReflectBuff</span><span class="p">,</span> <span class="n">to_cache</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;reflect&#39;</span><span class="p">:</span> <span class="mf">0.5</span><span class="p">})</span> <span class="c1"># A single stack of ReflectBuff, with an extra cache value</span>
</pre></div>
</div>
<p>Two important attributes on the buff are checked when the buff is applied: <code class="docutils literal notranslate"><span class="pre">refresh</span></code> and <code class="docutils literal notranslate"><span class="pre">unique</span></code>.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">refresh</span></code> (default: True) determines if a buffs timer is refreshed when it is reapplied.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">unique</span></code> (default: True) determines if this buff is unique; that is, only one of it exists on the object.</p></li>
</ul>
<p>The combination of these two booleans creates one of three kinds of keys:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">Unique</span> <span class="pre">is</span> <span class="pre">True,</span> <span class="pre">Refresh</span> <span class="pre">is</span> <span class="pre">True/False</span></code>: The buffs default key.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Unique</span> <span class="pre">is</span> <span class="pre">False,</span> <span class="pre">Refresh</span> <span class="pre">is</span> <span class="pre">True</span></code>: The default key mixed with the appliers dbref. This makes the buff “unique-per-player”, so you can refresh through reapplication.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Unique</span> <span class="pre">is</span> <span class="pre">False,</span> <span class="pre">Refresh</span> <span class="pre">is</span> <span class="pre">False</span></code>: The default key mixed with a randomized number.</p></li>
</ul>
</section>
<section id="get-buffs">
<h3>Get Buffs<a class="headerlink" href="#get-buffs" title="Permalink to this headline"></a></h3>
<p>The handler has several getter methods which return instanced buffs. You wont need to use these for basic functionality, but if you want to manipulate
buffs after application, they are very useful. The handlers <code class="docutils literal notranslate"><span class="pre">check</span></code>/<code class="docutils literal notranslate"><span class="pre">trigger</span></code> methods utilize some of these getters, while others are just for developer convenience.</p>
<p><code class="docutils literal notranslate"><span class="pre">get(key)</span></code> is the most basic getter. It returns a single buff instance, or <code class="docutils literal notranslate"><span class="pre">None</span></code> if the buff doesnt exist on the handler. It is also the only getter
that returns a single buff instance, rather than a dictionary.</p>
<p>Group getters, listed below, return a dictionary of values in the format <code class="docutils literal notranslate"><span class="pre">{buffkey:</span> <span class="pre">instance}</span></code>. If you want to iterate over all of these buffs,
you should do so via the <code class="docutils literal notranslate"><span class="pre">dict.values()</span></code> method.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">get_all()</span></code> returns all buffs on this handler. You can also use the <code class="docutils literal notranslate"><span class="pre">handler.all</span></code> property.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">get_by_type(BuffClass)</span></code> returns buffs of the specified type.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">get_by_stat(stat)</span></code> returns buffs with a <code class="docutils literal notranslate"><span class="pre">Mod</span></code> object of the specified <code class="docutils literal notranslate"><span class="pre">stat</span></code> string in their <code class="docutils literal notranslate"><span class="pre">mods</span></code> list.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">get_by_trigger(string)</span></code> returns buffs with the specified string in their <code class="docutils literal notranslate"><span class="pre">triggers</span></code> list.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">get_by_source(Object)</span></code> returns buffs applied by the specified <code class="docutils literal notranslate"><span class="pre">source</span></code> object.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">get_by_cachevalue(key,</span> <span class="pre">value)</span></code> returns buffs with the matching <code class="docutils literal notranslate"><span class="pre">key:</span> <span class="pre">value</span></code> pair in their cache. <code class="docutils literal notranslate"><span class="pre">value</span></code> is optional.</p></li>
</ul>
<p>All group getters besides <code class="docutils literal notranslate"><span class="pre">get_all()</span></code> can “slice” an existing dictionary through the optional <code class="docutils literal notranslate"><span class="pre">to_filter</span></code> argument.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">dict1</span> <span class="o">=</span> <span class="n">handler</span><span class="o">.</span><span class="n">get_by_type</span><span class="p">(</span><span class="n">Burned</span><span class="p">)</span> <span class="c1"># This finds all &quot;Burned&quot; buffs on the handler</span>
<span class="n">dict2</span> <span class="o">=</span> <span class="n">handler</span><span class="o">.</span><span class="n">get_by_source</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">to_filter</span><span class="o">=</span><span class="n">dict1</span><span class="p">)</span> <span class="c1"># This filters dict1 to find buffs with the matching source</span>
</pre></div>
</div>
<blockquote>
<div><p><strong>Note</strong>: Most of these getters also have an associated handler property. For example, <code class="docutils literal notranslate"><span class="pre">handler.effects</span></code> returns all buffs that can be triggered, which
is then iterated over by the <code class="docutils literal notranslate"><span class="pre">get_by_trigger</span></code> method.</p>
</div></blockquote>
</section>
<section id="remove-buffs">
<h3>Remove Buffs<a class="headerlink" href="#remove-buffs" title="Permalink to this headline"></a></h3>
<p>There are also a number of remover methods. Generally speaking, these follow the same format as the getters.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">remove(key)</span></code> removes the buff with the specified key.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">clear()</span></code> removes all buffs.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_by_type(BuffClass)</span></code> removes buffs of the specified type.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_by_stat(stat)</span></code> removes buffs with a <code class="docutils literal notranslate"><span class="pre">Mod</span></code> object of the specified <code class="docutils literal notranslate"><span class="pre">stat</span></code> string in their <code class="docutils literal notranslate"><span class="pre">mods</span></code> list.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_by_trigger(string)</span></code> removes buffs with the specified string in their <code class="docutils literal notranslate"><span class="pre">triggers</span></code> list.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_by_source(Object)</span></code> removes buffs applied by the specified source</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">remove_by_cachevalue(key,</span> <span class="pre">value)</span></code> removes buffs with the matching <code class="docutils literal notranslate"><span class="pre">key:</span> <span class="pre">value</span></code> pair in their cache. <code class="docutils literal notranslate"><span class="pre">value</span></code> is optional.</p></li>
</ul>
<p>You can also remove a buff by calling the instances <code class="docutils literal notranslate"><span class="pre">remove</span></code> helper method. You can do this on the dictionaries returned by the
getters listed above.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">to_remove</span> <span class="o">=</span> <span class="n">handler</span><span class="o">.</span><span class="n">get_by_trigger</span><span class="p">(</span><span class="n">trigger</span><span class="p">)</span> <span class="c1"># Finds all buffs with the specified trigger</span>
<span class="k">for</span> <span class="n">buff</span> <span class="ow">in</span> <span class="n">to_remove</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="c1"># Removes all buffs in the to_remove dictionary via helper methods</span>
<span class="n">buff</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="check-modifiers">
<h3>Check Modifiers<a class="headerlink" href="#check-modifiers" title="Permalink to this headline"></a></h3>
<p>Call the handler <code class="docutils literal notranslate"><span class="pre">check(value,</span> <span class="pre">stat)</span></code> method when you want to see the modified value.
This will return the <code class="docutils literal notranslate"><span class="pre">value</span></code>, modified by any relevant buffs on the handlers owner (identified by
the <code class="docutils literal notranslate"><span class="pre">stat</span></code> string).</p>
<p>For example, lets say you want to modify how much damage you take. That might look something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># The method we call to damage ourselves</span>
<span class="k">def</span> <span class="nf">take_damage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source</span><span class="p">,</span> <span class="n">damage</span><span class="p">):</span>
<span class="n">_damage</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">damage</span><span class="p">,</span> <span class="s1">&#39;taken_damage&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">health</span> <span class="o">-=</span> <span class="n">_damage</span>
</pre></div>
</div>
<p>This method calls the <code class="docutils literal notranslate"><span class="pre">at_pre_check</span></code> and <code class="docutils literal notranslate"><span class="pre">at_post_check</span></code> methods at the relevant points in the process. You can use to this make
buffs that are reactive to being checked; for example, removing themselves, altering their values, or interacting with the game state.</p>
<blockquote>
<div><p><strong>Note</strong>: You can also trigger relevant buffs at the same time as you check them by ensuring the optional argument <code class="docutils literal notranslate"><span class="pre">trigger</span></code> is True in the <code class="docutils literal notranslate"><span class="pre">check</span></code> method.</p>
</div></blockquote>
</section>
<section id="trigger-buffs">
<h3>Trigger Buffs<a class="headerlink" href="#trigger-buffs" title="Permalink to this headline"></a></h3>
<p>Call the handlers <code class="docutils literal notranslate"><span class="pre">trigger(string)</span></code> method when you want an event call. This will call the <code class="docutils literal notranslate"><span class="pre">at_trigger</span></code> hook method on all buffs with the relevant trigger <code class="docutils literal notranslate"><span class="pre">string</span></code>.</p>
<p>For example, lets say you want to trigger a buff to “detonate” when you hit your target with an attack.
Youd write a buff that might look like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Detonate</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="n">triggers</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;take_damage&#39;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">at_trigger</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trigger</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">take_damage</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
</pre></div>
</div>
<p>And then call <code class="docutils literal notranslate"><span class="pre">handler.trigger('take_damage')</span></code> in the method you use to take damage.</p>
<blockquote>
<div><p><strong>Note</strong> You could also do this through mods and <code class="docutils literal notranslate"><span class="pre">at_post_check</span></code> if you like, depending on how to want to add the damage.</p>
</div></blockquote>
</section>
<section id="ticking">
<h3>Ticking<a class="headerlink" href="#ticking" title="Permalink to this headline"></a></h3>
<p>Ticking buffs are slightly special. They are similar to trigger buffs in that they run code, but instead of
doing so on an event trigger, they do so on a periodic tick. A common use case for a buff like this is a poison,
or a heal over time.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Poison</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="n">tickrate</span> <span class="o">=</span> <span class="mi">5</span>
<span class="k">def</span> <span class="nf">at_tick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">_dmg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">dmg</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">stacks</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">initial</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span>
<span class="s2">&quot;Poison courses through </span><span class="si">{actor}</span><span class="s2">&#39;s body, dealing </span><span class="si">{damage}</span><span class="s2"> damage.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">actor</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">named</span><span class="p">,</span> <span class="n">damage</span><span class="o">=</span><span class="n">_dmg</span>
<span class="p">)</span>
<span class="p">)</span>
</pre></div>
</div>
<p>To make a buff ticking, ensure the <code class="docutils literal notranslate"><span class="pre">tickrate</span></code> is 1 or higher, and it has code in its <code class="docutils literal notranslate"><span class="pre">at_tick</span></code>
method. Once you add it to the handler, it starts ticking!</p>
<blockquote>
<div><p><strong>Note</strong>: Ticking buffs always tick on initial application, when <code class="docutils literal notranslate"><span class="pre">initial</span></code> is <code class="docutils literal notranslate"><span class="pre">True</span></code>. If you dont want your hook to fire at that time,
make sure to check the value of <code class="docutils literal notranslate"><span class="pre">initial</span></code> in your <code class="docutils literal notranslate"><span class="pre">at_tick</span></code> method.</p>
</div></blockquote>
</section>
<section id="context">
<h3>Context<a class="headerlink" href="#context" title="Permalink to this headline"></a></h3>
<p>Every important handler method optionally accepts a <code class="docutils literal notranslate"><span class="pre">context</span></code> dictionary.</p>
<p>Context is an important concept for this handler. Every method which checks, triggers, or ticks a buff passes this
dictionary (default: empty) to the buff hook methods as keyword arguments (<code class="docutils literal notranslate"><span class="pre">**kwargs</span></code>). It is used for nothing else. This allows you to make those
methods “event-aware” by storing relevant data in the dictionary you feed to the method.</p>
<p>For example, lets say you want a “thorns” buff which damages enemies that attack you. Lets take our <code class="docutils literal notranslate"><span class="pre">take_damage</span></code> method
and add a context to the mix.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">take_damage</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">damage</span><span class="p">):</span>
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;attacker&#39;</span><span class="p">:</span> <span class="n">attacker</span><span class="p">,</span> <span class="s1">&#39;damage&#39;</span><span class="p">:</span> <span class="n">damage</span><span class="p">}</span>
<span class="n">_damage</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">damage</span><span class="p">,</span> <span class="s1">&#39;taken_damage&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">trigger</span><span class="p">(</span><span class="s1">&#39;taken_damage&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">health</span> <span class="o">-=</span> <span class="n">_damage</span>
</pre></div>
</div>
<p>Now we use the values that context passes to the buff kwargs to customize our logic.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ThornsBuff</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="n">triggers</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;taken_damage&#39;</span><span class="p">]</span>
<span class="c1"># This is the hook method on our thorns buff</span>
<span class="k">def</span> <span class="nf">at_trigger</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trigger</span><span class="p">,</span> <span class="n">attacker</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">damage</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">attacker</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">health</span> <span class="o">-=</span> <span class="n">damage</span> <span class="o">*</span> <span class="mf">0.2</span>
</pre></div>
</div>
<p>Apply the buff, take damage, and watch the thorns buff do its work!</p>
</section>
</section>
<section id="creating-new-buffs">
<h2>Creating New Buffs<a class="headerlink" href="#creating-new-buffs" title="Permalink to this headline"></a></h2>
<p>Creating a new buff is very easy: extend <code class="docutils literal notranslate"><span class="pre">BaseBuff</span></code> into a new class, and fill in all the relevant buff details.
However, there are a lot of individual moving parts to a buff. Heres a step-through of the important stuff.</p>
<section id="basics">
<h3>Basics<a class="headerlink" href="#basics" title="Permalink to this headline"></a></h3>
<p>Regardless of any other functionality, all buffs have the following class attributes:</p>
<ul class="simple">
<li><p>They have customizable <code class="docutils literal notranslate"><span class="pre">key</span></code>, <code class="docutils literal notranslate"><span class="pre">name</span></code>, and <code class="docutils literal notranslate"><span class="pre">flavor</span></code> strings.</p></li>
<li><p>They have a <code class="docutils literal notranslate"><span class="pre">duration</span></code> (float), and automatically clean-up at the end. Use -1 for infinite duration, and 0 to clean-up immediately. (default: -1)</p></li>
<li><p>They can stack, if <code class="docutils literal notranslate"><span class="pre">maxstacks</span></code> (int) is not equal to 1. If its 0, the buff stacks forever. (default: 1)</p></li>
<li><p>They can be <code class="docutils literal notranslate"><span class="pre">unique</span></code> (bool), which determines if they have a unique namespace or not. (default: True)</p></li>
<li><p>They can <code class="docutils literal notranslate"><span class="pre">refresh</span></code> (bool), which resets the duration when stacked or reapplied. (default: True)</p></li>
<li><p>They can be <code class="docutils literal notranslate"><span class="pre">playtime</span></code> (bool) buffs, where duration only counts down during active play. (default: False)</p></li>
</ul>
<p>They also always store some useful mutable information about themselves in the cache:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">ref</span></code> (class): The buff class path we use to construct the buff.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">start</span></code> (float): The timestamp of when the buff was applied.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">source</span></code> (Object): If specified; this allows you to track who or what applied the buff.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">prevtick</span></code> (float): The timestamp of the previous tick.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">duration</span></code> (float): The cached duration. This can vary from the class duration, depending on if the duration has been modified (paused, extended, shortened, etc).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">stacks</span></code> (int): How many stacks they have.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">paused</span></code> (bool): Paused buffs do not clean up, modify values, tick, or fire any hook methods.</p></li>
</ul>
<p>You can always access the raw cache dictionary through the <code class="docutils literal notranslate"><span class="pre">cache</span></code> attribute on an instanced buff. This is grabbed when you get the buff through
a handler method, so it may not always reflect recent changes youve made, depending on how you structure your buff calls. All of the above
mutable information can be found in this cache, as well as any arbitrary information you pass through the handler <code class="docutils literal notranslate"><span class="pre">add</span></code> method (via <code class="docutils literal notranslate"><span class="pre">to_cache</span></code>).</p>
</section>
<section id="modifiers">
<h3>Modifiers<a class="headerlink" href="#modifiers" title="Permalink to this headline"></a></h3>
<p>Mods are stored in the <code class="docutils literal notranslate"><span class="pre">mods</span></code> list attribute. Buffs which have one or more Mod objects in them can modify stats. You can use the handler method to check all
mods of a specific stat string and apply their modifications to the value; however, you are encouraged to use <code class="docutils literal notranslate"><span class="pre">check</span></code> in a getter/setter, for easy access.</p>
<p>Mod objects consist of only four values, assigned by the constructor in this order:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">stat</span></code>: The stat you want to modify. When <code class="docutils literal notranslate"><span class="pre">check</span></code> is called, this string is used to find all the mods that are to be collected.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mod</span></code>: The modifier. Defaults are add and mult. Modifiers are calculated additively, and in standard arithmetic order (see <code class="docutils literal notranslate"><span class="pre">_calculate_mods</span></code> for more)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">value</span></code>: How much value the modifier gives regardless of stacks</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">perstack</span></code>: How much value the modifier grants per stack, INCLUDING the first. (default: 0)</p></li>
</ul>
<p>The most basic way to add a Mod to a buff is to do so in the buff class definition, like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">DamageBuff</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="n">mods</span> <span class="o">=</span> <span class="p">[</span><span class="n">Mod</span><span class="p">(</span><span class="s1">&#39;damage&#39;</span><span class="p">,</span> <span class="s1">&#39;add&#39;</span><span class="p">,</span> <span class="mi">10</span><span class="p">)]</span>
</pre></div>
</div>
<p>No mods applied to the value are permanent in any way. All calculations are done at runtime, and the mod values are never stored
anywhere except on the buff in question. In other words: you dont need to track the origin of particular stat mods, and you will
never permanently change a stat modified by a buff. To remove the modification, simply remove the buff from the object.</p>
<blockquote>
<div><p><strong>Note</strong>: You can add your own modifier types by overloading the <code class="docutils literal notranslate"><span class="pre">_calculate_mods</span></code> method, which contains the basic modifier application logic.</p>
</div></blockquote>
<section id="generating-mods-advanced">
<h4>Generating Mods (Advanced)<a class="headerlink" href="#generating-mods-advanced" title="Permalink to this headline"></a></h4>
<p>An advanced way to do mods is to generate them when the buff is initialized. This lets you create mods on the fly that are reactive to the game state.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">GeneratedStatBuff</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handler</span><span class="p">,</span> <span class="n">buffkey</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="p">{})</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="n">buffkey</span><span class="p">,</span> <span class="n">cache</span><span class="p">)</span>
<span class="c1"># Finds our &quot;modgen&quot; cache value, and generates a mod from it</span>
<span class="n">modgen</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;modgen&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">modgen</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mods</span> <span class="o">=</span> <span class="p">[</span><span class="n">Mod</span><span class="p">(</span><span class="o">*</span><span class="n">modgen</span><span class="p">)]</span>
</pre></div>
</div>
</section>
</section>
<section id="triggers">
<h3>Triggers<a class="headerlink" href="#triggers" title="Permalink to this headline"></a></h3>
<p>Buffs which have one or more strings in the <code class="docutils literal notranslate"><span class="pre">triggers</span></code> attribute can be triggered by events.</p>
<p>When the handlers <code class="docutils literal notranslate"><span class="pre">trigger</span></code> method is called, it searches all buffs on the handler for any with a matchingtrigger,
then calls their <code class="docutils literal notranslate"><span class="pre">at_trigger</span></code> hooks. Buffs can have multiple triggers, and you can tell which trigger was used by
the <code class="docutils literal notranslate"><span class="pre">trigger</span></code> argument in the hook.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AmplifyBuff</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="n">triggers</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;damage&#39;</span><span class="p">,</span> <span class="s1">&#39;heal&#39;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">at_trigger</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trigger</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">trigger</span> <span class="o">==</span> <span class="s1">&#39;damage&#39;</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Damage trigger called!&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">trigger</span> <span class="o">==</span> <span class="s1">&#39;heal&#39;</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Heal trigger called!&#39;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="id1">
<h3>Ticking<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<p>A buff which ticks isnt much different than one which triggers. Youre still executing arbitrary hooks on
the buff class. To tick, the buff must have a <code class="docutils literal notranslate"><span class="pre">tickrate</span></code> of 1 or higher.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Poison</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="c1"># this buff will tick 6 times between application and cleanup.</span>
<span class="n">duration</span> <span class="o">=</span> <span class="mi">30</span>
<span class="n">tickrate</span> <span class="o">=</span> <span class="mi">5</span>
<span class="k">def</span> <span class="nf">at_tick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">take_damage</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</pre></div>
</div>
<blockquote>
<div><p><strong>Note</strong>: The buff always ticks once when applied. For this <strong>first tick only</strong>, <code class="docutils literal notranslate"><span class="pre">initial</span></code> will be True in the <code class="docutils literal notranslate"><span class="pre">at_tick</span></code> hook method. <code class="docutils literal notranslate"><span class="pre">initial</span></code> will be False on subsequent ticks.</p>
</div></blockquote>
<p>Ticks utilize a persistent delay, so they should be pickleable. As long as you are not adding new properties to your buff class, this shouldnt be a concern.
If you <strong>are</strong> adding new properties, try to ensure they do not end up with a circular code path to their object or handler, as this will cause pickling errors.</p>
</section>
<section id="extras">
<h3>Extras<a class="headerlink" href="#extras" title="Permalink to this headline"></a></h3>
<p>Buffs have a grab-bag of extra functionality to let you add complexity to your designs.</p>
<section id="conditionals">
<h4>Conditionals<a class="headerlink" href="#conditionals" title="Permalink to this headline"></a></h4>
<p>You can restrict whether or not the buff will <code class="docutils literal notranslate"><span class="pre">check</span></code>, <code class="docutils literal notranslate"><span class="pre">trigger</span></code>, or <code class="docutils literal notranslate"><span class="pre">tick</span></code> through defining the <code class="docutils literal notranslate"><span class="pre">conditional</span></code> hook. As long
as it returns a “truthy” value, the buff will apply itself. This is useful for making buffs dependent on game state - for
example, if you want a buff that makes the player take more damage when they are on fire:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FireSick</span><span class="p">(</span><span class="n">BaseBuff</span><span class="p">):</span>
<span class="o">...</span>
<span class="k">def</span> <span class="nf">conditional</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">buffs</span><span class="o">.</span><span class="n">get_by_type</span><span class="p">(</span><span class="n">FireBuff</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
</pre></div>
</div>
<p>Conditionals for <code class="docutils literal notranslate"><span class="pre">check</span></code>/<code class="docutils literal notranslate"><span class="pre">trigger</span></code> are checked when the buffs are gathered by the handler methods for the respective operations. <code class="docutils literal notranslate"><span class="pre">Tick</span></code>
conditionals are checked each tick.</p>
</section>
<section id="helper-methods">
<h4>Helper Methods<a class="headerlink" href="#helper-methods" title="Permalink to this headline"></a></h4>
<p>Buff instances have a number of helper methods.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">remove</span></code>/<code class="docutils literal notranslate"><span class="pre">dispel</span></code>: Allows you to remove or dispel the buff. Calls <code class="docutils literal notranslate"><span class="pre">at_remove</span></code>/<code class="docutils literal notranslate"><span class="pre">at_dispel</span></code>, depending on optional arguments.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pause</span></code>/<code class="docutils literal notranslate"><span class="pre">unpause</span></code>: Pauses and unpauses the buff. Calls <code class="docutils literal notranslate"><span class="pre">at_pause</span></code>/<code class="docutils literal notranslate"><span class="pre">at_unpause</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">reset</span></code>: Resets the buffs start to the current time; same as “refreshing” it.</p></li>
</ul>
</section>
<section id="playtime-duration">
<h4>Playtime Duration<a class="headerlink" href="#playtime-duration" title="Permalink to this headline"></a></h4>
<p>If your handler has <code class="docutils literal notranslate"><span class="pre">autopause</span></code> enabled, any buffs with truthy <code class="docutils literal notranslate"><span class="pre">playtime</span></code> value will automatically pause
and unpause when the object the handler is attached to is puppetted or unpuppetted. This even works with ticking buffs,
although if you have less than 1 second of tick duration remaining, it will round up to 1s.</p>
<blockquote>
<div><p><strong>Note</strong>: If you want more control over this process, you can comment out the signal subscriptions on the handler and move the autopause logic
to your objects <code class="docutils literal notranslate"><span class="pre">at_pre/post_puppet/unpuppet</span></code> hooks.</p>
</div></blockquote>
<hr class="docutils" />
<p><small>This document page is generated from <code class="docutils literal notranslate"><span class="pre">evennia/contrib/rpg/buffs/README.md</span></code>. Changes to this
file will be overwritten, so edit that file rather than this one.</small></p>
</section>
</section>
</section>
</section>
<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="#">Buffs</a><ul>
<li><a class="reference internal" href="#quick-start">Quick Start</a><ul>
<li><a class="reference internal" href="#customization">Customization</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-the-handler">Using the Handler</a><ul>
<li><a class="reference internal" href="#apply-a-buff">Apply a Buff</a></li>
<li><a class="reference internal" href="#get-buffs">Get Buffs</a></li>
<li><a class="reference internal" href="#remove-buffs">Remove Buffs</a></li>
<li><a class="reference internal" href="#check-modifiers">Check Modifiers</a></li>
<li><a class="reference internal" href="#trigger-buffs">Trigger Buffs</a></li>
<li><a class="reference internal" href="#ticking">Ticking</a></li>
<li><a class="reference internal" href="#context">Context</a></li>
</ul>
</li>
<li><a class="reference internal" href="#creating-new-buffs">Creating New Buffs</a><ul>
<li><a class="reference internal" href="#basics">Basics</a></li>
<li><a class="reference internal" href="#modifiers">Modifiers</a><ul>
<li><a class="reference internal" href="#generating-mods-advanced">Generating Mods (Advanced)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#triggers">Triggers</a></li>
<li><a class="reference internal" href="#id1">Ticking</a></li>
<li><a class="reference internal" href="#extras">Extras</a><ul>
<li><a class="reference internal" href="#conditionals">Conditionals</a></li>
<li><a class="reference internal" href="#helper-methods">Helper Methods</a></li>
<li><a class="reference internal" href="#playtime-duration">Playtime Duration</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Contrib-XYZGrid.html"
title="previous chapter">XYZgrid</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Dice.html"
title="next chapter">Dice roller</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Contribs/Contrib-Buffs.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="Contrib-Buffs.html">1.0-dev (develop branch)</a></li>
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 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="right" >
<a href="Contrib-Dice.html" title="Dice roller"
>next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Buffs</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Health Bar" href="Contrib-Health-Bar.html" />
<link rel="prev" title="XYZgrid" href="Contrib-XYZGrid.html" />
<link rel="prev" title="Buffs" href="Contrib-Buffs.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Contrib-Health-Bar.html" title="Health Bar"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"
<a href="Contrib-Buffs.html" title="Buffs"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
@ -145,8 +145,8 @@ file will be overwritten, so edit that file rather than this one.</small></p>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Contrib-XYZGrid.html"
title="previous chapter">XYZgrid</a></p>
<p class="topless"><a href="Contrib-Buffs.html"
title="previous chapter">Buffs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Health-Bar.html"
title="next chapter">Health Bar</a></p>
@ -190,7 +190,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<a href="Contrib-Health-Bar.html" title="Health Bar"
>next</a> |</li>
<li class="right" >
<a href="Contrib-XYZGrid.html" title="XYZgrid"
<a href="Contrib-Buffs.html" title="Buffs"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>

View file

@ -17,7 +17,7 @@
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Pseudo-random generator and registry" href="Contrib-Random-String-Generator.html" />
<link rel="next" title="Random Name Generator" href="Contrib-Name-Generator.html" />
<link rel="prev" title="Input/Output Auditing" href="Contrib-Auditing.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@ -30,7 +30,7 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Random-String-Generator.html" title="Pseudo-random generator and registry"
<a href="Contrib-Name-Generator.html" title="Random Name Generator"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-Auditing.html" title="Input/Output Auditing"
@ -233,8 +233,8 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<p class="topless"><a href="Contrib-Auditing.html"
title="previous chapter">Input/Output Auditing</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Random-String-Generator.html"
title="next chapter">Pseudo-random generator and registry</a></p>
<p class="topless"><a href="Contrib-Name-Generator.html"
title="next chapter">Random Name Generator</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
@ -272,7 +272,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Random-String-Generator.html" title="Pseudo-random generator and registry"
<a href="Contrib-Name-Generator.html" title="Random Name Generator"
>next</a> |</li>
<li class="right" >
<a href="Contrib-Auditing.html" title="Input/Output Auditing"

View file

@ -0,0 +1,415 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Random Name Generator &#8212; Evennia 1.0-dev documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Pseudo-random generator and registry" href="Contrib-Random-String-Generator.html" />
<link rel="prev" title="Easy fillable form" href="Contrib-Fieldfill.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Contrib-Random-String-Generator.html" title="Pseudo-random generator and registry"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-Fieldfill.html" title="Easy fillable form"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Random Name Generator</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="random-name-generator">
<h1>Random Name Generator<a class="headerlink" href="#random-name-generator" title="Permalink to this headline"></a></h1>
<p>Contribution by InspectorCaracal (2022)</p>
<p>A module for generating random names, both real-world and fantasy. Real-world
names can be generated either as first (personal) names, family (last) names, or
full names (first, optional middles, and last). The name data is from <a class="reference external" href="https://www.behindthename.com/">Behind the Name</a>
and used under the <a class="reference external" href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0 license</a>.</p>
<p>Fantasy names are generated from basic phonetic rules, using CVC syllable syntax.</p>
<p>Both real-world and fantasy name generation can be extended to include additional
information via your games <code class="docutils literal notranslate"><span class="pre">settings.py</span></code></p>
<section id="installation">
<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline"></a></h2>
<p>This is a stand-alone utility. Just import this module (<code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">evennia.contrib.utils</span> <span class="pre">import</span> <span class="pre">name_generator</span></code>) and use its functions wherever you like.</p>
</section>
<section id="usage">
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline"></a></h2>
<p>Import the module where you need it with the following:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia.contrib.utils.name_generator</span> <span class="kn">import</span> <span class="n">namegen</span>
</pre></div>
</div>
<p>By default, all of the functions will return a string with one generated name.
If you specify more than one, or pass <code class="docutils literal notranslate"><span class="pre">return_list=True</span></code> as a keyword argument, the returned value will be a list of strings.</p>
<p>The module is especially useful for naming newly-created NPCs, like so:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">npc_name</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">full_name</span><span class="p">()</span>
<span class="n">npc_obj</span> <span class="o">=</span> <span class="n">create_object</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">npc_name</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="s2">&quot;typeclasses.characters.NPC&quot;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="available-settings">
<h2>Available Settings<a class="headerlink" href="#available-settings" title="Permalink to this headline"></a></h2>
<p>These settings can all be defined in your games <code class="docutils literal notranslate"><span class="pre">server/conf/settings.py</span></code> file.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_FIRST_NAMES</span></code> adds a new list of first (personal) names.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_LAST_NAMES</span></code> adds a new list of last (family) names.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_REPLACE_LISTS</span></code> - set to <code class="docutils literal notranslate"><span class="pre">True</span></code> if you want to use only the names defined in your settings.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_FANTASY_RULES</span></code> lets you add new phonetic rules for generating entirely made-up names. See the section “Custom Fantasy Name style rules” for details on how this should look.</p></li>
</ul>
<p>Examples:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">NAMEGEN_FIRST_NAMES</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span><span class="s2">&quot;Evennia&quot;</span><span class="p">,</span> <span class="s1">&#39;mf&#39;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;Green Tea&quot;</span><span class="p">,</span> <span class="s1">&#39;f&#39;</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">NAMEGEN_LAST_NAMES</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">&quot;Beeblebrox&quot;</span><span class="p">,</span> <span class="s2">&quot;Son of Odin&quot;</span> <span class="p">]</span>
<span class="n">NAMEGEN_FANTASY_RULES</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;example_style&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;syllable&quot;</span><span class="p">:</span> <span class="s2">&quot;(C)VC&quot;</span><span class="p">,</span>
<span class="s2">&quot;consonants&quot;</span><span class="p">:</span> <span class="p">[</span> <span class="s1">&#39;z&#39;</span><span class="p">,</span><span class="s1">&#39;z&#39;</span><span class="p">,</span><span class="s1">&#39;ph&#39;</span><span class="p">,</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="s1">&#39;r&#39;</span><span class="p">,</span><span class="s1">&#39;n&#39;</span> <span class="p">],</span>
<span class="s2">&quot;start&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;m&#39;</span><span class="p">],</span>
<span class="s2">&quot;end&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">,</span><span class="s1">&#39;n&#39;</span><span class="p">],</span>
<span class="s2">&quot;vowels&quot;</span><span class="p">:</span> <span class="p">[</span> <span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;a&quot;</span><span class="p">,</span><span class="s2">&quot;i&quot;</span><span class="p">,</span><span class="s2">&quot;i&quot;</span><span class="p">,</span><span class="s2">&quot;u&quot;</span><span class="p">,</span><span class="s2">&quot;o&quot;</span><span class="p">,</span> <span class="p">],</span>
<span class="s2">&quot;length&quot;</span><span class="p">:</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="generating-real-names">
<h2>Generating Real Names<a class="headerlink" href="#generating-real-names" title="Permalink to this headline"></a></h2>
<p>The contrib offers three functions for generating random real-world names:
<code class="docutils literal notranslate"><span class="pre">first_name()</span></code>, <code class="docutils literal notranslate"><span class="pre">last_name()</span></code>, and <code class="docutils literal notranslate"><span class="pre">full_name()</span></code>. If you want more than one name
generated at once, you can use the <code class="docutils literal notranslate"><span class="pre">num</span></code> keyword argument to specify how many.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">first_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="go">[&#39;Genesis&#39;, &#39;Tali&#39;, &#39;Budur&#39;, &#39;Dominykas&#39;, &#39;Kamau&#39;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">first_name</span><span class="p">(</span><span class="n">gender</span><span class="o">=</span><span class="s1">&#39;m&#39;</span><span class="p">)</span>
<span class="go">&#39;Blanchard&#39;</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">first_name</span></code> function also takes a <code class="docutils literal notranslate"><span class="pre">gender</span></code> keyword argument to filter names
by gender association. f for feminine, m for masculine, mf for feminine
<em>and</em> masculine, or the default <code class="docutils literal notranslate"><span class="pre">None</span></code> to match any gendering.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">full_name</span></code> function also takes the <code class="docutils literal notranslate"><span class="pre">gender</span></code> keyword, as well as <code class="docutils literal notranslate"><span class="pre">parts</span></code> which
defines how many names make up the full name. The minimum is two: a first name and
a last name. You can also generate names with the family name first by setting
the keyword arg <code class="docutils literal notranslate"><span class="pre">surname_first</span></code> to <code class="docutils literal notranslate"><span class="pre">True</span></code></p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">full_name</span><span class="p">()</span>
<span class="go">&#39;Keeva Bernat&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">full_name</span><span class="p">(</span><span class="n">parts</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="go">&#39;Suzu Shabnam Kafka Baier&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">full_name</span><span class="p">(</span><span class="n">parts</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">surname_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">&#39;Ó Muircheartach Torunn Dyson&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">full_name</span><span class="p">(</span><span class="n">gender</span><span class="o">=</span><span class="s1">&#39;f&#39;</span><span class="p">)</span>
<span class="go">&#39;Wikolia Ó Deasmhumhnaigh&#39;</span>
</pre></div>
</div>
<section id="adding-your-own-names">
<h3>Adding your own names<a class="headerlink" href="#adding-your-own-names" title="Permalink to this headline"></a></h3>
<p>You can add additional names with the settings <code class="docutils literal notranslate"><span class="pre">NAMEGEN_FIRST_NAMES</span></code> and
<code class="docutils literal notranslate"><span class="pre">NAMEGEN_LAST_NAMES</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_FIRST_NAMES</span></code> should be a list of tuples, where the first value is the name
and then second value is the gender flag - m for masculine-only, f for feminine-
only, and mf for either one.</p>
<p><code class="docutils literal notranslate"><span class="pre">NAMEGEN_LAST_NAMES</span></code> should be a list of strings, where each item is an available
surname.</p>
<p>Examples:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">NAMEGEN_FIRST_NAMES</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span><span class="s2">&quot;Evennia&quot;</span><span class="p">,</span> <span class="s1">&#39;mf&#39;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;Green Tea&quot;</span><span class="p">,</span> <span class="s1">&#39;f&#39;</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">NAMEGEN_LAST_NAMES</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">&quot;Beeblebrox&quot;</span><span class="p">,</span> <span class="s2">&quot;Son of Odin&quot;</span> <span class="p">]</span>
</pre></div>
</div>
<p>Set <code class="docutils literal notranslate"><span class="pre">NAMEGEN_REPLACE_LISTS</span> <span class="pre">=</span> <span class="pre">True</span></code> if you want your custom lists above to entirely replace the built-in lists rather than extend them.</p>
</section>
</section>
<section id="generating-fantasy-names">
<h2>Generating Fantasy Names<a class="headerlink" href="#generating-fantasy-names" title="Permalink to this headline"></a></h2>
<p>Generating completely made-up names is done with the <code class="docutils literal notranslate"><span class="pre">fantasy_name</span></code> function. The
contrib comes with three built-in styles of names which you can use, or you can
put a dictionary of custom name rules into <code class="docutils literal notranslate"><span class="pre">settings.py</span></code></p>
<p>Generating a fantasy name takes the ruleset key as the “style” keyword, and can
return either a single name or multiple names. By default, it will return a
single name in the built-in “harsh” style. The contrib also comes with “fluid” and “alien” styles.</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">()</span>
<span class="go">&#39;Vhon&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;harsh&quot;</span><span class="p">)</span>
<span class="go">[&#39;Kha&#39;, &#39;Kizdhu&#39;, &#39;Godögäk&#39;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;fluid&quot;</span><span class="p">)</span>
<span class="go">[&#39;Aewalisash&#39;, &#39;Ayi&#39;, &#39;Iaa&#39;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;alien&quot;</span><span class="p">)</span>
<span class="go">[&quot;Qz&#39;vko&#39;&quot;, &quot;Xv&#39;w&#39;hk&#39;hxyxyz&quot;, &quot;Wxqv&#39;hv&#39;k&quot;, &quot;Wh&#39;k&quot;, &quot;Xbx&#39;qk&#39;vz&quot;]</span>
</pre></div>
</div>
<section id="multi-word-fantasy-names">
<h3>Multi-Word Fantasy Names<a class="headerlink" href="#multi-word-fantasy-names" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">fantasy_name</span></code> function will only generate one name-word at a time, so for multi-word names
youll need to combine pieces together. Depending on what kind of end result you want, there are
several approaches.</p>
<section id="the-simple-approach">
<h4>The simple approach<a class="headerlink" href="#the-simple-approach" title="Permalink to this headline"></a></h4>
<p>If all you need is for it to have multiple parts, you can generate multiple names at once and <code class="docutils literal notranslate"><span class="pre">join</span></code> them.</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span>
<span class="go">&#39;Dezhvözh Khäk&#39;</span>
</pre></div>
</div>
<p>If you want a little more variation between first/last names, you can also generate names for
different styles and then combine them.</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">first</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="s2">&quot;fluid&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">last</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="s2">&quot;harsh&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">first</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">last</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span>
<span class="go">&#39;Ofasa Käkudhu&#39;</span>
</pre></div>
</div>
</section>
<section id="nakku-silversmith">
<h4>“Nakku Silversmith”<a class="headerlink" href="#nakku-silversmith" title="Permalink to this headline"></a></h4>
<p>One common fantasy name practice is profession- or title-based surnames. To achieve this effect,
you can use the <code class="docutils literal notranslate"><span class="pre">last_name</span></code> function with a custom list of last names and combine it with your generated
fantasy name.</p>
<p>Example:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">NAMEGEN_LAST_NAMES</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">&quot;Silversmith&quot;</span><span class="p">,</span> <span class="s2">&quot;the Traveller&quot;</span><span class="p">,</span> <span class="s2">&quot;Destroyer of Worlds&quot;</span> <span class="p">]</span>
<span class="n">NAMEGEN_REPLACE_LISTS</span> <span class="o">=</span> <span class="kc">True</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">first</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">()</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">last</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">last_name</span><span class="p">()</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">first</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">last</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">name</span>
<span class="s1">&#39;Tözhkheko the Traveller&#39;</span>
</pre></div>
</div>
</section>
<section id="elarion-dyrinea-thror-obinson">
<h4>Elarion dYrinea, Thror Obinson<a class="headerlink" href="#elarion-dyrinea-thror-obinson" title="Permalink to this headline"></a></h4>
<p>Another common flavor of fantasy names is to use a surname suffix or prefix. For that, youll
need to add in the extra bit yourself.</p>
<p>Examples:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">names</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s2"> za&#39;</span><span class="si">{</span><span class="n">names</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span>
<span class="go">&quot;Tithe za&#39;Dhudozkok&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">names</span> <span class="o">=</span> <span class="n">namegen</span><span class="o">.</span><span class="n">fantasy_name</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">names</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2">son&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">name</span>
<span class="go">&#39;Kön Ködhöddoson&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="custom-fantasy-name-style-rules">
<h3>Custom Fantasy Name style rules<a class="headerlink" href="#custom-fantasy-name-style-rules" title="Permalink to this headline"></a></h3>
<p>The style rules are contained in a dictionary of dictionaries, where the style name
is the key and the style rules are the dictionary value.</p>
<p>The following is how you would add a custom style to <code class="docutils literal notranslate"><span class="pre">settings.py</span></code>:</p>
<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">NAMEGEN_FANTASY_RULES</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;example_style&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;syllable&quot;</span><span class="p">:</span> <span class="s2">&quot;(C)VC&quot;</span><span class="p">,</span>
<span class="s2">&quot;consonants&quot;</span><span class="p">:</span> <span class="p">[</span> <span class="s1">&#39;z&#39;</span><span class="p">,</span><span class="s1">&#39;z&#39;</span><span class="p">,</span><span class="s1">&#39;ph&#39;</span><span class="p">,</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="s1">&#39;r&#39;</span><span class="p">,</span><span class="s1">&#39;n&#39;</span> <span class="p">],</span>
<span class="s2">&quot;start&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;m&#39;</span><span class="p">],</span>
<span class="s2">&quot;end&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">,</span><span class="s1">&#39;n&#39;</span><span class="p">],</span>
<span class="s2">&quot;vowels&quot;</span><span class="p">:</span> <span class="p">[</span> <span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;e&quot;</span><span class="p">,</span><span class="s2">&quot;a&quot;</span><span class="p">,</span><span class="s2">&quot;i&quot;</span><span class="p">,</span><span class="s2">&quot;i&quot;</span><span class="p">,</span><span class="s2">&quot;u&quot;</span><span class="p">,</span><span class="s2">&quot;o&quot;</span><span class="p">,</span> <span class="p">],</span>
<span class="s2">&quot;length&quot;</span><span class="p">:</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Then you could generate names following that ruleset with <code class="docutils literal notranslate"><span class="pre">namegen.fantasy_name(style=&quot;example_style&quot;)</span></code>.</p>
<p>The keys <code class="docutils literal notranslate"><span class="pre">syllable</span></code>, <code class="docutils literal notranslate"><span class="pre">consonants</span></code>, <code class="docutils literal notranslate"><span class="pre">vowels</span></code>, and <code class="docutils literal notranslate"><span class="pre">length</span></code> must be present, and <code class="docutils literal notranslate"><span class="pre">length</span></code> must be the minimum and maximum syllable counts. <code class="docutils literal notranslate"><span class="pre">start</span></code> and <code class="docutils literal notranslate"><span class="pre">end</span></code> are optional.</p>
<section id="syllable">
<h4>syllable<a class="headerlink" href="#syllable" title="Permalink to this headline"></a></h4>
<p>The “syllable” field defines the structure of each syllable. C is consonant, V is vowel,
and parentheses mean its optional. So, the example <code class="docutils literal notranslate"><span class="pre">(C)VC</span></code> means that every syllable
will always have a vowel followed by a consonant, and will <em>sometimes</em> have another
consonant at the beginning. e.g. <code class="docutils literal notranslate"><span class="pre">en</span></code>, <code class="docutils literal notranslate"><span class="pre">bak</span></code></p>
<p><em>Note:</em> While its not standard, the contrib lets you nest parentheses, with each layer
being less likely to show up. Additionally, any other characters put into the syllable
structure - e.g. an apostrophe - will be read and inserted as written. The
“alien” style rules in the module gives an example of both: the syllable structure is <code class="docutils literal notranslate"><span class="pre">C(C(V))(')(C)</span></code>
which results in syllables such as <code class="docutils literal notranslate"><span class="pre">khq</span></code>, <code class="docutils literal notranslate"><span class="pre">xho'q</span></code>, and <code class="docutils literal notranslate"><span class="pre">q'</span></code> with a much lower frequency of vowels than
<code class="docutils literal notranslate"><span class="pre">C(C)(V)(')(C)</span></code> would have given.</p>
</section>
<section id="consonants">
<h4>consonants<a class="headerlink" href="#consonants" title="Permalink to this headline"></a></h4>
<p>A simple list of consonant phonemes that can be chosen from. Multi-character strings are
perfectly acceptable, such as “th”, but each one will be treated as a single consonant.</p>
<p>The function uses a naive form of weighting, where you make a phoneme more likely to
occur by putting more copies of it into the list.</p>
</section>
<section id="start-and-end">
<h4>start and end<a class="headerlink" href="#start-and-end" title="Permalink to this headline"></a></h4>
<p>These are <strong>optional</strong> lists for the first and last letters of a syllable, if theyre
a consonant. You can add on additional consonants which can only occur at the beginning
or end of a syllable, or you can add extra copies of already-defined consonants to
increase the frequency of them at the start/end of syllables.</p>
<p>For example, in the <code class="docutils literal notranslate"><span class="pre">example_style</span></code> above, we have a <code class="docutils literal notranslate"><span class="pre">start</span></code> of m, and <code class="docutils literal notranslate"><span class="pre">end</span></code> of x and n.
Taken with the rest of the consonants/vowels, this means you can have the syllables of <code class="docutils literal notranslate"><span class="pre">mez</span></code>
but not <code class="docutils literal notranslate"><span class="pre">zem</span></code>, and you can have <code class="docutils literal notranslate"><span class="pre">phex</span></code> or <code class="docutils literal notranslate"><span class="pre">phen</span></code> but not <code class="docutils literal notranslate"><span class="pre">xeph</span></code> or <code class="docutils literal notranslate"><span class="pre">neph</span></code>.</p>
<p>They can be left out of custom rulesets entirely.</p>
</section>
<section id="vowels">
<h4>vowels<a class="headerlink" href="#vowels" title="Permalink to this headline"></a></h4>
<p>Vowels is a simple list of vowel phonemes - exactly like consonants, but instead used for the
vowel selection. Single-or multi-character strings are equally fine. It uses the same naive weighting system
as consonants - you can increase the frequency of any given vowel by putting it into the list multiple times.</p>
</section>
<section id="length">
<h4>length<a class="headerlink" href="#length" title="Permalink to this headline"></a></h4>
<p>A tuple with the minimum and maximum number of syllables a name can have.</p>
<p>When setting this, keep in mind how long your syllables can get! 4 syllables might
not seem like very many, but if you have a ©(V)VC structure with one- and
two-letter phonemes, you can get up to eight characters per syllable.</p>
<hr class="docutils" />
<p><small>This document page is generated from <code class="docutils literal notranslate"><span class="pre">evennia/contrib/utils/name_generator/README.md</span></code>. Changes to this
file will be overwritten, so edit that file rather than this one.</small></p>
</section>
</section>
</section>
</section>
<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="#">Random Name Generator</a><ul>
<li><a class="reference internal" href="#installation">Installation</a></li>
<li><a class="reference internal" href="#usage">Usage</a></li>
<li><a class="reference internal" href="#available-settings">Available Settings</a></li>
<li><a class="reference internal" href="#generating-real-names">Generating Real Names</a><ul>
<li><a class="reference internal" href="#adding-your-own-names">Adding your own names</a></li>
</ul>
</li>
<li><a class="reference internal" href="#generating-fantasy-names">Generating Fantasy Names</a><ul>
<li><a class="reference internal" href="#multi-word-fantasy-names">Multi-Word Fantasy Names</a><ul>
<li><a class="reference internal" href="#the-simple-approach">The simple approach</a></li>
<li><a class="reference internal" href="#nakku-silversmith">“Nakku Silversmith”</a></li>
<li><a class="reference internal" href="#elarion-dyrinea-thror-obinson">Elarion dYrinea, Thror Obinson</a></li>
</ul>
</li>
<li><a class="reference internal" href="#custom-fantasy-name-style-rules">Custom Fantasy Name style rules</a><ul>
<li><a class="reference internal" href="#syllable">syllable</a></li>
<li><a class="reference internal" href="#consonants">consonants</a></li>
<li><a class="reference internal" href="#start-and-end">start and end</a></li>
<li><a class="reference internal" href="#vowels">vowels</a></li>
<li><a class="reference internal" href="#length">length</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Contrib-Fieldfill.html"
title="previous chapter">Easy fillable form</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Random-String-Generator.html"
title="next chapter">Pseudo-random generator and registry</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Contribs/Contrib-Name-Generator.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="Contrib-Name-Generator.html">1.0-dev (develop branch)</a></li>
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 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="right" >
<a href="Contrib-Random-String-Generator.html" title="Pseudo-random generator and registry"
>next</a> |</li>
<li class="right" >
<a href="Contrib-Fieldfill.html" title="Easy fillable form"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Random Name Generator</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -18,7 +18,7 @@
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Easy menu selection tree" href="Contrib-Tree-Select.html" />
<link rel="prev" title="Easy fillable form" href="Contrib-Fieldfill.html" />
<link rel="prev" title="Random Name Generator" href="Contrib-Name-Generator.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@ -33,7 +33,7 @@
<a href="Contrib-Tree-Select.html" title="Easy menu selection tree"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Contrib-Fieldfill.html" title="Easy fillable form"
<a href="Contrib-Name-Generator.html" title="Random Name Generator"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> &#187;</li>
@ -138,8 +138,8 @@ file will be overwritten, so edit that file rather than this one.</small></p>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Contrib-Fieldfill.html"
title="previous chapter">Easy fillable form</a></p>
<p class="topless"><a href="Contrib-Name-Generator.html"
title="previous chapter">Random Name Generator</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Contrib-Tree-Select.html"
title="next chapter">Easy menu selection tree</a></p>
@ -183,7 +183,7 @@ file will be overwritten, so edit that file rather than this one.</small></p>
<a href="Contrib-Tree-Select.html" title="Easy menu selection tree"
>next</a> |</li>
<li class="right" >
<a href="Contrib-Fieldfill.html" title="Easy fillable form"
<a href="Contrib-Name-Generator.html" title="Random Name Generator"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> &#187;</li>

View file

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

View file

@ -384,12 +384,20 @@ current location (useful for displaying the grid as an in-game, updating map).</
and rule implementation like character traits, dice rolling and emoting.</em></p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Buffs.html">Buffs</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Dice.html">Dice roller</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Health-Bar.html">Health Bar</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-RPSystem.html">Roleplaying base system for Evennia</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Traits.html">Traits</a></li>
</ul>
</div>
<section id="contrib-buffs">
<h3>Contrib: <code class="docutils literal notranslate"><span class="pre">buffs</span></code><a class="headerlink" href="#contrib-buffs" title="Permalink to this headline"></a></h3>
<p><em>Contribution by Tegiminis 2022</em></p>
<p>A buff is a timed object, attached to a game entity. It is capable of modifying values, triggering code, or both.
It is a common design pattern in RPGs, particularly action games.</p>
<p><a class="reference internal" href="Contrib-Buffs.html"><span class="doc std std-doc">Read the documentation</span></a> - <a class="reference internal" href="../api/evennia.contrib.rpg.buffs.html#evennia-contrib-rpg-buffs"><span class="std std-ref">Browse the Code</span></a></p>
</section>
<section id="contrib-dice">
<h3>Contrib: <code class="docutils literal notranslate"><span class="pre">dice</span></code><a class="headerlink" href="#contrib-dice" title="Permalink to this headline"></a></h3>
<p><em>Contribution by Griatch, 2012</em></p>
@ -504,6 +512,7 @@ and more.</em></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Auditing.html">Input/Output Auditing</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Fieldfill.html">Easy fillable form</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Name-Generator.html">Random Name Generator</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Random-String-Generator.html">Pseudo-random generator and registry</a></li>
<li class="toctree-l1"><a class="reference internal" href="Contrib-Tree-Select.html">Easy menu selection tree</a></li>
</ul>
@ -528,6 +537,15 @@ function. Once the form is submitted, the forms data is submitted as a dictio
to any callable of your choice.</p>
<p><a class="reference internal" href="Contrib-Fieldfill.html"><span class="doc std std-doc">Read the documentation</span></a> - <a class="reference internal" href="../api/evennia.contrib.utils.fieldfill.html#evennia-contrib-utils-fieldfill"><span class="std std-ref">Browse the Code</span></a></p>
</section>
<section id="contrib-name-generator">
<h3>Contrib: <code class="docutils literal notranslate"><span class="pre">name_generator</span></code><a class="headerlink" href="#contrib-name-generator" title="Permalink to this headline"></a></h3>
<p><em>Contribution by InspectorCaracal (2022)</em></p>
<p>A module for generating random names, both real-world and fantasy. Real-world
names can be generated either as first (personal) names, family (last) names, or
full names (first, optional middles, and last). The name data is from <a class="reference external" href="https://www.behindthename.com/">Behind the Name</a>
and used under the <a class="reference external" href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0 license</a>.</p>
<p><a class="reference internal" href="Contrib-Name-Generator.html"><span class="doc std std-doc">Read the documentation</span></a> - <span class="xref myst">Browse the Code</span></p>
</section>
<section id="contrib-random-string-generator">
<h3>Contrib: <code class="docutils literal notranslate"><span class="pre">random_string_generator</span></code><a class="headerlink" href="#contrib-random-string-generator" title="Permalink to this headline"></a></h3>
<p><em>Contribution by Vincent Le Goff (vlgeoff), 2017</em></p>
@ -615,6 +633,7 @@ will be overwritten.</small></p>
</ul>
</li>
<li><a class="reference internal" href="#rpg">rpg</a><ul>
<li><a class="reference internal" href="#contrib-buffs">Contrib: <code class="docutils literal notranslate"><span class="pre">buffs</span></code></a></li>
<li><a class="reference internal" href="#contrib-dice">Contrib: <code class="docutils literal notranslate"><span class="pre">dice</span></code></a></li>
<li><a class="reference internal" href="#contrib-health-bar">Contrib: <code class="docutils literal notranslate"><span class="pre">health_bar</span></code></a></li>
<li><a class="reference internal" href="#contrib-rpsystem">Contrib: <code class="docutils literal notranslate"><span class="pre">rpsystem</span></code></a></li>
@ -633,6 +652,7 @@ will be overwritten.</small></p>
<li><a class="reference internal" href="#utils">utils</a><ul>
<li><a class="reference internal" href="#contrib-auditing">Contrib: <code class="docutils literal notranslate"><span class="pre">auditing</span></code></a></li>
<li><a class="reference internal" href="#contrib-fieldfill">Contrib: <code class="docutils literal notranslate"><span class="pre">fieldfill</span></code></a></li>
<li><a class="reference internal" href="#contrib-name-generator">Contrib: <code class="docutils literal notranslate"><span class="pre">name_generator</span></code></a></li>
<li><a class="reference internal" href="#contrib-random-string-generator">Contrib: <code class="docutils literal notranslate"><span class="pre">random_string_generator</span></code></a></li>
<li><a class="reference internal" href="#contrib-tree-select">Contrib: <code class="docutils literal notranslate"><span class="pre">tree_select</span></code></a></li>
</ul>