Saturday, January 27, 2018

The last few weeks I have reworked the way Evennia's startup procedure works. This is now finished in the develop branch so I thought I'd mention a little what's going on.

Evennia, being a server for creating and running text-games (MU*s), consists of two main processes:

The Portal - this is what players connect to with their clients.

The Server - 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.

Since Evennia should be easy to set up and 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:

Here I've excluded connections irrelevant to reloading, such as the Twisted AMP connection between Portal and Server. Dashed lines suggest a more "temporary" connection than a solid line.

The Launcher is the evennia program one uses to interact with the Server in the terminal/console. You give it commands like evennia start/stop/reload.

When starting, the Launcher spawns a new program, the Runner, 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 .pid files.

When reloading, the Launcher writes a flag in a little .restartfile. The Launcher then looks up the Server'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's .restart file. If that indicates a reload is desired, The Runner steps in its loop and starts up a new Server process.

When stopping, 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's .pid file and sends a SIGINT signal to kill it. Internally the processes catch the SIGINT and close gracefully.

The original reason for this Server-Portal-Runner setup is that the Portal is also reloadable in the same way (it's not shown above). But over time I'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 ...
It overall feels a little ... fiddly.

In develop branch, this is now the new process management setup:

The Portal is now a Twisted AMP server, while the Evennia Server and Launcher are AMP clients. The Runner is no more.

When starting, 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.

When reloading, 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.

When stopping, the Launcher sends the "Stop Server" 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 "Stop Portal" command to also stop the Portal. The Launcher waits until the Portal's AMP port dies, at which point it reports the shutdown to the user and stops itself.

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.

This solution gives much more control over the processes. It'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's instructions.
The launcher is now only a client connecting to a port, so one difference with this setup is that there is no more 'interactive' 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.

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.

Friday, January 5, 2018

Happy 2018 everyone! Here's a little summary of the past Evennia year and what is brewing.

(Evennia is a Python server- and toolbox for creating text-based multiplayer games (MU*)).

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 as described in my blog post here. But now 0.7 is released and a few initial minor adjustments could be made after feedback from daring pilot testers. The final process of migrating from 0.6 to 0.7 is, while involved, a step-by-step copy&paste list that has worked fine for most to follow. I've gotten far fewer questions and complains about it than could be expected so that's a good sign.

Working away on the boring but important behind-the-scenes stuff made me less able to keep up with more "mundane" issues and bugs popping up, or with adding new "fun" 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's really awesome to see others donating their time and energy adding to Evennia. The Hacktoberfest participation was also surprisingly effective in getting people to create PRs - I have a feeling some were just happy to have an "excuse" for getting started to contribute. We should attend that next year too.

One thing we added with 0.7 was a more formal branching structure: Evennia now uses fixed master and develop 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.

Now that Twisted is at a point where this is possible for us to do, we also now have a sort-of plan for finally moving Evennia to Python 3. I won't personally be actively working on it until after 0.8 is out though. I don't expect both Evennia 0.8 and 0.9 (which will be pure py3) to get released this year, but we'll see - so far contributors have done all the work on the conversion.

At any rate, this coming year will probably be dominated by catching up on issues and edge cases that are lining our Issue tracker. 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.

Finally, a continued great thank you to those of you contributing to the Patreon. 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!

Sunday, October 29, 2017

This article is a little different from the normal more technical Evennia-specific content of this blog. It was originally published as a light-hearted addition to the Imaginary Realities e-zine many years ago. While IR is still online it has since dozed off. So I'm reposting it here to bring it to a new audience.

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.

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.

Some terms used in the list:

Character concept - The general idea behind your player character (PC), like “The scarred veteran”, “The grumpy old magician” or “The swashbuckling bounty-hunter”.

IC/OOC - In-Character/Out-Of-Character.

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.

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.

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.

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.

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.

Scene starters

Scene starters are for when you are alone in a room hoping for others to join you (we'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'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.

The Scene starters below are intended as ideas and suggestions, but are also examples of archetypical behaviour I’ve observed myself.

The Barfly

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

The Strider

This is the "dark stranger in the corner" 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'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.

The Busybody

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.

The Demagogue

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 "arguing" with the NPC, playing both roles. The argument could be "continuing" 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.

The Damsel in Distress

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

The Organizer

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.

The Aggravator

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

The Stage Director

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

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.

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's important to remember to avoid god-modding here - never dictate another PCs actions, let other Players react as they see fit.

The Lazy Bum

This is unfortunately the most common of starters and we'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.

Scene entrances

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!

The Mouse

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.

The Ignoranti

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 "S/he does not notice the others yet". This entrance makes for a nice variation by allowing the ignoranti and other PCs to "accidentally" bump into each other later in a very natural way.

The Walker

The walker is just "passing through" 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's an effective entrance that allows for quick, logical exits as well (they just have to 'be on their way'). 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.

The Planned Visitor

This is a variation on Thebusybody and the opposite of The walker. Theplanned visitorneeds 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.

The Wet Kitten

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.

The Third Wheel

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.

In both cases it'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...”

The Theatrist

This is an on-the-fly version of the Stage director or demagogue. Only use if it'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't shove it down their throats (no god-modding!)

The Non-sequitur

This, strangely rare, entrance involves running into a crowded room, shouting "Monkeeey!" 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't do this unless you have a very specific and suitable character concept, kids.

The Newbie

The classic newbie entrance involves walking into a room and saying "Hello" to no one in particular. Bonus points if this is done while ignoring the fact that the room'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.

Sunday, October 1, 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!

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.

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.

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.