28 Feb, 2009, Barm wrote in the 1st comment:
Votes: 0
Hey Everyone,

I registered the other day and wanted to say hello. Last year I started coding a MUD in Python. My approach is single-threaded, tick-less, with an event scheduler and game data stored in YAML files. Eventually, persistent data will go into a SQLite database (especially since it's built into Python now).

I used to run a BBS in the early 90's and wrote some utilities and a couple DOOR games. I really enjoy working with Python and this is a chance to scratch on old itch.

Anyways, I had one of those moments where you sit back and say "Oh, that's cool" and wanted to share. I was coding an administrative shutdown procedure and wanted to give the users a little bit of warning when it's coming. My event scheduler takes a delay, a function, and an optional set of arguments. I was pondering where to stick these little one-use functions and then I remembered you can nest functions in Python (which I rarely use). My shutdown function became:

def shutdown(client):

"""Shutdown the server with a ten second warning to users."""

def second_warning():
broadcast("\n!! Server shutdown in 5 seconds. Please log off.\n")

def kill():
shared.SERVER_RUN = False

if client.verb_args:
client.send('\nShutdown command takes no arguments.')

else:
broadcast("\n!! Server shutdown in 10 seconds. Please log off.\n")
THE_SCHEDULER.add(5, second_warning)
THE_SCHEDULER.add(10, kill)


And testing it gave me:

$ telnet localhost 7777
Trying 127.0.0.1…
Connected to localhost.
Escape character is '^]'.
You enter The Lobby.
Welcome.
You may 'load' an existing character or 'create' a new one.

You receive a new ability: load
You receive a new ability: create
You receive a new ability: help
You receive a new ability: quit
You receive a new ability: shutdown
> shutdown fred

Shutdown command takes no arguments.
> shutdown

!! Server shutdown in 10 seconds. Please log off.

>
!! Server shutdown in 5 seconds. Please log off.
Connection closed by foreign host.


Okay, nothing earth shattering but it made me smile when it worked.

The YAML for my lobby room looks like this. The 'on_enter' block is converted into Python bytecode and stored in the room object under a dictionary of scripts.

uuid: 0c9997b9-5068-46d9-a245-12991bdf3f17
module: base
name: The Lobby
desc:

Welcome.

You may 'load' an existing character
or 'create' a new one.

on_enter: |

## Grant some commands

mob.grant_ability('load')
mob.grant_ability('create')
mob.grant_ability('help')
mob.grant_ability('quit')
mob.grant_ability('shutdown')

mob.prompt()


No, future visitors wont be offered the ability to shutdown the server at login. :grinning: Thanks for letting me ramble.
01 Mar, 2009, Idealiad wrote in the 2nd comment:
Votes: 0
I just wanted to say I totally dig the idea of a Python codebase using YAML. Also I'm curious if you have a public site for this project at all? I have a list of Python mud servers and if you'd like to add yours that'd be cool.
01 Mar, 2009, David Haley wrote in the 3rd comment:
Votes: 0
What's even cooler about local function definitions is that you create closures with them with local variables staying around.

def f(a):
def g(b):
return a + b
return g


Now calling f(1) gives you a function that adds 1 to its argument. So f(1)(2) will return 3.

Obviously this example is contrived, but I think you can see how you could apply it to create interesting event handler functions "on the fly" that remember something about the state they were created in.
01 Mar, 2009, Barm wrote in the 4th comment:
Votes: 0
Idealiad said:
I just wanted to say I totally dig the idea of a Python codebase using YAML. Also I'm curious if you have a public site for this project at all? I have a list of Python mud servers and if you'd like to add yours that'd be cool.


I'd like to and the code will be open source, but I still have tons of programming left to do before I'd call it presentable. I think YAML was a good call. One of my design goals is permit folks to design modules, like say 'The Haunted Goldmine (for levels 5-9)' and package them in a zip file you simply drop into your data directory. The module could contain new items, mobs, and quests which are indexed by UUID to avoid name clashes. The local admin/builder would have to create a route to it, which could be as simple as talking to the local innkeeper (aka the dungeon master's travel agent).
01 Mar, 2009, Barm wrote in the 5th comment:
Votes: 0
David Haley said:
What's even cooler about local function definitions is that you create closures with them with local variables staying around.
Obviously this example is contrived, but I think you can see how you could apply it to create interesting event handler functions "on the fly" that remember something about the state they were created in.


Neat. I read an article a few years back where a guy from Humongous Entertainment was using 'yield' inside his AI routines because generators not only retain their state, but pick up exactly where they left off. I find that especially appealing because of my single threaded server.
0.0/5