<h1>Spawner and Prototypes<aclass="headerlink"href="#spawner-and-prototypes"title="Permalink to this headline">¶</a></h1>
<p>The <em>spawner</em> is a system for defining and creating individual objects from a base template called a
<em>prototype</em>. It is only designed for use with in-game <aclass="reference internal"href="Objects.html"><spanclass="doc">Objects</span></a>, not any other type of
entity.</p>
<p>The normal way to create a custom object in Evennia is to make a <aclass="reference internal"href="Typeclasses.html"><spanclass="doc">Typeclass</span></a>. If you
haven’t read up on Typeclasses yet, think of them as normal Python classes that save to the database
behind the scenes. Say you wanted to create a “Goblin” enemy. A common way to do this would be to
first create a <codeclass="docutils literal notranslate"><spanclass="pre">Mobile</span></code> typeclass that holds everything common to mobiles in the game, like generic
AI, combat code and various movement methods. A <codeclass="docutils literal notranslate"><spanclass="pre">Goblin</span></code> subclass is then made to inherit from
<codeclass="docutils literal notranslate"><spanclass="pre">Mobile</span></code>. The <codeclass="docutils literal notranslate"><spanclass="pre">Goblin</span></code> class adds stuff unique to goblins, like group-based AI (because goblins are
smarter in a group), the ability to panic, dig for gold etc.</p>
<p>But now it’s time to actually start to create some goblins and put them in the world. What if we
wanted those goblins to not all look the same? Maybe we want grey-skinned and green-skinned goblins
or some goblins that can cast spells or which wield different weapons? We <em>could</em> make subclasses of
<codeclass="docutils literal notranslate"><spanclass="pre">Goblin</span></code>, like <codeclass="docutils literal notranslate"><spanclass="pre">GreySkinnedGoblin</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">GoblinWieldingClub</span></code>. But that seems a bit excessive (and a
lot of Python code for every little thing). Using classes can also become impractical when wanting
to combine them - what if we want a grey-skinned goblin shaman wielding a spear - setting up a web
of classes inheriting each other with multiple inheritance can be tricky.</p>
<p>This is what the <em>prototype</em> is for. It is a Python dictionary that describes these per-instance
changes to an object. The prototype also has the advantage of allowing an in-game builder to
customize an object without access to the Python backend. Evennia also allows for saving and
searching prototypes so other builders can find and use (and tweak) them later. Having a library of
interesting prototypes is a good reasource for builders. The OLC system allows for creating, saving,
loading and manipulating prototypes using a menu system.</p>
<p>The <em>spawner</em> takes a prototype and uses it to create (spawn) new, custom objects.</p>
<divclass="section"id="using-the-olc">
<h2>Using the OLC<aclass="headerlink"href="#using-the-olc"title="Permalink to this headline">¶</a></h2>
<p>Enter the <codeclass="docutils literal notranslate"><spanclass="pre">olc</span></code> command or <codeclass="docutils literal notranslate"><spanclass="pre">@spawn/olc</span></code> to enter the prototype wizard. This is a menu system for
creating, loading, saving and manipulating prototypes. It’s intended to be used by in-game builders
and will give a better understanding of prototypes in general. Use <codeclass="docutils literal notranslate"><spanclass="pre">help</span></code> on each node of the menu
for more information. Below are further details about how prototypes work and how they are used.</p>
</div>
<divclass="section"id="the-prototype">
<h2>The prototype<aclass="headerlink"href="#the-prototype"title="Permalink to this headline">¶</a></h2>
<p>The prototype dictionary can either be created for you by the OLC (see above), be written manually
in a Python module (and then referenced by the <codeclass="docutils literal notranslate"><spanclass="pre">@spawn</span></code> command/OLC), or created on-the-fly and
manually loaded into the spawner function or <codeclass="docutils literal notranslate"><spanclass="pre">@spawn</span></code> command.</p>
<p>The dictionary defines all possible database-properties of an Object. It has a fixed set of allowed
keys. When preparing to store the prototype in the database (or when using the OLC), some
of these keys are mandatory. When just passing a one-time prototype-dict to the spawner the system
other advanced Python functionality, such as executable code, <codeclass="docutils literal notranslate"><spanclass="pre">lambda</span></code> etc. If builders are supposed
<h3>Prototype keys<aclass="headerlink"href="#prototype-keys"title="Permalink to this headline">¶</a></h3>
<p>All keys starting with <codeclass="docutils literal notranslate"><spanclass="pre">prototype_</span></code> are for book keeping.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> - the ‘name’ of the prototype. While this can sometimes be skipped (such as when
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">prototype_parent</span></code> - If given, this should be the <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> of another prototype stored in
the system or available in a module. This makes this prototype <em>inherit</em> the keys from the
parent and only override what is needed. Give a tuple <codeclass="docutils literal notranslate"><spanclass="pre">(parent1,</span><spanclass="pre">parent2,</span><spanclass="pre">...)</span></code> for multiple
left-right inheritance. If this is not given, a <codeclass="docutils literal notranslate"><spanclass="pre">typeclass</span></code> should usually be defined (below).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">prototype_desc</span></code> - this is optional and used when listing the prototype in in-game listings.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">protototype_tags</span></code> - this is optional and allows for tagging the prototype in order to find it
easier later.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">prototype_locks</span></code> - two lock types are supported: <codeclass="docutils literal notranslate"><spanclass="pre">edit</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">spawn</span></code>. The first lock restricts
the copying and editing of the prototype when loaded through the OLC. The second determines who
may use the prototype to create new objects.</p></li>
</ul>
<p>The remaining keys determine actual aspects of the objects to spawn from this prototype:</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> - the main object identifier. Defaults to “Spawned Object <em>X</em>”, where <em>X</em> is a random
integer.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">typeclass</span></code> - A full python-path (from your gamedir) to the typeclass you want to use. If not
set, the <codeclass="docutils literal notranslate"><spanclass="pre">prototype_parent</span></code> should be
defined, with <codeclass="docutils literal notranslate"><spanclass="pre">typeclass</span></code> defined somewhere in the parent chain. When creating a one-time
prototype
dict just for spawning, one could omit this - <codeclass="docutils literal notranslate"><spanclass="pre">settings.BASE_OBJECT_TYPECLASS</span></code> will be used
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">location</span></code> - this should be a <codeclass="docutils literal notranslate"><spanclass="pre">#dbref</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">home</span></code> - a valid <codeclass="docutils literal notranslate"><spanclass="pre">#dbref</span></code>. Defaults to <codeclass="docutils literal notranslate"><spanclass="pre">location</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">settings.DEFAULT_HOME</span></code> if location does not
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">destination</span></code> - a valid <codeclass="docutils literal notranslate"><spanclass="pre">#dbref</span></code>. Only used by exits.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">permissions</span></code> - list of permission strings, like <codeclass="docutils literal notranslate"><spanclass="pre">["Accounts",</span><spanclass="pre">"may_use_red_door"]</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">locks</span></code> - a <aclass="reference internal"href="Locks.html"><spanclass="doc">lock-string</span></a> like <codeclass="docutils literal notranslate"><spanclass="pre">"edit:all();control:perm(Builder)"</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">aliases</span></code> - list of strings for use as aliases</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">tags</span></code> - list <aclass="reference internal"href="Tags.html"><spanclass="doc">Tags</span></a>. These are given as tuples <codeclass="docutils literal notranslate"><spanclass="pre">(tag,</span><spanclass="pre">category,</span><spanclass="pre">data)</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">attrs</span></code> - list of <aclass="reference internal"href="Attributes.html"><spanclass="doc">Attributes</span></a>. These are given as tuples <codeclass="docutils literal notranslate"><spanclass="pre">(attrname,</span><spanclass="pre">value,</span><spanclass="pre">category,</span><spanclass="pre">lockstring)</span></code></p></li>
<li><p>Any other keywords are interpreted as non-category <aclass="reference internal"href="Attributes.html"><spanclass="doc">Attributes</span></a> and their values.
convenient for simple Attributes - use <codeclass="docutils literal notranslate"><spanclass="pre">attrs</span></code> for full control of Attributes.</p></li>
</ul>
<p>Deprecated as of Evennia 0.8:</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">ndb_<name></span></code> - sets the value of a non-persistent attribute (<codeclass="docutils literal notranslate"><spanclass="pre">"ndb_"</span></code> is stripped from the name).
This is simply not useful in a prototype and is deprecated.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">exec</span></code> - This accepts a code snippet or a list of code snippets to run. This should not be used -
<p>By use of Python <codeclass="docutils literal notranslate"><spanclass="pre">lambda</span></code> one can wrap the callable so as to make immediate settings in the
prototype:</p>
<divclass="highlight-python notranslate"><tableclass="highlighttable"><tr><tdclass="linenos"><divclass="linenodiv"><pre>1</pre></div></td><tdclass="code"><divclass="highlight"><pre><span></span><spanclass="p">{</span><spanclass="s2">"key"</span><spanclass="p">:</span><spanclass="k">lambda</span><spanclass="p">:</span><spanclass="n">random</span><spanclass="o">.</span><spanclass="n">choice</span><spanclass="p">((</span><spanclass="s2">"Urfgar"</span><spanclass="p">,</span><spanclass="s2">"Rick the smelly"</span><spanclass="p">,</span><spanclass="s2">"Blargh the foul"</span><spanclass="p">,</span><spanclass="o">...</span><spanclass="p">)),</span><spanclass="o">...</span><spanclass="p">}</span>
</pre></div>
</td></tr></table></div>
<divclass="section"id="protfuncs">
<h4>Protfuncs<aclass="headerlink"href="#protfuncs"title="Permalink to this headline">¶</a></h4>
3</pre></div></td><tdclass="code"><divclass="highlight"><pre><span></span><spanclass="p">{</span><spanclass="s2">"key"</span><spanclass="p">:</span><spanclass="s2">"$choice(Urfgar, Rick the smelly, Blargh the foul)"</span><spanclass="p">,</span>
<spanclass="s2">"attrs"</span><spanclass="p">:</span><spanclass="p">{</span><spanclass="s2">"desc"</span><spanclass="p">:</span><spanclass="s2">"This is a large $red(and very red) demon. "</span>
<spanclass="s2">"He has $randint(2,5) skulls in a chain around his neck."</span><spanclass="p">}</span>
9</pre></div></td><tdclass="code"><divclass="highlight"><pre><span></span><spanclass="c1"># this is a silly example, you can just color the text red with |r directly!</span>
<spanclass="k">raise</span><spanclass="ne">ValueError</span><spanclass="p">(</span><spanclass="s2">"Must have one argument, the text to color red!"</span><spanclass="p">)</span>
<div><p>Note that we must make sure to validate input and raise <codeclass="docutils literal notranslate"><spanclass="pre">ValueError</span></code> if that fails. Also, it is
<em>not</em> possible to use keywords in the call to the protfunc (so something like <codeclass="docutils literal notranslate"><spanclass="pre">$echo(text,</span><spanclass="pre">align=left)</span></code> is invalid). The <codeclass="docutils literal notranslate"><spanclass="pre">kwargs</span></code> requred is for internal evennia use and not used at all for
<p>All <em>global callables</em> in your added module will be considered a new protfunc. To avoid this (e.g.
to have helper functions that are not protfuncs on their own), name your function something starting
with <codeclass="docutils literal notranslate"><spanclass="pre">_</span></code>.</p>
<p>The default protfuncs available out of the box are defined in <codeclass="docutils literal notranslate"><spanclass="pre">evennia/prototypes/profuncs.py</span></code>. To
override the ones available, just add the same-named function in your own protfunc module.</p>
<p>| <codeclass="docutils literal notranslate"><spanclass="pre">$random()</span></code> | Returns random value in range [0, 1) |
| <codeclass="docutils literal notranslate"><spanclass="pre">$randint(start,</span><spanclass="pre">end)</span></code> | Returns random value in range [start, end] |
| <codeclass="docutils literal notranslate"><spanclass="pre">$left_justify(<text>)</span></code> | Left-justify text |
| <codeclass="docutils literal notranslate"><spanclass="pre">$right_justify(<text>)</span></code> | Right-justify text to screen width |
| <codeclass="docutils literal notranslate"><spanclass="pre">$center_justify(<text>)</span></code> | Center-justify text to screen width |
| <codeclass="docutils literal notranslate"><spanclass="pre">$full_justify(<text>)</span></code> | Spread text across screen width by adding spaces |
| <codeclass="docutils literal notranslate"><spanclass="pre">$protkey(<name>)</span></code> | Returns value of another key in this prototype (self-reference) |
| <codeclass="docutils literal notranslate"><spanclass="pre">$add(<value1>,</span><spanclass="pre"><value2>)</span></code> | Returns value1 + value2. Can also be lists, dicts etc |
| <codeclass="docutils literal notranslate"><spanclass="pre">$toint(<value>)</span></code> | Returns value converted to integer (or value if not possible) |
| <codeclass="docutils literal notranslate"><spanclass="pre">$eval(<code>)</span></code> | Returns result of <aclass="reference external"href="https://docs.python.org/2/library/ast.html#ast.literal_eval">literal-
eval</a> of code string. Only simple
python expressions. |
| <codeclass="docutils literal notranslate"><spanclass="pre">$obj(<query>)</span></code> | Returns object #dbref searched globally by key, tag or #dbref. Error if more
| <codeclass="docutils literal notranslate"><spanclass="pre">$objlist(<query>)</span></code> | Like <codeclass="docutils literal notranslate"><spanclass="pre">$obj</span></code>, except always returns a list of zero, one or more results. |
| <codeclass="docutils literal notranslate"><spanclass="pre">$dbref(dbref)</span></code> | Returns argument if it is formed as a #dbref (e.g. #1234), otherwise error.</p>
<p>Stored as <aclass="reference internal"href="Scripts.html"><spanclass="doc">Scripts</span></a> in the database. These are sometimes referred to as <em>database-
prototypes</em> This is the only way for in-game builders to modify and add prototypes. They have the
advantage of being easily modifiable and sharable between builders but you need to work with them
<p>These prototypes are defined as dictionaries assigned to global variables in one of the modules
defined in <codeclass="docutils literal notranslate"><spanclass="pre">settings.PROTOTYPE_MODULES</span></code>. They can only be modified from outside the game so they are
are necessarily “read-only” from in-game and cannot be modified (but copies of them could be made
into database-prototypes). These were the only prototypes available before Evennia 0.8. Module based
prototypes can be useful in order for developers to provide read-only “starting” or “base”
prototypes to build from or if they just prefer to work offline in an external code editor.</p>
<p>By default <codeclass="docutils literal notranslate"><spanclass="pre">mygame/world/prototypes.py</span></code> is set up for you to add your own prototypes. <em>All global
dicts</em> in this module will be considered by Evennia to be a prototype. You could also tell Evennia
to look for prototypes in more modules if you want:</p>
<div><p>Note the += operator in the above example. This will extend the already defined <codeclass="docutils literal notranslate"><spanclass="pre">world.prototypes</span></code>
definition in the settings_default.py file in Evennia. If you would like to completely override the
location of your <codeclass="docutils literal notranslate"><spanclass="pre">PROTOTYPE_MODULES</span></code> then set this to just = without the addition operator.</p>
<div><p>Note that in the example above, <codeclass="docutils literal notranslate"><spanclass="pre">"ORC_SHAMAN"</span></code> will become the <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> of this prototype.
It’s the only case when <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> can be skipped in a prototype. However, if <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code>
was given explicitly, that would take precedence. This is a legacy behavior and it’s recommended
that you always add <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> to be consistent.</p>
</div></blockquote>
</div>
</div>
<divclass="section"id="using-spawn">
<h2>Using @spawn<aclass="headerlink"href="#using-spawn"title="Permalink to this headline">¶</a></h2>
<p>The spawner can be used from inside the game through the Builder-only <codeclass="docutils literal notranslate"><spanclass="pre">@spawn</span></code> command. Assuming the
“goblin” typeclass is available to the system (either as a database-prototype or read from module),
<div><p>Note: The <codeclass="docutils literal notranslate"><spanclass="pre">@spawn</span></code> command is more lenient about the prototype dictionary than shown here. So you
can for example skip the <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> if you are just testing a throw-away prototype. A random
hash will be used to please the validation. You could also skip <codeclass="docutils literal notranslate"><spanclass="pre">prototype_parent/typeclass</span></code> - then
the typeclass given by <codeclass="docutils literal notranslate"><spanclass="pre">settings.BASE_OBJECT_TYPECLASS</span></code> will be used.</p>
<p>All arguments are prototype dictionaries or the unique <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code>s of prototypes
known to the system (either database- or module-based). The function will return a matching list of
<div><p>Hint: Same as when using <codeclass="docutils literal notranslate"><spanclass="pre">@spawn</span></code>, when spawning from a one-time prototype dict like this, you can
skip otherwise required keys, like <codeclass="docutils literal notranslate"><spanclass="pre">prototype_key</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">typeclass</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">prototype_parent</span></code>. Defaults will
<p>Note that no <codeclass="docutils literal notranslate"><spanclass="pre">location</span></code> will be set automatically when using <codeclass="docutils literal notranslate"><spanclass="pre">evennia.prototypes.spawner.spawn()</span></code>,
<p>If the prototypes you supply are using <codeclass="docutils literal notranslate"><spanclass="pre">prototype_parent</span></code> keywords, the spawner will read prototypes
from modules
in <codeclass="docutils literal notranslate"><spanclass="pre">settings.PROTOTYPE_MODULES</span></code> as well as those saved to the database to determine the body of
available parents. The <codeclass="docutils literal notranslate"><spanclass="pre">spawn</span></code> command takes many optional keywords, you can find its definition <aclass="reference external"href="https://github.com/evennia/evennia/blob/master/evennia.prototypes.spawner#spawn">in