2006-11-02

Visualization of Progress in MUDding using Python and RRDTool

I like skill-based, level-less MUDs, so this will be about one of such MUDs, but provided here scripts probably can be adopted to any MUD system or even to any log file. Skill-based MUDs send special message to player when he archives progress in character development. Such message can look like this:
 "You learned a trick of casting snake rune" 
Let's try to write some code which can visualise progress of character development on time axis. As input data we will use log of all mud sessions. Saving mud session to log-file can be configured in most mud clients. First we have to extract progression marks and their essence. This can be easily done using following *nix commands:
grep 'You learned a trick of ' atp_log_0 | \
sort | \
sed -e 's/You learned a trick of casting \([a-zA-Z ]\+\).*/\1/'
As a result we will get something like this:
...
snake rune
stoneskin
stoneskin
stoneskin
summon
summon
...
Now the harder part, we have to count occurrences of the same strings and put them to some database. To see changes in time we have to do this regularly, for example every hour. In this case rrdtool would be very good as database engine. Following Python script will do everything what we need:
#!/usr/bin/python

import os
import rrdtool
from sys import argv
from sys import exit

if len(argv) != 2:
    print "USAGE: %s prepared_log" % argv[0]
    exit(1)

lines = open(argv[1], "r").readlines()

counter = {}

spell = ""
for line in lines:
    line = line[:-1]
    if spell == line:
        counter[line] += 1
    else:
        counter[line] = 1
    spell = line

for spell in counter.keys():
    print spell + ": " + str(counter[spell])
    rrdFileName = spell + ".rrd"
    if not os.path.exists(rrdFileName):
        # create rrd file
        rrdtool.create(rrdFileName, '-s', '3600',
            'DS:data:COUNTER:86400:0:50000',
            'RRA:AVERAGE:0.5:1:5000')
        print "created: " + rrdFileName
    rrdtool.update(rrdFileName, 'N:' + str(counter[spell]))
Now we have to play MUD for few hours and collect data. Finally we can attempt to perform visualisation. Manual generation of image[s] with charts from all .rrd files can be tiring, so we will use following Python script:
#!/usr/bin/python

import os

RRD_EXT = ".rrd"

colors = ("B81818","5CDE00","0089DE",
    "1A1F14","DEC400","486B20","1216A1",
    "432A96","913F64","9A3C17","F4A179","4B7B47",
    "7E6C67","51D9F4","559E7B","4B4D35","D8980E","A32245")

defs = ""
lines = ""
num = 0;
numc = 0;
files = os.listdir(".")
for file in files:
    base,ext = os.path.splitext(file)
    if ext == RRD_EXT:
        color = colors[numc]
        defs += 'DEF:d%d="%s":data:AVERAGE ' % (num, file)
        lines += 'AREA:d%d#%s:"%s":STACK ' % (num, color, base)
        num += 1
        if len(colors) == numc:
            numc = 0;
        else:
            numc += 1

command = 'rrdtool graph test.png --end now --start end-58h ' + \
'--height 400 --width 600 ' + defs + ' ' + lines

k = os.system(command)
if k == 0:
    os.system("eog test.png")
else:
    print "error code: ", k
"eog" is a standard Gnome image viewer. Of course you can put here your favourite one.

No comments: