Showing posts with label announcement. Show all posts
Showing posts with label announcement. Show all posts

Thursday, November 18, 2021

The Evennia blog has moved to evennia.com!

This dev blog has moved! All past and future posts will now be found here instead on evennia.com. The linked post discusses the move in more detail, including the little custom blog platform I wrote for it.


The new blog has a new RSS feed address, so if you follow this blog via RSS, update your feed link (all old entries were migrated as well).


The old posts here on blogspot/bloggly will remain but won't be updated anymore.

Cheers,

Griatch

Friday, January 1, 2021

Happy new years 2021! Evennia things to come this year


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. 

On my development horizon for 2021 are the main new features planned for v1.0. Some of these are rather big things I've wanted to get around to for a while. They are all happening in the develop branch of Evennia, which is currently not recommended for general use.

  • SessionDB: 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.  
  • Script refactor: 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'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's life-cycle). 
  • Channel refactor: 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'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. 
  • New starting tutorial: As part of the new documentation, I'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.
  • Contrib restructure: Our contrib/ folder is getting a little cluttered. I'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'll see just how it goes.
  • Documentation cleanup: 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). 
  • Unittest coverage: 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.
  • Evennia PYPI package: 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 pip install evennia. Once we do it will simplify the install instructions dramatically for those not interested in contributing to Evennia proper.
We also have some pull-requests in the making that will be interesting to have in the system, such as Volund'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). 

A lot of work to do as usual! 

Thanks 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's very encouraging! 
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!

May all our game development move forward and our hard drives stay healthy for another year. 

Cheers and a Happy new year,
Griatch

Saturday, November 14, 2020

Evennia 0.9.5 released!

 

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*). 

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 master branch of Evennia over the last year you will not notice much difference from this release (time to upgrade if you haven't been keeping up though!). 

While an interim release, there are still a lot of things that has happened since v0.9: 

Webclient improvements

  • Big web client 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). 
  • 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'll try to gather screenshots for a future blog.
  • Allow to redirect video/music to separate panes.
  • Many other fixes, such as improving the input-history behavior.

EvMenu improvements

EvMenu is a powerful system for creating in-game text menus.

  • The EvMenu class was refactored to be easier to override. For example, all messages now go through EvMenu.msg which allows for easy customization. It also defaults to sending with a type of "menu", making it easier to redirect menus to seprate panes in the webclient.
  • In a node, EvMenu is now accessed via the much more logically named .ndb._evmenu instead of .ndb._menutree (the old name still works for backwards compatibility, but is deprecated).
  • New optional EvMenu template 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.

New settings

  • INLINEFUNC_STACK_MAXSIZE is an integer that allows to control how big the inlinefunc nesting stacksize is.
  • New DEFAULT_CHANNELS setting to allow customization of which channels should be initialized on startup. This can be modified after initial server start.
  • CHANNEL_HANDLER_CLASS allows for specifying an alternative to the default ChannelHandler if wanting to change how Channels behave. 
  • SERVER_LOG_DAY_ROTATION defines how many days the server log should run before being force-rotated (default is seven days).
  • SERVER_LOG_MAX_SIZE specifies how big the log must be before it auto-rotates (even if SERVER_LOG_DAY_ROTATION days has not passed yet). 
  • PORTAL_LOG_DAY_ROTATION, PORTA_LOG_MAX_SIZE - equivalent for the Portal.

 Other improvements

  • The EvMore pager saw big performance speedups, making the viewing of large numbers of entries much snappier. You can now also paginate EvTables directly and create custom pagers by override the EvMore class (useful if you want to e.g. do a EvTable per-page).   
  • Improvement to the multi-match parser: Trying to get for example 3-box will now fail with a no-found if there are only two boxes in the room (before it would show the multi-match menu).  
  • New inside_rec 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).
  • New $random inlinefunc for producing a random number in strings.
  • TickerHandler.add() now returns a store_key to uniquely describe the ticker just added. The TickerHandler.remove() accepts a new kwarg store_key for removing the ticker - this makes it easier to manage tickers instead having to insert the full specifications of the ticker to remove it.
  • Many fixes to the spawn command and prototype functionality. The new spawn/raw flag will now return the prototype-dict so one can manually edit and copy&paste it.
  • The evennia.GLOBAL_SCRIPTS container will now contain all global scripts, not only those explicitly created with the GLOBAL_SCRIPTS setting. 
  • The list_to_string utility converts a list to a nice string-representation, such as ["a", "b", "c", "d"] -> "a, b, c and d". The function is renamed to iter_to_string (but old name still works) and now also works with generators and will not crash even when provided a single value.
  • A lot of bug fixes and stability fixes!

See the changelog here.

 

New documentation system 

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 my prervious post. 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. 

Check it out: 

 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.
 
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. 
 
But that's for future blogs ...


 


Monday, September 30, 2019

Blackifying and fixing bugs

Since version 0.9 of Evennia, 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.




On Frontends

Contributor friarzen has chipped away at improving Evennia'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'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:

Inline image by me (griatch-art.deviantart.com)


A related fun development is Castlelore Studios' development of an Unreal Engine Evennia plugin (this is unaffiliated with core Evennia development and I've not tried it, but it looks pretty nifty!): 

Image ©Castlelore Studios
 
On Black

Evennia's source code is extensively documented and was sort of 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.
 
After pre-work and recommendation by Greg Taylor, Evennia has adopted the black autoformatter for its source code. I'm not really convinced that black produces the best output of all possible outputs every time, but as Greg puts it, it's at least consistent in style. We use a line width of 100.

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 >100 at times (especially for long strings), but otherwise this reduces the number of different PEP8 infractions in the code a lot.

On Python3

Overall the move to Python3 appears to have been pretty uneventful for most users. I've not heard almost any complaints or requests for help with converting an existing game.
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.

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.

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've not seen any Windows install issues in a while.

On Future

For now we'll stay in bug-fixing mode, with the ocational new feature popping up here and there. In the future we'll move to the develop branch again. I have a slew of things in mind for 1.0. 

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'll also try reworking and consolidating the tutorials so one can follow them with a more coherent "red thread", as well as improving the documentation in various other ways to help newcomers with the common questions we hear a lot. 

The current project plan (subject to change) is found here. Lots of things to do!



Top image credit: https://www.goodfreephotos.com/ (public domain)

Sunday, May 26, 2019

Creating Evscaperoom, part 2


Jester smiling oh so sweetly
The Jester, your 'adversary'


This is part two of my post-mortem dev-blog about Evscaperoom, the multiplayer, text-based 'escape room' I wrote in Python and Evennia. You can read the first part of the dev blog here.

This was a game-jam entry I created in a month for the Mud Coder's guild's Game Jam. The theme was One Room. You can play the game for free in your browser or with a traditional MUD client. There are no spoilers in these blog posts. 

Update: These days you can play the Evscaperoom by logging into the Evennia demo game at https://demo.evennia.com. It's just one of the exits you can get through when you enter.

The first part 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 on github.

At the time of this post, players have played Evscaperoom for a little more than a week. At the end I'll share some observations and things I learned along the way.

Ease of building

Over the one-month game jam, I spent about four days making the game's 'engine' and toolset with Evennia. The rest of the time was spent using those tools to actually create game content (the story, puzzles etc).

An important thing was that I didn't want to do any traditional in-game 'building'. 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't want my game to only exist in the database but in actual version-controllable python modules.

So all of the Evscaperoom is created in code (notably in the game states 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.


Overall game structure 

The main Evscaperoom menu, showing the option to create a new room or join one of two existing rooms.
Main menu
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 ('room').

To make it easier for people to agree to meet up in a room, i made a little 'fantasy name generator' to make unique random names of the rooms. It felt more thematic than showing room id'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.

I decided that I should not keep empty rooms around, so whenever a room has no more players in it, it's deleted from the database along with all its content. This means players can'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.

I distribute Evscaperoom as an Evennia 'game dir'. Once you'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 the evscaperoom/ folder. The only other modification I did was to make sure Evennia rerouted new players into the Evscaperoom menu when they connect.


Room class

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 Room class. This "EvscapeRoom" class holds all resources for this room. Evennia makes sure to persist it all to the database for you.

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.

For example, I added helper methods both for creating and finding objects in the room. On creation, all objects are tagged with the room'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.

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.

Importantly, the very action of deleting the room will automatically clean all resources tied to it, keeping things tidy.


Commands and Objects

This shows a list of all commands useful in the room.
The help screen, show all top-level commands
As discussed in part one of this blog, the Evscaperoom, uses a 'focus' mode: The player must examine/focus on an object first in order to operate or use it.

The basic command syntax is:
> command [target]
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 'focused' object does not need to be specified. This is the process of using one object with another:

> examine key

~~ key (examining) ~~ 
This is a brass key.

(To unlock something with it, use insert into <target>)

> insert into door

You unlock the door with the key!

(the into is optional). Here, we focus on the key. We get the key's description and a hint that you can insert it into things. We then insert it into the door, which is another object in the room. The insert 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.

Technically, these on-object 'actions' (like insert above), are dynamically generated. Here is an example of the key object:

class Key(EvscaperoomObject):
    def at_focus_insert(self, caller, **kwargs):
        target = kwargs['args']
        obj = caller.search(obj)
        if not obj: 
            return 
        if obj.check_flag("can_use_key"):
            obj.handle_insert(self)

Not shown here is that I made a wrapper for the "no-match" command of Evennia. This command fires when no other commands match. I made this instead analyze the currently 'focused' object to see if it had a method at_focus_<command_name> on it. If so, I inject the supplied arguments into that method as a keyword argument args.

So when you focus on the key and give the insert 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.

I created a library of base objects that I can just use as mixins for the object I want to create. Here's an example:

from evscaperoom import objects

class Box(objects.Openable, 
          objects.CodeInput, 
          objects.Movable):
     # ...
    
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.


Room states

I think of the escape room as going through a series of states. 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.

I chose to represent states as Python modules in a folder. To be a state, each module needs to have a global-level class State inheriting from my new BaseState 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.

This is a (simplified) example of a state module:  

# module state_001_start.py
       
from evscaperoom.state import BaseState
from evscaperoom import objects


MUG_DESC = """
A blue mug filled with a swirling liquid. 
On it is written "DRINK ME" with big letters.
"""

class Mug(objects.EvscapeRoomObject):
    def at_focus_drink(self, caller, **kwargs): 
        caller.msg(f"You drink {self.key}.")      
        self.next_state() # trigger next state

class State(BaseState):

    hints = ["You are feeling a little thirsty...",
             "Drink from the mug, dummy."]

    next_state = "state_002_big_puzzle"

    def init(self): 
        mug = self.create_object(
            Mug, key="wooden mug", aliases=["mug"])
        mug.db.desc = MUG_DESC.strip()

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.

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
a sequence of hints specific for that state.



Informing the room

I wrote the content in second-person perspective ("You open the door"). This is however a multiplayer game and I didn't intially appreciate how many texts must also exist in a third-party form for the rest of the room to see ("Griatch opens the door").

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.

The solution was to add parsing and translation of pronouns and verbs (a concept I first saw on the game Armageddon).

I write the string like this:

OPEN_TEXT = "~You ~open the *door."

The ~ marks text that should be parsed for second/third-person use (I'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 and to the room, in which it will look different depending on who receives it:

     I see "You open the [door]."
     Others see "Griatch opens the [door]."

English is luckily pretty easy to use for this kind of automatic translation - in general you can just add an "s" to the end of the verb. I made a simple mapping for the few irregular verbs I ended up using.

Overall, this made it quick to present multiple viewpoints with minimal extra text to write.

Shows the various accessibility options for showing items.
The option menu
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).

Bringing it online

Evennia is both a mud framework and mudserver as well as a webserver based on Twisted. It runs the game's website (with the help of Django) and also provides its own HTML5 webclient. I tweaked the default website text and played a little with CSS but otherwise didn't spend too much time on this bit.

I got a $5/month DigitalOcean droplet with Ubuntu. I made a new, unprivileged "evennia" 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.

I then pointed http://experimental.evennia.com at the droplet's IP and that was it!

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.

Some lessons learned

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've had to make small typos and grammar corrections as I (or players) spot them. 

There were nevertheless some things I learned, some of which led to more real improvements post-launch.

No amount of help is too much help

Shows focus on the 'bed', with an example of the header telling how to leave the 'focus' mode.
The header shows how to get out of focus mode
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 one 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 leave the focus mode. They'd just flounder about, think the game was buggy and log off. 

The answer (just run examine again) is found with the help 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. 

Make it easy to connect for all tastes

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 'huge hurdle'. Not sure if that's true. But unless you want to use a particular name, there is also no actual gameplay reason to formally authenticate for Evscaperoom. 

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 "Guest 1", "Guest 2" etc. Since then, maybe 40% of players connecting have chosen to do so as an anonymous guest. I don't know if those would have left completely if the option was not available, but it's at least a convenient shortcut for getting into the game.

Everything takes longer than expected

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. 

Creating text content is a lot faster than creating graphical assets, but it's still a lot of work. Just the ending 'cinematics' took me almost two days to finish and clean up at the end. 

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.


Building a MU* game in pure code is awesome

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 easy it is to do things when you don't need to cover the general case.

Using the tools and creating content purely in-code was great and ended up leading to a very fast content creation. Python works perfectly as a scripting language and I don'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.

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.


Conclusions

For all my work on the Evennia library/server, I've not actually used 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.

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.

In the future I will most likely break out the 'engine' and tools of the Evscaperoom into an Evennia contrib so that others can make similar games with it easily.

Looking forward to future game jams now!

Thursday, May 9, 2019

Podcast about Evennia

I was interviewed on the (pretty grandiosely named) podcast Titans of Text the other day.

In the interview, which are run by people from the MUD Coder's Guild (a great initiative!), I talk a bit about the history of Evennia, the text-based multiplayer game engine I'm working on, and go into some various technical aspects of the engine as well. Check it out and support the podcast!

https://www.titansoftext.com/4

Thursday, October 4, 2018

Evennia in Hacktoberfest 2018

Like last year, Evennia, the Python MUD creation system, takes part in Hacktoberfest, a yearly event run by Digitalocean in collaboration with GitHub.

The premise is simple: Sign up at their website and then contribute with 5 GitHub pull requests during the month of October. If you do, you'll win a unique T-shirt!

You can help out any OSS project to win, if you want to help out Evennia, I have marked a bunch of suitable issues with the Hacktoberfest label for you to sink your teeth in. 

Code on!

Sunday, September 30, 2018

Evennia 0.8 released

After about a year of work and almost 540 commits from close to 20 contributors, Evennia 0.8 is out! Evennia is a Python game server for creating text-based multiplayer games (MUDs, Mushes, etc) using Django and Twisted.

Some of the upcoming improvements have been covered by previous dev blogs, such as the completely reworked server infrastructure:




as well as the new Online Creation System that allows for editing in-game prototypes using a powerful menu system:



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 "all the rest" or "all" of the content.


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's a step forward!

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.

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's very mature security features. 

The more detailed list of improvements and changes can be found in the announcement here. As usual, please report any issues to the issue tracker on github. 

Future

In the immediate future, we'll focus on resolving any bugs that may have slipped through the cracks and also resolve some other issues in the pipeline. 

But beyond that, work on Evennia 0.9 will begin. And before you ask - yes Evennia 0.9 is the version where we'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.


Sunday, October 1, 2017

Evennia in Hacktoberfest 2017

Evennia, the Python MUD/MUSH/MU* creation library participates in the Hacktoberfest 2017 (sign up on that page)! Hacktoberfest is open for all open-source projects like ours. After registering, if you make at least four Pull Requests to a public repo on Github during October (need not just be to Evennia), you win a limited-edition T-shirt!

The help Evennia out and get your T-Shirt, look at our Issue Tracker. I have marked some issues with "Hacktoberfest" but you could take on any issue you want. Take a look in particular at the Unit test issue if you are looking to get into contributing on a smaller scale while helping us tremendously.

If you have any questions on contributing (or it's your first time making a Pull Request), don't be shy to drop into #evennia on irc.freenode.net or ask in our forum/mailing list. Have fun!

Wednesday, September 20, 2017

Evennia 0.7 released

As of today Evennia 0.7 is officially out! Evennia is a Python framework and -server for creating text-based multiplayer games (MU*).

A big thank you to all collaborators that have helped with code and testing along the way!

Here is the hefty forum post that details how you migrate to Evennia 0.7.

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): 
 
  • Evennia separates Player objects from Character objects in that the former is an OOC entity that can puppet one or more of the latter. The name Player was a source of some confusion since this is used differently in other code bases. Player has now been renamed to Account to make its function clearer.
  • Evennia's in-built website now uses our own theme and bootstrap 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).
  • Shared logins between webclient and website, with the ability to log out of each independently of the other if so desired.
  • 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 "+foo", then that will still work and won't clash with another command named just "foo".
  • Easy pause mechanisms using yield statements directly in Command code (just do yield 10 in your command code to have it pause ten seconds without blocking anyone else). You can also do retval = yield "Do you want to accept?" and have the command pause (non-blocking) for the player's input before continuing.
New contribs (optional plugins) (selection, new since 0.6 but many have been available on master branch for a while):
  • The optional In-Game-Python contrib by Vincent le Geoff allows for coding and scripting in-game using full-fledged Python to make events and triggers. It's not 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.
  • 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)
  • Full turn-based combat system, meant to expand for a desired system (battlejenkins)
  • Alternative Unix-style command base for Evennia, for those that prefer to enter commands like you do on the unix command line (with --flags etc) (Vincent le Geoff)
  • Multidescer, which together with Evennia's nick replacement system can be heavily customized in-game (me).
  • Mail - a @brandymail-style in-game mail-system (grungies1138)
  • Clothing system, for layered outfits adding to the wearer's desc when worn (battlejenkins).
A more technical list from the main announcement post: 
  • EvMenu formatting functions now part of class - 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. 
  • Scripts are now valid message senders - Also Scripts can now act as "sender" of a Msg, for example to a Channel or a player.
  • Due to the new prefix-ignoring above, @desc (builder-level description-setting) was renamed to setdesc to make it clearly separate from desc (used by a player setting their own description). This was actually the only clash we had to resolve this way in the default commands. 
  • Permission Hierarchy names change - To make Evennia's permission hierarchy better reflect how Evennia actually works, the old Players, Player Helpers, Builders, Wizards, Immortals hierarchy has changed to Player, Helper, Builder, Admin, Developer. Singular/Plural form is now ignored so Builder and Builders 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.  
  • All manager methods now return querysets - 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.
  • PrettyTable was removed from the codebase. You can still fetch it for your game if you prefer (it's on pypi). But EvTable has more functionality as well as color-support. 
  • Add **kwargs support to all object at_* hooks - All object at_ hooks, such as at_look, at_give 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.  
  • Remove {-color tags - The use of {r, {n etc was deprecated for years and have now been completely removed from Evennia'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.  
  • Updated hooks for say/whisper commands - 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. this PR).  
  • More compact distribution of ports - Before, Evennia distributed its ports widely, such as using 4000, 4001, 8000, 8001, 5001, 8022, 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 4000-4006 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.  
  • Change how auto-login works - 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 "decouple" 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.  
  • Better idle disconnects - 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.
  • A slew of bug fixes and other tweaks. See here for the list.

    Friday, July 1, 2016

    The art of sharing nicks and descriptions

    In the month or so since the merger of Evennia's development branch and all its web-client updates, we have been in bug-fixing mode as more people use and stress the code.

    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.

     

    Shared web login

    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.

    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.

    Extended Nicks 

    Evennia'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.

    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.

    Let's say we often use the @dig command this limited way:

    @dig roomname;alias = exit;alias, backexit;alias
     
    Let'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 "real" command. Here is an example of a syntax putting the aliases in parentheses and separating all components with commas:

    > nick newroom $1($2), $3($4), $5($6) = @dig $1;$2 = $3;$4, $5;$6

    From here on you can now create your rooms with entries like this: 

    > newroom The great castle(castle), to the castle(castle), back to the path(back)

    Multidescer contrib

    I have added a new "multidescer" 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 "active" description.

    An example of usage:

    desc hat = a blue hat.
    desc basic = This is a tall man with narrow features.
    desc clothing = He is wearing black, flowing robes.

     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: 

    > desc/set basic + |/ + clothing + On his head he has + hat
    > look self
    This is a tall man with narrow features. 
    He is wearing black, flowing robes. On his head he has a blue hat.

    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

    > nick setdesc $1 $2 $3 $4 = $1 + |/ + clothing + On his head he has a $4

    This way you can clothe yourself in different outfits easily using the same output format:

    > setdesc basic clothing hat 
     
     The multidescer is a single, self-contained command that is easy to import and add to your game as needed.



    ... There's also plenty of bug fixes, documentation work and other minor things or course.

    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 'un!
    .
    Griatch

    Image by ryancr (released under Creative Commons)

    Sunday, May 22, 2016

    Evennia 0.6 !


    As of today, I merged the development branch to make version 0.6 of the MU* development system and server Evennia.

    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).

    For example the user can now easily plug in "inputfuncs" 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).

    The HTML5 webclient has itself updated considerably. Most is happening behind the scenes though. Notably the webclient's javascript component is split into two:

    •  evennia.js, 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. 
    • evennia_gui.js is the default front-end and implements a traditional and stable "telnet-like" 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). 
    There are a truckload of more updates and features that are covered on the mailing list.
    .
    Griatch

    Sunday, February 14, 2016

    Climbing up Branches

    Today I pushed the latest Evennia development branch "wclient". This has a bunch of updates to how Evennia's webclient infrastructure works, by making all exchanged data be treated equal (instead of treating text separately from other types of client instructions).

    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.

    A much more detailed description of what is currently going on (including how to check out the latest for yourself) is found in this mailing list post. Enjoy!

    Thursday, November 12, 2015

    MIT uses Evennia!

    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.

    Researchers at MIT (Massachusetts Institute of Technology) recently presented the paper Language understanding for Text-based games using Deep reinforcement learning (PDF) at a conference on natural language processing. A summary is in the MIT press release.

    I was contacted by these fine folks some time ago so I knew they had plans to use Evennia for their research. It'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! 

    MUDs are tricky

    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'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.

    To test their AI, the researchers first used Evennia to build a simple training "Home World": a 4-room "house" 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.

    They then took this trained neural network and applied it to the real challenge, playing the Evennia Tutorial World. You can yourself try this out in our demo install or by just running a single command when starting Evennia. They call it "Fantasy World" in the article.

    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.

    A bridge too far

    As far as I understand from the article, the AI does understand to use commands with one or two arguments (like eat apple or the move red-root right), but they note that actually finding the tomb of the fallen hero (the main quest of the tutorial) is too hard for the AI:

    [...]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.
    So instead they evaluate the AI's performance on a more mundane task: Getting across the bridge to the castle. It'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 does play more due to the examples they use from other rooms; evaluating the bridge-crossing is just a clear-cut metric to use for "success".

    The MIT press release claims that the AI is also scored on how much health/magic it has, but I don't see that mentioned in the article itself (and the tutorial world only has magic if you find the hero's tomb which they claim they cannot do).

    The bridge in Evennia's tutorial world is actually a single "room" 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.

    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's given at any given time.

    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.

    Beyond the bridge

    The results are that after being trained on the training house setup, the AI will eventually be able to cross the bridge. The particular algorithm proposed also perform slightly better than the comparison ones (and a lot better than simple randomness).

    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 *actually* 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.

    Who knows, maybe the AI will even find that ancient tomb eventually!

    Image from MIT news

    Friday, October 2, 2015

    Emoting system, or how to chat up a girl

    A few days ago I pushed an emoting contribution to Evennia. A "contrib" is an optional plugin system that is not part of core Evennia but is meant to be easily picked up and used in people's own designs.

    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 dance 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:

    emote /me smiles at /cheerful as he sits at her table. "Hello!" he says.

    Now, this includes /keywords that relate to the objects in the room. So assuming there is a very cheerful girl in the room, this string will come out as 

    Griatch smiles at a very cheerful girl as he sits at her table. "Hello!" he says. 

    But she will actually see only my outward appearance (the short description) since she doesn't know me. So the cheerful girl (let's say her name is Sandra) would for example see

    A man in flowing robes smiles at Sandra as he sits at her table. "Hello!" he says.

    The emoting system has the following features: 

    • Short description replacement in emotes and in searches, as seen above. This means that you can do look cute and the system will know what you want to look at (in vanilla Evennia you'd need to use look Sandra).
    • Multi-word searching and disambiguation. If there is a cute girl and a cute puppy 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.
    • Recognition. You can assign your own aliases to people. If Sandra introduces herself you could assign her the name Sandra and henceforth be able to reference her as such and see that name appear. But you could also name her The girl calling herself Sandra if you didn't believe that's her actual name.
    • Languages. Everything within double-quotes is parsed as spoken language (like the Hello! above). By using writing this as (elvish)"Hello!", this could be spoken in another language and those who don't speak elvish would receive an obfuscated string.
    • Masking. A person wearing a mask can force people's recognition replacement to deactivate so that they are not recognized anymore.
    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!

    image ©Griatch, from griatch-art.deviantart.com

    Tuesday, September 29, 2015

    Evennia on Podcast.__init__

    So a few weeks back I was contacted by the general Python podcast Podcast.__init__. They had stumbled on Evennia and were intrigued about MUD development still going on - and in Python even! 

    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. 

    You can listen to my accent via one of the links below:
     

    Podcast.__init__ logo borrowed from their homepage.

    Monday, June 22, 2015

    Announcing the Evennia example-game project "Ainneve"

    The Evennia example-game project is underway!

    I was quite impressed with the response I got on the mailing list to my call for developing an Evennia example game (see my Need your Help blog post).

    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 "official" Evennia game is quite big.

    I'm happy to announce, however, that after only a week we now have a solid lead developer/manager, George Oliver. Helping him on the technical/architecture side is Whitenoise (who, despite a barren github profile, is a professional developer).

    George put together a game proposal based on the OpenAdventure rpg, an open-source (CC-SA) ruleset that is also found on github. The example game is to be named "Ainneve" and its development is found in a in a separate repository under the github Evennia organisation.

    All the relevant links and future discussion can be found on the mailing list.

    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!

    So thanks to George and whitenoise for taking this on, looking forward to see where it leads!


    image from loveintoblender.

    Monday, June 15, 2015

    Need your help

    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.

    We need an example game

    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'm talking "diku-like", 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'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 "code-heavy" MUD could easily be extracted and adopted to a more freeform-style game whereas the reverse is not generally true.

    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'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 Evennia github organisation - a spin-off from the main evennia project, and maintained separately.

    We need you!


    Thing is, while I am (and, I'm sure other Evennia core devs) certainly willing to give considerable help and input on such a project, it's not something I have time to take the lead on myself. So I'm looking for enthusiastic coders who would be willing to step up to both help and take the lead on this; both designing and (especially) coding such an example game. Even if you have your own game in mind for the future, you still 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.


    Suggestion for game

    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):
    • Generic fantasy theme (lore is not the focus here, but it can still be made interesting)
    • Character creation module
    • Races (say, 2-3)
    • Classes (say 2-3)
    • Attributes and Skills (based on D&D? Limit number of skills to the minimal set)
    • Rule module for making skill checks, rolls etc (D&D rules?)
    • Combat system (twitch? Turn-based?)
    • Mobs, both friendly and aggressive, with AI
    • Trade with NPC / other players (money system)
    • Quest system
    • Eventual new GM/admin tools as needed
    • Small game world (batch-built) to demonstrate all features (of good quality to show off)
    • More? Less?

    I'm interested!

    Great! We are as a first step looking for a driven lead dev for this project, a person who has the enthusiasm, coding experience and drive 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 "lead the charge" 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.

    Reply to this thread if you are willing to participate at any level to the project, including chipping in with code from your already ongoing development. I don't know if there'd be any "competition" over the lead-dev position but if multiple really enthusiastic and willing devs step forward we'll handle that then.

    So get in touch!