evennia/docs/0.x/Spawner-and-Prototypes.html
2023-12-20 19:10:09 +01:00

441 lines
No EOL
38 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>Spawner and Prototypes &#8212; Evennia 0.9.5 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>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Spawner and Prototypes</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="spawner-and-prototypes">
<h1>Spawner and Prototypes<a class="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 <a class="reference internal" href="Objects.html"><span class="doc std std-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 <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclass</span></a>. If you
havent 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 <code class="docutils literal notranslate"><span class="pre">Mobile</span></code> typeclass that holds everything common to mobiles in the game, like generic
AI, combat code and various movement methods. A <code class="docutils literal notranslate"><span class="pre">Goblin</span></code> subclass is then made to inherit from
<code class="docutils literal notranslate"><span class="pre">Mobile</span></code>. The <code class="docutils literal notranslate"><span class="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 its 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
<code class="docutils literal notranslate"><span class="pre">Goblin</span></code>, like <code class="docutils literal notranslate"><span class="pre">GreySkinnedGoblin</span></code> and <code class="docutils literal notranslate"><span class="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>
<section id="using-the-olc">
<h2>Using the OLC<a class="headerlink" href="#using-the-olc" title="Permalink to this headline"></a></h2>
<p>Enter the <code class="docutils literal notranslate"><span class="pre">olc</span></code> command or <code class="docutils literal notranslate"><span class="pre">&#64;spawn/olc</span></code> to enter the prototype wizard. This is a menu system for
creating, loading, saving and manipulating prototypes. Its intended to be used by in-game builders
and will give a better understanding of prototypes in general. Use <code class="docutils literal notranslate"><span class="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>
</section>
<section id="the-prototype">
<h2>The prototype<a class="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 <code class="docutils literal notranslate"><span class="pre">&#64;spawn</span></code> command/OLC), or created on-the-fly and
manually loaded into the spawner function or <code class="docutils literal notranslate"><span class="pre">&#64;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
is
more lenient and will use defaults for keys not explicitly provided.</p>
<p>In dictionary form, a prototype can look something like this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="s2">&quot;prototype_key&quot;</span><span class="p">:</span> <span class="s2">&quot;house&quot;</span>
<span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;Large house&quot;</span>
<span class="s2">&quot;typeclass&quot;</span><span class="p">:</span> <span class="s2">&quot;typeclasses.rooms.house.House&quot;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If you wanted to load it into the spawner in-game you could just put all on one line:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@spawn {&quot;prototype_key=&quot;house&quot;, &quot;key&quot;: &quot;Large house&quot;, ...}
</pre></div>
</div>
<blockquote>
<div><p>Note that the prototype dict as given on the command line must be a valid Python structure -
so you need to put quotes around strings etc. For security reasons, a dict inserted from-in game
cannot have any
other advanced Python functionality, such as executable code, <code class="docutils literal notranslate"><span class="pre">lambda</span></code> etc. If builders are supposed
to be able to use such features, you need to offer them through [$protfuncs](Spawner-and-
Prototypes#protfuncs), embedded runnable functions that you have full control to check and vet
before running.</p>
</div></blockquote>
<section id="prototype-keys">
<h3>Prototype keys<a class="headerlink" href="#prototype-keys" title="Permalink to this headline"></a></h3>
<p>All keys starting with <code class="docutils literal notranslate"><span class="pre">prototype_</span></code> are for book keeping.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> - the name of the prototype. While this can sometimes be skipped (such as when
defining a prototype in a module or feeding a prototype-dict manually to the spawner function),
its good
practice to try to include this. It is used for book-keeping and storing of the prototype so you
can find it later.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code> - If given, this should be the <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">(parent1,</span> <span class="pre">parent2,</span> <span class="pre">...)</span></code> for multiple
left-right inheritance. If this is not given, a <code class="docutils literal notranslate"><span class="pre">typeclass</span></code> should usually be defined (below).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">prototype_desc</span></code> - this is optional and used when listing the prototype in in-game listings.</p></li>
<li><p><code class="docutils literal notranslate"><span class="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><code class="docutils literal notranslate"><span class="pre">prototype_locks</span></code> - two lock types are supported: <code class="docutils literal notranslate"><span class="pre">edit</span></code> and <code class="docutils literal notranslate"><span class="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>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="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><code class="docutils literal notranslate"><span class="pre">typeclass</span></code> - A full python-path (from your gamedir) to the typeclass you want to use. If not
set, the <code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code> should be
defined, with <code class="docutils literal notranslate"><span class="pre">typeclass</span></code> defined somewhere in the parent chain. When creating a one-time
prototype
dict just for spawning, one could omit this - <code class="docutils literal notranslate"><span class="pre">settings.BASE_OBJECT_TYPECLASS</span></code> will be used
instead.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">location</span></code> - this should be a <code class="docutils literal notranslate"><span class="pre">#dbref</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">home</span></code> - a valid <code class="docutils literal notranslate"><span class="pre">#dbref</span></code>. Defaults to <code class="docutils literal notranslate"><span class="pre">location</span></code> or <code class="docutils literal notranslate"><span class="pre">settings.DEFAULT_HOME</span></code> if location does not
exist.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">destination</span></code> - a valid <code class="docutils literal notranslate"><span class="pre">#dbref</span></code>. Only used by exits.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">permissions</span></code> - list of permission strings, like <code class="docutils literal notranslate"><span class="pre">[&quot;Accounts&quot;,</span> <span class="pre">&quot;may_use_red_door&quot;]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">locks</span></code> - a <a class="reference internal" href="Locks.html"><span class="doc std std-doc">lock-string</span></a> like <code class="docutils literal notranslate"><span class="pre">&quot;edit:all();control:perm(Builder)&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">aliases</span></code> - list of strings for use as aliases</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">tags</span></code> - list <a class="reference internal" href="Tags.html"><span class="doc std std-doc">Tags</span></a>. These are given as tuples <code class="docutils literal notranslate"><span class="pre">(tag,</span> <span class="pre">category,</span> <span class="pre">data)</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">attrs</span></code> - list of <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a>. These are given as tuples <code class="docutils literal notranslate"><span class="pre">(attrname,</span> <span class="pre">value,</span> <span class="pre">category,</span> <span class="pre">lockstring)</span></code></p></li>
<li><p>Any other keywords are interpreted as non-category <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a> and their values.
This is
convenient for simple Attributes - use <code class="docutils literal notranslate"><span class="pre">attrs</span></code> for full control of Attributes.</p></li>
</ul>
<p>Deprecated as of Evennia 0.8:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">ndb_&lt;name&gt;</span></code> - sets the value of a non-persistent attribute (<code class="docutils literal notranslate"><span class="pre">&quot;ndb_&quot;</span></code> is stripped from the name).
This is simply not useful in a prototype and is deprecated.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">exec</span></code> - This accepts a code snippet or a list of code snippets to run. This should not be used -
use callables or <a class="reference internal" href="#protfuncs"><span class="std std-doc">$protfuncs</span></a> instead (see below).</p></li>
</ul>
</section>
<section id="prototype-values">
<h3>Prototype values<a class="headerlink" href="#prototype-values" title="Permalink to this headline"></a></h3>
<p>The prototype supports values of several different types.</p>
<p>It can be a hard-coded value:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;An ugly goblin&quot;</span><span class="p">,</span> <span class="o">...</span><span class="p">}</span>
</pre></div>
</div>
<p>It can also be a <em>callable</em>. This callable is called without arguments whenever the prototype is
used to
spawn a new object:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="n">_get_a_random_goblin_name</span><span class="p">,</span> <span class="o">...</span><span class="p">}</span>
</pre></div>
</div>
<p>By use of Python <code class="docutils literal notranslate"><span class="pre">lambda</span></code> one can wrap the callable so as to make immediate settings in the
prototype:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">((</span><span class="s2">&quot;Urfgar&quot;</span><span class="p">,</span> <span class="s2">&quot;Rick the smelly&quot;</span><span class="p">,</span> <span class="s2">&quot;Blargh the foul&quot;</span><span class="p">,</span> <span class="o">...</span><span class="p">)),</span> <span class="o">...</span><span class="p">}</span>
</pre></div>
</div>
<section id="protfuncs">
<h4>Protfuncs<a class="headerlink" href="#protfuncs" title="Permalink to this headline"></a></h4>
<p>Finally, the value can be a <em>prototype function</em> (<em>Protfunc</em>). These look like simple function calls
that you embed in strings and that has a <code class="docutils literal notranslate"><span class="pre">$</span></code> in front, like</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;$choice(Urfgar, Rick the smelly, Blargh the foul)&quot;</span><span class="p">,</span>
<span class="s2">&quot;attrs&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;desc&quot;</span><span class="p">:</span> <span class="s2">&quot;This is a large $red(and very red) demon. &quot;</span>
<span class="s2">&quot;He has $randint(2,5) skulls in a chain around his neck.&quot;</span><span class="p">}</span>
</pre></div>
</div>
<p>At execution time, the place of the protfunc will be replaced with the result of that protfunc being
called (this is always a string). A protfunc works in much the same way as an
<a class="reference internal" href="TextTags.html#inline-functions"><span class="std std-doc">InlineFunc</span></a> - they are actually
parsed using the same parser - except protfuncs are run every time the prototype is used to spawn a
new object (whereas an inlinefunc is called when a text is returned to the user).</p>
<p>Here is how a protfunc is defined (same as an inlinefunc).</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># this is a silly example, you can just color the text red with |r directly!</span>
<span class="k">def</span> <span class="nf">red</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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $red(&lt;text&gt;)</span>
<span class="sd"> Returns the same text you entered, but red.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Must have one argument, the text to color red!&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot;|r</span><span class="si">{}</span><span class="s2">|n&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
<blockquote>
<div><p>Note that we must make sure to validate input and raise <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">$echo(text,</span> <span class="pre">align=left)</span></code> is invalid). The <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> requred is for internal evennia use and not used at all for
protfuncs (only by inlinefuncs).</p>
</div></blockquote>
<p>To make this protfunc available to builders in-game, add it to a new module and add the path to that
module to <code class="docutils literal notranslate"><span class="pre">settings.PROT_FUNC_MODULES</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/server/conf/settings.py</span>
<span class="n">PROT_FUNC_MODULES</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;world.myprotfuncs&quot;</span><span class="p">]</span>
</pre></div>
</div>
<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 <code class="docutils literal notranslate"><span class="pre">_</span></code>.</p>
<p>The default protfuncs available out of the box are defined in <code class="docutils literal notranslate"><span class="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>| Protfunc | Description |</p>
<p>| <code class="docutils literal notranslate"><span class="pre">$random()</span></code> | Returns random value in range [0, 1) |
| <code class="docutils literal notranslate"><span class="pre">$randint(start,</span> <span class="pre">end)</span></code> | Returns random value in range [start, end] |
| <code class="docutils literal notranslate"><span class="pre">$left_justify(&lt;text&gt;)</span></code> | Left-justify text |
| <code class="docutils literal notranslate"><span class="pre">$right_justify(&lt;text&gt;)</span></code> | Right-justify text to screen width |
| <code class="docutils literal notranslate"><span class="pre">$center_justify(&lt;text&gt;)</span></code> | Center-justify text to screen width |
| <code class="docutils literal notranslate"><span class="pre">$full_justify(&lt;text&gt;)</span></code> | Spread text across screen width by adding spaces |
| <code class="docutils literal notranslate"><span class="pre">$protkey(&lt;name&gt;)</span></code> | Returns value of another key in this prototype (self-reference) |
| <code class="docutils literal notranslate"><span class="pre">$add(&lt;value1&gt;,</span> <span class="pre">&lt;value2&gt;)</span></code> | Returns value1 + value2. Can also be lists, dicts etc |
| <code class="docutils literal notranslate"><span class="pre">$sub(&lt;value1&gt;,</span> <span class="pre">&lt;value2&gt;)</span></code> | Returns value1 - value2 |
| <code class="docutils literal notranslate"><span class="pre">$mult(&lt;value1&gt;,</span> <span class="pre">&lt;value2&gt;)</span></code> | Returns value1 * value2 |
| <code class="docutils literal notranslate"><span class="pre">$div(&lt;value1&gt;,</span> <span class="pre">&lt;value2&gt;)</span></code> | Returns value2 / value1 |
| <code class="docutils literal notranslate"><span class="pre">$toint(&lt;value&gt;)</span></code> | Returns value converted to integer (or value if not possible) |
| <code class="docutils literal notranslate"><span class="pre">$eval(&lt;code&gt;)</span></code> | Returns result of <a class="reference external" href="https://docs.python.org/2/library/ast.html#ast.literal_eval">literal-
eval</a> of code string. Only simple
python expressions. |
| <code class="docutils literal notranslate"><span class="pre">$obj(&lt;query&gt;)</span></code> | Returns object #dbref searched globally by key, tag or #dbref. Error if more
than one found.” |
| <code class="docutils literal notranslate"><span class="pre">$objlist(&lt;query&gt;)</span></code> | Like <code class="docutils literal notranslate"><span class="pre">$obj</span></code>, except always returns a list of zero, one or more results. |
| <code class="docutils literal notranslate"><span class="pre">$dbref(dbref)</span></code> | Returns argument if it is formed as a #dbref (e.g. #1234), otherwise error.</p>
<p>For developers with access to Python, using protfuncs in prototypes is generally not useful. Passing
real Python functions is a lot more powerful and flexible. Their main use is to allow in-game
builders to
do limited coding/scripting for their prototypes without giving them direct access to raw Python.</p>
</section>
</section>
</section>
<section id="storing-prototypes">
<h2>Storing prototypes<a class="headerlink" href="#storing-prototypes" title="Permalink to this headline"></a></h2>
<p>A prototype can be defined and stored in two ways, either in the database or as a dict in a module.</p>
<section id="database-prototypes">
<h3>Database prototypes<a class="headerlink" href="#database-prototypes" title="Permalink to this headline"></a></h3>
<p>Stored as <a class="reference internal" href="Scripts.html"><span class="doc std std-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
using in-game tools.</p>
</section>
<section id="module-based-prototypes">
<h3>Module-based prototypes<a class="headerlink" href="#module-based-prototypes" title="Permalink to this headline"></a></h3>
<p>These prototypes are defined as dictionaries assigned to global variables in one of the modules
defined in <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="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 class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/server/conf/settings.py</span>
<span class="n">PROTOTYPE_MODULES</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;world.myownprototypes&quot;</span><span class="p">,</span> <span class="s2">&quot;combat.prototypes&quot;</span><span class="p">]</span>
</pre></div>
</div>
<blockquote>
<div><p>Note the += operator in the above example. This will extend the already defined <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">PROTOTYPE_MODULES</span></code> then set this to just = without the addition operator.</p>
</div></blockquote>
<p>Here is an example of a prototype defined in a module:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># in a module Evennia looks at for prototypes,</span>
<span class="c1"># (like mygame/world/prototypes.py)</span>
<span class="n">ORC_SHAMAN</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span><span class="s2">&quot;Orc shaman&quot;</span><span class="p">,</span>
<span class="s2">&quot;typeclass&quot;</span><span class="p">:</span> <span class="s2">&quot;typeclasses.monsters.Orc&quot;</span><span class="p">,</span>
<span class="s2">&quot;weapon&quot;</span><span class="p">:</span> <span class="s2">&quot;wooden staff&quot;</span><span class="p">,</span>
<span class="s2">&quot;health&quot;</span><span class="p">:</span> <span class="mi">20</span><span class="p">}</span>
</pre></div>
</div>
<blockquote>
<div><p>Note that in the example above, <code class="docutils literal notranslate"><span class="pre">&quot;ORC_SHAMAN&quot;</span></code> will become the <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> of this prototype.
Its the only case when <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> can be skipped in a prototype. However, if <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code>
was given explicitly, that would take precedence. This is a legacy behavior and its recommended
that you always add <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> to be consistent.</p>
</div></blockquote>
</section>
</section>
<section id="using-spawn">
<h2>Using &#64;spawn<a class="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 <code class="docutils literal notranslate"><span class="pre">&#64;spawn</span></code> command. Assuming the
“goblin” typeclass is available to the system (either as a database-prototype or read from module),
you can spawn a new goblin with</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@spawn goblin
</pre></div>
</div>
<p>You can also specify the prototype directly as a valid Python dictionary:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>@spawn {&quot;prototype_key&quot;: &quot;shaman&quot;, \
&quot;key&quot;:&quot;Orc shaman&quot;, \
&quot;prototype_parent&quot;: &quot;goblin&quot;, \
&quot;weapon&quot;: &quot;wooden staff&quot;, \
&quot;health&quot;: 20}
</pre></div>
</div>
<blockquote>
<div><p>Note: The <code class="docutils literal notranslate"><span class="pre">&#64;spawn</span></code> command is more lenient about the prototype dictionary than shown here. So you
can for example skip the <code class="docutils literal notranslate"><span class="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 <code class="docutils literal notranslate"><span class="pre">prototype_parent/typeclass</span></code> - then
the typeclass given by <code class="docutils literal notranslate"><span class="pre">settings.BASE_OBJECT_TYPECLASS</span></code> will be used.</p>
</div></blockquote>
</section>
<section id="using-evennia-prototypes-spawner">
<h2>Using evennia.prototypes.spawner()<a class="headerlink" href="#using-evennia-prototypes-spawner" title="Permalink to this headline"></a></h2>
<p>In code you access the spawner mechanism directly via the call</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">new_objects</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">prototypes</span><span class="o">.</span><span class="n">spawner</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">*</span><span class="n">prototypes</span><span class="p">)</span>
</pre></div>
</div>
<p>All arguments are prototype dictionaries or the unique <code class="docutils literal notranslate"><span class="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
created objects. Example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">obj1</span><span class="p">,</span> <span class="n">obj2</span><span class="p">,</span> <span class="n">obj3</span> <span class="o">=</span> <span class="n">evennia</span><span class="o">.</span><span class="n">prototypes</span><span class="o">.</span><span class="n">spawner</span><span class="o">.</span><span class="n">spawn</span><span class="p">({</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;Obj1&quot;</span><span class="p">,</span> <span class="s2">&quot;desc&quot;</span><span class="p">:</span> <span class="s2">&quot;A test&quot;</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="s2">&quot;Obj2&quot;</span><span class="p">,</span> <span class="s2">&quot;desc&quot;</span><span class="p">:</span> <span class="s2">&quot;Another test&quot;</span><span class="p">},</span>
<span class="s2">&quot;GOBLIN_SHAMAN&quot;</span><span class="p">)</span>
</pre></div>
</div>
<blockquote>
<div><p>Hint: Same as when using <code class="docutils literal notranslate"><span class="pre">&#64;spawn</span></code>, when spawning from a one-time prototype dict like this, you can
skip otherwise required keys, like <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> or <code class="docutils literal notranslate"><span class="pre">typeclass</span></code>/<code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code>. Defaults will
be used.</p>
</div></blockquote>
<p>Note that no <code class="docutils literal notranslate"><span class="pre">location</span></code> will be set automatically when using <code class="docutils literal notranslate"><span class="pre">evennia.prototypes.spawner.spawn()</span></code>,
you
have to specify <code class="docutils literal notranslate"><span class="pre">location</span></code> explicitly in the prototype dict.</p>
<p>If the prototypes you supply are using <code class="docutils literal notranslate"><span class="pre">prototype_parent</span></code> keywords, the spawner will read prototypes
from modules
in <code class="docutils literal notranslate"><span class="pre">settings.PROTOTYPE_MODULES</span></code> as well as those saved to the database to determine the body of
available parents. The <code class="docutils literal notranslate"><span class="pre">spawn</span></code> command takes many optional keywords, you can find its definition <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.prototypes.spawner#spawn">in
the api docs</a>.</p>
</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="#">Spawner and Prototypes</a><ul>
<li><a class="reference internal" href="#using-the-olc">Using the OLC</a></li>
<li><a class="reference internal" href="#the-prototype">The prototype</a><ul>
<li><a class="reference internal" href="#prototype-keys">Prototype keys</a></li>
<li><a class="reference internal" href="#prototype-values">Prototype values</a><ul>
<li><a class="reference internal" href="#protfuncs">Protfuncs</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#storing-prototypes">Storing prototypes</a><ul>
<li><a class="reference internal" href="#database-prototypes">Database prototypes</a></li>
<li><a class="reference internal" href="#module-based-prototypes">Module-based prototypes</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-spawn">Using &#64;spawn</a></li>
<li><a class="reference internal" href="#using-evennia-prototypes-spawner">Using evennia.prototypes.spawner()</a></li>
</ul>
</li>
</ul>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="_sources/Spawner-and-Prototypes.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="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
<li><a href="Spawner-and-Prototypes.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="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Spawner and Prototypes</a></li>
</ul>
</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>