<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
<p>When you send a command like <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> into Evennia - what actually happens? How does that <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> string end up being handled by the <codeclass="docutils literal notranslate"><spanclass="pre">CmdLook</span></code> class? What happens when we use e.g. <codeclass="docutils literal notranslate"><spanclass="pre">caller.msg()</span></code> to send the message back?</p>
<p>Understanding this flow of data - the <em>message path</em> is important in order to understand how Evennia works.</p>
<sectionid="ingoing-message-path">
<h2>Ingoing message path<aclass="headerlink"href="#ingoing-message-path"title="Permalink to this headline">¶</a></h2>
<h3>Incoming command tuples<aclass="headerlink"href="#incoming-command-tuples"title="Permalink to this headline">¶</a></h3>
<p>Ingoing data from the client (coming in as raw strings or serialized JSON) is converted by Evennia to a <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code>. Thesa are the same regardless of what client or connection was used. A <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> is a simple tuple with three elements:</p>
<p>For the <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code>-command (and anything else written by the player), the <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code><codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> is generated:</p>
<h3>Inputfuncs<aclass="headerlink"href="#inputfuncs"title="Permalink to this headline">¶</a></h3>
<p>On the Evennia server side, a list of <spanclass="xref myst">inputfucs</span> are registered. You can add your own by extending <codeclass="docutils literal notranslate"><spanclass="pre">settings.INPUT_FUNC_MODULES</span></code>.</p>
<p>Here the <codeclass="docutils literal notranslate"><spanclass="pre">session</span></code> represents the unique client connection this is coming from (that is, it’s identifying just <em>who</em> is sending this input).</p>
<p>One such inputfunc is named <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code>. For sending a <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code>, it will be called as</p>
<asideclass="sidebar">
<p>If you know how <codeclass="docutils literal notranslate"><spanclass="pre">*args</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">**kwargs</span></code> work in Python, you’ll see that this is the same as a call <codeclass="docutils literal notranslate"><spanclass="pre">text(session,</span><spanclass="pre">"look")</span></code></p>
<p>What an <codeclass="docutils literal notranslate"><spanclass="pre">inputfunc</span></code> does with this depends. For an <aclass="reference internal"href="OOB.html"><spanclass="doc std std-doc">Out-of-band</span></a> instruction, it could fetch the health of a player or tick down some counter.</p>
<asideclass="sidebar">
<pclass="sidebar-title">No text parsing happens before this</p>
<p>If you send <codeclass="docutils literal notranslate"><spanclass="pre">look</span><spanclass="pre">here</span></code>, the call would be <codeclass="docutils literal notranslate"><spanclass="pre">text(session,</span><spanclass="pre">*("look</span><spanclass="pre">here",</span><spanclass="pre">**{})</span></code>. All parsing of the text input happens in the command-parser, after this step.</p>
</aside>
<p>For the <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code><codeclass="docutils literal notranslate"><spanclass="pre">inputfunc</span></code> the Evennia <aclass="reference internal"href="../Components/Commands.html"><spanclass="doc std std-doc">CommandHandler</span></a> is invoked and the argument is parsed further in order to figure which command was intended.</p>
<p>In the example of <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code>, the <codeclass="docutils literal notranslate"><spanclass="pre">CmdLook</span></code> command-class will be invoked. This will retrieve the description of the current location.</p>
</section>
</section>
<sectionid="outgoing-message-path">
<h2>Outgoing message path<aclass="headerlink"href="#outgoing-message-path"title="Permalink to this headline">¶</a></h2>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> to outgoing commandtuple<aclass="headerlink"href="#msg-to-outgoing-commandtuple"title="Permalink to this headline">¶</a></h3>
<p>When the <codeclass="docutils literal notranslate"><spanclass="pre">inputfunc</span></code> has finished whatever it is supposed to, the server may or may not decide to return a result (Some types of <codeclass="docutils literal notranslate"><spanclass="pre">inputcommands</span></code> may not expect or require a response at all). The server also often sends outgoing messages without any prior matching ingoing data.</p>
<p>Whenever data needs to be sent “out” of Evennia, we must generalize it into a (now outgoing) <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code><codeclass="docutils literal notranslate"><spanclass="pre">(commandname,</span><spanclass="pre">(args),</span><spanclass="pre">{kwargs})</span></code>. This we do with the <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method. For convenience, this methods is available on every major entity, such as <codeclass="docutils literal notranslate"><spanclass="pre">Object.msg()</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">Account.msg()</span></code>. They all link back to <codeclass="docutils literal notranslate"><spanclass="pre">Session.msg()</span></code>.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">text</span></code> is so common that it is given as the default:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"A meadow</span><spanclass="se">\n\n</span><spanclass="s2">This is a beautiful meadow..."</span><spanclass="p">)</span>
</pre></div>
</div>
<p>This is converted to a <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> looking like this:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="p">(</span><spanclass="s2">"text"</span><spanclass="p">,</span><spanclass="p">(</span><spanclass="s2">"A meadow</span><spanclass="se">\n\n</span><spanclass="s2">This is a beutiful meadow..."</span><spanclass="p">,)</span><spanclass="p">{})</span>
</pre></div>
</div>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method allows you to define the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> directly, for whatever outgoing instruction you want to find:</p>
<h3>outputfuncs<aclass="headerlink"href="#outputfuncs"title="Permalink to this headline">¶</a></h3>
<asideclass="sidebar">
<p><codeclass="docutils literal notranslate"><spanclass="pre">outputfuncs</span></code> are tightly coupled to the protocol and you usually don’t need to touch them, unless you are <aclass="reference internal"href="Protocols.html"><spanclass="doc std std-doc">adding a new protocol</span></a> entirely.</p>
</aside>
<p>Since <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> is aware of which <aclass="reference internal"href="../Components/Sessions.html"><spanclass="doc std std-doc">Session</span></a> to send to, the outgoing <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> is always end up pointed at the right client.</p>
<p>Each supported Evennia Protocol (Telnet, SSH, Webclient etc) has their own <codeclass="docutils literal notranslate"><spanclass="pre">outputfunc</span></code>, which converts the generic <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> into a form that particular protocol understands, such as telnet instructions or JSON.</p>
<p>For telnet (no SSL), the <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> will return over the wire as plain text:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>A meadow\n\nThis is a beautiful meadow...
</pre></div>
</div>
<p>When sending to the webclient, the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> is converted as serialized JSON, like this:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>'["look", ["A meadow\\n\\nThis is a beautiful meadow..."], {}]'
</pre></div>
</div>
<p>This is then sent to the client over the wire. It’s then up to the client to interpret and handle the data properly.</p>
</section>
</section>
<sectionid="components-along-the-path">
<h2>Components along the path<aclass="headerlink"href="#components-along-the-path"title="Permalink to this headline">¶</a></h2>
<sectionid="ingoing">
<h3>Ingoing<aclass="headerlink"href="#ingoing"title="Permalink to this headline">¶</a></h3>
<li><p>Client - sends handshake or commands over the wire. This is received by the Evennia <aclass="reference internal"href="../Components/Portal-And-Server.html"><spanclass="doc std std-doc">Portal</span></a>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">PortalSession</span></code> represents one client connection. It understands the communiation protocol used. It converts the protocol-specific input to a generic <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> structure <codeclass="docutils literal notranslate"><spanclass="pre">(cmdname,</span><spanclass="pre">(args),</span><spanclass="pre">{kwargs})</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">PortalSessionHandler</span></code> handles all connections. It pickles the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> together with the session-id.</p></li>
<li><p>Pickled data is sent across the <codeclass="docutils literal notranslate"><spanclass="pre">AMP</span></code> (Asynchronous Message Protocol) connection to the <spanclass="xref myst">Server</span> part of Evennia.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">ServerSessionHandler</span></code> unpickles the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> and matches the session-id to a matching <codeclass="docutils literal notranslate"><spanclass="pre">SessionSession</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">ServerSession</span></code> represents the session-connection on the Server side. It looks through its registry of <aclass="reference internal"href="../Components/Inputfuncs.html"><spanclass="doc std std-doc">Inputfuncs</span></a> to find a match.</p></li>
<li><p>The appropriate <codeclass="docutils literal notranslate"><spanclass="pre">Inputfunc</span></code> is called with the args/kwargs included in the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code>. Depending on <codeclass="docutils literal notranslate"><spanclass="pre">Inputfunc</span></code>, this could have different effects. For the <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code> inputfunc, it fires the <aclass="reference internal"href="../Components/Commands.html"><spanclass="doc std std-doc">CommandHandler</span></a>.</p></li>
</ol>
</section>
<sectionid="outgoing">
<h3>Outgoing<aclass="headerlink"href="#outgoing"title="Permalink to this headline">¶</a></h3>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> method is called</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">ServerSession</span></code> and in particular <codeclass="docutils literal notranslate"><spanclass="pre">ServerSession.msg()</span></code> is the central point through which all <codeclass="docutils literal notranslate"><spanclass="pre">msg()</span></code> calls are routed in order to send data to that <aclass="reference internal"href="../Components/Sessions.html"><spanclass="doc std std-doc">Session</span></a>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">ServerSessionHandler</span></code> converts the <codeclass="docutils literal notranslate"><spanclass="pre">msg</span></code> input to a proper <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> structure <codeclass="docutils literal notranslate"><spanclass="pre">(cmdname,</span><spanclass="pre">(args),</span><spanclass="pre">{kwargs})</span></code>. It pickles the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> together with the session-id.</p></li>
<li><p>Pickled data is sent across across the <codeclass="docutils literal notranslate"><spanclass="pre">AMP</span></code> (Asynchronous Message Protocol) connection to the <spanclass="xref myst">Portal</span> part of Evennia.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">PortalSessionHandler</span></code> unpickles the <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> and matches its session id to a matching <codeclass="docutils literal notranslate"><spanclass="pre">PortalSession</span></code>.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">PortalSession</span></code> is now responsible for converting the generic <codeclass="docutils literal notranslate"><spanclass="pre">commandtuple</span></code> to the communication protocol used by that particular connection.</p></li>
<li><p>The Client receives the data and can act on it.</p></li>
<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.