mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 13:56:30 +01:00
441 lines
No EOL
38 KiB
HTML
441 lines
No EOL
38 KiB
HTML
|
||
<!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 — 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> »</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
|
||
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 <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 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
|
||
<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">@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 <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">@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">@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">"prototype_key"</span><span class="p">:</span> <span class="s2">"house"</span>
|
||
<span class="s2">"key"</span><span class="p">:</span> <span class="s2">"Large house"</span>
|
||
<span class="s2">"typeclass"</span><span class="p">:</span> <span class="s2">"typeclasses.rooms.house.House"</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 {"prototype_key="house", "key": "Large house", ...}
|
||
</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),
|
||
it’s 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">["Accounts",</span> <span class="pre">"may_use_red_door"]</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">"edit:all();control:perm(Builder)"</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_<name></span></code> - sets the value of a non-persistent attribute (<code class="docutils literal notranslate"><span class="pre">"ndb_"</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">"key"</span><span class="p">:</span> <span class="s2">"An ugly goblin"</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">"key"</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">"key"</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">"Urfgar"</span><span class="p">,</span> <span class="s2">"Rick the smelly"</span><span class="p">,</span> <span class="s2">"Blargh the foul"</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">"key"</span><span class="p">:</span> <span class="s2">"$choice(Urfgar, Rick the smelly, Blargh the foul)"</span><span class="p">,</span>
|
||
<span class="s2">"attrs"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"This is a large $red(and very red) demon. "</span>
|
||
<span class="s2">"He has $randint(2,5) skulls in a chain around his neck."</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">"""</span>
|
||
<span class="sd"> Usage: $red(<text>)</span>
|
||
<span class="sd"> Returns the same text you entered, but red.</span>
|
||
<span class="sd"> """</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">></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">"Must have one argument, the text to color red!"</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="s2">"|r</span><span class="si">{}</span><span class="s2">|n"</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">"world.myprotfuncs"</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(<text>)</span></code> | Left-justify text |
|
||
| <code class="docutils literal notranslate"><span class="pre">$right_justify(<text>)</span></code> | Right-justify text to screen width |
|
||
| <code class="docutils literal notranslate"><span class="pre">$center_justify(<text>)</span></code> | Center-justify text to screen width |
|
||
| <code class="docutils literal notranslate"><span class="pre">$full_justify(<text>)</span></code> | Spread text across screen width by adding spaces |
|
||
| <code class="docutils literal notranslate"><span class="pre">$protkey(<name>)</span></code> | Returns value of another key in this prototype (self-reference) |
|
||
| <code class="docutils literal notranslate"><span class="pre">$add(<value1>,</span> <span class="pre"><value2>)</span></code> | Returns value1 + value2. Can also be lists, dicts etc |
|
||
| <code class="docutils literal notranslate"><span class="pre">$sub(<value1>,</span> <span class="pre"><value2>)</span></code> | Returns value1 - value2 |
|
||
| <code class="docutils literal notranslate"><span class="pre">$mult(<value1>,</span> <span class="pre"><value2>)</span></code> | Returns value1 * value2 |
|
||
| <code class="docutils literal notranslate"><span class="pre">$div(<value1>,</span> <span class="pre"><value2>)</span></code> | Returns value2 / value1 |
|
||
| <code class="docutils literal notranslate"><span class="pre">$toint(<value>)</span></code> | Returns value converted to integer (or value if not possible) |
|
||
| <code class="docutils literal notranslate"><span class="pre">$eval(<code>)</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(<query>)</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(<query>)</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">"world.myownprototypes"</span><span class="p">,</span> <span class="s2">"combat.prototypes"</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">"key"</span><span class="p">:</span><span class="s2">"Orc shaman"</span><span class="p">,</span>
|
||
<span class="s2">"typeclass"</span><span class="p">:</span> <span class="s2">"typeclasses.monsters.Orc"</span><span class="p">,</span>
|
||
<span class="s2">"weapon"</span><span class="p">:</span> <span class="s2">"wooden staff"</span><span class="p">,</span>
|
||
<span class="s2">"health"</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">"ORC_SHAMAN"</span></code> will become the <code class="docutils literal notranslate"><span class="pre">prototype_key</span></code> of this prototype.
|
||
It’s 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 it’s 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 @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">@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 {"prototype_key": "shaman", \
|
||
"key":"Orc shaman", \
|
||
"prototype_parent": "goblin", \
|
||
"weapon": "wooden staff", \
|
||
"health": 20}
|
||
</pre></div>
|
||
</div>
|
||
<blockquote>
|
||
<div><p>Note: The <code class="docutils literal notranslate"><span class="pre">@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">"key"</span><span class="p">:</span> <span class="s2">"Obj1"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"A test"</span><span class="p">},</span>
|
||
<span class="p">{</span><span class="s2">"key"</span><span class="p">:</span> <span class="s2">"Obj2"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Another test"</span><span class="p">},</span>
|
||
<span class="s2">"GOBLIN_SHAMAN"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<blockquote>
|
||
<div><p>Hint: Same as when using <code class="docutils literal notranslate"><span class="pre">@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 @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> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Spawner and Prototypes</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2020, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |