mirror of
https://github.com/evennia/evennia.git
synced 2026-03-29 12:07:17 +02:00
Updated HTML docs.
This commit is contained in:
parent
e078081850
commit
fd348593b2
38 changed files with 484 additions and 660 deletions
|
|
@ -63,7 +63,7 @@
|
|||
<h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Accounts</a><ul>
|
||||
<li><a class="reference internal" href="#how-to-create-your-own-account-types">How to create your own Account types</a></li>
|
||||
<li><a class="reference internal" href="#how-to-customize-your-own-account-types">How to customize your own Account types</a></li>
|
||||
<li><a class="reference internal" href="#properties-on-accounts">Properties on Accounts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
@ -107,94 +107,76 @@
|
|||
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="accounts">
|
||||
<h1>Accounts<a class="headerlink" href="#accounts" title="Permalink to this headline">¶</a></h1>
|
||||
<p>All <em>users</em> (real people) that starts a game <a class="reference internal" href="Sessions.html"><span class="doc std std-doc">Session</span></a> on Evennia are doing so through an
|
||||
object called <em>Account</em>. The Account object has no in-game representation, it represents a unique
|
||||
game account. In order to actually get on the game the Account must <em>puppet</em> an <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a>
|
||||
(normally a <a class="reference internal" href="Objects.html#characters"><span class="std std-doc">Character</span></a>).</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>┌──────┐ │ ┌───────┐ ┌───────┐ ┌──────┐
|
||||
│Client├─┼──►│Session├───►│Account├──►│Object│
|
||||
└──────┘ │ └───────┘ └───────┘ └──────┘
|
||||
^
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An <em>Account</em> represents a unique game account - one player playing the game. Whereas a player can potentially connect to the game from several Clients/Sessions, they will normally have only one Account.</p>
|
||||
<p>The Account object has no in-game representation. In order to actually get on the game the Account must <em>puppet</em> an <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Object</span></a> (normally a <a class="reference internal" href="Objects.html#characters"><span class="std std-doc">Character</span></a>).</p>
|
||||
<p>Exactly how many Sessions can interact with an Account and its Puppets at once is determined by
|
||||
Evennia’s <a class="reference internal" href="Sessions.html#multisession-mode"><span class="std std-doc">MULTISESSION_MODE</span></a> setting.</p>
|
||||
<p>Apart from storing login information and other account-specific data, the Account object is what is
|
||||
chatting on <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a>. It is also a good place to store <a class="reference internal" href="Locks.html"><span class="doc std std-doc">Permissions</span></a> to be
|
||||
consistent between different in-game characters as well as configuration options. The Account
|
||||
object also has its own <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">CmdSet</span></a>, the <code class="docutils literal notranslate"><span class="pre">AccountCmdSet</span></code>.</p>
|
||||
<p>Logged into default evennia, you can use the <code class="docutils literal notranslate"><span class="pre">ooc</span></code> command to leave your current
|
||||
<a class="reference internal" href="Objects.html"><span class="doc std std-doc">character</span></a> and go into OOC mode. You are quite limited in this mode, basically it works
|
||||
like a simple chat program. It acts as a staging area for switching between Characters (if your
|
||||
game supports that) or as a safety mode if your Character gets deleted. Use <code class="docutils literal notranslate"><span class="pre">ic</span></code> to attempt to
|
||||
(re)puppet a Character.</p>
|
||||
<p>Note that the Account object can have, and often does have, a different set of
|
||||
<a class="reference internal" href="Permissions.html"><span class="doc std std-doc">Permissions</span></a> from the Character they control. Normally you should put your
|
||||
permissions on the Account level - this will overrule permissions set on the Character level. For
|
||||
the permissions of the Character to come into play the default <code class="docutils literal notranslate"><span class="pre">quell</span></code> command can be used. This
|
||||
allows for exploring the game using a different permission set (but you can’t escalate your
|
||||
permissions this way - for hierarchical permissions like <code class="docutils literal notranslate"><span class="pre">Builder</span></code>, <code class="docutils literal notranslate"><span class="pre">Admin</span></code> etc, the <em>lower</em> of the
|
||||
permissions on the Character/Account will always be used).</p>
|
||||
<section id="how-to-create-your-own-account-types">
|
||||
<h2>How to create your own Account types<a class="headerlink" href="#how-to-create-your-own-account-types" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You will usually not want more than one Account typeclass for all new accounts (but you could in
|
||||
principle create a system that changes an account’s typeclass dynamically).</p>
|
||||
<p>An Evennia Account is, per definition, a Python class that includes <code class="docutils literal notranslate"><span class="pre">evennia.DefaultAccount</span></code> among
|
||||
its parents. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/accounts.py</span></code> there is an empty class ready for you to modify.
|
||||
Evennia defaults to using this (it inherits directly from <code class="docutils literal notranslate"><span class="pre">DefaultAccount</span></code>).</p>
|
||||
<p>Apart from storing login information and other account-specific data, the Account object is what is chatting on Evennia’s default <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a>. It is also a good place to store <a class="reference internal" href="Locks.html"><span class="doc std std-doc">Permissions</span></a> to be consistent between different in-game characters. It can also hold player-level configuration options.</p>
|
||||
<p>The Account object has its own default <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">CmdSet</span></a>, the <code class="docutils literal notranslate"><span class="pre">AccountCmdSet</span></code>. The commands in this set are available to the player no matter which character they are puppeting. Most notably the default game’s <code class="docutils literal notranslate"><span class="pre">exit</span></code>, <code class="docutils literal notranslate"><span class="pre">who</span></code> and chat-channel commands are in the Account cmdset.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> ooc
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The default <code class="docutils literal notranslate"><span class="pre">ooc</span></code> command causes you to leave your current puppet and go into OOC mode. In this mode you have no location and have only the Account-cmdset available. It acts a staging area for switching characters (if your game supports that) as well as a safety fallback if your character gets accidentally deleted.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> ic
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This re-puppets the latest character.</p>
|
||||
<p>Note that the Account object can have, and often does have, a different set of <a class="reference internal" href="Permissions.html"><span class="doc std std-doc">Permissions</span></a> from the Character they control. Normally you should put your permissions on the Account level - this will overrule permissions set on the Character level. For the permissions of the Character to come into play the default <code class="docutils literal notranslate"><span class="pre">quell</span></code> command can be used. This allows for exploring the game using a different permission set (but you can’t escalate your permissions this way - for hierarchical permissions like <code class="docutils literal notranslate"><span class="pre">Builder</span></code>, <code class="docutils literal notranslate"><span class="pre">Admin</span></code> etc, the <em>lower</em> of the permissions on the Character/Account will always be used).</p>
|
||||
<section id="how-to-customize-your-own-account-types">
|
||||
<h2>How to customize your own Account types<a class="headerlink" href="#how-to-customize-your-own-account-types" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You will usually not want more than one Account typeclass for all new accounts.</p>
|
||||
<p>An Evennia Account is, per definition, a Python class that includes <code class="docutils literal notranslate"><span class="pre">evennia.DefaultAccount</span></code> among its parents. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/accounts.py</span></code> there is an empty class ready for you to modify. Evennia defaults to using this (it inherits directly from <code class="docutils literal notranslate"><span class="pre">DefaultAccount</span></code>).</p>
|
||||
<p>Here’s an example of modifying the default Account class in code:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># in mygame/typeclasses/accounts.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultAccount</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Account</span><span class="p">(</span><span class="n">DefaultAccount</span><span class="p">):</span> <span class="c1"># [...]</span>
|
||||
|
||||
<span class="n">at_account_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="s2">"this is called only once, when account is first created"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">real_name</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># this is set later self.db.real_address = None # "</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">config_1</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># default config self.db.config_2 = False # "</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">config_3</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># "</span>
|
||||
|
||||
<span class="c1"># ... whatever else our game needs to know ``` Reload the server with `reload`.</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Account</span><span class="p">(</span><span class="n">DefaultAccount</span><span class="p">):</span>
|
||||
<span class="c1"># [...]</span>
|
||||
<span class="k">def</span> <span class="nf">at_account_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="s2">"this is called only once, when account is first created"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">real_name</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># this is set later </span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">real_address</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># "</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">config_1</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># default config </span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">config_2</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># "</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">config_3</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># "</span>
|
||||
|
||||
<span class="c1"># ... whatever else our game needs to know </span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>… However, if you use <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">*self</span></code> (the asterisk makes you examine your Account object rather
|
||||
than your Character), you won’t see your new Attributes yet. This is because <code class="docutils literal notranslate"><span class="pre">at_account_creation</span></code>
|
||||
is only called the very <em>first</em> time the Account is called and your Account object already exists
|
||||
(any new Accounts that connect will see them though). To update yourself you need to make sure to
|
||||
re-fire the hook on all the Accounts you have already created. Here is an example of how to do this
|
||||
using <code class="docutils literal notranslate"><span class="pre">py</span></code>:</p>
|
||||
<p>Reload the server with <code class="docutils literal notranslate"><span class="pre">reload</span></code>.</p>
|
||||
<p>… However, if you use <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">*self</span></code> (the asterisk makes you examine your Account object rather than your Character), you won’t see your new Attributes yet. This is because <code class="docutils literal notranslate"><span class="pre">at_account_creation</span></code> is only called the very <em>first</em> time the Account is called and your Account object already exists (any new Accounts that connect will see them though). To update yourself you need to make sure to re-fire the hook on all the Accounts you have already created. Here is an example of how to do this using <code class="docutils literal notranslate"><span class="pre">py</span></code>:</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">py</span> <span class="pre">[account.at_account_creation()</span> <span class="pre">for</span> <span class="pre">account</span> <span class="pre">in</span> <span class="pre">evennia.managers.accounts.all()]</span></code></p>
|
||||
<p>You should now see the Attributes on yourself.</p>
|
||||
<blockquote>
|
||||
<div><p>If you wanted Evennia to default to a completely <em>different</em> Account class located elsewhere, you
|
||||
must point Evennia to it. Add <code class="docutils literal notranslate"><span class="pre">BASE_ACCOUNT_TYPECLASS</span></code> to your settings file, and give the python
|
||||
path to your custom class as its value. By default this points to <code class="docutils literal notranslate"><span class="pre">typeclasses.accounts.Account</span></code>,
|
||||
the empty template we used above.</p>
|
||||
<div><p>If you wanted Evennia to default to a completely <em>different</em> Account class located elsewhere, you > must point Evennia to it. Add <code class="docutils literal notranslate"><span class="pre">BASE_ACCOUNT_TYPECLASS</span></code> to your settings file, and give the python path to your custom class as its value. By default this points to <code class="docutils literal notranslate"><span class="pre">typeclasses.accounts.Account</span></code>, the empty template we used above.</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="properties-on-accounts">
|
||||
<h2>Properties on Accounts<a class="headerlink" href="#properties-on-accounts" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Beyond those properties assigned to all typeclassed objects (see <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a>), the
|
||||
Account also has the following custom properties:</p>
|
||||
<p>Beyond those properties assigned to all typeclassed objects (see <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a>), the Account also has the following custom properties:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">user</span></code> - a unique link to a <code class="docutils literal notranslate"><span class="pre">User</span></code> Django object, representing the logged-in user.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">obj</span></code> - an alias for <code class="docutils literal notranslate"><span class="pre">character</span></code>.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">name</span></code> - an alias for <code class="docutils literal notranslate"><span class="pre">user.username</span></code></p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">sessions</span></code> - an instance of
|
||||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.objects.objects#objectsessionhandler">ObjectSessionHandler</a>
|
||||
managing all connected Sessions (physical connections) this object listens to (Note: In older
|
||||
versions of Evennia, this was a list). The so-called <code class="docutils literal notranslate"><span class="pre">session-id</span></code> (used in many places) is found
|
||||
as
|
||||
a property <code class="docutils literal notranslate"><span class="pre">sessid</span></code> on each Session instance.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">sessions</span></code> - an instance of <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.objects.objects#objectsessionhandler">ObjectSessionHandler</a> managing all connected Sessions (physical connections) this object listens to (Note: In older versions of Evennia, this was a list). The so-called <code class="docutils literal notranslate"><span class="pre">session-id</span></code> (used in many places) is found as a property <code class="docutils literal notranslate"><span class="pre">sessid</span></code> on each Session instance.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">is_superuser</span></code> (bool: True/False) - if this account is a superuser.</p></li>
|
||||
</ul>
|
||||
<p>Special handlers:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">cmdset</span></code> - This holds all the current <a class="reference internal" href="Commands.html"><span class="doc std std-doc">Commands</span></a> of this Account. By default these are
|
||||
the commands found in the cmdset defined by <code class="docutils literal notranslate"><span class="pre">settings.CMDSET_ACCOUNT</span></code>.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">nicks</span></code> - This stores and handles <a class="reference internal" href="Nicks.html"><span class="doc std std-doc">Nicks</span></a>, in the same way as nicks it works on Objects.
|
||||
For Accounts, nicks are primarily used to store custom aliases for
|
||||
<a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a>.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">nicks</span></code> - This stores and handles <a class="reference internal" href="Nicks.html"><span class="doc std std-doc">Nicks</span></a>, in the same way as nicks it works on Objects. For Accounts, nicks are primarily used to store custom aliases for <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a>.</p></li>
|
||||
</ul>
|
||||
<p>Selection of special methods (see <code class="docutils literal notranslate"><span class="pre">evennia.DefaultAccount</span></code> for details):</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">get_puppet</span></code> - get a currently puppeted object connected to the Account and a given session id, if
|
||||
any.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">get_puppet</span></code> - get a currently puppeted object connected to the Account and a given session id, if any.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">puppet_object</span></code> - connect a session to a puppetable Object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">unpuppet_object</span></code> - disconnect a session from a puppetable Object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">msg</span></code> - send text to the Account</p></li>
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Accounts.html">Accounts</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Accounts.html#how-to-create-your-own-account-types">How to create your own Account types</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Accounts.html#how-to-customize-your-own-account-types">How to customize your own Account types</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Accounts.html#properties-on-accounts">Properties on Accounts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -114,22 +114,50 @@
|
|||
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="objects">
|
||||
<h1>Objects<a class="headerlink" href="#objects" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>┌──────┐ │ ┌───────┐ ┌───────┐ ┌──────┐
|
||||
│Client├─┼──►│Session├───►│Account├──►│Object│
|
||||
└──────┘ │ └───────┘ └───────┘ └──────┘
|
||||
^
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>All in-game objects in Evennia, be it characters, chairs, monsters, rooms or hand grenades are
|
||||
represented by an Evennia <em>Object</em>. Objects form the core of Evennia and is probably what you’ll
|
||||
spend most time working with. Objects are <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclassed</span></a> entities.</p>
|
||||
<p>An Evennia Object is, by definition, a Python class that includes
|
||||
<a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">evennia.objects.objects.DefaultObject</span></a> among its
|
||||
parents. Evennia defines several subclasses of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>:</p>
|
||||
<p>An Evennia Object is, by definition, a Python class that includes <a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">evennia.objects.objects.DefaultObject</span></a> among its parents. Evennia defines several subclasses of <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code> in the following inheritance tree:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> ┌────────────┐
|
||||
Evennia│ │ObjectParent│
|
||||
library│ └──────▲─────┘
|
||||
│ │
|
||||
┌─────────────┐ │ ┌──────┐ │
|
||||
│DefaultObject◄────────────────────┼────┤Object├──────┤
|
||||
└──────▲──────┘ │ └──────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────┐ │ ┌─────────┐ │
|
||||
├────────┤DefaultCharacter◄─┼────┤Character├───┤
|
||||
│ └────────────────┘ │ └─────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────┐ │ ┌────┐ │
|
||||
├────────┤DefaultRoom ◄─┼────┤Room├────────┤
|
||||
│ └────────────────┘ │ └────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────┐ │ ┌────┐ │
|
||||
└────────┤DefaultExit ◄─┼────┤Exit├────────┘
|
||||
└────────────────┘ │ └────┘
|
||||
│
|
||||
│Game-dir
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here, arrows indicate inheritance and point from-child-to-parent.</p>
|
||||
<p>So, for example <code class="docutils literal notranslate"><span class="pre">DefaultObjet</span></code> is a child of <code class="docutils literal notranslate"><span class="pre">DefaultCharacter</span></code> (in the Evennia library), which is a parent of <code class="docutils literal notranslate"><span class="pre">Character</span></code> (in the game dir). The class in the game-dir is the one you should modify for your game.</p>
|
||||
<blockquote>
|
||||
<div><p>Note the <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> class. This is an empty mix-in that all classes in the game-dir inherits from. It’s where you put things you want <em>all</em> these classes to have.</p>
|
||||
</div></blockquote>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultCharacter" title="evennia.objects.objects.DefaultCharacter"><span class="xref myst py py-class">evennia.objects.objects.DefaultCharacter</span></a> -
|
||||
the normal in-game Character, controlled by a player.</p></li>
|
||||
<li><p><a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultCharacter" title="evennia.objects.objects.DefaultCharacter"><span class="xref myst py py-class">evennia.objects.objects.DefaultCharacter</span></a> - the normal in-game Character, controlled by a player.</p></li>
|
||||
<li><p><a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultRoom" title="evennia.objects.objects.DefaultRoom"><span class="xref myst py py-class">evennia.objects.objects.DefaultRoom</span></a> - a location in the game world.</p></li>
|
||||
<li><p><a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultExit" title="evennia.objects.objects.DefaultExit"><span class="xref myst py py-class">evennia.objects.objects.DefaultExit</span></a> - an entity that (usually) sits
|
||||
in a room and represents a one-way connection to another location.</p></li>
|
||||
<li><p><a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultExit" title="evennia.objects.objects.DefaultExit"><span class="xref myst py py-class">evennia.objects.objects.DefaultExit</span></a> - an entity that in a location (usually a Room). It represents a one-way connection to another location.</p></li>
|
||||
</ul>
|
||||
<p>You will usually not use the <code class="docutils literal notranslate"><span class="pre">Default*</span></code> parents themselves. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/</span></code> there are
|
||||
convenient subclasses to use. They are empty, and thus identical to
|
||||
the defaults. Tweaking them is one of the main ways to customize you game!</p>
|
||||
<p>Here are the import paths for the relevant child classes in the game dir</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">mygame.typeclasses.objects.Object</span></code> (inherits from <code class="docutils literal notranslate"><span class="pre">DefaultObject</span></code>)</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">mygame.typeclasses.characters.Character</span></code> (inherits from <code class="docutils literal notranslate"><span class="pre">DefaultCharacter</span></code>)</p></li>
|
||||
|
|
@ -138,11 +166,8 @@ the defaults. Tweaking them is one of the main ways to customize you game!</p>
|
|||
</ul>
|
||||
<section id="how-to-create-your-own-object-types">
|
||||
<h2>How to create your own object types<a class="headerlink" href="#how-to-create-your-own-object-types" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can easily add your own in-game behavior by either modifying one of the typeclasses in
|
||||
your game dir or by inheriting from them.</p>
|
||||
<p>You can put your new typeclass directly in the relevant parent
|
||||
module, or you could organize your code in some other way. Here we assume we make a new module
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/flowers.py</span></code>:</p>
|
||||
<p>You can easily add your own in-game behavior by either modifying one of the typeclasses in your game dir or by inheriting from them.</p>
|
||||
<p>You can put your new typeclass directly in the relevant module, or you could organize your code in some other way. Here we assume we make a new module <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/flowers.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="c1"># mygame/typeclasses/flowers.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">typeclasses.objects</span> <span class="kn">import</span> <span class="n">Object</span>
|
||||
|
|
@ -160,7 +185,7 @@ module, or you could organize your code in some other way. Here we assume we mak
|
|||
</div>
|
||||
<p>Now you just need to point to the class <em>Rose</em> with the <code class="docutils literal notranslate"><span class="pre">create</span></code> command
|
||||
to make a new rose:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> @create/drop MyRose:flowers.Rose
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> create/drop MyRose:flowers.Rose
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>What the <code class="docutils literal notranslate"><span class="pre">create</span></code> command actually <em>does</em> is to use the <a class="reference internal" href="../api/evennia.utils.create.html#evennia.utils.create.create_object" title="evennia.utils.create.create_object"><span class="xref myst py py-func">evennia.create_object</span></a>
|
||||
|
|
@ -181,10 +206,8 @@ will usually want to change this at build time (using the <code class="docutils
|
|||
<section id="adding-common-functionality">
|
||||
<h2>Adding common functionality<a class="headerlink" href="#adding-common-functionality" title="Permalink to this headline">¶</a></h2>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">Object</span></code>, <code class="docutils literal notranslate"><span class="pre">Character</span></code>, <code class="docutils literal notranslate"><span class="pre">Room</span></code> and <code class="docutils literal notranslate"><span class="pre">Exit</span></code> also inherit from <code class="docutils literal notranslate"><span class="pre">mygame.typeclasses.objects.ObjectParent</span></code>.
|
||||
This is an empty ‘mixin’ class. Optionally, you can modify this class if you want to easily add some <em>common</em> functionality to all
|
||||
your Objects, Characters, Rooms and Exits at once. You can still customize each subclass separately (see the Python
|
||||
docs on <a class="reference external" href="https://docs.python.org/3/tutorial/classes.html#multiple-inheritance">multiple inheritance</a> for details).</p>
|
||||
<p>For example:</p>
|
||||
This is an empty ‘mixin’ class. Optionally, you can modify this class if you want to easily add some <em>common</em> functionality to all your Objects, Characters, Rooms and Exits at once. You can still customize each subclass separately (see the Python docs on <a class="reference external" href="https://docs.python.org/3/tutorial/classes.html#multiple-inheritance">multiple inheritance</a> for details).</p>
|
||||
<p>Here is an example:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/typeclasses/objects.py</span>
|
||||
<span class="c1"># ... </span>
|
||||
|
||||
|
|
@ -194,137 +217,65 @@ docs on <a class="reference external" href="https://docs.python.org/3/tutorial/c
|
|||
<span class="k">def</span> <span class="nf">at_pre_get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">getter</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="c1"># make all entities by default un-pickable</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultObject</span><span class="p">):</span>
|
||||
<span class="c1"># replaces at_pre_get with its own</span>
|
||||
<span class="k">def</span> <span class="nf">at_pre_get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">getter</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="kc">True</span>
|
||||
|
||||
<span class="c1"># each in their respective modules ...</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Character</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># will inherit at_pre_get from ObjectParent</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Exit</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultExit</span><span class="p">):</span>
|
||||
<span class="c1"># Overrides and uses the DefaultExit version of at_pre_get instead</span>
|
||||
<span class="k">def</span> <span class="nf">at_pre_get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">getter</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">DefaultExit</span><span class="o">.</span><span class="n">at_pre_get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">getter</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now all of <code class="docutils literal notranslate"><span class="pre">Object</span></code>, <code class="docutils literal notranslate"><span class="pre">Exit</span></code>. <code class="docutils literal notranslate"><span class="pre">Room</span></code> and <code class="docutils literal notranslate"><span class="pre">Character</span></code> default to not being able to be picked up using the <code class="docutils literal notranslate"><span class="pre">get</span></code> command.</p>
|
||||
</section>
|
||||
<section id="properties-and-functions-on-objects">
|
||||
<h2>Properties and functions on Objects<a class="headerlink" href="#properties-and-functions-on-objects" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Beyond the properties assigned to all <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">typeclassed</span></a> objects (see that page for a list
|
||||
of those), the Object also has the following custom properties:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">aliases</span></code> - a handler that allows you to add and remove aliases from this object. Use
|
||||
<code class="docutils literal notranslate"><span class="pre">aliases.add()</span></code> to add a new alias and <code class="docutils literal notranslate"><span class="pre">aliases.remove()</span></code> to remove one.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">aliases</span></code> - a handler that allows you to add and remove aliases from this object. Use <code class="docutils literal notranslate"><span class="pre">aliases.add()</span></code> to add a new alias and <code class="docutils literal notranslate"><span class="pre">aliases.remove()</span></code> to remove one.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">location</span></code> - a reference to the object currently containing this object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">home</span></code> is a backup location. The main motivation is to have a safe place to move the object to if
|
||||
its <code class="docutils literal notranslate"><span class="pre">location</span></code> is destroyed. All objects should usually have a home location for safety.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">destination</span></code> - this holds a reference to another object this object links to in some way. Its
|
||||
main use is for <a class="reference internal" href="#exits"><span class="std std-doc">Exits</span></a>, it’s otherwise usually unset.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">nicks</span></code> - as opposed to aliases, a <a class="reference internal" href="Nicks.html"><span class="doc std std-doc">Nick</span></a> holds a convenient nickname replacement for a
|
||||
real name, word or sequence, only valid for this object. This mainly makes sense if the Object is
|
||||
used as a game character - it can then store briefer shorts, example so as to quickly reference game
|
||||
commands or other characters. Use nicks.add(alias, realname) to add a new one.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - this holds a reference to a connected <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> controlling this object (if
|
||||
any). Note that this is set also if the controlling account is <em>not</em> currently online - to test if
|
||||
an account is online, use the <code class="docutils literal notranslate"><span class="pre">has_account</span></code> property instead.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">sessions</span></code> - if <code class="docutils literal notranslate"><span class="pre">account</span></code> field is set <em>and the account is online</em>, this is a list of all active
|
||||
sessions (server connections) to contact them through (it may be more than one if multiple
|
||||
connections are allowed in settings).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">has_account</span></code> - a shorthand for checking if an <em>online</em> account is currently connected to this
|
||||
object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">contents</span></code> - this returns a list referencing all objects ‘inside’ this object (i,e. which has this
|
||||
object set as their <code class="docutils literal notranslate"><span class="pre">location</span></code>).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">exits</span></code> - this returns all objects inside this object that are <em>Exits</em>, that is, has the
|
||||
<code class="docutils literal notranslate"><span class="pre">destination</span></code> property set.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">home</span></code> is a backup location. The main motivation is to have a safe place to move the object to if its <code class="docutils literal notranslate"><span class="pre">location</span></code> is destroyed. All objects should usually have a home location for safety.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">destination</span></code> - this holds a reference to another object this object links to in some way. Its main use is for <a class="reference internal" href="#exits"><span class="std std-doc">Exits</span></a>, it’s otherwise usually unset.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">nicks</span></code> - as opposed to aliases, a <a class="reference internal" href="Nicks.html"><span class="doc std std-doc">Nick</span></a> holds a convenient nickname replacement for a real name, word or sequence, only valid for this object. This mainly makes sense if the Object is used as a game character - it can then store briefer shorts, example so as to quickly reference game commands or other characters. Use nicks.add(alias, realname) to add a new one.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">account</span></code> - this holds a reference to a connected <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> controlling this object (if any). Note that this is set also if the controlling account is <em>not</em> currently online - to test if an account is online, use the <code class="docutils literal notranslate"><span class="pre">has_account</span></code> property instead.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">sessions</span></code> - if <code class="docutils literal notranslate"><span class="pre">account</span></code> field is set <em>and the account is online</em>, this is a list of all active sessions (server connections) to contact them through (it may be more than one if multiple connections are allowed in settings).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">has_account</span></code> - a shorthand for checking if an <em>online</em> account is currently connected to this object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">contents</span></code> - this returns a list referencing all objects ‘inside’ this object (i,e. which has this object set as their <code class="docutils literal notranslate"><span class="pre">location</span></code>).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">exits</span></code> - this returns all objects inside this object that are <em>Exits</em>, that is, has the <code class="docutils literal notranslate"><span class="pre">destination</span></code> property set.</p></li>
|
||||
</ul>
|
||||
<p>The last two properties are special:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">cmdset</span></code> - this is a handler that stores all <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">command sets</span></a> defined on the
|
||||
object (if any).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">cmdset</span></code> - this is a handler that stores all <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">command sets</span></a> defined on the object (if any).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">scripts</span></code> - this is a handler that manages <a class="reference internal" href="Scripts.html"><span class="doc std std-doc">Scripts</span></a> attached to the object (if any).</p></li>
|
||||
</ul>
|
||||
<p>The Object also has a host of useful utility functions. See the function headers in
|
||||
<code class="docutils literal notranslate"><span class="pre">src/objects/objects.py</span></code> for their arguments and more details.</p>
|
||||
<p>The Object also has a host of useful utility functions. See the function headers in <code class="docutils literal notranslate"><span class="pre">src/objects/objects.py</span></code> for their arguments and more details.</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">msg()</span></code> - this function is used to send messages from the server to an account connected to this
|
||||
object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">msg()</span></code> - this function is used to send messages from the server to an account connected to this object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">msg_contents()</span></code> - calls <code class="docutils literal notranslate"><span class="pre">msg</span></code> on all objects inside this object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">search()</span></code> - this is a convenient shorthand to search for a specific object, at a given location
|
||||
or globally. It’s mainly useful when defining commands (in which case the object executing the
|
||||
command is named <code class="docutils literal notranslate"><span class="pre">caller</span></code> and one can do <code class="docutils literal notranslate"><span class="pre">caller.search()</span></code> to find objects in the room to operate
|
||||
on).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">search()</span></code> - this is a convenient shorthand to search for a specific object, at a given location or globally. It’s mainly useful when defining commands (in which case the object executing the command is named <code class="docutils literal notranslate"><span class="pre">caller</span></code> and one can do <code class="docutils literal notranslate"><span class="pre">caller.search()</span></code> to find objects in the room to operate on).</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">execute_cmd()</span></code> - Lets the object execute the given string as if it was given on the command line.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">move_to</span></code> - perform a full move of this object to a new location. This is the main move method
|
||||
and will call all relevant hooks, do all checks etc.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">move_to</span></code> - perform a full move of this object to a new location. This is the main move method and will call all relevant hooks, do all checks etc.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">clear_exits()</span></code> - will delete all <a class="reference internal" href="#exits"><span class="std std-doc">Exits</span></a> to <em>and</em> from this object.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">clear_contents()</span></code> - this will not delete anything, but rather move all contents (except Exits) to
|
||||
their designated <code class="docutils literal notranslate"><span class="pre">Home</span></code> locations.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">delete()</span></code> - deletes this object, first calling <code class="docutils literal notranslate"><span class="pre">clear_exits()</span></code> and
|
||||
<code class="docutils literal notranslate"><span class="pre">clear_contents()</span></code>.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">clear_contents()</span></code> - this will not delete anything, but rather move all contents (except Exits) to their designated <code class="docutils literal notranslate"><span class="pre">Home</span></code> locations.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">delete()</span></code> - deletes this object, first calling <code class="docutils literal notranslate"><span class="pre">clear_exits()</span></code> and <code class="docutils literal notranslate"><span class="pre">clear_contents()</span></code>.</p></li>
|
||||
</ul>
|
||||
<p>The Object Typeclass defines many more <em>hook methods</em> beyond <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>. Evennia calls
|
||||
these hooks at various points. When implementing your custom objects, you will inherit from the
|
||||
base parent and overload these hooks with your own custom code. See <code class="docutils literal notranslate"><span class="pre">evennia.objects.objects</span></code> for an
|
||||
updated list of all the available hooks or the <a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">API for DefaultObject here</span></a>.</p>
|
||||
<p>The Object Typeclass defines many more <em>hook methods</em> beyond <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code>. Evennia calls these hooks at various points. When implementing your custom objects, you will inherit from the base parent and overload these hooks with your own custom code. See <code class="docutils literal notranslate"><span class="pre">evennia.objects.objects</span></code> for an updated list of all the available hooks or the <a class="reference internal" href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject" title="evennia.objects.objects.DefaultObject"><span class="xref myst py py-class">API for DefaultObject here</span></a>.</p>
|
||||
</section>
|
||||
<section id="subclasses-of-object">
|
||||
<h2>Subclasses of <code class="docutils literal notranslate"><span class="pre">Object</span></code><a class="headerlink" href="#subclasses-of-object" title="Permalink to this headline">¶</a></h2>
|
||||
<p>There are three special subclasses of <em>Object</em> in default Evennia - <em>Characters</em>, <em>Rooms</em> and
|
||||
<em>Exits</em>. The reason they are separated is because these particular object types are fundamental,
|
||||
something you will always need and in some cases requires some extra attention in order to be
|
||||
recognized by the game engine (there is nothing stopping you from redefining them though). In
|
||||
practice they are all pretty similar to the base Object.</p>
|
||||
<p>There are three special subclasses of <em>Object</em> in default Evennia - <em>Characters</em>, <em>Rooms</em> and <em>Exits</em>. The reason they are separated is because these particular object types are fundamental, something you will always need and in some cases requires some extra attention in order to be recognized by the game engine (there is nothing stopping you from redefining them though). In practice they are all pretty similar to the base Object.</p>
|
||||
<section id="characters">
|
||||
<h3>Characters<a class="headerlink" href="#characters" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Characters are objects controlled by <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>. When a new Account
|
||||
logs in to Evennia for the first time, a new <code class="docutils literal notranslate"><span class="pre">Character</span></code> object is created and
|
||||
the Account object is assigned to the <code class="docutils literal notranslate"><span class="pre">account</span></code> attribute. A <code class="docutils literal notranslate"><span class="pre">Character</span></code> object
|
||||
must have a <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Default Commandset</span></a> set on itself at
|
||||
creation, or the account will not be able to issue any commands! If you just
|
||||
inherit your own class from <code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code> and make sure to use
|
||||
<code class="docutils literal notranslate"><span class="pre">super()</span></code> to call the parent methods you should be fine. In
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> is an empty <code class="docutils literal notranslate"><span class="pre">Character</span></code> class ready for you
|
||||
to modify.</p>
|
||||
<p>Characters are objects controlled by <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>. When a new Account logs in to Evennia for the first time, a new <code class="docutils literal notranslate"><span class="pre">Character</span></code> object is created and the Account object is assigned to the <code class="docutils literal notranslate"><span class="pre">account</span></code> attribute. A <code class="docutils literal notranslate"><span class="pre">Character</span></code> object must have a <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">Default Commandset</span></a> set on itself at creation, or the account will not be able to issue any commands! If you just inherit your own class from <code class="docutils literal notranslate"><span class="pre">evennia.DefaultCharacter</span></code> and make sure to use <code class="docutils literal notranslate"><span class="pre">super()</span></code> to call the parent methods you should be fine. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/characters.py</span></code> is an empty <code class="docutils literal notranslate"><span class="pre">Character</span></code> class ready for you to modify.</p>
|
||||
</section>
|
||||
<section id="rooms">
|
||||
<h3>Rooms<a class="headerlink" href="#rooms" title="Permalink to this headline">¶</a></h3>
|
||||
<p><em>Rooms</em> are the root containers of all other objects. The only thing really separating a room from
|
||||
any other object is that they have no <code class="docutils literal notranslate"><span class="pre">location</span></code> of their own and that default commands like <code class="docutils literal notranslate"><span class="pre">@dig</span></code>
|
||||
creates objects of this class - so if you want to expand your rooms with more functionality, just
|
||||
inherit from <code class="docutils literal notranslate"><span class="pre">ev.DefaultRoom</span></code>. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/rooms.py</span></code> is an empty <code class="docutils literal notranslate"><span class="pre">Room</span></code> class ready for
|
||||
you to modify.</p>
|
||||
<p><em>Rooms</em> are the root containers of all other objects. The only thing really separating a room from any other object is that they have no <code class="docutils literal notranslate"><span class="pre">location</span></code> of their own and that default commands like <code class="docutils literal notranslate"><span class="pre">@dig</span></code> creates objects of this class - so if you want to expand your rooms with more functionality, just inherit from <code class="docutils literal notranslate"><span class="pre">ev.DefaultRoom</span></code>. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/rooms.py</span></code> is an empty <code class="docutils literal notranslate"><span class="pre">Room</span></code> class ready for you to modify.</p>
|
||||
</section>
|
||||
<section id="exits">
|
||||
<h3>Exits<a class="headerlink" href="#exits" title="Permalink to this headline">¶</a></h3>
|
||||
<p><em>Exits</em> are objects connecting other objects (usually <em>Rooms</em>) together. An object named <em>North</em> or
|
||||
<em>in</em> might be an exit, as well as <em>door</em>, <em>portal</em> or <em>jump out the window</em>. An exit has two things
|
||||
that separate them from other objects. Firstly, their <em>destination</em> property is set and points to a
|
||||
valid object. This fact makes it easy and fast to locate exits in the database. Secondly, exits
|
||||
define a special <a class="reference internal" href="Commands.html"><span class="doc std std-doc">Transit Command</span></a> on themselves when they are created. This command is
|
||||
named the same as the exit object and will, when called, handle the practicalities of moving the
|
||||
character to the Exits’s <em>destination</em> - this allows you to just enter the name of the exit on its
|
||||
own to move around, just as you would expect.</p>
|
||||
<p>The exit functionality is all defined on the Exit typeclass, so you could in principle completely
|
||||
change how exits work in your game (it’s not recommended though, unless you really know what you are
|
||||
doing). Exits are <a class="reference internal" href="Locks.html"><span class="doc std std-doc">locked</span></a> using an access_type called <em>traverse</em> and also make use of a few
|
||||
hook methods for giving feedback if the traversal fails. See <code class="docutils literal notranslate"><span class="pre">evennia.DefaultExit</span></code> for more info.
|
||||
In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/exits.py</span></code> there is an empty <code class="docutils literal notranslate"><span class="pre">Exit</span></code> class for you to modify.</p>
|
||||
<p><em>Exits</em> are objects connecting other objects (usually <em>Rooms</em>) together. An object named <em>North</em> or <em>in</em> might be an exit, as well as <em>door</em>, <em>portal</em> or <em>jump out the window</em>. An exit has two things that separate them from other objects. Firstly, their <em>destination</em> property is set and points to a valid object. This fact makes it easy and fast to locate exits in the database. Secondly, exits define a special <a class="reference internal" href="Commands.html"><span class="doc std std-doc">Transit Command</span></a> on themselves when they are created. This command is named the same as the exit object and will, when called, handle the practicalities of moving the character to the Exits’s <em>destination</em> - this allows you to just enter the name of the exit on its own to move around, just as you would expect.</p>
|
||||
<p>The exit functionality is all defined on the Exit typeclass, so you could in principle completely change how exits work in your game (it’s not recommended though, unless you really know what you are doing). Exits are <a class="reference internal" href="Locks.html"><span class="doc std std-doc">locked</span></a> using an access_type called <em>traverse</em> and also make use of a few hook methods for giving feedback if the traversal fails. See <code class="docutils literal notranslate"><span class="pre">evennia.DefaultExit</span></code> for more info. In <code class="docutils literal notranslate"><span class="pre">mygame/typeclasses/exits.py</span></code> there is an empty <code class="docutils literal notranslate"><span class="pre">Exit</span></code> class for you to modify.</p>
|
||||
<p>The process of traversing an exit is as follows:</p>
|
||||
<ol class="simple">
|
||||
<li><p>The traversing <code class="docutils literal notranslate"><span class="pre">obj</span></code> sends a command that matches the Exit-command name on the Exit object. The
|
||||
<a class="reference internal" href="Commands.html"><span class="doc std std-doc">cmdhandler</span></a> detects this and triggers the command defined on the Exit. Traversal always
|
||||
involves the “source” (the current location) and the <code class="docutils literal notranslate"><span class="pre">destination</span></code> (this is stored on the Exit
|
||||
object).</p></li>
|
||||
<li><p>The traversing <code class="docutils literal notranslate"><span class="pre">obj</span></code> sends a command that matches the Exit-command name on the Exit object. The <a class="reference internal" href="Commands.html"><span class="doc std std-doc">cmdhandler</span></a> detects this and triggers the command defined on the Exit. Traversal always involves the “source” (the current location) and the <code class="docutils literal notranslate"><span class="pre">destination</span></code> (this is stored on the Exit object).</p></li>
|
||||
<li><p>The Exit command checks the <code class="docutils literal notranslate"><span class="pre">traverse</span></code> lock on the Exit object</p></li>
|
||||
<li><p>The Exit command triggers <code class="docutils literal notranslate"><span class="pre">at_traverse(obj,</span> <span class="pre">destination)</span></code> on the Exit object.</p></li>
|
||||
<li><p>In <code class="docutils literal notranslate"><span class="pre">at_traverse</span></code>, <code class="docutils literal notranslate"><span class="pre">object.move_to(destination)</span></code> is triggered. This triggers the following hooks,
|
||||
in order:</p>
|
||||
<li><p>In <code class="docutils literal notranslate"><span class="pre">at_traverse</span></code>, <code class="docutils literal notranslate"><span class="pre">object.move_to(destination)</span></code> is triggered. This triggers the following hooks, in order:</p>
|
||||
<ol class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">obj.at_pre_move(destination)</span></code> - if this returns False, move is aborted.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">origin.at_pre_leave(obj,</span> <span class="pre">destination)</span></code></p></li>
|
||||
|
|
@ -337,9 +288,7 @@ in order:</p>
|
|||
</li>
|
||||
<li><p>On the Exit object, <code class="docutils literal notranslate"><span class="pre">at_post_traverse(obj,</span> <span class="pre">source)</span></code> is triggered.</p></li>
|
||||
</ol>
|
||||
<p>If the move fails for whatever reason, the Exit will look for an Attribute <code class="docutils literal notranslate"><span class="pre">err_traverse</span></code> on itself
|
||||
and display this as an error message. If this is not found, the Exit will instead call
|
||||
<code class="docutils literal notranslate"><span class="pre">at_failed_traverse(obj)</span></code> on itself.</p>
|
||||
<p>If the move fails for whatever reason, the Exit will look for an Attribute <code class="docutils literal notranslate"><span class="pre">err_traverse</span></code> on itself and display this as an error message. If this is not found, the Exit will instead call <code class="docutils literal notranslate"><span class="pre">at_failed_traverse(obj)</span></code> on itself.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -111,23 +111,17 @@
|
|||
|
||||
<section class="tex2jax_ignore mathjax_ignore" id="sessions">
|
||||
<h1>Sessions<a class="headerlink" href="#sessions" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>┌──────┐ │ ┌───────┐ ┌───────┐ ┌──────┐
|
||||
│Client├─┼──►│Session├───►│Account├──►│Object│
|
||||
└──────┘ │ └───────┘ └───────┘ └──────┘
|
||||
^
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An Evennia <em>Session</em> represents one single established connection to the server. Depending on the
|
||||
Evennia session, it is possible for a person to connect multiple times, for example using different
|
||||
clients in multiple windows. Each such connection is represented by a session object.</p>
|
||||
<p>A session object has its own <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">cmdset</span></a>, usually the “unloggedin” cmdset. This is what
|
||||
is used to show the login screen and to handle commands to create a new account (or
|
||||
<a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> in evennia lingo) read initial help and to log into the game with an existing
|
||||
account. A session object can either be “logged in” or not. Logged in means that the user has
|
||||
authenticated. When this happens the session is associated with an Account object (which is what
|
||||
holds account-centric stuff). The account can then in turn puppet any number of objects/characters.</p>
|
||||
<blockquote>
|
||||
<div><p>Warning: A Session is not <em>persistent</em> - it is not a <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclass</span></a> and has no
|
||||
connection to the database. The Session will go away when a user disconnects and you will lose any
|
||||
custom data on it if the server reloads. The <code class="docutils literal notranslate"><span class="pre">.db</span></code> handler on Sessions is there to present a uniform
|
||||
API (so you can assume <code class="docutils literal notranslate"><span class="pre">.db</span></code> exists even if you don’t know if you receive an Object or a Session),
|
||||
but this is just an alias to <code class="docutils literal notranslate"><span class="pre">.ndb</span></code>. So don’t store any data on Sessions that you can’t afford to
|
||||
lose in a reload. You have been warned.</p>
|
||||
</div></blockquote>
|
||||
<p>A session object has its own <a class="reference internal" href="Command-Sets.html"><span class="doc std std-doc">cmdset</span></a>, usually the “unloggedin” cmdset. This is what is used to show the login screen and to handle commands to create a new account (or <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Account</span></a> in evennia lingo) read initial help and to log into the game with an existing account. A session object can either be “logged in” or not. Logged in means that the user has authenticated. When this happens the session is associated with an Account object (which is what holds account-centric stuff). The account can then in turn puppet any number of objects/characters.</p>
|
||||
<p>A Session is not <em>persistent</em> - it is not a <a class="reference internal" href="Typeclasses.html"><span class="doc std std-doc">Typeclass</span></a> and has no connection to the database. The Session will go away when a user disconnects and you will lose any custom data on it if the server reloads. The <code class="docutils literal notranslate"><span class="pre">.db</span></code> handler on Sessions is there to present a uniform API (so you can assume <code class="docutils literal notranslate"><span class="pre">.db</span></code> exists even if you don’t know if you receive an Object or a Session), but this is just an alias to <code class="docutils literal notranslate"><span class="pre">.ndb</span></code>. So don’t store any data on Sessions that you can’t afford to lose in a reload.</p>
|
||||
<section id="properties-on-sessions">
|
||||
<h2>Properties on Sessions<a class="headerlink" href="#properties-on-sessions" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Here are some important properties available on (Server-)Sessions</p>
|
||||
|
|
@ -154,39 +148,61 @@ last time this session was truly visibly active.</p></li>
|
|||
</section>
|
||||
<section id="multisession-mode">
|
||||
<h2>Multisession mode<a class="headerlink" href="#multisession-mode" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The number of sessions possible to connect to a given account at the same time and how it works is
|
||||
given by the <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span></code> setting:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=0</span></code>: One session per account. When connecting with a new session the old one is
|
||||
disconnected. This is the default mode and emulates many classic mud code bases. In default Evennia,
|
||||
this mode also changes how the <code class="docutils literal notranslate"><span class="pre">create</span> <span class="pre">account</span></code> Command works - it will automatically create a
|
||||
Character with the <em>same name</em> as the Account. When logging in, the login command is also modified
|
||||
to have the player automatically puppet that Character. This makes the distinction between Account
|
||||
and Character minimal from the player’s perspective.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=1</span></code>: Many sessions per account, input/output from/to each session is treated the
|
||||
same. For the player this means they can connect to the game from multiple clients and see the same
|
||||
output in all of them. The result of a command given in one client (that is, through one Session)
|
||||
will be returned to <em>all</em> connected Sessions/clients with no distinction. This mode will have the
|
||||
Session(s) auto-create and puppet a Character in the same way as mode 0.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=2</span></code>: Many sessions per account, one character per session. In this mode,
|
||||
puppeting an Object/Character will link the puppet back only to the particular Session doing the
|
||||
puppeting. That is, input from that Session will make use of the CmdSet of that Object/Character and
|
||||
outgoing messages (such as the result of a <code class="docutils literal notranslate"><span class="pre">look</span></code>) will be passed back only to that puppeting
|
||||
Session. If another Session tries to puppet the same Character, the old Session will automatically
|
||||
un-puppet it. From the player’s perspective, this will mean that they can open separate game clients
|
||||
and play a different Character in each using one game account.
|
||||
This mode will <em>not</em> auto-create a Character and <em>not</em> auto-puppet on login like in modes 0 and 1.
|
||||
Instead it changes how the account-cmdsets’s <code class="docutils literal notranslate"><span class="pre">OOCLook</span></code> command works so as to show a simple
|
||||
‘character select’ menu.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=3</span></code>: Many sessions per account <em>and</em> character. This is the full multi-puppeting
|
||||
mode, where multiple sessions may not only connect to the player account but multiple sessions may
|
||||
also puppet a single character at the same time. From the user’s perspective it means one can open
|
||||
multiple client windows, some for controlling different Characters and some that share a Character’s
|
||||
input/output like in mode 1. This mode otherwise works the same as mode 2.</p></li>
|
||||
<p>The number of sessions possible to connect to a given account at the same time and how it works is given by the <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span></code> setting:</p>
|
||||
<ul>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=0</span></code>: One session per account. When connecting with a new session the old one is disconnected. This is the default mode and emulates many classic mud code bases.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>┌──────┐ │ ┌───────┐ ┌───────┐ ┌─────────┐
|
||||
│Client├─┼──►│Session├───►│Account├──►│Character│
|
||||
└──────┘ │ └───────┘ └───────┘ └─────────┘
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=1</span></code>: Many sessions per account, input/output from/to each session is treated the same. For the player this means they can connect to the game from multiple clients and see the same output in all of them. The result of a command given in one client (that is, through one Session) will be returned to <em>all</em> connected Sessions/clients with no distinction.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> │
|
||||
┌──────┐ │ ┌───────┐
|
||||
│Client├─┼──►│Session├──┐
|
||||
└──────┘ │ └───────┘ └──►┌───────┐ ┌─────────┐
|
||||
│ │Account├──►│Character│
|
||||
┌──────┐ │ ┌───────┐ ┌──►└───────┘ └─────────┘
|
||||
│Client├─┼──►│Session├──┘
|
||||
└──────┘ │ └───────┘
|
||||
│
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=2</span></code>: Many sessions per account, one character per session. In this mode, puppeting an Object/Character will link the puppet back only to the particular Session doing the puppeting. That is, input from that Session will make use of the CmdSet of that Object/Character and outgoing messages (such as the result of a <code class="docutils literal notranslate"><span class="pre">look</span></code>) will be passed back only to that puppeting Session. If another Session tries to puppet the same Character, the old Session will automatically un-puppet it. From the player’s perspective, this will mean that they can open separate game clients and play a different Character in each using one game account.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> │ ┌───────┐
|
||||
┌──────┐ │ ┌───────┐ │Account│ ┌─────────┐
|
||||
│Client├─┼──►│Session├──┐ │ │ ┌►│Character│
|
||||
└──────┘ │ └───────┘ └──┼───────┼──┘ └─────────┘
|
||||
│ │ │
|
||||
┌──────┐ │ ┌───────┐ ┌──┼───────┼──┐ ┌─────────┐
|
||||
│Client├─┼──►│Session├──┘ │ │ └►│Character│
|
||||
└──────┘ │ └───────┘ │ │ └─────────┘
|
||||
│ └───────┘
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE=3</span></code>: Many sessions per account <em>and</em> character. This is the full multi-puppeting mode, where multiple sessions may not only connect to the player account but multiple sessions may also puppet a single character at the same time. From the user’s perspective it means one can open multiple client windows, some for controlling different Characters and some that share a Character’s input/output like in mode 1. This mode otherwise works the same as mode 2.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> │ ┌───────┐
|
||||
┌──────┐ │ ┌───────┐ │Account│ ┌─────────┐
|
||||
│Client├─┼──►│Session├──┐ │ │ ┌►│Character│
|
||||
└──────┘ │ └───────┘ └──┼───────┼──┘ └─────────┘
|
||||
│ │ │
|
||||
┌──────┐ │ ┌───────┐ ┌──┼───────┼──┐
|
||||
│Client├─┼──►│Session├──┘ │ │ └►┌─────────┐
|
||||
└──────┘ │ └───────┘ │ │ │Character│
|
||||
│ │ │ ┌►└─────────┘
|
||||
┌──────┐ │ ┌───────┐ ┌──┼───────┼──┘ ▼
|
||||
│Client├─┼──►│Session├──┘ │ │
|
||||
└──────┘ │ └───────┘ └───────┘
|
||||
│
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<div><p>Note that even if multiple Sessions puppet one Character, there is only ever one instance of that
|
||||
Character.</p>
|
||||
<div><p>Note that even if multiple Sessions puppet one Character, there is only ever one instance of that Character.</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="returning-data-to-the-session">
|
||||
|
|
|
|||
|
|
@ -118,10 +118,7 @@
|
|||
<p><em>Typeclasses</em> form the core of Evennia’s data storage. It allows Evennia to represent any number of
|
||||
different game entities as Python classes, without having to modify the database schema for every
|
||||
new type.</p>
|
||||
<p>In Evennia the most important game entities, <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>, <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Objects</span></a>,
|
||||
<a class="reference internal" href="Scripts.html"><span class="doc std std-doc">Scripts</span></a> and <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a> are all Python classes inheriting, at
|
||||
varying distance, from <code class="docutils literal notranslate"><span class="pre">evennia.typeclasses.models.TypedObject</span></code>. In the documentation we refer to
|
||||
these objects as being “typeclassed” or even “being a typeclass”.</p>
|
||||
<p>In Evennia the most important game entities, <a class="reference internal" href="Accounts.html"><span class="doc std std-doc">Accounts</span></a>, <a class="reference internal" href="Objects.html"><span class="doc std std-doc">Objects</span></a>, <a class="reference internal" href="Scripts.html"><span class="doc std std-doc">Scripts</span></a> and <a class="reference internal" href="Channels.html"><span class="doc std std-doc">Channels</span></a> are all Python classes inheriting, at varying distance, from <code class="docutils literal notranslate"><span class="pre">evennia.typeclasses.models.TypedObject</span></code>. In the documentation we refer to these objects as being “typeclassed” or even “being a typeclass”.</p>
|
||||
<p>This is how the inheritance looks for the typeclasses in Evennia:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">TypedObject</span>
|
||||
<span class="n">_________________</span><span class="o">|</span><span class="n">_________________________________</span>
|
||||
|
|
@ -175,12 +172,7 @@ default library):</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p>A typeclass’ <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method should normally not be overloaded. This has mostly to do with the
|
||||
fact that the <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method is not called in a predictable way. Instead Evennia suggest you use
|
||||
the <code class="docutils literal notranslate"><span class="pre">at_*_creation</span></code> hooks (like <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> for Objects) for setting things the very first
|
||||
time the typeclass is saved to the database or the <code class="docutils literal notranslate"><span class="pre">at_init</span></code> hook which is called every time the
|
||||
object is cached to memory. If you know what you are doing and want to use <code class="docutils literal notranslate"><span class="pre">__init__</span></code>, it <em>must</em>
|
||||
both accept arbitrary keyword arguments and use <code class="docutils literal notranslate"><span class="pre">super</span></code> to call its parent::</p>
|
||||
<li><p>A typeclass’ <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method should normally not be overloaded. This has mostly to do with the fact that the <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method is not called in a predictable way. Instead Evennia suggest you use the <code class="docutils literal notranslate"><span class="pre">at_*_creation</span></code> hooks (like <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> for Objects) for setting things the very first time the typeclass is saved to the database or the <code class="docutils literal notranslate"><span class="pre">at_init</span></code> hook which is called every time the object is cached to memory. If you know what you are doing and want to use <code class="docutils literal notranslate"><span class="pre">__init__</span></code>, it <em>must</em> both accept arbitrary keyword arguments and use <code class="docutils literal notranslate"><span class="pre">super</span></code> to call its parent:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="c1"># my content</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
|
|
@ -194,8 +186,7 @@ treat it as such.</p>
|
|||
</section>
|
||||
<section id="creating-a-new-typeclass">
|
||||
<h2>Creating a new typeclass<a class="headerlink" href="#creating-a-new-typeclass" title="Permalink to this headline">¶</a></h2>
|
||||
<p>It’s easy to work with Typeclasses. Either you use an existing typeclass or you create a new Python
|
||||
class inheriting from an existing typeclass. Here is an example of creating a new type of Object:</p>
|
||||
<p>It’s easy to work with Typeclasses. Either you use an existing typeclass or you create a new Python class inheriting from an existing typeclass. Here is an example of creating a new type of Object:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Furniture</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
|
||||
|
|
@ -334,8 +325,7 @@ you will always query all children on the database model.</p>
|
|||
<section id="updating-existing-typeclass-instances">
|
||||
<h2>Updating existing typeclass instances<a class="headerlink" href="#updating-existing-typeclass-instances" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you already have created instances of Typeclasses, you can modify the <em>Python code</em> at any time -
|
||||
due to how Python inheritance works your changes will automatically be applied to all children once
|
||||
you have reloaded the server.</p>
|
||||
due to how Python inheritance works your changes will automatically be applied to all children once you have reloaded the server.</p>
|
||||
<p>However, database-saved data, like <code class="docutils literal notranslate"><span class="pre">db_*</span></code> fields, <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a>, <a class="reference internal" href="Tags.html"><span class="doc std std-doc">Tags</span></a> etc, are
|
||||
not themselves embedded into the class and will <em>not</em> be updated automatically. This you need to
|
||||
manage yourself, by searching for all relevant objects and updating or adding the data:</p>
|
||||
|
|
@ -361,7 +351,7 @@ it all in-game using <code class="docutils literal notranslate"><span class="pre
|
|||
single line using <code class="docutils literal notranslate"><span class="pre">;</span></code> and <a class="reference external" href="http://www.secnetix.de/olli/Python/list_comprehensions.hawk">list
|
||||
comprehensions</a>, like this (ignore the
|
||||
line break, that’s only for readability in the wiki):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@py</span> <span class="kn">from</span> <span class="nn">typeclasses.furniture</span> <span class="kn">import</span> <span class="n">Furniture</span><span class="p">;</span>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">py</span> <span class="kn">from</span> <span class="nn">typeclasses.furniture</span> <span class="kn">import</span> <span class="n">Furniture</span><span class="p">;</span>
|
||||
<span class="p">[</span><span class="n">obj</span><span class="o">.</span><span class="n">at_object_creation</span><span class="p">()</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">Furniture</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worth</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -370,59 +360,35 @@ retroactively update objects more than necessary.</p>
|
|||
</section>
|
||||
<section id="swap-typeclass">
|
||||
<h2>Swap typeclass<a class="headerlink" href="#swap-typeclass" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you want to swap an already existing typeclass, there are two ways to do so: From in-game and via
|
||||
code. From inside the game you can use the default <code class="docutils literal notranslate"><span class="pre">@typeclass</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@typeclass</span> <span class="n">objname</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">typeclass</span>
|
||||
<p>If you want to swap an already existing typeclass, there are two ways to do so: From in-game and via code. From inside the game you can use the default <code class="docutils literal notranslate"><span class="pre">@typeclass</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">typeclass</span> <span class="n">objname</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">typeclass</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>There are two important switches to this command:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">/reset</span></code> - This will purge all existing Attributes on the object and re-run the creation hook
|
||||
(like <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> for Objects). This assures you get an object which is purely of this new
|
||||
class.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">/force</span></code> - This is required if you are changing the class to be <em>the same</em> class the object
|
||||
already has - it’s a safety check to avoid user errors. This is usually used together with <code class="docutils literal notranslate"><span class="pre">/reset</span></code>
|
||||
to re-run the creation hook on an existing class.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">/reset</span></code> - This will purge all existing Attributes on the object and re-run the creation hook (like <code class="docutils literal notranslate"><span class="pre">at_object_creation</span></code> for Objects). This assures you get an object which is purely of this new class.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">/force</span></code> - This is required if you are changing the class to be <em>the same</em> class the object already has - it’s a safety check to avoid user errors. This is usually used together with <code class="docutils literal notranslate"><span class="pre">/reset</span></code> to re-run the creation hook on an existing class.</p></li>
|
||||
</ul>
|
||||
<p>In code you instead use the <code class="docutils literal notranslate"><span class="pre">swap_typeclass</span></code> method which you can find on all typeclassed entities:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">obj_to_change</span><span class="o">.</span><span class="n">swap_typeclass</span><span class="p">(</span><span class="n">new_typeclass_path</span><span class="p">,</span> <span class="n">clean_attributes</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
||||
<span class="n">run_start_hooks</span><span class="o">=</span><span class="s2">"all"</span><span class="p">,</span> <span class="n">no_default</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">clean_cmdsets</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The arguments to this method are described <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.typeclasses.models#typedobjectswap_typeclass">in the API docs
|
||||
here</a>.</p>
|
||||
<p>The arguments to this method are described <a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.typeclasses.models#typedobjectswap_typeclass">in the API docs here</a>.</p>
|
||||
</section>
|
||||
<section id="how-typeclasses-actually-work">
|
||||
<h2>How typeclasses actually work<a class="headerlink" href="#how-typeclasses-actually-work" title="Permalink to this headline">¶</a></h2>
|
||||
<p><em>This is considered an advanced section.</em></p>
|
||||
<p>Technically, typeclasses are <a class="reference external" href="https://docs.djangoproject.com/en/1.7/topics/db/models/#proxy-models">Django proxy
|
||||
models</a>. The only database
|
||||
models that are “real” in the typeclass system (that is, are represented by actual tables in the
|
||||
database) are <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code>, <code class="docutils literal notranslate"><span class="pre">ObjectDB</span></code>, <code class="docutils literal notranslate"><span class="pre">ScriptDB</span></code> and <code class="docutils literal notranslate"><span class="pre">ChannelDB</span></code> (there are also
|
||||
<a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a> and <a class="reference internal" href="Tags.html"><span class="doc std std-doc">Tags</span></a> but they are not typeclasses themselves). All the
|
||||
subclasses of them are “proxies”, extending them with Python code without actually modifying the
|
||||
database layout.</p>
|
||||
<p>Evennia modifies Django’s proxy model in various ways to allow them to work without any boiler plate
|
||||
(for example you don’t need to set the Django “proxy” property in the model <code class="docutils literal notranslate"><span class="pre">Meta</span></code> subclass, Evennia
|
||||
handles this for you using metaclasses). Evennia also makes sure you can query subclasses as well as
|
||||
patches django to allow multiple inheritance from the same base class.</p>
|
||||
<p>Technically, typeclasses are <a class="reference external" href="https://docs.djangoproject.com/en/1.7/topics/db/models/#proxy-models">Django proxy models</a>. The only database
|
||||
models that are “real” in the typeclass system (that is, are represented by actual tables in the database) are <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code>, <code class="docutils literal notranslate"><span class="pre">ObjectDB</span></code>, <code class="docutils literal notranslate"><span class="pre">ScriptDB</span></code> and <code class="docutils literal notranslate"><span class="pre">ChannelDB</span></code> (there are also <a class="reference internal" href="Attributes.html"><span class="doc std std-doc">Attributes</span></a> and <a class="reference internal" href="Tags.html"><span class="doc std std-doc">Tags</span></a> but they are not typeclasses themselves). All the subclasses of them are “proxies”, extending them with Python code without actually modifying the database layout.</p>
|
||||
<p>Evennia modifies Django’s proxy model in various ways to allow them to work without any boiler plate (for example you don’t need to set the Django “proxy” property in the model <code class="docutils literal notranslate"><span class="pre">Meta</span></code> subclass, Evennia handles this for you using metaclasses). Evennia also makes sure you can query subclasses as well as patches django to allow multiple inheritance from the same base class.</p>
|
||||
</section>
|
||||
<section id="caveats">
|
||||
<h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Evennia uses the <em>idmapper</em> to cache its typeclasses (Django proxy models) in memory. The idmapper
|
||||
allows things like on-object handlers and properties to be stored on typeclass instances and to not
|
||||
get lost as long as the server is running (they will only be cleared on a Server reload). Django
|
||||
does not work like this by default; by default every time you search for an object in the database
|
||||
you’ll get a <em>different</em> instance of that object back and anything you stored on it that was not in
|
||||
the database would be lost. The bottom line is that Evennia’s Typeclass instances subside in memory
|
||||
a lot longer than vanilla Django model instance do.</p>
|
||||
<p>Evennia uses the <em>idmapper</em> to cache its typeclasses (Django proxy models) in memory. The idmapper allows things like on-object handlers and properties to be stored on typeclass instances and to not get lost as long as the server is running (they will only be cleared on a Server reload). Django does not work like this by default; by default every time you search for an object in the database you’ll get a <em>different</em> instance of that object back and anything you stored on it that was not in the database would be lost. The bottom line is that Evennia’s Typeclass instances subside in memory a lot longer than vanilla Django model instance do.</p>
|
||||
<p>There is one caveat to consider with this, and that relates to [making your own models](New-
|
||||
Models): Foreign relationships to typeclasses are cached by Django and that means that if you were
|
||||
to change an object in a foreign relationship via some other means than via that relationship, the
|
||||
object seeing the relationship may not reliably update but will still see its old cached version.
|
||||
Due to typeclasses staying so long in memory, stale caches of such relationships could be more
|
||||
visible than common in Django. See the <a class="reference external" href="https://github.com/evennia/evennia/issues/1098">closed issue #1098 and its
|
||||
comments</a> for examples and solutions.</p>
|
||||
Models): Foreign relationships to typeclasses are cached by Django and that means that if you were to change an object in a foreign relationship via some other means than via that relationship, the object seeing the relationship may not reliably update but will still see its old cached version. Due to typeclasses staying so long in memory, stale caches of such relationships could be more
|
||||
visible than common in Django. See the <a class="reference external" href="https://github.com/evennia/evennia/issues/1098">closed issue #1098 and its comments</a> for examples and solutions.</p>
|
||||
</section>
|
||||
<section id="will-i-run-out-of-dbrefs">
|
||||
<h2>Will I run out of dbrefs?<a class="headerlink" href="#will-i-run-out-of-dbrefs" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue