Silence-py Guide

by Anders Petersson, demitar@worldforge.org
v0.1.1, 26 July 2001
This document is an introduction to the silence-py WorldForge client. You can find the most recent version here.

1. Introduction

2. User

3. Developer


1. Introduction

Silence-py is a textclient built on curses using python. It's targeted at being a test client for STAGE, reaching level 7 compliance before all other clients, becoming a dynamic client capable of all WorldForge games and eventually take over the world.

Hope you enjoy!

2. User

This section contains an introduction on how to use silence-py.

2.1 Starting out

Requirements

To run silence you need:

  1. python (>=1.5.2)
  2. A friend to hold your hand so you don't get scared by the silence.
  3. The python curses module. I you're using win32 you can get pdcurses from http://www.mikroplan.com.pl/~mak/python/ (Currently you need this since all the other interfaces are well behind.)

Optionally you can have use for:

Installation

To get up and running you need to do the following.

login to cvs

Read the cvs FAQ to find out how.

get silence-py

cvs checkout forge/clients/silence-py/

get Atlas-Python

cvs checkout forge/libs/Atlas-Python/

Since it's python you don't need to do more. ;-)

QuickStart

Change to the silence-py directory and run


demitar@dumle:~/dev/forge/clients/silence-py$ python silence.py

this will launch silence and it will give you the best interface available (curses of course :). Then tap into the prompt
/connect somewhere.over.the.rainbow

to connect to the specified STAGE server. When you have gotten a codec type
/login MrFroodiness

to login using your froody account tap in your pass and your login op is away. When STAGE finds out that it's MrFroodiness it will cry out loud that you don't have an account and you'll be prompted if you want to create your very own account which you of course do and then you type your password at the prompt.

Now that you've been logged in you can chat and use emotes just as in a normal irc client with a couple of extensions.

2.2 Commands

Help

The universal /help command lists the currently available commands with a short description. To get more extensive help you can /help which lists the short help, a syntax description and an optional longer description. You can generate a html/text file from this using gendoc.py or you can view the html version here.

Tab completion

All commands names can be tab completed, future enhancements might include nick completion, history completion and thought completion. To use it simply type the start of a command and press TAB it will then complete as much of the command possible unambiguously.

Modules

There are extension modules containing commands that are not enabled by default to load one of them type


/load 

currently only the referee module exists.

2.3 Commandline arguments

Interfaces

Automation

2.4 Configuration files

Note: The current config is dumped on exit into the file silence.conf.dump.

Locations

Configuration files are looked for in the combinations of the following directories and filenames:

Syntax

You specify sections as [section] and options as option=value with hash comments (# comment).

3. Developer

Here is an introduction for all prospective silence-py developers. ;-)

3.1 Commands

To create a new command you create a new class as follows:


# first derive it from the base command class
class MyCommand(Command):
    # specify a name, this can either be a string or a tuple or strings
    name = 'mycommand'
    # specify a short help string (this combined with the name should not
    # exceed about 50-60 chars to make it appear neatly on it's own row)
    # should not begin with a capital letter and not end in a dot
    help = 'do a sequence of foobar thingies'
    # optionally specify a longer description it should be entirely standalone
    #description = 'This can be multiline.'
    # specify a named list of arguments this is both used in syntax and
    # to retrieve the data inside the command currently three restrictions
    # apply must be compatible with a python function arg and must not
    # have the names 'text' or 'net' and no duplicates
    # this is apply()ed to the run method
    syntax_args = ('myarg',)
    # set a default, None means mandatory arg if you want a semi-empty
    # arg style demand it is '' which is treated as false but not None
    syntax_def = (None,)
    # regexps used to match the argument, these are blank separated so
    # the command needn't worry about that
    syntax_re = ("[^ ]+",)
    # note that all syntax args must be tuples of the same length or
    # the __init__ function will assert

# define a run method which is called from the base class' # __call__() method where args and all the other magic happends # I use the kw since I like to copy things around but you could # just as well make that named args (in this case myarg) def run(self, net, text, kw): # check some runtime magic against our arg if kw['myarg']=='microsoft': # if we detect an error that would've been too clumsy in the re # or perhaps a true runtime error you can raise self.error # which accepts a string which will be reported to the user raise self.error, "You have been infected, please implode." # if we had multiple names we could check which one was called # example: name = 'foo' then kw['__CMD__'] == '/foo' #if kw['__CMD__'][1]=='f': # do the foothing # to make something appear as those notices ('[notice] foo') # we call the textinterfaces notice method, unless we specify # a channel it comes in the current window (channels will be # reworked into objects sometime in the future) text.notice(kw['myarg']) # to make sure everyone else agrees on what we're saying we'd # better speak out loud (note that this is clumsy and to be # reworked as soon as I bother) # for now just accept this structure where the first are is what # you say and pass the two other and set the optional style # who the chat comes from is worked out automatically net.chat(kw['myarg'], text.channel_get(), inf=text) #, style='popup')


Finally you have to that the command actually gets registered by inserting it into the modules Load() method.


def Load(registerIn):
    registerIn(MyCommand())

By style this method should be defined first.

3.2 Command Modules

Module files are named command_.py. Currently the command module hierarchy is as follows:

+ Default modules (these are always loaded unless overridden in the config)
| + base (only depend on anything but the client itself)
| + net (these commands deal with the network)
| + game (you need to be logged in to use these)
+ Extension modules (these must be loaded using the /load command)
  + referee (commands to aid in rpg sessions and meetings)
  + debug (things that are not intended for public use)

3.3 Handlers

Currently a handler consists of one big function with a huge number of if ... elif cases. Enough to make pychecker complain:

handlers.py:50: Function (handler_main_interface) has too many branches (85)
handlers.py:50: Function (handler_main_interface) has too many lines (373)

This will be reworked into a more efficient recursive structure sometime in the future.

3.4 Commandline arguments

Currently there is no commandline parsing and if something wants to use a commandline arg they simply have to if '--arg' in sys.argv:. Something should be worked out using getopt sometime and should include means for automatic documentation extraction.

3.5 Configuration structure

The conf object that you see used throughout the code is a singleton that resides in the config module. To use it include this at the top of the module:


import config
conf = config.get()
del config

To set a default value (you should always do this at module level before you retrieve the value):


conf['section']['item'] = 'value'

To retrieve the current config (possibly overridden by the config file):


conf.get('section', 'item')

Please note that this:


conf['section']['item']

will retrieve the default and not the current config.

Some means of automatically documenting this, overriding config values and saving them back to disk should be developed.

3.6 Outstanding tasks

Note: The main source of things to do is the silence.py, this may shift towards this document or the website in the future however.

3.7 Wishlist tasks

Note: These are listed here not necessarily because they are difficult but because they aren't the primary goal.

Level 7 compliance

I made an informal analysis of the current status of silence in terms of client compliance and came up with this:

Level 0

Well not even level 0 since I miss the INSTALL file... but I wouldn't count that.. :)

Level 1

And no announcements on freshmeat for level 1 but I wouldn't count that either in this case.. :)

Level 2

Done.

Level 3

Done.

Level 4

Anymore container support needed? Otherwise Done.

Level 5

installation docs.. but I wouldn't count that :)

Level 6

Hmm... a couple of whitepapers, some more docs and freshmeat and I'll be up at level 6

Level 7

level 7 is simple with the pluggable structure of the client too

For level 7 the main target is to add handlers to make scripts such as patrol and follow:


patrol:
        on self.standing:
                move to next waypoint
follow:
        on other move:
                if too far:
                        walk close

With the advent of this paper I think silence-py might reach level 6.

Syntax completion etc

By syntax completion I mean intelligent completion based on what we know about the syntax if we try to complete /connect purple.w it should complete that to purple.worldforge.org since we naturally have been playing acorn on purple before.

Semantic completion would be a nice project for someone completing sentences based on what the person might want to say. It's not as much science fiction as it might sound as it could probably be archieved with a combination of Markov Chains and a grammar filter.

OpenGL

This is "working" but needs someone to look over it and clean it up. Especially make it update correctly. Perhaps someone would like to assimilate apogee instead? ;-)