mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 05:46:31 +01:00
2240 lines
No EOL
505 KiB
XML
2240 lines
No EOL
505 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Evennia Devblog RSS Feed</title><link>https://www.evennia.com/devblog/feed.rss</link><description>Evennia is a modern Python library and server for creating text-based
|
||
multi-player games and virtual worlds (also known as MUD, MUSH, MU,
|
||
MUX, MUCK, etc). While Evennia handles all the necessary things every
|
||
online game needs, like database and networking, you create the game of
|
||
your dreams by writing normal Python modules.</description><language>en-US</language><lastBuildDate>Sat, 10 Jun 2023 16:32:17 GMT</lastBuildDate><generator>rfeed v1.1.1</generator><docs>https://github.com/svpino/rfeed/blob/master/README.md</docs><item><title> Evennia 2.0.0 released today</title><link>2023.html#2023-06-10-evennia-2.0.0-released-today</link><description><p><img src="https://upload.wikimedia.org/wikipedia/commons/c/c4/Field_Hamois_Belgium_Luc_Viatour.jpg" alt="screenshot" />
|
||
<br></p>
|
||
<p>As part of our new use of <a href="https://semver.org/">semantic versioning</a>, Evennia
|
||
2.0.0 was released today. Evennia is a Python <code>MU*</code> creation framework and
|
||
server. As the change of the major version indicates, this is a backwards
|
||
incompatible change ... well, <em>maybe</em>. It depends on your use-case. Read on.</p>
|
||
<p>In this post I&#x27;ll go over some of the new things since the release of Evennia
|
||
1.0 some six months ago.</p>
|
||
<h2>New version of the ExtendedRoom</h2>
|
||
<p>The main thing that <em>may</em> be backwards income is the <code>ExtendedRoom</code> contrib.
|
||
This contrib extends the standard room with the ability to look at &#x27;details&#x27; and
|
||
to have descriptions that change by season and by time-of-day in the game. I
|
||
originally wrote the <code>ExtendedRoom</code> contrib more than a decade ago and it was
|
||
in dire need to be recactored and cleaned up to use the modern tools available
|
||
in Evennia. Not to mention make use of my additional years of experience since
|
||
first creating it.</p>
|
||
<p>Here are the <a href="https://github.com/evennia/evennia/discussions/3200">new features</a>:</p>
|
||
<ul>
|
||
<li>All rooms can now have any number of &quot;room states&quot;, like &quot;burning&quot;, &quot;flooded&quot;,
|
||
&quot;dark&quot;, &quot;crowded&quot; or what have you. The <code>season</code> and <code>time_of_day</code> are now just
|
||
treated as any other room-states except that they auto-change with in-game time.</li>
|
||
<li>Rooms can have any number of swappable room-descriptions, just by adding an
|
||
Attribute <code>desc_&lt;roomstate&gt;</code> to the room. This will be used when a given
|
||
room-state is set on the room. If no room state matches, the traditional
|
||
<code>desc</code> Attribute is used.</li>
|
||
<li>In the old contrib, you could add special tags, like <code>&lt;morning&gt;...&lt;/morning&gt;</code>
|
||
in your descriptions and have those parts of the texts only appear when it&#x27;s
|
||
morning in-game. This still works, but only ever supported time-of-day states.
|
||
The new way is to make use Evennia&#x27;s FuncParser to embed functions in the text
|
||
directly. The <code>ExtendedRoom</code> understands the new <code>state</code> inline function. This
|
||
can be used with <em>any</em> room state (including seasons and time-of-day). For
|
||
example: <code>$state(morning, The morning sun is shining in.)</code> or
|
||
<code>$state(burning, This place is on fire!)</code>.</li>
|
||
<li>The room still supports <code>details</code> - the ability to look at things in the room
|
||
without needing to create a new database object first. This hasn&#x27;t changed.</li>
|
||
<li>The <code>ExtendedRoom</code> now also has simple support for echoing random messages now
|
||
and then to the room.</li>
|
||
</ul>
|
||
<p>Overall, the code was completely re-written and cleaned up, making use of the
|
||
latest Evennia tooling. It also has much better unit-test coverage. All the unit
|
||
tests of the old implementation passes for the new one, but the changes are
|
||
so big that it&#x27;s nevertheless possible people making heavy use of
|
||
this contrib may see side effects from upgrading.</p>
|
||
<p>Now, a contrib is not part of the core, so it (potentially) being
|
||
backwards-incompatible should normally not warrant a major version bump. But I
|
||
feel the <code>ExtendedRoom</code> contrib is used by so many in the Evennia community that
|
||
it&#x27;s prudent to up the major version to let people know that they should
|
||
keep an eye out when upgrading.</p>
|
||
<h2>More on the Beginner Tutorial</h2>
|
||
<p>Most of my time has been spent continuing to work on the new <a href="https://www.evennia.com/docs/latest/Howtos/Beginner-Tutorial/Beginner-Tutorial-Overview.html">Beginner Tutorial</a>. Notably on <a href="https://www.evennia.com/docs/latest/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-Part3-Overview.html">part three</a>, where
|
||
we are making a whole little Evennia MUD game from scratch. While still not
|
||
done, I have now added detailed lessons on</p>
|
||
<ul>
|
||
<li>Creating RPG dice rollers and rule systems (in our example we are using the
|
||
<em>Knave</em> TTRPG ruleset).</li>
|
||
<li>Organizing Player Character data, and character generation.</li>
|
||
<li>In-game objects and items.</li>
|
||
<li>Handling equipment and weapons.</li>
|
||
<li>In-game rooms.</li>
|
||
<li>Non-player characters.</li>
|
||
<li>Two types of Combat systems (Twitch-based and Turn based).</li>
|
||
</ul>
|
||
<p>TODOs are Monster/NPC AI, Dynamical generation of rooms, Questin, Shops and some
|
||
more bits and bobs. And of course a separate session on building the game world
|
||
and tying all these systems together into a little example game.</p>
|
||
<h2>A truckload of new features!</h2>
|
||
<p>As usual, the Evennia community ame through with a bunch of new useful stuff since
|
||
the release of Evennia 1.0.</p>
|
||
<ul>
|
||
<li><code>Containers</code> - A new contrib with a typeclass and commands to make and manage
|
||
all sorts of containers, from chests to crates and jars, along with commands
|
||
to put things in them and take things out of them. A great place to start
|
||
tweaking for your own game implementation (InspectorCaracal).</li>
|
||
<li>The ANSI color fallbacks (for use when your client does not support XTerm256)
|
||
were improved to make more sense (InspectorCaracal).</li>
|
||
<li>New <code>logger.delete_log</code> method for deleting log files from inside the server (aMiss-aWry).</li>
|
||
<li>For those intending to override the <code>SessionHandler</code>, it was cleaned up and
|
||
refactored to make it less prone to cause circular import issues (Volund).</li>
|
||
<li>New <code>create_channel(attr=...)</code> keyword, for setting channel Attributes
|
||
directly on creation, especially from channels defined in <code>settings.DEFAULT_CHANNELS</code> (me)</li>
|
||
<li>Attributes will now properly save Python <code>deques</code> with <code>maxlen=...</code> set (me).</li>
|
||
<li><a href="https://www.evennia.com/docs/latest/Components/Tags.html#tagcategoryproperty"><code>TagCategoryProperty</code></a> - A new way to define tags with a particular category on a class at creation-time, without having to do so in the <code>at_object_creation</code> method (me).</li>
|
||
<li>A lot of bug fixes; <a href="https://www.evennia.com/docs/latest/Coding/Changelog.html">see the CHANGELOG</a> for all the details!</li>
|
||
</ul>
|
||
<h2>Continuing</h2>
|
||
<p>Over summer, my development usually slows down a bit, but I plan to keep pushing
|
||
on getting that Beginner tutorial done. We are also seeing more people joing
|
||
the <a href="https://discord.gg/AJJpcRUhtF">evennia discord</a>, which means more eyes on
|
||
the code and more bugs and edge cases being detected (and ironed out). So a lot
|
||
of maintenance work to be done in the short term.</p>
|
||
<p>In the longer term, there are a lot of exciting plans for Evennia in the pipe,
|
||
but we&#x27;ll get there when we get there. :)</p>
|
||
<p>Have a nice summer!</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 10 Jun 2023 00:00:00 GMT</pubDate><guid isPermaLink="true">2023.html#2023-06-10-evennia-2.0.0-released-today</guid></item><item><title> Evennia 1.0 released!</title><link>2022.html#2022-12-03-evennia-1.0-released!</link><description><p><img src="https://user-images.githubusercontent.com/294267/205434941-14cc4f59-7109-49f7-9d71-0ad3371b007c.jpg" alt="screenshot" />
|
||
<br></p>
|
||
<p>As of today, <a href="https://github.com/evennia/evennia/discussions/3017">Evennia 1.0 released</a>! This has been a long time coming. Not only were there a lot of fixes and features to add, we also moved to a completely new documentation system. With many moving parts and my wish to get as much as possible into this release, it took a while to get things aligned.</p>
|
||
<p>This release is also the first one where we distribute Evennia on Pypi, so you can install with <code>pip install evennia</code>. This also led to a lot of new work and documentation to write.</p>
|
||
<p>That said, it would have taken even longer if I had been alone - and I was not. The Evennia community is growing ever more active, and we now have a regular influx of PRs. I even get help fixing bugs at times! Not to mention a bunch of very sweet new contribs and implemented features. It feels super-luxurious to wake up and find a bug has been fixed for me!</p>
|
||
<p>Thanks a lot, everyone!</p>
|
||
<h2>Moving forward</h2>
|
||
<p>The linked announcement above covers the new features of 1.0. Check it out - there&#x27;s a lot of fun stuff. In this dev-blog, I wanted to talk a little bit about the future instead.</p>
|
||
<h3>Main is where it&#x27;s at</h3>
|
||
<p>As usual when the <code>develop</code> branch merges, activity shifts. So moving forward, the <code>main</code> branch (which is now what we use instead of <code>master</code>) will be the &#x27;active&#x27; branch.</p>
|
||
<p>All new PRs and features should now be made against <code>main</code>. The <code>develop</code> branch will likely make its return as the bleeding-edge, but I hope that it will be mainly for testing individual complex features rather than for a huge new version like in the past.</p>
|
||
<h3>Versioning</h3>
|
||
<p>In the past we have made big version changes: <code>0.5-&gt;0.6-&gt;0.7-&gt;0.8-&gt;0.9</code>. Then we got sort of stuck preparing for <code>1.0</code>, and there was an interim <code>0.9.5</code> release just to hold us over. In the end, <code>1.0</code> took almost two years to complete.</p>
|
||
<p>Having the <code>develop</code> branch open for this long is not good. Users of <code>0.9.5</code> were stuck with the old docs (just a plain import from the github wiki) since I couldn&#x27;t maintain both. It meant stagnation for people downloading <code>master</code> branch. And while people in the know eventually switched to use <code>develop</code> branch (helping a lot of with testing!) it&#x27;s still not an ideal state of affairs. I don&#x27;t want something similar to happen leading up to 2.0.</p>
|
||
<p>So for that reason I plan to move Evennia to <a href="https://semver.org/">semantic versioning</a> going forward. Semantic versioning means that we&#x27;ll use <code>Major.Minor.Patch</code> versioning. For you as a developer of an Evennia game (using <code>pip install</code> - if you follow <code>main</code> on git, it&#x27;s less relevant, you&#x27;ll have bleeding edge), this versioning means</p>
|
||
<ul>
|
||
<li><code>1.0.x</code> - changes (<code>1.0.1</code>, <code>1.0.2</code> etc) are <em>patches</em>. Bug fixes. Security fixes. Should always be safe to upgrade to without anything breaking.</li>
|
||
<li><code>1.x.0</code> - changes (<code>1.1.0</code>, <code>1.2.0</code> etc) are <em>minor version changes</em>. This can introduce new functionality that is <em>backwards compatible</em>. So a new default command, a new contrib, stuff like that. Maybe bigger bug fixes and refactoring that don&#x27;t change existing functionality. So Minor versions are also usually worthwhile to update to.</li>
|
||
<li><code>x.0.0</code> - changes (<code>2.0.0</code>, <code>3.0.0</code> etc) are <em>major version changes</em>. These versions include changes that are <em>backwards-incompatible</em>. The change may still be small! The gist of it is that they are changes that require you to take some action.</li>
|
||
</ul>
|
||
<p>With semantic versioning, Evennia 2.0, 3.0 etc may happen sooner than you may think - even changing how a setting should be written is technically a backwards-incompatible change. I think this will help make those major versions be less daunting too - meaning we won&#x27;t get stuck at 1.9.5 again.</p>
|
||
<h3>Finishing the beginner tutorial</h3>
|
||
<p>The new <a href="https://www.evennia.com/docs/latest/Howtos/Howtos-Overview.html#beginner-tutorial">Beginner Tutorial</a> is not ready yet.</p>
|
||
<p>As mentioned in my previous devblog, I had to pause work on it or 1.0 wouldn&#x27;t get out this year. That said, I think the first two parts that are finished are already useful to newcomers. In the coming months I will continue with the tutorial-game and finish all the code. In the end I aim to have the reader make a complete little MUD from scratch if they follow the tutorial from beginning to end.</p>
|
||
<h2>Onward!</h2>
|
||
<p>After the 1.0 release we are now officially in the &#x27;bug fix and cleanup&#x27; phase. So report all the issues you find - especially with the new docs!</p>
|
||
<p>So moving forward, I expect to mainly do patches and minor versions for a while. I don&#x27;t intend to start any major work until after the beginner-tutorial is complete.</p>
|
||
<p>For now though, let&#x27;s just be happy that 1.0 is out! :D</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 03 Dec 2022 00:00:00 GMT</pubDate><guid isPermaLink="true">2022.html#2022-12-03-evennia-1.0-released!</guid></item><item><title> Project plans and Splitting a Setting in two</title><link>2022.html#2022-09-17-project-plans-and-splitting-a-setting-in-two</link><description><p><img src="images/pause_break_key.jpg" alt="Pause/Break button" /></p>
|
||
<p>As those following Evennia development should be aware of for now, we are approaching the 1.0 release of Evennia, the MU*-building framework.</p>
|
||
<p>Thing is, that release has been coming &#x27;soon&#x27; for quite a while now. Since some time you can already test Evennia 1.0-dev by checking out the Evennia <code>develop</code> branch (<a href="https://github.com/evennia/evennia/discussions/2640">here</a> for help on how). Evennia 1.0-dev is still changing, but it&#x27;s already stable enough that It&#x27;s gotten to the point that people in chat now recommend new users to start fresh with 1.0-dev rather than the &#x27;stable&#x27; version 0.9.5, which is now 1.5 years old and is not seeing more updates.</p>
|
||
<h2>Changes to 1.0 release plans</h2>
|
||
<h3>In short:</h3>
|
||
<p>I plan to pause the work on the new beginner tutorial and release 1.0 with that piece of the documentation unfinished. It still has a large swathes of useful info, but the new from-scratch game will not be ready.</p>
|
||
<h3>Longer:</h3>
|
||
<p>One of the reasons for 1.0 not being released is that I have been working on a new beginner-tutorial to go with the new system. This involves making a full little MUD game from scratch, and I&#x27;m making a full system you can both follow lesson-per-lesson as well as implementing it for those that prefer to pull apart code.</p>
|
||
<p>Writing good code as well as full tutorial lessons is however a big, full-time job (next to my actual real-life full-time job) and thus I expect it will take a good while longer before the new tutorial is done. Worse, in the meantime I can&#x27;t spend much time resolving the 1.0-dev bugs that has been reported by community testers and also block release.</p>
|
||
<p>So I will map out the remaining pieces of the tutorial with informational &quot;Work in progress&quot; markers, merge what I have, and stop work on it for now.</p>
|
||
<p>I&#x27;ll continue finishing the tutorial in smaller sub-releases after the main 1.0 release.</p>
|
||
<h3>What&#x27;s left for 1.0-dev</h3>
|
||
<p>So, with the main bulk of work (the beginner tutorial) on hold, what&#x27;s left to do?</p>
|
||
<ul>
|
||
<li>Cleanup the rest of the docs! There&#x27;s still much to do there, including removing old tutorials that are now covered in the parts of the beginner-tutorial already finished. Also need to connect all pages and structure the docs better.</li>
|
||
<li>Get into the bug backlog of Evennia 1.0-dev that people have reported. Also work to merge some outstanding PRs. I&#x27;ll need to triage issues more, but hopefully I can get some help fixing simpler bugs during October&#x27;s <a href="https://github.com/evennia/evennia/discussions/2858">Hacktoberfest</a>.</li>
|
||
</ul>
|
||
<h2>MULTISESSION_MODE changes (this will affect your current game!)</h2>
|
||
<p>That said, now to some recent changes in 1.0-dev. This one is important since it affects your existing game.</p>
|
||
<h3>In short:</h3>
|
||
<p>The functionality of <code>MULTISESSION_MODE</code> has been broken into smaller sub-settings. This makes it a lot more flexible, but if you used the &#x27;side-effects&#x27; of a higher <code>MULTISESSION_MODE</code> in your game, you now need to set a few other settings to get that back.</p>
|
||
<h3>Longer:</h3>
|
||
<p>The <code>MULTISESSION_MODE</code> is a long-standing Evennia setting. It controls how many sessions you can connect to the game at a time. In other words, how many game clients you can open against the same accoung login at the same time.</p>
|
||
<ul>
|
||
<li>Mode 0: A single session. Connecting a new one will disconnect the previous one.</li>
|
||
<li>Mode 1: Multiple sessions can be connected. When you puppet a Character, each session will see the same output.</li>
|
||
<li>Mode 2: Multiple sessions can be connected. Each session can puppet one Character each.</li>
|
||
<li>Mode 3: Multiple sessions can be connected. Multiple sessions can puppet a Character, each session will see the same output.</li>
|
||
</ul>
|
||
<p>Thing is that for the longest time, this setting has <em>also</em> controlled other things:</p>
|
||
<ul>
|
||
<li>Mode 0,1: A Character of the same name as the Account is auto-created when first connecting.</li>
|
||
<li>Mode 0,1: You auto-connect to your last character whenever you log in.</li>
|
||
<li>Mode 2,3: You don&#x27;t get an auto-created character and end up in and OOC &#x27;character&#x27; select screen when logging in.</li>
|
||
</ul>
|
||
<p>These things don&#x27;t really belong together. For example, if you want players to be able to choose between multiple characters (a character selection screen) but only play one at a time (<code>MULTISESSION_MODE</code> 0 or 1), you&#x27;d need to work around Evennia&#x27;s default.</p>
|
||
<p>As of today, I&#x27;ve merged a change to Evennia 1.0-dev (<code>develop</code> branch) which changes this.</p>
|
||
<ul>
|
||
<li><code>MULTISESSION_MODE</code> now <em>only</em> controls how sessions connect and how they can puppet characters.</li>
|
||
<li><code>MAX_NR_SIMULTANEOUS_PUPPETS</code> is a new setting that controls how many puppets you can control for <code>MULTISESSION_MODE</code> 2 and 3. This will not change anything for modes 0 and 1 (always acts as 1 due to how those modes work).</li>
|
||
<li><code>AUTO_CREATE_CHARACTERS_WITH_ACCOUNT</code> allows you to turn off the auto-creation of a character with the same name as the Account when you register. This used to be enforced as a part of <code>MULTISESSION_MODE</code> 0 or 1.</li>
|
||
<li><code>AUTO_PUPPET_ON_LOGIN</code> controls if you will auto-connect to the last thing you puppet when you login, of if you&#x27;ll end up OOC (by default at a character selection screen). Again, this used to be enforced by <code>MULTISESSION_MODE</code> 0 or 1.</li>
|
||
<li><code>MAX_NR_CHARACTERS</code> existed before. It controls how many characters the default <code>charcreate</code> command will allow you to create.</li>
|
||
</ul>
|
||
<p>By default these settings are all setup to mimic the old <code>MULTISESSION_MODE</code> 0, so you should not notice any difference in a fresh game.</p>
|
||
<p>The drawback is that if you use a higher <code>MULTISESSION_MODE</code> in your existing game, you will need to tweak these settings to get back what you had before. Also, if you overrode <code>Account</code> or the default login commands, you may need to tweak things to match the new upstream default.</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 17 Sep 2022 00:00:00 GMT</pubDate><guid isPermaLink="true">2022.html#2022-09-17-project-plans-and-splitting-a-setting-in-two</guid></item><item><title> Tutorial-writing and Attributes galore</title><link>2022.html#2022-07-05-tutorial-writing-and-attributes-galore</link><description><p><img src="images/tutorial.jpg" alt="Tutorial sign" /></p>
|
||
<p>It has been a while since I wrote anything for the dev blog of Evennia, the MU creation system - so it&#x27;s about time!</p>
|
||
<p>It&#x27;s been a busy spring and early summer for me, with lots of real-life work going on away from Evennia land. But that hasn&#x27;t meant activity on the Evennia code base has slowed!</p>
|
||
<h2>Many eyes on Evennia 1.0-dev</h2>
|
||
<p>Earlier this year I <a href="https://github.com/evennia/evennia/discussions/2640">invited people to try the Evennia develop branch</a> - what will become Evennia 1.0. A lot of bold beta-testers have since swapped to using the 1.0 branch. While there are plenty of issues being reported, most seem pretty happy about it so far. As mentioned in earlier dev blogs, Evennia 1.0 has a <a href="https://github.com/evennia/evennia/blob/master/CHANGELOG.md">lot of improvements and new features</a>!</p>
|
||
<p>As part of this, the amount of PRs being made against develop branch has increased a lot, with awesome community members stepping up to fix bugs and even address long-standing annoyances. This includes everything from big improvements in ANSI parsing, fixes to the 1.0 FuncParser, RPSystem contrib optimizations and much more - <a href="https://github.com/evennia/evennia/pulls?page=2&amp;q=is%3Apr+is%3Aclosed">the list of closed PRs is long</a>.</p>
|
||
<p>Another big part are everyone helping to answer questions in chat and suggesting improvements to the community in general. Thanks everyone!</p>
|
||
<h2>The upcoming beginner tutorial</h2>
|
||
<p>On my end, I&#x27;m working on the Beginner Tutorial for the new 1.0 documentation. This will be a multi-part tutorial where you get to make a little MUD game from scratch. It goes through the basics of Evennia all the way to releasing your little game and I hope it will help people get started. This will also lead to a new contrib - the <code>evadventure</code> package, which should (I plan) have everything the tutorial needs to run. This is useful for those that prefer picking apart existing code over reading about it.</p>
|
||
<p>The tutorial game itself is based on <a href="https://www.gmbinder.com/share/-LZGcbbCQaqjIV0TmLx3">Knave</a>, an light Old-School-Renaissance (OSR) tabletop roleplaying ruleset inspired by early editions Dungeons &amp; Dragons. It&#x27;s simple enough to fit in a tutorial but with enough wrinkles to showcase how to create some basic rpg systems in Evennia:</p>
|
||
<ul>
|
||
<li>Using Attributes (STR, DEX etc)</li>
|
||
<li>Rules (dice rolls, advantage, contested rolls etc)</li>
|
||
<li>Character generation (Knave chargen is mostly random, but it still showcases Evennia&#x27;s menu system EvMenu).</li>
|
||
<li>Inventory management and equipment (including limited storage as well as items worn or wielded).</li>
|
||
<li>Turn-based combat system (menu based)</li>
|
||
<li>
|
||
<ul>
|
||
<li>Attacking with wielded weapons (or spell rune)</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<ul>
|
||
<li>Stunts to give you advantages for later turns or give enemies disadvantage for later turns</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<ul>
|
||
<li>Using items for healing or other effects</li>
|
||
</ul>
|
||
</li>
|
||
<li>
|
||
<ul>
|
||
<li>Fleeing and chasing</li>
|
||
</ul>
|
||
</li>
|
||
<li>Alternative Twitch-based combat system (might be a stretch goal)</li>
|
||
<li>NPCs with very simple AI, Death and respawn</li>
|
||
<li>Simple Questing system with NPC quest givers and quest states</li>
|
||
<li>A small example world (tech-demo)</li>
|
||
</ul>
|
||
<p>I won&#x27;t include how to make a Crafting system, since I&#x27;ve added a full <a href="https://www.evennia.com/docs/1.0-dev/Contribs/Contrib-Crafting.html">Crafting contrib</a> to Evennia 1.0 for devs to be inspired by or tear apart.</p>
|
||
<h2>Some nice new things about Attributes</h2>
|
||
<p>In general news, Evennia 1.0 will see two big improvements when it comes to <a href="https://www.evennia.com/docs/1.0-dev/Components/Attributes.html">Attributes</a>.</p>
|
||
<h3>AttributeProperty</h3>
|
||
<p>This is a new way to write - and particularly initialize - Attributes. Traditionally in Evennia you need to initialize your object&#x27;s Attributes something like this:</p>
|
||
<pre><code class="language-python">from evennia import DefaultCharacter
|
||
|
||
class Character(DefaultCharacter):
|
||
def at_object_creation(self):
|
||
self.db.strength = 10
|
||
self.db.mana = 12
|
||
</code></pre>
|
||
<p>This still works. But with the new <code>AttributeProperty</code> you can now write it like this instead:</p>
|
||
<pre><code class="language-python">from evennia import DefaultCharacter
|
||
from evennia.typeclasses.attributes import AttributeProperty
|
||
|
||
class Character(DefaultCharacter):
|
||
strength = AttributeProperty(10)
|
||
mana = AttributeProperty(10)
|
||
</code></pre>
|
||
<p>This makes Attributes look more like Django fields, sitting directly on the class. They can also have <code>category</code> and all other values you&#x27;d expect. You can still access those Attributes like normal:</p>
|
||
<pre><code class="language-python">strength = char.db.strength
|
||
mana = char.attributes.get(&quot;mana&quot;)
|
||
</code></pre>
|
||
<p>But you can now also do just</p>
|
||
<pre><code class="language-python">strength = char.strength
|
||
mana = char.mana
|
||
</code></pre>
|
||
<p>directly (you&#x27;ll need to be careful to not override any existing properties on objects this way of course).</p>
|
||
<p>An interesting feature of using an <code>AttributeProperty</code> is that you can choose to <em>not</em> actually create the <code>Attribute</code> under the hood unless the default changed:</p>
|
||
<pre><code class="language-python">class Character(DefaultCharacter):
|
||
strength = AttributeProperty(10, autocreate=False)
|
||
mana = AttributeProperty(10, autocreate=False)
|
||
</code></pre>
|
||
<p>When you now access <code>char.strength</code> you will get <code>10</code> back but you won&#x27;t actually be hitting the database to load anything - it&#x27;s just giving you the default. Not until you <em>change</em> the default will the actual <code>Attribute</code> be created. While this can be very powerful for optimization, note that you can of course not access such data via <code>char.db</code> or <code>char.attributes.get</code> either (because no <code>Attribute</code> yet exists). So this functionality can be confusing unless you know what you are doing. Hence <code>autocreate</code> defaults to <code>True</code>.</p>
|
||
<h3>Saving Attributes with hidden database objects</h3>
|
||
<p>This is one of those classical quirks of Evennia that many have encountered. While Evennia can save a lot of things in an <code>Attribute</code>, including database objects, it cannot do so if it doesnt <em>know</em> those database objects are there. This is fine if you are saving a list or a dict with objects in it - Evennia will go through it and make sure to serialize each db-object in turn.</p>
|
||
<p>But if you &quot;hide away&quot; your db-object you will be in trouble:</p>
|
||
<pre><code class="language-python">class MyStore:
|
||
def __init__(self, dbobj):
|
||
self.dbobj = dbjobj
|
||
|
||
char = Character.objects.get(id=1)
|
||
obj.db.mystore = MyStore(char) # leads to Traceback!
|
||
</code></pre>
|
||
<p>This fails because we store <code>char</code> inside <code>MyStore</code> and there is no way for Evennia to know it&#x27;s there and to handle it properly.</p>
|
||
<p>For the longest time, this was just a limitation you had to accept. But with Evennia 1.0-dev you can now help Evennia out:</p>
|
||
<pre><code class="language-python">from evennia.utils.dbserialize import dbserialize, dbunserialize
|
||
|
||
class MyStore:
|
||
def __init__(self, dbobj):
|
||
self.dbobj = dbobj
|
||
def __serialize_dbobjs__(self):
|
||
self.dbobj = dbserialize(self.dbobj)
|
||
def __deserialize_dbobjs__(self):
|
||
self.dbobj = dbunserialize(self.dbobj)
|
||
|
||
char = Character.objects.get(id=1)
|
||
obj.db.mystore = MyStore(char) # now OK!
|
||
</code></pre>
|
||
<p>With the new <code>__serialize_dbobjs__</code> and <code>__deserialize_dbobjs__</code>, Evennia is told how to properly stow away the db-object (using the tools from <code>evennia.utils</code>) before trying to serialize the entire <code>MyStore</code>. And later, when loading it up, Evennia is helped to know how to restore the db-object back to normal again after the rest of <code>MyStore</code> was already loaded up.</p>
|
||
<h2>Moving forward ...</h2>
|
||
<p>For Evennia 1.0, the tutorial-writing is the single biggest project that remains - that and the general documentation cleanup of our entirely rewritten documentation.</p>
|
||
<p>After that I will dive back in with the issues that has popped up during beta-testing of 1.0-dev and try to wrap up the most serious ones before release. Still some time away, but it&#x27;s getting there ... slowly!</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 05 Jul 2022 00:00:00 GMT</pubDate><guid isPermaLink="true">2022.html#2022-07-05-tutorial-writing-and-attributes-galore</guid></item><item><title> Into 2022 with thanks and plans</title><link>2022.html#2022-01-06-into-2022-with-thanks-and-plans</link><description><p><img src="https://www.nafcu.org/sites/default/files/inline-images/2022-blog.png" alt="2022 getting started" />
|
||
<br>
|
||
I didn&#x27;t write an end-of-the year summary for 2021, so this first devblog of 2022 will also look back a bit at the past year. It also helps me get used to using this new blog platform I wrote about in the previous post.</p>
|
||
<h2>On Evennia 1.0</h2>
|
||
<p>Speaking of 2021, you may have noticed that there was no new versioned Evennia release last year. Last one was 0.9.5 back in 2020. This may make it seem like little is happening in Evennia-land ... but the fact is that while little has happened in <code>master</code> branch over the past year, all the more has been going on in Evennia&#x27;s <code>develop</code> branch - the branch which will become Evennia 1.0.</p>
|
||
<p>Now, it&#x27;s not really so good to have a development branch run so long. This is because in the interim people report errors in <code>master</code> branch that has since been resolved in <code>develop</code>. It&#x27;s becoming more and more cumbersome to backport which means that <code>master</code> is not getting updated all that much right now.</p>
|
||
<p>Post 1.0, I&#x27;ll likely switch to a faster release cycle, but at least for now, it has been hard to avoid, this is because I&#x27;m reworking the entire documentation site alongside the code, with new autodocs and tutorials. Releasing an intermediary version with some sort of mid-way documentation version is just not practical for me. So I hope you can be patient a bit further!</p>
|
||
<p>Soonish™, I hope to have finished the code changes needed for 1.0 and then I&#x27;ll invite adventurous folks to use the branch more extensively while the docs are still in flux.</p>
|
||
<h3>So what&#x27;s still to do for Evennia 1.0?</h3>
|
||
<p><a href="https://github.com/evennia/evennia/projects/9">This is the current TODO list</a>.</p>
|
||
<p>The big one I&#x27;m currently doing is to refactor the <code>contrib/</code> folder to have more structure (it has grown organically until now). After this, there are a series of bugs and minor features to do. I will also go back and address the low-hanging <code>master</code> branch bugs that haven&#x27;t already been resolved in <code>develop</code>.
|
||
Most remaining points are then documentation fixes. Those will be handled in one go as the docs are finalized.</p>
|
||
<h3>So ...</h3>
|
||
<p>I won&#x27;t/can&#x27;t commit to a deadline for Evennia 1.0, but I&#x27;ll keep chipping away at it as fast as I can. If you want things to move quicker you are more than welcome to join the other contributors that have chipped in with PRs over the past year. Check out the TODO list and consider investigating a bug or implementing a feature - some may be pretty straight forward.</p>
|
||
<h3>... some thanks!</h3>
|
||
<p>A big thanks to those that dropped an encouraing buck in my hat (aka <a href="https://www.patreon.com/griatch">patreon</a> or with a one-time paypal donation) over the year. Everyone has different economical situations and I hope I&#x27;ve been very clear that noone should feel obligated to pay anything. But those of you that could and did - know that you have my thanks - it&#x27;s very encouraging.</p>
|
||
<p>But - just as big thanks go out to <em>everyone</em> that contributed to Evennia in 2021! &quot;Contribution&quot; means so many things - we have the troopers that contributed code and made PRs (best Hacktoberfest yet!), but also those that dilligently reported bugs and pointed out problems as well as (and this is just as important) were active and helpful in the support chat and github discussion!</p>
|
||
<p>You guys make the community, that&#x27;s all there is to it. Thanks a lot.</p>
|
||
<p>Now onward into this new, fresh year and towards that elusive Evennia 1.0 ...</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 06 Jan 2022 00:00:00 GMT</pubDate><guid isPermaLink="true">2022.html#2022-01-06-into-2022-with-thanks-and-plans</guid></item><item><title> The blog moved!</title><link>2021.html#2021-11-18-the-blog-moved!</link><description><p><img src="images/to_greener_pastures_by_griatch_art_smallview.jpg" alt="to greener pastures image by Griatch" /></p>
|
||
<p>If you are reading this, you may notice that this blog has moved from <a href="https://evennia.blogspot.com/">its old home</a> over on blogspot. I had no issues with blogspot except for the fact that writing the blog itself was done in a rather clunky editor with limited support for code.</p>
|
||
<p>Every other text in Evennia (docs, comments etc) is written in <a href="https://en.wikipedia.org/wiki/Markdown">markdown</a> and I figured it would be nice to be able to use that also for my dev blog.</p>
|
||
<p>So I put together my own little blog platform.</p>
|
||
<h2>Making a little blog platform</h2>
|
||
<p>I have rather small requirements - I don&#x27;t publish a crazy amount of Evennia devblogs and I&#x27;m fine with making a git commit to do so.</p>
|
||
<p>I already use github pages for the <a href="https://www.evennia.com">Evennia homepage</a> and <a href="https://www.evennia.com/docs">documentation</a>. These are simply html pages located in a <code>gh-pages</code> branch of the main <code>evennia</code> repo. So I decided I would just post my blog posts in a folder and then run a markdown parser to turn it into publisheable HTML pages.</p>
|
||
<h3>The tools</h3>
|
||
<p>Markdown was originally made to be converted to HTML and there is a plethora of markdown parsers for Python. I also wanted an easy way to insert my text into HTML template; this is also a well-solved problem. So these are the tools I used:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/miyuchina/mistletoe">mistletoe</a> is a pure-Python markdown-&gt;HTML parser. I had never used it before but it was easy to use and very fast. It also supports the <code>CommonMark</code> Markdown spec (same as github). I could also easily have it use <a href="https://pygments.org/">pygments</a> to add code-highlighting to code snippets.</li>
|
||
<li><a href="https://jinja.palletsprojects.com/en/3.0.x/">jinja2</a> is a way to embed special tags in HTML &quot;templates&quot; that can then be programmatically filled with content. It&#x27;s very similar to the Django templating language.</li>
|
||
</ul>
|
||
<h3>The posts</h3>
|
||
<p>I then decided that each blog post should be one markdown file with a file name <code>YYYY-MM-DD-The-post-name.md</code>. So this current devblog has a file name of <code>2021-11-18-The-blog-moved.md</code>.</p>
|
||
<p>In its simplest form, the date and name of the blog is just parsed from the filename (also makes it easy to find in the file system). But I also decided that each post could have a little optional meta-header for customizing things:</p>
|
||
<pre><code>title: The blog moved!
|
||
date: 2021-10-11
|
||
copyrights: Image: [©Griatch](https://deviantart.com/griatch-art)
|
||
|
||
---
|
||
|
||
Here the blog starts...
|
||
</code></pre>
|
||
<p>The <code>title</code> is mainly to be able to add characters like <code>!</code> or <code>?</code> that I don&#x27;t want to add to the file name. I&#x27;ve not used the <code>date</code> yet, but I guess one could use it to publish a text at a different date than the filename (not sure why one would want that ...). The <code>copyrights</code> is to properly credit any resources (mostly images) used.</p>
|
||
<p>I wrote my own <code>build_devblog.py</code> program that simple reads all <code>.md</code> files from a directory. It figures out the date and title (from file name or meta-header) and runs <code>mistletoe</code> on it. I create a dataclass with all the post-relevant properties on it. So far so good. Now we need to inject this into an HTML structure.</p>
|
||
<h3>The html</h3>
|
||
<p>Next I prepared a little <code>post.html</code> Jinja template:</p>
|
||
<pre><code class="language-jinja">&lt;h1 id={{ blogpost.anchor }}&gt;
|
||
{{ blogpost.title }}
|
||
&lt;a class=&quot;devblog-headerlink&quot; href=&quot;{{ blogpost.permalink }}&quot; title=&quot;Permalink to this blog post&quot;&gt;¶&lt;/a&gt;
|
||
&lt;div class=&quot;devblog-title-date&quot;&gt;- {{ blogpost.date_pretty }}&lt;/div&gt;
|
||
&lt;/h1&gt;
|
||
{{ blogpost.html }}
|
||
&lt;footer class=&quot;devblog-footer&quot;&gt;
|
||
&lt;span class=&quot;devblog-copyrights&quot;&gt;
|
||
{{ blogpost.image_copyrights }}
|
||
&lt;/span&gt;
|
||
&lt;a class=&quot;devblog-to-toplink&quot; href=&quot;{{ blogpost.permalink }}&quot; title=&quot;Link to top of post&quot;&gt;⇬(top)&lt;/a&gt;
|
||
&lt;/footer&gt;
|
||
</code></pre>
|
||
<p>Above, the <code>blogpost</code> is a dataclass made available to Jinja, from which it reads and inserts data into the HTML using the <code>{{ ... }}</code> templating fields.
|
||
I wanted each individual blog post to have a permalink, so that you could refer to it. I also decided that I would group all blog posts from a year into one HTML page, so <code>2021.html</code>, <code>2020.html</code> etc. Within each page, the blog post is just an anchor. So the link to this post is</p>
|
||
<pre><code> https://www.evennia.com/devblog/2021.html#2021-11-18-The-blog-moved
|
||
</code></pre>
|
||
<p>which seems quite clear.</p>
|
||
<p>For the entire year of devblogs, I stole the template used by the main <code>evennia.com</code> page, and also used the same CSS file (it&#x27;s all in the same repo after all). Jinja allows you to do simple <code>for</code> loops within the template so it&#x27;s easy to add all posts into a page.</p>
|
||
<h3>The CSS</h3>
|
||
<p>The final bit was to clean up the CSS and make a little &#x27;calendar&#x27; in the sidebar to make it easy to navigate to older devblogs. In the wide-page view you can hover over the blog dates to see their names for easy lookup.</p>
|
||
<h3>Converting the old blog</h3>
|
||
<p>Google (which owns blogspot (formar Blogger) has an export feature but the result of this is a very dense XML file. It&#x27;s mainly intended to be imported by Wordpress or some other existing blog platform. In the end I gave up on trying to parse it.</p>
|
||
<p>Instead I went the dumb route and just copy&amp;pasted each of my old blogs from the old blog into Obsidian, which I use for markdown editing. Luckily this worked very well - all layout was retained and converted automatically to markdown syntax, including links to images etc. I only needed to add some nicer markup for code strings (since that was not a thing on blogspot).</p>
|
||
<p>I don&#x27;t know if I have Obsidian to thank for this or if blogspot uses some standardized format, but manually converti of all my devblogs since 2012 thus ended up being a lot less painful than I thought (for once).</p>
|
||
<h3>Things lost in move</h3>
|
||
<p>There are a few things that were possible on blogspot that my simple little custom platform cannot do.</p>
|
||
<ul>
|
||
<li>Online editing: I&#x27;m not posting things on the fly so I&#x27;m fine with making a commit. Writing in a proper text editor is more confortable anyway. And the posts are under version control too!</li>
|
||
<li>Comments: Few people every commented directly in the old blog though - and lately it has mostly been spam. To comment, people&#x27;ll need to use our forums on github or the support channel.</li>
|
||
<li>Notifications: <del>I haven&#x27;t added an RSS feed for this page and there is thus no automatic reporting of new posts in chat etc. I think the amount of posts I do is low enough that I can advertise them manually. I&#x27;ll probably just make a dedicated announcement thread in Github discussions.</del>
|
||
<strong>Update</strong>: I added an RSS feed now, see the little <img src="images/rss-icon.png" alt="rss-feed" /> icon on the top-right of this page.</li>
|
||
</ul>
|
||
<h2>Onward</h2>
|
||
<p>So, with this new blog platform in place (this post is the first one I write using the new system), I won&#x27;t update the old one anymore. The old one&#x27;s not going anywhere though, and I will point here from it.</p>
|
||
<p>The new Evennia site ecosystem is getting a little more compact. These are services hosted on github/github pages:</p>
|
||
<ul>
|
||
<li>Homepage - <a href="https://www.evennia.com">https://www.evennia.com</a></li>
|
||
<li>Docs - <a href="https://www.evennia.com/docs">https://www.evennia.com/docs</a></li>
|
||
<li>Devblog - <a href="https://www.evennia.com/devblog">https://www.evennia.com/devblog</a></li>
|
||
<li>Forums - <a href="https://github.com/evennia/evennia/discussions">https://github.com/evennia/evennia/discussions</a></li>
|
||
<li>Code - [https://github.com/evennia/evennia](https://github.com/evennia/evennia</li>
|
||
</ul>
|
||
<p>At this point, the only things running elsewhere (and which will continue doing so) are:</p>
|
||
<ul>
|
||
<li><a href="https://games.evennia.com">https://games.evennia.com</a> - runs on Google App Engine</li>
|
||
<li><a href="https://demo.evennia.com">https://demo.evennia.com</a> - Digital Ocean droplet</li>
|
||
<li><a href="https://discord.gg/AJJpcRUhtF">https://discord.gg/AJJpcRUhtF</a> - Discord server (duh)</li>
|
||
</ul>
|
||
<p>There is also an old version of the docs on <code>ReadTheDocs</code>. This is out of date and should be removed ...</p>
|
||
<p>But overall, the Evennia ecosystem is getting more and more cleaned up as we (slowly) approach the release of Evennia 1.0 ...</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 18 Nov 2021 00:00:00 GMT</pubDate><guid isPermaLink="true">2021.html#2021-11-18-the-blog-moved!</guid></item><item><title> Where do I begin?</title><link>2021.html#2021-03-21-where-do-i-begin?</link><description><blockquote>
|
||
<p><em>This is a repost of an article I originally wrote for the Imaginary Realities e-zine, Volume 7, issue 3 back in 2015. It&#x27;s not Evennia-specific but meant for a wider audience interested in making a text-based multiplayer game (MUD/MU*). Since IR is no longer active, I repost it here with only some minor cleanup.</em></p>
|
||
</blockquote>
|
||
<p>When a new user has everything installed and drops into Evennia’s IRC support chat or mailing list, there is one question that we regularly get in various variations:</p>
|
||
<p><img src="images/yellow_world_by_griatch_art-d7a6e5n.jpg" alt="painted image of the beginning of a road in autumn" /></p>
|
||
<p><em>“Where do I begin?”</em><br />
|
||
How to actually start down that long road towards your own game is an important question. Unfortunately it has no one-size-fits-all answer. So it usually leads to a series of counter-questions. In this article I will try to (without being Evennia-specific) pose those questions in a way that would not fit in a chat window.</p>
|
||
<pre><code>
|
||
</code></pre>
|
||
<h2>What is your motivation for doing this?</h2>
|
||
<p>So you want to make a game. First you need to make a few things clear to yourself.</p>
|
||
<p>Making a multiplayer online game is a big undertaking. You will (if you are like most of us) be doing it as a hobby, without getting paid. And you’ll be doing it for a long time.</p>
|
||
<p>So the very first thing you should ask yourself (and your team, if you have any) is why am I doing this? Do some soul-searching here. Here are some possible answers:</p>
|
||
<ul>
|
||
<li>I want to earn recognition and fame from my online community and/or among my friends.</li>
|
||
<li>I want to build the game so I can play and enjoy it myself.</li>
|
||
<li>I want to build the same game I already play but without the bad people.</li>
|
||
<li>I want to create a game so that I can control it and be the head honcho.</li>
|
||
<li>A friend or online acquaintance talked me into working on it.</li>
|
||
<li>I work on this because I’m paid to (wow!)</li>
|
||
<li>I only build this for my own benefit or to see if I can pull it off.</li>
|
||
<li>I want to create something to give back to the community I love.</li>
|
||
<li>I want to use this project as a stepping-stone towards other projects (like a career in game design or programming).</li>
|
||
<li>I am interested in coding or server and network architectures, making a MUD just seems to be a good way to teach myself.</li>
|
||
<li>I want to build a commercial game and earn money.</li>
|
||
<li>I want to fulfill a life-long dream of game making.</li>
|
||
</ul>
|
||
<p>There are many other possibilities. How “solid” your answer is for a long-term development project is up to you. The important point is that you ask yourself the question.</p>
|
||
<p>Answering this question you may find that you should not start a new project - maybe it’s better to build on or help improve something that already exists. Maybe you find you are more of a game engine developer than a game designer. Some answers may also suggest that you are driven by emotions of revenge or disconcert - emotions that may have abated later when the project most needs your enthusiasm and motivation.</p>
|
||
<p>If your aim is to earn money your design goals may well be very different from those of a person who only builds for their own benefit.</p>
|
||
<p>Whichever your motivation, you should at least have it clear in your own mind. It’s worth to make sure your eventual team is on the same page too.</p>
|
||
<h2>What are your skills?</h2>
|
||
<p>Once you have your motivations straight you need to take stock of your own skills and the skills available in your team, if you have one.</p>
|
||
<p>Your game will have two principal components and you will need skills to cater for both:</p>
|
||
<ul>
|
||
<li>The game engine (“the code base”)</li>
|
||
<li>The assets created for using the game engine (“the game world”)</li>
|
||
</ul>
|
||
<h2>The game engine</h2>
|
||
<p>The game engine is maintained and modified by programmers (coders). It represents the infrastructure that runs the game - the network code, the protocol support, the handling of commands, scripting and data storage.</p>
|
||
<p>Creating your game engine from scratch can be a worthwhile and rewarding endeavour. It is however not a small one and if your main goal is to create a running game I would recommend building on an existing engine. It’s worth to take your time and do your research here. Searching the net and various MUD sites will bring you a slew of options. I will give some things to look for here.</p>
|
||
<p>Whereas some engines/code bases offer a lot of pre-existing coded systems, there is no denying that your team will always need someone who either already knows some basic programming or is willing to learn it.</p>
|
||
<p>When judging which engine you want to use, consider:</p>
|
||
<ul>
|
||
<li>The engine’s community - hang out in the community/forums/chat surrounding the respective engine. Expect to need to ask a lot of “stupid” questions as you start developing (hint: no question is stupid). Is this a community in which you would feel comfortable doing so?</li>
|
||
<li>Active development - is the code base actively maintained? If there are bugs in the engine, does it seem likely they will be fixed upstream or will you be patching bugs yourself? Or alternatively, are there many active users that can help you out with known quirks?</li>
|
||
<li>Other available documentation - does the engine come with a manual? Are there online tutorials or other help resources to read?</li>
|
||
<li>Which language is the engine coded in? What is it scripted in? Do you or your team already know this language or are you willing to learn it?</li>
|
||
<li>If you don’t know the language, do a few beginner tutorial so that you can at least vaguely recognize the syntax. Does the engine’s code seem easy to read and well documented? If the engine is poorly documented, the time of development may rise dramatically.</li>
|
||
<li>Something to remember here is that computers of today are very powerful. And while scaling may be interesting if your game really takes off, a text game is, for the most part, not very demanding. So I’d recommend you pick your language and engine not primarily based on performance but on what you feel comfortable and productive working with.</li>
|
||
<li>What is the engine’s license? This is mainly important if you plan to ever earn money with your game. Some common engines explicitly forbid commercial use.</li>
|
||
</ul>
|
||
<h2>Asset creation</h2>
|
||
<p>Compared to the level of work needed to produce professional graphics for an MMORPG, detailed text assets for a mud are cheap to create. This is one of the many reasons muds are so well suited for a small team.</p>
|
||
<p>This is not to say that making “professional” text content is easy though. Knowing how to write imaginative and grammatically correct prose is only the minimal starting requirement. A good asset-creator (traditionally called a “builder”) must also be able to utilize the tools of the game engine to its fullest in order to script events, make quests, triggers and interactive, interesting environments.</p>
|
||
<p>Some game engines will offer generic online building tools while others will depend on the coders to create tools specific for their game. What you go for may be influenced by just how technically savvy your builders are and what skills they are willing to pick up along the way.</p>
|
||
<p>Your team’s in-house builders will be the first ones to actually “use” your game framework and build tools. They will stumble on all the bugs. This means that you need people who are just not “artsy” or “good with words”. Assuming coders and builders are not the same people, builders need to be able to collaborate well and give clear and concise feedback.</p>
|
||
<h2>So, where <em>do</em> I begin?</h2>
|
||
<p>Right, after all this soul-searching and skill-inventory-checking, let’s go back to the original question. And maybe you’ll find that you have a better feeling for the answer yourself already:</p>
|
||
<ul>
|
||
<li>If you are learning a new programming language, you should follow basic tutorials so that you can read, understand and replicate example code without being completely in the dark.</li>
|
||
<li>If you have decided on your game engine you should dive into its manual and basic tutorials. Also make sure to introduce yourself to its community so you can get as much help as possible.</li>
|
||
<li>If the game engine offers tutorials on making some small example game, do that carefully. Even if the resulting demo game has nothing to do with what you aim to build. If there are no tutorials maybe you can instead find a full example code that you can examine in the same way. Not only will this give you a better understanding of how parts of the engine hangs together, it will also give you ideas for what you can do with it. If something is surprisingly easy to do, you might even be able to expand your plans!</li>
|
||
<li>If your game engine comes with pre-made game tools or building commands, the builders can start getting familiar with it. But keep in mind that these will not reflect the full capabilities of the game - your game is not yet built! So don’t set builders off to build large zone projects at this point. If they are building anything at all, it should be small test areas in order to agree on a homogenous form, mood and literary style.</li>
|
||
</ul>
|
||
<p>With a few tutorials and game examples under your belt you are ready to start some preliminary coding-tests of your own. You won’t be making a full game yet! Working without a step-by-step tutorial will give you an idea of just how easy or hard this stuff is to figure out in practice at your current skill level, chosen game engine and language. Make ample use of any manuals, help channels or other resources you can find - anything you will also have access to when you code the real thing. This allows you to judge the quality and usefulness of those resources at the same time.</p>
|
||
<p>You or any builders may also get some building exercise here, using the commands and objects you create for simple testing. Here is a list of things to try out (you should be able to do these in any game engine worth its salt):</p>
|
||
<ul>
|
||
<li>Change some phrasing in the output of an already existing command.</li>
|
||
<li>Make a new command and add it to the game engine. Make it just echo back whatever argument you give it.</li>
|
||
<li>Code an object that echoes “tick” to everyone at its location every 20 seconds.</li>
|
||
<li>Make a new command that creates new ticking objects where you are, but with a name given by you.</li>
|
||
<li>Make a room whose description changes every time you enter it.</li>
|
||
<li>Make an object that deletes itself when its “health” property is changed to zero.</li>
|
||
<li>Make an “attack” command that randomly reduces the “health” property of a target object until it deletes itself.</li>
|
||
<li>These are all simple things but it should give you an idea of what your chosen game engine is capable of and, most importantly, where to find help when you get stuck. If you can’t get past this step even with help you might need to go back and read up on the programming bit some more. Or maybe you should consider an easier game engine.</li>
|
||
</ul>
|
||
<h2>What is your scope?</h2>
|
||
<p>We are now past the “things to do first”. Welcome to the things you do later.</p>
|
||
<p>To reiterate, at this point you should have pondered why you are doing this and made an inventory of your available skills. You have gotten a first taste of the kind of coding work you will need to do and what that entails. You have built a few things to see how that works. Maybe you even changed game engine somewhere in the middle. Still ready to roll? Excellent.</p>
|
||
<p>You should now hopefully have enough information to be able to realistically set the scope of your game.</p>
|
||
<p>Everyone wants to make the best game ever. You want a whole world simulated in minute detail with next-generation artificial intelligence. You want instant action that puts Hollywood to shame and emergent storytelling worthy of Shakespeare.</p>
|
||
<p>It’s okay to dream big, but your first goal now is to get something out. Something that players can actually connect to and give feedback on. Having players enjoying an early version of your game is a great motivational boost in itself, you should try to reach that stage quickly. You are aiming for a first version, not the ultimate version. All online mmo:s keep improving the game after release, that’s the name of the game.</p>
|
||
<p>So keep your grand plans in mind but limit your scope for your first release. For a group of hobbyist developers (which is, frankly what almost all MU* development teams are) your motivational time is precious. You are likely not getting paid during development which means that it’s imperative that you set out to create something you are capable of finishing while still having fun. Adjust the scope to fit this time. If you run out of steam before this time you’ll know you went for too big a scope.</p>
|
||
<h2>How to continue from here?</h2>
|
||
<p>How to progress is depending on your preference. Some prefer to just jump straight into coding and figure out things as they go. It&#x27;s not a bad idea to to sit down and plan a little first though - and remember that you want <em>a first version</em> of your game at this point, not the <em>final, ultimate</em> version.</p>
|
||
<p>This is beyond the first question asked in this article (which is long enough as it is) but I have written about this process in <a href="https://evennia.com/docs/latest/Game-Planning">Evennia’s game planning documentation</a>. This reiterates some aspects of this article while expanding on others.</p>
|
||
<p>… But in the end, remember that what kills a hobby game project will usually be <em>your own lack of motivation</em>. So do whatever you can to keep that motivation burning strong! Even if it means deviating from what you read in articles like this one. Just get that game out there, whichever way works best for you.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 21 Mar 2021 00:00:00 GMT</pubDate><guid isPermaLink="true">2021.html#2021-03-21-where-do-i-begin?</guid></item><item><title> Happy New Years 2021!</title><link>2021.html#2021-01-01-happy-new-years-2021!</link><description><p><a href="https://1.bp.blogspot.com/-QtfaDoIwzkA/X-8XYiPQ27I/AAAAAAAALm4/2-EHKh3IaYMNeoj6WykJvhPccJeJ1KD7QCLcBGAsYHQ/s2048/1a1-sydney_new_years_eve_2008.jpeg"><img src="https://1.bp.blogspot.com/-QtfaDoIwzkA/X-8XYiPQ27I/AAAAAAAALm4/2-EHKh3IaYMNeoj6WykJvhPccJeJ1KD7QCLcBGAsYHQ/s320/1a1-sydney_new_years_eve_2008.jpeg" alt="" /></a></p>
|
||
<p>Another year passed with Evennia, the Python MU* creation system. The past year saw a lot of bug fixing and more gradual additions and in September we released version 0.9.5. This was an intermediary version on our way to 1.0. Time to look forward to next year.</p>
|
||
<p>On my development horizon for 2021 are the main new features planned for v1.0. Some of these are rather big things I&#x27;ve wanted to get around to for a while. They are all happening in the <em>develop</em> branch of Evennia, which is currently <em>not</em> recommended for general use.</p>
|
||
<ul>
|
||
<li><strong>SessionDB:</strong> In the current Evennia, Sessions (the representation of a single client connection) is an in-memory entity. This is changing to be a database-backed entity instead. One will be able to typeclass Sessions like other entities for easier overriding. This change also means that there will be one single point of session-id (the django-session), alleviating some reported issues where the Portal- and Server-side sessions have drifted out of sync. It will also make it a lot easier to support auto-logins, also across server reboots. Db-backed Sessions will also simplify the Portal-Session interaction a lot.</li>
|
||
<li><strong>Script refactor:</strong> The Scripts will see some refactoring, mainly because they are used more as general-storage entities compared to the timers they were originally meant to be. These days Evennia also offers a range of other timer-mechanisms (tickers, delays, Events etc), so it&#x27;s less important to rely on Scripts for this functionality. The most important change will be that the timer will required to be explicitly started (instead of always starting on script-creation). It will also be possible to stop the timer without the script getting deleted (so separating the timer from the Script&#x27;s life-cycle).</li>
|
||
<li><strong>Channel refactor:</strong> The Channels will also see changes; notably to make it considerably easier to override and customize them per-caller. Today the Channel typeclass has a maze of different hooks being called, but it&#x27;s harder for devs wanting users to customize their channel output. So one of the changes will be new hooks on the account/object level for allowing to format the channel output per-user. There will also be a cleanup of the existing hooks to make things clearer.</li>
|
||
<li><strong>New starting tutorial:</strong> As part of the new documentation, I&#x27;m writing a new starting-tutorial. This will consolidate many of the existing beginner tutorials in a consistent sequence and if following it to the end, the reader will have created a small beginner game with everything in place. I plan to make a few new contribs to support this.</li>
|
||
<li><strong>Contrib restructure:</strong> Our contrib/ folder is getting a little cluttered. I&#x27;m investigating organizing things a little differently by at least moving things into categorized folders. This will lead to people having to change their imports, but we&#x27;ll see just how it goes.</li>
|
||
<li><strong>Documentation cleanup:</strong> There are a lot of small changes, cleanup and restructuring needed in the docs overall - many of the existing pages are auto-translated from the old wiki and need rewriting both in style and content. The whole idea of moving to the new doc-system is to be able to update the docs alongside the code changes. So hopefully the changes to Sessions, Scripts and Channels etc will all be covered properly from the onset rather than after release (as was the case with the wiki).</li>
|
||
<li><strong>Unittest coverage:</strong> Our current test coverate is 64%, we need to expand this. I hope to get to at least 70% before v1.0 but that is less of a strict goal.</li>
|
||
<li><strong>Evennia PYPI package:</strong> This will be one of the last things before the release of 1.0 - Evennia will be put onto PYPI so you can install with <strong>pip install evennia</strong>. Once we do it will simplify the install instructions dramatically for those not interested in contributing to Evennia proper.</li>
|
||
</ul>
|
||
<p>We also have some pull-requests in the making that will be interesting to have in the system, such as Volund&#x27;s plugin system, making it easier to inject custom settings on the fly (good for contribs wanting to add their own database tables, for example).</p>
|
||
<p>A lot of work to do as usual!</p>
|
||
<p><strong>Thanks</strong> for the past year, everyone - thanks to all of you that contributed to Evennia with code or by reporting issues or coming with feedback. Thanks particularly to those of you willing (and able) to chip in with some financial support for Evennia development - that&#x27;s very encouraging!</p>
|
||
<p>And finally, a big thanks to all of you taking part in community discussions, both you asking questions and you helping to answer them tirelessly and with good cheer - you make the Evennia community the friendly, inviting place it is!</p>
|
||
<p>May all our game development move forward and our hard drives stay healthy for another year.</p>
|
||
<p>Cheers and a Happy new year,</p>
|
||
<p>Griatch</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 01 Jan 2021 00:00:00 GMT</pubDate><guid isPermaLink="true">2021.html#2021-01-01-happy-new-years-2021!</guid></item><item><title>Evennia 0.9.5 released</title><link>2020.html#2020-11-14-evennia-0.9.5-released</link><description><p><a href="https://1.bp.blogspot.com/-WACefg23bBA/X6_6vGTcjbI/AAAAAAAALh0/4FtZQDj5XosG_Dnyj6e-8ScHwyOTaOSzQCLcBGAsYHQ/s1544/evennia_screenshot.png"><img src="https://1.bp.blogspot.com/-WACefg23bBA/X6_6vGTcjbI/AAAAAAAALh0/4FtZQDj5XosG_Dnyj6e-8ScHwyOTaOSzQCLcBGAsYHQ/s320/evennia_screenshot.png" alt="" /></a></p>
|
||
<p>As of today, Evennia 0.9.5 is out. Evennia is a Python based library and framework for creating text-based multiplayer games (MUD/MU*).</p>
|
||
<p>This is a gradual improvement halfway between 0.9 and the upcoming 1.0. So if you have been keeping up-to-date with the <em>master</em> branch of Evennia over the last year you will not notice much difference from this release (time to upgrade if you haven&#x27;t been keeping up though!).</p>
|
||
<p>While an interim release, there are still a lot of things that has happened since v0.9:</p>
|
||
<h4>Webclient improvements</h4>
|
||
<ul>
|
||
<li>
|
||
<p>Big <strong>web client</strong> improvements (courtesy of contributor friarzen) - players can now save and restore pane layouts directly in the client (so you could have a separate pane for channel chatter, another for look-returns, two input panes etc etc).</p>
|
||
</li>
|
||
<li>
|
||
<p>The layout changes makes it easier for devs to create default layouts to offer to players of their game. People in the Evennia community have already started doing very cool stuff with this, I&#x27;ll try to gather screenshots for a future blog.</p>
|
||
</li>
|
||
<li>
|
||
<p>Allow to redirect video/music to separate panes.</p>
|
||
</li>
|
||
<li>
|
||
<p>Many other fixes, such as improving the input-history behavior.</p>
|
||
</li>
|
||
</ul>
|
||
<h4>EvMenu improvements</h4>
|
||
<p><strong>EvMenu</strong> is a powerful system for creating in-game text menus.</p>
|
||
<ul>
|
||
<li>The <strong>EvMenu</strong> class was refactored to be easier to override. For example, all messages now go through <strong>EvMenu.msg</strong> which allows for easy customization. It also defaults to sending with a <strong>type</strong> of &quot;menu&quot;, making it easier to redirect menus to seprate panes in the webclient.</li>
|
||
<li>In a node, EvMenu is now accessed via the much more logically named <strong>.ndb._evmenu</strong> instead of <strong>.ndb._menutree</strong> (the old name still works for backwards compatibility, but is deprecated).</li>
|
||
<li>New optional <strong>EvMenu template</strong> system for quickly building simpler EvMenus without needing so much code. This makes it easy to catch and parse arbitrary input from the user and redirect to the correct node as needed. Creating menu nodes as functions still work (and is a lot more powerful), this can be mixed with templating to create different effects.</li>
|
||
</ul>
|
||
<h4>New settings</h4>
|
||
<ul>
|
||
<li>
|
||
<p><strong>INLINEFUNC_STACK_MAXSIZE</strong> is an integer that allows to control how big the inlinefunc nesting stacksize is.</p>
|
||
</li>
|
||
<li>
|
||
<p>New <strong>DEFAULT_CHANNELS</strong> setting to allow customization of which channels should be initialized on startup. This can be modified after initial server start.</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>CHANNEL_HANDLER_CLASS</strong> allows for specifying an alternative to the default <strong>ChannelHandler</strong> if wanting to change how Channels behave.</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>SERVER_LOG_DAY_ROTATION</strong> defines how many days the server log should run before being force-rotated (default is seven days).</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>SERVER_LOG_MAX_SIZE</strong> specifies how big the log must be before it auto-rotates (even if <strong>SERVER_LOG_DAY_ROTATION</strong> days has not passed yet).</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>PORTAL_LOG_DAY_ROTATION, PORTA_LOG_MAX_SIZE</strong> - equivalent for the Portal.</p>
|
||
</li>
|
||
</ul>
|
||
<h4>Other improvements</h4>
|
||
<ul>
|
||
<li>
|
||
<p>The <strong>EvMore</strong> pager saw big performance speedups, making the viewing of large numbers of entries much snappier. You can now also paginate <strong>EvTables</strong> directly and create custom pagers by override the <strong>EvMore class</strong> (useful if you want to e.g. do a EvTable per-page).</p>
|
||
</li>
|
||
<li>
|
||
<p>Improvement to the multi-match parser: Trying to get for example <strong>3-box</strong> will now fail with a no-found if there are only two boxes in the room (before it would show the multi-match menu).</p>
|
||
</li>
|
||
<li>
|
||
<p>New <strong>inside_rec</strong> lockfunc to recursively check if an object is inside another. Putting this on a room will thus also check the contents of any objects in the room, not only the contents themselves. Or if you had something in your wallet (a container).</p>
|
||
</li>
|
||
<li>
|
||
<p>New <strong>$random</strong> inlinefunc for producing a random number in strings.</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>TickerHandler.add()</strong> now returns a <strong>store_key</strong> to uniquely describe the ticker just added. The <strong>TickerHandler.remove()</strong> accepts a new kwarg <strong>store_key</strong> for removing the ticker - this makes it easier to manage tickers instead having to insert the full specifications of the ticker to remove it.</p>
|
||
</li>
|
||
<li>
|
||
<p>Many fixes to the <strong>spawn</strong> command and prototype functionality. The new <strong>spawn/raw</strong> flag will now return the prototype-dict so one can manually edit and copy&amp;paste it.</p>
|
||
</li>
|
||
<li>
|
||
<p>The <strong>evennia.GLOBAL_SCRIPTS</strong> container will now contain all global scripts, not only those explicitly created with the <strong>GLOBAL_SCRIPTS</strong> setting.</p>
|
||
</li>
|
||
<li>
|
||
<p>The <strong>list_to_string</strong> utility converts a list to a nice string-representation, such as <strong>[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]</strong> -&gt; <strong><em>&quot;a, b, c and d&quot;</em></strong>. The function is renamed to <strong>iter_to_string</strong> (but old name still works) and now also works with generators and will not crash even when provided a single value.</p>
|
||
</li>
|
||
<li>
|
||
<p>A lot of bug fixes and stability fixes!</p>
|
||
</li>
|
||
</ul>
|
||
<h4>See the <a href="https://github.com/evennia/evennia/blob/master/CHANGELOG.md#evennia-095-nov-2020">changelog here.</a></h4>
|
||
<h3>New documentation system</h3>
|
||
<p>The bigger change with 0.9.5 is that we are moving to a new documentation system. The details of the long road to do this is documented in <a href="">my previous post</a>. The point is that we are stopping the use of the Github wiki in favor of statically generated documentation hosted on github pages. At the same time we also move the old evennia.com website from Google-sites to Github.</p>
|
||
<p>Check it out:</p>
|
||
<ul>
|
||
<li>New evennia.com: <a href="https://evennia.com">https://evennia.com</a></li>
|
||
<li>New static documentation: <a href="https://evennia.com/docs/latest">https://evennia.com/docs/latest</a></li>
|
||
</ul>
|
||
<p>As for the docs, they will be maturing for a long time still. The old wiki will not be updated anymore, but it will also not be going anywhere in the short term. Version 0.9.5 of the docs is pretty much a copy of the wiki and I hope to not have to spend too much more work maintaining it since the wiki is still around.</p>
|
||
<p>New updates and documentation features will primarily be happening in the 1.0-dev version of the documentation. This will include refactoring all pages as well as a new intro-tutorial and many other things.</p>
|
||
<p>But that&#x27;s for future blogs ...</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 14 Nov 2020 00:00:00 GMT</pubDate><guid isPermaLink="true">2020.html#2020-11-14-evennia-0.9.5-released</guid></item><item><title>On using Markdown with Sphinx</title><link>2020.html#2020-10-20-on-using-markdown-with-sphinx</link><description><p><a href="https://1.bp.blogspot.com/-GNQ1IGvFf3o/X44OC1-OxXI/AAAAAAAALgY/OugrLSGGW7YgPDxHuG-tveB-xcCQ2RVZACLcBGAsYHQ/s207/book.png"><img src="https://1.bp.blogspot.com/-GNQ1IGvFf3o/X44OC1-OxXI/AAAAAAAALgY/OugrLSGGW7YgPDxHuG-tveB-xcCQ2RVZACLcBGAsYHQ/s0/book.png" alt="" /></a></p>
|
||
<p>Last post I wrote about the upcoming v1.0 of Evennia, the Python MU* creation engine. We are not getting to that 1.0 version quite yet though: The next release will be 0.9.5, hopefully out relatively soon (TM).</p>
|
||
<p>Evennia 0.9.5 is, as you may guess, an intermediary release. Apart from the 1.0 roadmap just not being done yet, there is one other big reason for this - we are introducing documentation versioning and for that a proper release is needed as a base to start from. Version 0.9.5 contains everything already in <em>master</em> branch, so if you have kept up-to-date you won&#x27;t notice too much difference. Here are some highlights compared to version 0.9:</p>
|
||
<ul>
|
||
<li>
|
||
<p>EvMore will paginate and properly handle both EvTables and database query output. For huge data sets, pagination can give a 100-fold speed-increase. This is noticeable e.g. in the <strong>scripts</strong> and <strong>spawn/list</strong> commands, once you have a lot of items.</p>
|
||
</li>
|
||
<li>
|
||
<p>EvMenu templating language, to make it easier to create simpler menus.</p>
|
||
</li>
|
||
<li>
|
||
<p>Webclient improvements: Cleanup of interface and the ability for players to save/load their pane layouts from the client. The developer can still provide a default for them to start out with.</p>
|
||
</li>
|
||
<li>
|
||
<p>MUD/Evennia Intro wizard to the tutorial world to explain basic game controls in an interactive way.</p>
|
||
</li>
|
||
<li>
|
||
<p>Default channels can now be defined in settings instead of having to do so from in-game.</p>
|
||
</li>
|
||
<li>
|
||
<p>New documentation system (see below).</p>
|
||
</li>
|
||
<li>
|
||
<p>Many, many bug fixes and optimizations!</p>
|
||
</li>
|
||
</ul>
|
||
<p>Many contributors helped out along the way. See the <a href="https://github.com/evennia/evennia/blob/master/CHANGELOG.md">changelog</a> where contributors of the bigger new features are listed.</p>
|
||
<h2>The path to a new documentation</h2>
|
||
<p>For many years we&#x27;ve used the Github wiki as our documentation hub. It has served us well. But as mentioned <a href="http://evennia.blogspot.com/2020/04/spring-updates-while-trying-to-stay.html">in my previous post</a>, it has its drawbacks, in particular when it comes to handling documentation for multiple Evennia versions in parallel.</p>
|
||
<p>After considering a bunch of options, I eventually went with <a href="https://www.sphinx-doc.org">sphinx</a>, because it has such a good autodoc functionality (parsing of the source-code docstrings). This is despite our wiki docs are all in markdown and I dislike restructured text quite a bit. Our code also uses friendly and in-code-readable Google-style docstrings instead of Sphinx&#x27; hideous and unreadable format.</p>
|
||
<p>Luckily there are extensions for Sphinx to handle this:</p>
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html">Napoleon</a> to convert Google-style docstrings to reST on the fly</p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://recommonmark.readthedocs.io/en/latest/index.html">recommonmark</a> to convert our markdown wiki pages to reST on compile-time</p>
|
||
</li>
|
||
<li>
|
||
<p><a href="https://holzhaus.github.io/sphinx-multiversion/master/index.html">sphinx-multiversion</a> to merge docs from one or more GIT branches into a documentation where you can select between the versions.</p>
|
||
</li>
|
||
</ul>
|
||
<p>What could go wrong? Well, it&#x27;s been quite a ride.</p>
|
||
<h4>Getting Markdown into reST</h4>
|
||
<p>Linking to things in recommonmark turned out to be very flaky. I ended up forking and merging a bunch of PRs from the project but that was not enough: Clearly this thing was not built to convert 200 pages of technical markdown from a github wiki.</p>
|
||
<p>My custom fork of recommonmark had to be tweaked a bit for my needs, such as not having to specify the <strong>.md</strong> file ending in every link and make sure the url-resolver worked as I expected. There were a bunch of other things but I will probably not merge this back, the changes are pretty Evennia-specific.</p>
|
||
<p>Even so, many of my wiki links just wouldn&#x27;t work. This is not necessarily recommonmark&#x27;s fault, but how sphinx works by grouping things into <em>toctrees</em>, something that the Evennia wiki doesn&#x27;t have.</p>
|
||
<p>Also, the recommonmark way to make a toctree in Markdown is to make a list of links - you can&#x27;t have any descriptive text, making the listing quite useless (apparently people only want bland lists of link-names?). After trying to figure out a way to make this work I eventually capitulated - I make pretty lists in Markdown while using a &quot;hidden&quot; toctree to inform sphinx how the pages are related.</p>
|
||
<h4>Getting the wiki into the new doc site</h4>
|
||
<p>This required more custom code. I wrote a custom importer that reads the wiki and cleans/reformats it in places where recommonmark just dies on them. I also made a preprocessor that not only finds orphan pages but also builds a toctree and remaps all links in all documents to their actual location on compilation. The remapper makes it a lot easier to move things around. The drawback is that every page needs to be uniquely named. Since this was already the case in the wiki, this was a good tradeoff. So with a lot of custom code the wiki eventually could port automatically.</p>
|
||
<p>The thing is, that even with all this processing, recommonmark doesn&#x27;t support stuff like Markdown tables, so you still have to fall back to reST notation for those. And Napoleon, while doing a good job of parsing google docstrings, do <em>not</em> expect Markdown. So the end result is <em>mostly</em> markdown but we still have to fall back to reST for some things. It&#x27;s probably as far as we get.</p>
|
||
<h4>Deploying the docs</h4>
|
||
<p>Figuring out how to build and deploy these components together was the next challenge. Sphinx&#x27; default Makefile was quite anemic and I also wanted something that regular contributors could use to test their documentation contributions easily. I ended up having to expand the Makefile quite a lot while also adding separate deploy scripts and interfaces to github actions (which we recently started using too).</p>
|
||
<p>Finally, the versioning. The sphinx-multiversion plugin works by extracting the branches you choose from git and running the sphinx compiler in each branch. The plugin initially had a bug with how our docs are located (not at the root of the package) but after I reported it, it was quickly fixed. The result is a static document site where you can select between the available versions in the sidebar.</p>
|
||
<p>I&#x27;ve not gotten down to trying to make LaTeX/PDF generation work yet. I&#x27;m dreading it quite a bit...</p>
|
||
<h4>Where we are</h4>
|
||
<p>The github wiki is now closed for external contributions. The v0.9.5 of the new documentation will pretty much be an import of the last state of the wiki with some minor cleanup (such as tables). While we&#x27;ll fix outright errors in it, I don&#x27;t plan to do many fixes of purely visual glitches from the conversion - the old wiki is still there should that be a problem.</p>
|
||
<p>The main refactoring and cleanup of the documentation to fit its new home will instead happen in v1.0. While the rough structure of this is already in place, it&#x27;s very much a work in progress at this point.</p>
|
||
<h4>Conclusions</h4>
|
||
<p>Evennia 0.9.5 has a lot of features, but the biggest things are &#x27;meta&#x27; changes in the project itself. After it is out, it&#x27;s onward towards 1.0 again!</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 20 Oct 2020 00:00:00 GMT</pubDate><guid isPermaLink="true">2020.html#2020-10-20-on-using-markdown-with-sphinx</guid></item><item><title>Spring updates while trying to stay healthy</title><link>2020.html#2020-04-14-spring-updates-while-trying-to-stay-healthy</link><description><p><a href="https://1.bp.blogspot.com/-vnauuJpCVfo/XpXkbERzSRI/AAAAAAAALJQ/lDoYHE6zjWsg7It_fsXn_3roGUISX2HxgCLcBGAsYHQ/s1600/spring-flower-and-snow.jpg"><img src="https://1.bp.blogspot.com/-vnauuJpCVfo/XpXkbERzSRI/AAAAAAAALJQ/lDoYHE6zjWsg7It_fsXn_3roGUISX2HxgCLcBGAsYHQ/s320/spring-flower-and-snow.jpg" alt="" /></a></p>
|
||
<p>So, spring grows nearer for those of us on the Northern hemisphere. With everyone hopefully hunkered down and safe from the Covid-19 pandemic, I thought it overdue to make another dev blog for the progress of Evennia, the Python MU*-creation system.</p>
|
||
<p>The last few months have seen primarily bug fixing on the Evennia front, but it also has seen an uptick of PRs from the community and the re-opening of the develop branch in earnest. There is still quite a lot of work to do before we can add that extra 0.1 and go from version 0.9 to 1.0.</p>
|
||
<h3>What&#x27;s in a version?</h3>
|
||
<p>For me personally, I never put much stock in the notion of versions. Evennia didn&#x27;t even have versions until a few years back: We used to just have a rolling git release. But eventually it became clear that our user base was big enough that we needed to more clearly separate major (and possibly breaking) updates from what came before. So I started versioning at Evennia 0.5 and have had roughly a new release every year since (not a plan or a promise, it just happened to turn out that way).</p>
|
||
<p>Evennia has been useful (and been used) for game development for many years already. But there is no denying that a 1.x label tends to convey more confidence in a system than a 0.x label, that&#x27;s just the way things are. So while the new version is still quite some way off, there are a bunch of changes and improvements that we want to do in this release to mark the version change in a good way.</p>
|
||
<h3>Documentation changes</h3>
|
||
<p>Our documentation will move away from our trusty <a href="https://github.com/evennia/evennia/wiki">Github wiki</a>. Instead we will convert the wiki into a static github page built from sources inside evennia/docs/.</p>
|
||
<p>The advantage of the wiki is that it is a very low entry for people to contribute and fix things using Github&#x27;s editing system. We have had a lot of use of this over the years and the wiki has served us well. The drawbacks are starting to get ever more noticeable, however:</p>
|
||
<ul>
|
||
<li>Whereas the wiki is itself version-controlled, we cannot show multiple versions of the wiki at the same time. This makes it hard to update the documentation at the same time as non-released code is being written. This is probably my main reason for doing the change.</li>
|
||
<li>The wiki today consists of some 200+ pages. It is hard to get an overview of what is where and what needs to be updated.</li>
|
||
<li>The wiki word-search functionality is not really great.</li>
|
||
<li>It&#x27;s impossible to review changes before they go live, to check consistency and style. This has led to some documentation pages overlapping.</li>
|
||
<li>Building the documentation to local HTML or PDF is an archaic process that I doubt anyone but me has done with any regularity.</li>
|
||
</ul>
|
||
<p>The change so far planned is to switch to the <a href="https://www.sphinx-doc.org/en/master/">Sphinx</a> documentation build-system (same as Python/Django etc is using). We will use it with extensions that allows us to still use Markdown like in the old wiki. This also allows us to build a more comprehensive (and pretty) API documentation of the entire library. We have more options to add comprehensive online search functionality in this solution as well.</p>
|
||
<p>Furthermore, will hopefully be able to set it up so that we can maintain and publish separate documentations for each forthcoming release. That is, you should be able to read the docs for 1.0, 1.1 or the latest master development as you like (similarly to how Django does it, although probably not as fancy from the onset).</p>
|
||
<p>This means that contributions to the documentation will be done as PRs through GitHub, just like when contributing any other code. While this does add a little more of a hurdle to contributions, hopefully the benefits will far outweigh those. Building the docs locally will not require a running Evennia server (unless you want the api docs) and we will try to set everything up for to make it easy to contribute.</p>
|
||
<p>Many of the details around the docs are still up in the air. This is still very much work-in-progress, like everything else.</p>
|
||
<p>Work with this has started in the static-file-docs branch of Evennia. But we have not closed the wiki either - the two will exist in parallel for now.</p>
|
||
<h3>PyPi</h3>
|
||
<p>As mentioned before, we will finally start to distribute Evennia via PyPi (the Python Package Index) - that is, you will be able to run <code>pip install evennia</code>. Using GIT will no longer be a requirement to get started.</p>
|
||
<p>Considering how quickly people in open-source throw up their three lines of code on PyPi these days, it may be surprising Evennia is not already on PyPi. I have however felt that reading and referencing the highly-commented code is a big part and requirement for getting the most out of the library.</p>
|
||
<p>With the new documentation system, this would improve. And you can of course still use git and follow master branch like the good ol&#x27; days if you want!</p>
|
||
<h3>Web Admin improvements</h3>
|
||
<p>For the longest time, the Django-admin component has been somewhat on the back-burner. With the help of community contributors, this is improving so you will be able to do more work the Admin GUI related to creating and managing objects, tie puppets to Accounts etc.</p>
|
||
<h3>API improvements</h3>
|
||
<p>Whereas the last few months have been mostly spent fixing lingering bugs, one thing planned for version 1.0 is a general cleanup of legacy strangeness in the API. For example, certain methods can return a list or a single object depending situation, which makes it hard to generalize. There are a lot of small quirks like that which we hope to address and make more consistent.</p>
|
||
<p>There has also been a recent flurry of contributor PRs intended to help decouple Evennia&#x27;s systems and make them easier to replace for those inclined to do so. Many of this is still being worked on, but it&#x27;s likely you&#x27;ll be able to replace many more &quot;core&quot; components for 1.0 with your own variations without doing any hacking in upstream code at all.<br />
|
||
... Needless to say, this is an advanced feature that most developers will never need. But Evennia was always intended to be heavily customizable and having the option is a good thing!</p>
|
||
<p>Another feature that will come for 1.0 is a REST-API, added by one of our contributors. This uses Django-REST-Framework and makes it easier for external programs to authenticate and fetch data out of the Evennia database (great both for external apps, websites or custom what-have-you).<br />
|
||
At this time you can only fetch database objects via this interface, you cannot perform Command-calls or &quot;play the game&quot; this way (REST is a stateless concept and Evennia Commands tend to retain state).</p>
|
||
<h3>Many other fixes and contributions</h3>
|
||
<p>There&#x27;s a truckload of stuff already available in master branch, but with the latest contributions of bigger code changes, we have started to use the Evennia develop branch again in earnest again. For a summary of the changes so far, check out the <a href="https://github.com/evennia/evennia/blob/develop/CHANGELOG.md">Changelog</a>.</p>
|
||
<p>However, unless you want to contribute to Evennia itself (or really, really want to be on the bleeding edge), you are still recommended to use the master branch for now. A lot of work still to do, as said.</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 14 Apr 2020 00:00:00 GMT</pubDate><guid isPermaLink="true">2020.html#2020-04-14-spring-updates-while-trying-to-stay-healthy</guid></item><item><title>Blackifying and fixing bugs</title><link>2019.html#2019-09-30-blackifying-and-fixing-bugs</link><description><p><a href="https://1.bp.blogspot.com/-Ez3s-a2ja-8/XZIg4EA7wUI/AAAAAAAAK7I/rYyRh8tvpQkjRnd-VJe9AUzI9g4ZwKb9wCLcBGAsYHQ/s1600/black-beetle-on-concrete_800.jpg"><img src="https://1.bp.blogspot.com/-Ez3s-a2ja-8/XZIg4EA7wUI/AAAAAAAAK7I/rYyRh8tvpQkjRnd-VJe9AUzI9g4ZwKb9wCLcBGAsYHQ/s320/black-beetle-on-concrete_800.jpg" alt="" /></a></p>
|
||
<p>Since <a href="http://evennia.blogspot.com/2019/07/evennia-09-released.html">version 0.9</a> of <a href="http://www.evennia.com/">Evennia</a>, the MU*-creation framework, was released, work has mainly been focused on bug fixing. But there few new features also already sneaked into master branch, despite technically being changes slated for Evennia 1.0.</p>
|
||
<h2>On Frontends</h2>
|
||
<p>Contributor friarzen has chipped away at improving Evennia&#x27;s HTML5 web client. It already had the ability to structure and spawn any number of nested text panes. In the future we want to extend the user&#x27;s ability to save an restore its layouts and allow developers to offer pre-prepared layouts for their games. Already now though, it has gotten plugins for handling both graphics, sounds and video:</p>
|
||
<p><a href="https://1.bp.blogspot.com/-pd6LQR70OkU/XZIaSIo__6I/AAAAAAAAK68/LoHgTq4xW58aHQvH-OHEqd7QfCcBUgZRgCLcBGAsYHQ/s1600/Screenshot%2Bfrom%2B2019-09-30%2B17-06-58.png"><img src="https://1.bp.blogspot.com/-pd6LQR70OkU/XZIaSIo__6I/AAAAAAAAK68/LoHgTq4xW58aHQvH-OHEqd7QfCcBUgZRgCLcBGAsYHQ/s400/Screenshot%2Bfrom%2B2019-09-30%2B17-06-58.png" alt="" /></a></p>
|
||
<blockquote>
|
||
<p><em>Inline image by me (deviantart.com/griatch-art)</em></p>
|
||
</blockquote>
|
||
<p>A related fun development is Castlelore Studios&#x27; development of an <a href="https://www.unrealengine.com/marketplace/en-US/slug/evennia-plugin">Unreal Engine Evennia plugin</a> (this is unaffiliated with core Evennia development and I&#x27;ve not tried it, but it looks pretty nifty!):</p>
|
||
<p><a href="https://cdn1.epicgames.com/ue/product/Screenshot/EvenniaPlugin1920x1080-2-1920x1080-4705074bbe9ecdc688a46880506eb419.png"><img src="https://cdn1.epicgames.com/ue/product/Screenshot/EvenniaPlugin1920x1080-2-1920x1080-4705074bbe9ecdc688a46880506eb419.png" alt="" /></a></p>
|
||
<blockquote>
|
||
<p><em>Image ©Castlelore Studios</em></p>
|
||
</blockquote>
|
||
<h2>On Black</h2>
|
||
<p>Evennia&#x27;s source code is extensively documented and was <em>sort of</em> adhering to the Python formatting standard PEP8. But many places were sort of hit-and-miss and others were formatted with slight variations due to who wrote the code.</p>
|
||
<pre><code>
|
||
</code></pre>
|
||
<p>After pre-work and recommendation by Greg Taylor, Evennia has adopted the <a href="https://pypi.org/project/black/">black autoformatter</a> for its source code. I&#x27;m not really convinced that black produces the best output of all possible outputs every time, but as Greg puts it, it&#x27;s at least consistent in style. We use a line width of 100.</p>
|
||
<p>I have set it up so that whenever a new commit is added to the repo, the black formatter will run on it. It may still produce line widths &gt;100 at times (especially for long strings), but otherwise this reduces the number of different PEP8 infractions in the code a lot.</p>
|
||
<h2>On Python3</h2>
|
||
<p>Overall the move to Python3 appears to have been pretty uneventful for most users. I&#x27;ve not heard almost any complaints or requests for help with converting an existing game.<br />
|
||
The purely Python2-to-Python3 related bugs have been very limited after launch; almost all have been with unicode/bytes when sending data over the wire.</p>
|
||
<p>People have wholeheartedly adopted the new f-strings though, and some spontaneous PRs have already been made towards converting some of Evennia existing code into using them.</p>
|
||
<p>Post-launch we moved to Django 2.2.2, but the Django 2+ upgrades have been pretty uneventful so far.Some people had issues installing Twisted on Windows since there was no py3.7 binary wheel (causing them to have to compile it from scratch). The rise of the Linux Subsystem on Windows have alleviated most of this though and I&#x27;ve not seen any Windows install issues in a while.</p>
|
||
<h2>On Future</h2>
|
||
<p>For now we&#x27;ll stay in bug-fixing mode, with the ocational new feature popping up here and there. In the future we&#x27;ll move to the <em>develop</em> branch again. I have a slew of things in mind for 1.0.</p>
|
||
<p>Apart from bug fixing and cleaning up the API in several places, I plan to make use of the feedback received over the years to make Evennia a little more accessible for a new user. This means I&#x27;ll also try reworking and consolidating the tutorials so one can follow them with a more coherent &quot;red thread&quot;, as well as improving the documentation in various other ways to help newcomers with the common questions we hear a lot.</p>
|
||
<p>The current project plan (subject to change) is <a href="https://github.com/evennia/evennia/projects/9">found here</a>. Lots of things to do!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 30 Sep 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-09-30-blackifying-and-fixing-bugs</guid></item><item><title>Evennia 0.9 released</title><link>2019.html#2019-07-04-evennia-0.9-released</link><description><p><a href="https://1.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/mNkREiXqmJM8Ilz-VmP3V-4YhazaZJIIQCPcBGAYYCw/s1600/evennia_logo_small.png"><img src="https://1.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/mNkREiXqmJM8Ilz-VmP3V-4YhazaZJIIQCPcBGAYYCw/s1600/evennia_logo_small.png" alt="" /></a></p>
|
||
<p>Last week we released <a href="http://www.evennia.com/">Evennia</a> 0.9, the next version of the open source Python MU* creation system.</p>
|
||
<p>This release is the result of about 10 months of development, featuring 771 commits, 70 closed pull requests from the community and something like 80 issues and feature/requests closed. Thanks everyone!</p>
|
||
<p>The main feature of Evennia 0.9 is that we have finally made the move to <strong>Python3</strong>. And we burn the bridges behind us; as announced in previous posts we completely drop Python2 support and move exclusively to only support the latest Python3.7.</p>
|
||
<p>Overall the move to Python3 was not too bloody (and much work towards a never published py2+3 version was already done by Evennia contributors in a separate branch earlier). The main issues I ran into were mainly in the changes in how Python3 separates strings from bytes. This became crticial since Evennia implements several connection protocols; there were a lot of edge cases and weird errors appearing where data went to and from the wire.</p>
|
||
<p>A regular user has it a lot easier though. So far people have not had too much trouble converting their games from 2.7 to 3.7. The biggest Linux distros don&#x27;t all have Py3.7 out of the box though, so that may be a concern for some, we&#x27;ll see.</p>
|
||
<p>... but Py3 is nowhere all there is to find in this release though! There are a plethora of <strong>more features</strong> in the latest Evennia, all to make it easier to make the text-based multiplayer game of your dreams.</p>
|
||
<p>You can see a <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/cOs4HWh0MFQ">summary of new features in the ML announcement</a> and even more details <a href="https://github.com/evennia/evennia/blob/master/CHANGELOG.md">in the actual CHANGELOG file</a>.</p>
|
||
<p><strong>So what&#x27;s up next?</strong></p>
|
||
<p>Now follows a period of bug-fixing and stabilizing. Maybe resolve some of those long-standing &quot;tech-dept&quot; issues and overall make Evennia more stable.</p>
|
||
<p>Eventually work will then commence (in the <strong>develop</strong> branch) on version 1.0 of Evennia. For this next release I think I&#x27;ll step back from new features a bit and focus on refactoring and cleanup of the API as well as other things around the library&#x27;s distribution, documentation and presentation.</p>
|
||
<p>But for now, onward to summer vacations.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 04 Jul 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-07-04-evennia-0.9-released</guid></item><item><title>Creating Evscaperoom Part 2</title><link>2019.html#2019-05-26-creating-evscaperoom-part-2</link><description><p><a href="https://www.deviantart.com/griatch-art/art/Say-hi-to-Mrs-Buttons-153984575"><img src="https://1.bp.blogspot.com/-qQX6D_pjg6s/XOmtdhylulI/AAAAAAAAKik/Jtzv1X6X3qYGFo0fXaoj0P-tiEUGC2j6gCLcBGAs/s320/say__hi__to_mrs_buttons_by_griatch_art_d2jof9b-fullview.jpg" alt="Jester smiling oh so sweetly" title="The Jester" /></a></p>
|
||
<p><a href="https://www.deviantart.com/griatch-art/art/Say-hi-to-Mrs-Buttons-153984575">The Jester, your &#x27;adversary&#x27;</a></p>
|
||
<p><a href="https://1.bp.blogspot.com/-JVAZ65CrRZ0/XOAWibmcrhI/AAAAAAAAKeg/CxL-ddQ5yKk6NnZIrgD7o8FcAatoNazIgCPcBGAYYCw/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-38-49.png"></a></p>
|
||
<p>This is part two of my post-mortem dev-blog about <em>Evscaperoom</em>, the multiplayer, text-based &#x27;escape room&#x27; I wrote in Python and <a href="http://www.evennia.com/">Evennia</a>. You can read the <a href="https://evennia.blogspot.com/2019/05/creating-evscaperoom-part-1.html">first part of the dev blog here</a>.</p>
|
||
<p>This was a game-jam entry I created in a month for the Mud Coder&#x27;s guild&#x27;s <a href="https://itch.io/jam/enterthemud2/rate/422945">Game Jam</a>. The theme was <em>One Room.</em> You can play the game for free in your browser or with a traditional MUD client. There are no spoilers in these blog posts.</p>
|
||
<p><em>Update: These days you can play the Evscaperoom by logging into the Evennia demo game at <a href="https://demo.evennia.com">https://demo.evennia.com</a>. It&#x27;s just one of the exits you can get through when you enter.</em></p>
|
||
<p><a href="https://evennia.blogspot.com/2019/05/creating-evscaperoom-part-1.html">The first part</a> dealt with the overall game-design aspects. This second, final part will go into details of the code and the systems I built to quickly create all the content. The code referenced here is released under the BSD license and is available <a href="https://github.com/Griatch/evscaperoom">on github</a>.</p>
|
||
<p>At the time of this post, players have played <em>Evscaperoom</em> for a little more than a week. At the end I&#x27;ll share some observations and things I learned along the way.</p>
|
||
<h2>Ease of building</h2>
|
||
<p>Over the one-month game jam, I spent about four days making the game&#x27;s &#x27;engine&#x27; and toolset with Evennia. The rest of the time was spent using those tools to actually create game content (the story, puzzles etc).</p>
|
||
<p>An important thing was that I didn&#x27;t want to do any traditional in-game &#x27;building&#x27;. That is - no logging into the game and running various commands to build objects and rooms. This is partly because I wanted rooms to be buildable on-demand, but also because I didn&#x27;t want my game to only exist in the database but in actual version-controllable python modules.</p>
|
||
<p>So all of the Evscaperoom is created in code (notably in the game <em>states</em> discussed below). This made it so that I could add unit tests to quickly find bugs and edge cases. It also made it easy to just clone the full game to an online server, init a database and run Evennia on it in a docker when time came to make it public.</p>
|
||
<h2>Overall game structure</h2>
|
||
<p><a href="https://1.bp.blogspot.com/-qB8ch7ELOKA/XOmHomllRzI/AAAAAAAAKiU/Y9dnXGPgsF4ke8odCDqCrssVJcWScCPGQCLcBGAs/s1600/Screenshot%2Bfrom%2B2019-05-25%2B20-20-17.png"><img src="https://1.bp.blogspot.com/-qB8ch7ELOKA/XOmHomllRzI/AAAAAAAAKiU/Y9dnXGPgsF4ke8odCDqCrssVJcWScCPGQCLcBGAs/s320/Screenshot%2Bfrom%2B2019-05-25%2B20-20-17.png" alt="The main Evscaperoom menu, showing the option to create a new room or join one of two existing rooms." title="Menu" /></a></p>
|
||
<h3>Main menu</h3>
|
||
<p>The game loop is simple: When you log in to the game, you get into a menu where you can create a new room to solve or join an existing one. Quitting a room brings you back to that menu. Quitting again leaves the game entirely. In between, you remain inside a single game location (&#x27;room&#x27;).</p>
|
||
<p>To make it easier for people to agree to meet up in a room, i made a little &#x27;fantasy name generator&#x27; to make unique random names of the rooms. It felt more thematic than showing room id&#x27;s. The generator combines phonemes together with some very simple logic. Not all comes out easy-to-pronounce, but the result is at least identifiable, like the Sheru and Uyoha above.</p>
|
||
<p>I decided that I should not keep empty rooms around, so whenever a room has no more players in it, it&#x27;s deleted from the database along with all its content. This means players can&#x27;t really log off and come back to the same room unless a friend stays behind. I felt it was worth keeping things clean and avoid a growing backlog of empty, unsolved rooms. It is, unfortunately, quite common for players to log in, create a room and then immediately log off.</p>
|
||
<p>I distribute <em>Evscaperoom</em> as an Evennia &#x27;game dir&#x27;. Once you&#x27;ve installed Evennia you can just clone the evscaperoom repo and start a new multiplayer server with it. While the game dir has some Evennia templates in it by default, Almost all the custom logic for this game is in <a href="https://github.com/Griatch/evscaperoom/tree/master/evscaperoom">the evscaperoom/ folder.</a> The only other modification I did was to make sure Evennia rerouted new players into the Evscaperoom menu when they connect.</p>
|
||
<h3>Room class</h3>
|
||
<p>Since all of the gameplay happens in a single room, it made sense to center all of the data-storage around a new, custom Evennia <strong>Room</strong> class. This &quot;EvscapeRoom&quot; class holds all resources for this room. Evennia makes sure to persist it all to the database for you.</p>
|
||
<p>The Evennia API provides a lot of powerful but game-general functions. Since our use-case for this game is very strictly defined, I made a slew of helper functions to cut down on boiler plate and pre-set options I wanted to always use.</p>
|
||
<p>For example, I added helper methods both for creating and finding objects in the room. On creation, all objects are tagged with the room&#x27;s unique hash, meaning that one can be sure to never have any cross-over between rooms (like accidentally finding the object in another room (that of course has the exact same name). Since I also decided to never have more than one object with a given name per room, I could make these methods very simple.</p>
|
||
<p>The room class also has helpers for finding all players in the room and for sending messages to them. It also catches players leaving so that eventual on-character variables can be cleaned.</p>
|
||
<p>Importantly, the very action of deleting the room will automatically clean all resources tied to it, keeping things tidy.</p>
|
||
<h3>Commands and Objects</h3>
|
||
<p><a href="https://1.bp.blogspot.com/-JVAZ65CrRZ0/XOAWibmcrhI/AAAAAAAAKeg/CxL-ddQ5yKk6NnZIrgD7o8FcAatoNazIgCPcBGAYYCw/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-38-49.png"><img src="https://1.bp.blogspot.com/-JVAZ65CrRZ0/XOAWibmcrhI/AAAAAAAAKeg/CxL-ddQ5yKk6NnZIrgD7o8FcAatoNazIgCPcBGAYYCw/s320/Screenshot%2Bfrom%2B2019-05-17%2B11-38-49.png" alt="This shows a list of all commands useful in the room." title="The Help screen" /></a></p>
|
||
<p>The help screen, show all top-level commands</p>
|
||
<p>As discussed in part one of this blog, the Evscaperoom, uses a &#x27;focus&#x27; mode: The player must examine/focus on an object first in order to operate or use it.</p>
|
||
<p>The basic command syntax is:</p>
|
||
<p><strong>&gt; command [target]</strong></p>
|
||
<p>The parsing I made actually allows for a more complex syntax, but in the end this was all that was really needed, since the currently &#x27;focused&#x27; object does not need to be specified. This is the process of using one object with another:</p>
|
||
<p><strong>&gt; examine key</strong></p>
|
||
<pre><code>~~ key (examining) ~~
|
||
This is a brass key.
|
||
|
||
(To unlock something with it, use insert into &lt;target&gt;)
|
||
</code></pre>
|
||
<p><strong>&gt; insert into door</strong></p>
|
||
<pre><code> You unlock the **door** with the **key**!
|
||
</code></pre>
|
||
<p>(the <em>into</em> is optional). Here, we focus on the key. We get the key&#x27;s description and a hint that you can <em>insert</em> it into things. We then insert it into the door, which is another object in the room. The <em>insert</em> command knows that we are focusing on the key already and that it should look into the room for an object door to use this with.</p>
|
||
<p>Technically, these on-object &#x27;actions&#x27; (like <em>insert</em> above), are dynamically generated. Here is an example of the key object:</p>
|
||
<pre><code class="language-python">class Key(EvscaperoomObject):
|
||
def at_focus_insert(self, caller, **kwargs):
|
||
target = kwargs[&#x27;args&#x27;]
|
||
obj = caller.search(obj)
|
||
if not obj:
|
||
return
|
||
if obj.check_flag(&quot;can_use_key&quot;):
|
||
obj.handle_insert(self)
|
||
</code></pre>
|
||
<p>Not shown here is that I made a wrapper for the &quot;no-match&quot; command of Evennia. This command fires when no other commands match. I made this instead analyze the currently &#x27;focused&#x27; object to see if it had a method at_focus_&lt;command_name&gt; on it. If so, I inject the supplied arguments into that method as a keyword argument <em>args</em>.</p>
|
||
<p>So when you focus on the key and give the <em>insert</em> command, the at_focus_insert method on the key will be called with a target to insert the key into_._ We search for the target (the door in the example), check if it even accepts keys and then pass the key to that object to handle. It would then be up to the door to figure out if this particular key unlocks it.</p>
|
||
<p>I created a library of base objects that I can just use as mixins for the object I want to create. Here&#x27;s an example:</p>
|
||
<pre><code class="language-python">from evscaperoom import objects
|
||
|
||
class Box(objects.Openable,
|
||
objects.CodeInput,
|
||
objects.Movable):
|
||
# ...
|
||
</code></pre>
|
||
<p>This class will offer actions to open, insert a code and move the object around. It will need some more configuration and addition of messages to show etc. But overall, this method-to-command solution ended up being very stable and extremely easy to use to make complex, interactive objects.</p>
|
||
<h3>Room states</h3>
|
||
<p>I think of the escape room as going through a series of <em>states</em>. A change of state could for example be that the user solved a puzzle to open a secret wall. That wall is now open, making new items and puzzles available. This means room description should change along with new objects being created or old ones deleted.</p>
|
||
<p>I chose to represent states as Python modules in a folder. To be a state, each module needs to have a global-level class <strong>State</strong> inheriting from my new <strong>BaseState</strong> class. This class has methods for initializing and cleaning up the state, as well as was for figuring out which state to go to next. As the system initializes the new state, it gets the current room as argument, so it can modify it.</p>
|
||
<p>This is a (simplified) example of a state module:</p>
|
||
<pre><code class="language-python"># module `state_001_start.py`
|
||
|
||
from evscaperoom.state import BaseState
|
||
from evscaperoom import objects
|
||
|
||
MUG_DESC = &quot;&quot;&quot;
|
||
A blue mug filled with a swirling liquid.
|
||
On it is written &quot;DRINK ME&quot; with big letters.
|
||
&quot;&quot;&quot;
|
||
|
||
class Mug(objects.EvscapeRoomObject):
|
||
def at_focus_drink(self, caller, **kwargs):
|
||
caller.msg(f&quot;You drink {self.key}.&quot;)
|
||
self.next_state() # trigger next state
|
||
|
||
class State(BaseState):
|
||
|
||
hints = [&quot;You are feeling a little thirsty...&quot;,
|
||
&quot;Drink from the mug, dummy.&quot;]
|
||
|
||
next_state = &quot;state_002_big_puzzle&quot;
|
||
|
||
def init(self):
|
||
mug = self.create_object(
|
||
Mug, key=&quot;wooden mug&quot;, aliases=[&quot;mug&quot;])
|
||
mug.db.desc = MUG_DESC.strip()
|
||
</code></pre>
|
||
<p>In this simple state, a mug is created, and when you drink from it, the next state is triggered. The base object has a helper function to trigger the next state since I found that interactive with an object is almost always the reason for switching states.</p>
|
||
<p>The state-class has a lot of useful properties to set, such as which the next state should be (this can be overridden in case of branching paths). You can also store<br />
|
||
a sequence of hints specific for that state.</p>
|
||
<h3>Informing the room</h3>
|
||
<p>I wrote the content in second-person perspective (<em>&quot;You open the door&quot;</em>). This is however a multiplayer game and I didn&#x27;t intially appreciate how many texts must also exist in a third-party form for the rest of the room to see (<em>&quot;Griatch opens the door&quot;</em>).</p>
|
||
<p>As the amount of text grew (the Evscaperoom has close to 10 000 lines of code, a lot of which is content strings), it became clear that it would not be feasible to manually supply third-persion version strings as well.</p>
|
||
<p>The solution was to add parsing and translation of pronouns and verbs (a concept I first saw on the game <em>Armageddon</em>).</p>
|
||
<p>I write the string like this:</p>
|
||
<pre><code> OPEN_TEXT = &quot;~You ~open the *door.&quot;
|
||
</code></pre>
|
||
<p>The ~ marks text that should be parsed for second/third-person use (I&#x27;ll discuss the *door marking in the next section). This I then send to a helper method that either sends it only to you (which means it comes back pretty much the same, but without the special markers) or to you <em>and</em> to the room, in which it will look different depending on who receives it:</p>
|
||
<p>I see</p>
|
||
<pre><code> You open the [door].
|
||
|
||
</code></pre>
|
||
<p>Others see</p>
|
||
<pre><code> Griatch opens the [door].
|
||
</code></pre>
|
||
<p>English is luckily pretty easy to use for this kind of automatic translation - in general you can just add an &quot;s&quot; to the end of the verb. I made a simple mapping for the few irregular verbs I ended up using.</p>
|
||
<p>Overall, this made it quick to present multiple viewpoints with minimal extra text to write.</p>
|
||
<p><a href="https://1.bp.blogspot.com/-HdLAfVl8P5A/XOAWjd_zoDI/AAAAAAAAKek/KnWDYcsFZP0w1Fb9DEFTd64BkWmnAgIFACPcBGAYYCw/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-49-20.png"><img src="https://1.bp.blogspot.com/-HdLAfVl8P5A/XOAWjd_zoDI/AAAAAAAAKek/KnWDYcsFZP0w1Fb9DEFTd64BkWmnAgIFACPcBGAYYCw/s320/Screenshot%2Bfrom%2B2019-05-17%2B11-49-20.png" alt="Shows the various accessibility options for showing items." title="option menu" /></a></p>
|
||
<blockquote>
|
||
<p>The option menu</p>
|
||
</blockquote>
|
||
<p>The *door -style marking allowed me to generalize how target-able objects in the room were displayed. This meant that users can customize how objects are shown to them. The default is to mark them both with colors and square brackets (this makes it clear also for people with screen readers). But one can also use only colors or turn off the marking completely (hard mode).</p>
|
||
<h2>Bringing it online</h2>
|
||
<p>Evennia is both a mud framework and mudserver as well as a webserver based on <a href="https://twistedmatrix.com/trac/">Twisted</a>. It runs the game&#x27;s website (with the help of <a href="https://www.djangoproject.com/">Django</a>) and also provides its own HTML5 webclient. I tweaked the default website text and played a little with CSS but otherwise didn&#x27;t spend too much time on this bit.</p>
|
||
<p>I got a $5/month DigitalOcean droplet with Ubuntu. I made a new, unprivileged &quot;evennia&quot; user on it and cloned the evscaperoom repo to it. I then started a tmux session and ran the Evennia docker image in there. Getting the game online took maybe thirty minutes, most of which was me figuring out where to open the droplet and DigitalOcean firewalls.</p>
|
||
<p>I then pointed <a href="http://experimental.evennia.com/">http://experimental.evennia.com</a> at the droplet&#x27;s IP and that was it!</p>
|
||
<p>Updating the online server is now only a matter of pushing changes to my github repo, pulling it to the server and reloading Evennia; Before release, I used a private github repo for this, afterwards I simply made it public. Pretty straightforward.</p>
|
||
<h1>Some lessons learned</h1>
|
||
<p>I have gotten pretty positive reviews on Evscaperoom so far. In the first two days people stumbled on some edge-case bugs, but after that it has been very stable. Mostly I&#x27;ve had to make small typos and grammar corrections as I (or players) spot them.</p>
|
||
<p>There were nevertheless some things I learned, some of which led to more real improvements post-launch.</p>
|
||
<h2>No amount of help is too much help</h2>
|
||
<p><a href="https://1.bp.blogspot.com/-Qd1rZr-X6So/XOpAV1O5cAI/AAAAAAAAKi0/sTtOwnqnj4Iqf5iEMHOUMhIvTJpEGSEiQCLcBGAs/s1600/Screenshot%2Bfrom%2B2019-05-26%2B09-26-49.png"><img src="https://1.bp.blogspot.com/-Qd1rZr-X6So/XOpAV1O5cAI/AAAAAAAAKi0/sTtOwnqnj4Iqf5iEMHOUMhIvTJpEGSEiQCLcBGAs/s320/Screenshot%2Bfrom%2B2019-05-26%2B09-26-49.png" alt="Shows focus on the &#x27;bed&#x27;, with an example of the header telling how to leave the &#x27;focus&#x27; mode." title="Header example" /></a></p>
|
||
<blockquote>
|
||
<p>The header shows how to get out of focus mode</p>
|
||
</blockquote>
|
||
<p>Firstly, the focus-system (examine, then do stuff) is a little un-orthodox and needs to be explained. I saw people logging in, examining exactly <em>one</em> thing and then logging out. Eventually I found out (because a user told me), that this was likely because they could not figure out how to <em>leave</em> the focus mode. They&#x27;d just flounder about, think the game was buggy and log off.</p>
|
||
<p>The answer (just run <em>examine</em> again) is found with the <em>help</em> command, but clearly this was not intuitive. The solution was to add an explicit help text to the top every time you examine something. After this, the confusion seems to have gone away.</p>
|
||
<h2>Make it easy to connect for all tastes</h2>
|
||
<p>Another example - a commenting user had pretty strong opinions about the fact that you used to have to supply a username and password to play the game. They suggested this was a &#x27;huge hurdle&#x27;. Not sure if that&#x27;s true. But unless you want to use a particular name, there is also no actual gameplay <em>reason</em> to formally authenticate for Evscaperoom.</p>
|
||
<p>This was easy to fix. Evennia has guest-player support out of the box so I just activated that and supplied some more fantasy-sounding names than the default &quot;Guest 1&quot;, &quot;Guest 2&quot; etc. Since then, maybe 40% of players connecting have chosen to do so as an anonymous guest. I don&#x27;t know if those would have left completely if the option was not available, but it&#x27;s at least a convenient shortcut for getting into the game.</p>
|
||
<h2>Everything takes longer than expected</h2>
|
||
<p>I already knew this one, but still I fell into the trap of thinking that things were going well and that there would be plenty of time to finish before deadline.</p>
|
||
<p>Creating text content is a lot faster than creating graphical assets, but it&#x27;s still a lot of work. Just the ending &#x27;cinematics&#x27; took me almost two days to finish and clean up at the end.</p>
|
||
<p>For once I did pick a reasonable scale for this project though. So while the last few days of the Jam was more intense than I would have liked, I never truly felt like I would not be able to finish in time.</p>
|
||
<h2>Building a MU* game in pure code is awesome</h2>
|
||
<p>Evennia tries to not instil and specific game type, hence its tools are very general. Wrapping these general tools as a highly opinionated and game-specific toolbox enforced to me just how <em>easy</em> it is to do things when you don&#x27;t need to cover the general case.</p>
|
||
<p>Using the tools and creating content purely in-code was great and ended up leading to a <em>very</em> fast content creation. Python works perfectly as a scripting language and I don&#x27;t think there is a reason for using in-game building at all for your game, especially not when you are working on your own like this.</p>
|
||
<p>I made a few admin-only commands to jump between states and to set flags, but otherwise most bugs were caught by a generic unit test that just looped over all founds states and tried to initialize them, one after another.</p>
|
||
<h1>Conclusions</h1>
|
||
<p>For all my work on the Evennia library/server, I&#x27;ve not actually <em>used</em> it for games of my own very much. This was a great opportunity for doing so. It also gave me the opportunity to test the Python3-development branch of Evennia in a production setting.</p>
|
||
<p>I found a few edge-case library bugs which I fixed, but overall things worked very smoothly, also for this kind of game which is certainly far away from the normal MU*-mold that most use Evennia for. I am a bit biased, but overall I felt Evennia to be very mature for the use of making a game from scratch.</p>
|
||
<p>In the future I will most likely break out the &#x27;engine&#x27; and tools of the Evscaperoom into an Evennia contrib so that others can make similar games with it easily.</p>
|
||
<p>Looking forward to future game jams now!</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 26 May 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-05-26-creating-evscaperoom-part-2</guid></item><item><title>Creating Evscaperoom Part 1</title><link>2019.html#2019-05-18-creating-evscaperoom-part-1</link><description><p><a href="https://2.bp.blogspot.com/-lfWBLhFKJjA/XOAWicyFg-I/AAAAAAAAKeM/sKHVm2iWCnAPjgvFRSuOiqe74HpDJDlEgCLcBGAs/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-36-47.png"><img src="https://2.bp.blogspot.com/-lfWBLhFKJjA/XOAWicyFg-I/AAAAAAAAKeM/sKHVm2iWCnAPjgvFRSuOiqe74HpDJDlEgCLcBGAs/s320/Screenshot%2Bfrom%2B2019-05-17%2B11-36-47.png" alt="" /></a></p>
|
||
<p>Over the last month (April-May 2019) I have taken part in the <a href="https://itch.io/jam/enterthemud2">Mud Coder&#x27;s Guild Game Jam</a> &quot;Enter the (Multi-User) Dungeon&quot;. This year the theme for the jam was <em>One Room.</em></p>
|
||
<p>The result was <a href="http://experimental.evennia.com/">Evscaperoom</a>, an text-based multi-player &quot;escape-room&quot; written in Python using the <a href="http://www.evennia.com/">Evennia</a> MU* creation system. You can play it from that link in your browser or MU*-client of choice. If you are so inclined, you can also <a href="https://itch.io/jam/enterthemud2/rate/422945">vote for it here</a> in the jam (well, no more).</p>
|
||
<p>This little series of (likely two) dev-blog entries will try to recount the planning and technical aspects of the Evscaperoom. This is also for myself - I&#x27;d better write stuff down now while it&#x27;s still fresh in my mind!</p>
|
||
<p>Update: The Evscaperoom can these days be played by connecting to the Evennia game demo at <a href="https://demo.evennia.com">https://demo.evennia.com</a>.</p>
|
||
<h2>Inception</h2>
|
||
<p>When I first heard about the upcoming game-jam&#x27;s theme of <em>One Room</em>, an &#x27;escape room&#x27; was the first thing that came to mind, not the least because I just recently got to solve my my own first real-world escape-room as a gift on my birthday.</p>
|
||
<p>If you are not familiar with escape-rooms, the premise is simple - you are locked into a room and have to figure out a way to get out of it by solving practical puzzles and finding hidden clues in the room.</p>
|
||
<p>While you could create such a thing in your own bedroom (and there are also some one-use board game variants), most escape-rooms are managed by companies selling this as an experience for small groups. You usually have one hour to escape and if you get stuck you can press a button (or similar) to get a hint.</p>
|
||
<p>I thought making a computer escape-room. Not only can you do things in the computer that you cannot do in the real world, restricting the game to a single room limits so that it&#x27;s conceivable to actually finish the damned thing in a month.</p>
|
||
<p>A concern I had was that everyone else in the jam surely must have went for the same obvious idea. In the end that was not an issue at all though.</p>
|
||
<h2>Basic premises</h2>
|
||
<pre><code>
|
||
</code></pre>
|
||
<p>I was pretty confident that I would <em>technically</em> be able to create the game in time (not only is Python and Evennia perfect for this kind of fast experimentation and prototyping, I know the engine very well). But that&#x27;s not enough; I had to first decide on how the thing should actually <em>play.</em> Here are the questions I had to consider:</p>
|
||
<h3>Room State</h3>
|
||
<p>An escape room can be seen as going through multiple <em>states</em> as puzzles are solved. For example, you may open a cabinet and that may open up new puzzles to solve. This is fine in a single-player game, but how to handle it in a multi-player environment?</p>
|
||
<p>My first thought was that each object may have multiple states and that players could co-exist in the same room, seeing <em>different</em> states at the same time. I really started planning for this. It would certainly be possible to implement.</p>
|
||
<p>But in the end I considered how a real-world escape-room works - people in the same room solves it together. For there to be any <em>meaning</em> with multi-player, they must <em>share</em> the room state.</p>
|
||
<p>So what I went with was a solution where players can create their own room or join an existing one. Each such room is generated on the fly (and filled with objects etc) and will change as players solve it. Once complete and/or everyone leaves, the room is deleted along with all objects in it. Clean and tidy.</p>
|
||
<p>So how to describe these states? I pictured that these would be described as normal Python modules with a start- and end function that initialized each state and cleaned it up when a new state was started. In the beginning I pictured these states as being pretty small (like one state to change one thing in the room). In the end though, the entire Evscaperoom fits in 12 state modules. I&#x27;ll describe them in more detail in the second part of this post.</p>
|
||
<h3>Accessibility and &quot;pixel-hunting&quot; in text</h3>
|
||
<p>When I first started writing descriptions I didn&#x27;t always note which objects where interactive. It&#x27;s a very simple and tempting puzzle to add - mention an object as part of a larger description and let the player figure out that it&#x27;s something they can interact with. This practice is sort-of equivalent to <em>pixel-hunting</em> in graphical games - sweeping with the mouse across the screen until you find that little spot on the screen that you can do something with.</p>
|
||
<p>Problem is, pixel-hunting&#x27;s not really <em>fun</em>. You easily get stuck and when you eventually find out what was blocking you, you don&#x27;t really feel clever but only frustrated. So I decided that I should <em>clearly mark every object that people could interact with</em> and focus puzzles on better things.</p>
|
||
<p>In fact, in the end I made it an option:</p>
|
||
<p><a href="https://3.bp.blogspot.com/-HdLAfVl8P5A/XOAWjd_zoDI/AAAAAAAAKek/GBrnsZDvck0rkeBW2WVLZHXNG6ePqKEjgCEwYBhgL/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-49-20.png"><img src="https://3.bp.blogspot.com/-HdLAfVl8P5A/XOAWjd_zoDI/AAAAAAAAKek/GBrnsZDvck0rkeBW2WVLZHXNG6ePqKEjgCEwYBhgL/s400/Screenshot%2Bfrom%2B2019-05-17%2B11-49-20.png" alt="Option menu (&#x27;quit&#x27; to return) 1: ( ) No item markings (hard mode) 2: ( ) Items marked as item (with color) 3: (*) Items are marked as [item] (screenreader friendly) 4: ( ) Screenreader mode" title="In-game option menu" /></a></p>
|
||
<p>As part of this I had to remind myself <em>never to use colors only</em> when marking important information: Visually impaired people with screen readers will simply miss that. Not to mention that some just disable colors in their clients.</p>
|
||
<p>So while I personally think option 2 above is the most visually pleasing, Evscaperoom defaults to the third option. It should should start everyone off on equal footing. Evennia has a screen-reader mode out of the box, but I moved it into the menu here for easy access.</p>
|
||
<h3>Inventory and collaboration</h3>
|
||
<p>In a puzzle-game, you often find objects and combine them with other things. Again, this is simple to do in a single-player game: Players just pick things up and use them later.</p>
|
||
<p>But in a multi-player game this offers a huge risk: players that pick up something important and then log off. The remaining players in that room would then be stuck in an unsolvable room - and it would be very hard for them to know this.</p>
|
||
<p>In principle you could try to &#x27;clean&#x27; player inventories when they leave, but not only does it add complexity, there is another issue with players picking things up: It means that <em>the person first to find/pick up the item is the only one that can use it and look at it</em>. Others won&#x27;t have access until the first player gives it up. Trusting that to anonymous players online is not a good idea.</p>
|
||
<p>So in the end I arrived at the following conclusions:</p>
|
||
<ul>
|
||
<li>As soon as an item/resource is discovered, <em>everyone</em> in the room must be able to access it immediately.</li>
|
||
<li>There can be <em>no inventory</em>. Nothing can ever be picked up and tied to a specific player.</li>
|
||
<li>As soon as a discovery is made, this <em>must be echoed to the entire room</em> (it must not be up to the finder to announce what they found to everyone else).</li>
|
||
</ul>
|
||
<p>As a side-effect of this I also set a limit to the kind of puzzles I would allow:</p>
|
||
<ul>
|
||
<li><em>No puzzles must require more than one player to solve</em>. While one could indeed create some very cool puzzles where people collaborate, it&#x27;s simply not feasible to do so with random strangers on the internet. At any moment the other guy may log off and leave you stuck. And that&#x27;s if you even find someone logged in at the same time in the first place! The room should always be possible to solve solo, from beginning to end.</li>
|
||
</ul>
|
||
<h3>Focusing on objects</h3>
|
||
<p>So without inventory system, how <em>do</em> you interact with objects? A trademark of any puzzle is using one object with another and also to explore things closer to find clues. I turned to graphical adventure games for inspiration:<br />
|
||
<a href="https://1.bp.blogspot.com/-hTP1HlMck3c/XOA9-qVnrHI/AAAAAAAAKew/GOVcWIfwyZIr25CZj3VadztdjeVwmzl7gCLcBGAs/s1600/1569-4-secret-of-monkey-island-the.jpg"><img src="https://1.bp.blogspot.com/-hTP1HlMck3c/XOA9-qVnrHI/AAAAAAAAKew/GOVcWIfwyZIr25CZj3VadztdjeVwmzl7gCLcBGAs/s400/1569-4-secret-of-monkey-island-the.jpg" alt="Hovering with mouse over lens object offers action &quot;look at lens&quot;" title="Monkey Island GUI" /></a></p>
|
||
<p><em>Secret of Monkey Island ©1990 LucasArts. Image from old-games.com</em></p>
|
||
<p>A common way to operate on an object in traditional adventure games is to hover the mouse over it and then select the action you want to apply to it. In later (3D) games you might even zoom in of the object and rotate it around with your mouse to see if there are some clues to be had.</p>
|
||
<p>While Evennia and modern UI clients <em>may</em> allow you to use the mouse to select objects, I wanted this to work the traditional MUD-way, by inserting commands. So I decided that you as a player would be in one of two states:</p>
|
||
<ul>
|
||
<li>The &#x27;normal&#x27; state: When you use <strong>look</strong> you see the room description.</li>
|
||
<li>The &#x27;focused&#x27; state: You focus on a specific object with the <strong>examine <target></strong> command (aliases are <strong>ex</strong> or just <strong>e</strong>). Now object-specific actions become available to you. Use <strong>examine</strong> again to &quot;un-focus&quot;.</li>
|
||
</ul>
|
||
<p><a href="https://2.bp.blogspot.com/-E-J-PZZ2KbY/XOAWidK1Y_I/AAAAAAAAKek/mcWbgVNkvVkBBZEUpOuaaWyBVkNoE7K9gCEwYBhgL/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-41-50.png"><img src="https://2.bp.blogspot.com/-E-J-PZZ2KbY/XOAWidK1Y_I/AAAAAAAAKek/mcWbgVNkvVkBBZEUpOuaaWyBVkNoE7K9gCEwYBhgL/s400/Screenshot%2Bfrom%2B2019-05-17%2B11-41-50.png" alt="A small stone fireplace sits in the middle of the wall opposite the [door]. On the chimney hangs a small oil [painting] of a man. Hanging over the hearth is a black [cauldron]. The piles of [ashes] below are cold. (It looks like fireplace may be suitable to [climb].)" title="Examining a fireplace" /></a></p>
|
||
<p>In the example above, the fireplace points out other objects you could also focus on, whereas the last parenthesis includes one or more &quot;actions&quot; that you can perform on the fireplace only when you have it focused.</p>
|
||
<p>This ends up pretty different from most traditional MUD-style inputs. When I first released this to the public, I found people logged off after their first examine. It turned out that they couldn&#x27;t figure out how to leave the focus mode. So they just assumed the thing was buggy and quit instead. Of course it&#x27;s mentioned if you care to write <strong>help</strong>, but this is clearly one step too many for such an important UI concept.</p>
|
||
<p>So I ended up adding the header above that always reminds you. And since then I&#x27;ve not seen any confusion over how the focus mode works.</p>
|
||
<p>For making it easy to focus on things, I also decided that each room would only ever have one object named a particular thing. So there is for example only one single object in the game named &quot;key&quot; that you can focus on.</p>
|
||
<h3>Communication</h3>
|
||
<p>I wanted players to co-exist in the same room so that they could collaborate on solving it. This meant communication must be possible. I pictured people would want to point things out and talk to each other.</p>
|
||
<p>In my first round of revisions I had a truckload of individual emotes; you could</p>
|
||
<p><strong>point at target</strong></p>
|
||
<p>for example. In the end I just limited it to</p>
|
||
<p><strong>say/shout/whisper <message></strong></p>
|
||
<p>and</p>
|
||
<p><strong>emote <whatever></strong></p>
|
||
<p>And seeing what people actually use, this is more than enough (<strong>say</strong> alone is probably 99% of what people need, really). I had a notion that the shout/whisper could be used in a puzzle later but in the end I decided that communication commands should be strictly between players and not have anything to do with the puzzles.</p>
|
||
<p>I removed all other interaction: There is no fighting and without an inventory or requirement to collaborate on puzzles, there is no need for other interactions than to communicate.</p>
|
||
<p>First version you didn&#x27;t even see what the others did, but eventually I added so that you at least saw what other players were focusing on at the moment (and of course if some major thing was solved/found).</p>
|
||
<p>In the end I don&#x27;t even list characters as objects in the room (you have to use the <strong>who</strong> command to see who&#x27;s in there with you).</p>
|
||
<p><a href="https://1.bp.blogspot.com/-JVAZ65CrRZ0/XOAWibmcrhI/AAAAAAAAKeg/_YopP6nWqPUqK6B3JD_54RDqvE5a_fijQCEwYBhgL/s1600/Screenshot%2Bfrom%2B2019-05-17%2B11-38-49.png"><img src="https://1.bp.blogspot.com/-JVAZ65CrRZ0/XOAWibmcrhI/AAAAAAAAKeg/_YopP6nWqPUqK6B3JD_54RDqvE5a_fijQCEwYBhgL/s400/Screenshot%2Bfrom%2B2019-05-17%2B11-38-49.png" alt="Listing of commands available in the Evscaperoom (output of the help-command in game)" title="Help command output" /></a></p>
|
||
<p>The main <strong>help</strong> command output.</p>
|
||
<h2>Story</h2>
|
||
<p>It&#x27;s very common for this type of game to have a dangerous or scary theme. Things like &quot;get out before the bomb explodes&quot;, &quot;save the space ship before the engines overheat&quot;, &quot;flee the axe murderer before he comes back&quot; etc). I&#x27;m no stranger to dark themes, but for this I wanted something friendlier and brighter, maybe with a some dark undercurrents here and there.</p>
|
||
<p>My <a href="https://www.deviantart.com/griatch-art/art/Say-hi-to-Mrs-Buttons-153984575">Jester character</a> is someone I&#x27;ve not only depicted in art, but she&#x27;s also an old RP character and literary protagonist of mine. Who else would find it funny to lock someone into a room only to provide crazy puzzles and hints for them to get out again? So my flimsy &#x27;premise&#x27; was this:</p>
|
||
<p><em>The village Jester wants to win the pie eating contest. You are one of her most dangerous opponents. She tricked you to her cabin and now you are locked in! If you don&#x27;t get out in time, she&#x27;ll get to eat all those pies on her own and surely win!</em></p>
|
||
<p>That&#x27;s it - this became the premise from which the entire game flowed. I quickly decided that it to be a very &quot;small-scale&quot; story: no life-or-death situation, no saving of the world. The drama takes place in a small village with an &quot;adversary&quot; that doesn&#x27;t really want to hurt you, but only to eat more pies than you.</p>
|
||
<p>From this, the way to offer hints came naturally - just eat a slice of &quot;hintberry pie&quot; the jester made (she even encourage you to eat it). It gives you a hint but is also very filling. So if you eat too much, how will you beat her in the contest later, even if you do get out?</p>
|
||
<p>To further the rustic and friendly tone I made sure the story took place on a warm summer day. Many descriptions describe sunshine, chirping birds and the smell of pie. I aimed at letting the text point out quirky and slightly comedic tone of the puzzles the Jester left behind. The player also sometimes gets teased by the game when doing things that does not make sense.</p>
|
||
<p>I won&#x27;t go into the story further here - it&#x27;s best if you experience it yourself. Let&#x27;s just say that the village has some old secrets. And and the Jester has her own ways of doing things and of telling a story. The game has multiple endings and so far people have drawn very different conclusions in the end.</p>
|
||
<h2>Scoring</h2>
|
||
<p>Most often in escape rooms, final score is determined by the time and the number of hints used. I do keep the latter - for every pie you eat, you get a penalty on your final score.</p>
|
||
<p>As for time - this background story <em>would</em> fit very well with a time limit (get out in X time, after which the pie-eating contest will start!). But from experience with other online text-based games I decided against this. Not only should a player be able to take a break, they may also want to wait for a friend to leave and come back etc.</p>
|
||
<p>But more importantly, I want players to explore and read all my carefully crafted descriptions! So I&#x27;d much rather prefer they take their time and reward them for being thorough.</p>
|
||
<p>So in the end I give specific scores for actions throughout the game instead. Most points are for doing things that drive the story forward, such as using something or solving a puzzle. But a significant portion of the score comes from turning every stone and trying everything out. The nice side-effect of this is that even if you know exactly how to solve everything and rush through the game you will still not end up with a perfect score.</p>
|
||
<p>The final score, adjusted by hints is then used to determine if you make it in time to the contest and how you fare. This means that if you explore carefully you have a &quot;buffer&quot; of points so eating a few pies may still land you a good result in the end.</p>
|
||
<pre><code>
|
||
</code></pre>
|
||
<h2>First sketch</h2>
|
||
<p>I really entered the game &#x27;building&#x27; aspect with no real notion of how the Jester&#x27;s cabin should look nor which puzzles should be in it. I tried to write things down beforehand but it didn&#x27;t really work for me.</p>
|
||
<p>So in the end I decided &quot;let&#x27;s just put a lot of interesting stuff in the room and then I&#x27;ll figure out how they interact with each other&quot;. I&#x27;m sure this is different from game-maker to game-maker. But for me, this process worked perfectly.</p>
|
||
<p><a href="https://1.bp.blogspot.com/-3mV7GIsQbDo/XOBI3SX6bmI/AAAAAAAAKe8/DSYB7q6otCwLkKb1JNTco6kTJ1UEbVp1ACKgBGAs/s1600/20190515_230856.jpg"><img src="https://1.bp.blogspot.com/-3mV7GIsQbDo/XOBI3SX6bmI/AAAAAAAAKe8/DSYB7q6otCwLkKb1JNTco6kTJ1UEbVp1ACKgBGAs/s640/20190515_230856.jpg" alt="Scribbles on my notebook, sketching up the room&#x27;s main items" title="Scriblles on notebook" /></a></p>
|
||
<blockquote>
|
||
<p>My first, very rough, sketch of the Jester&#x27;s cabin</p>
|
||
</blockquote>
|
||
<p>The above, first sketch ended up being what I used, although many of the objects mentioned never ended up in the final game and some things switched places. I did some other sketches too, but they&#x27;d be spoilers so I won&#x27;t show them here ...</p>
|
||
<h2>The actual game logic</h2>
|
||
<p>The Evscaperoom principles outlined above deviate quite a bit from the traditional MU* style of game play.</p>
|
||
<p>While Evennia provides everything for database management, in-game objects, commands, networking and other resources, the specifics of your game is something you need to make yourself - and you have the full power of Python to do it!</p>
|
||
<p>So for the first three days of the jam I used Evennia to build the custom game logic needed to provide the evscaperoom style of game play. I also made the tools I needed to quickly create the game content (which then took me the rest of the jam to make).</p>
|
||
<p>In part 2 of this blog post I will cover the technical details of the Evscaperoom I built. I&#x27;ll also go through some issues I ran into and conclusions I drew. I&#x27;ll link to that from here when it&#x27;s available!</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 18 May 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-05-18-creating-evscaperoom-part-1</guid></item><item><title>Podcast about Evennia</title><link>2019.html#2019-05-09-podcast-about-evennia</link><description><p><a href="https://assets.fireside.fm/file/fireside-images/podcasts/images/f/f5646c0a-3321-4158-a4fa-d4a14ec2d573/cover_medium.jpg"><img src="https://assets.fireside.fm/file/fireside-images/podcasts/images/f/f5646c0a-3321-4158-a4fa-d4a14ec2d573/cover_medium.jpg" alt="" /></a></p>
|
||
<p>I was interviewed on the (pretty grandiosely named) podcast <em>Titans of Text</em> the other day.</p>
|
||
<p>In the interview, which are run by people from the <a href="https://mudcoders.com/">MUD Coder&#x27;s Guild</a> (a great initiative!), I talk a bit about the history of Evennia, the text-based multiplayer game engine I&#x27;m working on, and go into some various technical aspects of the engine as well. Check it out and support the podcast!</p>
|
||
<p><a href="https://www.titansoftext.com/4">https://www.titansoftext.com/4</a></p>
|
||
</description><author>Griatch</author><pubDate>Thu, 09 May 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-05-09-podcast-about-evennia</guid></item><item><title>Steaming on Eating Jam</title><link>2019.html#2019-04-25-steaming-on-eating-jam</link><description><p><a href="https://3.bp.blogspot.com/-5Co5uPbwKTQ/XMF-PalVycI/AAAAAAAAKVU/EAtFXY2nqPUyecpTMagdIz1lsQwk55KVwCLcBGAs/s1600/2009-2211.jpg"><img src="https://3.bp.blogspot.com/-5Co5uPbwKTQ/XMF-PalVycI/AAAAAAAAKVU/EAtFXY2nqPUyecpTMagdIz1lsQwk55KVwCLcBGAs/s320/2009-2211.jpg" alt="" /></a></p>
|
||
<p>In the last few months, development of the upcoming <a href="http://www.evennia.com/">Evennia</a> 0.9 has been steaming on. Evennia is, as you may know, a Python library for creating text-based multiplayer games (MUDs, MUSH etc).<br />
|
||
But it&#x27;s not all backend work! There is also some sweet game-jamming going on, I get to that at the end.</p>
|
||
<h3>Evennia progress towards Python3</h3>
|
||
<p>The regular Evennia <em>develop</em> branch is now running completely in Python 3. Since we are using some new features of this Python release, we will be aiming for Python 3.7 as a minimum version once Evennia 0.9 goes stable. We will also use Django 2.1 and likely Twisted 19 - so we&#x27;ll be pretty much up-to-date on all our main dependencies.</p>
|
||
<p>Now, while the release of Evennia 0.9 is still some time away (there are a bunch of regular bug fixes and minor features that I want to get in there too (see the progress <a href="https://github.com/evennia/evennia/projects/8">here on the github 0.9 project page</a>), it&#x27;s worth to consider how much work it&#x27;ll be for you to migrate and if you should wait or jump in right now.</p>
|
||
<p>If you are new, I still recommend you use regular <em>master</em> branch Evennia (using Python 2.7). This is for which all wiki articles and documentation online is currently written after all. Once we move to python3, you&#x27;ll need to convert your code ... but syntactically the two are really not that different and conversion should not be much of an issue.</p>
|
||
<p>Not only are there automatic converters for most stuff, you should only need to do one pass to make sure things work and then you&#x27;ll be done. <a href="https://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html">This article</a> is pretty old but it serves well to identify the main differences. Later Py3 versions just adds new stuff which you would just not have had access to in Python2.7. Once 0.9 is released, we&#x27;ll also make guides for how you go about converting existing code (apart from the wealth of info on this topic online).</p>
|
||
<p>That said, if you are feeling more adventurous, or <em>really</em> want to use Python3 right away, many of the Evennia developer regulars have been running and testing <em>develop</em> branch for months now. It&#x27;s overall been a pretty painless transition - as said, py3 is not that different from py2.</p>
|
||
<p>However, <em>develop</em> branch has other features beyond the py3 jump. And those are not yet documented in the main docs. So you&#x27;ll have to contend with that (but asking in chat/forum works of course). However while it works fine for development already, as a matter of principle I <em>do not</em> recommend ever using Evennia&#x27;s <em>develop</em> branch for a production game - it can change quickly and may occationally be broken. You have been warned!</p>
|
||
<h3>Game Jam</h3>
|
||
<p>We are now a little more than a week into the <a href="https://mudcoders.com/">Mud Coders Guild</a>&#x27;s second yearly <a href="https://itch.io/jam/enterthemud2">Game Jam</a>. This year&#x27;s theme is &quot;One Room&quot;.</p>
|
||
<p>I really hope some more Evennia devs jump on this one because Evennia is perfect for this kind of experimental games. This is because Evennia is not imposing a game style on you - while there are default commands you are free to replace or customize the commands, objects and every aspect of your game to be as specific as you want to your game.</p>
|
||
<p>For example, I have a small Game Jam contribution in the works, where I very quickly reworked the default Evennia setup to pretty much make it into a different genre of game.</p>
|
||
<p>Usually the systems I make for Evennia are generic and intended for any game-type. By contrast, making somehing highly niched is super-fast to do: Building a whole new framework for game mechanisms along with build helpers for me to quickly make content took no more than three days.</p>
|
||
<p>There will no doubt be some iteration, but I hope to spend the rest of the jam time on content and gameplay. I have some RL things happening in the coming weeks (including work on Evennia proper) but if I can get the time to tie my jam entry together, I&#x27;ll likely make one or two blog posts about how it was developed and my reasons for making the choices i did. Most likely the code will appear as an Evennia contribution in case people want to do something similar for their own projects.</p>
|
||
<p>So, busy days.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 25 Apr 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-04-25-steaming-on-eating-jam</guid></item><item><title>Into 2019</title><link>2019.html#2019-01-02-into-2019</link><description><p><a href="https://2.bp.blogspot.com/-9Ns3IqsRFbk/XC0NiCOW4gI/AAAAAAAAJ1U/wCH9LQJ6Tq0WeJSfnhdCPzeA1aTNa-d2wCLcBGAs/s1600/fireworks.jpg"><img src="https://2.bp.blogspot.com/-9Ns3IqsRFbk/XC0NiCOW4gI/AAAAAAAAJ1U/wCH9LQJ6Tq0WeJSfnhdCPzeA1aTNa-d2wCLcBGAs/s320/fireworks.jpg" alt="" /></a></p>
|
||
<p>A new year has come around and it&#x27;s time to both look back at the old and onward to the future of <a href="https://www.evennia.com/">Evennia</a>, the Python MUD creation system!</p>
|
||
<h4>Last year</h4>
|
||
<p><a href="https://2.bp.blogspot.com/-BKHBV0L443U/W7EgLdZIQmI/AAAAAAAAJZs/CpmGtCk6U_QyoXGIEyQbIPBUmAbPbOgawCPcBGAYYCw/s1600/Screenshot%2Bfrom%2B2018-09-30%2B21-09-55.png"><img src="https://2.bp.blogspot.com/-BKHBV0L443U/W7EgLdZIQmI/AAAAAAAAJZs/CpmGtCk6U_QyoXGIEyQbIPBUmAbPbOgawCPcBGAYYCw/s320/Screenshot%2Bfrom%2B2018-09-30%2B21-09-55.png" alt="" /></a></p>
|
||
<p>Last year saw the release of <a href="https://www.blogger.com/blogger.g?blogID=8338260444057832583#editor/target=post;postID=7101674864552615043;onPublishedMenu=allposts;onClosedMenu=allposts;postNum=2;src=postname">Evennia 0.8</a>. This version of Evennia changes some fundamental aspects of the server infrastructure so that the server can truly run in daemon mode as you would expect (no more running it in a GnuScreen session if you want to see logging to the terminal). It also adds the new Online Creation System, which lets builders create and define prototypes using a menu system as well as big improvements in the web client, such as multiple window-panes (allows the user to assign text to different windows to keep their client uncluttered) as well as plenty of fixes and features to help ease life for the Evennia developer. Thanks again to everyone who helped out and contributed to the release of Evennia 0.8!</p>
|
||
<p>On a personal note, I spoke about Evennia at PyCon Sweden this December, which was fun. I might put up my talk and make a more detailed blog post about that in the future, but my talk got a surprising amount of attention and positive feedback. Clearly many people have fond memories of MUDs and enjoy seeing they are not only still around but are possible to create in Python!</p>
|
||
<h4>This year</h4>
|
||
<p><a href="https://1.bp.blogspot.com/-zNtXFGrN344/XC0MhJjWzcI/AAAAAAAAJ1M/UDd_QQRYuh8GNuXefblRIh6qfcDB9784QCLcBGAs/s1600/61SA0Wq1P1L.png"><img src="https://1.bp.blogspot.com/-zNtXFGrN344/XC0MhJjWzcI/AAAAAAAAJ1M/UDd_QQRYuh8GNuXefblRIh6qfcDB9784QCLcBGAs/s200/61SA0Wq1P1L.png" alt="" /></a></p>
|
||
<p>Now we are steaming ahead towards Evennia 0.9! Already we have had a large number of contributions towards this release. A coming change is a much improved central way to make typeclass information available to a website as well as central ways to do various common operations like creating characters and linking them to Accounts. Much of this functionality is today hidden in the various default commands. In Evennia 0.9 they will be moved into more easily-findable locations as library functions everyone can just trigger without having to copy functionality.</p>
|
||
<p>The biggest change for Evennia 0.9 is however that we will now finally move Evennia over to <strong>Python 3</strong>. This is now possible as all our dependencies are now sufficiently ported. As discussed in the community for a long time, this will be a clean break - we will not offer any mid-way solution of Python2/3 but will drop Python2 support entirely. We will at the same time move to Django 2.+. In Django 0.9 we will however probably not use any special Python3 features yet. It should hopefully not be too difficult for our users to upgrade, but we&#x27;ll of course publish extensive instructions and help when that time comes.</p>
|
||
<p>We will likely support a minimum of Python 3.6 and maybe 3.7. This work is currently happening in a separate branch <strong>develop-py3</strong> which will soonish merge into the current Python2.7-based <strong>develop</strong> branch and become Evennia 0.9 when it merges into <strong>master</strong> branch at an unknown time later this year.</p>
|
||
<p>There are a slew of other things planned for Evennia 0.9 and you can <a href="https://github.com/evennia/evennia/projects/8">follow the progress from our project page</a>. If you want to help out you are of course also very welcome. If you are new and are interested in getting your feet wet in helping out with Open-source development, we have <a href="https://github.com/evennia/evennia/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22">a list of good first issues you could jump into</a>.</p>
|
||
<p>Onward into the new year!</p>
|
||
</description><author>Griatch</author><pubDate>Wed, 02 Jan 2019 00:00:00 GMT</pubDate><guid isPermaLink="true">2019.html#2019-01-02-into-2019</guid></item><item><title>Evennia 0.8 released</title><link>2018.html#2018-09-30-evennia-0.8-released</link><description><p><a href="https://4.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/mNkREiXqmJM8Ilz-VmP3V-4YhazaZJIIQCPcBGAYYCw/s1600/evennia_logo_small.png"><img src="https://4.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/mNkREiXqmJM8Ilz-VmP3V-4YhazaZJIIQCPcBGAYYCw/s1600/evennia_logo_small.png" alt="" /></a>After about a year of work and almost 540 commits from close to 20 contributors, <a href="http://www.evennia.com/">Evennia</a> 0.8 is out! Evennia is a Python game server for creating text-based multiplayer games (MUDs, Mushes, etc) using Django and Twisted.</p>
|
||
<p>Some of the upcoming improvements have been covered by previous dev blogs, such as the <a href="https://evennia.blogspot.com/2018/01/kicking-into-gear-from-distance.html">completely reworked server infrastructure</a>:</p>
|
||
<p><a href="https://4.bp.blogspot.com/-R0ziGF8cMPc/Wmz0ppbJkQI/AAAAAAAAH9s/e1D6DVBVwMMia04OubZi5nvO1h8RfdRoACPcBGAYYCw/s1600/portal_server_reboot_develop.png"><img src="https://4.bp.blogspot.com/-R0ziGF8cMPc/Wmz0ppbJkQI/AAAAAAAAH9s/e1D6DVBVwMMia04OubZi5nvO1h8RfdRoACPcBGAYYCw/s320/portal_server_reboot_develop.png" alt="" /></a></p>
|
||
<p>as well as the new <a href="https://evennia.blogspot.com/2018/08/inline-building-in-upcoming-evennia-08.html">Online Creation System</a> that allows for editing in-game prototypes using a powerful menu system:</p>
|
||
<p><a href="https://3.bp.blogspot.com/-ht9SIPcUxfc/W3f0xcl2HdI/AAAAAAAAJIw/cZt90znG82sSNg7Y-dpdiG5f1EXefZiNACPcBGAYYCw/s1600/Screenshot%2Bfrom%2B2018-08-18%2B12-26-12.png"><img src="https://3.bp.blogspot.com/-ht9SIPcUxfc/W3f0xcl2HdI/AAAAAAAAJIw/cZt90znG82sSNg7Y-dpdiG5f1EXefZiNACPcBGAYYCw/s400/Screenshot%2Bfrom%2B2018-08-18%2B12-26-12.png" alt="" /></a></p>
|
||
<p>Other improvements are in the web client, which supports split-panes out of the box. The user can split the output area in any number of panes, resize as desired and then assign different types of content to each pane. You can also have panes that absorb &quot;all the rest&quot; or &quot;all&quot; of the content.</p>
|
||
<p><a href="https://4.bp.blogspot.com/-BKHBV0L443U/W7EgLdZIQmI/AAAAAAAAJZo/Dzv_aD80B-80GgxzZsyq6XUSzAzv86IwQCLcBGAs/s1600/Screenshot%2Bfrom%2B2018-09-30%2B21-09-55.png"><img src="https://4.bp.blogspot.com/-BKHBV0L443U/W7EgLdZIQmI/AAAAAAAAJZo/Dzv_aD80B-80GgxzZsyq6XUSzAzv86IwQCLcBGAs/s400/Screenshot%2Bfrom%2B2018-09-30%2B21-09-55.png" alt="" /></a></p>
|
||
<p>There are still some bits which are a bit shaky and there is still much to do with the web client (for example, not that many outgoing messages yet defaults to being tagged in a way that the webclient recognizes). But it&#x27;s a step forward!</p>
|
||
<p>There are many other improvements for developers, such as easier tools for running debuggers and a lot of new utilities and helper functions. The menu-creation tool (EvMenu) has seen a lot of improvements and also sport a few new decorators for quickly creating multi-page menus with full functionality to flip through and select large numbers of options.</p>
|
||
<p>The community has also chipped in with a large number of optional contributions for developers to use for their own game, such as a full turn-based combat system (divided into convenient chunks for the dev to pick and choose support for everything from magic and potions to equipment and ranged attacks). There are also a range of helper functions for creating simpler menus and build commands as well as auditing tools and additions making better use of Django&#x27;s very mature security features.</p>
|
||
<p>The more detailed list of improvements and changes can be found in the announcement <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/teSx6ICHSTU">here</a>. As usual, please report any issues to the issue tracker on github.</p>
|
||
<h3>Future</h3>
|
||
<p>In the immediate future, we&#x27;ll focus on resolving any bugs that may have slipped through the cracks and also resolve some other issues in the pipeline.</p>
|
||
<p>But beyond that, work on Evennia 0.9 will begin. And before you ask - yes Evennia 0.9 is the version where we&#x27;ll move fully to Python3. Our dependencies have now reached a point where this is possible and there will be no intermediary Python2/3 version. There is no timeline for the 0.9 release but it should hopefully not be too tricky for the community to make the jump when the time comes.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 30 Sep 2018 00:00:00 GMT</pubDate><guid isPermaLink="true">2018.html#2018-09-30-evennia-0.8-released</guid></item><item><title>Inline building in upcoming Evennia 0.8</title><link>2018.html#2018-08-18-inline-building-in-upcoming-evennia-0.8</link><description><p><a href="https://4.bp.blogspot.com/-h2OiulcCLIY/W3gLw-UzGgI/AAAAAAAAJKI/bS_gTmOcQoAgaGmCOnx-b4x60zTr1pVCgCLcBGAs/s1600/773px-Industrial_Trust_Building_Providence_RI.jpg"><img src="https://4.bp.blogspot.com/-h2OiulcCLIY/W3gLw-UzGgI/AAAAAAAAJKI/bS_gTmOcQoAgaGmCOnx-b4x60zTr1pVCgCLcBGAs/s200/773px-Industrial_Trust_Building_Providence_RI.jpg" alt="" /></a></p>
|
||
<p><a href="http://www.evennia.com/">Evennia</a>, the Python MUD-server game development kit, is slowly creeping closer to its 0.8 release.</p>
|
||
<p>In our development branch I&#x27;ve just pushed the first version of the new OLC (OnLine Creator) system. This is a system to allow builders (who may have limited coding knowledge) to customize and spawn new in-game objects more easily without code access. It&#x27;s started with the <strong>olc</strong> command in-game. This is a visual system for manipulating Evennia <em>Prototypes</em>.</p>
|
||
<h3>Briefly on Prototypes</h3>
|
||
<p>The <em>Prototype</em> is an Evennia concept that has been around a good while. The prototype is a Python dictionary that holds specific keys with values representing properties on a game object. Here&#x27;s an example of a simple prototype:</p>
|
||
<pre><code> {&quot;key&quot;: &quot;My house&quot;,
|
||
&quot;typeclass&quot;: &quot;typeclasses.houses.MyHouse&quot;}
|
||
</code></pre>
|
||
<p>By passing this dict to the spawner, a new object named &quot;My house&quot; will be created. It will be set up with the given typeclass (a &#x27;typeclass&#x27; is, in Evennia lingo, a Python class with a database backend). A prototype can specify all aspects of an in-game object - its attributes (like description and other game-specific properties), tags, aliases, location and so on. Prototypes also support inheritance - so you can expand on an existing template without having to add everything fresh every time.</p>
|
||
<p>There are two main reasons for the Prototypes existing in Evennia:</p>
|
||
<ul>
|
||
<li>They allow you to customize <em>individual</em> objects easier. For example you could have a &#x27;Goblin&#x27; base prototype with inheriting prototypes Goblin Wizard&quot; and &quot;Goblin Chieftain&quot; - all using the same Typeclass, but with different Attributes, equipment etc.</li>
|
||
<li>Prototypes can be manipulated and scripted by builders without needing full Python access. This means that while the Typeclasses are designed and supplied by the Python developer, the builders can then use that typeclass to make very different types of object instances in-game.</li>
|
||
</ul>
|
||
<h3>What&#x27;s new</h3>
|
||
<p>As said, Prototypes have been around for a good while in Evennia. But in the past they were either manually entered directly as a dict on the command line, or created in code and read from a Python module. The former solution is cumbersome and requires that you know how to build a proper-syntax Python dictionary. The latter requires server code access, making them less useful to builders than they could be.</p>
|
||
<p><em>Note: If you are visually impaired, each image is also a link to a text-only version.</em></p>
|
||
<p><a href="https://pastebin.com/raw/3YNtAdvz"><img src="https://2.bp.blogspot.com/-ht9SIPcUxfc/W3f0xcl2HdI/AAAAAAAAJIk/VSk4VaBMhTc3J8ZaTnar9X2Rws-LOMiqACLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B12-26-12.png" alt="OLC index" title="OLC index 1" /></a></p>
|
||
<p>In Evennia 0.8, while you can still insert the Prototype as a raw dict, <strong>spawn/menu</strong> or the new <strong>olc</strong> command opens a new menu-driven interface.<br />
|
||
<a href="https://pastebin.com/raw/4UbUNGmG"><img src="https://3.bp.blogspot.com/-tdauL-B6j1E/W3f01ltKlzI/AAAAAAAAJIs/Q5-cIY6AcGU_IXXasdzPWec7cxN061WrwCLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B12-27-37.png" alt="Select a prototype to load. This will replace any prototype currently being edited! ___________________________________________________________________________________________________ Select with &lt;num&gt;. Other actions: examine &lt;num&gt; | delete &lt;num&gt; Back (index) | Validate prototype | Quit 1: goblin_archer 5: goblin_archwizard 2: goblin_wizard 3: goblin 4: archwizard_mixin " title="Prototype loading" /></a></p>
|
||
<p>More importantly, builders can now create, save and load prototypes in the database for themselves and other builders to use. The prototypes can be tagged and searched as a joint resource. Builders can also lock prototypes if others are not to be able to read or use them to spawn things. Developers can still supply module-based &quot;read-only&quot; prototypes (for use as starting points or examples to their Builders, for example).</p>
|
||
<p><a href="https://pastebin.com/raw/dUGiSLDL"><img src="https://2.bp.blogspot.com/-XFm3KqhLBwE/W3f93upyVLI/AAAAAAAAJJA/eZDWGPHM93MWvt2T5W8Ytr4cHstGg8iXACLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B13-04-48.png" alt="Found 1 match. (Warning: creating a prototype will overwrite the current prototype!) ____________________________________________________________________________________ Actions: examine &lt;num&gt; | create prototype from object &lt;num&gt; Back (index) | Quit 1: Griatch(#1)" title="Load prototype from object" /></a></p>
|
||
<p>You can now also use the menu to search for and create a new Prototype based on <em>an existing object</em> (if you have access to do so). This makes it quick to start up a new prototype and tweak it for spawning other similar objects. Of course you could spawn temporary objects without saving the prototype as well.</p>
|
||
<p><a href="https://pastebin.com/raw/VspKN3xf"><img src="https://1.bp.blogspot.com/-DYcYStEWXKk/W3f_-bnH4vI/AAAAAAAAJJY/iv4-GN8NTpUCpBvyXBwMUABG8TTPJYN9ACLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B13-15-44.png" alt="The Typeclass defines what &#x27;type&#x27; of object this is - the actual working code to use. All spawned objects must have a typeclass. If not given here, the typeclass must be set in one of the prototype&#x27;s parents. [No typeclass set] ______________________________________________________________________________________________________________________________________________ Back (prototype-parent) | Forward (key) | Index | Validate prototype | Quit 1: evennia.contrib.tutorial_world.mob.Mob 7: evennia.contrib.tutorial_world.objects.TutorialObject 2: evennia.contrib.tutorial_world.objects.Climbable 8: evennia.contrib.tutorial_world.objects.Weapon 3: evennia.contrib.tutorial_world.objects.CrumblingWall 9: evennia.contrib.tutorial_world.objects.WeaponRack 4: evennia.contrib.tutorial_world.objects.LightSource 10: evennia.contrib.tutorial_world.rooms.BridgeRoom 5: evennia.contrib.tutorial_world.objects.Obelisk current: (1/3) 6: evennia.contrib.tutorial_world.objects.Readable next page " title="Typeclass selection, miltipage" /></a></p>
|
||
<p>Builders will likely not know which typeclasses are available in the code base. There are new a few ways to list them. The menu display makes use of Evennia 0.8&#x27;s new EvMenu improvements, which allows for automatically creating multi-page listings (see example above).</p>
|
||
<p>There is also a new switch to the <strong>typeclass</strong> command, <strong>/list</strong>, that will list all available typeclasses outside of the OLC.</p>
|
||
<h3>Protfuncs</h3>
|
||
<p>Another new feature are <em>Protfuncs.</em> Similarly to how <em>Inlinefuncs</em> allows for calling for the result of a function call inside a text string, Protfuncs allows for calling functions inside a prototype&#x27;s values. It&#x27;s given on the form $funcname(arguments), where arguments could themselves contain one or more nested Protfuncs.</p>
|
||
<p>As with other such systems in Evennia, only Python functions in a specific module or modules (given by settings) are available for use as Protfuncs in-game. A bunch of default ones are included out of the box. Protfuncs are called at the time of spawning. So for example, you could set the Attribute</p>
|
||
<blockquote>
|
||
<p><strong>Strength = $randint(5, 20)</strong></p>
|
||
</blockquote>
|
||
<p>to automatically spawn objects with a random strength between 5 and 20.</p>
|
||
<p><a href="https://pastebin.com/raw/3VLMEPFd"><img src="https://1.bp.blogspot.com/-qHeRpEQTEzU/W3gFpJ9ge5I/AAAAAAAAJJw/-PVcelDk2CsIW1nJwWvMjazcJ9LyKx5pgCLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B13-40-04.png" alt="prototype-key: goblin, -tags: [], -locks: spawn:all();edit:all() -desc: Built from goblin prototype-parent: None key: goblin aliases: monster, mob attrs: desc = You see nothing special. strength = $randint(5,20) agility = $random(6,20) magic = 0 tags: mob (category: None) locks: call:true();control:id(1) or perm(Admin);delete:id(1) or perm(Admin);edit:perm(Admin);examine:perm(Builder);get:all();puppet:pperm(Developer) ;tell:perm(Admin);view:all() location: #2 home: #2 No validation errors found. (but errors could still happen at spawn-time) ______________________________________________________________________________________________________________________________________________ Actions: examine &lt;num&gt; | remove &lt;num&gt; Back (index) | Validate prototype | Quit 1: Spawn in prototype&#x27;s defined location (#2) 2: Spawn in Griatch&#x27;s location (Limbo) 3: Spawn in Griatch&#x27;s inventory 4: Update 2 existing objects with this prototype" title="Spawning screen" /></a></p>
|
||
<p>When spawning, the olc will validate the prototype and run tests on any Protfunc used. For convenience you can override the spawn-location if any is hard-coded in the prototype.</p>
|
||
<p><a href="https://pastebin.com/raw/K0a1z23h"><img src="https://4.bp.blogspot.com/-mkpUmXNQsWQ/W3gKE-5nnlI/AAAAAAAAJJ8/S65RiLXa6BcSstru3ePZmMna38cnWGRYQCLcBGAs/s400/Screenshot%2Bfrom%2B2018-08-18%2B13-58-27.png" alt="https://pastebin.com/raw/K0a1z23h" /></a></p>
|
||
<p>The system will also allow you to try updating existing objects created from the same-named prototype earlier. It will sample the existing objects and calculate a &#x27;diff&#x27; to apply. This is bit is still a bit iffy, with edge cases that still needs fixing.</p>
|
||
<h2>Current status</h2>
|
||
<p>The OLC is currently in the develop branch of Evennia - what will soon(ish) merge to become Evennia 0.8.</p>
|
||
<p>It&#x27;s a pretty big piece of code and as such it&#x27;s still a bit unstable and there are edge cases and display issues to fix. But it would be great with more people trying it out and reporting errors so the childhood issues can be ironed out before release!</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 18 Aug 2018 00:00:00 GMT</pubDate><guid isPermaLink="true">2018.html#2018-08-18-inline-building-in-upcoming-evennia-0.8</guid></item><item><title>Kicking into gear from a distance</title><link>2018.html#2018-01-27-kicking-into-gear-from-a-distance</link><description><p><a href="https://3.bp.blogspot.com/-63mc2ur3Gyk/Wmz6puNzMGI/AAAAAAAAH94/vsXKZcCu2MwKlEaoCi7IjzWHJnPvGAQKgCLcBGAs/s1600/karate-312470_640.png"><img src="https://3.bp.blogspot.com/-63mc2ur3Gyk/Wmz6puNzMGI/AAAAAAAAH94/vsXKZcCu2MwKlEaoCi7IjzWHJnPvGAQKgCLcBGAs/s200/karate-312470_640.png" alt="" /></a></p>
|
||
<p>The last few weeks I have reworked the way <a href="http://www.evennia.com/">Evennia</a>&#x27;s startup procedure works. This is now finished in the <em>develop</em> branch so I thought I&#x27;d mention a little what&#x27;s going on.</p>
|
||
<p>Evennia, being a server for creating and running text-games (MU*s), consists of two main processes:</p>
|
||
<ul>
|
||
<li>The <em>Portal</em> - this is what players connect to with their clients.</li>
|
||
<li>The <em>Server</em> - this is the actual game, with the database etc. This can be shutdown and started again without anyone connected to the Portal getting kicked from the game. This allows for hot-adding new Python code into the running Server without any downtime.</li>
|
||
</ul>
|
||
<p>Since Evennia should be easy to set up <em>and</em> also run easily on Windows as well as on Linux/Mac, we have foregone using the linux process management services but instead offered our own solution. This is how the reload mechanism currently looks in master branch:</p>
|
||
<p><a href="https://1.bp.blogspot.com/-U98LnVTJF7Y/WmzvHbQN2NI/AAAAAAAAH9U/10u8n91y56MdyW4Fmuv9k5Abk79TCCtUgCLcBGAs/s1600/portal_server_reboot_master.png"><img src="https://1.bp.blogspot.com/-U98LnVTJF7Y/WmzvHbQN2NI/AAAAAAAAH9U/10u8n91y56MdyW4Fmuv9k5Abk79TCCtUgCLcBGAs/s400/portal_server_reboot_master.png" alt="" /></a></p>
|
||
<p>Here I&#x27;ve excluded connections irrelevant to reloading, such as the Twisted AMP connection between Portal and Server. Dashed lines suggest a more &quot;temporary&quot; connection than a solid line.</p>
|
||
<p>The <strong><em>Launcher</em></strong> is the evennia program one uses to interact with the Server in the terminal/console. You give it commands like evennia start/stop/reload.</p>
|
||
<ul>
|
||
<li>When <strong>starting</strong>, the Launcher spawns a new program, the <em><strong>Runner</strong></em>, and then exits. The Runner stays up and starts the Portal and Server. When it starts the Server, it does so in a blocking way and sits waiting in a stalled loop for the Server process to end. As the Server and Portal start they record their current process-ids in <em><strong>.pid files</strong></em>.</li>
|
||
<li>When <strong>reloading</strong>, the Launcher writes a flag in a little <em><strong>.restart</strong></em> <em><strong>file</strong></em>. The Launcher then looks up the Server&#x27;s .pid file and sends a SIGINT signal to that process to tell it to gracefully shut down. As the Server process dies, the Runner next looks at the Server&#x27;s .restart file. If that indicates a reload is desired, The Runner steps in its loop and starts up a new Server process.</li>
|
||
<li>When <strong>stopping,</strong> everything happens like when reloading, except the .restart file tells the Runner that it should just exit the loop and let the Server stay down. The Launcher also looks at the Portal&#x27;s .pid file and sends a SIGINT signal to kill it. Internally the processes catch the SIGINT and close gracefully.</li>
|
||
</ul>
|
||
<p>The original reason for this Server-Portal-Runner setup is that the Portal is <em>also</em> reloadable in the same way (it&#x27;s not shown above). But over time I&#x27;ve found that having the Portal reloadable is not very useful - since players get disconnected when the Portal reloads one can just as well stop and start both processes. There are also a few issues with the setup, such as the .pid files going stale if the server is killed in some catastrophic way and various issues with reliably sending signals under Windows. Also, the interactive mode works a little strangely since closing the terminal will actually kill the Runner, not the Server/Portal - so they will keep on running except they can no longer reload ...<br />
|
||
It overall feels a little ... fiddly.</p>
|
||
<p>In develop branch, this is now the new process management setup:</p>
|
||
<p><a href="https://4.bp.blogspot.com/-R0ziGF8cMPc/Wmz0ppbJkQI/AAAAAAAAH9o/2BNcUTEqvBwkmlZAy7Q74Xmww_LkpB3wgCLcBGAs/s1600/portal_server_reboot_develop.png"><img src="https://4.bp.blogspot.com/-R0ziGF8cMPc/Wmz0ppbJkQI/AAAAAAAAH9o/2BNcUTEqvBwkmlZAy7Q74Xmww_LkpB3wgCLcBGAs/s400/portal_server_reboot_develop.png" alt="" /></a></p>
|
||
<p>The Portal is now a Twisted <a href="https://twistedmatrix.com/documents/current/api/twisted.protocols.amp.html">AMP</a> server, while the Evennia Server and Launcher are AMP clients. The Runner is no more.</p>
|
||
<ul>
|
||
<li>When <strong>starting</strong>, the Launcher spawns the Portal and tries to connect to it as an AMP client as soon as it can. The Portal in turn spawns the Server. When the Server AMP client connects back to the Portal, the Portal reports back to the Launcher over the AMP connection. The Launcher then prints to the user and disconnects.</li>
|
||
<li>When <strong>reloading</strong>, the Launcher connects to the Portal and gives it a reload-command. The Portal then tells the Server (over their AMP connection) to shutdown. Once the Portal sees that the Server has disconnected, it spawns a new Server. Since the Portal itself knows if a reload or shutdown is desired no external .restart (or .pid) files are needed. It reports the status back to the Launcher that can then disconnect.</li>
|
||
<li>When <strong>stopping</strong>, the Launcher sends the &quot;Stop Server&quot; command to the Portal. The Portal tells the Server to shut down and when it has done so it reports back to the Launcher that the Server has stopped. The Launcher then sends the &quot;Stop Portal&quot; command to also stop the Portal. The Launcher waits until the Portal&#x27;s AMP port dies, at which point it reports the shutdown to the user and stops itself.</li>
|
||
</ul>
|
||
<p>So far I really like how this new setup works and while there were some initial issues on Windows (spawning new processes does not quite work they way you expect on that platform) I think this should conceptually be more OS-agnostic than sending kill-signals.</p>
|
||
<p>This solution gives much more control over the processes. It&#x27;s easy to start/stop the Server behind the portal at will. The Portal knows the Server state and stores the executable-string needed to start the Server. Thus the Server can also itself request to be reloaded by just mimicking the Launcher&#x27;s instructions.<br />
|
||
The launcher is now only a client connecting to a port, so one difference with this setup is that there is no more &#x27;interactive&#x27; mode - that is the Server/Portal will always run as daemons rather than giving log messages directly in the terminal/console. For that reason the Launcher instead has an in-built log-tailing mechanism now. With this the launcher will combine the server/portal logs and print them in real time to easily see errors etc during development.</p>
|
||
<p>The merger of the develop branch is still a good bit off, but anyone may try it out already here: https://github.com/evennia/evennia/tree/develop . Report problems to the issue tracker as usual.</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 27 Jan 2018 00:00:00 GMT</pubDate><guid isPermaLink="true">2018.html#2018-01-27-kicking-into-gear-from-a-distance</guid></item><item><title> New year, new stuff</title><link>2018.html#2018-01-05-new-year,-new-stuff</link><description><p><a href="https://1.bp.blogspot.com/-Cos98gc1wVU/Wk9Qdu2v6pI/AAAAAAAAH3U/O29xABaYrPYxPT3xubw79li5zU-kj_HVACLcBGAs/s1600/child-1539341_640.jpg"><img src="https://1.bp.blogspot.com/-Cos98gc1wVU/Wk9Qdu2v6pI/AAAAAAAAH3U/O29xABaYrPYxPT3xubw79li5zU-kj_HVACLcBGAs/s200/child-1539341_640.jpg" alt="" /></a></p>
|
||
<p>Happy 2018 everyone! Here&#x27;s a little summary of the past Evennia year and what is brewing.</p>
|
||
<p><em>(Evennia is a Python server- and toolbox for creating text-based multiplayer games (MU*)).</em></p>
|
||
<p>The biggest challenge for me last year Evennia-wise was the release of Evennia 0.7. Especially designing the migration process for arbitrary users migrating the Django auth-user took a lot of thought to figure out <a href="http://evennia.blogspot.se/2017/08/renaming-djangos-auth-user-and-app.html">as described in my blog post here.</a> But now 0.7 <a href="http://evennia.blogspot.se/2017/09/evennia-07-released.html">is released</a> and a few initial minor adjustments could be made after feedback from daring pilot testers. <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/0JYYNGY-NfE">The final process</a> of migrating from 0.6 to 0.7 is, while involved, a step-by-step copy&amp;paste list that has worked fine for most to follow. I&#x27;ve gotten far fewer questions and complains about it than could be expected so that&#x27;s a good sign.</p>
|
||
<p>Working away on the boring but important behind-the-scenes stuff made me less able to keep up with more &quot;mundane&quot; issues and bugs popping up, or with adding new &quot;fun&quot; features to existing code. Luckily the Evennia community has really been thriving this year; It feels like new users pop up in the support channel all the time now. The number of pull requests both fixing issues and offering new features and contribs have really picked up. A bigger part of my time has been spent reviewing Pull Requests this year than any other I think. I would like to take the opportunity to thank everyone contributing, it&#x27;s really awesome to see others donating their time and energy adding to Evennia. The <a href="http://evennia.blogspot.se/2017/10/evennia-in-hacktoberfest-2017.html">Hacktoberfest</a> participation was also surprisingly effective in getting people to create PRs - I have a feeling some were just happy to have an &quot;excuse&quot; for getting started to contribute. We should attend that next year too.</p>
|
||
<p>One thing we added with 0.7 was a more formal branching structure: Evennia now uses fixed <strong>master</strong> and <strong>develop</strong> branches, where master is for bug-fixes and develop is for new features (things that will eventually become evennia 0.8). This is simple but enough for our needs; it also makes it easier to track new from old now that we are actually doing releases.</p>
|
||
<p>Now that Twisted is at a point where this is possible for us to do, we also now have a <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/GbLh1GF-ZaY">sort-of plan</a> for finally moving Evennia to Python 3. I won&#x27;t personally be actively working on it until after 0.8 is out though. I don&#x27;t expect both Evennia 0.8 and 0.9 (which will be pure py3) to get released this year, but we&#x27;ll see - so far contributors have done all the work on the conversion.</p>
|
||
<p>At any rate, this coming year will probably be dominated by catching up on issues and edge cases that are lining our <a href="https://github.com/evennia/evennia/issues">Issue tracker</a>. One side effect of more newcomers is more eyes on the code and finding the creaky-bits. At least for me, most of my Evennia-time will be spent resolving bugs and issues. The fun thing is that unlike previous years this is not only up to me anymore - hopefully others will keep helping to resolve issues/bugs to broaden our bandwidth when it comes to keeping Evennia stable. The faster we can handle the backlog of issues the faster we can focus on new shiny features after all.</p>
|
||
<p>Finally, a continued great thank you to those of you contributing to the <a href="https://www.patreon.com/griatch">Patreon</a>. Even small donations have a great encouraging value when working on something as niche as a Python MU* game server in 2018 - thanks a lot!</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 05 Jan 2018 00:00:00 GMT</pubDate><guid isPermaLink="true">2018.html#2018-01-05-new-year,-new-stuff</guid></item><item><title>Getting a MUD RP scene going</title><link>2017.html#2017-10-29-getting-a-mud-rp-scene-going</link><description><p>This article is a little different from the normal more technical <a href="https://www.evennia.com/">Evennia</a>-specific content of this blog. It was originally published as a light-hearted addition to the <a href="http://journal.imaginary-realities.com/">Imaginary Realities</a> e-zine many years ago. While IR is still online it has since dozed off. So I&#x27;m reposting it here to bring it to a new audience.</p>
|
||
<p>In roleplay-heavy MUDs (and in other categories of text-based roleplaying games), the concept of scenes become important. A scene in this concept is simply a situation big or small that involves you and your fellow players in interesting role play. A scene can be as simple as two players meeting in the street and exchanging a few words to the dramatic conclusion to a staff-driven quest. Whenever role player-interested players meet, a scene may happen.</p>
|
||
<p>But sometimes scenes won’t come naturally. Sometimes your favourite game has only a few people online, or most of them are hovering in private areas. It’s time to go proactive. Below I offer some archetypes, tropes and ideas for how to get a random Scene started and people interested. The list is based on one I did for a RP-heavy MUD I played some time back.</p>
|
||
<p>Some terms used in the list:</p>
|
||
<ul>
|
||
<li>Character concept - The general idea behind your player character (PC), like “The scarred veteran”, “The grumpy old magician” or “The swashbuckling bounty-hunter”.</li>
|
||
<li>IC/OOC - In-Character/Out-Of-Character.</li>
|
||
<li>Emote/pose - This is the common way to roleplay in MUDs. This displays a free-form action to the room, such as “The tall man sighs heavily”. Some MUDs offer a slew of special commands for particular actions or special syntax to decorate poses. Some games use specific “say” commands for verbal communication whereas others make say’s part of the emote completely.</li>
|
||
<li>Action/static pose - a pose that “lingers”, such as The tall man is sitting by the bar. Commonly static poses remain assigned to your character’s description until you change it or exit the room, meaning that new people entering will immediately see your current status.</li>
|
||
<li>NPC - Non-Player Character. Also known as a “mob”. An in-game character that is controlled by the computer, such as a bartender or a city guard.</li>
|
||
<li>vNPC - a “virtual” NPC. This NPC does not actually exist in code but they should be there. Even though there are only two Players and a City guard in the central plaza, that place is actually packed with people most of the day. Most RP-heavy muds ask players to imagine vNPCs being all around them and have it influence their roleplay.</li>
|
||
<li>Godmodding - this is considered very bad form. Godmodding means to include another Player’s character in your roleplay in a way that takes control away from them unfairly. Depending on the game, disagreements on how to resolve a situation may be down to skill checks, die rolls or calling in a staff arbiter.</li>
|
||
</ul>
|
||
<h2>Scene starters</h2>
|
||
<p>Scene starters are for when you are alone in a room hoping for others to join you (we&#x27;ve all done it). It is considerably easier to run Scene starters if there is some OOC way for other players to know where to find you (such as a list showing who&#x27;s interesting in roleplay and where they are in the game). If not, it’s best to prepare your starter in a commonly visited central location or hub. You normally trigger the starter whenever another Player enters.</p>
|
||
<p>The Scene starters below are intended as ideas and suggestions, but are also examples of archetypical behaviour I’ve observed myself.</p>
|
||
<h3><a href="https://lh5.googleusercontent.com/h5i2RaOuaKozyn9f3_BTy6DgIEtxivNHKmBE4sWQntpDM0CHof9VOVbouwCZY1X6AMtGOZIYGo8A-nJSDtDED3y-PxVKv74G5eiY__r2sjUR8XurPOoSupWvyzUmjdNazd_E4P8"><img src="https://lh5.googleusercontent.com/h5i2RaOuaKozyn9f3_BTy6DgIEtxivNHKmBE4sWQntpDM0CHof9VOVbouwCZY1X6AMtGOZIYGo8A-nJSDtDED3y-PxVKv74G5eiY__r2sjUR8XurPOoSupWvyzUmjdNazd_E4P8" alt="" /></a>The Barfly</h3>
|
||
<p>A role playing mud classic since time immemorial. The barfly is alone in a tavern and tends their drink, waiting for things to happen. A passive role, but trivial to setup and easy for other players to jump in on - they just slide up to the bar and ask what&#x27;s up. Fun variations is the drunk barfly or really, really sad/happy barfly, states which immediately give other Players things to ask about and work with.</p>
|
||
<h3><a href="https://lh3.googleusercontent.com/RQVHP9QaojaIeer1bYbsblxkBk2kqxN04Tom_8YffXOD7JlBmJrCGbdMJ-qpZF8aAVOiCFeyL8kiiRYwc0JkOqOjCy3Ytcwf0qS-EymdnEZJnQFIEmRdmvVu16UFdOW9SpTkkEc"><img src="https://lh3.googleusercontent.com/RQVHP9QaojaIeer1bYbsblxkBk2kqxN04Tom_8YffXOD7JlBmJrCGbdMJ-qpZF8aAVOiCFeyL8kiiRYwc0JkOqOjCy3Ytcwf0qS-EymdnEZJnQFIEmRdmvVu16UFdOW9SpTkkEc" alt="" /></a>The Strider</h3>
|
||
<p>This is the &quot;dark stranger in the corner&quot; variation of the barfly. It is simple to execute - just sit in a dark tavern corner looking glum and mysterious. Often used by newbie players unsure of the game’s commands. The problem is that unless they know the Strider from before it&#x27;s hard for other Characters to include him/her in their roleplay in a realistic way. The whole IC point of this trope is after all to avoid attention.</p>
|
||
<h3><a href="https://lh3.googleusercontent.com/nQbZY-w_ChB4LhIqcT2-IWONaPl2VTl4_RZ05buEBwDABE7pZJ84TBgnTQni3IxhKqNvkKwU6UQA7k7xJtrTcRkuXhOXrgP3j7xX5zucumMBagIaKX1D0CfAkCIB8w9A0h0TBtI"><img src="https://lh3.googleusercontent.com/nQbZY-w_ChB4LhIqcT2-IWONaPl2VTl4_RZ05buEBwDABE7pZJ84TBgnTQni3IxhKqNvkKwU6UQA7k7xJtrTcRkuXhOXrgP3j7xX5zucumMBagIaKX1D0CfAkCIB8w9A0h0TBtI" alt="" /></a> The Busybody</h3>
|
||
<p>The busybody is keeping busy in this room. Most commonly they are performing their job. If they own a bar or run the shop, they tend it. If they are guardsmen they are standing on patrol. If they are wee jesters they are making fools out of themselves. And so on. This is a great starter since it is both natural, realistic and in-character all at once. The nature of their work may occasionally make it easier or harder for other Characters come up with reasons to interact with them though - it might be harder to motivate why some characters would strike up a conversation with a guardsman than they would with a street vendor.</p>
|
||
<h3>The Demagogue</h3>
|
||
<p><a href="https://lh5.googleusercontent.com/5fFNF2AG29zrkxWJH3qcen_SJpFLOnIDXDUt1f-k8bbhtjPoV-Bd_i-wvHge4DITlB7KXLGgzr4YD4Hf8cWJX8Q3KFHYZMXbLJXBqZdfhS23vtoyg6w7kuQ3AMHLhnc-GEsRuT8"><img src="https://lh5.googleusercontent.com/5fFNF2AG29zrkxWJH3qcen_SJpFLOnIDXDUt1f-k8bbhtjPoV-Bd_i-wvHge4DITlB7KXLGgzr4YD4Hf8cWJX8Q3KFHYZMXbLJXBqZdfhS23vtoyg6w7kuQ3AMHLhnc-GEsRuT8" alt="" /></a>This more involved starter involves striking up a loud conversation with an NPC/vNPC. Whenever another Character enters, the Demagogue plays out a small scene where they are &quot;arguing&quot; with the NPC, playing both roles. The argument could be &quot;continuing&quot; or just starting as the new PC enters. It could be about anything from tavern prices to refuting a made-up insult. The advantage of this is that it gives immediate character to the demagogue and to the NPC both. It also makes it easy for the newcomer to get into the scene just by taking sides in the debate.</p>
|
||
<h3><a href="https://lh6.googleusercontent.com/K49MsnM4i2kMCpy7VQpOtw4tIoZjcM12JP-Gszfec04wnRftasf390AjEW644FuxRtBMtkn5kLbLeHrZctUPJutzWTApW3snrNCP6xFtcW-1DwQvOX1uFUhp7HSZANJcdaL85CQ"><img src="https://lh6.googleusercontent.com/K49MsnM4i2kMCpy7VQpOtw4tIoZjcM12JP-Gszfec04wnRftasf390AjEW644FuxRtBMtkn5kLbLeHrZctUPJutzWTApW3snrNCP6xFtcW-1DwQvOX1uFUhp7HSZANJcdaL85CQ" alt="" /></a></h3>
|
||
<h3>The Damsel in Distress</h3>
|
||
<p>This starter, which of course works both for male and female Characters, sets up the damsel as being in a dependency situation to whomever enters the room next. It involves describing the damsel in a sort of precarious situation that clearly requires an extra hand to resolve. This could be anything: Having their hands full and nearly dropping stuff. Chasing a dog that is running off with their book. Being accosted by vNPC ruffians (which should bugger off quickly, unless roleplaying completely “virtual” combat is your cup of tea). Either way the newcomer has an ongoing scene to react to, and roleplay immediately ensues.</p>
|
||
<h3>The Organizer</h3>
|
||
<p><a href="https://lh6.googleusercontent.com/TquhRSMaFqrIsKPkIa2LZRw6mgiYsjD4Aban4OfAox60W9PiW2sWiKjsRnw2q_oUaFgD5cw9pHdNAYSDBHQOnbO5aFaRL1iVU2JP68W9AKsnAyzN3eCy81yxAfjuVVbATHueYro"><img src="https://lh6.googleusercontent.com/TquhRSMaFqrIsKPkIa2LZRw6mgiYsjD4Aban4OfAox60W9PiW2sWiKjsRnw2q_oUaFgD5cw9pHdNAYSDBHQOnbO5aFaRL1iVU2JP68W9AKsnAyzN3eCy81yxAfjuVVbATHueYro" alt="" /></a>This starter requires that the game has a developed in-game message- or mailing system. If so - use it to explicitly and in-character invite people to a scene! If the organizer is in a position of in-game power, this could make good IC sense - like the lord calling on their vassals to attend some sort of function. But anything from calling in a favor to suggesting a business opportunity or looking for a job works. Throw a party. Get drunk and send an ill-advised love letter. This starter works exceptionally well in combination with Stage director or Aggravator for getting selected Players into a memorable scene.</p>
|
||
<h3><a href="https://lh5.googleusercontent.com/ZKPX1lB3mp5BAFCLNd13sSR3UnXLGoC-uNASS_-T3BxSAu546fzIBZblSedIU_gOz4qyuo9GZvdLBl0V88TgWBJDJ2IYBBhjJs9uC-XLkTFy32dvyTRkn4UwszwKnnomk-OilGA"><img src="https://lh5.googleusercontent.com/ZKPX1lB3mp5BAFCLNd13sSR3UnXLGoC-uNASS_-T3BxSAu546fzIBZblSedIU_gOz4qyuo9GZvdLBl0V88TgWBJDJ2IYBBhjJs9uC-XLkTFy32dvyTRkn4UwszwKnnomk-OilGA" alt="" /></a></h3>
|
||
<h3>The Aggravator</h3>
|
||
<p>The aggravator starts off on the wrong foot with people. Maybe they lash out due to some perceived injustice or they are just grumpy. This starter does not fit all character concepts. The aggravator should accuse the newly arrived PC for something. It could be something from their common history or something made-up out of the blue. It is an active starter in that it leads the way and forces other PCs into roleplay - if nothing else in order to defend themselves. A simple example is to chide the newly arrived PC for not stopping the vNPC that just ran past them out the door. It&#x27;s important not to take the aggravator trope too far, especially not when using vNPCs. The idea is to get a scene started with some tension, not to get the other (possibly random) PC into real trouble. No god-modding, remember. If the two Characters are actual enemies though, it may be another matter ...</p>
|
||
<h3>The Stage Director</h3>
|
||
<p><a href="https://lh5.googleusercontent.com/e2N_x7CTxpkz7suW4EpXkp-5My9U8L73rpkPuDIaU51lG5pyTU0lg-jVXYV2z14lU0bbu6QdFavVFbHodECRZueBF--tNYZZTyJ4EkN9hDehAbcydxs7U0CdrUtpsQLL7JQ9wEc"><img src="https://lh5.googleusercontent.com/e2N_x7CTxpkz7suW4EpXkp-5My9U8L73rpkPuDIaU51lG5pyTU0lg-jVXYV2z14lU0bbu6QdFavVFbHodECRZueBF--tNYZZTyJ4EkN9hDehAbcydxs7U0CdrUtpsQLL7JQ9wEc" alt="" /></a>This is a more sophisticated starter that is halfway to improvised theater. It sets up a whole little scene involving some event with a number of semi-named vNPCs. The stage director could be directly involved or be a spectator (in which case other PCs can walk up to them and ask what&#x27;s going on). The event could be anything from a trite bar brawl to a domestic dispute in progress. Or why not a marriage proposal between two vNPCs in the middle of the street! If the stage director is threatened in some way, this is a large-scale version of damsel in distress.</p>
|
||
<p>The nice thing about staged scenes like this is that it gives depth and personality to the game and is often highly appreciated by other Players. If done well, the stage director could give everyone involved a true feeling of being in a living environment.</p>
|
||
<p>The scene could continue to be played out around the PCs also as they interact, making this starter potentially demanding on the stage director. If the other Players are experienced they should pick up on this and maybe even contribute their own vNPCs to the scenario (or the stage director could actively invite other Players to do so). It&#x27;s important to remember to avoid god-modding here - never dictate another PCs actions, let other Players react as they see fit.</p>
|
||
<h3><a href="https://lh3.googleusercontent.com/ZLRgi7wonS0OUBRM-RUNCxiz-ZpkV0Upr2yIo4Sf8ROpOFaJtrXtAiHMWOmsel6TU3gCKyB7H5DIT9_fUDkebFT4SS1Tc1f_DHGoZUPjRnazFf5Qin-wlJI6u8QjJSqQodDoEQs"><img src="https://lh3.googleusercontent.com/ZLRgi7wonS0OUBRM-RUNCxiz-ZpkV0Upr2yIo4Sf8ROpOFaJtrXtAiHMWOmsel6TU3gCKyB7H5DIT9_fUDkebFT4SS1Tc1f_DHGoZUPjRnazFf5Qin-wlJI6u8QjJSqQodDoEQs" alt="" /></a></h3>
|
||
<h3>The Lazy Bum</h3>
|
||
<p>This is unfortunately the most common of starters and we&#x27;ve probably all done it one time or another. It does not involve anything but simply standing in a room. No action set, no nothing. Just being there, the Character staring blankly into space until something happens. Yeah.</p>
|
||
<h2>Scene entrances</h2>
|
||
<p>Here are some ideas on how to enter a scene/room with one or more other PCs already involved in role play. It should be noted that if other PCs already have a scene going they might be OOC annoyed if the newcomer muscles in with some room-changing entrance. So you as a Player have to show some consideration here. Check the land and eventual actions set on people in the room. If a great scene is already in progress you shouldn’t need to start your own - instead try to get in on the action!</p>
|
||
<h3><a href="https://lh6.googleusercontent.com/M5gSt-Jag0SvZy7Pb0esu44RkEdfzfrNuv10wp1nVHV6e0gWJozqYjaOTfUNuBCzK2AVko-jUE_mctHUvj7fsu9_3X8Wn85E6eTVkjD7QFkQpaT6Vx-wCylBZgE2UmD30A8BwtM"><img src="https://lh6.googleusercontent.com/M5gSt-Jag0SvZy7Pb0esu44RkEdfzfrNuv10wp1nVHV6e0gWJozqYjaOTfUNuBCzK2AVko-jUE_mctHUvj7fsu9_3X8Wn85E6eTVkjD7QFkQpaT6Vx-wCylBZgE2UmD30A8BwtM" alt="" /></a>The Mouse</h3>
|
||
<p>The most common of entering schemes. The Mouse walks into the room/area not drawing attention to themselves. A simple, passive setup that fits many situations and Character concepts. The mouse is a useful way to enter an already running scene. It is a bit overused though, possibly being The lazy bum of entrances. It seem to imply that it is up to others to notice and respond to the mouse. If really aiming for anonymity, the mouse must emote explicitly that they are not drawing attention to themselves, making it clear to other characters they need not go out of their way to be courteous and notice the newcomer.</p>
|
||
<h3>The Ignoranti</h3>
|
||
<p><a href="https://lh5.googleusercontent.com/DxLRp-g0L8meJkvI7WTLxvPtm2Q4GbMDOrdjWgwHifsnZn354T3SsMQKyIOQajX2mx8-SmfyjbKXOWUDbF-6WpkKq608iWDiIAeZHqtkIAfUvw-Kl2BWDNYdmTdVrKF5w7sgqHc"><img src="https://lh5.googleusercontent.com/DxLRp-g0L8meJkvI7WTLxvPtm2Q4GbMDOrdjWgwHifsnZn354T3SsMQKyIOQajX2mx8-SmfyjbKXOWUDbF-6WpkKq608iWDiIAeZHqtkIAfUvw-Kl2BWDNYdmTdVrKF5w7sgqHc" alt="" /></a>The ignoranti acts as if they do not notice the other Characters in the room. This entrance variant is useful for crowded or large locations. It is also realistic - just because the “chock-full” tavern has only two PCs in it, it doesn’t mean you would actually immediately notice them. vNPCs are everywhere. The ignoranti must emote their ignorance explicitly, with something like &quot;S/he does not notice the others yet&quot;. This entrance makes for a nice variation by allowing the ignoranti and other PCs to &quot;accidentally&quot; bump into each other later in a very natural way.</p>
|
||
<h3><a href="https://lh3.googleusercontent.com/edaRIo1m0kQ7U3N1xoijVUI0Gkgi7_l6uyRPTozq0ITfN1Oiaq0AovWkubMwhLEdg5Qtx-hg41XXJCavvLhToZnLHuYGoc0L2Asn6HJf9W-jxmQ-vgKDrPJ477e3ezB9b6EA-IM"><img src="https://lh3.googleusercontent.com/edaRIo1m0kQ7U3N1xoijVUI0Gkgi7_l6uyRPTozq0ITfN1Oiaq0AovWkubMwhLEdg5Qtx-hg41XXJCavvLhToZnLHuYGoc0L2Asn6HJf9W-jxmQ-vgKDrPJ477e3ezB9b6EA-IM" alt="" /></a></h3>
|
||
<h3>The Walker</h3>
|
||
<p>The walker is just &quot;passing through&quot; this area. This entrance is useful for outdoor areas or minor streets were many Character concepts probably have no real reason to be hanging about more than necessary. The walker is really heading somewhere else and just happens to stop to chat with people in this room. It&#x27;s an effective entrance that allows for quick, logical exits as well (they just have to &#x27;be on their way&#x27;). This is far better than the more common approach of just congesting onto a street room and start greeting people as if all you do is stand in the street all day.</p>
|
||
<h3>The Planned Visitor</h3>
|
||
<p><a href="https://lh6.googleusercontent.com/ZVc7Hd-nbgyqyW1UcvjLDi16RmPMbphOZzPecRHnUqSDxyQmdh0ACsGYy-XAv7xj12M_7bPauEPmgZykpIhVrjNy0xZTD9B5AgNSvFOpJ0NNm_xjjIdJj6wlgHdwZNpLia417qM"><img src="https://lh6.googleusercontent.com/ZVc7Hd-nbgyqyW1UcvjLDi16RmPMbphOZzPecRHnUqSDxyQmdh0ACsGYy-XAv7xj12M_7bPauEPmgZykpIhVrjNy0xZTD9B5AgNSvFOpJ0NNm_xjjIdJj6wlgHdwZNpLia417qM" alt="" /></a>This is a variation on The busybody and the opposite of The walker. The planned visitor needs to come to this room, and that is not in order to chat with random PCs. The visitor will start to perform whatever they are here to do and interaction with others is mere a side effect. The classic take on this trope is to read message boards or to order food and drink. More imaginative ones could be to ask the NPC barkeep for a job, look for a vNPC (which turns out to not be here), repair something, do some sort of inspection or setup for an artistic performance. If done well, others will have plenty of opportunity to ask The Planned Visitor what they are up to. It also makes for a thematic way to exit the scene once you declare your business there done.</p>
|
||
<h3><a href="https://lh4.googleusercontent.com/WWGpwuKchPjC6s9oh6B4c5c-VW9eoYRuXc_hPns6OQsatfv_Qtyj858Mj3y2IODS9kbMbWrim0FluhkkG65HEQULVFm1SPwVATWhkaRs4thScnmkpmruMKzfZ4T3ba7d9m1T_rc"><img src="https://lh4.googleusercontent.com/WWGpwuKchPjC6s9oh6B4c5c-VW9eoYRuXc_hPns6OQsatfv_Qtyj858Mj3y2IODS9kbMbWrim0FluhkkG65HEQULVFm1SPwVATWhkaRs4thScnmkpmruMKzfZ4T3ba7d9m1T_rc" alt="" /></a>The Wet Kitten</h3>
|
||
<p>A classic that involves entering a scene drenched to the bone, shivering from cold, gasping from heat or otherwise be dramatically and visually affected by whatever weather or situation reigns outside. Common to taverns everywhere. For some reason this entrance rarely instills as much sympathy as one would think - but at least it opens up for other Characters to comment on the weather. Taken to the extreme, this becomes a variation on Damsel in Distress.</p>
|
||
<h3>The Third Wheel</h3>
|
||
<p><a href="https://lh6.googleusercontent.com/v0kwyIVi0j5BqUnULNtUYT3hLtA_-FkqfckTA-NiLED56H2andf76UvXgioCHDExDdxbV4ALx7OqH6JKhSABQ2oOTaXJkRQntr7p7r0511_Wkm03rlEfMilqb318Iz1qWZelq8c"><img src="https://lh6.googleusercontent.com/v0kwyIVi0j5BqUnULNtUYT3hLtA_-FkqfckTA-NiLED56H2andf76UvXgioCHDExDdxbV4ALx7OqH6JKhSABQ2oOTaXJkRQntr7p7r0511_Wkm03rlEfMilqb318Iz1qWZelq8c" alt="" /></a>This is an active, provocative entrance and a variant on the aggravator. It should directly interrupt and involve other PCs in the room entered. The trivial confrontational way to do this is for the intruder to muscle or elbow past other PCs in a rude way, maybe even (attempting to) give them a rough shove (remember to avoid god-modding). This is sure to start off a scene! The more common third-wheel approach is to walk up to another group of conversing PCs and simply jump into their conversation mid-sentence. How this is received depends on the situation and Characters involved.</p>
|
||
<p>In both cases it&#x27;s important to make it clear that your actions is a conscious RP choice - it’s your Character which is inconsiderate, not the Player behind it. In other words, emote something like “... He/She does not seem to notice or care that s/he is intruding...”</p>
|
||
<h3><a href="https://lh5.googleusercontent.com/Aqil3Dbo2dsJAcOxOlk4w7vYNcyJi5FkbemipnPFpyl_VcvtKRlKsCOD7tKJ2NW57adNKA7D6Zqu5ocup-DwD8WGHq1Izq947cTx42fUs8mdC_E-ivCKRkHOoSW-4OF7-RaL9Ks"><img src="https://lh5.googleusercontent.com/Aqil3Dbo2dsJAcOxOlk4w7vYNcyJi5FkbemipnPFpyl_VcvtKRlKsCOD7tKJ2NW57adNKA7D6Zqu5ocup-DwD8WGHq1Izq947cTx42fUs8mdC_E-ivCKRkHOoSW-4OF7-RaL9Ks" alt="" /></a>The Theatrist</h3>
|
||
<p>This is an on-the-fly version of the Stage director or demagogue. Only use if it&#x27;s clear the currently ongoing scene allows it (so its often a good idea to follow a few emotes in the room before setting this one off). Just like stage director, it starts some sort of background action in the room based on vNPCs. Maybe a brawl, an argument or some other event like a happy announcement. Maybe a vNPC starts hitting on a PC. Or, like the demagogue, the theatrist gets involved in a discussion with an NPC/vNPC. Bartender NPCs are classically useful targets for this. Again, the theatrist must be considerate here, and perceptive so as to not take over an already running scene. Some PCs might forcibly choose to ignore the events going on in order to focus on their ongoing RP, so don&#x27;t shove it down their throats (no god-modding!)</p>
|
||
<h3><a href="https://lh6.googleusercontent.com/qwzycM2BAkL1Ad5WaUmdmCQ4E_l7zdq8Z4BMTYNqISqEmihrF6rVnRNdtBdZQnt1uSUJ0jR0130agWDIsqhSOpekDqN2J1fhB1KNDx-D-9B2NAj-JZmeAnjcZN8pP22ypV7iRNM"><img src="https://lh6.googleusercontent.com/qwzycM2BAkL1Ad5WaUmdmCQ4E_l7zdq8Z4BMTYNqISqEmihrF6rVnRNdtBdZQnt1uSUJ0jR0130agWDIsqhSOpekDqN2J1fhB1KNDx-D-9B2NAj-JZmeAnjcZN8pP22ypV7iRNM" alt="" /></a>The Non-sequitur</h3>
|
||
<p>This, strangely rare, entrance involves running into a crowded room, shouting &quot;Monkeeey!&quot; and then run out again. This one will at least lead to roleplay for the confused people in the room you just visited. And no, don&#x27;t do this unless you have a very specific and suitable character concept, kids.</p>
|
||
<h3><a href="https://lh3.googleusercontent.com/H1dasQzorKRf7wttBC4O-rgWrIpueB77Qj_9nDliP4SnImbI0Kc2FThSmT83TAYS2U37_8zv-gMb4v9EFa1KkMyLlKGLrv8FbbAiGmZ-5dCTyUUOPd8wvUZnvrGFhYHPjdAgDnA"><img src="https://lh3.googleusercontent.com/H1dasQzorKRf7wttBC4O-rgWrIpueB77Qj_9nDliP4SnImbI0Kc2FThSmT83TAYS2U37_8zv-gMb4v9EFa1KkMyLlKGLrv8FbbAiGmZ-5dCTyUUOPd8wvUZnvrGFhYHPjdAgDnA" alt="" /></a></h3>
|
||
<h3>The Newbie</h3>
|
||
<p>The classic newbie entrance involves walking into a room and saying &quot;Hello&quot; to no one in particular. Bonus points if this is done while ignoring the fact that the room&#x27;s on fire and the PCs within are all involved in mortal combat. Luckily this entrance trope screams newbie so clearly that players may be urged to pity and lenience. It may in fact be the trigger for getting a more experienced player to take the newbie under their wing and explain a thing or two.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 29 Oct 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-10-29-getting-a-mud-rp-scene-going</guid></item><item><title>Evennia in Hacktobergest 2017</title><link>2017.html#2017-10-01-evennia-in-hacktobergest-2017</link><description><p><a href="https://assets.digitalocean.com/ghost/2017/09/Hacktoberfest17-Blog-01.png"><img src="https://assets.digitalocean.com/ghost/2017/09/Hacktoberfest17-Blog-01.png" alt="" /></a></p>
|
||
<p>Evennia, the Python MUD/MUSH/MU* creation library participates in the <a href="https://hacktoberfest.digitalocean.com/">Hacktoberfest</a> 2017 (sign up on that page)! Hacktoberfest is open for all open-source projects like ours. After registering, if you make at least <strong>four</strong> Pull Requests to a public repo on Github during October (need not just be to Evennia), you win a limited-edition T-shirt!</p>
|
||
<p>The help Evennia out and get your T-Shirt, look at our <a href="https://github.com/evennia/evennia/issues">Issue Tracker</a>. I have marked some issues with &quot;Hacktoberfest&quot; but you could take on any issue you want. Take a look in particular at the <a href="https://github.com/evennia/evennia/issues/1458">Unit test issue</a> if you are looking to get into contributing on a smaller scale while helping us tremendously.</p>
|
||
<p>If you have any questions on contributing (or it&#x27;s your first time making a Pull Request), don&#x27;t be shy to drop into #evennia on irc.freenode.net or ask in our <a href="https://groups.google.com/forum/#%21forum/evennia">forum/mailing list</a>. Have fun!</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 01 Oct 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-10-01-evennia-in-hacktobergest-2017</guid></item><item><title>Evennia 0.7 released</title><link>2017.html#2017-09-20-evennia-0.7-released</link><description><h3><a href="https://evennia.blogspot.com/2017/09/evennia-07-released.html">Evennia 0.7 released</a></h3>
|
||
<p><a href="https://2.bp.blogspot.com/-7JYRn1RCBx4/Ty5kCnTY3oI/AAAAAAAABMM/TpmCOJ31orcl0O5b-i_wXVwL6lJLB3fkgCPcBGAYYCw/s1600/evennia_logo.png"><img src="https://2.bp.blogspot.com/-7JYRn1RCBx4/Ty5kCnTY3oI/AAAAAAAABMM/TpmCOJ31orcl0O5b-i_wXVwL6lJLB3fkgCPcBGAYYCw/s200/evennia_logo.png" alt="" /></a></p>
|
||
<p>As of today <strong>Evennia 0.7</strong> is officially out! Evennia is a Python framework and -server for creating text-based multiplayer games (MU*).</p>
|
||
<p>A big thank you to all collaborators that have helped with code and testing along the way!</p>
|
||
<p>Here is the <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/0JYYNGY-NfE">hefty forum post</a> that details how you migrate to Evennia 0.7.</p>
|
||
<p>Evennia 0.7 comes with a range of changes and updates (these are just the ones merged from the latest devel branch, a lot more has happened since 0.6 that were already in master):</p>
|
||
<ul>
|
||
<li>Evennia separates <code>Player</code> objects from <code>Character</code> objects in that the former is an OOC entity that can puppet one or more of the latter. The name <code>Player</code> was a source of some confusion since this is used differently in other code bases. <code>Player</code> has now been renamed to <code>Account</code> to make its function clearer.</li>
|
||
<li>Evennia&#x27;s in-built website now uses our own theme and <code>bootstrap</code> under the hood to make it easier to modify as well as rescale it better on mobile devices (webclient is not updated at this point).</li>
|
||
<li>Shared logins between webclient and website, with the ability to log out of each independently of the other if so desired.</li>
|
||
<li>Prefix-ignoring - All default commands are now renamed without their @-prefixes. Both @examine, +examine or examine will now all point to the same command. You can customize which prefixes Evennia simply ignores when searching for a command. The mechanic is clever though - if you create a command with a specific key &quot;+foo&quot;, then that will still work and won&#x27;t clash with another command named just &quot;foo&quot;.</li>
|
||
<li>Easy pause mechanisms using <code>yield</code> statements directly in Command code (just do <code>yield 10</code> in your command code to have it pause ten seconds without blocking anyone else). You can also do <code>retval = yield &quot;Do you want to accept?&quot;</code> and have the command pause (non-blocking) for the player&#x27;s input before continuing.</li>
|
||
</ul>
|
||
<p>New contribs (optional plugins) (selection, new since 0.6 but many have been available on <code>master</code> branch for a while):</p>
|
||
<ul>
|
||
<li>The optional <a href="https://github.com/evennia/evennia/wiki/Tutorials#contrib"><em>In-Game-Python</em></a> contrib by Vincent le Geoff allows for coding and scripting in-game using full-fledged Python to make events and triggers. It&#x27;s <em>not</em> a safe softcode-style language (you have the full power of Python which is not good for untrusted users) but is intended for trusted builders to make complex scripting from the command line.</li>
|
||
<li>Wilderness/maps - Creation of dynamic or static maps based on ascii-maps for dynamically creating rooms and to show when moving around. (titeuf87, Cloud Keeper)</li>
|
||
<li>Full turn-based combat system, meant to expand for a desired system (battlejenkins)</li>
|
||
<li>Alternative Unix-style command base for Evennia, for those that prefer to enter commands like you do on the unix command line (with <code>--flags</code> etc) (Vincent le Geoff)</li>
|
||
<li>Multidescer, which together with Evennia&#x27;s nick replacement system can be heavily customized in-game (me).</li>
|
||
<li>Mail - a <code>@brandymail</code>-style in-game mail-system (grungies1138)</li>
|
||
<li>Clothing system, for layered outfits adding to the wearer&#x27;s desc when worn (battlejenkins).</li>
|
||
</ul>
|
||
<p>A more technical list from the main announcement post:</p>
|
||
<ul>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1205">EvMenu formatting functions now part of class</a> - EvMenu no longer accepts formatting functions as inputs, these are now part of the EvMenu class. To override the formatting of EvMenu nodes you should now override EvMenu and replace the format method you want. This brings EvMenu more in line with other services in Evennia, all of which are built around overriding.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1179">Scripts are now valid message senders</a> - Also Scripts can now act as &quot;sender&quot; of a Msg, for example to a Channel or a player.</li>
|
||
<li>Due to the new prefix-ignoring above, <strong>@desc</strong> (builder-level description-setting) was renamed to <strong>setdesc</strong> to make it clearly separate from <strong>desc</strong> (used by a player setting their own description). This was actually the only clash we had to resolve this way in the default commands.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1175">Permission Hierarchy names change</a> - To make Evennia&#x27;s permission hierarchy better reflect how Evennia actually works, the old <strong>Players, Player Helpers, Builders, Wizards, Immortals</strong> hierarchy has changed to <strong>Player, Helper, Builder, Admin, Developer</strong>. Singular/Plural form is now ignored so <strong>Builder</strong> and <strong>Builders</strong> will both work (this was a common source of simple errors) Old permissions will be renamed as part of the migration process. The distribution of responsibilities has not changed: Wizards (which in some other systems was the highest level, which confused some) always had the power to affect player accounts (like an admin) whereas Immortals had server-level access such as @py - that is, they were developers. The new names hopefully makes this distinction clearer.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1206">All manager methods now return querysets</a> - Some of these used to return lists which was a throwback to an older version of Typeclasses. With manager methods returning querysets one can chain queries onto their results like you can with any django query.</li>
|
||
<li>PrettyTable was removed from the codebase. You can still fetch it for your game if you prefer (it&#x27;s on pypi). But <strong>EvTable</strong> has more functionality as well as color-support.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1276">Add *<em>kwargs support to all object at_</em> hooks</a> - All object at_ hooks, such as <strong>at_look</strong>, <strong>at_give</strong> etc now has an additional **kwarg argument. This allows developers to send arbitrary data to those hooks so they can expand on them without changing the API.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1229">Remove {-color tags</a> - The use of {r, {n etc was deprecated**** for years and have now been completely removed from Evennia&#x27;s core in favor of only one form, namely |r, |n etc. However, the color parser is now pluggable and the {-style as well as the %c style color tags etc can be re-added to your game since they are now in a contrib.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1288">Updated hooks for say/whisper commands</a> - There are now at_before/after_say sub-hooks to allow say to be more easily customized. There is still ongoing discussion on the best way to handle this (see e.g. <a href="https://github.com/evennia/evennia/pull/1419">this PR</a>).</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1365">More compact distribution of ports</a> - Before, Evennia distributed its ports widely, such as using <strong>4000, 4001, 8000, 8001, 5001, 8022</strong>, some of which appeared close but actually was unrelated in functionality. They were also scattered throughout the settings file. The port definitions have now all moved more closer together, at the top of the settings file. Evennia will now use ports <strong>4000-4006</strong> by default (fewer depending on which protocols you want to start). This should make it easier to assign port ranges when wanting to run multiple Evennia instances on the same machine.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/1063">Change how auto-login works</a> - It used to be that once you logged into the website, every time you went to the webclient you would auto-login, even if you manually quite the webclient before. Only way to really log out (to change account, say) would be to first log out of the website. Now this will work more intuitively - you will still auto-login but if you log out of the webclient you &quot;decouple&quot; from the login state of the website and need to re-login to the webclient next time, even if you are still logged into the website.</li>
|
||
<li><a href="https://github.com/evennia/evennia/issues/701">Better idle disconnects</a> - This is a long-running pet peeve for many. Idle timeouts will now honor a particular lock. Setting this lock allows selected entities (for example staff and bots) to avoid getting timed out like everyone else.</li>
|
||
<li>A slew of bug fixes and other tweaks. See <a href="https://github.com/evennia/evennia/projects/6">here</a> for the list.</li>
|
||
</ul>
|
||
</description><author>Griatch</author><pubDate>Wed, 20 Sep 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-09-20-evennia-0.7-released</guid></item><item><title> Renaming Django's Auth User and App</title><link>2017.html#2017-08-25-renaming-django's-auth-user-and-app</link><description><p><a href="https://4.bp.blogspot.com/-DRHk1mmLB0Y/WaCUd8tmYbI/AAAAAAAAHaU/QXkryhYVJBIVWPykT08nSokCHfFc6-2LACLcBGAs/s1600/birds-1976981_640.jpg"><img src="https://4.bp.blogspot.com/-DRHk1mmLB0Y/WaCUd8tmYbI/AAAAAAAAHaU/QXkryhYVJBIVWPykT08nSokCHfFc6-2LACLcBGAs/s400/birds-1976981_640.jpg" alt="" /></a></p>
|
||
<p>Now that <a href="http://www.evennia.com/">Evennia&#x27;s</a> devel branch (what will become Evennia 0.7) is slowly approaching completion, I thought I&#x27;d try to document an aspect of it that probably took me the longest to figure out. One change in Evennia 0.7 is that the Django model named &quot;Player&quot; changes name to &quot;Account&quot;. Over time it has become clear that the old name didn&#x27;t properly reflected the intention of the model. Sounds like a simple change, right? Well, it was not.</p>
|
||
<h3>Briefly on migrations</h3>
|
||
<p>First some background. A Django <em>migration</em> is a small Python file sitting in migrations/ sub folders throughout Evennia. A migration describes how our database schema changes over time, so as we change or update fields or add new features we add new migrations to describe how to go from the old to the new state. You apply them with the <code>evennia migrate</code> command we sometimes ask you to run. If we did not supply migrations, anyone with an existing Evennia database would have to either start from scratch or manually go in and tweak their database to match every upstream change we did.</p>
|
||
<p>Each migration file has a sequential number, like migration_name.0002.py etc. Migrations will run in order but each migration can also &quot;depend&quot; on another. This means for example that a migration in the player/ folder (application) knows that it need to wait for the changes done by a migration in the typeclasses/ folder/app before it can run. Finally, Django stores a table in the database to know which migrations were already run so to not apply them more than once.</p>
|
||
<p><em>For reference, Evennia is wrapping the django manage commands, so where I refer to evennia migrate below you would use manage.py migrate in most Django applications.</em></p>
|
||
<h3>Our problem</h3>
|
||
<p>So I wanted to migrate the database change &quot;Rename the Player model to Account&quot;. We had to do this under a series of additional constraints however:</p>
|
||
<ol>
|
||
<li>The Player is the Django Auth user, storing the password. Such a user Django expects to exist from the beginning of the migration history.</li>
|
||
<li>The Player model sits in a application (folder) named &quot;players&quot;. This folder should also be renamed to &quot;accounts&quot;, meaning any in-migration references to this from other apps would become invalid.</li>
|
||
<li>Our migration must both work for old <em>and</em> new users. That is, we cannot expect people to all have existing databases to migrate. Some will need to create the database from scratch and must be able to do so without needing to do any changes to the migration structure.</li>
|
||
<li>We have a lot of references to &quot;player&quot; throughout the code, all of which must be renamed.</li>
|
||
<li>The migration, including renames, should be possible to do by new users with newbie-level Python and database skills.</li>
|
||
</ol>
|
||
<h3>Some false starts</h3>
|
||
<p>There is no lack of tutorials and help online for solving the problem of renaming a model. I think I tested most of them. But none I found actually ended up addressing these restraints. Especially point <strong>2</strong> in combination with point <strong>3</strong> above is a <em>killer</em>.</p>
|
||
<ul>
|
||
<li>One of my first tries wiped the migrations table completely, renamed the folder and just assumed Player never existed. This sounds good on paper and works perfectly for fresh databases. But existing databases will still contain the old Player-related models. With the old migrations gone, this is now all wrong and there is no information on how to migrate it.</li>
|
||
<li>I tried initiating fresh migrations with a player model state so you can move an existing database over to it. But then fresh databases doesn&#x27;t work instead, since the player folder is gone. Also, you run into trouble with the auth system.</li>
|
||
<li>I next tried to keep the old migrations (those we know work both for old and new databases) but to migrate it in-place. I did many different attempts at this, but every time one of the restraints above would get in the way.</li>
|
||
<li>Eventually I wrote raw SQL code in the migrations to modify the database tables retroactively. That is, I basically manually removed all traces of Player in the database where it was, copying things table by table. This was very work-intensive but overall decently successful. With proper error-checking I could get most of the migration to work from old databases as well as for new databases. The trouble was the migrations themselves. No matter how I tried, I couldn&#x27;t get the migration history to accept what I had done - the dependencies now longer made sense on the database level (since I had manually edited things) and adding new migrations in the future would have been tricky.</li>
|
||
</ul>
|
||
<p>In the end I concluded that I had to abandon the notion that users be able to just do a single migrate command. Some more work would be needed on the user&#x27;s part.</p>
|
||
<h3>The solution</h3>
|
||
<p>In the end I needed to combine the power of migrations with the power of Git. Using Git resolved the Gordian knot about the player folder. Basically the process goes like this:</p>
|
||
<ul>
|
||
<li>First I copied of the <code>players</code> folder and renamed it and everything in it to accounts. I added this to settings.INSTALLED_APPS. I also copied the migrations from player and renamed everything in them appropriately - those migrations thus look like Account has always existed - so when you run the migration from scratch the database will be created normally. Note that this also means setting the Account as the auth user from the beginning of the migration history. This would be fine when migrating from scratch except for the fact that it would clash with the still existing Player model saying the same thing. We dodge this problem by the way we run this migration (we&#x27;ll get to this later).</li>
|
||
<li>Next I added one new migration in the Account app - this is the migration that copies the data from the player to the equivalent account-named copies in the database. Since Player will not exist if you run this from scratch you have to make sure that the Player model exists at that point in the migration chain. You can&#x27;t just do this with a normal import and traceback, you need to use the migration infrastructure. This kind of check works:</li>
|
||
</ul>
|
||
<pre><code class="language-python"> # ...
|
||
|
||
def forwards(apps, schema_editor):
|
||
try:
|
||
PlayerDB = apps.get_model(&quot;players&quot;, &quot;PlayerDB&quot;)
|
||
except LookupError:
|
||
return
|
||
|
||
# copy data from player-tables to database tables here
|
||
|
||
class Migrations(migrations.Migration):
|
||
# ...
|
||
operations = [
|
||
migrations.RunPython(forwards, migrations.RunPython.noop)
|
||
]
|
||
</code></pre>
|
||
<ul>
|
||
<li>Now, a lot of my other apps/models has ForeignKey or Many2Many relations to the Player model. Aided by viewing the tables in the database I visited all of those and added a migration to each where I duplicated the player-relation with a duplicate account relation. So at this point I had set up a parallel, co-existing duplicate of the Player model, named Account.</li>
|
||
<li>I now made sure to commit my changes to git and tag this position in the version history with a clear git tag for later reference. This is an important step. We are saving the historical point in time where the player- and account-apps coexisted.5. The git position safely saved, I now went about purging player. I removed the player app and its folder.</li>
|
||
<li>Since the player folder is not there, it&#x27;s migrations are not there either. So in another app (any would work) I made a migration to remove the player tables from the database. Thing is, the missing player app means other migrations also cannot reference it. It is possible I could have waited to remove the player/ folder so as to be able to do this bit in pure Python. On the other hand, that might have caused issues since you would be trying to migrate with two Auth users - not sure. As it were, I ended up purging the now useless player-tables with raw SQL:</li>
|
||
</ul>
|
||
<pre><code class="language-python"> from django.db import connection
|
||
|
||
# ...
|
||
|
||
def _table_exists(db_cursor, tablename):
|
||
&quot;Returns bool if table exists or not&quot;
|
||
sql_check_exists = &quot;SELECT * from %s;&quot; % tablename
|
||
### [Renaming Django&#x27;s Auth User and App](https://evennia.blogspot.com/2017/08/renaming-djangos-auth-user-and-app.html)
|
||
</code></pre>
|
||
<p><a href="https://4.bp.blogspot.com/-DRHk1mmLB0Y/WaCUd8tmYbI/AAAAAAAAHaU/QXkryhYVJBIVWPykT08nSokCHfFc6-2LACLcBGAs/s1600/birds-1976981_640.jpg"><img src="https://4.bp.blogspot.com/-DRHk1mmLB0Y/WaCUd8tmYbI/AAAAAAAAHaU/QXkryhYVJBIVWPykT08nSokCHfFc6-2LACLcBGAs/s400/birds-1976981_640.jpg" alt="" /></a></p>
|
||
<p>And with this, the migration&#x27;s design was complete. Below is how to actually <em>use</em> it ...</p>
|
||
<h3>Running the final migration</h3>
|
||
<p>In brief, what our users will do after pulling the latest code is as follows:</p>
|
||
<ol>
|
||
<li>If they are starting fresh, they just run <strong>evennia migrate</strong> as usual. All migrations referencing player will detect that there is no such app and just be skipped. They are finished, hooray!</li>
|
||
<li>If they have an existing database, they should make a copy of my renaming-program, then check out the tagged point in the git history I created above, a time when players and accounts coexisted in code.</li>
|
||
<li>Since an important aspect of Evennia is that users create their own game in a &quot;game&quot; folder, the user can now use my renaming program to interactively rename all occurrencies of <code>player</code> into <code>account</code> (the term &#x27;player&#x27; is so ubiquitous that they may have used in in different places they don&#x27;t want to rename).</li>
|
||
<li>Next they run migrations at that point of the git history. This duplicates player data into its renamed counterparts.</li>
|
||
<li>Now they should check out the latest Evennia again, jumping back to a point where the players application is gone and only accounts exists.</li>
|
||
<li>Note that our migration history is wrong at this point. It will still contain references to migrations from the now nonexisting players app. When trying to run from scratch, those will fail. We need to force Django to forget that. So the user must here go into their database of choice and run the single SQL statement <strong>DELETE FROM django_migations;</strong> . This clears the migration history. This is a step I wanted to avoid (since it requires users to use SQL) but in the end I concluded it must be done (and is hopefully a simple enough instruction).</li>
|
||
<li>Next, we trick the database to again think that we have run all the migrations from the beginning (this time without any mention of players). This is done with the <strong>--fake</strong> switch: <strong>evennia migrate --fake</strong> . This fake-applies all migrations and stores in the database that they have run.</li>
|
||
<li>However, the last few migrations are the ones I added just above. Those actually remove the player-related tables from the database. We really <em>do</em> want to run those. So we fake-<em>fake</em> undo those with <strong>evennia migrate --fake typeclasses 0007</strong>, which is the application and migration number I used to wipe players. This causes django to forget those migrations so we can run them again.</li>
|
||
<li>Finally we run evennia migrate. This runs the previously &quot;forgotten&quot; migrations and purges the last vestigest of players from the database. Done!</li>
|
||
</ol>
|
||
<h3>Conclusions</h3>
|
||
<p>And that&#x27;s it. It&#x27;s a bit more involved for the end user than I would have liked, and took me much longer than expected to figure out. But it&#x27;s possible to reproduce and you only need to do it once - and only if you have a database to convert. Whereas this is necessarily specified for Evennia, I hope this might give a hint for other django users aiming to do something like this!</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 25 Aug 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-08-25-renaming-django's-auth-user-and-app</guid></item><item><title>The luxury of a creative community</title><link>2017.html#2017-04-23-the-luxury-of-a-creative-community</link><description><p><a href="https://2.bp.blogspot.com/-dZZUpZiYFsY/WP0R1uhmXvI/AAAAAAAAG8M/q9zszXPIP_00n9C-0B6b1IapbEoiRtqgQCLcB/s1600/maxpixel.freegreatpicture.com-Silver-Treasure-Gold-Jewels-Costume-Jewelry-Pearls-395994.jpg"><img src="https://2.bp.blogspot.com/-dZZUpZiYFsY/WP0R1uhmXvI/AAAAAAAAG8M/q9zszXPIP_00n9C-0B6b1IapbEoiRtqgQCLcB/s320/maxpixel.freegreatpicture.com-Silver-Treasure-Gold-Jewels-Costume-Jewelry-Pearls-395994.jpg" alt="" /></a></p>
|
||
<p>For this blog post I want to focus on the series of very nice pull requests coming in from a growing cadre of contributors over the last few months.</p>
|
||
<h2>Contributed goodness</h2>
|
||
<p>People have put in a lot of good work to boost Evennia, both by improving existing things and by adding new features. Thanks a lot everyone (below is just a small selection)!</p>
|
||
<ul>
|
||
<li>
|
||
<p>Contrib: Turn-based combat system - this is a full, if intentionally bare-bones implementation of a combat system, meant as a template to put in your particular game system into.</p>
|
||
</li>
|
||
<li>
|
||
<p>Contrib: Clothing sytem - a roleplaying mechanic where a character can &#x27;wear&#x27; items and have this show in their descriptions. Worn items can also be layered to hide that underneath. Had plenty of opportunities for extensions to a given game.</p>
|
||
</li>
|
||
<li>
|
||
<p>Contrib: An &#x27;event&#x27; system is in the works, for allowing privileged builders to add dynamic code to objects that fires when particular events happen. The PR is not yet merged but promises the oft pondered feature of in-game coding without using softcode (and notably also without the security of softcode!).</p>
|
||
</li>
|
||
<li>
|
||
<p>A lot of PRs, especially from one user, dealt with cleanup and adherence to PEP8 as well as fixing the &#x27;alerts&#x27; given by <a href="https://lgtm.com/projects/g/evennia/evennia/">LGTM</a> on our code (LGTM is by the way a pretty nifty service, they parse the code from the github repo without actually running it and try to find problems. Abiding by their advice results is cleaner code and it also found some actual edge-case bugs here and there not covered by unit tests. The joint effort has brought us down from some 600+ alerts to somewhere around 90 - the remaining ones are alerts which I don&#x27;t agree with or which are not important enough to spend effort on).</p>
|
||
</li>
|
||
<li>
|
||
<p>The help mechanics of Evennia were improved by splitting up the default help command into smaller parts, making it easier to inject some changes to your help system without completely replacing the default one.</p>
|
||
</li>
|
||
<li>
|
||
<p>Evennia&#x27;s Xterm256 implementation was not correctly including the additional greyscale colors, those were added with new tags <strong>|=a</strong> ... <strong>|=z</strong>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Evennia has the ability to relay data to external services through &#x27;bots&#x27;. An example of this is the IRC bot, which is a sort of &#x27;player&#x27; that sits in an in-game channel and connects that to a counterpart-bot sitting in a remote IRC channel. It allows for direct game-IRC communication, something enjoyed by people in the Evennia demo for many years now. The way the bot was defined used to be pretty hard-coded though. A crafty contributor changed that though, but incorporating the bot mechanism into Evennia&#x27;s normal message flow. This allows for adding new types of bots or extending existing ones without having to modify Evennia&#x27;s core. There is already an alternative IRC bot out there that represents everyone in the IRC room as a room full of people in the MUD.</p>
|
||
</li>
|
||
<li>
|
||
<p>Evennia&#x27;s <strong>Attributes</strong> is a database table connected to other objects via a ForeignKey relation. This relation is cached on the object. A user however found that for certain implementations, such as using Attributes for large coordinate systems, <em>non-matches</em> (that is failed Attribute lookups on the object) can also be cached and leads to dramatic speed increases for those particular use cases. A PR followed. You live and learn.</p>
|
||
</li>
|
||
<li>
|
||
<p>Another contributor helped improve the EvEditor (Evennia&#x27;s VIM-like in-game text editor) by giving it a code-mode for editing Python code in-game with auto-indents and code execution. Jump into the code mode with the command <strong>@py/edit</strong>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Time scheduling is another feature that has been discussed now and then and has now been added through a PR. This means that rather than specifying &#x27;<em>Do this in 400 seconds</em>&#x27; you can say &#x27;<em>do this at 12AM, in-game time</em>&#x27;. The core system works with the real-world time units. If you want 10 hours to a day or two weeks to a month the same contributor also made an optional calendar contrib for that!</p>
|
||
</li>
|
||
<li>
|
||
<p>A new &#x27;whisper&#x27; command was added to the Default cmdset. It&#x27;s an in-game command for whispering to someone in the same room without other people hearing it. This is a nice thing to have considering Evennia is out-of-the-box pretty much offering the features of a &#x27;talker&#x27; type of game.</p>
|
||
</li>
|
||
<li>
|
||
<p>Lots of bug fixes big and small!</p>
|
||
</li>
|
||
<li>
|
||
<p>Some <strong>at_</strong>* hooks were added, such as <strong>at_give(giver, getter)</strong>. This allows for finer control of the give process without handling all the logics at the command level. There are others hooks in the works but those will not be added until in Evennia 0.7.</p>
|
||
</li>
|
||
</ul>
|
||
<h2>About that Evennia 0.7 ...</h2>
|
||
<p>So while PRs are popping up left and right in master I&#x27;ve been working in the <strong>devel</strong> branch towards what will be the Evennia 0.7 release. The branch is not ready for public consumption and testing yet But tentatively it&#x27;s about halfway there as I am slowly <a href="https://github.com/evennia/evennia/projects/6">progressing through the tickets</a>. Most of the upcoming features were covered in the previous blog post so I&#x27;ll leave it at that.</p>
|
||
<p>I just want to end by saying that it&#x27;s a very luxurious (and awesome) feeling for me to see master-branch Evennia expand with lots of new stuff &quot;without me&quot; so to speak. The power of Open Source indeed!</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 23 Apr 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-04-23-the-luxury-of-a-creative-community</guid></item><item><title>News items from the new year</title><link>2017.html#2017-02-05-news-items-from-the-new-year</link><description><p><a href="https://cloud.githubusercontent.com/assets/294267/22219746/511151f8-e1ac-11e6-8445-9cdfd4b9ab5d.png"><img src="https://cloud.githubusercontent.com/assets/294267/22219746/511151f8-e1ac-11e6-8445-9cdfd4b9ab5d.png" alt="" /></a></p>
|
||
<p>The last few months have been mostly occupied with fixing bugs and straightening out usage quirks as more and more people take Evennia through its paces.</p>
|
||
<h2>Webclient progress</h2>
|
||
<p>One of our contributors, mewser/titeuf87 has put in work on implementing part of our roadmap for the webclient. In the first merged batch, the client now has an option window for adjusting and saving settings. This is an important first step towards expanding the client&#x27;s functionality. Other features is showing help in an (optional) popup window and to report window activity by popup and/or sound.</p>
|
||
<p>The goal for the future is to allow the user or developer to split the client window into panes to which they can then direct various output from the server as they please It&#x27;s early days still but some of the example designs being discussed can be found in the <a href="https://github.com/evennia/evennia/wiki/Webclient%20brainstorm">wiki webclient brainstorm</a> (see the title image of this blog for one of the mockups).</p>
|
||
<h2>New server stuff</h2>
|
||
<p>Last year saw the death of our old demo server on horizondark.com, luckily the new one at <a href="http://silvren.com:4281/">silvren.com</a> has worked out fine with no hickups. As part of setting that up, we also got together a more proper list of recommended hosts for Evennia games. Evennia requires more memory than your average C code base so this is important information to have. It seems most of our users run Evennia on various cloud hosting services rather than from a traditional remote server login.</p>
|
||
<h2>Arx going strong</h2>
|
||
<p>The currently largest Evennia game, the mush <a href="http://play.arxmush.org/">Arx - After the Reckoning</a> has helped a lot in stress testing. Their lead coder Tehom has also been active both in reporting issues and fixing them - kudos! There are however <a href="https://github.com/evennia/evennia/issues?utf8=%E2%9C%93&amp;q=is%3Aopen%20is%3Aissue%20author%3ATehomCD%20label%3Abug">some lingering issues</a> which appears rarely enough that they have not been possible to reproduce yet; we&#x27;re working on those. Overall though I must say that considering how active Arx is, I would have expected to have seen even more &quot;childhood diseases&quot; than we have.</p>
|
||
<h2>Launch scripts and discussions</h2>
|
||
<p>It is always interesting with feedback, and some time back another discussion thread erupted over on <a href="http://musoapbox.net/topic/1366/what-is-out-there-hard-and-soft-codebases-of-choice">musoapbox, here</a>. The musoapbox regulars have strong opinions about many things and this time some were critical of Evennia&#x27;s install process. They felt it was too elaborate with too many steps, especially if you are approaching the system with no knowledge about Python. Apparently the average MUSH server has a much shorter path to go (even though that does require C compiling). Whereas I don&#x27;t necessarily agree with all notions in that thread, it&#x27;s valuable feedback - I&#x27;ve long acknowledged that it&#x27;s hard to know just what is hard or not for a beginner.</p>
|
||
<p>Whereas we are planning to eventually move Evennia to pypi (so you can do pip install evennia), the instructions around getting virtualenv setup is not likely to change. So there is now unix shell scripts supplied with the system for installing on debian-derived systems (Debian, Ubuntu, Mint etc). I also made scripts for automating the setup and launch of Evennia and to use it with linux&#x27; initd within the scope of a virtualenv.<br />
|
||
So far these scripts are not tested by enough people to warrant them being generally recommended, but if you are on a supported OS and is interested to try they are found from the top of the Evennia repo, in bin/unix/. More info can be found <a href="https://github.com/evennia/evennia/wiki/Start-Stop-Reload#optional-server-startup-script-linux-only">on their documentation page</a>.</p>
|
||
<h2>Docker</h2>
|
||
<p>Speaking of installing, Evennia now has an official Docker image, courtesy of the work of contributor and Ainneve dev feend78. The image is automatically kept up-to.date with the latest Evennia repo and allows Evennia to be easily deployed in a production environment (most cloud services supports this). See <a href="https://github.com/evennia/evennia/wiki/Running%20Evennia%20in%20Docker">Docker wiki page</a> for more info.</p>
|
||
<h2>Lots of new PRs</h2>
|
||
<p>There was a whole slew of contributions waiting for me when returning from Chistmas break, and this has not slowed since. Github makes it easy to contribute and I think we are really starting to see this effect (Google Code back in the day was not as simple in this regard). The best thing with many of these PRs is that they address common things that people need to do but which could be made simpler or more flexible. It&#x27;s hard to plan for all possibilities, so many people using the system is the best way to find such solutions.</p>
|
||
<p>Apart from the map-creation contribs from last year we also have a new Wildnerness system by mewser/titeuf87. This implements wilderness according to an old idea I had on the mailing list - instead of making a room per location, players get a single room. The room tracks its coordinate in the wildnerness and updates its description and exits dynamically every time you move. This way you could in principle have an infinite wilderness without it taking any space. It&#x27;s great to see the idea turned into a practical implementation and that it seems to work so well. Will be fun to see what people can do with it in the future!</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 05 Feb 2017 00:00:00 GMT</pubDate><guid isPermaLink="true">2017.html#2017-02-05-news-items-from-the-new-year</guid></item><item><title>Birthday retrospective</title><link>2016.html#2016-11-30-birthday-retrospective</link><description><p><a href="https://4.bp.blogspot.com/-pW3nsIxgroY/WDDFXo3z2dI/AAAAAAAAEs8/n9ehRTZrlggiEIOMGZupSVFxYa7DSGsZgCPcB/s1600/evennia_logo_festive_small.png"><img src="https://4.bp.blogspot.com/-pW3nsIxgroY/WDDFXo3z2dI/AAAAAAAAEs8/n9ehRTZrlggiEIOMGZupSVFxYa7DSGsZgCPcB/s200/evennia_logo_festive_small.png" alt="" /></a></p>
|
||
<p>So, recently Evennia celebrated its ten-year anniversary. That is, it was on Nov 20, 2006, Greg Taylor made the first repo commit to what would eventually become the Evennia of today. Greg has said that Evennia started out as a &quot;weird experiment&quot; of building a MUD/MUX using Django. The strange name he got from a cheesy NPC in the <a href="https://wiki.guildwars.com/wiki/Evennia">Guild Wars</a> MMORPG and Greg&#x27;s <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/5hQTspfWd_Q">first post</a> to the mailing list also echoes the experimental intention of the codebase. The merger with Twisted came <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/CJ52R4Ws0OM">pretty early too</a>, replacing the early asyncore hack he used and immediately seeing a massive speedup. Evennia got attention from the MUD community - clearly a Python-based MUD system sounded attractive.</p>
|
||
<p>When I first joined the project I had been looking at doing something MUD-like in Python for a good while. I had looked over the various existing Python code bases at the time and found them all to be either abandoned or very limited. I had a few week&#x27;s stunt working with <a href="https://sourceforge.net/projects/pymoo/">pymoo</a> before asking myself why I was going through the trouble of parsing a custom script language <em>... in Python</em> ... Why not use Python throughout? This is when I came upon Evennia. I started <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/yfR0GLKGhJA">making contributions</a> and around 2010 I <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/zXsA2PaWUoU">took over the development</a> as real life commitments forced Greg to step down.</p>
|
||
<p>Over the years we have gone through a series of changes. We have gone from using SVN to Mercurial and then to using GIT. We have transited from GoogleCode to GitHub - the main problem of which was converting the wiki documentation (Evennia has <a href="https://github.com/evennia/evennia/wiki">extensive documentation</a>).</p>
|
||
<p>For a long time we used Python&#x27;s reload() function to add code to the running game. It worked ... sometimes, depending on what you changed. Eventually it turned out to be so unpredictable that we now use two processes, one to connect clients to and the other running the game, meaning we can completely restart one process without disconnecting anyone.</p>
|
||
<p>Back in the day you were also expected to create your own game in a folder game/ inside the Evennia repo itself. It made it really hard for us to update that folder without creating merge conflicts all over. Now Evennia is a proper library and the code you write is properly separated from ours.</p>
|
||
<p>So in summary, many things have happened over the years, much of it documented in this blog. With 3500 commits, 28 000 lines of code (+46% comments) and some 25 people contributing in the last year, <a href="https://www.openhub.net/p/evennia">Openhub</a> lists us as</p>
|
||
<blockquote>
|
||
<p>&quot;<em>A mature, well-established codebase with a stable commit history, a large development team and very well documented source code</em>&quot;.</p>
|
||
</blockquote>
|
||
<p>It&#x27;s just words compiled by an algorithm, but they still feel kinda good!</p>
|
||
<p>While Evennia was always meant to be used for any type of multiplayer text game, this general use have been expanded and cleaned up a lot over the years.</p>
|
||
<p>This has been reflected in the width of people wanting to use it for different genres: Over time the MUSH people influenced us into adding the option to play the same character from many different clients at the same time (apparently, playing on the bus and then continuing on another device later is common for such games). Others have wanted to use Evennia for interactive fiction, for hack&amp;slash, deep roleplay, strategy, education or just for learning Python.</p>
|
||
<p>Since Evennia is a framework/library and tries to not impose any particular game systems, it means there is much work to do when building a game using Evennia. The result is that there are dozens of games &quot;in production&quot; using Evennia (and more we probably don&#x27;t know about), but few public releases yet.</p>
|
||
<p>The first active &quot;game&quot; may have been an Evennia game/chat supporting the Russian version of 4chan... The community driven Evennia demo-game <a href="http://ainneve.evennia.com/">Ainneve</a> is also progressing, recently adding combat for testing. This is aimed at offering an example of more game-specific code people can build from (the way Diku does). There are similar projects meant for helping people create RPI (RolePlay Intensive) and MUSH-style games. That said, the Evennia-game <a href="http://games.evennia.com/game/arx">Arx, After the Reckoning</a> is progressing through beta at a good clip and is showing all signs of becoming the first full-fledged released Evennia game.</p>
|
||
<p>So cheers, Evennia for turning 10. That&#x27;s enough of the introspection and history. I&#x27;ll get back to more technical aspects in the next post.</p>
|
||
</description><author>Griatch</author><pubDate>Wed, 30 Nov 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-11-30-birthday-retrospective</guid></item><item><title>Season of fixes</title><link>2016.html#2016-10-13-season-of-fixes</link><description><p><a href="https://2.bp.blogspot.com/-WRQkMo7-t8o/V_931Qgj7bI/AAAAAAAAEq4/GN2_I60bzdQGpgqJ_Brl-dFnmxK_2QsiACPcB/s1600/New_hampshire_in_autumn.jpg"><img src="https://2.bp.blogspot.com/-WRQkMo7-t8o/V_931Qgj7bI/AAAAAAAAEq4/GN2_I60bzdQGpgqJ_Brl-dFnmxK_2QsiACPcB/s320/New_hampshire_in_autumn.jpg" alt="" /></a></p>
|
||
<p>The last few months has been dominated by bug-fixing and testing in Evennia-land. A lot more new users appears to be starting to use Evennia, especially from the <a href="https://en.wikipedia.org/wiki/MUSH">MUSH</a> world where the Evennia-based <em><a href="http://play.arxgame.org/">Arx, After the Reckoning</a></em> is, while still in alpha, currently leading the charge.</p>
|
||
<p>With a new influx of users comes the application of all sorts of use- and edge-cases that stretch and exercise the framework in all the places where it matters. There is no better test of code than new users trying to use it unsupervised! Evennia is holding up well overall but there are always things that can be improved.</p>
|
||
<ul>
|
||
<li>I reworked the way on-object Attributes was cached (from a stupid but simple way to a lot more sophisticated but harder way) and achieved three times faster performance in certain special cases people had complained about. Other issues also came to view while diving into this, which could be fixed.</li>
|
||
<li>I reworked the venerable batch command and batchcode processors (these allow to create a game world from a script file) and made their inputs make more sense to people. This was one of the older parts of Evennia and apart from the module needing a big refactoring to be easier to read, some parts were pretty fragile and prone to break. Especially when passing it file names tended to be confusing since it understood only certain relative paths to the files to read in and not even I could remember if one should include the file ending or not. This was cleaned up a lot.</li>
|
||
<li>Lots of changes and updates were made to the RPSystem contrib, which optionally adds more advanced roleplaying mechanics to Evennia. The use of this in Evennia&#x27;s demo game (<a href="https://github.com/evennia/ainneve">Ainneve</a>, being separately developed) helps a lot for ironing out any remaining wrinkles.</li>
|
||
<li>Lots and lots of other fixes and smaller feature updates were done (About <a href="https://www.blogger.com/goog_1124770844"></a><a href="https://github.com/evennia/evennia/commits/master">150 commits and 50 Issues</a> closed since end of summer).</li>
|
||
</ul>
|
||
<p>A fun thing with a growing user base is that we are also starting to see a lot more Pull requests and contributions. Thanks a lot, keep &#x27;em coming!</p>
|
||
<ul>
|
||
<li>Map system contrib (merged), for creating a world based on ASCII map. Talking about maps, users contributed not just one but two new tutorials for implementing both static and dynamic maps with Evennia.</li>
|
||
<li>Webclient notifications (pending), for making the webclient show us in a clearer way when it gets updated in a different tab. A more advanced implementation awaits the webclient being expanded with a proper client-side option window; there is currently a feature request for this if anyone&#x27;s interested in taking it on.</li>
|
||
<li>AI system contrib (pending). This is a full AI backend for adding complex behaviors to game agents. It uses Behavioral trees and is designed to be modified both in code and from inside the game.</li>
|
||
<li>Action system contrib (pending). This contrib assigns the actions of Characters a time cost and delays the results of commands the given time. It also allows players to go into turn-based mode to enforce a strict action order.</li>
|
||
<li><em>Lots</em> of now closed PRs were contributed by the Arx lead developer to fix various bugs and edge-cases as they came up in live use.</li>
|
||
</ul>
|
||
<p>The fixing and tightening of the nuts and bolts will likely continue the remainder of the year. I&#x27;m currently working on a refactoring of the way command sets are merged together (see the end of my <a href="http://evennia.blogspot.se/2016/05/evennia-in-pictures.html">blog post on Evennia in pictures</a> for a brief summary of the command system). But with so much new blood in the community, who can tell where things will turn from here!</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 13 Oct 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-10-13-season-of-fixes</guid></item><item><title>The art of sharing nicks and descriptions</title><link>2016.html#2016-07-01-the-art-of-sharing-nicks-and-descriptions</link><description><p><a href="https://3.bp.blogspot.com/-wIhCzMzQyho/V3aDpCR8dEI/AAAAAAAAEog/L8_xmAiXKK8b-42Zoa7t8vjgpIBx1fgnQCLcB/s1600/142455033_49ce50a89b_m.jpg"><img src="https://3.bp.blogspot.com/-wIhCzMzQyho/V3aDpCR8dEI/AAAAAAAAEog/L8_xmAiXKK8b-42Zoa7t8vjgpIBx1fgnQCLcB/s320/142455033_49ce50a89b_m.jpg" alt="" /></a></p>
|
||
<p>In the month or so since the merger of Evennia&#x27;s development branch and all its web-client updates, we have been in bug-fixing mode as more people use and stress the code.</p>
|
||
<p>There have been some new features as well though - I thought it could be interesting to those of you not slavishly following the mailing list.</p>
|
||
<h3>Shared web login</h3>
|
||
<p>When you are logged into the website you will now also auto-login to your account in the web client - no need to re-enter the login information! The inverse is also true. You still need to connect to game at least once to create the account, but after that you will stay connected while the browser session lasts.</p>
|
||
<p>Behind the scenes the shared login uses cookies linked to server-side Django sessions which is a robust and safe way to manage access tokens. Obviously browser sessions are irrelevant to telnet- or ssh connections.</p>
|
||
<h3>Extended Nicks</h3>
|
||
<p>Evennia&#x27;s nick(name) system is a way to create a personal alias for things in game - both to on-the-fly replacing text you input and for referring to in-game objects. In the old implementation this replacement was simply matched from the beginning of the input - if the string matched, it was replaced with the nick.</p>
|
||
<p>In this new implementation, the matching part can be much more elaborate. For example you can catch arguments and put those arguments into the replacement nick in another order.</p>
|
||
<p>Let&#x27;s say we often use the @dig command this limited way:</p>
|
||
<blockquote>
|
||
<p><strong>@dig roomname;alias = exit;alias, backexit;alias</strong></p>
|
||
</blockquote>
|
||
<p>Let&#x27;s say we find this syntax unintuitive. The new nick system allows to change this by catching the arguments in your nick and put it into the &quot;real&quot; command. Here is an example of a syntax putting the aliases in parentheses and separating all components with commas:</p>
|
||
<p><strong>&gt; nick newroom $1($2), $3($4), $5($6) = @dig $1;$2 = $3;$4, $5;$6</strong></p>
|
||
<p>From here on you can now create your rooms with entries like this:</p>
|
||
<p><strong>&gt; newroom The great castle(castle), to the castle(castle), back to the path(back)</strong></p>
|
||
<h3>Multidescer contrib</h3>
|
||
<p>I have added a new &quot;multidescer&quot; to the contrib folder. A multidescer is (I think) a MUSH term for a mechanism managing more than one description. You can then combine any of these various descriptions into your &quot;active&quot; description.</p>
|
||
<p>An example of usage:</p>
|
||
<p><strong>desc hat = a blue hat.</strong><br />
|
||
<strong>desc basic = This is a tall man with narrow features.</strong><br />
|
||
<strong>desc clothing = He is wearing black, flowing robes.</strong></p>
|
||
<p>These commands store the description on the Character and references them as unique keywords. Next we can combine these strings together in any order to build the actual current description:</p>
|
||
<p><strong>&gt; desc/set basic + |/ + clothing + On his head he has + hat</strong><br />
|
||
<strong>&gt; look self</strong><br />
|
||
<strong>This is a tall man with narrow features.</strong><br />
|
||
<strong>He is wearing black, flowing robes. On his head he has a blue hat.</strong></p>
|
||
<p>This allows for both very flexible and easy-to-update descriptions but also a way to handle freeform equipment and clothing. And you can of course use the nick system to pre-format the output</p>
|
||
<p><strong>&gt; nick setdesc $1 $2 $3 $4 = $1 + |/ + clothing + On his head he has a $4</strong></p>
|
||
<p>This way you can clothe yourself in different outfits easily using the same output format:</p>
|
||
<p><strong>&gt; setdesc basic clothing hat</strong></p>
|
||
<pre><code>
|
||
</code></pre>
|
||
<p>The multidescer is a single, self-contained command that is easy to import and add to your game as needed.</p>
|
||
<p>... There&#x27;s also plenty of bug fixes, documentation work and other minor things or course.</p>
|
||
<p>Anyway, summer is now upon us here in the northern hemisphere so things will calm down for a bit, at least from my end. Have a good &#x27;un!</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 01 Jul 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-07-01-the-art-of-sharing-nicks-and-descriptions</guid></item><item><title>Evennia in Pictures</title><link>2016.html#2016-05-31-evennia-in-pictures</link><description><p>This article describes the MU* development system <a href="http://www.evennia.com/">Evennia</a> using pictures!</p>
|
||
<p><em>This article was originally written for <a href="http://www.optionalrealities.com/">Optional Realities</a>.</em></p>
|
||
<p><em>Since it is no longer available to read on OR, I&#x27;m reposting it in full here.</em></p>
|
||
<h4>Figure 1: The parts of the Evennia library</h4>
|
||
<p><a href="https://2.bp.blogspot.com/-0-oir21e76k/W3kaUuGrg3I/AAAAAAAAJLU/qlQWmXlAiGUz_eKG_oYYVRf0yP6KVDdmQCEwYBhgL/s1600/Evennia_illustrated_fig1.png"><img src="https://2.bp.blogspot.com/-0-oir21e76k/W3kaUuGrg3I/AAAAAAAAJLU/qlQWmXlAiGUz_eKG_oYYVRf0yP6KVDdmQCEwYBhgL/s640/Evennia_illustrated_fig1.png" alt="" /></a></p>
|
||
<p>Evennia is a game development library. What you see in Figure 1 is the part you download from us. This will not run on its own, we will soon initialize the missing “jigsaw puzzle” piece on the left. But first let’s look at what we’ve got.</p>
|
||
<p>Looking at Figure 1 you will notice that Evennia internally has two components, the Portal and the Server. These will run as separate processes.</p>
|
||
<p>The Portal tracks all connections to the outside world and understands Telnet protocols, websockets, SSH and so on. It knows nothing about the database or the game state. Data sent between the Portal and the Server is protocol-agnostic, meaning the Server sends/receives the same data regardless of how the user is connected. Hiding behind the Portal also means that the Server can be completely rebooted without anyone getting disconnected.</p>
|
||
<p>The Server is the main “mud driver” and handles everything related to the game world and its database. It&#x27;s asynchronous and uses <a href="http://twistedmatrix.com/trac/">Twisted</a>. In the same process of the Server is also the Evennia web server component that serves the game’s website. That the Server and webserver are accessing the database in the same process allows for a consistent game state without any concerns for caching or race condition issues.</p>
|
||
<p>Now, let’s get a game going. We’ll call it mygame. Original, isn’t it?</p>
|
||
<h4>Figure 2: The full setup for mygame</h4>
|
||
<p><a href="https://4.bp.blogspot.com/-TuLk-PIVyK8/W3kaUi-e-MI/AAAAAAAAJLc/DA9oMA6m5ooObZlf0Ao6ywW1jHqsPQZAQCEwYBhgL/s1600/Evennia_illustrated_fig2.png"><img src="https://4.bp.blogspot.com/-TuLk-PIVyK8/W3kaUi-e-MI/AAAAAAAAJLc/DA9oMA6m5ooObZlf0Ao6ywW1jHqsPQZAQCEwYBhgL/s640/Evennia_illustrated_fig2.png" alt="" /></a></p>
|
||
<p>After <a href="https://github.com/evennia/evennia/wiki/Getting-Started">installing evennia</a> you will have the evennia command available. Using this you create a game directory - the darker grey piece in Figure 2 that was missing previously. This is where you will create your dream game!</p>
|
||
<p>During initialization, Evennia will create Python module templates in mygame/ and link up all configurations to make mygame a fully functioning, if empty, game, ready to start extending. Two more commands will create your database and then start the server. From this point on, mygame is up and running and you can connect to your new game with telnet on localhost:4000 or by pointing your browser to http://localhost:4001.</p>
|
||
<p>Now, our new mygame world needs Characters, locations, items and more! These we commonly refer to as game entities. Let’s see how Evennia handles those.</p>
|
||
<h4>Figure 3: The Database Abstraction of Evennia entities</h4>
|
||
<p><a href="https://3.bp.blogspot.com/-81zsySVi_EE/W3kaVRn4IWI/AAAAAAAAJLc/yA-j1Nwy4H8F28BF403EDdCquYZ9sN4ZgCEwYBhgL/s1600/Evennia_illustrated_fig3.png"><img src="https://3.bp.blogspot.com/-81zsySVi_EE/W3kaVRn4IWI/AAAAAAAAJLc/yA-j1Nwy4H8F28BF403EDdCquYZ9sN4ZgCEwYBhgL/s400/Evennia_illustrated_fig3.png" alt="" /></a></p>
|
||
<p>Evennia is fully persistent and abstracts its database in Python using <a href="https://www.djangoproject.com/">Django</a>. The database tables are few and generic, each represented by a single Python class. As seen in Figure 3, the example ObjectDB Python class represents one database table. The properties on the class are the columns (fields) of the table. Each row is an instance of the class (one entity in the game).</p>
|
||
<p>Among the example columns shown is the key (name) of the ObjectDB entity as well as a <a href="https://en.wikipedia.org/wiki/Foreign_key">Foreign key</a>-relationship for its current “location”. From the above we can see that Trigger is in the Dungeon, carrying his trusty crossbow Old Betsy!</p>
|
||
<p>The db_typeclass_path is an important field. This is a python-style path and tells Evennia which subclass of ObjectDB is actually representing this entity.</p>
|
||
<h4>Figure 4: Inheriting classes to customize entities</h4>
|
||
<p><a href="https://2.bp.blogspot.com/--4_MqVdHj8Q/W3kaVpdAZKI/AAAAAAAAJLk/jvTsuBBUlkEbBCaV9vyIU0IWiuF6PLsSwCEwYBhgL/s1600/Evennia_illustrated_fig4.png"><img src="https://2.bp.blogspot.com/--4_MqVdHj8Q/W3kaVpdAZKI/AAAAAAAAJLk/jvTsuBBUlkEbBCaV9vyIU0IWiuF6PLsSwCEwYBhgL/s400/Evennia_illustrated_fig4.png" alt="" /></a></p>
|
||
<p>In Figure 4 we see the (somewhat simplified) Python class inheritance tree that you as an Evennia developer will see, along with the three instanced entities.</p>
|
||
<p>ObjectDB represents stuff you will actually see in-game and its child classes implement all the handlers, helper code and the hook methods that Evennia makes use of. In your mygame/ folder you just import these and overload the things you want to modify. In this way, the Crossbow is modified to do the stuff only crossbows can do and CastleRoom adds whatever it is that is special about rooms in the castle.</p>
|
||
<p>When creating a new entity in-game, a new row will automatically be created in the database table and then “Trigger” will appear in-game! If we, in code, search the database for Trigger, we will get an instance of the Character class back - a Python object we can work with normally.</p>
|
||
<p>Looking at this you may think that you will be making a lot of classes for every different object in the game. Your exact layout is up to you but Evennia also offers other ways to customize each individual object, as exemplified by Figure 5.</p>
|
||
<h4>Figure 5: Adding persistent Attributes to a game entity.</h4>
|
||
<p><a href="https://3.bp.blogspot.com/-6ulv5T_gUCI/W3kaViWBBfI/AAAAAAAAJLU/0NqeAsz3YVsQKwpODzsmjzR-7tICw1pTQCEwYBhgL/s1600/Evennia_illustrated_fig5.png"><img src="https://3.bp.blogspot.com/-6ulv5T_gUCI/W3kaViWBBfI/AAAAAAAAJLU/0NqeAsz3YVsQKwpODzsmjzR-7tICw1pTQCEwYBhgL/s400/Evennia_illustrated_fig5.png" alt="" /></a></p>
|
||
<p>The Attribute is another class directly tied to the database behind the scenes. Each Attribute basically has a key, a value and a ForeignKey relation to another ObjectDB. An Attribute serializes Python constructs into the database, meaning you can store basically any valid Python, like the dictionary of skills seen in Figure 5. The “strength” and “skills” Attributes will henceforth be reachable directly from the Trigger object. This (and a few other resources) allow you to create individualized entities while only needing to create classes for those that really behave fundamentally different.</p>
|
||
<h4>Figure 6: Sessions, Players and Objects</h4>
|
||
<p><a href="https://4.bp.blogspot.com/-u-npXjlq6VI/W3kaVwAoiUI/AAAAAAAAJLY/T9bhrzhJJuQwTR8nKHH9GUxQ74hyldKOgCEwYBhgL/s1600/Evennia_illustrated_fig6.png"><img src="https://4.bp.blogspot.com/-u-npXjlq6VI/W3kaVwAoiUI/AAAAAAAAJLY/T9bhrzhJJuQwTR8nKHH9GUxQ74hyldKOgCEwYBhgL/s400/Evennia_illustrated_fig6.png" alt="" /></a></p>
|
||
<p>Trigger is most likely played by a human. This human connects to the game via one or more Sessions, one for each client they connect with. Their account on mygame is represented by a PlayerDB entity. The PlayerDB holds the password and other account info but has no existence in the game world. Through the PlayerDB entity, Sessions can control (“puppet”) one or more ObjectDB entities in-game.</p>
|
||
<p>In Figure 6, a user is connected to the game with three Sessions simultaneously. They are logged in to their Player account Richard. Through these Sessions they are simultaneously puppeting the in-game entities Trigger and Sir Hiss. Evennia can be configured to allow or disallow a range of different gaming styles like this.</p>
|
||
<p>Now, for users to be able to control their game entities and actually play the game, they need to be able to send Commands.</p>
|
||
<h4>Figure 7: Commands are Python classes too</h4>
|
||
<p><a href="https://3.bp.blogspot.com/-_RM9-Pb2uKg/W3kaWIs4ndI/AAAAAAAAJLc/n45Hcvk1PiYhNdBbAAr_JjkebRVReffTgCEwYBhgL/s1600/Evennia_illustrated_fig7.png"><img src="https://3.bp.blogspot.com/-_RM9-Pb2uKg/W3kaWIs4ndI/AAAAAAAAJLc/n45Hcvk1PiYhNdBbAAr_JjkebRVReffTgCEwYBhgL/s400/Evennia_illustrated_fig7.png" alt="" /></a></p>
|
||
<p>Commands represent anything a user can input actively to the game, such as the look command, get, quit, emote and so on.</p>
|
||
<p>Each Command handles both argument parsing and execution. Since each Command is described with a normal Python class, it means that you can implement parsing once and then just have the rest of your commands inherit the effect. In Figure 7, the DIKUCommand parent class implements parsing of all the syntax common for all DIKU-style commands so CmdLook and others won’t have to.</p>
|
||
<h4>Figure 8: Commands are grouped together in sets and always associated with game entities.</h4>
|
||
<p><a href="https://2.bp.blogspot.com/-pgpYPsd4CLM/W3kaWG2ffuI/AAAAAAAAJLg/LKl4m4-1xkYxVA7JXXuVP28Q9ZqhNZXTACEwYBhgL/s1600/Evennia_illustrated_fig8.png"><img src="https://2.bp.blogspot.com/-pgpYPsd4CLM/W3kaWG2ffuI/AAAAAAAAJLg/LKl4m4-1xkYxVA7JXXuVP28Q9ZqhNZXTACEwYBhgL/s400/Evennia_illustrated_fig8.png" alt="" /></a></p>
|
||
<p>Commands in Evennia are always joined together in Command Sets. These are containers that can hold many Command instances. A given Command class can contribute Command instances to any number of Command Sets. These sets are always associated with game entities. In Figure 8, Trigger has received a Command Set with a bunch of useful commands that he (and by extension his controlling Player) can now use.</p>
|
||
<h4>Figure 9: Command Sets can affect those around them</h4>
|
||
<p><a href="https://3.bp.blogspot.com/-acmVo7kUZCk/W3kaWZWlT0I/AAAAAAAAJLk/nnFrNaq_TNoO08MDleadwhHfVQLdO74eACEwYBhgL/s1600/Evennia_illustrated_fig9.png"><img src="https://3.bp.blogspot.com/-acmVo7kUZCk/W3kaWZWlT0I/AAAAAAAAJLk/nnFrNaq_TNoO08MDleadwhHfVQLdO74eACEwYBhgL/s400/Evennia_illustrated_fig9.png" alt="" /></a></p>
|
||
<p>Trigger’s Command Set is only available to himself. In Figure 8 we put a Command Set with three commands on the Dungeon room. The room itself has no use for commands but we configure this set to affect those inside it instead. Note that we let these be different versions of these commands (hence the different color)! We’ll explain why below.</p>
|
||
<h4>Figure 10: The name Command “Set” is not just a name</h4>
|
||
<p><a href="https://4.bp.blogspot.com/--lixKOYjEe4/W3kaUl9SFXI/AAAAAAAAJLQ/tCGd-dFhZ8gfLH1HAsQbZdaIS_OQuvU3wCEwYBhgL/s1600/Evennia_illustrated_fig10.png"><img src="https://4.bp.blogspot.com/--lixKOYjEe4/W3kaUl9SFXI/AAAAAAAAJLQ/tCGd-dFhZ8gfLH1HAsQbZdaIS_OQuvU3wCEwYBhgL/s400/Evennia_illustrated_fig10.png" alt="" /></a></p>
|
||
<p>Command Sets can be dynamically (and temporarily) merged together in a similar fashion as <a href="https://en.wikipedia.org/wiki/Set_theory">Set Theory</a>, except the merge priority can be customized. In Figure 10 we see a Union-type merger where the Commands from Dungeon of the same name temporarily override the commands from Trigger. While in the Dungeon, Trigger will be using this version of those commands. When Trigger leaves, his own Command Set will be restored unharmed.</p>
|
||
<p>Why would we want to do this? Consider for example that the dungeon is in darkness. We can then let the Dungeon’s version of the look command only show the contents of the room if Trigger is carrying a light source. You might also not be able to easily get things in the room without light - you might even be fumbling randomly in your inventory!</p>
|
||
<p>Any number of Command Sets can be merged on the fly. This allows you to implement multiple overlapping states (like combat in a darkened room while intoxicated) without needing huge if statements for every possible combination. The merger is non-destructive, so you can remove cmdsets to get back previous states as needed.</p>
|
||
<p>… And that’s how many illustrations I have the stamina to draw at this time. Hopefully this quick illustrated dive into Evennia helps to clarify some of the basic features of the system!</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 31 May 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-05-31-evennia-in-pictures</guid></item><item><title> Evennia 0.6!</title><link>2016.html#2016-05-22-evennia-0.6!</link><description><p><a href="https://1.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/_W0YsmCG6BwRv8a01AOG-nXfYws5wCilwCKgB/s1600/evennia_logo_small.png"><img src="https://1.bp.blogspot.com/-2Axqwk9ps84/Ui8fvdZ3ReI/AAAAAAAAB-M/_W0YsmCG6BwRv8a01AOG-nXfYws5wCilwCKgB/s1600/evennia_logo_small.png" alt="" /></a></p>
|
||
<p>As of today, I merged the development branch to make version 0.6 of the MU* development system and server Evennia.</p>
|
||
<p>Evennia 0.6 comes with a lot of updates, mainly in the way Evennia talks to the outside world. All communication is now standardized, so there are no particular treatment of things like text - text is just one of any standardized commands being passed between the server the client (whether over telnet, ssh, websockets or ajax/comet).</p>
|
||
<p>For example the user can now easily plug in &quot;inputfuncs&quot; to handle any data coming from the client. If you want your client to offer some particular functionality, you just need to plop in a python function to handle it, server-side. We also now offer a lot of utility functions for things like monitoring change (tell the client whenever your health status changes so it can update a health bar or flash the screen).</p>
|
||
<p>The HTML5 webclient has itself updated considerably. Most is happening behind the scenes though. Notably the webclient&#x27;s javascript component is split into two:</p>
|
||
<p><a href="https://1.bp.blogspot.com/-vx-uriUXOjI/V0If9Q3TcVI/AAAAAAAAEm4/35haAV1OyAoafjxwHP8wMcOad4CC4OpkQCLcB/s1600/evennia_screen.png"><img src="https://1.bp.blogspot.com/-vx-uriUXOjI/V0If9Q3TcVI/AAAAAAAAEm4/35haAV1OyAoafjxwHP8wMcOad4CC4OpkQCLcB/s400/evennia_screen.png" alt="" /></a></p>
|
||
<ul>
|
||
<li><strong>evennia.js</strong>, acts as a library for handling all communication with the server part of Evennia. It offers events for a gui library to plug into and send/receive. It will also gracefully degrade from a websocket connection to AJAX/COMET long-polling if the player uses an older browser.</li>
|
||
<li><strong>evennia_gui.js</strong> is the default front-end and implements a traditional and stable &quot;telnet-like&quot; interface. The html part uses uses Django templating to make it easy to customize and expand. Since this simply makes use of the resources offered by evennia.js, one could pretty easily slip in some other gui library here, or set up calls to get all sorts of interesting information from the server (which talks back using inputfuncs).</li>
|
||
</ul>
|
||
<p>There are a truckload of more updates and features that are covered <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/Ik8hi7ajZlI">on the mailing list</a>.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 22 May 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-05-22-evennia-0.6!</guid></item><item><title>Technical stuff happening</title><link>2016.html#2016-03-24-technical-stuff-happening</link><description><p><a href="https://2.bp.blogspot.com/-2joU-U3OlH0/VvQ9hatC4MI/AAAAAAAAEic/PdL_kxHeXPE6O-HuM3Pk_6GQ5T19fc2zA/s1600/supersonic-nozzle.png"><img src="https://2.bp.blogspot.com/-2joU-U3OlH0/VvQ9hatC4MI/AAAAAAAAEic/PdL_kxHeXPE6O-HuM3Pk_6GQ5T19fc2zA/s320/supersonic-nozzle.png" alt="" /></a></p>
|
||
<p>Hi folks, a bit more technical entry this time. These usually go onto the Evennia mailing list but I thought it would be interesting to put it in the dev-blog for once.</p>
|
||
<p>So, I&#x27;m now halfway through the <a href="https://github.com/evennia/evennia/issues/924">TODO list issue</a> of the <a href="http://evennia.blogspot.se/2016/02/climbing-up-branches.html">wclient development branch</a> as alluded to in the last post. The wclient branch aims to rework and beef up the web client infrastructure of Evennia.</p>
|
||
<p>The first steps, which has been done a while was converting the SSH/SSL and IRC input/output protocols to use the new protocol infrastructure (telnet and websockets was done since before). That&#x27;s just under-the-hood stuff though. Today I finished the changes to the Monitor/TickerHandlers, which may be of more general interest.</p>
|
||
<p>With the changes to the the way OOB (Out-Of-Band) messages are passing through Evennia (see <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/xWQu_YVm14k">this mailing list post</a> for more details), the <strong>OOBHandler</strong> is no more. As discussed there, the handling of incoming data is becoming a lot freer and will be easily expandable to everyone wanting to make for a custom client experience. The idea is thus for Evennia to offer <em>resources</em> for various input commands to make use of, rather than prescribing such functionality in a monolothic way in the OOBHandler. There were three main functionalities the OOBHandler offered, and which will now be offered by separate components:</p>
|
||
<ol>
|
||
<li><strong>Direct function callback.</strong> The instruction from the client should be able to trigger a named server-side function. This is the core of the inputfunc system described previously.</li>
|
||
<li><strong>Field/Attribute monitoring</strong>. The client should be able to request <em>monitoring</em> of an object&#x27;s database fields or Attributes. For example, the client may request to be notified whenever the Character&#x27;s &quot;health&quot; Attribute changes in some way. This is now handled by the new <em>monitorhandler</em>. See below.</li>
|
||
<li><strong>Non-persistent function repeats.</strong> One should be able to set up a repeating ticker that survives a server reload but does <em>not</em> survive a cold shutdown - this mimics the life cycle of server Sessions. Scripts could do this already but I wanted to be able to use the TickerHandler for quick assignment. Problem was that the Tickerhandler in master branch is not only always-persistent, it also only calls <em>database</em> <em>object methods</em>. So I have now expanded the tickerhandler to also accept arbitrary module functions, without any connection to a database object.</li>
|
||
</ol>
|
||
<h2>The MonitorHandler</h2>
|
||
<p><strong>evennia.MONITOR_HANDLER</strong> is the new singleton managing monitoring of on-object field/attribute changes. It is used like this:</p>
|
||
<pre><code> MONITOR_HANDLER.add(obj, field_or_attrname, callback, **kwargs)
|
||
</code></pre>
|
||
<p>Here <strong>obj</strong> is a database entity, like a Character or another Object. The <strong>field_or_attrname</strong> is a string giving the name of a <strong>db_</strong>* database field (like <strong>&quot;db_key&quot;, &quot;db_location&quot;</strong> etc). Any name not starting with <strong>db_</strong> is assumed to be the name of an on-object Attribute (like <strong>&quot;health&quot;</strong>). Henceforth, whenever this field or attribute changes in any way (that is, whenever it is re-saved to the database), the <strong>callback</strong> will be called with the optional <strong>kwargs</strong>, as well as a way to easily get to the changed value. As all handlers you can also list and remove monitors using the standard <strong>MONITOR_HANDLER</strong>.<strong>remove()</strong>, <strong>.all()</strong> etc.</p>
|
||
<h2>The TickerHandler</h2>
|
||
<p><strong>evennia.TICKER_HANDLER</strong> should be familiar to Evennia users from before - it&#x27;s been around for a good while. It allows for creating arbitrary &quot;tickers&quot; that is being &quot;subscribed&quot; to - one ticker will call all subscribers rather than each object or function having its own timer.</p>
|
||
<p>Before, the syntax for adding a new ticker required you specify a typeclassed entity and the name of the method on it to call every N seconds. This will now change. This is the new callsign for creating a new ticker:</p>
|
||
<pre><code> TICKER_HANDLER.add(interval, callback, idstring=&quot;&quot;, persistent=True, *args, **kwargs)
|
||
</code></pre>
|
||
<p>Here**, interval,** like before, defines how often to call **callback(*args, <strong>kwargs)</strong>.</p>
|
||
<p>The big change here is that <strong>callback</strong> should be given as a valid, already imported callable, which can be <em>either</em> an on-entity method (like obj.func) or a global function in any module (like world.test.func) - the TickerHandler will analyze it and internally store it properly.</p>
|
||
<p><strong>idstring</strong> works as before, to separate tickers with the same intervals. Finally <strong>persistent</strong>=<strong>False</strong> means the ticker will behave the same way a Script with <strong>persistent=False</strong> does: it will survive a server reload but will <em>not</em> survive a server shutdown. This latter functionality is particularly useful for client-side commands since the client Session will also not survive a shutdown.</p>
|
||
<p>... So this is a rather big API change to the TickerHandler, which will mean some conflicts for those of you relying heavily on tickers. Easiest will definitely be to simply stop the old and start new ones. It&#x27;s not clear yet if we&#x27;ll offer some automated way to convert old tickers to new ones. Chime in if this is something important to you.</p>
|
||
<h2>Happening Next</h2>
|
||
<p>The next steps involves making use of these new utilities to implement the basic OOB commands recommended by the MSDP and GMCP protocols along with some recommended functionality. We&#x27;ll see how long that takes, but progress is being made. And if you are a web guy, do consider <a href="https://github.com/evennia/evennia/issues/924">helping out.</a></p>
|
||
</description><author>Griatch</author><pubDate>Thu, 24 Mar 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-03-24-technical-stuff-happening</guid></item><item><title>Climbing up Branches</title><link>2016.html#2016-02-14-climbing-up-branches</link><description><p><a href="https://2.bp.blogspot.com/-YRSejcCHpq4/VsDcZRdmTVI/AAAAAAAAEgE/oK4igrEnqWk/s1600/male-lazuli-bunting-bird-perches-on-branch-passerina-amoena.jpg"><img src="https://2.bp.blogspot.com/-YRSejcCHpq4/VsDcZRdmTVI/AAAAAAAAEgE/oK4igrEnqWk/s320/male-lazuli-bunting-bird-perches-on-branch-passerina-amoena.jpg" alt="" /></a></p>
|
||
<p>Today I pushed the latest Evennia development branch &quot;wclient&quot;. This has a bunch of updates to how Evennia&#x27;s webclient infrastructure works, by making all exchanged data be treated equal (instead of treating text separately from other types of client instructions).</p>
|
||
<p>It also reworks the javascript client into a library that should be a lot easier to expand on and customize. The actual client GUI is still pretty rudimentary though, so I hope a user with more web development experience can take upon themselves to look it over for best practices.</p>
|
||
<p>A much more detailed description of what is currently going on (including how to check out the latest for yourself) is found in this <a href="https://groups.google.com/forum/#%21category-topic/evennia/evennia-news/xWQu_YVm14k">mailing list post</a>. Enjoy!</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 14 Feb 2016 00:00:00 GMT</pubDate><guid isPermaLink="true">2016.html#2016-02-14-climbing-up-branches</guid></item><item><title>A summary of a year</title><link>2015.html#2015-12-17-a-summary-of-a-year</link><description><h3><a href="https://evennia.blogspot.com/2015/12/a-summary-of-year.html">A summary of a year</a></h3>
|
||
<p><a href="https://4.bp.blogspot.com/-_8Yxtk6y1KQ/VnLiQf1U18I/AAAAAAAAEew/7zabQTvUEdY/s1600/33-1196545384.jpg"><img src="https://4.bp.blogspot.com/-_8Yxtk6y1KQ/VnLiQf1U18I/AAAAAAAAEew/7zabQTvUEdY/s200/33-1196545384.jpg" alt="" /></a></p>
|
||
<p>As 2015 is slowly drawing to an end, I looked back through Evennia&#x27;s repository to see just what was going on this year. And it turns out it was a lot! I honestly didn&#x27;t remember some things happened as recently as they did.</p>
|
||
<p><em>Note: For those reading this not familiar with Evennia, it&#x27;s a Python library for creating MUDs (text-based multiplayer games).</em></p>
|
||
<pre><code>
|
||
</code></pre>
|
||
<h2>Making Evennia into a library</h2>
|
||
<p>In February of 2015 we merged what was likely the biggest change happening for a good while in Evennia - the complete refactoring of the Evennia repository into a library. It used to be that when you cloned the Evennia repo, it would come with a pre-made game/ folder where you were supposed to put your custom files. Mixing the stuff you downloaded from us with your own files (which you might want to keep under version control of your own) was not a very clean solution.</p>
|
||
<p>In the big &quot;library update&quot;, we instead created a stand-alone evennia program which you use to create your own &quot;game dir&quot; with pre-created templates. Not only does this allow you to treat the cloned evennia repo as a proper library, you can also use the same evennia install for multiple games and makes it a lot clearer just what comes from us and what is your custom code.</p>
|
||
<p>Below is a fun Gource representation (courtesy of Youtuber Landon Wilkins) of how the Evennia repository structure has changed over the years. You can see the latest library-change a little after the <a href="https://youtu.be/sXCm78XEJ9c?t=3m20s">3minute, 20 second mark</a>.</p>
|
||
<h2>Typeclasses into proxies</h2>
|
||
<p>At the same time as the library change, I also completely overhauled the way typeclasses are represented in Evennia: Typeclasses are Python classes that links back to a database model under the hood. They used to use a custom overloading of varioust get/set methods, now they instead utilize <a href="https://docs.djangoproject.com/en/1.9/topics/db/models/#proxy-models">django proxy models</a> extended to support multiple inheritance. T</p>
|
||
<p>his radically increased performance and made the code considerably cleaner, as well as completely hid the core django model from the end user (no longer a need to track if you were dealing with a model or its typeclass - you only ever run into typeclasses). This, together with the library-model led to some changes in people&#x27;s source codes.</p>
|
||
<p>Even so, this change led to a lot less problems and edge-cases than I had anticipated: it seems more people had issues with upgrading django than with adopting their codes to the new typeclass changes ...</p>
|
||
<h2>Evennia Autodocs</h2>
|
||
<p>Following the big library merger I sat down to write a more comprehensive autodoc utility. We had been distributing a Doxygen config file with the repo for a long time, but I wanted something that integrated with our github wiki, using markdown in the source (because frankly, while Sphinx produces very pretty output, ReST markup looks really ugly in source code, in my opinion).</p>
|
||
<p>The result was the api2md program, which is now a part of our wiki repository. It allows our source code to be decorated in &quot;Google style&quot;, very readable output:</p>
|
||
<pre><code class="language-python">def funcname(a, b, c, d=False): &quot;&quot;&quot;
|
||
This is a brief introduction to the
|
||
function/class/method
|
||
|
||
Args:
|
||
a (str): This is a string argument that
|
||
we can talk about over multiple lines.
|
||
b (int or str): Another argument
|
||
c (list): A list argument
|
||
d (bool, optional): An optional keyword argument
|
||
|
||
Returns:
|
||
str: The result of the function
|
||
|
||
Notes:
|
||
This is an example function. If `d=True`, something
|
||
amazing will happen.
|
||
|
||
&quot;&quot;&quot;
|
||
</code></pre>
|
||
<p>This will be parsed and converted to a Markdown entry and put into the Github wiki, one page per module. The result is the automatically generated <a href="https://github.com/evennia/evennia/wiki/evennia">Evennia API autodocs</a>, reachable as any other wiki page.</p>
|
||
<p>The convertion/prettification of all core functions of Evennia to actually <em>use</em> the Google-style docstrings took almost all year, finishing late in autumn. But now almost all of Evennia uses this style. Coincidentally this also secures us at a 45% comment/code ratio. This places us in the top 10% of well-documented open-source projects according to <a href="https://www.openhub.net/p/evennia/factoids#FactoidCommentsVeryHigh">openhub</a> (gotta love statistics).</p>
|
||
<h2>Imaginary realities / Optional Realities</h2>
|
||
<p>Spring of 2015 saw some more articles for the <a href="http://journal.imaginary-realities.com/">Imaginary Realities</a> e-zine as well as some for the newly-opened <a href="http://optionalrealities.com/">Optional Realities</a> web forum (unrelated, despite the similar name). The latter was made by a team working on a commercial Evennia-based sci-fi game, but the forums were open for other games (of any engine) and general discussion on mud and mud design.</p>
|
||
<p>Optional Realities published an impressive range of articles (one every week for several months) and organized several very interesting mud-related contests. It did, I think, a lot for bringing some new life to the mud-development scene. Unfortunately Optional Realities suffered a complete database loss towards the end of the year, forcing it to sort of reboot from scratch. I hope it will rebound and that the articles can be put back online again!</p>
|
||
<h2>Ainneve</h2>
|
||
<p>Over summer I put out a general roll call for developers willing to lead the development of a small but fully functioning Evennia demo game - a project separate from the main Evennia development. The idea is to have something working for people to rip out and start from. The response to my request was very good and we relatively quickly ended up with two devs willing to lead and direct the effort.</p>
|
||
<p>The work-in-progress demo game they started is called <em><a href="https://github.com/evennia/ainneve">Ainneve</a></em>. It uses the base <a href="http://geekguild.com/openadventure/">Open Adventure</a> RPG rules and is distributed using the same liberal licence as Evennia.</p>
|
||
<p>Ainneve has been sputtering along throughout autumn and winter, and while progress has been a bit ... sporadic, it seems to attract new volunteers to help out. As more of the base systems gets finalized there is going to be even more &quot;low hanging fruit&quot; for people to jump in and help with.</p>
|
||
<h2>EvMenu, EvMore and EvEditor, RPSystem</h2>
|
||
<p>In July I merged some new systems into Evennia&#x27;s utilities library. <em>EvMenu</em> is a class that builds an in-game menu. It uses multiple-choice questions for the user to navigate its nodes. I had a &quot;menusystem&quot; in our contrib/ folder since many years, but it was showing its age and when I found I myself didn&#x27;t really understand how it was working I found it time to make something more flexible.</p>
|
||
<p>The <em>EvMore</em> is a page-scroller that allows the server to pause long texts and wait for the user to press a key before continuing. It&#x27;s functionality is similar to the unix <em>more</em> program.</p>
|
||
<p>For its part, <em>EvEditor</em> has existed for a while as well, but it was moved from the contrib folder into the main utilility library as it turned out to be an important and common resource (it&#x27;s basically a mud-version of the classic <em>vi</em> editor).</p>
|
||
<p>Finally, some months later, in September, I added the <em>rpsystem</em> and <em>rplanguage</em> contribution modules. The former is an author-stance recognition system similar to what is seen in some rp-heavy muds (where you don&#x27;t know/see people&#x27;s name off the bat, but only their description, until you manually assign a name to them).</p>
|
||
<p>The <em>rplanguage</em> module is used for handling foreign (fantasy) languages by obfuscating words heard by different parties depending on their relative language skills.</p>
|
||
<h2>Python 3 ... some day</h2>
|
||
<p>As we know, Evennia uses Python 2. In autumn of 2015 first one and then two of our users took upon themselves to help make Evennia a little more ready for running also under Python 3. After a lot of work, Evennia&#x27;s core is now using code syntax that is compatible with both Python 2 and 3.</p>
|
||
<p>We <em>don&#x27;t</em> run under Python 3 at this point though. This is not something under our control, but is due to Twisted not supporting Python 3 yet. But when it becomes possible, we are now better prepared for transitioning to a point where we can (hopefully) support both main Python versions.</p>
|
||
<h2>EvCast</h2>
|
||
<p>In September, user whitenoise started his &quot;EvCast&quot; video tutorial series on Evennia. There are so far two episodes, one on installing Evennia and the second on general Python concepts you need to use Evennia efficiently:</p>
|
||
<iframe width="320" height="266" src="https://www.youtube.com/embed/tjiS2Bx5xb0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||
<h2><code>Python.__init__</code> Podcast</h2>
|
||
<p>In the end of September I was interviewed by the hosts of the <em>python.<strong>init</strong></em> podcast. Turned into more than an hour of discussion about Evennia. T&#x27;was fun! You can <a href="https://plus.google.com/+Podcastinit-the-python-podcast/posts/Vu9dPVjsR9h">listen to it here</a>.</p>
|
||
<h2>Nested inlinefuncs</h2>
|
||
<p>Towards the end of the year I got (via Optional Realities) lured to participate in another text-gaming related website, <a href="http://musoapbox.net/">musoapbox</a>. This is a forum primarily populated by players from the MUSH-side of text-gaming. After some back and forth they made a strong case for increasing the functionality of Evennia&#x27;s <em>inlinefunctions</em>.</p>
|
||
<p>An inlinefunction is, in Evennia, a function call embedded in a string sent to the server. This is parsed and executed (no, there is no dangerous eval happening, the call is parsed as text and then called as a normal function call). It allows for text to be dynamically replaced at run-time. What the MUSHers suggested was to also allow those inlinefunc&#x27;s to be nestable - that is, to implement a call stack. The nestable form of inlinefuncs was merged with Evennia master at the end of November.</p>
|
||
<h2>Patreon</h2>
|
||
<p>This actually happened already back in February: after some requests for more ways to support Evennia development, I opened <a href="https://www.patreon.com/griatch?ty=h">a Patreon page</a>. And here at the end of the year, a whole ten patrons have signed up for it. Very encouraging!</p>
|
||
<h2>Next year</h2>
|
||
<p>In 2016 the first upcoming thing that comes to mind is push out the changes to the webclient infrastructure. That has been a long time coming since I&#x27;ve been unsure of how to proceed on it for quite some time. The goal is to make the webclient a lot more &quot;pluggable&quot; and modular than it is, and to clean up its API and way of communicating with the server. Overall I think the web-side of things need some love.</p>
|
||
<p>I&#x27;ll likely put together some more general-use contribs as well, I have some possibles in mind.</p>
|
||
<p>We&#x27;ll continue squashing bugs and work down our roadmap.</p>
|
||
<p>I&#x27;ll also try to get an Evennia Wikipedia.org page together, if you want to look at how it&#x27;s progressing and help editing it, see the Evennia mailing list for the link.</p>
|
||
<p>... And a lot more I don&#x27;t know yet, no doubt! On towards a new year!</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 17 Dec 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-12-17-a-summary-of-a-year</guid></item><item><title> MIT uses Evennia!</title><link>2015.html#2015-11-12-mit-uses-evennia!</link><description><p><a href="https://2.bp.blogspot.com/-FPg1PS8At3k/VkR7vqSz1LI/AAAAAAAAEco/bKSpvhDxLp0/s1600/MIT-Language-Games_0.jpg"><img src="https://2.bp.blogspot.com/-FPg1PS8At3k/VkR7vqSz1LI/AAAAAAAAEco/bKSpvhDxLp0/s320/MIT-Language-Games_0.jpg" alt="" /></a></p>
|
||
<p><a href="https://www.blogger.com/"></a>Evennia was recently used as a test bed to train an AI system to attempt to play a MUD as a human would - by only reading and understanding the text on the screen.</p>
|
||
<p>Researchers at MIT (Massachusetts Institute of Technology) recently presented the paper <em>Language understanding for Text-based games using Deep reinforcement learning</em> <a href="https://arxiv.org/pdf/1506.08941.pdf">(PDF)</a> at a conference on natural language processing. A summary is in the <a href="http://news.mit.edu/2015/learning-language-playing-computer-games-0924#_msocom_1">MIT press release</a>.</p>
|
||
<p>I was contacted by these fine folks some time ago so I knew they had plans to use Evennia for their research. It&#x27;s great to see they now have an article out on it! Evennia devs are also mentioned in the acknowledgements - so something for the Evennia dev community to be proud of!</p>
|
||
<h3>MUDs are tricky</h3>
|
||
<p>The main complication for an AI playing a MUD is that the computer has no access to the actual game state but must try to surmise how well it&#x27;s doing only from the text given (same as a human would). The researchers compare the results from a range of deep-learning neural network algorithm that they train to play.</p>
|
||
<p>To test their AI, the researchers first used Evennia to build a simple training &quot;Home World&quot;: a 4-room &quot;house&quot; where the simple goal is to find and eat an apple while refraining to go to sleep. The room descriptions used here were pretty formulaic although not trivial to give a challenge. This they used to train their AI system.</p>
|
||
<p>They then took this trained neural network and applied it to the real challenge, playing the Evennia <a href="https://github.com/evennia/evennia/wiki/Tutorial%20World%20Introduction">Tutorial World</a>. You can yourself try this out in our demo install or by just running a single command when starting Evennia. They call it &quot;Fantasy World&quot; in the article.</p>
|
||
<p>The tutorial world has hand-written descriptions and often describes the exits as part of the room text. The article actually makes a comprehensive analysis of the tutorial world, including the available game states and transitions as well as the number of words and number of commands per state. Interesting stuff in itself. I presume the scientists have modified their copy of the tutorial world to provide better metrics for their analysis.</p>
|
||
<h3>A bridge too far</h3>
|
||
<p>As far as I understand from the article, the AI does understand to use commands with one or two arguments (like <em>eat apple</em> or the <em>move red-root right</em>), but they note that actually finding the tomb of the fallen hero (the main quest of the tutorial) is too hard for the AI:</p>
|
||
<blockquote>
|
||
<p>[...]However, this is a complex quest that requires the player to memorize game events and perform high-level planning which are beyond the scope of this current work.</p>
|
||
</blockquote>
|
||
<p>So instead they evaluate the AI&#x27;s performance on a more mundane task: Getting across the bridge to the castle. It&#x27;s not clear to me if the AI actually plays more of the game too or if their test just exposes the AI to the bridge itself. I suspect it <em>does</em> play more due to the examples they use from other rooms; evaluating the bridge-crossing is just a clear-cut metric to use for &quot;success&quot;.</p>
|
||
<p>The MIT press release claims that the AI is also scored on how much health/magic it has, but I don&#x27;t see that mentioned in the article itself (and the tutorial world only has magic if you find the hero&#x27;s tomb which they claim they cannot do).</p>
|
||
<p>The bridge in Evennia&#x27;s tutorial world is actually a single &quot;room&quot; that takes multiple steps to cross. At every step the room description changes to describe the progress. Random texts will appear as the bridge sways in the wind and various environmental cues are heard and seen. There is also a small chance of falling off the bridge if one lingers too long on it.</p>
|
||
<p>So although all you really need to do is to walk east repeatedly, I can see why this can be a challenge to a neural network having no mental image of what a bridge is. It can only work off the text it&#x27;s given at any given time.</p>
|
||
<p>In the paper, the algorithms are evaluated both on their ability to actually cross the bridge and on how optimal their solution was, for example by not issuing invalid commands to the situation.</p>
|
||
<h3>Beyond the bridge</h3>
|
||
<p>The results are that after being trained on the training house setup, the AI <em>will</em> eventually be able to cross the bridge. The particular algorithm proposed also perform slightly better than the comparison ones (and <em>a lot</em> better than simple randomness).</p>
|
||
<p>So from the perspective of the researchers this seems to be a success. Even so, this reinforces the fact that quite some way to go before an AI can <em>actually</em> play a real MUD successfully. Using MUDs for this type of research is a good idea though, and I do hope they expand and continue this line work in the future.</p>
|
||
<p>Who knows, maybe the AI will even find that ancient tomb eventually!</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 12 Nov 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-11-12-mit-uses-evennia!</guid></item><item><title>Illustrations and soaps</title><link>2015.html#2015-10-11-illustrations-and-soaps</link><description><p><a href="http://optionalrealities.com/wp-content/uploads/2015/10/Evennia_illustrated_fig2.png"><img src="https://lh6.googleusercontent.com/proxy/akVd5ALnso-4giJqE1OAHXgxuIZeAx2IYQC-o_zAarsIu1ge2XQkPSQO_nKFz_dX6P5EreO39-HileXV7UmobyAsfE-MlDBUy2J5c1dx4vb5hUjgR6WXzAvOcmrZ20NXVGR2ivvcqKA=s0-d" alt="" /></a></p>
|
||
<p>I recently made an article presenting the infrastructure and main coding features of Evennia using a series of nifty diagrams.</p>
|
||
<p>It can hopefully help newcomers get a feeling for the grand structure of an Evennia server/game a little easier. It&#x27;s published as a feature on <a href="http://optionalrealities.com/">Optional Realities</a> and you can find the article here: <a href="http://optionalrealities.com/evennia-illustrated/">Evennia Illustrated</a>.</p>
|
||
<p>I also recently joined <a href="http://musoapbox.net/topic/620/evennia-a-python-based-mu-server">MU Soapbox</a>, a forum predominantly discussing MUSH games, to answer some technical questions on Evennia. Unsurprisingly, some (although so far surprisingly few) MUSHers express concern about Evennia&#x27;s explicit lack of softcode (that is, the ability for players to use a safe in-game language to code their game rather than to use external Python modules). Their argument is sound: They are used to in-game coding as a way to easily express creatitivy and easily garner help from players.</p>
|
||
<p>Evennia&#x27;s stance here clash a bit with those opinions: Our philosophy is that our command system is powerful enough to offer players any complexity of build commands they want. The design/coding of the game itself should be done using proper coding IDEs and modern version control tools.</p>
|
||
<p>There is no denying that compared to a softcode-coded game, a player-level contributor to an Evennia game needs some extra tools to create and contribute code over version control. The admin also needs to check such contributions for malicious code before merging it into their running game. Now, these are differences I actually consider <em>advantages</em> from a code-quality perspective. And for finding help, people on average are more likely to know Python than a custom softcode language. But here opinions differ and in a given game community those language adoption numbers can be severely skewed.</p>
|
||
<p>So far, the MUSHers that have adopted Evennia seems to have done so very much to <em>get away</em> from softcode. It will be interesting to see if things like Kelketek&#x27;s in-development <a href="https://github.com/evennia/evennia/pull/711">Group building Evennia contrib</a> will be stirring some interest from those on the fence, or if coding their entire game in softcode is indeed an irreplaceable source of their gaming fun.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 11 Oct 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-10-11-illustrations-and-soaps</guid></item><item><title>Emoting System</title><link>2015.html#2015-10-02-emoting-system</link><description><p>title: Emoting Systems, or how to chat up a girl
|
||
copyrights: Image: ©Griatch <a href="https://deviantart.com/griatch-art">deviantart</a></p>
|
||
<p><a href="http://pre03.deviantart.net/54d0/th/pre/i/2012/114/c/8/what__s_yer_name__by_griatch_art-d4xfokb.jpg"><img src="https://lh6.googleusercontent.com/proxy/l_2MjemzGRtxOqicx4EXXRT63jmryGr7Ml_wvtSSDGg8Rc-oVzKL-_Jxy9f4gvkzROS3eE8jR3R9I2iguw0Cki4oc4reqwi607HGigS6iSO8BxHuZ53k70NUI0ZfWTpXoCqBm-Wr0LakUjfQQxIJIehaRGbvrvU=s0-d" alt="" /></a></p>
|
||
<p>A few days ago I pushed an emoting contribution to Evennia. A &quot;contrib&quot; is an optional plugin system that is not part of core Evennia but is meant to be easily picked up and used in people&#x27;s own designs.</p>
|
||
<p>If you are not familiar with what an emoting system does, it is a way to decribe the actions of a character in the game. The simplest form of emote is a single command (like the command <strong>dance</strong> leading to some canned response, or in the case of a graphical game, a dance animation). This contribution offers a more sophisticated system though, allowing input like the following:</p>
|
||
<p>emote /me smiles at /cheerful as he sits at her table. &quot;Hello!&quot; he says.</p>
|
||
<p>Now, this includes /keywords that relate to the objects in the room. So assuming there is <strong><em>a very cheerful girl</em></strong> in the room, this string will come out as</p>
|
||
<p>Griatch smiles at <em><strong>a very cheerful girl</strong></em> as he sits at her table. <strong>&quot;Hello!&quot;</strong> he says.</p>
|
||
<p>But she will actually see only my outward appearance (the short description) since she doesn&#x27;t know me. So the cheerful girl (let&#x27;s say her name is Sandra) would for example see</p>
|
||
<p><em><strong>A man in flowing robes</strong></em> smiles at <em><strong>Sandra</strong></em> as he sits at her table. <strong>&quot;Hello!&quot;</strong> he says.</p>
|
||
<p>The emoting system has the following features:</p>
|
||
<ul>
|
||
<li>Short description replacement in emotes and in searches, as seen above. This means that you can do <strong>look cute</strong> and the system will know what you want to look at (in vanilla Evennia you&#x27;d need to use <strong>look Sandra</strong>).</li>
|
||
<li>Multi-word searching and disambiguation. If there is <strong>a cute girl</strong> and <strong>a cute puppy</strong> both in the same room, your referencing of /cute will give an error listing the alternatives. You can then either include more words to make your reference unique or use an index (1-cute, 2-cute) to make it clear who you mean. This mimics normal object-key disambiguation in Evennia.</li>
|
||
<li>Recognition. You can assign your own aliases to people. If Sandra introduces herself you could assign her the name <strong>Sandra</strong> and henceforth be able to reference her as such and see that name appear. But you could also name her <strong>The girl calling herself Sandra</strong> if you didn&#x27;t believe that&#x27;s her actual name.</li>
|
||
<li>Languages. Everything within double-quotes is parsed as spoken language (like the Hello! above). By using writing this as <strong>(elvish)&quot;Hello!&quot;</strong>, this could be spoken in another language and those who don&#x27;t speak elvish would receive an obfuscated string.</li>
|
||
<li>Masking. A person wearing a mask can force people&#x27;s recognition replacement to deactivate so that they are not recognized anymore.</li>
|
||
</ul>
|
||
<p>The emoting contrib comes as two files in evennia/contrib/: rpsystem.py and rplanguage.py. To use them fully, make your Characters and Rooms inherit from the supplied classes and/or add the new commands to the Character command set. Enjoy!</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 02 Oct 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-10-02-emoting-system</guid></item><item><title> Evennia on `podcast.__init__`</title><link>2015.html#2015-09-29-evennia-on-`podcast.__init__`</link><description><p><a href="http://pythonpodcast.com/images/podcast_init_logo.png"><img src="https://lh6.googleusercontent.com/proxy/vHgHjWEhvYzINt2GwdHGR_s1jI4YncKvh3lIVRCM93oiRAcG4yBpMSIBidwGJ2-kNKprClzeyJMDHM84-QeMJxOyYTHcP_U8GA=s0-d" alt="" /></a></p>
|
||
<p>So a few weeks back I was contacted by the general Python podcast <em>Podcast.<strong>init</strong></em>. They had stumbled on Evennia and were intrigued about MUD development still going on - and in Python even!</p>
|
||
<p>As it turned out at least one of the two hosts were an old-school MU* gamer and between the two of them they had plenty of good questions both on multiplayer text games in general and about Evennia technology in particular.</p>
|
||
<p>You can listen to my accent via one of the links below:</p>
|
||
<ul>
|
||
<li>Google+: <a href="https://plus.google.com/+Podcastinit-the-python-podcast/posts/Vu9dPVjsR9h">https://plus.google.com/+Podcastinit-the-python-podcast/posts/Vu9dPVjsR9h</a></li>
|
||
<li>Show Notes: <a href="http://pythonpodcast.com/griatch_evennia.html">http://pythonpodcast.com/griatch_evennia.html</a></li>
|
||
<li>Patreon Post: <a href="https://www.patreon.com/posts/3448526">https://www.patreon.com/posts/3448526</a></li>
|
||
<li>Twitter Announcement: <a href="https://twitter.com/Podcast__init__/status/648703365019529216">https://twitter.com/Podcast__init__/status/648703365019529216</a></li>
|
||
</ul>
|
||
</description><author>Griatch</author><pubDate>Tue, 29 Sep 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-09-29-evennia-on-`podcast.__init__`</guid></item><item><title>Pushing through a straw</title><link>2015.html#2015-09-24-pushing-through-a-straw</link><description><p><a href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/DrinkingStraws.jpg/401px-DrinkingStraws.jpg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/DrinkingStraws.jpg/401px-DrinkingStraws.jpg" alt="" /></a></p>
|
||
<p>Recently, a user reported a noticeable delay between sending a command in-game to multiple users and the result of that command appearing to everyone. You didn&#x27;t notice this when testing alone but I could confirm there was almost a second delay <em>sometimes</em> between entering the command and some users seeing the result. A second is very long for stuff like this. Processing time for a single command is usually in the milliseconds. What was going on?</p>
|
||
<h3>Some background</h3>
|
||
<p>Evennia has two components, the <em>Portal</em> and the <em>Server,</em> running as two separate processes_._ The basic principle is that players connecting to an Evennia instance connects to the Portal side - this is the outward facing part of Evennia. The connection data and any other input and output will be piped from the Portal to the Server and back again.</p>
|
||
<p>The main reason for this setup is that it allows us to completely reset the Server component (reloading module data in memory is otherwise error-prone or at least very tricky to make generically work in Python) without anyone getting disconnected from the Portal. On the whole it works very well.</p>
|
||
<h3>Debugging</h3>
|
||
<p>Tracing of timings throughout the entire Server&lt;-&gt;Portal pipeline quickly led me to rule out the command handler or any of the core systems being responsible - including both sides of the process divide was a few milliseconds. But in the <em>transfer</em> between Portal and Server, an additional <em>900</em> miliseconds were suddenly added! This was clearly the cause for the delay.</p>
|
||
<p>Turns out that it all came down to faulty optimization. At some point I built a batch-send algorithm between the Server and Portal. The idea was to group command data together if they arrived too fast - bunch them together and send them as a single batch. In theory this would be more efficient once the rate of command sending increased. It was partly a DoS protection, partly a way to optimize transfer handling.</p>
|
||
<p>The (faulty) idea was to drop incoming data into a queue and if the rate was too high, wait to empty that queue until a certain &quot;command/per second&quot; rate was fullfilled. There was also a timed routine that every second force-emptied the queue to make sure it would be cleaned up also if noone made any further commands.</p>
|
||
<p>In retrospect it sounds silly but the &quot;rate of command&quot; was based on a simple two-time-points derivative;</p>
|
||
<blockquote>
|
||
<p>rate = 1 / (now - last_command_time)</p>
|
||
</blockquote>
|
||
<p>If this rate exceeded a set value, the batch queuing mechanism would kick in. The issue with this (which is easy to see now) is that if you set your limit at (say) 100 commands / second, two commands can happen to enter so close to each other time that their rate far exceed that limit just based on the time passed between them. But <em>there are not actually 100 commands coming in every second</em> which is really what the mechanism was meant to react to.</p>
|
||
<p>So basically using a moment-to-moment rate like this is just too noisy to be useful; the value will jump all over the place. The slowdown seen was basically the DoS protection kicking in because when you are relaying data to other users, each of them will receive &quot;commands&quot; in quick succession - fast enough to trigger the limiter. These would be routed to the queue and the sometimes-delay simply depended on when the queue cleanup mechanism happened to kick in.</p>
|
||
<h3>Resolution</h3>
|
||
<p>Once having identfied the rate measuring bug, the obvious solution to this would be to gather command rates over a longer time period and take an average - you will then filter out the moment-to-moment noise and get an actually useful rate.</p>
|
||
<p>Instead I ended up going with an even simpler solution: Every command that comes in ups a counter. If I want a command rate limit of 100 commands/second, I wait until that counter reaches 100. At that point I check when the time difference between now and when the counter was last reset. If this value is below 1, well then our command rate is higher than 100/second and I can kick in whatever queuing or limiter is needed. The drawback is that until you have 100 commands you won&#x27;t know the rate. In practice though, once the rate is high enough to be of interest, this simple solution leads to an automatic check with minimal overhead.</p>
|
||
<p>In the end I actually removed the batch-sending component completely and instead added command DoS protection higher up on the Portal side. The Command-input is now rate limited using the same count-until-limit mechanism. Seems to work fine. People have no artificial slowdowns anymore and the DoS limiter will only kick in at loads that are actually relevant. And so all was again well in Evennia world.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 24 Sep 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-09-24-pushing-through-a-straw</guid></item><item><title>A wagon load of post summer updates</title><link>2015.html#2015-08-27-a-wagon-load-of-post-summer-updates</link><description><p><a href="http://img10.deviantart.net/adb4/i/2012/322/f/8/the_troll_here_a_cometh_by_griatch_art-d5kp988.jpg"><img src="https://lh3.googleusercontent.com/proxy/5aVkih3LRcrhVNGudLivJ7KJPkDL7bYpusuEQuygCeBQSlnWXawPMkI4a4WCeYkwfnp5LewB3XhGUdNYzcVGd40ZLAz6Oy_-PdVhyZrJtGZqYvBsBOdC8y6cYmiAJ4Vz00l2hv3gQ70yYKbYQyT8khFQFS6grg=s0-d" alt="" /></a></p>
|
||
<p>Summer vacations are over and work resumes in Evennia land! Here&#x27;s a wagon-load of small updates on what&#x27;s going on.</p>
|
||
<h3>Ainneve</h3>
|
||
<p>The <a href="https://github.com/evennia/ainneve">Ainneve project</a>, the creation of an official, open-source Evennia demo game, has gotten going. The lead devs of the project are keen to make this a collaborative effort and there is a lot of good discussion and code being written. After some slowdown at the end of summer it&#x27;s bound to pick up again.</p>
|
||
<p>Ainneve&#x27;s a rare chance to see a full MUD getting developed from scratch out in the open. <a href="https://github.com/evennia/ainneve/issues">The current issue list</a> includes tags for difficulty and allows also newbie Python coders to jump in. Not to mention you have a chance to get valuable feedback on your work by seasoned coders!</p>
|
||
<p>So if you are at all interested in making a MUD, try out Python/Evennia or just get involved in a semi-big programming project, this is a great chance to do so.</p>
|
||
<h3>Imaginary Realities</h3>
|
||
<p>Since a few weeks, there is a new issue of <a href="http://journal.imaginary-realities.com/index.html">Imaginary realities</a> (vol 7, issue 3) is out. As usual I have an article in it. This venerable e-zine was revitalized to include articles on both MU* as well as roguelikes, Interactive fiction and others. Not only is this issue the most content-rich since the reboot, with this issue they have also spruced up their interface to make past issues easier to navigate.</p>
|
||
<ul>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/a-text-mud-with-a-working-ecology-system/index.html">A text MUD with a working ecology system</a>&quot; - in this article Molly O&#x27;Hara details the concepts behind simulating a functioning ecologic network in a game. Interesting stuff and some parts of this is certainly worth considering for any open-world game design. I wonder at which level of detail the system become more complex than the players can appreciate though.</li>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/dispelling-the-gloom/index.html">Dispelling the gloom</a>&quot; by Tomasz Gruca is an interesting essay on the author&#x27;s history growing up in the former Soviet Union and eventually finding text adventure games and interactive fiction, a passion he has apparently lately re-kindled. He makes the observation that the current &quot;retro&quot; trend of games have not really reached back to the text-based game world when it comes to mainstream acceptance.</li>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/how-integral-are-letters-and-text-to-ascii-gaming/index.html">How integral are letters and text to ASCII gaming?</a>&quot;by Mark R. Johnson goes into the practical use of ASCII in traditional rogue-like games (beyond nostalgia). This is a meaty article that goes into both text-as-graphics as well as the use of text for aiding imagination and suggest subtle puzzles in some classic rogue-likes.</li>
|
||
<li><a href="http://journal.imaginary-realities.com/volume-07/issue-03/legend-and-the-lore/index.html">&quot;Legend and the lore&quot;</a> (Hugo Zombiestalker) proclaims the death of the traditional point-and-click adventure game and but then moves on to try to distill just why those games nevertheless was so appealing to him and how it can be applied in modern game designs like zombie-survival MUD <em>Epitath</em> which he is a senior developer for. Plenty of good observations here!</li>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/the-bonds-of-mudding/index.html">The bonds of mudding&quot;</a> by Clint Itan Kuranes Knapp writes about the community that can spring up on a long-running MUD, the interactions the friends and the relationships that could persist already long before &quot;social media&quot; became a buzz word. A warm text with plenty of anecdotes and examples and things to ponder for both designers and staff when wanting to cater for this type of player bonding.</li>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/the-mercurial-temperament-at-the-end-of-the-world/index.html">The mercurial temperament at the end of the world&quot;</a> (Drakkos) discusses NPCs and how they rarely are as interactive as one would want (the term &quot;vend a chat&quot; is a good one I think). He then goes on to how they have implemented their &quot;Mercurial&quot; system for NPCs in <em>Epitath</em>. This seems to be a state-AI system where NPCs have moods that affects what they say based on their circumstance and relation to other actors in the world. Sounds really cool and since he goes into some details on the implementation there is a lot to ponder here.</li>
|
||
<li>&quot;<a href="http://journal.imaginary-realities.com/volume-07/issue-03/where-do-i-begin/index.html">Where do I begin?</a>&quot; by me, Griatch, discusses one of the more common questions we get in the Evennia chat - &#x27;I want to make a MUD, but how do I begin?&#x27; This article starts before Evennia&#x27;s Game planning wiki page - it discusses assessing your capabilities and resources in the form of programming skills, code bases and motivations to help you figure out what you can realistically accomplish.</li>
|
||
</ul>
|
||
<h3>Evennia Web client</h3>
|
||
<p>In the pipeline I have some updates to Evennia&#x27;s websocket/JSON MUD-web client component. These are changes that are intended to make the webclient easier to customize and hook into Evennia output using only HTML/CSS. More details on this will be forthcoming when I have more solid stuff to show.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 27 Aug 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-08-27-a-wagon-load-of-post-summer-updates</guid></item><item><title> Announcing the Evennia example-game project "Ainneve"</title><link>2015.html#2015-06-22-announcing-the-evennia-example-game-project-"ainneve"</link><description><p><a href="https://1.bp.blogspot.com/-QZScgcWodAg/UZu0R2DaJOI/AAAAAAAAAIw/57rwaNQNyx8/s1600/Sunrise+landscape+render+retouches.png"><img src="https://1.bp.blogspot.com/-QZScgcWodAg/UZu0R2DaJOI/AAAAAAAAAIw/57rwaNQNyx8/s1600/Sunrise+landscape+render+retouches.png" alt="" /></a></p>
|
||
<p>The Evennia example-game project is underway!</p>
|
||
<p>I was quite impressed with the response I got on the mailing list to my call for developing an Evennia example game (see my <a href="http://evennia.blogspot.se/2015/06/need-your-help.html">Need your Help</a> blog post).</p>
|
||
<p>The nature of the responses varied, many were from interested people with little to no experience in Evennia or Python whereas others had the experience but not the time to lead it. It was however clear that the interest to work on an &quot;official&quot; Evennia game is quite big.</p>
|
||
<p>I&#x27;m happy to announce, however, that after only a week we now have a solid lead developer/manager, <a href="https://github.com/ergodicbreak">George Oliver</a>. Helping him on the technical/architecture side is <a href="https://github.com/whitenoiseoss">Whitenoise</a> (who, despite a barren github profile, is a professional developer).</p>
|
||
<p>George put together a <a href="https://docs.google.com/document/d/1fu-zYvFytKHGxFHD6_bLQ4FrotAQ0izXuWE_gn8q2Oc/edit">game proposal</a> based on the <a href="http://geekguild.com/openadventure/">OpenAdventure</a> rpg, an open-source (CC-SA) ruleset that is also <a href="https://github.com/openadventure/Open-Adventure">found on github</a>. The example game is to be named &quot;Ainneve&quot; and its development is found in a <a href="https://github.com/evennia/ainneve">in a separate repository under the github Evennia organisation</a>.</p>
|
||
<p>All the relevant links and future discussion can be found <a href="https://groups.google.com/forum/#%21msg/evennia/rOMo5DwhXgE/0jmCpj4gITYJ">on the mailing list</a>.</p>
|
||
<p>George and whitenoise have already made it clear that they aim to not only make Ainneve a good example Evennia game for others to learn from and build on, but to make the development itself a possibility for people of all skill levels to get involved. So get in touch with them if you are at all interested in Python, Evennia and mud development!</p>
|
||
<p>So thanks to George and whitenoise for taking this on, looking forward to see where it leads!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 22 Jun 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-06-22-announcing-the-evennia-example-game-project-"ainneve"</guid></item><item><title> Need your help!</title><link>2015.html#2015-06-15-need-your-help!</link><description><p><a href="https://sites.google.com/site/evenniaserver/_/rsrc/1429261373725/old_evennia/demo_color.png"><img src="https://sites.google.com/site/evenniaserver/_/rsrc/1429261373725/old_evennia/demo_color.png" alt="" /></a><em>This for all you developers out there who want to make a game with Evennia but are not sure about what game to make or where to start off.</em></p>
|
||
<h3>We need an example game</h3>
|
||
<p>One of the main critiques Evennia get from newbies is the lack of an (optional) full game implementation to use as an example and base to build from. So, Evennia needs a full, BSD-licensed example game. I&#x27;m talking &quot;diku-like&quot;, something you could in principle hook up and allow players into within minutes of installing Evennia. The Tutorial world we already have is a start but it is more of a solo quest, it&#x27;s not designed to be a full multiplayer game. Whereas Evennia supports other forms of MU* too, the idea is that the systems from a more &quot;code-heavy&quot; MUD could easily be extracted and adopted to a more freeform-style game whereas the reverse is not generally true.</p>
|
||
<p>The exact structure of such a game would be up to the person or team taking this on, but it should be making use of Evennia&#x27;s api and come distributed as a custom game folder (the folder you get with evennia --init). We will set this up as a separate repository under the <a href="https://github.com/evennia">Evennia github organisation</a> - a spin-off from the main evennia project, and maintained separately.</p>
|
||
<h3>We need you!</h3>
|
||
<p>Thing is, while I am (and, I&#x27;m sure other Evennia core devs) certainly willing to give considerable help and input on such a project, it&#x27;s <em>not</em> something I have time to take the <em>lead</em> on myself. So I&#x27;m looking for enthusiastic coders who would be willing to step up to both help and <em>take the lead</em> on this; both designing and (especially) coding such an example game. Even if you have your own game in mind for the future, you <em>still</em> need to build most of these systems, so starting with a generic system will still help you towards that final goal - plus you get to be immortalized in the code credits, of course.</p>
|
||
<h3></h3>
|
||
<p>Suggestion for game</p>
|
||
<p>Being an example game, it should be well-documented and following good code practices (this is something we can always fix and adjust as we go though). The systems should be designed as stand-alone/modular as possible to make them easy to rip out and re-purpose (you know people will do so anyway). These are the general features I would imagine are needed (they are open to discussion):</p>
|
||
<ul>
|
||
<li>Generic fantasy theme (lore is not the focus here, but it can still be made interesting)</li>
|
||
<li>Character creation module</li>
|
||
<li>Races (say, 2-3)</li>
|
||
<li>Classes (say 2-3)</li>
|
||
<li>Attributes and Skills (based on D&amp;D? Limit number of skills to the minimal set)</li>
|
||
<li>Rule module for making skill checks, rolls etc (D&amp;D rules?)</li>
|
||
<li>Combat system (twitch? Turn-based?)</li>
|
||
<li>Mobs, both friendly and aggressive, with AI</li>
|
||
<li>Trade with NPC / other players (money system)</li>
|
||
<li>Quest system</li>
|
||
<li>Eventual new GM/admin tools as needed</li>
|
||
<li>Small game world (batch-built) to demonstrate all features (of good quality to show off)</li>
|
||
<li>More? Less?</li>
|
||
</ul>
|
||
<h3>I&#x27;m interested!</h3>
|
||
<p>Great! We are as a first step looking for a driven <strong>lead dev</strong> for this project, a person who has the enthusiasm, coding experience and <em>drive</em> to see the project through and manage it. You will (hopefully) get plenty of collaborators willing to help out but It is my experience that a successful hobby project really needs at least one person taking responsibility to &quot;lead the charge&quot; and having the final say on features: Collaborative development can otherwise easily mean that everyone does their own thing or cannot agree on a common course. This would be a spin-off from the main Evennia project and maintained separately as mentioned above.</p>
|
||
<p>Reply to <a href="https://groups.google.com/forum/#%21msg/evennia/48PMDirb7go/w_hZ1mWhH8AJ">this thread</a> if you are willing to participate <strong><em>at any level</em></strong> to the project, including chipping in with code from your already ongoing development. I don&#x27;t know if there&#x27;d be any &quot;competition&quot; over the lead-dev position but if multiple really enthusiastic and willing devs step forward we&#x27;ll handle that then.</p>
|
||
<p>So get in touch!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 15 Jun 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-06-15-need-your-help!</guid></item><item><title> Dreaming big?</title><link>2015.html#2015-05-30-dreaming-big?</link><description><p><a href="https://1.bp.blogspot.com/-o3D_2InpMD0/VWnYBCUe2QI/AAAAAAAAEaQ/3JCuwjCrzjA/s1600/Battle_of_the_throne_small.jpg"><img src="https://1.bp.blogspot.com/-o3D_2InpMD0/VWnYBCUe2QI/AAAAAAAAEaQ/3JCuwjCrzjA/s320/Battle_of_the_throne_small.jpg" alt="" /></a></p>
|
||
<p>Optional Reality&#x27;s <a href="http://optionalrealities.com/forums/index.php?topic=13.0">Dreaming Big Challenge</a> has come to an end. This was a challenge about designing a &quot;sales pitch&quot; in 600 words or less for a text-based online roleplaying game. This is the kind of pitch you&#x27;d tease knowledgeable investors with - if investors cared about multiplayer text games and you ended up in an elevator with one, that is.</p>
|
||
<p>There were 10 entries to the competition and as the <a href="http://optionalrealities.com/forums/index.php?topic=101.0">results are now in</a> (including very elaborate judge feedback!), I encourage you to go read all the entries. The focus was on originality and fresh ideas and maybe these short pitches represent a cross-section of the current trends or a whiff of where the wind is blowing for future games. Or maybe it will help inspire you to make a sales pitch of your own.</p>
|
||
<p>You can find all the entries <a href="http://optionalrealities.com/forums/index.php?topic=100.0">linked from the second post of this thread.</a> Enjoy!</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 30 May 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-05-30-dreaming-big?</guid></item><item><title>Things goin on</title><link>2015.html#2015-05-11-things-goin-on</link><description><p><a href="https://4.bp.blogspot.com/-2Y8na9nvtog/VU_WU7zs8uI/AAAAAAAAEYc/IyRyP69b99w/s1600/Truss-Stage-Light-Truss-.jpg"><img src="https://4.bp.blogspot.com/-2Y8na9nvtog/VU_WU7zs8uI/AAAAAAAAEYc/IyRyP69b99w/s200/Truss-Stage-Light-Truss-.jpg" alt="" /></a></p>
|
||
<p>We are currently in a maintenance and cleanup phase of Evennia, where bugs are found and reported and things are getting more and more stable as people learn and use the new features we merged a few months back.</p>
|
||
<p>Overall though I must say the relatively big changes we did to the infrastructure (making Evennia into a full library and making a complete overhaul of the typeclass system behind the scenes) went over with surprising smoothness. There were a flurry of things to fix immediately after the devel-branch merger but no more than expected. For the big changes it really worked very well I think, with no big disaster stories. We have a few bugs lingering in the issue tracker that need to be addressed but nothing show-stopping.</p>
|
||
<p>I have been a bit busy with various projects off-MUD so to speak. I was contracted for making the cover and illustration for a book (this is not hobby art for once, but a professional commission which I was quite excited to be asked to do). I also author and draw <a href="http://griatch-art.deviantart.com/art/Crossing-borders-page-1-527982536">a fantasy comic as part of another project.</a></p>
|
||
<p>I&#x27;ve not been slacking off on on the MUD side though: I have written and submitted an article for the revived <a href="http://journal.imaginary-realities.com/">Imaginary Realities e-zine</a> (next issue should be out end of May/early June?) and another article (on Evennia) for the new <a href="http://optionalrealities.com/">Optional Realities</a> MUD community website. I also contributed a game-design blurb for the latter&#x27;s <a href="http://optionalrealities.com/forums/index.php?topic=13.0">Dreaming Big</a> contest, where you compete (for cash prizes, actually!) by submitting a game sale&#x27;s pitch under 600 words.</p>
|
||
<p>The above mentioned Optional Realities website is so far picking up pace with quite good discussion in its forums (the similarity of name with Imaginary Realities is unfortunate, apparently they were not aware of the former when choosing it). While targeted at discussions of RPI-style games (a sort of sub-genre of roleplay-enforced MUDs with perma-death), it already hosts several invited articles on game design and general game development that can be interesting for any MU* dev.</p>
|
||
<p>People should know by now that I like to support MUD community efforts when possible, and Evennia is thus listed as an official &quot;affiliate&quot; to Optional Realities (which admittedly means little more than us linking to each other but still). The team behind OR is however also using Evennia for their own &quot;Project Redshift&quot; Sci-fi mud, so we hope to get plenty of good feedback as their project matures.</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 11 May 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-05-11-things-goin-on</guid></item><item><title>Documenting Python without Sphinx</title><link>2015.html#2015-05-09-documenting-python-without-sphinx</link><description><p><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/La_Granja_de_San_Ildefonso_Sfinx01.jpg/800px-La_Granja_de_San_Ildefonso_Sfinx01.jpg"><img src="https://lh4.googleusercontent.com/proxy/KbIwdEDoKI3YPVgVArY87c8tHYHbRamzP5RsqyRKu62rVXabv9fFLBgcMorVujBaKdsfxtKnFpUUNS1z3OkGBo-en1f9pwaNyYeTu08PxNSR3EB_Zjvs9LtQfcSzXx_h7dU4RdnC81jTtAkfoGEewKp4KOP3dnml_Z6yAMdPFWHjU_r8T5_jjC7Oi0pKp3w1PV9_ep2u9zCF1dLEgvoHDIs=s0-d" alt="" /></a></p>
|
||
<p>Last week Evennia merged its development branch <a href="http://evennia.blogspot.se/2015/01/building-django-proxies-and-mud.html">with all the features mentioned in the last post</a>. Post-merger we have since gone through and fixed remaining bugs and shortened the list at a good clip.</p>
|
||
<p>One thing I have been considering is how to make Evennia&#x27;s API auto-documenting - we are after all a MUD creation library and whereas our code has always been well-documented the docs were always only accessible from the source files themselves.</p>
|
||
<p>Now, when you hear &quot;Python&quot; and &quot;documentation&quot; in the same sentence, the first thought usually involves Sphinx or <a href="http://sphinx-doc.org/ext/autodoc.html">Sphinx autodoc</a> in some form. Sphinx produces <a href="https://docs.djangoproject.com/en/1.7/">very nice looking documentation</a> indeed. My problem is however as follows:</p>
|
||
<ul>
|
||
<li>I don&#x27;t want our API documentation to be written in a different format from the rest of our documentation, which is in Github&#x27;s wiki using Markdown. Our users should be able to help document Evennia without remembering which formatting language is to be used.</li>
|
||
<li>I don&#x27;t like reStructuredText syntax. This is a personal thing. I get that it is powerful but it is also really, really ugly to read in its raw form in the source code. I feel the sources must be easy to read on their own.</li>
|
||
<li>Sphinx plugins like <a href="http://sphinx-doc.org/latest/ext/napoleon.html">napoleon</a> understands this ugliness and allows you to document your functions and classes in a saner form, such as the &quot;Google style&quot;. One still needs reST for in-place formatting though.</li>
|
||
<li>Organizing sphinx document trees is fiddly and having had a few runs with sphinx autodoc it&#x27;s just a mess trying to get it to section the Evennia sources in a way that makes sense. It could probably be done if I worked a lot more with it, but it&#x27;s a generic page generator and I feel that I will eventually have to get down to make those toctrees myself before I&#x27;m happy.</li>
|
||
<li>I want to host the API docs as normal Wiki files on Github (this might be possible with reST too I suppose).</li>
|
||
</ul>
|
||
<p>Long story short, rather than messing with getting Sphinx to do what I want, I ended up writing my own api-to-github-Markdown parser for the Evennia sources: api2md. Using Python&#x27;s inspect module and aiming for a subset of the <a href="http://sphinx-doc.org/latest/ext/example_google.html">Google formatted docstrings</a>, this was maybe a day&#x27;s work in total - the rest was/is fine-tuning for prettiness.</p>
|
||
<p>Now whenever the source is updated, I follow the following procedure to fully update the API docs:</p>
|
||
<ol>
|
||
<li>I pull the latest version of Evennia&#x27;s wiki git repository from github alongside the latest version of the main Evennia repository.</li>
|
||
<li>I run api2md on the changed Evennia sources. This crawls the main repo for top-level package imports (which is a small list currently hard-coded in the crawler - this is to know which modules should create &quot;submodule&quot; pages rather than try to list class contents etc). Under each package I specify it then recursively gets all modules. For each module in that package, it creates a new Markdown formatted wiki page which it drops in a folder in the wiki repository. The files are named after the model&#x27;s path in the library, meaning you get files like evennia.objects.models.md and can easily cross-link to subsections (aka classes and functions) on a page using page anchors.</li>
|
||
<li>I add eventual new files and commit the changes, then push the result to the Github wiki online. Done!</li>
|
||
</ol>
|
||
<p>(I could probably automate this with a git hook. Maybe as a future project.)</p>
|
||
<p>The api2md program currently has some Evennia-custom elements in it (notably in which packages it imports) but it&#x27;s otherwise a very generic parser of Python code into Markdown. It could maybe be broken out into its own package at some point if there&#x27;s interest.</p>
|
||
<p>The interesting thing is that since I already have code for <a href="http://evennia.blogspot.se/2014/02/moving-from-google-code-to-github.html">converting our wiki to reST</a> and ReadTheDocs, I should be able to get the best of both worlds and convert our API wiki pages the same way later. The result will probably not be quite as custom-stunning as a Sphinx generated autodoc (markdown is a lot simpler in what formatting options it can offer) but that is a lesser concern.<br />
|
||
So far very few of Evennia&#x27;s docstrings are actually updated for the Google style syntax (or any type of formatting, really) so the result is often not too useful. We hope that many people will help us with the doc strings in the future - it&#x27;s a great and easy way to get to know Evennia while helping out.</p>
|
||
<p>But where the sources <em>are</em> updated, <a href="https://github.com/evennia/evennia/wiki/evennia.utils.evtable">the auto-generated wiki page looks pretty neat</a>.</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 09 May 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-05-09-documenting-python-without-sphinx</guid></item><item><title>Building Django proxies and MUD libraries</title><link>2015.html#2015-01-19-building-django-proxies-and-mud-libraries</link><description><p><a href="http://upload.wikimedia.org/wikipedia/commons/5/5e/Bibliothek_St._Florian.jpg"><img src="https://lh5.googleusercontent.com/proxy/06dVvLrRNe-EqZJBbCF12T6O69WuNMoJpK1Vo_aIRTed86sKe49GhKvHrA_y02GuSOxzZQGojbU0YCyHQzqWXVJME8YUJd89A3IDqqCag5b_xnBXxNwwPlq4Mpd7a7JdNQ=s0-d" alt="" /></a></p>
|
||
<p>2015 is here and there is a lot of activity going on in Evennia&#x27;s repository, mailing list and IRC channel right now, with plenty of people asking questions and starting to use the system to build online games.</p>
|
||
<p>We get newcomers of all kinds, from experienced coders wanting to migrate from other code bases to newbies who are well versed in mudding but who aim to use Evennia for learning Python. At the moment the types of games planned or under development seems rather evenly distributed between RPI-style MUDs and MUSH games (maybe with a little dominance of MUSH) but there are also a couple of hack-and-slash concepts thrown into the mix. We also get some really wild concepts pitched to us now and then. What final games actually comes of it, who can tell, but people are certainly getting their MU*-creative urges scratched in greater numbers, which is a good sign.</p>
|
||
<p>Since Christmas our <em>&quot;devel&quot;</em> branch is visible online and is teeming with activity. So I thought I&#x27;d post an summary about it in this blog. The more detailed technical details for active developers can be found on Evennia&#x27;s mailing list <a href="https://groups.google.com/forum/#%21topic/evennia/6ug7m872GIk">here</a> (note that full docs are not yet written for devel-branch).</p>
|
||
<h2>Django proxies for Typeclasses</h2>
|
||
<p>I have written about Evennia&#x27;s Typeclass system before on this blog. It is basically a way to &quot;decorate&quot; Django database models with a second set of classes to allow Evennia developers to create any type of game entity without having to modify the database schema. It does so by connecting one django model instance to one typeclass instance and overloading <strong>setattr</strong> and <strong>getattribute</strong> to transparently communicate between the two.</p>
|
||
<p>For the devel branch I have refactored our typeclass system to make use of Django&#x27;s <em><a href="https://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models">proxy models</a></em> instead. Proxy models have existed for quite a while in Django, but they simply slipped under my radar until a user pointed them out to me late last year. A proxy model is basically a way to &quot;replace the Python representation of a database table with a proxy class&quot;. Sounds like a Typeclass, doesn&#x27;t it?<br />
|
||
Now, proxy models doesn&#x27;t work <em>quite</em> like typeclasses out of the box - for one thing if you query for them in the database you will get back the original model and not the proxy one. They also do not allow multiple inheritance. Finally I don&#x27;t want Evennia users to have to set up django Meta info every time they use a proxy. So most work went into overloading the proxy multiclass inheritance check (there is a django issue about how to fix this). Along the way I also redefined the default managers and <strong>init</strong> methods to always load the proxy actually searched for and not the model. I finally created metaclasses to handle all the boilerplate. We choose to keep the name <em>Typeclass</em> also for this extended proxy. This is partly for legacy reasons, but typeclasses do have their own identity: they are not vanilla Django-proxies nor completely normal Python classes (although they are very close to the latter from the perspective of the end user).<br />
|
||
Since typeclasses now are directly inheriting from the base class (due to meta-classing this looks like normal Python inheritance), it makes things a lot easier to visualize, explain and use. Performance-wise this system is en par with the old, or maybe a little faster, but it will also be a lot more straight forward to cache than the old. I have done preliminary testing with threading and it looks promising (but more on that in a future post).</p>
|
||
<h2>Evennia as a Python library package</h2>
|
||
<p>Evennia has until now been solely distributed as a version controlled source tree (first under SVN, then Mercurial and now via GIT and Github). In its current inception you clone the tree and find inside it a game/ directory where you create your game. A problem we have when helping newbies is that we can&#x27;t easily put pre-filled templates in there - if people used them there might be merge conflicts when we update the templates upstream. So the way people configure Evennia is to make copies of template modules and then change the settings to point to that copy rather than the default module. This works well but it means a higher threshold of setup for new users and a lot of describing text. Also, while learning GIT is a useful skill, it&#x27;s another hurdle to get past for those who just want to change something minor to see if Evennia is for them.</p>
|
||
<p>In the devel branch, Evennia is now a library. The game/ folder is no longer distributed as part of the repository but is created dynamically by using the new binary evennia launcher program, which is also responsible for creating (or migrating) the database as well as operating the server:</p>
|
||
<pre><code>evennia --init mygame
|
||
cd mygame
|
||
evennia migrate
|
||
evennia start
|
||
</code></pre>
|
||
<p>Since this new folder is <em>not</em> under our source tree, we can set up and copy pre-made template modules to it that people can just immediately start filling in without worrying about merge conflicts. We can also dynamically create a setting file that fits the environment as well as set up a correct tree for overloading web functionality and so on. It also makes it a lot easier for people wanting to create multiple games and to put their work under separate version control.</p>
|
||
<p>Rather than traversing the repository structure as before you henceforth will just do import evennia in your code to have access to the entirety of the API. And finally this means it will (eventually) be possible to install Evennia from <a href="https://pypi.python.org/pypi/Evennia-MUD-Server/Beta">pypi</a> with something like pip install evennia. This will greatly ease the first steps for those not keen on learning GIT.</p>
|
||
<h2>For existing users</h2>
|
||
<p>Both the typeclasses-as-proxies and the evennia library changes are now live in the devel branch. Some brave users have already started taking it through its paces (and is helping to flesh it out) but it will take some time before it merges into master.</p>
|
||
<p>The interesting thing is that despite all this sounding like a huge change to Evennia, the coding API doesn&#x27;t change very much, the database schema almost not at all. With the exception of some properties specific to the old connection between the typeclass and model, code translate over pretty much without change from the developer&#x27;s standpoint.</p>
|
||
<p>The main translation work for existing developers lies in copying over their code from the old game/ directory to the new dynamically created game folder. They need to do a search-and-replace so that they import from evennia rather than from src or ev. There may possibly be some other minor things. But so far testers have not found it too cumbersome or time consuming to do. And all agree that the new structure is worth it.</p>
|
||
<p>So, onward into 2015!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 19 Jan 2015 00:00:00 GMT</pubDate><guid isPermaLink="true">2015.html#2015-01-19-building-django-proxies-and-mud-libraries</guid></item><item><title>Slowly moving through town</title><link>2014.html#2014-10-02-slowly-moving-through-town</link><description><p><a href="https://4.bp.blogspot.com/-LEAcNfC4EmQ/VC1ySqlz7cI/AAAAAAAAEO4/yVEgs7T6jlo/s1600/Grapevinesnail_01.jpg"><img src="https://4.bp.blogspot.com/-LEAcNfC4EmQ/VC1ySqlz7cI/AAAAAAAAEO4/yVEgs7T6jlo/s1600/Grapevinesnail_01.jpg" alt="" /></a></p>
|
||
<p>After getting questions about it I recently added the <a href="https://github.com/evennia/evennia/blob/master/contrib/slow_exit.py">Slow Exit contribution</a> to the main repository as an example.</p>
|
||
<p>Delayed movement is something often seen in various text games, it simply means that the time to move from room to room is artificially extended.</p>
|
||
<p>Evennia&#x27;s default model uses traditional MU* rooms. These are simple nodes with exits linking them together. Such Rooms have no internal size and no inherent spatial relationship to each other. Moving from any Room to any other is happening as fast as the system can process the movement.</p>
|
||
<p>Introducing a delay on exit traversal can have a surprisingly big effect on a game:</p>
|
||
<ul>
|
||
<li>It dramatically changes the &quot;feel&quot; of the game. It often makes the game feel less &quot;twitch&quot; and slows things down in a very real way. It lets Players consider movement as a &quot;cost&quot;.</li>
|
||
<li>It simulates movement speed. A &quot;quick&quot; (or maybe well-rested) character might perceive an actual difference in traversal. The traversal speed can vary depending on if the Character is &quot;running&quot; or &quot;walking&quot;.</li>
|
||
<li>It can emulate travel distance. An Exit leading to &quot;the top of the mountain&quot; may take longer to traverse than going &quot;inside the tent&quot;.</li>
|
||
<li>It makes movement a &quot;cost&quot; to take into consideration in the game. Moving back and forth over and over across a distance of multiple rooms becomes a much more daunting prospect with a time delay than if you could just zip along as quickly as you could press the button. This also has effects on map and quest design.</li>
|
||
</ul>
|
||
<p>Introducing delayed movement in Evennia is simple. But to explain the idea, let&#x27;s first briefly explain how Evennia implements Exits.</p>
|
||
<h4>A brief sideline: About Exits</h4>
|
||
<p>An Exit in Evennia is a persistent Object sitting in a room. The Exit class is just like any Object except for two things - it stores a &quot;destination&quot; property and it houses a CommandSet on itself. This particular CommandSet holds a single command with the same name as the Exit object.</p>
|
||
<p>Commands and CommandSets are things <a href="http://evennia.blogspot.se/2012/08/taking-command.html">I&#x27;ve covered in earlier blog posts</a>. Suffice to say is that any number of command sets can be merged together dynamically to at any moment represent the commands available to the Character at any given time or situation.</p>
|
||
<p>What happens when an Exit bject is in the same room as a Character is that the Exit&#x27;s command set is dynamically merged with that of the Character. This means a new command - which always has the same name as the Exit - becomes available. The result is that if the Exit object is called &quot;south&quot;, the Character can use the command &quot;south&quot;. By default all the command does is to call a hook method on the Exit object. This hook hooks simply moves the calling Character to the &quot;destination&quot; stored by the Exit. Done!</p>
|
||
<p>The nice thing with this is that the whole system is implemented without any special cases or custom hard-wired code. It also means that the entire Exit system can be changed and modified without ever touching Evennia&#x27;s core.</p>
|
||
<h4>Delaying Exits</h4>
|
||
<p>To delay the traversal, the principle is simple - after the Exit command has triggered, wait for a little while before continuing.</p>
|
||
<p>Technically we define a new class of Exit, let&#x27;s call it SlowExit, inheriting from the default Exit. We locate the spot where the Exit normally sends traversing objects on their way (this is a method called move_to()).</p>
|
||
<p>Since Evennia is based on Twisted, we use Twisted&#x27;s intrinsic CallLater() function to delay the move for as many seconds we desire (in the contrib I use a thin wrapper around CallLater called delay()). The result is that the command is called, you get a little text saying that you have started moving ... and a few seconds later you actually move.</p>
|
||
<p>Once one understands how Exits work it&#x27;s really quite straight forward - see the <a href="https://github.com/evennia/evennia/blob/master/contrib/slow_exit.py">code on github</a> for more details (it&#x27;s got plenty of comments).</p>
|
||
<p>In the contrib are also some example utility commands for setting one&#x27;s movement speed and to abort movement if you change your mind before the timeout has passed.</p>
|
||
<p>This simple start can easily be expanded as befits each individual game. One can imagine introducing anything from stamina costs to make travel time be dynamically calculated based on terrain or other factors.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 02 Oct 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-10-02-slowly-moving-through-town</guid></item><item><title>Dance my puppets</title><link>2014.html#2014-08-04-dance-my-puppets</link><description><p><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/5016_-_Archaeological_Museum,_Athens_-_Dolls_-_Photo_by_Giovanni_Dall%27Orto,_Nov_13_2009.jpg/374px-5016_-_Archaeological_Museum,_Athens_-_Dolls_-_Photo_by_Giovanni_Dall%27Orto,_Nov_13_2009.jpg"><img src="https://lh3.googleusercontent.com/proxy/hraqnaf9pLN_5rYSN5vnqysZwOaipiA32vImwp1-TWic6HtbYxqlwtRLjJgl9WQd6IY0TsCGPiPaEw8HEEgcxx_yy9S3E3KRKRk0Ksdm50RDLgAtNaftkVdS2EGU0nuOqdIeUHIWmijKMWNtknEj7891LEFUgjaTDCcsvenRq7f3032soPG_mfUz5bXw7PMGiyQd42PSnvbBh4ufwvzvlQZp-93GVKsTH40MN5vgQm0SfEDVp4fNY49Yyo16MLMQM5MVEfWA9EKmy_HxCPwX07NmWLwIRbRD1_q821tQXDaYeJzzj40If2hJrB1EKPTzo41A7HKfsPbRnla48S9wtqcny_kTO88AdcF1=s0-d" alt="" /></a></p>
|
||
<p>In many traditional multiplayer text engines for MUD/MUSH/MU*, the player connects to the game with an account name that also becomes their character&#x27;s in-game name. When they log into the game they immediately &quot;become&quot; that character. If they want to play with another character, they need to create a new account.</p>
|
||
<p>A single-login system is easy to implement but many code bases try to expand with some sort of &quot;account system&quot; where a single login &quot;account&quot; will allow you to manage one or more game characters. Matthew “Chaos” Sheahan beautifully argues for the benefits of an account system in the April issue of <a href="http://journal.imaginary-realities.com/volume-06/issue-01/index.html">Imaginary Realities</a>; you can read his article <a href="http://journal.imaginary-realities.com/volume-06/issue-01/your-mud-should-have-an-account-system/index.html">here</a>.</p>
|
||
<h3>Evennia and account systems</h3>
|
||
<p>First a brief show of how Evennia handles this. We use the following separation:</p>
|
||
<p><strong>Session(s) &lt;-&gt; Player &lt;-&gt; Objects/Characters(s)</strong></p>
|
||
<p>The <em>Session</em> object represents individual client connections to Evennia. The <em>Player</em> is our &quot;account&quot; object. It holds the password hash and your login name but has no in-game existence. Finally we have <em>Objects</em>, the most common being a subclass of Object we call <em>Character.</em> Objects exist in the game. They are &quot;puppeted&quot; by Sessions via the Player account.</p>
|
||
<p>From this separation an account system follows naturally. Evennia also offers fully flexible puppeting out of the box: Changing characters (or for staff to puppet an NPC) is simply a matter of &quot;disconnecting&quot; from one Character and connecting to another (presuming you have permission to do so).</p>
|
||
<h3>The Multisession modes of Evennia</h3>
|
||
<p>This is the main gist of this entry since we just added another of these (mode 3). Evennia now offers four different <em>multisession modes</em> for the game designer to choose between. They affect how you gamers may control their characters and can be changed with just a server reload.</p>
|
||
<h4>Mode 0</h4>
|
||
<p>This is emulates the &quot;traditional&quot; mud codebase style. In mode 0 a Session controls one Character and one character only. Only one Session per account is allowed - that is, if a user try to connect to their Player account with a different client the old connection will be disconnected. In the default command set a new Character is created with the same name as the Player account and the two are automatically connected whenever they log in. To the user this makes Player and Character seem to be virtually the same thing.</p>
|
||
<h4>Mode 1</h4>
|
||
<p>In this mode, multiple Sessions are allowed per Player account. You still only have one Character per account but you can control that Character from any number of simultaneously connected clients. This is a requirement from MUSHes and some slower-moving games where there are communities of gamers who want to conveniently track the progress of the game continuously on multiple clients and computers.</p>
|
||
<h4>Mode 2</h4>
|
||
<p>In multisession mode 2, multiple Characters are allowed per Player account. No Characters are created by default in this mode, rather the default command set will drop you to a simplified OOC management screen where you can create new characters, list the ones you already have and puppet them. This mode offers true multiplaying, where you can connect via several clients simultaneously, each Session controlling a different Character.</p>
|
||
<h4>Mode 3</h4>
|
||
<p>This mode allows gamers not only to play multiple Characters on the same Player account (as in mode 2) but to also connect <em>multiple Sessions to each Character.</em> This is a multi-character version of Mode 1, where players can control the same Character via Player logins from several different clients on different machines in any combination.</p>
|
||
<p>It&#x27;s interesting that some of these modes may seem silly or superfluous to people used to a certain type of MU* yet are killer features for other communities. It goes to show how different the needs are for users of different game styles.</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 04 Aug 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-08-04-dance-my-puppets</guid></item><item><title>Webby stuff</title><link>2014.html#2014-06-30-webby-stuff</link><description><p><a href="https://3.bp.blogspot.com/-82MT42ksmuU/U7FpMy-LgGI/AAAAAAAADqA/ok6MfvNNTvY/s1600/spiderweb.jpg"><img src="https://3.bp.blogspot.com/-82MT42ksmuU/U7FpMy-LgGI/AAAAAAAADqA/ok6MfvNNTvY/s1600/spiderweb.jpg" alt="" /></a></p>
|
||
<p>Latest Evennia come with a range of improvements, mainly related to its integration with the web.</p>
|
||
<h3>New and improved ways to expand the website/webclient</h3>
|
||
<p>Thanks to the work of contributor Kelketek, Evennia&#x27;s Django-based web system (website and webclient) has been restructured to be much easier to expand. Previously you had to basically copy the entire web/ folder into your game and modify things in-place. This was not ideal since it made it inherently harder to update when things changed upstream. Now Evennia makes use of Django&#x27;s <em>collectstatic</em> functionality to allow people to plugin and overload only the media files and templates that they need. Kelketek wrote a new and shiny <a href="https://github.com/evennia/evennia/wiki/Web%20Tutorial">web tutorial</a> explaining just how things work.</p>
|
||
<h3>Websocket-based webclient with OOB</h3>
|
||
<p>Evennia&#x27;s webclient was an ajax-based one using a long polling (&quot;comet&quot;) paradigm to work. These days all modern browsers support <a href="http://en.wikipedia.org/wiki/WebSocket">websockets</a> though, a protocol that allows asynchronous server-client communication without the cludgery of long polling. So Evennia&#x27;s new webclient will now use websockets if the browser supports it and fall back to the old comet client if it does not.</p>
|
||
<p>The new client also has full support for OOB (Out-of-band) communication. The client uses JSON for straight forward OOB messaging with the server. As part of this, I had an excuse to go back to clean up and make the OOB backbone of Evennia more complete. The server-side oob commands are borrowed from <a href="http://tintin.sourceforge.net/msdp/">MSDP</a> but the server side is of course independent of communication protocol (so webclient and telnet extensions can call the same server-side callbacks). I&#x27;ve not yet finalized the documentation for how to use the OOB yet, that will come soon-ish.</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 30 Jun 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-06-30-webby-stuff</guid></item><item><title>Bringing back Python memory</title><link>2014.html#2014-06-15-bringing-back-python-memory</link><description><p><a href="https://2.bp.blogspot.com/-AoyW71rwdmw/U52RCQqYoDI/AAAAAAAADnU/KH7QGKf_GmM/s1600/RAM.jpg"><img src="https://2.bp.blogspot.com/-AoyW71rwdmw/U52RCQqYoDI/AAAAAAAADnU/KH7QGKf_GmM/s1600/RAM.jpg" alt="" /></a></p>
|
||
<p>Lately I&#x27;ve done work on the memory management of Evennia. Analyzing the memory footprint of a python program is a rather educational thing in general.</p>
|
||
<p>Python keeps tracks of all objects (from variables to classes and everything in between) via a memory reference. When other objects reference that object it tracks this too.<br />
|
||
Once nothing references an object, it does not need to be in memory any more - in a more low-level languages this might lead to a memory leak. Python&#x27;s <em>garbage collector</em> handles this for us though - it goes through all abandoned objects and frees the memory for usage by other things. The garbage collector will however <em>not</em> do its thing as long as some other object (which will not be garbage-collected) <em>still</em> holds a reference to the object. This is what you want - you don&#x27;t want existing objects to stop working because an object they rely on is suddenly not there.</p>
|
||
<p>Normally in Django, whenever you retrieve an database model instance, that exists only in memory then and there. If you later retrieve the same object from the database, the model instance you have to work with is most likely a new one. This is okay for most usage, but Evennia&#x27;s typeclass system (described in an earlier blog entry) as well our wish to store temporary properties on models (existing until next server restart) does not work if the model instance we get is always different. It would also help if we didn&#x27;t have to load models from the database more than necessary.</p>
|
||
<p>For this reason, Evennia uses something called the <em>idmapper</em>. This is a cache mechanism (heavily modified for Evennia) that allows objects to be loaded from the database only once and then be reused when later accessed. The speedup achieved from this is important, but as said it also makes critical systems work properly.</p>
|
||
<p>The tradeoff of speed and utility is memory usage. Since the idmapper never drops those references it means that objects will never be garbage collected. The result was that the memory usage of Evennia could rise rapidly with an increasing number of objects. Whereas some objects (like those with temporary attributes) should indeed not be garbage collected, in a working game there is likely to be objects without such volatile data. An example might be objects that are not used some of the time - simply because players or the game don&#x27;t need them for the moment. For such objects it may be okay to re-load them on demand rather than keep them in memory indefinitely.</p>
|
||
<p>When looking into this I found that simply force-flushing the idmapper did <em>not</em> clean up all objects from memory. The reason for this has to do with how Evennia references objects via a range of other means. The reference count never went to zero and so the garbage collector never got around to it.</p>
|
||
<p>With the excellent <a href="https://pypi.python.org/pypi/objgraph">objgraph</a> library it is actually pretty easy to track just what is referencing what, and to figure out what to remove. Using this I went through a rather prolonged spree of cleanups where I gradually (and carefully) cleaned up Evennia&#x27;s object referencing to a point where the only external reference to most objects were the idmapper cache reference. So removing that (like when deliberately flushing the cache) will now make the object possible to garbage-collect.</p>
|
||
<p><a href="http://postimg.org/image/p00v4oinl/">This</a> is how the reference map used to look for one type of Evennia object (ObjectDB) before the cleanup. Note the several references into the ObjectDB and the cyclic references for all handlers (the cyclic reference is in itself not a problem for reference-counting but they are slow and unnecessary; I now made all handlers use lazy-loading with weak referencing instead).</p>
|
||
<p><a href="http://postimg.org/image/90i7l4mlt/">This</a> is how the reference map looks for the same object now. The <strong>instance</strong> cache is the idmapper reference. There are also no more cyclic references for handlers (the display don&#x27;t even pick up on them for this depth of recursion). Just removing that single link will now garbage-collect ObjectDB and its typeclass (ignore the <em>g</em> reference, that is just the variable holding the object in ipython).<br />
|
||
We also see that the dbobj.typeclass &lt;-&gt; typeclass.dbobj references keep each other alive and when one goes the other one goes too - just as expected.</p>
|
||
<p>An curious aspect of Python memory handling is that (C-)Python does <em>not</em> actually release the memory back to operating system when flushing the idmapper cache. Rather Python makes it internally available so that it does not need to request any more. The result is that if you look at Evennia with the <em>top</em> command, its memory requirement (for example while continuously creating new objects) will not actually <em>drop</em> on a idmapper flush, it will just <em>stop rising</em>. This is discussed at length in <a href="http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm">this blog</a>, it was good to learn it was not something I did at least.</p>
|
||
<p>Apart from the memory stuff, there is work ongoing with fixing the latest batch of user issue reports. Another dev is working on cleaning up the web-related code, it should make it a lot cleaner to overload web functionality with custom code. One of those days I&#x27;ll also try to sit down and finally convert our web client from long-polling to use web sockets now that Evennia suppports web sockets natively. Time, time ...</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 15 Jun 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-06-15-bringing-back-python-memory</guid></item><item><title> Imaginary Realities volume 6, issue 1</title><link>2014.html#2014-05-16-imaginary-realities-volume-6,-issue-1</link><description><p><a href="http://imaginary-realities.disinterest.org/pics/logo_new.gif"><img src="https://lh4.googleusercontent.com/proxy/CEw97RBnw7FiR_z7fqlj9ELtwgDU-knwkyiW8Ybjg9tjTUAerwxQ0-omUEwpZAz4jKP1ozmnCLHPBh1A4QxrGZzYD3DEFfIdTReu0TTPJwo=s0-d" alt="" /></a></p>
|
||
<p>I&#x27;m a bit late with writing about it, but the latest issue of <em>Imaginary Realities</em> has been out for a month or so now. You can find it <a href="https://www.blogger.com/"></a><a href="http://journal.imaginary-realities.com/volume-06/issue-01/index.html">here</a>.</p>
|
||
<p>Here is a brief summary of the articles in the latest issue.</p>
|
||
<ul>
|
||
<li>In <em><strong>A Journey Through Paradice, Part II</strong>,</em> Matthew Chaplan continues his description of the C++ codebase <em>Paradice9</em>, notably focusing on its input handling, which uses character-mode telnet to produce plenty of interesting effects in a custom terminal client. There are plenty of interesting features (or potential features) discussed. An example is the client knowing to store the receiver of a &quot;reply&quot; command the moment the command is entered rather than waiting for the player the press return (at which point someone else might have written to you and the reply-to target would have changed in a traditional setup). There is no denying the power of having a custom client for your game. And whereas I think some more secure protocol than telnet would maybe be better to use when you control both server and client anyway, it&#x27;s really interesting to see the power and features you can achieve with it.</li>
|
||
<li><em><strong>Building a Giant Mech in Evennia</strong> -</em> this is my entry for this issue; a short little tutorial on designing a machine of mirth and mayhem in Evennia.</li>
|
||
<li>Richard “KaVir” Woolcock&#x27;s <em><strong>Describing a Virtual World</strong></em> covers the different uses of dynamically created descriptions in text games. He summarizes the types, from the most common, fully static room description up unto the character-dependent procedurally generated descriptions in his own <em>GodWarsII</em> mud. It&#x27;s a fascinating read since it not only goes into rooms but also how to build piecemeal and situation-aware character and object descriptions as well as procedural help and quest info. The techniques are not for every type of game of course. But a good and informative read for anyone interested in game design.</li>
|
||
<li><em><strong>Dynamic room descriptions</strong>,</em> by Jana, are also covering room descriptions although takes a more conservative conclusion than the full procedural contruction of KaVir&#x27;s article. This covers the hybrid hand-written description - that is hand-written text that uses a markup language for optional or situation-dependent text. It makes for a good text on implementing such a system (an Evennia equivalent is <em>extended_room.py</em> found in our <em>contrib</em> folder.</li>
|
||
<li><strong><em>Saddle Up - A Personal Story about Riding Your Demon to Success</em></strong> is a summary and inspirational story by Michael &quot;Drakkos&quot; Heron. It ties back to his work with <em>Epitath</em> and how it has affected and improved (and continues to improve) his personal and professional life. I like that he manages to include his game development work into his teaching and reasearch, a cool way to make use of your hobby. He has a point on the usability of a coding hobby like this: I myself have had lots of use and even landed project work based on my work with Evennia. One of our users landed his current job based on knowledge he learned working with Evennia. So there is definitely an advantage to mud-development outside the hobby realm.</li>
|
||
<li><em><strong>The Successful Quest Builder</strong></em> by John &quot;TheDude&quot; Robinette and Joanna &quot;Lorana&quot; Liberty covers the construction of a Quest from the designer&#x27;s perspective. Rather than focusing on gameplay considerations the authors here focus on the technical aspects; learning the codebase&#x27;s tools and things to think about debugging and developing something that is enjoyable for the players.</li>
|
||
<li>The article <strong><em>Your MUD Should Have an Account System</em></strong> finally, is Matthew “Chaos” Sheahan&#x27;s argument as to why a game should use a single login account system rather than the old way of creating a new account per player. Much of the argument is around converting an old-school code base into this configuration and how it&#x27;s not as hard as one may think. I fully agree on his assessment (although I wonder just how &quot;easy&quot; it is to patch on such a system on an old-running mud). He even mentions Evennia as an example of a modern codebase having this functionality out of the box (yay!).</li>
|
||
</ul>
|
||
<p>Deadline for the next issue is <a href="http://posted-stuff.blogspot.se/2014/04/write-article-for-imaginary-realities.html">announced to be May 31 2014</a> so don&#x27;t be shy to contribute your own article. Richard Tew hints at in his introduction, finding people to write articles is the tricky part still.</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 16 May 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-05-16-imaginary-realities-volume-6,-issue-1</guid></item><item><title>Moving from Google Code to Github</title><link>2014.html#2014-02-08-moving-from-google-code-to-github</link><description><p><a href="https://1.bp.blogspot.com/-O_mHSjm4u90/UvVmXrY3kkI/AAAAAAAACJc/5bREd9YEbLU/s1600/ar12943602961303.jpg"><img src="https://1.bp.blogspot.com/-O_mHSjm4u90/UvVmXrY3kkI/AAAAAAAACJc/5bREd9YEbLU/s1600/ar12943602961303.jpg" alt="" /></a></p>
|
||
<p>A few weeks back, the Evennia project made the leap from Google Code to GitHub (<a href="https://github.com/evennia/evennia">here</a>). Things have been calming down so it&#x27;s time to give a summary of how the process went.</p>
|
||
<p>Firstly I want to say that I liked Google Code. It did everything expected of it with little hassle. It had a very good Issue system (better than GitHub in my opinion) and it allowed us to use Mercurial instead of Git for version control (I just happen to like Mercurial better than Git, so sue me). Now, GitHub is getting to be something of a standard these days. But whereas our users have occationaly inquired about us making the move, I&#x27;ve been reluctant to do so.</p>
|
||
<p>The problem I <em>did</em> have with Google Code was that I got the increasing feeling that Google didn&#x27;t care all that much about it. It worked decently, but it was not really going anywhere either. What finally made me change my mind though was an event just after summer last year. There was a bug in Google Code that made the links to online clones disappear. It was worse than that - creating new online clones of the main repo didn&#x27;t work - people wanting to contribute using a clone just couldn&#x27;t.</p>
|
||
<p>This is extremely critical functionality for a code-sharing website to have! I made a bug report and many other projects chimed in seeing the same issues. Eventually the links returned and everything worked the way it had. But it took <em>several months</em> before this critical bug was fixed. Even then Google didn&#x27;t even bother to close my issue. This suggested quite strongly to me that Google Code is not really a priority even for its parent company. It was time to consider a move.</p>
|
||
<p>I was never personally a fan of Git. It is undoubtedly powerful, but I always felt its syntax way too archaic and the number of ways to shoot yourself in the foot way too many. But I do like GitHub better than BitBucket (I&#x27;ve used both in other projects), so that&#x27;s where we nevertheless were heading.</p>
|
||
<p>Already last year I created an Evennia &quot;organization&quot; on GitHub and one of our users first helped to set up a Git Mirror of our Mercurial repo. The idea was a good one - have a mirror on GitHub, allowing the transition to be more gradual. In the end this didn&#x27;t work out though - there were some issue with the hg-git conversion and the mirror never didn&#x27;t actually update. When I checked back and it was three months behind we just removed that first ill-fated version.</p>
|
||
<p>In the end I decided to not fiddle about with it, but to move everything over in one go.</p>
|
||
<h3>Converting the repository</h3>
|
||
<p>I set aside a new folder on my hard drive and cloned the original mercurial repo into a new sub folder. A good idea is to set up a quick Python <a href="https://pypi.python.org/pypi/virtualenv">virtual environment</a> for easily getting updated dependencies of build scripts.</p>
|
||
<p>I initialized an empty Git repository and used a program called <a href="https://github.com/frej/fast-export">hg-fast-export</a> to convert. As it turned out there were some finer details to consider when doing that:</p>
|
||
<ul>
|
||
<li>The most obvious one was that the conversion initially failed, complaining about the Mercurial original containing &quot;unnamed branches&quot;. These came from a contributor who did <em>something</em> to spawn off all sorts of weird branches with little purpose. I should not have merged those into main in the first place, but in those days I didn&#x27;t know mercurial well enough to be concerned. In the end I simply used mercurial&#x27;s MQ extension to remove the unnamed (and unused) branches so the conversion could complete.</li>
|
||
<li>The second issue was that Mercurial is less stringent about its author strings than Git is. Git&#x27;s author string is &quot;name <email>&quot;. Over the years we have gotten contributions from people with all sorts of combinations of names, with or without an email address. So for this we had to supply a mapping file to the converter. It&#x27;s basically a list of old_author_string = new_author_string and allows for grouping the various used names as needed (some of them were the same person using slightly different author strings).</li>
|
||
</ul>
|
||
<p>Once this was in place, the repo conversion worked fine. It was just a matter of changing the .hgignore file to a .gitignore file and change some code that made use of mercurial to get and display the current revision id.</p>
|
||
<h3>Converting the Wiki, part one</h3>
|
||
<p>Evennia&#x27;s wiki consitutes our documentation, it&#x27;s some 80+ pages or so by now. Definitely not something we want to loose. Google Code use a dialect of MediaWiki whereas GitHub&#x27;s wiki supports a few other formats, like markdown or reST. I needed to convert between them.</p>
|
||
<p>Digging around a bit I found <a href="https://github.com/trentm/googlecode2github.git">googlecode2github</a>. This download contains python scripts for converting the wiki as well as Issues. I didn&#x27;t really get the issues-converter to work, so I had to find another solution for that (see next section).</p>
|
||
<p>All in all, the initial wiki conversion worked decently - all the pages were converted over and were readable. I was even to the point of declaring success when finding the damn thing messed up the links. Googe Code writes links like this: [MyLink Text to see on page]. The script converted this to [[MyLink|Text to see on page]]. Which may look fine except it isn&#x27;t. GitHub actually wants the syntax in the inverse order: [[Text to see on page|MyLink]].</p>
|
||
<p>Furthermore, in Google Code&#x27;s wiki, code blocks were marked with</p>
|
||
<pre><code>{{{
|
||
&lt;verbatim code&gt;
|
||
}}}
|
||
</code></pre>
|
||
<p>In markdown, code blocks are created just by indenting the block by four spaces. The converter dutifully did this - but it didn&#x27;t add empty lines above and below the block, which is another thing markdown requires. The result was that all code ended up mixed into the running text output.</p>
|
||
<p>I could have gone back and fixed the converter script, but I suspected there would be enough small things to fix anyway. So in the end I went through 80+ pages of fixing link syntax and adding empty lines by hand. After that I could finally push the first converted wiki version up to the GitHub wiki repository.</p>
|
||
<p>Some time later I also found that there is a way to let GitHub wiki pages use syntax highlighting for the language of your choice. The way to do this is to enclose your code blocks like this:</p>
|
||
<pre><code>```python
|
||
|
||
&lt;verbatim code&gt;
|
||
|
||
```
|
||
</code></pre>
|
||
<p>This is apparently &quot;GitHub-flavoured&quot; markdown. So another stint into all the pages followed, to update everything for prettiness.</p>
|
||
<h3>Converting Google Code Issues</h3>
|
||
<p>I didn&#x27;t want to loose our Issues from Google Code. I looked around a bit and tested some conversions for this (it helps to be able to create and delete repos on GitHub with abandon when things fail). I eventually settled on <a href="https://github.com/arthur-debert/google-code-issues-migrator">google-code-issues-migrator</a>.</p>
|
||
<p>This is a Python script that gathers all the Issues from a given Google Code project. It then uses GitHub&#x27;s API to re-post the issues. It retains the issue numbers and re-maps the Google Code Issue tags to GitHub&#x27;s equivalent. It didn&#x27;t retain most other formatting and whereas I ended up as the creator of all issues, the converter included the name of the original author as well as a link back to the original Google Code one. I found that to be quite sufficient for our needs.</p>
|
||
<h3>Converting the IRC announcer</h3>
|
||
<p>A lot of development discussion goes on in our IRC channel #evennia on Freenode. There is an announcer bot in there that I&#x27;ve written, that collates information from various sources and reports it in the IRC channel:</p>
|
||
<ul>
|
||
<li>Repository updates</li>
|
||
<li>Wiki updates</li>
|
||
<li>Issue creation and updates</li>
|
||
<li>Mailing list/forum posts</li>
|
||
<li>Dev-blog updates (this blog)</li>
|
||
</ul>
|
||
<p>Say what you will about Google, but they are great at offering RSS feeds to all their stuff. So my IRC bot was basically a glorified threaded RSS reader that echoed changes to the channel as they came in. This had been working nicely for years.</p>
|
||
<p>GitHub does offer RSS feeds to -some- of their offerings, but it&#x27;s a lot more patchy. I eventually had to do quite a bit of hacking to get everything reporting the way we were used to.</p>
|
||
<ul>
|
||
<li>GitHub has its own IRC announcer bot that reports to IRC. The problem is that this will connect, send message and then disconnect. This causes a lot of spam in the channel. We neither can nor want to set +n on our channel to allow external messages either. The way I solved this was to expand my own custom IRC bot to sit in <em>two</em> irc channels. The GitHub announcer connects to only one of them (so this gets all the spammy connect messages). My IRC bot picks up the announcement and echoes it cleanly to our main #evennia channel. It works really well.</li>
|
||
<li>Issues are handled by the GitHub announcer in the same way.</li>
|
||
<li>GitHub has no automatic way to report wiki updates. It doesn&#x27;t even have a proper RSS feed. However, a user clued me in on using the <a href="http://pipes.yahoo.com/pipes/pipe.info?_id=02bfefe73ba14054570ce82f1929e433">pipes</a> website to relay an RSS feed from github. I then configured my IRC bot to check that RSS and report it (I also changed the IRC colours to match the GitHub-announcer ones).</li>
|
||
<li>Mailing list and blog haven&#x27;t changed, so those are still handled via RSS as before.</li>
|
||
</ul>
|
||
<p>All this done, the modified IRC announcement works well.</p>
|
||
<h3>Closing the book on Google Code</h3>
|
||
<p>At this point all the critical things were moved over. So after some heads-up warnings on the mailing list (and users helping to rewrite our documentation to use Git instead of mercurial) we eventually made the official move.</p>
|
||
<p>One thing I really dislike is when a project switches hosts and don&#x27;t let users know about it in their revision history. So I made a mercurial-only last commit announcing that the repo is closed and giving the link to the new one.</p>
|
||
<p>The Google Code page doesn&#x27;t go anywhere, but I changed the front page to point to GitHub instead. I even made an issue in the Issue tracker with a title telling people not to use that tracker anymore. Finally I re-pointed all the links on <a href="http://www.evennia.com/">http://www.evennia.com</a> to GitHub and made a mailing list posting. Move was officially complete.</p>
|
||
<h3>Converting the Wiki, part 2</h3>
|
||
<p>At this point were were officially moved over and I started to look into getting fancy with our documentation. We have for the longest time made automated translations of our wiki for compiling by <a href="https://readthedocs.org/projects/evennia/">ReadTheDocs</a>.</p>
|
||
<p>Getting Google Code&#x27;s special wikimedia syntax into reST (that ReadTheDocs uses) used to mean jumping through a few hoops. My hackish solution worked in two steps. First a custom python script (whose originating url I can no longer find, sorry) converted the Google Code wiki to HTML. Once this was done, <a href="http://johnmacfarlane.net/pandoc/">pandoc</a> converted the files from HTML to reST. The result was ... acceptable. There were some minor issues here and there but mostly the result was readable.</p>
|
||
<p>I figured that converting from the more standard Markdown of the GitHub wiki to reST should be a breeze by comparison. Not so.</p>
|
||
<p>The first hurdle was that the version of pandoc coming with my Linux distribution was too old to support Github-flavoured markdown syntax. I knew from before that Pandoc worked so I didn&#x27;t want to start with something else. I had to download the several hundred MBs needed by the Haskell build environment and their package manager in order to get and compile all the dependencies and finally the latest version of pandoc. To their credit it was all a very streamlined experience, it just took quite some time.</p>
|
||
<p>The second hurdle came when finally looping pandoc to convert all wiki files. It turns out to be that the [[Text on page|address]] syntax I had manually corrected earlier is a special syntax offered by <em>Gollum,</em> the engine powering GitHub&#x27;s wiki behind the scenes. None of the markdown-to-reSt converters I looked at (pandoc or otherwise) even recognized this syntax as a link at all. As it turns out, normal markdown actually expects its links in the format <a href="address">Text on page</a>.</p>
|
||
<p>I was not going to go through and edit all those pages <em>again.</em> So my next step was to write a script to scan and replace all the [[...|...]] syntax in our wiki and replace it with the standard markdown one. After this the markdown files converted to reST quite nicely -- formatting-wise they look much better than the old wiki to HTML to reST chain I had to use from Google Code.</p>
|
||
<p>Problem was that when compiling these reST pages into HTML with Sphinx, no links worked.</p>
|
||
<p>Each individual page looked okay, just that the links were not pointing to anything reasonable. In retrospect this was not so strange. Pandoc knows nothing about the relationships between files, and clearly the simple naming scheme used for addresses is something the wiki softwares knows and Sphinx does not.</p>
|
||
<p>Some thinking lead to a custom Python script for renaming the link targets in the converted pages to their html page name. This needed to handle the fact that wiki links also allows whitespace. So the [Start](Getting Started) link would be converted to <a href="GettingStarted.html">Start</a>, which seems to be the format with which Sphinx will generate its pages.</p>
|
||
<p>One also needs to have a &quot;toc&quot; (Table of Contents) to tie all those pages together for the benefit of Sphinx. I just used a &quot;hidden&quot; toc, letting my converter script add this to the bottom of my normal index file. As long as it&#x27;s included <em>somewhere,</em> Sphinx will be happy.</p>
|
||
<p>Originally I put the reST files in a subfolder of the GitHub wiki repo, I thought I could just point ReadTheDocs to that repo later. The GitHub wiki has a strange &quot;feature&quot; though. It seems to pick its wiki pages from <em>wherever</em> they are in the repo, no matter if they are in the root or in subfolders. Suddenly I was starting to see reST-style pages appear in the online wiki, and sometimes I would get the markdown version (the two would go out of sync). Very strange and confusing.</p>
|
||
<p>Since the files clearly &quot;polluted&quot; our wiki, I had to move the converted reST files to a separate branch of the wiki repository. This has the advantage of keeping all the support scripts and converter mechanisms separate from the normal wiki content. ReadTheDocs can luckily be set to read its information from another branch than master, so finally the latest converted wiki can again be read there!</p>
|
||
<p>That concludes what I think was the last main conversion effort. Phew!</p>
|
||
<h3>Impressions so far</h3>
|
||
<p>GitHub is nice. The merge requests and easy way to comment on them are really good. Since people are more familiar with using GitHub overall, it does seem to be a shorter step for people to make a fork and contribute small things. Doing the same in Google Code was probably not harder per se, just something less people were previously familiar with.</p>
|
||
<p>Due to the modular way Evennia is structured, people are recommended to make a fresh clone of the new Git repo and simply copy their plugin source files and database back into it. So far this seems to have gone smoothly.</p>
|
||
<p>The GitHub issue tracker is worse than the Google Code one. It has no good way to order Issues or list them in a more compact form (nor in a matrix). Not having good issue templates is really limiting; having to reply to issues only to ask for basic info they should include in their issue is an unnecessary time sink.</p>
|
||
<p>I also find that there is no clear way to announce an issue change (like &quot;Needing more information&quot;). Tags work partly for this, but setting them is not announced anywhere as far as I can tell - they are just there.</p>
|
||
<p>Most things also takes so much spaaace. Overall GitHub seems designed for people with big monitors. I have those, but most of the time I prefer working on my laptop. I&#x27;m sure it&#x27;s a matter of habit, but Google Code is very compact by comparison. It gave a lot better overview of things. On GitHub I have to scroll everywhere and this is true both in the repo view, wiki and issues.</p>
|
||
<p>These small quips nonwithstanding, I think this move will serve us well. There is a good wibe of development and continuing improvement going on at GitHub. There&#x27;s plenty of help and tutorials all over. Since so many people are using GitHub, problems are more likely to have been answered before. And of course we hope this will in effect help more people find Evennia and join the fun.</p>
|
||
</description><author>Griatch</author><pubDate>Sat, 08 Feb 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-02-08-moving-from-google-code-to-github</guid></item><item><title>Looking forwards and backwards</title><link>2014.html#2014-01-24-looking-forwards-and-backwards</link><description><p><a href="https://2.bp.blogspot.com/-wjnGsBNyUqg/UuLtTZAo_II/AAAAAAAACJE/vYvxUE0zIpw/s1600/1390625062_binoculars.png"><img src="https://2.bp.blogspot.com/-wjnGsBNyUqg/UuLtTZAo_II/AAAAAAAACJE/vYvxUE0zIpw/s1600/1390625062_binoculars.png" alt="" /></a></p>
|
||
<p>We are almost a month into the new year, time to look forward.</p>
|
||
<p>But first a look backwards. The year of 2013 was a year of big development projects and lots of quiet in the main repository in between. Two major updates were released during the year.</p>
|
||
<p>The first update, the &quot;many sessions per player&quot; update, originated in a feature request that I thought would be easy to implement but which led to far-ranging changes (and honestly, improvements) to how Players and Sessions interconnect. It was a <em>lot</em> more more work than I anticipated.</p>
|
||
<p>The second update was about moving Evennia&#x27;s web server from the Portal level into the Server-level. The actual moving of the server was actually considerably easier than I thought it would be. But it turned out that a truckload of other things came along with it. Not only did the cache system have to change in order to accommodate the new webs erver, I had to also finalize the Out-of-band structure, since this made use of the cache system. And while I were at it, other fixes were done and ... the update grew and grew. When it finally merged late last year it closed plenty of issues, but it would probably have been better to structure it into more, small updates instead.</p>
|
||
<p>Anyway, 2014 promises continued (and hopefully more continuous and gradual) development of Evennia. The closest upcoming upheaval is our move from Google Code to GitHub in a few days (I&#x27;ll probably do a blog about that once it&#x27;s done). Apart from that we are currently in a fixing state, cleaning up and fixing remnant issues from the big mergers.</p>
|
||
<p>Another Issue of the MUD e-zine <a href="http://journal.imaginary-realities.com/volume-05/issue-01/index.html">Imaginary Realities</a> is coming too. I just contributed with an Evennia-related article. If anyone reading this blog has anything MUD-related to write about, do consider <a href="http://posted-stuff.blogspot.se/2013/12/write-article-for-imaginary-realities.html">contributing</a> before January 31, they need more articles! I don&#x27;t think you need to be too advanced, anything from a mud-development anecdote to retells of good MUD gaming memories might be interesting I would think.</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 24 Jan 2014 00:00:00 GMT</pubDate><guid isPermaLink="true">2014.html#2014-01-24-looking-forwards-and-backwards</guid></item><item><title>Imaginary Realities is back</title><link>2013.html#2013-12-16-imaginary-realities-is-back</link><description><p><a href="http://imaginary-realities.disinterest.org/pics/logo_new.gif"><img src="https://lh4.googleusercontent.com/proxy/CEw97RBnw7FiR_z7fqlj9ELtwgDU-knwkyiW8Ybjg9tjTUAerwxQ0-omUEwpZAz4jKP1ozmnCLHPBh1A4QxrGZzYD3DEFfIdTReu0TTPJwo=s0-d" alt="" /></a>The <em><a href="http://imaginary-realities.disinterest.org/">Imaginariy Realities</a></em> webzine was the place to go to for MUD game design articles in the late 90&#x27;s. Last released in 2001, its articles are still worth the read for any game designers today.</p>
|
||
<p>But guess what - this venerable ezine has now returned! You can find the new issue <a href="http://journal.imaginary-realities.com/volume-05/issue-01/index.html">here</a>.</p>
|
||
<p>I think this is a good community initiative worthy of support. I contibuted two articles myself (one of which is about Evennia) and would like to thank the staff/editors who took their work very seriously and did sterling work on getting everything in shape.</p>
|
||
<p>Thanks also to the other authors who penned some very interesting articles. Great job guys!</p>
|
||
<p>My impressions:</p>
|
||
<ul>
|
||
<li>KaVir elaborates in <em>A modern interface for a modern MUD</em> on the advantages of not sticking with an outdated UI just for the sake of it. Adding a more accessible presentation is not that hard and won&#x27;t ruin your game but rather help it. Whereas I have read his argument about this before, this is a good summary to take to heart. Evennia&#x27;s javascript web client is currently mainly a telnet clone; there&#x27;s a lot of things we could offer to make it easier for users to offer a more graphical presentation.</li>
|
||
<li>Molly O’Hara, in her <em>A well built zone is a work of art,</em> outlines a list of useful things to keep in mind when designing a zone. While some of these vary with game type, others do not. I like the suggestion that scripting bugs need not be the most important aspect - syntactic errors can be handled by automated means as long as the design aspect of the zone is solid.</li>
|
||
<li><em>A journey through Paradice</em> [sic] is Matthew Chaplain&#x27;s entry on designing a dice-roller using the telnet protocol. Some interesting things here, including making creative use of the telnet character-mode and VT100 control sequences. This ties a bit into KaVir&#x27;s article, in that the interface used for &quot;modern&quot; MUDs are often voefully missing out on a lot of possibilities.</li>
|
||
<li><em>Blind accessibility: challenges and opportunities</em> by Matthew “Chaos” Sheahan, is based on interviews with a blind mudder and a game admin having implemented lots of support for seeing-impaired players. This was a really interesting article since I&#x27;ve been pondering myself what could be done from Evennia&#x27;s core side to help players support players using screen readers. Most seem to be down to configuration options though, and avoiding making colour or ascii art the only sources of information. These are all things Evennia devs implement depend on their game. We may offer some good contribs to build from though.</li>
|
||
<li><em>Evennia: an introduction -</em> this is mine. It not-so-briefly sums up stuff about Evennia and the more important systems it relies on.</li>
|
||
<li><em>Getting a roleplaying scene going</em> - another article of mine. This is a light-hearted list of tropes for getting a RP scene going on an RP-mud. It&#x27;s based on things I&#x27;ve tried or seen myself in play.</li>
|
||
<li>Darcie “Natilena” Laur laments on the often opaque newbie guides in <em>Introducing new players and redesigning MUD School.</em> It describes how she tested (and improved) her own MUD&#x27;s starter area while testing it on her kids. It made me think more on having Evennia offering easier ways to dump text logs in all sorts of situations. And we find out that kids have the attention span of zombie squirrels - something new learned every day!</li>
|
||
<li>Finally, <em>The Hunger Game, or how I learned to break the ship from the bottle</em> is Michael “Drakkos” Heron&#x27;s epic about his journey developing and releasing his zombie-survival MUD <em>Epitaph.</em> Drakkos is a frequent blogger on the MUD-planet feed, so I knew some of this already, but it&#x27;s a good read and contains some useful warnings and things-to-think-of for those thinking of starting their own MUD project. We already give some of the same advice (albeit with fewer words) in our wiki but I&#x27;m seriously considering linking to Drakkos post from there as well - it gives a more comprehensive treatment and offers a real-world example of the long road to a released game.</li>
|
||
</ul>
|
||
<p>The issue also contains a call to help recover old MUDing resources that has gone offline since their heyday. Having browsed through the classic MUD-dev mailing list archives I can agree they are not quite as easily searchable as could be hoped. It would also be great to see the old comment posts tied to the articles of the old <em>Imaginary Realities</em> articles, if those could be found somehow.</p>
|
||
<p>This is actually one thing which I do miss with this first Imaginary Realities issue - a way for readers to comment on the articles. This would likely mean a much higher level of complexity and work though, so I can certainly see why it&#x27;s not there - using the existing MUD forums is probably enough for now.</p>
|
||
<p>Anyway, I&#x27;m happy to see this thing getting off on a good start. I&#x27;m already looking forward to the next issue!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 16 Dec 2013 00:00:00 GMT</pubDate><guid isPermaLink="true">2013.html#2013-12-16-imaginary-realities-is-back</guid></item><item><title>Out of band mergings</title><link>2013.html#2013-11-28-out-of-band-mergings</link><description><p><a href="https://4.bp.blogspot.com/-RcZi6McnLtc/Upd90AEpnTI/AAAAAAAACHA/ALGE2Ompi6k/s1600/FS-0609-Merger-1.jpg"><img src="https://4.bp.blogspot.com/-RcZi6McnLtc/Upd90AEpnTI/AAAAAAAACHA/ALGE2Ompi6k/s200/FS-0609-Merger-1.jpg" alt="" /></a></p>
|
||
<p>As of today the development repository of Evennia, which has been brewing for a few months now, merged into the main repository. This update grew from one experimental feature to a relatively big update in the end. Together with the &quot;many-character-per-player&quot; feature released earlier, this update covers all the stuff I talked about in my <a href="http://evennia.blogspot.se/2013/01/churning-behind-scenes.html">Behind the Scenes</a> blog post.</p>
|
||
<ul>
|
||
<li>Evennia&#x27;s webserver was moved from <em>Portal</em> to <em>Server</em>. This moves all database-modifying operations into the same process and neatly avoids race conditions when modifying a game world from various interfaces.</li>
|
||
<li>The OOB (Out Of Band) handler was implemented. This goes together with a protocol for telnet sub-negotiations according to the <a href="http://tintin.sourceforge.net/msdp/">MSDP</a> specification. The handler allows on-demand reporting whenever database fields update. It also offers regular polling of properties if needed. A user can customize which oob commands are available to the client and write whatever handlers are needed for their particular game. In the future we&#x27;ll also add support for GMCP, but the lack of a central, official specification is off-putting (if there is a central document besides accounts of how individual games chose to implement GMCP, please let me know). For our own included web client, we&#x27;ll likely just use JSON straight off.</li>
|
||
<li>Our channel system is now <em>typeclassed</em>. If you are not familiar with Evennia this won&#x27;t mean much to you - In short it means developers will be able to customize their channel system much easier than in the past since a channel can be treated pretty much like any Python class (thanks go to user Kelketek who actually did the implementation).</li>
|
||
<li>We added the concept of <em>Tagging</em>, as a more generalized version of our old <em>Alias</em> system. Tagging is just what it sounds like - it allows you to tag all your objects in order to group them and easily (and efficiently) find them later. Tagging offers a powerful way to create what other code bases refer to as &quot;zones&quot;. There are many other possible uses though, such as having effects appear only in certainly tagged rooms, indicate which Characters have joined a particular guild and so on.</li>
|
||
<li>Behind the scenes there were a lot of cleanups, along with minor API changes mentioned on the mailing list. A slew of older Issues were also fixed with this merge.</li>
|
||
</ul>
|
||
<p>Now, in the immediate future we&#x27;ll be working on updating the documentation. Evennia prides itself with having a large body of documentation and this update comes with small changes to various existing systems. There are also a few bigger new features (such as OOB). No doubt the near future will also see other issues popping up as more people try things out.</p>
|
||
<h4>Imaginary Realities update</h4>
|
||
<p>Apparently the reboot of <em>Imaginary Realities</em> (to which I contribute two articles) has been <a href="http://posted-stuff.blogspot.se/2013/11/imaginary-realities-update_15.html">pushed forward a week or two</a>. Reason being, apparently, to finalize the actual presentation of the content. I already signed off on the last editorial fixes way before deadline, so I guess it&#x27;s just to wait and see what comes of it!</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 28 Nov 2013 00:00:00 GMT</pubDate><guid isPermaLink="true">2013.html#2013-11-28-out-of-band-mergings</guid></item><item><title>A list of Evennia topics</title><link>2013.html#2013-10-22-a-list-of-evennia-topics</link><description><p><a href="https://4.bp.blogspot.com/-WXVxxb06XBA/UmZ_5TSzmrI/AAAAAAAACE4/NbBAjohOi6E/s1600/building-blocks.jpg"><img src="https://4.bp.blogspot.com/-WXVxxb06XBA/UmZ_5TSzmrI/AAAAAAAACE4/NbBAjohOi6E/s1600/building-blocks.jpg" alt="" /></a></p>
|
||
<p>Some Evennia updates.</p>
|
||
<h2>Development</h2>
|
||
<p>Lots of work has been happening in the <a href="http://code.google.com/r/griatch-evennia-dev/source/list">dev-clone</a> of Evennia over the last few months.<br />
|
||
As alluded to in the last blog, the main work has been to move Evennia&#x27;s webserver component into the <em>Server</em>-half of Evennia for various reasons, the most obvious one to make sure that all database writes happen in the same process, avoiding race conditions. But this move lead to a rework of the cache system, which in turn lead to me having to finalize the plans for how Out-of-Band protocols should be implemented server-side. And once that was finalized, OOB was pretty much implemented anyway. As part of making sure OOB trackers were updated correctly at all times meant reworking some of the ways data is stored ... So one thing led to another making this a bigger update than originally planned.</p>
|
||
<p>I plan to make a more detailed post to the <a href="https://groups.google.com/forum/#%21forum/evennia">mailing list</a> soon with more technical details of the (relatively minor) API changes existing users should expect. The merging of the clone into the main repo is still a little way off, but adventurous users have already started testing things.</p>
|
||
<h2>Google Code</h2>
|
||
<p>I like Google Code. It&#x27;s easy to manage and maintain, it has a good wiki and Issue system, not to mention that it allows the use of Mercurial. But in the beginning of September, suddenly all links to our user&#x27;s clone repositories were <em>gone</em> from the front of the project page_._ Not only that, creating new clones just didn&#x27;t work anymore.<br />
|
||
Now any site can have bugs, and we made an <a href="http://code.google.com/p/support/issues/detail?id=30989">issue</a> for it (other projects were similarly affected). But nothing happened for the longest time - at least two months given that we didn&#x27;t report it right away. Just recently the functionality came back but there is no confirmation or comments from Google (our issue is not even closed).<br />
|
||
That such a fundamental feature can go unheeded for so long is disturbing to me, driving home the fact that Google is certainly not putting much priority in their code hosting.</p>
|
||
<h2>Community</h2>
|
||
<p>Some furious activity in the <a href="http://webchat.freenode.net/?channels=evennia&amp;uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC chat</a> lately, with new people dropping in to chat and ask about Evennia. For example, an enthusiastic new user learned not only about Evennia but also Python for the first time. It was a lot of fun to see him go from having <em>no programming experience except</em> <em>mush softcode</em> to doing advanced Evennia system implementations in the course of a week and offering good feedback on new features in two. Good show! The freedom you get upgrading from something like softcode to Evennia&#x27;s use of a full modern programming language was seemingly quite eye-opening.</p>
|
||
<p>Other discussions have concerned the policies around using clones/branches for development as well as the benefits of some other hosting solution. Nothing has been decided on this. There is however now also an official GitHub mirror of Evennia&#x27;s main repo to be found <a href="https://github.com/Evennia/evennia">here</a>.</p>
|
||
<h2>Imaginary Realities</h2>
|
||
<p>The deadline for entering articles for the <em>Imaginary Realities</em> web zine <a href="http://posted-stuff.blogspot.se/2013/10/imaginary-realities-update.html">reboot</a> has passed. It&#x27;s a good initiative to bring this back - the <a href="http://en.wikipedia.org/wiki/Imaginary_Realities">original (archived) webzine</a> remains a useful mud-creation resource to this day. I entered two articles, one about Evennia and another about general mud-roleplaying. It will be fun to see how it comes out, apparently the first issue will appear Nov 13</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 22 Oct 2013 00:00:00 GMT</pubDate><guid isPermaLink="true">2013.html#2013-10-22-a-list-of-evennia-topics</guid></item><item><title>One to Many</title><link>2013.html#2013-05-13-one-to-many</link><description><p><a href="https://4.bp.blogspot.com/-M_YNUYvWuiw/UZCNa-U24lI/AAAAAAAAB2o/6wZzFjpCSvk/s1600/one-in-many.jpg"><img src="https://4.bp.blogspot.com/-M_YNUYvWuiw/UZCNa-U24lI/AAAAAAAAB2o/6wZzFjpCSvk/s320/one-in-many.jpg" alt="" /></a></p>
|
||
<p>As of yesterday, I completed and merged the first of the three upcoming Evennia features I mentioned in my <a href="http://evennia.blogspot.se/2013/01/churning-behind-scenes.html">Churning Behind the Scenes</a> blog post: the &quot;Multiple Characters per Player&quot; feature.</p>
|
||
<p>Evennia makes a strict division between <em>Player</em> (this is an object storing login-info and represents the person connecting to the game) and their <em>Character</em> (their representation in-game; Characters are just Objects with some nice defaults). When you log into the game with a client, a <em>Session</em> tracks that particular connection.</p>
|
||
<p>Previously the Player class would normally only handle one Session at a time. This made for an easy implementation and this behavior is quite familiar to users of many other mud code bases. There was an option to allow more than one Session, but each were then treated equally: all Sessions would see the same returns and the same in-game entities were controlled by all (and giving the quit command from one would kick all out).</p>
|
||
<p>What changed now is that the Player class will manage each Session separately, without interfering with other Sessions connected to the same Player. Each Session can be connected, through the Player, to an individual Character. So multiple Characters could in principle be controlled simultaneously by the same real-world player using different open mud clients. This gives a lot of flexibility for games supporting multi-play but also as a nice way to transparently puppet temporary extras in heavy roleplaying games.</p>
|
||
<p>It is still possible to force Evennia to accept only one Session per Player just like before, but this is now an option, not a limitation. And even in hardcore one-character-at-a-time roleplaying games it is nice for builders and admins to be able to have separate staff or npc characters without needing a separate account for each.</p>
|
||
<p>This feature took a lot more work than I anticipated - it consitutes a lot of under-the-hood changes. But it also gave me ample opportunity to fix and clean up older systems and fix bugs. The outcome is more consistency and standardization in several places. There are plenty of other noteworthy changes that were made along the way in the dev branch along with some API changes users should be aware of.<br />
|
||
So if you are an Evennia game developer you should peek at the more detailed mailing list <a href="https://groups.google.com/forum/#%21topic/evennia/EjAW8S2N86I">announcement</a> on what has changed. The wiki is not updated yet, that will come soon.</p>
|
||
<p>Now onward to the next feature!</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 13 May 2013 00:00:00 GMT</pubDate><guid isPermaLink="true">2013.html#2013-05-13-one-to-many</guid></item><item><title>Churning behind the scenes</title><link>2013.html#2013-01-29-churning-behind-the-scenes</link><description><p><a href="https://1.bp.blogspot.com/-kMcLTjgmpa0/UQfBh7FsD7I/AAAAAAAABys/uGhAhtwG22s/s1600/red_curtain_hand3crop_category.jpg"><img src="https://1.bp.blogspot.com/-kMcLTjgmpa0/UQfBh7FsD7I/AAAAAAAABys/uGhAhtwG22s/s200/red_curtain_hand3crop_category.jpg" alt="" /></a></p>
|
||
<p>At the moment there are several Evennia projects churning along behind the scenes, none of which I&#x27;ve yet gotten to the point of pushing into a finished state. Apart from bug fixes and other minor things happening, these are the main updates in the pipeline at the moment.</p>
|
||
<h3>Multiple Characters per Player/Session</h3>
|
||
<p>Evennia has for a long time enforced a clean separation between the <em>Player</em> and the <em>Character.</em> It&#x27;s a much appreciated feature among our users. The <em>Player</em> is &quot;you&quot;, the human playing the game. It knows your password, eventual user profile etc. The <em>Character</em> is your avatar in-game. This setup makes it easy for a Player to have many characters, and to &quot;puppet&quot; characters - all you need to do is &quot;disconnect&quot; the Player object from the Character object, then connect to another Character object (assuming you are allowed to puppet that object, obviously). So far so good.</p>
|
||
<p>What Evennia currently <em>doesn&#x27;t</em> support is being logged in with <em>different</em> client sessions to the <em>same</em> Player/account while puppeting <em>multiple</em> characters <em>at the same time.</em> Currently multiple client sessions may log into the same Player account, but they will then all just act as separate views of the same action (all will see the same output, you can send commands from each but they will end up with the same Character).</p>
|
||
<p>Allowing each session to control a separate Character suggests changing the way the session is tracked by the player and Character. This turns out to be more work than I originally envisioned when seeing the feature request in the issue tracker. But if my plan works out it will indeed become quite easy to use Evennia to both allow multi-play or not as you please, without having to remember separate passwords for each Character/account.</p>
|
||
<h3>Webserver change to Server level</h3>
|
||
<p>Evennia consists of two main processes, the <em>Portal</em> and the <em>Server.</em> The details of those were covered in an earlier blog post <a href="http://evennia.blogspot.se/2012/08/combining-twisted-and-django.html">here</a>. Evennia comes with a Twisted-based webserver which is currently operating on the <em>Portal</em> level. This has the advantage of not being affected by Server-reboots. The drawback is however that being in a different process from the main Server, accessing the database and notably its server-side caches becomes a problem - changing the database from the Portal side does not automatically update the caches on the Server side, telling them that the database has changed. Also writing to the database from two processes may introduce race conditions.</p>
|
||
<p>For our simple default setup (like a website just listing some database statistics) this is not a terrible problem, but as more users start to use Evennia, there is a growing interest in more advanced uses of the webserver. Several developers want to use the webserver to build game-related rich website experiences for their games - online character generation, tie-in forums and things like that. Out-of-sync caches then becomes a real concern.</p>
|
||
<p>One way around this could be to implement a framework (such as memcached) for homogenizing caches across all Evennia processes. After lots of IRC discussions I&#x27;m going with what seems to be the more elegant and clean solution though - moving the webserver into the <em>Server</em> process altogether. The <em>Portal</em> side will thus only hold a web proxy and the webclient protocol. This way all database access will happen from the same process simplifying things a lot. It will make it much easier for users to use django to create rich web experiences without having to worry about pesky behind the scenes things like caches and the like.</p>
|
||
<h3>Out-of-band communication</h3>
|
||
<p>This has been &quot;brewing&quot; for quite some time, I&#x27;ve been strangely unmotivated to finalize it. Out of band communication means the MUD client can send and receive data to/from the server directly, without the player having to necessesarily enter an active command or see any immediate effect. This could be things like updating a health bar in a client-side GUI, redirect text to a specific client window but also potentially more advanced stuff. I created the Evennia-side oob-handler over Christmas; it allows for client sessions to &quot;sign up&quot; for &quot;listening&quot; to attribute updates, do scheduled checks and so on. It&#x27;s already in the codebase but is not activated nor tested yet.</p>
|
||
<p>On the protocol side (for serializing data to the client) I have a MSDP implementation ready for telnet subnegotiation, it should be simple to add also GMCP once everything is tested. A JSON-based side channel for the webclient is already in place since a long time if I remember correctly, it just need to be connected to the server-side oob-handler once that&#x27;s finished.</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 29 Jan 2013 00:00:00 GMT</pubDate><guid isPermaLink="true">2013.html#2013-01-29-churning-behind-the-scenes</guid></item><item><title>Evennia changes to BSD license</title><link>2012.html#2012-10-28-evennia-changes-to-bsd-license</link><description><p><a href="https://4.bp.blogspot.com/-mFTXyssJj3Y/UI1NUnfYb-I/AAAAAAAABxs/2yJAilrx3j0/s1600/open+neon+95n.jpg"><img src="https://4.bp.blogspot.com/-mFTXyssJj3Y/UI1NUnfYb-I/AAAAAAAABxs/2yJAilrx3j0/s200/open+neon+95n.jpg" alt="" /></a>As of today, <a href="http://www.evennia.com/">Evennia</a> changes to use the very permissive <a href="http://opensource.org/licenses/BSD-3-Clause">BSD license.</a></p>
|
||
<p>Now, our previous &quot;Artistic License&quot; was also very friendly. One main feature was that it made sure that changes people made to the core Evennia library (i.e. not the game-specific files) were also made available for possible inclusion upstream. A good notion perhaps, but the licensing text was also quite long and it was clear some newcomers parsed it as more restrictive than it actually was.</p>
|
||
<p>... And let&#x27;s be honest, it&#x27;s not like I would have come hunting down anyone not complying fully with the Artistic license&#x27;s terms. Changing to the much simpler and more well-known BSD license better clarifies the actual licensing situation.</p>
|
||
<p>After all, far too many older MUD-code bases are weighted by a legacy of licensing issues. Anything we can do to avoid this is better in the long run. Indeed we hope this change in licensing will remove eventual licensing doubts for new adopters and have more people join and contribute to the project.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 28 Oct 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-10-28-evennia-changes-to-bsd-license</guid></item><item><title>Community interest</title><link>2012.html#2012-10-05-community-interest</link><description><p><a href="https://2.bp.blogspot.com/-ETdBSHZJeKM/UG67GMElKvI/AAAAAAAABxI/J-PZhdCZDhU/s1600/800px-Billard.JPG"><img src="https://2.bp.blogspot.com/-ETdBSHZJeKM/UG67GMElKvI/AAAAAAAABxI/J-PZhdCZDhU/s320/800px-Billard.JPG" alt="" /></a></p>
|
||
<p>It&#x27;s fun to see a growing level of activity in the Evennia community. The last few months have seen an increase in the number of people showing up in our <a href="http://webchat.freenode.net/?channels=evennia">IRC</a> channel and mailing list. With this has come a slew of interesting ideas, projects and MUD-related discussion (as well as a few inevitable excursions into interesting but very non-mud-related territory - sorry to those reading our chat logs).</p>
|
||
<p>One sign of more people starting to actually use Evennia &quot;for real&quot; is how the number of bugs/feature requests have been increasing. These are sometimes issues related to new things being implemented but also features that have been there for some time and which people are now wanting to use in new and creative ways - or systems which noone has yet really used &quot;seriously&quot; before. This is very encouraging, especially since a lot of good alternative solutions, variations and edge cases can be ironed out this way. So keep submitting those Issues, people!</p>
|
||
<p>The budding Evennia community consists of people with a wide variety of interests, skillset and ambition.</p>
|
||
<p>There are quite a few people who sees Evennia as a great stepping stone for learning Python, or for getting experience with creating a bigger programming project in general. Some are skilled programmers in other languages but we also have a few with only limited prior coding experience. From the experience in chat, it&#x27;s really quite striking how fast members pick up the ropes. I&#x27;d like to think our documentation is at least partially helping here, but of course it helps that Python is inherently very easy a language to learn and use in the first place.<br />
|
||
Not all are participating with the goal of building a specific game. The general flow of patches and clone repository merges have also picked up. We have some users which are primarily interested in a coding challenge, to help with fixing bugs and features, or which uses Evennia as a starting point for exploring various web- and technical solutions that may or may not be a part of Evennia in the future.</p>
|
||
<p>The proposed Evennia game projects are just as varied as its users - and none are yet open to the public. As is common with these things, it&#x27;s of course hard to determine who actually has the time and discipline to bring their plans to fruition. But I should really start to keep some sort of record of who works on what, I&#x27;m terrible with remembering this stuff ... so below is just some sort of summary of my impressions, not a comprehensive listing.</p>
|
||
<p>As can be expected, most proposed Evennia projects concern relatively standard MUD-style games. A few people are into building traditional hack-and-slash variety games, but most want to expand on the concept considerably. There was even one user exploring using Evennia for a RobotWars kind of experience (where you &quot;program&quot; robot programs in a custom language and battle them). Another project (<em>Avaloria,</em> also blogging on the <a href="http://planet-muddev.disinterest.org/">MUD-dev</a> rss feed) aims for a sort of base-building/strategy mechanic combined with more traditional MUD elements. There are at least two zombie-survival concepts floating around and a few large-scale procedural-content-driven science-fiction text games. One user has apparently a working Smaug-&gt;Evennia importer.</p>
|
||
<p>It seems that most Evennia users want to offer some sort of roleplaying environment, or at least a &quot;roleplay-friendly&quot; one. Currently we have at least two MUCK admins who aim to convert their existing, running games to Evennia. Whereas the initial idea was to implement parsers for MUCK&#x27;s MUF language, it seems the conclusion has now shifted to it being faster and easier to just rewrite the MUF-coded functionality in Python (and maybe use something like <a href="http://evennia.blogspot.se/2012/06/coding-from-inside.html">Evlang</a> for player scripting instead). Several people have announced their interest in creating &quot;RPI&quot;-style games (<em>Armageddon</em> seems to be a big inspiration here), but there was also a MOO admin and even a writer of Interactive Fiction who dropped into the mailing list to see if Evennia could be used for their style of game.</p>
|
||
<p>How many of these projects actually reach a point of maturity remains to be seen. But that people are wanting to use the system and is really putting it through its paces is encouraging and very helpful for general Evennia development.</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 05 Oct 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-10-05-community-interest</guid></item><item><title>Combining Twisted and Django</title><link>2012.html#2012-08-31-combining-twisted-and-django</link><description><h3><a href="https://evennia.blogspot.com/2012/08/combining-twisted-and-django.html">Combining Twisted and Django</a></h3>
|
||
<p><a href="https://3.bp.blogspot.com/-Spum6fodLn0/TqPvuMp20mI/AAAAAAAAAIc/LteJztyYZXY/s1600/DJango.jpg"><img src="https://3.bp.blogspot.com/-Spum6fodLn0/TqPvuMp20mI/AAAAAAAAAIc/LteJztyYZXY/s320/DJango.jpg" alt="" /></a></p>
|
||
<p>Newcomers to Evennia sometimes misunderstand it as being a &quot;Django mud codebase somehow using Twisted&quot;. The correct description is rather that Evennia is a &quot;Twisted-based mud server using Django&quot;. Allow me to elaborate.</p>
|
||
<p>A mud/mux/moo/mu* is per definition a multi-user online game system. All these users need to co-exist on the server. If one player does something, other players shouldn&#x27;t have to (noticeably) wait for that something to end before they can do anything. Furthermore it&#x27;s important for the database schema to be easy to handle and upgrade. Finally, in a modern game, internet presence and web browser access is becoming a must. We combine two frameworks to achieve this.</p>
|
||
<h3>Two frameworks combined</h3>
|
||
<p><em><a href="http://twistedmatrix.com/trac/">Twisted</a></em> is a asynchronous Python framework. &quot;Asynchronous&quot; in this context means, very simplified, that Twisted chops up code execution into as small bits as the code lets it. It then flips through these snippets rapidly, executing each in turn. The result is the illusion of everything happening at the same time. The asynchronous operation is the basis for the framework, but it also helps that twisted makes it easy to support (and create) a massive range of different network protocols.</p>
|
||
<p><em><a href="https://www.djangoproject.com/">Django</a></em> implements a very nice abstract Python API for accessing a variety of SQL-like databases. It makes it very convenient to maintain the database schema (not to mention that <em>django-South</em> gives us easy database migrations). The fact that Django is really a web framework also makes it easy to offer various web features. There is for example an &quot;admin site&quot; that comes with Django. It allows to modify the database graphically (in Evennia&#x27;s case the admin site is not quite as polished as we would like yet, but it&#x27;s coming).</p>
|
||
<p>Here are some highlights of our architecture:</p>
|
||
<ul>
|
||
<li><em>Portal</em> - This is a stand-alone Twisted process talking to the outside world. It implements a range of communication protocols, such as telnet (traditional in MUD-world), ssh, ssl, a comet webclient and others. It is an auto-connecting client to <em>Server</em> (below).</li>
|
||
<li><em>Server</em> - This is the main MUD server. This twisted server handles everything related to the MUD world. It accesses and updates the database through Django models. It makes the world tick. Since all Players connect to the Server through the Portal&#x27;s <a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.protocols.amp.html">AMP</a> connection, it means Server can be restarted without any players getting kicked off the game (they will re-sync from Portal as soon as Server is back up again).</li>
|
||
<li><em>Webserver -</em> Evennia optionally starts its own Twisted webserver. This serves the game&#x27;s website (using the same database as the game for showing game statistics, for example). The website is of course a full Django project, with all the possibilities that entails. The Django <em>admin site</em> allows for modifying the database via a graphical interface.</li>
|
||
<li><em>Webclient -</em> There is a stand-alone MUD web client existing in a page on the default website. This uses Twisted to implement a long-polling (&quot;comet&quot;) connection to a javascript client. As far as Evennia&#x27;s concerned, this is just another outgoing protocol served by the Portal.</li>
|
||
<li><em>Other protocols</em> - Since it&#x27;s easy to add new connectivity, Evennia also offers a bunch of other connectivity options, such as relaying in-game channels to <em>IRC</em> and <em>IMC2</em> as well as <em>RSS</em> feeds and some other goodies.</li>
|
||
</ul>
|
||
<h3>On the joining of the two</h3>
|
||
<p>An important thing to note about Twisted&#x27;s asynchronous model is that there is no magic at work here: Each little snippet of code Twisted loops over <em>is</em> blocking. It&#x27;s just hopefully not blocking long enough for you to notice. So if you were to put <em>sleep(10)</em> in one of those snippets, then congratulations, you just froze the entire server for ten seconds.</p>
|
||
<p>Profiling becomes very important here. Evennia&#x27;s main launcher takes command arguments to run either of its processes under Python&#x27;s cProfile module. It also offers the ability to connect any number of dummy Players doing all sorts of automated random actions on the server. Such profile data is invaluable to know what is a bottleneck and what is not.</p>
|
||
<p>I never found Twisted asynchronous paradigms much harder to understand than other code. But there are sure ways to write stupid blocking code that will come back and bite you. For example, much of Evennia&#x27;s workload is spent in the <em>Server,</em> most notably in its <em>command handler</em>. This is not so strange; the command handler takes care of parsing and executing all input coming from Players, often modifying the game world in various ways (see my previous post for more info about the command handler).<br />
|
||
The command handler used to be a monolithic, single method. This meant that Twisted had to let it run its full course before letting anyone else do their turn. Using Twisted&#x27;s <em><a href="http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks">inlineCallbacks</a></em> instead allowed for yielding at many, many places in this method, giving Twisted ample possibilities to split execution. The effect on multi-user performance was quite impressive. Far from all code can be rewritten like this though.</p>
|
||
<p>Another important bottleneck on asynchronous operations is database operations. Django, as opposed to Twisted, is <em>not</em> an asynchronous framework. Accessing the database <em>is</em> a blocking operation and can be potentially expensive. It was never extremely bad in testing, to be honest. But for large database operations (e.g. many Players) database access was a noticeable effect.</p>
|
||
<p>I have read of some people using Twisted&#x27;s <em>deferToThread</em> to do database writes. The idea sounds reasonable - just offload the operation to another thread and go on your merry way. It did not help us at all though - rather it made things slower. I don&#x27;t know if this is some sort of overhead (or error) in my test implementation - or an effect of Python just not being ideal with using threading for concurrency (due to the GIL). Either way, certain databases like SQlite3 doesn&#x27;t support multiple threads very well anyway, and we prefer to keep giving plenty of options with that. So no <em>deferToThread</em> for database writes. I also did a little testing with parallel processes but found that even slower, at least once the number of writes started to pile up (we will offer easy process-pool offloading for other reasons though).</p>
|
||
<p>As many have found out before us, caching is king here. There is not so much to do about writes, but at least in our case the database is more often read than written to. Caching data and accessing the cache instead of accessing a field is doing much for performance, sometimes a <em>lot.</em> Database access is always going to cost, but it does not dominate the profile. We are now at a point where one of the most expensive single operations a Player (even a Builder) performs during an entire gaming session is the hashing of their password during login. I&#x27;d say that&#x27;s good enough for our use case anyway.</p>
|
||
<h3>Django + MUD?</h3>
|
||
<p>It&#x27;s interesting that whereas Twisted is a pretty natural fit for a Python MUD (I have learned that Twisted was in fact first intended for mudding, long ago), many tend to be intrigued and/or surprised about our use of Django. In the end these are only behind-the-scenes details though. The actual game designer using Evennia don&#x27;t really see any of this. They don&#x27;t really <em>need</em> to know neither Django nor Twisted to code their own dream MUD. It&#x27;s possible the combination fits less for some projects than for others. But at least in our case it has just helped us to offer more features faster and with less headaches.</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 31 Aug 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-08-31-combining-twisted-and-django</guid></item><item><title>Taking command</title><link>2012.html#2012-08-16-taking-command</link><description><p><a href="https://3.bp.blogspot.com/-uODV_t0eTv8/UC0czBg9ctI/AAAAAAAABTk/NvEUkwrrZPY/s1600/200px-Venn0001.svg.png"><img src="https://3.bp.blogspot.com/-uODV_t0eTv8/UC0czBg9ctI/AAAAAAAABTk/NvEUkwrrZPY/s1600/200px-Venn0001.svg.png" alt="" /></a><em>Commands</em> are the bread and butter of any game. Commands are the instructions coming in from the player telling the game (or their avatar in the game) to do stuff. This post will outline the reasoning leading up to Evennia&#x27;s somewhat (I think) non-standard way of handling commands.</p>
|
||
<p>In the case of MUDs and other text games commands usually come in the form of entered text. But clicking on a graphical button or using a joystick is also at some level issuing a command - one way or another the Player instructs the game in a way it understands. In this post I will stick to text commands though. So <em>open door with red key</em> is a potential command.</p>
|
||
<p>Evennia, being a MUD design system, needs to offer a stable and extensive way to handle new and old commands. More than that, we need to allow developers pretty big freedom with developing their own command syntax if they so please (our default is not for everyone). A small hard-coded command set is not an option.</p>
|
||
<h3>Identifying the command</h3>
|
||
<p>First step is <em>identifying</em> the command coming in. When looking at <em>open door with red key</em> it&#x27;s probably <em>open</em> that is the unique command. The other words are &quot;options&quot; to the command, stuff the <em>open</em> command supposedly knows what to do with. If you <em>know</em> already at this stage exactly how the command syntax looks, you could hard-code the parsing already here. In Evennia&#x27;s case that&#x27;s not possible though - we aim to let people define their command syntax as freely as possible. Our identifier actually requires no more than that the uniquely identifying command word (or words) appear <em>first</em> on the input line. It is hard to picture a command syntax where this isn&#x27;t true ... but if so people may freely plug in their own identifyer routine.</p>
|
||
<p>So the identifyer digs out the <em>open</em> command and sends it its options ... but what kind of code object is <em>open</em>?</p>
|
||
<h3>The way to define the command</h3>
|
||
<p>A common variant I&#x27;ve seen in various Python codebases is to implement commands as <em>functions</em>. A function maps intuitively to a command - it can take arguments and it does stuff in return. It is probably more than enough for some types of games.</p>
|
||
<p>Evennia chooses to let the command be defined as a <em>class</em> instead. There are a few reasons. Most predominantly, classes can inherit and require less boiler plate (there are a few more reasons that has to do with storing the results of a command between calls, but that&#x27;s not as commonly useful). Each Evennia command class has two primary methods:</p>
|
||
<ul>
|
||
<li><em>parse()</em> - this is responsible for parsing and splitting up the <em>options</em> part of the command into easy-to use chunks. In the case of <em>open door with red key,</em> it could be as simple as splitting the options into a list of strings. But this may potentially be more complex. A mux-like command, for exampe, takes <em>/switches</em> to control its functionality. They also have a recurring syntax using the &#x27;=&#x27; character to set properties. These components could maybe be parsed into a list <em>switches</em> and two parameters <em>lhs</em> and <em>rhs</em> holding the left- and right hand side of the equation sign.</li>
|
||
<li><em>func()</em> - this takes the chunks of pre-parsed input and actually does stuff with it.</li>
|
||
</ul>
|
||
<p>One of of the good things with executing class instances is that neither of these methods need to have any arguments or returns. They just store the data on their object (<em>self.switches</em>) and the next method can just access them as it pleases. Same is true when the command system instantiates the command. It will set a few useful properties on the command for the programmer to make use of in their code (<em>self.caller</em> always references the one executing the command, for example). This shortcut may sound like a minor thing, but for developers using Evennia to create countless custom commands for their game, it&#x27;s really very nice to not have to have all the input/output boilerplate to remember.</p>
|
||
<p>... And of course, class objects support inheritance. In Evennia&#x27;s default command set the <em>parse()</em> function is only implemented once, all handling all possible permutations of the syntax. Other commands just inherit from it and only needs to implement <em>func().</em> Some advanced build commands just use a parent with an overloaded and slightly expanded <em>parse()</em>.</p>
|
||
<h3>Commands in States</h3>
|
||
<p>So we have individual commands. Just as important is how we now group and access them. The most common way to do this (also used in an older version of Evennia) is to use a simple <em>global list</em>. Whenever a player enters a command, the <em>identifier</em> looks the command up in the list. Every player has access to this list (admin commands check permissions before running). It seems this is what is used in a large amount of code bases and thus obviously works well for many types of games. Where it starts to crack is when it comes to <em>game states.</em></p>
|
||
<ul>
|
||
<li>A first example is an in-game menu. Selecting a menu item means an instruction from the player - i.e. a command. A menu could have numbered options but it might also have named options that vary from menu node to menu node. Each of these are a command name that must be identified by the parser. Should you make <em>all</em> those possible commands globally available to your players at all times? Or do you hide them somehow until the player actually is in a menu? Or do you bypass the command system entirely and write new code only for handling menus...?</li>
|
||
<li>Second example: Picture this scenario: You are walking down a dark hallway, torch in hand. Suddenly your light goes out and you are thrown into darkness. You cannot see anything now, not even to look in your own backpack. How would you handle this in code? Trivially you can put <em>if</em> statements in your <em>look</em> and <em>inventory</em> commands. They check for the &quot;dark&quot; flag. Fair enough. Next you knock your head and goes &#x27;dizzy&#x27;. Suddenly your &quot;navigation&quot; skill is gone and your movement commands may randomly be turned around. Dizziness combined with darkness means your inventory command now returns a strange confused mess. Next you get into a fight ... the number of if statements starts piling up.</li>
|
||
<li>Last example: In the hypothetical FishingMUD,. you have lots of detailed skills for fishing. But different types of fishing rods makes different types of throws (commands) available. Also, they all work differently if you are on a shore as compared to being on a boat. Again, lots of if statements. It&#x27;s all possible to do, but the problem is maintenance; your command body keep growing to handle edge cases. Especially in a MUD, where new features tend to be added gradually over the course of years, this gives lots of possibilities for regressions.</li>
|
||
</ul>
|
||
<p>All of these are examples of situation-dependent (or object-dependent) commands. Let&#x27;s jointly call them <em>state-dependent commands.</em> You could picture handling the in-game menu by somehow dynamically changing the global list of commands available. But then the <em>global</em> bit becomes problematic - not all players are in the same menu at the same time. So you&#x27;ll then have to start to track <em>who</em> has which list of commands available to them. And what happens when a state ends? How do you get back to the previous state - a state which may itself be different from the &quot;default&quot; state (like clearing your dizzy state while still being in darkness)? This means you have to track the previous few states and ...</p>
|
||
<p>A few iterations of such thinking lead to what Evennia now uses: a <em>non-global</em> <em>command set</em> system. A command set (cmdset) is a structure that looks pretty much like a mathematical <em>set.</em> It can contain any number of (unique) command objects, and a particular command can occur in any number of command sets.</p>
|
||
<ul>
|
||
<li>A cmdset stored on an object makes all commands in that cmdset available to the object. So all player characters in the game has a &quot;default cmdset&quot; stored on them with all the common commands like <em>look, get</em> and so on.</li>
|
||
<li>Optionally, an object can make its cmdset available to other objects in the same location instead. This allows for commands only applicable with a given object or location, such as <em>wind up grandfather clock.</em> Or the various commands of different types of fishing rods.</li>
|
||
<li>Cmdsets can be non-destructively combined and merged like mathematical sets, using operations like &quot;Union&quot;, &quot;Intersect&quot; and a few other cmdset-special operations. Each cmdset can have priorities and exceptions to the various operations applied to them. Removing a set from the mix will dynamically rebuild the remaining sets into a new mixed set.</li>
|
||
</ul>
|
||
<p>The last point is the most interesting aspect of cmdsets. The ability to merge cmdsets allows you to develop your game states in isolation. You then just merge them in dynamically whenever the game state changes. So to implement the dark example above, you would define two types of &quot;look&quot; (the dark version probably being a child of the normal version). Normally you use your &quot;default cmdset&quot; containing the normal <em>look</em>. But once you end up in a dark room the system (or more likely the room) &quot;merges&quot; the <em>dark</em> cmdset with the default one on the player, replacing same-named commands with new ones. The <em>dark</em> cmdset contains the commands that are different (or new) to the dark condition - such as the <em>look</em> command and the changed <em>inventory</em> command. Becoming dazed just means yet another merger - merging the <em>dazed</em> set on top of the other two. Since all merges are non-destructive, you can later remove either of the sets to rebuild a new &quot;combined&quot; set only involving the remaining ones in any combination.</p>
|
||
<p>Similarly, the menu becomes very simple to create in isolation (in Evennia it&#x27;s actually an optional contrib). All it needs to do is define the required menu-commands in its own cmdset. Whenever someone triggers the menu, that cmdset is loaded onto the player. All relevant commands are then made available. Once the menu is exited, the menu-cmdset is simply removed and the player automatically returns to whichever state he or she was in before.</p>
|
||
<h3>Final words</h3>
|
||
<p>The combination of <em>commands-as-classes</em> and <em>command sets</em> has proved to very flexible. It&#x27;s not as easy to conceptualize as is the simple functions in a list, but so far it seems people are not having too much trouble. I also think it makes it pretty easy to both create and, importantly, expand a game with interesting new forms of gameplay <em>without</em> drastically rewriting old systems.</p>
|
||
</description><author>Griatch</author><pubDate>Thu, 16 Aug 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-08-16-taking-command</guid></item><item><title>Extending time and details</title><link>2012.html#2012-06-26-extending-time-and-details</link><description><p><a href="https://2.bp.blogspot.com/-D1dza7edP54/T-mEQhE_eEI/AAAAAAAABS0/omfBOfknDQc/s1600/TheVillasLivingRoom_Windows%25281%2529.JPG"><img src="https://2.bp.blogspot.com/-D1dza7edP54/T-mEQhE_eEI/AAAAAAAABS0/omfBOfknDQc/s1600/TheVillasLivingRoom_Windows%25281%2529.JPG" alt="" /></a>For the fun of it I added an &quot;Extended Room&quot; contrib to Evennia the other night.</p>
|
||
<p>(&quot;Contribs&quot; are optional code snippets and systems that are not part of the actual codebase. They are intended for you to use or dissect as you like in your game development efforts).</p>
|
||
<p>The ExtendedRoom is a room typeclass meant to showcase some more advanced features than the default one. Its functionality is by all means nothing revolutionary in MUD-world, but it was fun and very simple to do using only Evennia&#x27;s basic building blocks - the whole thing took me some two hours to code, document and clean up for a contrib push. The &quot;ExtendedRoom&quot; contribution has the following features:</p>
|
||
<ul>
|
||
<li><strong>Season-based descriptions</strong>. The new Room typeclass will change its overall description based on the time of year (the contrib supports the four seasons, you can hack this as you please). It&#x27;s interesting from an implementation point of view since it doesn&#x27;t require any Script or ticker at all - it just checks on-demand, whenever it is being looked at, only updating if the season has actually changed. There is also a general description used as a fallback in case of a missing seasonal one.</li>
|
||
<li><strong>Time-of-day-based descriptions</strong>. Within each Season-based description you can embed time-of-day based ones with special tags. The contrib supports four time slots out of the box (morning, afternoon, evening, night). In the description, you just embed time-dependent text within tags, like <em><morning>Morning sunlight is shining through the windows</morning></em>. Only time-relevant tags will be shown. This is a simple regular expression substitution, should be easy to expand on if one wants more fine-grained time slots.</li>
|
||
<li><strong>Details</strong>. I took the inspiration of these from a MOO tutorial I read a long time ago. &quot;Details&quot; are &quot;virtual&quot; look-targets in the room. It allows you to add visual interest without having to add a bunch of actual objects for that purpose. Details are simply stored in a dictionary on the room. Details don&#x27;t change with Season in this implementation, but they <em>are</em> parsed for time-of-day based tags!</li>
|
||
<li><strong>Custom commands</strong>. The room is supported by extending two of the custom commands. The Details require a slightly modified version of the <em>look</em> command. There is also a new <em>@desc</em> for setting/listing details and seasonal descriptions. The new <em>time</em> command, finally, simply shows the current game time and season in the room.</li>
|
||
</ul>
|
||
<p>Installing and testing the snippet is simple - just add the new commands to the default cmdset (they will dynamically replace the same-named default ones), dig a few rooms of the new typeclass and play around! Especially the details do make building interesting rooms a lot more fun (I got hung up playing with them way too long last night).</p>
|
||
</description><author>Griatch</author><pubDate>Tue, 26 Jun 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-06-26-extending-time-and-details</guid></item><item><title>Coding from the inside</title><link>2012.html#2012-06-11-coding-from-the-inside</link><description><p><a href="https://3.bp.blogspot.com/-ICX3MmHP4t0/T9UobF85chI/AAAAAAAABRs/806SyA-AQzc/s1600/broken+egg.jpg"><img src="https://3.bp.blogspot.com/-ICX3MmHP4t0/T9UobF85chI/AAAAAAAABRs/806SyA-AQzc/s1600/broken+egg.jpg" alt="" /></a></p>
|
||
<p>Some time ago, a message on the Evennia <a href="https://groups.google.com/forum/?fromgroups#%21topic/evennia/l5w_AcRdLds">mailing list</a> asked about &quot;softcode&quot; support in Evennia. Softcode, a defacto standard in the MUX/MUCK/MUSH/MOO world, is conceptually a &quot;safe&quot; in-game scripting language that allows Players to extend the functionality of things without having access to the server source.</p>
|
||
<p>Now, Evennia is meant to be extended by normal Python modules. For coding game systems and advanced stuff, there is really no reason (in my opinion) for a small development team to not use a modern version control system and proper text editors rather than entering things on a command line without formatting.</p>
|
||
<p>But there <em>is</em> a potential fun aspect of having an online scripting language - and that is player content creation. Crafters wanting to add some pizazz to their objects, builders getting an extra venue of creativity with their rooms - that kind of thing. I didn&#x27;t plan to add softcode support to Evennia, but it &quot;sounded like an interesting problem&quot; and one thing led to another.</p>
|
||
<p>Python is of course an excellent scripting language from the start. Problem is that it&#x27;s notoriously tricky to make it run safely with <em>untrusted</em> code - like that inserted by careless or even potentially malignant Players. Scanning the Internet on this topic is a pretty intimidating experience - everywhere you hear that it shouldn&#x27;t be done, and that the various suggested solutions of a &quot;sandbox&quot; are all inherently unsafe. Python&#x27;s awesome introspection utilities is its own enemy in this particular case.</p>
|
||
<p>For Evennia we are however not looking for a full sandbox. We want a Python-like way for Players to influence a few determined systems. Moreover, we expect short, simple scripts that can do without most of Python&#x27;s functionality (since our policy is that if it&#x27;s too complex or large, it belongs in an external Python module). We could supply black-box &quot;safe&quot; functions to hide away complex functionality while still letting people change things we expect them to want to script. This willingness to accept heavy restrictions to the language should work to our advantage, I hope.</p>
|
||
<p>Evennia actually already has a safe &quot;mini-language&quot; in the form its &quot;lock system&quot;, and thus it was a natural way for me to start looking. A &quot;lock string&quot; has a very restricted syntax - it&#x27;s basically function calls optionally separated by boolean operators, like this:</p>
|
||
<blockquote>
|
||
<p>lockfunc1(*args) and lockfunc(*args, **kwargs) and not lockfunc2()</p>
|
||
</blockquote>
|
||
<p>The result of this evaluation will always be a boolean True/False (if the lock is passed or not). Only certain functions are available to use (controlled by the coder). The interesting thing is that this string can be supplied by the Player, but it is not _eval_uated - rather it&#x27;s <em>manually</em> parsed, from left to right. The function names and arguments are identified (as for the rest, only and/or/not are allowed). The functions are then called explicitly (in Python code, not evaluated as a string) and combined to get a result. This should be perfectly safe as long as your functions are well-defined.</p>
|
||
<p>For the potential softcode language, I first took this hands-on approach - manually parsing the string into its components. I got a pretty decent demo going, but the possibilities are much larger than in the simple lockstring case. Just parsing would be one thing, but then to also make sure that each part is okay to use too is another matter ... It would probably be doable, but then I got to supplying some sort of flow-control. The code starts to become littered with special cases which is never a good sign.</p>
|
||
<p>So eventually I drifted off from the &quot;lock-like&quot; approach and looked into Python&#x27;s <em>ast</em> module. This allows you to view Python code as an &quot;abstract syntax tree&quot; (AST). This solves the parsing issues but once you start dealing with the AST tree you are sort of looking at the problem from the other end - rather than parsing and building the script from scratch it more becomes a matter of removing what is already there (an AST tree can be compiled directly back into Python code after all). It nevertheless seemed like the best way forward.</p>
|
||
<p>Testing a few different recipes from the web, I eventually settled on an <a href="http://code.activestate.com/recipes/496746/">approach</a> which (with some modifications compared to the original) uses a whitelist (and a blacklist for some other things) to only allow a given set of ast nodes and items in the execution environment. It walks the AST tree before execution and kills dangerous Python structures in one large swath. I expanded on this a fair bit, cutting away a lot of Python functionality for our particular use case. Stuff like attribute acces and assignments, while loops and many other Pythonesque things went out the window.</p>
|
||
<p>Around this highly stunted execution system I then built the Evennia in-game scripting system. This includes in-game commands as well as scriptable objects with suitable slots defining certain functionality the Player might want to change. Each Evennia developer can also supply any set of &quot;safe&quot; blackbox functions to offer more functionality to their Player-coders.</p>
|
||
<p>A drawback is the lack of a functional timeout watchdog in case of a script running too long. I&#x27;m using Twisted&#x27;s deferToThread to make sure the code blocks as little as possible, but alas, whereas I can check timeouts just fine, the problem lies in reliably killing the errant sub-thread. Internet experts suggest this to be tricky to do safely at the best of times (with threads running arbitrary code at least), and not wanting to kill the Twisted server is not helping things. I pondered using Twisted&#x27;s subprocess support, but haven&#x27;t gotten further into that at this point. Fact is that most of the obvious DOS attack vectors (such as the while loop and huge powers etc) are completely disabled, so it should hopefully not be trivial to DOS the system (famous last words).</p>
|
||
<p>I&#x27;ve tentatively dubbed the softcode system &quot;Evlang&quot; to differentiate it from our normal database-related &quot;Scripts&quot;.<br />
|
||
So is Evlang &quot;safe&quot; to use by untrusted evil Players? Well, suffice to say I&#x27;m putting it up with a huge EXPERIMENTAL flag, with plenty of warnings and mentions of &quot;on your own risk&quot;. Running Evennia in a chroot jail and with minimum permissions is probably to recommend for the security paranoid. Hopefully Evennia coders will try all sorts of nasty stuff with it in the future and report their finding in our Issue tracker!</p>
|
||
<p>But implementation details aside, I must admit it&#x27;s cool to be able to add custom code like this - the creative possibilities really do open up. And Python - even a stunted version of it - is really very nice to work with, also from inside the game.</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 11 Jun 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-06-11-coding-from-the-inside</guid></item><item><title> Dummies doing (even more) dummy things</title><link>2012.html#2012-05-30-dummies-doing-(even-more)-dummy-things</link><description><p><a href="http://www.smiley-faces.org/backgrounds/smiley-background-012.jpg"><img src="https://lh6.googleusercontent.com/proxy/7O-DqSxlUJDFdfWHuOcVzoSro_bzD9BSAipHXLKNG3gpwyTEptGPTOk5MAgX6yjrkAC2r7P1o9YtCZ1cjzTriLrE9I4kL3frKu4ZcvBpp3Uy8CvM4A=s0-d" alt="" /></a></p>
|
||
<p>This is a follow-up to the <a href="http://evennia.blogspot.se/2012/02/dummies-doing-dummy-things.html">Dummies doing dummy things</a> post. I originally posted info about this update on the mailing list some time back, but it has been pointed out to me that it might be a nice thing to put on the dev blog too since it&#x27;s well, related to development!</p>
|
||
<p>I have been at it with further profiling in Evennia. Notably even more aggressive on-demand caching of objects as well as on-object attributes. I found from profiling that there was an issue with how object access checks were done - they caused the lock handler to hit the database every lock check as it retrieved the needed attributes.</p>
|
||
<p>Whereas this was not much of a hit per call, access checks are done <em>all the time</em>, for commands, objects, scripts, well everything that might need restricted access.<br />
|
||
After caching also attributes, there is no need to hit the database as often. Some commands, such as listing all command help entries do see this effect (although you still probably wouldn&#x27;t notice it unless you checked before and after like I did). More importantly, under the hood I&#x27;m happy to see that the profile for normal Evennia usage is no longer dominated by Django db calls but by the functional python code in each command - that is, in code that the end user have full control over anyway. I&#x27;d say this is a good state of affairs for a mud creation system.</p>
|
||
<p>In the previous &quot;Dummies ...&quot; post I ran tests with rather extreme conditions - I had dummy clients logging to basically act like heavy builders. They dug rooms, created and defined objects randomly every five seconds (as well as walking around, reading help files, examining objects and other spurious things). In that post I found that my puny laptop could handle about <strong>75</strong> to <strong>100</strong> such builders at a time without me seeing a slowdown when playing. My old but more powerful desktop could handle some <strong>200</strong> or so.</p>
|
||
<p>Now, I didn&#x27;t re-run these build-heavy tests with the new caches in place. I imagine the numbers will improve a bit, but it&#x27;s just a guess. By all means, if you expect regularly having more than 100 builders on your game continuously creating 250 new rooms/objects per minute, do get back to me ...</p>
|
||
<p>... Instead I ran similar tests with more &quot;normal&quot; client usage. That is, I connected dummy clients that do what most players would do - they walk around, look at stuff, read help files and so on. I connected clients in batches of 100 at a time, letting them create accounts and logging in fully before connecting the next set of 100.</p>
|
||
<p>All in all I added <strong>1000</strong> dummy clients this way before I saw a noticeable lag on my small laptop. I didn&#x27;t find it necessary to try the desktop at this point. Whereas this of course was with a vanilla Evennia install, I&#x27;d say it should be reasonable room for most realistic mud concepts to grow in.</p>
|
||
<p>With the rather extensive caching going on, it is interesting to know what the memory consumption is.<br />
|
||
<a href="https://4.bp.blogspot.com/-ZNiU4qTi8XE/T8aMHbBck7I/AAAAAAAABRc/vn6EUwkJjJQ/s1600/2012-05-01-Evennia_1000_dummies.png"><img src="https://4.bp.blogspot.com/-ZNiU4qTi8XE/T8aMHbBck7I/AAAAAAAABRc/vn6EUwkJjJQ/s400/2012-05-01-Evennia_1000_dummies.png" alt="" /></a><br />
|
||
This graph shows memory info I noted down after adding each block of 100 players. The numbers fluctuated up and down a bit between readings (especially what the OS reported as total usage), which is why the lines are not perfectly straight.</p>
|
||
<p>In the end the database holds 1000 players (which also means there are 1000 Character objects), about as many rooms and about twice as many attributes. The &quot;idmapper cache&quot; is the mapper that makes sure all Django model instances retain their references between accesses (as opposed to normal Django were you can never be sure of this). &quot;Attribute cache&quot; is a cache storing the attribute objects themselves on the Objects, to avoid an extra database lookup. All in all we see that keeping the entire database in memory takes about 450MB.</p>
|
||
<p>Evennia&#x27;s caching is on-demand (so e.g. a room would not be loaded/cached until someone actually accessed it somehow). One could in principle run a script to clean all cached regularly if one was short on RAM - time will tell if this is something any user needs to worry about on modern hardware.</p>
|
||
</description><author>Griatch</author><pubDate>Wed, 30 May 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-05-30-dummies-doing-(even-more)-dummy-things</guid></item><item><title>Shortcuts to goodness</title><link>2012.html#2012-03-26-shortcuts-to-goodness</link><description><p><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/2011_attraction_repulsion_direction_arrows.png/120px-2011_attraction_repulsion_direction_arrows.png"><img src="https://lh4.googleusercontent.com/proxy/QkyxkcgmfR5RuTgXVrmufjqBSJDUNdFKVM50GLVV98Oj7kN0b7IJzWhCK8n1McUG119JfSMFKxCIRW57srOOW0vsPIcnC1D1aHCRJuwvLOydXOMQmkSWg1b9-h92QPchLVw8xYSoWaRB3I8oyHEpPcXEFEO86Vd9hI96fNdasSwU2B4OY5l5zKxmbd2sPIFSH8W6phmRB1lD7NW-sUJk_LQRgjRcl5iPRl9SuaOT3Dgm=s0-d" alt="" /></a>Evennia, being a MUD-design system, needs to take some special considerations with its source code - its sole purpose is after all to be read, understood and extended.<br />
|
||
Python is of course very readable by default and we have worked hard to give extensive comments and documentation. But for a new user looking into the code for the first time, it&#x27;s still a lot of stuff to take in. Evennia consists of a set of Django-style &quot;applications&quot; interacting and in some cases inheriting from each other so as to avoid code duplication. For a new user to get an overview could therefore mean diving into more layers of code than one would like.</p>
|
||
<p>I have now gone through the process of making Evennia&#x27;s <em>API</em> (Application Programming Interface) &quot;flatter&quot;. This has meant exposing some of the most commonly used methods and classes at a higher level and fully documenting exactly what they inherit av every layer one looks at. But I have also added a new module ev.py to the root directory. It implements &quot;shortcuts&quot; to all the most commonly used parts of the system, forming a very flat API. This means that what used to be</p>
|
||
<p>from src.objects.objects import Object</p>
|
||
<p>can now be done as</p>
|
||
<p>from ev import Object</p>
|
||
<p>Not only should it be easier to find things (and less boilerplate code to write) but I like that one can also easier explore Evennia interactively this way. Using a Python interpreter (I recommend ipython) you can just import ev and easily inspect all the important object classes, tab to their properties, helper functions and read their extensive doc strings.</p>
|
||
<p>Creating this API, i.e. going through and identifying all the useful entry points a developer will need, was also interesting in that it shows how small the API really is. Most of the ev interface is really various search functions and convenient options to inspect the database in various ways. The MUD-specific parts of the API is really lean, as befits a barebones MUD server/creation system.</p>
|
||
</description><author>Griatch</author><pubDate>Mon, 26 Mar 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-03-26-shortcuts-to-goodness</guid></item><item><title>Dummies doing dummy things</title><link>2012.html#2012-02-22-dummies-doing-dummy-things</link><description><p><a href="https://4.bp.blogspot.com/-fGC9QysIL-0/T0UwdxCwDiI/AAAAAAAABN4/cklfv7W28Iw/s1600/224108172066smileys.jpg"><img src="https://4.bp.blogspot.com/-fGC9QysIL-0/T0UwdxCwDiI/AAAAAAAABN4/cklfv7W28Iw/s1600/224108172066smileys.jpg" alt="" /></a>It can often be interesting to test hypothetical situations. So the other day I did a little stress test to see how Evennia handles many players. This is a follow-up to the <a href="http://evennia.blogspot.com/2012/02/evennias-open-bottlenecks.html">open bottlenecks</a> post.</p>
|
||
<p>Evennia, being based on Twisted, is an asynchronous mud server. This means that the program is not multi-threaded but instead it tries to divide up the code it runs into smaller parts. It then quickly switches between executing these parts in turn, giving the impression of doing many things at the same time. There is nothing magical about this - each little piece of code blocks the queue as it runs. So if a particular part takes too long, everyone else will have to wait for their turn. Likewise, if Twisted cannot flip through the queue as fast or faster than new things get added to it, it will start to fall behind.</p>
|
||
<p>The good thing is that all code in the queue <em>will</em> run, although if the event loop cannot keep up there will be a noticeable delay before it does. In a mud, this results in &quot;lagging&quot; (in addition to whatever lag is introduced by your network connection). Running Evennia with a handful of users shows no effect of this, but what happens when we start to add more and more players?</p>
|
||
<p>My &quot;dummy runner&quot; is a stand alone Twisted program that opens any number of Telnet connections to the Evennia server. Each such &quot;dummy&quot; client is meant to represent a player connecting. In order to mimic actual usage, a dummy client can perform a range of actions:</p>
|
||
<ul>
|
||
<li>They can create a new account and log in</li>
|
||
<li>They can look around and read random help files</li>
|
||
<li>They can create objects, name and describe them (for testing, the server is set to grant build privileges to all new players)</li>
|
||
<li>They can examine objects, rooms and themselves</li>
|
||
<li>They can dig new rooms, naming all exits and giving aliases</li>
|
||
<li>They can move between rooms</li>
|
||
</ul>
|
||
<p>The clients tick every 5 seconds, at which time there is a 10% chance each will perform an action from the list above (login first, then one of the others at random). This is meant to spread out the usage a bit, like it would be with real people. Some of these actions actually consist of multiple commands sent to the server (create + describe + set etc), possibly simulating people using shortcuts in their client to send several commands at the same time.</p>
|
||
<p>Results</p>
|
||
<p>Note that I didn&#x27;t do a proper objective benchmark. Rather, I logged in and ran commands to see, very subjectively, how the game &quot;felt&quot; with a number of different players. The lag times are rough estimates by putting time() printouts in the server.</p>
|
||
<p>First I tried with my development laptop, a Thinkpad X61s. It&#x27;s about 5 years old by now and certainly not the fastest thing out there, mainly it&#x27;s small and thin and has great battery life. I used a MySQL database.</p>
|
||
<ul>
|
||
<li><strong>1-50</strong> dummy players didn&#x27;t show any real difference from playing alone. It&#x27;s not so strange; 50 players meant on average 5 of them would do an action every 5 seconds. My laptop could handle that just fine.</li>
|
||
<li><strong>50-75</strong> dummy players introduced a brief lag (less than a second) when they logged in. 5-7 players logging in at exactly the same time will after all mean a lot of commands sent to the server (they not only log in, they create a new character at the same time). Throughout these tests, clients logging in showed the greatest effect on lag. I think this is mostly an artifact of how the clients operate by sending all relevant login commands at the same time. Once all were logged in, only brief lag occurred at random times as coincidence had all clients do something expensive at the same time.</li>
|
||
<li><strong>75-100</strong> dummy players introduced longer lags during login, as on average 7-10 clients were now logging in at exactly the same time. Most commands were unaffected, but occasionally there were some noticeable &quot;hiccups&quot; of about a second depending on what the clients were doing.</li>
|
||
<li><strong>100-150</strong> dummy players - here things started to go downhill rapidly. Dummy client login caused seriously lagging and at 150 logged in players, there were 15 exactly simultaneous actions coming in. This was clearly too much for my laptop; it lead to a very varying lag of 1-10 seconds also for simple commands.</li>
|
||
</ul>
|
||
<p>Next I tried my desktop machine. This is also not bleeding edge; it&#x27;s a 4-year old machine with 3GHz processor and 4GB RAM. Since I don&#x27;t have MySQL on this machine, I used SQLite3, which is interesting in its own right since it&#x27;s Evennia&#x27;s default database.</p>
|
||
<ul>
|
||
<li><strong>1-75</strong> dummy players didn&#x27;t affect the feel of the game one bit.</li>
|
||
<li><strong>75-100</strong> showed some occasional effects starting to appear during dummy client logins.</li>
|
||
<li><strong>100-150</strong> dummy players didn&#x27;t introduce more than a few hiccups of less than a second when approximately 15 clients decided to do something expensive at the same time.</li>
|
||
<li><strong>150-200</strong> introduces 2-3 seconds lag during client mass-logins, but once all clients had connected, things worked nicely with only brief random hiccups.</li>
|
||
<li><strong>200-250</strong> showed the lag getting more uneven, varying from no lag at all to 2-3 seconds for normal times and up to 5 seconds when clients were logging in.</li>
|
||
<li><strong>250-300</strong> dummy players showed login lag getting worse. The general lag varied from 0-5 seconds depending on what the other clients were up to.</li>
|
||
<li><strong>300-350</strong> dummy players, about double of what the laptop could handle, the CPU was not able to keep up anymore. The system remained stable and all commands got executed - eventually. But the lag times went up very rapidly.</li>
|
||
</ul>
|
||
<p>Conclusions</p>
|
||
<p>So, based on this I would say 50-75 was a comfortable maximum number of (dummy) players to have on my laptop whereas the desktop could handle around 150 without much effort, maybe up to 250 on a good day.</p>
|
||
<p>So what does these numbers mean? Well, the dummy clients are rather extreme, and 100+ builders walking around building stuff every 5 seconds is not something one will see in a game. Also so many logging on at the same time is not very likely (although it could happen after a crash or similar). If anything the usage pattern of human players will be more random and spread out, which helps the server to catch up on its event queue.</p>
|
||
<p>On the other hand these tests were run with a vanilla Evennia install - a full game might introduce more expensive commands and subsystems. Human players may also introduce random spikes of usage. So take this for what it is - a most subjective, un-scientific and back-of-the-envelope measure.</p>
|
||
<p>All in all though, I would say that few MUDs these days see 30 concurrent online users, even less 100 ...</p>
|
||
</description><author>Griatch</author><pubDate>Wed, 22 Feb 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-02-22-dummies-doing-dummy-things</guid></item><item><title>Commands and you</title><link>2012.html#2012-02-17-commands-and-you</link><description><p><em>Commands</em> define how a Player interacts with a given game. In a text-based game it&#x27;s not amiss to say that the available commands are paramount to the user experience. In principle commands could represent mouse clicks and other modernistic GUI sugar - but for this blog I&#x27;ll stick with the traditional entered text.</p>
|
||
<p>Like most things in Evennia, Commands are Python classes. If you read the <a href="http://code.google.com/p/evennia/wiki/Commands">documentation</a> about them you&#x27;ll find that the command classes are clumped together and tacked onto all objects in-game. Commands hanging onto a Character object will be available all the time, whereas commands tacked onto a grandfather&#x27;s clock will only be available to you when you stand in front of said clock.</p>
|
||
<p>The interesting thing with Commands being classes is that each Character gets a separate instance of each command. So when you do <em>look</em> 100 times in a row, it&#x27;s always the <em>same</em> Look command instance that has its methods called by the engine. Apart from being an efficient way to handle things, this has a major neat side-effect:</p>
|
||
<blockquote>
|
||
<p><em>You can store things on the Command object and whatever you store can be retrieved next time you execute that command.</em></p>
|
||
</blockquote>
|
||
<p>I find this very cool mainly because I didn&#x27;t really plan with this in mind when designing the command system - it was a happy side effect. A use I have thought of is to implement cooldowns. Say you have a powerful <em>bash</em> command. It makes a lot of damage, but you need time to recover between bashes. So when you do the <em>bash</em> command the Bash command object simply stores the current time on itself:</p>
|
||
<blockquote>
|
||
<p>self.last_bash = time.time()</p>
|
||
</blockquote>
|
||
<p>Next time the Player tries to use <em>bash</em>, all the command object needs to is to check if self.last_bash is set, and compare the time stored herein with the current time. No twisted tasks needed, no overhead. Very neat and tidy.</p>
|
||
<p>Another nice functionality (just added today in fact) is that Evennia can be set to <em>store a copy of the last command object executed</em>. What can one do with this? For starters, it allows for commands to check what a previous command was. This can be useful in itself, but since the next command actually have access to (a copy of) the previous command object itself, it will allow a lot more than that.</p>
|
||
<p>Consider a <em>look</em> command that remembers whatever object it is looking at. Since the Look command is a Python object, it simply stores the looked-at object on itself before returning the normal info to the Player. Next, let&#x27;s assume we use a <em>get</em> command. If no argument is given to this <em>get</em> (no given object to pick up), the <em>get</em> normally returns an error. But it can now instead peek at the <em>previous</em> command (look) and see what <em>that</em> command operated on. This allows for nice potential constructs like</p>
|
||
<blockquote>
|
||
<blockquote>
|
||
<blockquote>
|
||
<p>look [at] box</p>
|
||
</blockquote>
|
||
</blockquote>
|
||
</blockquote>
|
||
<blockquote>
|
||
<blockquote>
|
||
<blockquote>
|
||
<p>get [it]</p>
|
||
</blockquote>
|
||
</blockquote>
|
||
</blockquote>
|
||
<p>Evennia does not use this functionality in its default command set, but it offers some very powerful possibilities for MUD creators to design clever parsing schemes.</p>
|
||
</description><author>Griatch</author><pubDate>Fri, 17 Feb 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-02-17-commands-and-you</guid></item><item><title> Such a small thing ...</title><link>2012.html#2012-02-15-such-a-small-thing-...</link><description><p>Lately I went back to clean up and optimize the workings of Evennia&#x27;s Attributes. I had a nice idea for making the code easier to read and also faster by caching more aggressively. The end result was of course that I managed to break things. In the end it took me two weeks to get my new scheme to a state where it did what it already did before (although faster).</p>
|
||
<p>Doing so, some of the trickier aspects of implementing easily accessible Attributes came back into view, and I thought I&#x27;d cover them here. Python intricacies and black magic to follow. You have been warned.</p>
|
||
<p>Attributes are, in Evennia lingo, arbitrary things a user may want to permanently store on an object, script or player. It could be numbers or strings like health, mana or short descriptions, but also more advanced stuff like lists, dictionaries or custom Python objects.</p>
|
||
<p>Now, Evennia allows this syntax for defining an attribute on e.g. the object <em>myobj</em>:</p>
|
||
<blockquote>
|
||
<p>myobj.db.test = [1,2,3,4]</p>
|
||
</blockquote>
|
||
<p>This very Pythonic-looking thing allows a user to transparently save that list (or whatever) to an attribute named, in this example, <em>test.</em> This will save to the database.<br />
|
||
What happens is that <em>db</em>, which is a special object defined on all Evennia objects, takes all attributes on itself and saves them by overloading its <strong>setattr</strong> default method (you can actually skip writing <em>db</em> most of the time, and just use this like you would any Python attribute, but that&#x27;s another story).</p>
|
||
<p>Vice-versa,</p>
|
||
<blockquote>
|
||
<p>value = myobj.db.test</p>
|
||
</blockquote>
|
||
<p>This makes use of the <em>db</em> object&#x27;s custom <strong>get_attribute</strong> method behind the scenes. The <em>test</em> attribute is transparently retrieved from the database (or cache) for you.</p>
|
||
<p>Now, the (that is, my) headache comes when you try to do this:</p>
|
||
<blockquote>
|
||
<p>myobj.db.test[3] = 5</p>
|
||
</blockquote>
|
||
<p>Such a small, normal thing to do! Looks simple, right? It is actually trickier than it looks to allow for this basic functionality.<br />
|
||
The problem is that Python do everything by reference. The list is a separate object and has no idea it is connected to <em>db.</em> <em>db</em>&#x27;s <strong>get_attribute</strong> is called, and happily hands over the list <em>test</em>. And then <em>db</em> is out of the picture!. My nifty save-to-database feature (which sits in <em>db</em>) knows nothing about how the 3rd index of the list <em>test</em> now has a 5 instead of a 4.</p>
|
||
<p>Now, of course, you could always do this:</p>
|
||
<blockquote>
|
||
<p>temp = myobj.db.test</p>
|
||
</blockquote>
|
||
<blockquote>
|
||
<p>temp[3] = 5</p>
|
||
</blockquote>
|
||
<blockquote>
|
||
<p>myobj.db.test = temp</p>
|
||
</blockquote>
|
||
<p>This will work fine. It is however also clumsy and hardly intuitive. The only solution I have been able to come up with is to have <em>db</em> return something which is <em>almost</em> a list but not quite. It&#x27;s in fact returning an object I not-so-imaginatively named a <em>PackedList</em>_._ This object works just like a list, except all modifying methods on it makes sure to save the result to the database. So for example, what is called when you do mylist[3] = 4 is a method on the list named <strong>setitem</strong>. I overload this, lets it do its usual thing, then call the save.</p>
|
||
<blockquote>
|
||
<p>myobj.db.test[3] = 5</p>
|
||
</blockquote>
|
||
<p>now works fine, since <em>test</em> is in fact a <em>PackedList</em> and knows that changes to it should be saved to the database. I do the same for dictionaries and for nested combinations of lists and dictionaries. So all is nice and dandy, right? Things work just like Python now?</p>
|
||
<p>No, unfortunately not. Consider this:</p>
|
||
<blockquote>
|
||
<p>myobj.db.test = [1, 3, 4, [5, 6, 7]]</p>
|
||
</blockquote>
|
||
<p>A list with a list inside it. This is perfectly legal, and you can access all parts of this just fine:</p>
|
||
<blockquote>
|
||
<p>val = myobj.db.test[3][2] # returns 7!</p>
|
||
</blockquote>
|
||
<p>But how about <em>assigning</em> data to that internal nested list?</p>
|
||
<blockquote>
|
||
<p>myobj.db.test[3][2] = 8</p>
|
||
</blockquote>
|
||
<p>We would now expect <em>test</em> to be [1, 3, 4, [5, 6, 8]]. It is not. It is infact only [5, 6, 8]. The inner list has replaced the entire attribute!</p>
|
||
<p>What actually happens here? <em>db</em> returns a nested structure of two _PackedList_s. All nice and dandy. But Python thinks they are two separate objects! The main list holds a reference to the internal list, but as far as I know <em>there is no way for the nested list to get the back-reference to the list holding it</em>! As far as the nested list knows, it is all alone in the world, and therefore there is no way to trigger a save in the &quot;parent&quot; list.<br />
|
||
The result is that we update the nested list just fine - and that triggers the save operation to neatly overwrite the main list in the cache and the database.</p>
|
||
<p>This latter problem is not something I&#x27;ve been able to solve. The only way around it seems to use a temporary variable, assign properly, then save it back, as suggested earlier. I&#x27;m thinking this is a fundamental limitation in the way cPython is implemented, but maybe I&#x27;m missing some clever hack here (so anyone reading who has a better solution)?</p>
|
||
<p>Either way, the <em>db</em> functionality makes for easy coding when saving things to the database, so despite it not working <em>quite</em> like normal Python, I think it&#x27;s pretty useful.</p>
|
||
</description><author>Griatch</author><pubDate>Wed, 15 Feb 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-02-15-such-a-small-thing-...</guid></item><item><title>About this dev blog</title><link>2012.html#2012-02-05-about-this-dev-blog</link><description><p>This is to be my <a href="http://www.evennia.com/">Evennia</a> dev blog, but it will also cover various other musings concerning programming in general and mud designing in particular. Whereas the Evennia <a href="https://groups.google.com/forum/#%21forum/evennia">mailing list</a> remains the main venue for discussion, I will probably use this blog for announcing features too.</p>
|
||
<p>Some background:<br />
|
||
Evennia is a Python MUD/MUX/MU* server. More correct is probably to call it a &quot;MUD-building system&quot;. The developer codes their entire game using normal Python modules. All development is done with the full power of Python - gritty stuff like database operations and network communication are hidden away behind custom classes that you can treat and modify mostly like any Python primitives.</p>
|
||
<p>Since the server is based on the <a href="http://twistedmatrix.com/trac/">Twisted</a> and <a href="https://www.djangoproject.com/">Django</a> technologies we can offer many modern features out of the box. Evennia is for example its own web server and comes with both its own website and an &quot;comet&quot;-style browser mud client. But before this turns into even more of a sales pitch, I&#x27;ll just just direct you to the evennia website if you want to know more. :)</p>
|
||
<p>I, Griatch, took over the development of Evennia from the original author, Greg Taylor, in 2010.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 05 Feb 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-02-05-about-this-dev-blog</guid></item><item><title> Evennia's open bottlenecks</title><link>2012.html#2012-02-05-evennia's-open-bottlenecks</link><description><p>Since Evennia hit beta I have been mostly looking behind the scenes to see what can be cleaned up and not in the core server. One way to do that is to check where the bottlenecks are. Since a few commits, Evennia&#x27;s runner has additions for launching the Python cProfiler at startup. This can be done for both the Portal and the Server separately.</p>
|
||
<p>I have created a test runner (soon to hit trunk) that launches dummy clients. They log on and then goes about their way executing commands, creating objects and so on. The result of looking at the profiling data (using e.g. <em>runsnake)</em> has been very interesting.</p>
|
||
<p>Firstly, a comparably small part of execution time is actually spent in Evennia modules - most is spent using Python built-ins and in the Twisted/Django libraries. This is promising in a way - at least there are no expensive loops in the Evennia code itself that sucks up cycles. Of course it also means we depend heavily on django/twisted (no surprise there) and especially when it comes to database access, I know there could be more caching going on so as to cut down on db calls.</p>
|
||
<p>Of the Evennia modules, a lot of time is spent in getting properties off objects - this is hard to avoid, it a side effect of Evennia&#x27;s typeclass system - and this is cached very aggressively already. What also stands out as taking a considerable time is the command system - the merging of command sets in particular does a lot of comparing operations. This happens every time a command is called, so there are things to be done there. The same goes for the help system; it needs to collect all the currently active command sets for the calling player. Maybe this could be cached somehow.</p>
|
||
<p>More work on this is needed, but as usual optimization is a double-edged sword. Evennia is written to have a very readable code. Optimization is usually the opposite of readable, so one needs to thread carefully.</p>
|
||
</description><author>Griatch</author><pubDate>Sun, 05 Feb 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">2012.html#2012-02-05-evennia's-open-bottlenecks</guid></item></channel></rss> |