<p>Evennia comes with a MUD client accessible from a normal web browser. During development you can try
it at <codeclass="docutils literal notranslate"><spanclass="pre">http://localhost:4001/webclient</span></code>. The client consists of several parts, all under
<p><codeclass="docutils literal notranslate"><spanclass="pre">templates/webclient/webclient.html</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">templates/webclient/base.html</span></code> are the very simplistic
django html templates describing the webclient layout.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">static/webclient/js/evennia.js</span></code> is the main evennia javascript library. This handles all
communication between Evennia and the client over websockets and via AJAX/COMET if the browser can’t
handle websockets. It will make the Evennia object available to the javascript namespace, which
offers methods for sending and receiving data to/from the server transparently. This is intended to
be used also if swapping out the gui front end.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">static/webclient/js/webclient_gui.js</span></code> is the default plugin manager. It adds the <codeclass="docutils literal notranslate"><spanclass="pre">plugins</span></code> and
<codeclass="docutils literal notranslate"><spanclass="pre">plugin_manager</span></code> objects to the javascript namespace, coordinates the GUI operations between the
various plugins, and uses the Evennia object library for all in/out.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">static/webclient/js/plugins</span></code> provides a default set of plugins that implement a “telnet-like”
interface.</p>
<p><codeclass="docutils literal notranslate"><spanclass="pre">static/webclient/css/webclient.css</span></code> is the CSS file for the client; it also defines things like how
to display ANSI/Xterm256 colors etc.</p>
<p>The server-side webclient protocols are found in <codeclass="docutils literal notranslate"><spanclass="pre">evennia/server/portal/webclient.py</span></code> and
<codeclass="docutils literal notranslate"><spanclass="pre">webclient_ajax.py</span></code> for the two types of connections. You can’t (and should not need to) modify
<p>Like was the case for the website, you override the webclient from your game directory. You need to
add/modify a file in the matching directory location within one of the _overrides directories.
These _override directories are NOT directly used by the web server when the game is running, the
server copies everything web related in the Evennia folder over to <codeclass="docutils literal notranslate"><spanclass="pre">mygame/web/static/</span></code> and then
copies in all of your _overrides. This can cause some cases were you edit a file, but it doesn’t
seem to make any difference in the servers behavior. <strong>Before doing anything else, try shutting
down the game and running <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">collectstatic</span></code> from the command line then start it back up, clear
your browser cache, and see if your edit shows up.</strong></p>
<codeclass="docutils literal notranslate"><spanclass="pre">evennia/web/webclient/templates/webclient/base.html</span></code> to
<codeclass="docutils literal notranslate"><spanclass="pre">mygame/web/template_overrides/webclient/base.html</span></code> and editing it to add your new plugin.</p>
<h1>Evennia Web Client API (from evennia.js)<aclass="headerlink"href="#evennia-web-client-api-from-evennia-js"title="Permalink to this headline">¶</a></h1>
<h1>Plugin Manager API (from webclient_gui.js)<aclass="headerlink"href="#plugin-manager-api-from-webclient-gui-js"title="Permalink to this headline">¶</a></h1>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">options</span></code> Object, Stores key/value ‘state’ that can be used by plugins to coordinate behavior.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">plugins</span></code> Object, key/value list of the all the loaded plugins.</p></li>
<h1>Plugin callbacks API<aclass="headerlink"href="#plugin-callbacks-api"title="Permalink to this headline">¶</a></h1>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">init()</span></code>– The only required callback</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">boolean</span><spanclass="pre">onKeydown(event)</span></code> This plugin listens for Keydown events</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">onBeforeUnload()</span></code> This plugin does something special just before the webclient page/tab is
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">onLoggedIn(args,</span><spanclass="pre">kwargs)</span></code> This plugin does something when the webclient first logs in.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">onGotOptions(args,</span><spanclass="pre">kwargs)</span></code> This plugin does something with options sent from the server.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">boolean</span><spanclass="pre">onText(args,</span><spanclass="pre">kwargs)</span></code> This plugin does something with messages sent from the server.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">boolean</span><spanclass="pre">onPrompt(args,</span><spanclass="pre">kwargs)</span></code> This plugin does something when the server sends a prompt.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">boolean</span><spanclass="pre">onUnknownCmd(cmdname,</span><spanclass="pre">args,</span><spanclass="pre">kwargs)</span></code> This plugin does something with “unknown commands”.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">onConnectionClose(args,</span><spanclass="pre">kwargs)</span></code> This plugin does something when the webclient disconnects from
the server.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">newstring</span><spanclass="pre">onSend(string)</span></code> This plugin examines/alters text that other plugins generate. <strong>Use
<p>The order of the plugins defined in <codeclass="docutils literal notranslate"><spanclass="pre">base.html</span></code> is important. All the callbacks for each plugin
will be executed in that order. Functions marked “boolean” above must return true/false. Returning
true will short-circuit the execution, so no other plugins lower in the base.html list will have
their callback for this event called. This enables things like the up/down arrow keys for the
history.js plugin to always occur before the default_in.js plugin adds that key to the current input
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">clienthelp.js</span></code> Defines onOptionsUI from the options2 plugin. This is a mostly empty plugin to
add some “How To” information for your game.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">default_in.js</span></code> Defines onKeydown. <enter> key or mouse clicking the arrow will send the currently
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">default_out.js</span></code> Defines onText, onPrompt, and onUnknownCmd. Generates HTML output for the user.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">default_unload.js</span></code> Defines onBeforeUnload. Prompts the user to confirm that they meant to
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">font.js</span></code> Defines onOptionsUI. The plugin adds the ability to select your font and font size.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">goldenlayout_default_config.js</span></code> Not actually a plugin, defines a global variable that
goldenlayout uses to determine its window layout, known tag routing, etc.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">goldenlayout.js</span></code> Defines onKeydown, onText and custom functions. A very powerful “tabbed” window
manager for drag-n-drop windows, text routing and more.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">history.js</span></code> Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow
keys to peruse.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">hotbuttons.js</span></code> Defines onGotOptions. A Disabled-by-default plugin that defines a button bar with
user-assignable commands.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">iframe.js</span></code> Defines onOptionsUI. A goldenlayout-only plugin to create a restricted browsing sub-
window for a side-by-side web/text interface, mostly an example of how to build new HTML
“components” for goldenlayout.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">message_routing.js</span></code> Defines onOptionsUI, onText, onKeydown. This goldenlayout-only plugin
implements regex matching to allow users to “tag” arbitrary text that matches, so that it gets
routed to proper windows. Similar to “Spawn” functions for other clients.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">multimedia.js</span></code> An basic plugin to allow the client to handle “image” “audio” and “video” messages
from the server and display them as inline HTML.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">notifications.js</span></code> Defines onText. Generates browser notification events for each new message
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">oob.js</span></code> Defines onSend. Allows the user to test/send Out Of Band json messages to the server.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">options.js</span></code> Defines most callbacks. Provides a popup-based UI to coordinate options settings with
the server.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">options2.js</span></code> Defines most callbacks. Provides a goldenlayout-based version of the
options/settings tab. Integrates with other plugins via the custom onOptionsUI callback.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">popups.js</span></code> Provides default popups/Dialog UI for other plugins to use.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">splithandler.js</span></code> Defines onText. Provides an older, less-flexible alternative to goldenlayout for
multi-window UI to automatically separate out screen real-estate by type of message.</p></li>
<spanclass="n">tooltip</span><spanclass="p">:</span><spanclass="s1">'Input - The last input in the layout is always the default.'</span><spanclass="p">,</span>
<spanclass="n">tooltip</span><spanclass="p">:</span><spanclass="s1">'Input - The last input in the layout is always the default.'</span><spanclass="p">,</span>
<p>Remember, plugins are load-order dependent, so make sure the new <codeclass="docutils literal notranslate"><spanclass="pre"><script></span></code> tag comes before the
goldenlayout.js</p>
<p>Next, create a new plugin file <codeclass="docutils literal notranslate"><spanclass="pre">mygame/web/static_overrides/webclient/js/plugins/myplugin.js</span></code> and
<p>Remember, plugins are load-order dependent, so make sure the new <codeclass="docutils literal notranslate"><spanclass="pre"><script></span></code> tag comes after the
<p>Now, <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">stop</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">collectstatic</span></code>, and <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">start</span></code> and then load the webclient up in
your browser.
Enable developer options and look in the console, and you should see the message ‘myplugin! Hello
World!’</p>
<p>Since our layout.js plugin is going to use the splithandler, let’s enhance this by adding a check to
make sure the splithandler.js plugin has been loaded:</p>
<spanclass="n">alert</span><spanclass="p">(</span><spanclass="s1">'MyPlugin requires the splithandler.js plugin. Please contact the game maintainer to</span>
<spanclass="n">alert</span><spanclass="p">(</span><spanclass="s1">'MyPlugin requires the splithandler.js plugin. Please contact the game maintainer to</span>
<p><codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">stop</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">collectstatic</span></code>, and <codeclass="docutils literal notranslate"><spanclass="pre">evennia</span><spanclass="pre">start</span></code> once more, and force-reload your
browser page to clear any cached version. You should now have a nicely split layout.</p>