RIMpython Guide
Anders Petersson, demitar@worldforge.org
v0.1.1, 5 September 2001
This document is an introduction to the rimpython STAGE module (STAGE is an effort by the WorldForge Project). You can find the most recent version here.
1. Introduction
2. Playing text based WereWolf
3. Writing a game
1. Introduction
rimpython is a RIM with most of its functionality abstracted into python. Eventually most calculations should be done by calling c++ helper functions.
A RIM basically intercepts operations routed by pegasus, does some logic on them and replaces them with other ops.
1.1 Why should anubis/I care?
<Demitar> Basically server development was moving so slow I ran out of things to implement in silence-py and got bored. :)
<James> Becuase I told him to.
Official reason: Because it's vital to demonstrate that the RIM system is not tied to C++.
1.2 Installation
To install you need to get a copy of stage (and python of course) and apply some patches:
- Makefile.am
(stage/sys/) add
-lpython1.5to the stage linking.- Makefile.am
(stage/sys/pegasus/rim/) add
Py_Object.h/cppandrimpython.h/cppto the sources. (And perhaps you need to add-I/usr/include/python1.5to the INCLUDES too.)- pegasus.cpp
(stage/sys/pegasus/) apply the following patch:
Index: sys/pegasus/pegasus.cpp =================================================================== RCS file: /home/cvspsrv/worldforge/forge/servers/stage/sys/pegasus/pegasus.cpp,v retrieving revision 1.22 diff -c -r1.22 pegasus.cpp * sys/pegasus/pegasus.cpp 2001/07/26 10:45:50 1.22 --- sys/pegasus/pegasus.cpp 2001/09/05 15:51:44 *********** 27,32 *** --- 27,33 ----
#include "rim/rimcreate.h" #include "rim/rimchat.h" + #include "rim/rimpython.h"
#include
#include ************* 94,99 ** --- 95,117 ---- Galileo::log(2,1405, "Pegasus: Added RimChat as a RIM"); m_rim = rimchat; } + if(Config::inst()->getItem("pegasus","rim") == "rimpython"){ + RimPython rimpython = new RimPython(); + m_rimPre.push_back(RimItem("action",rimpython)); + m_rimPre.push_back(RimItem("create",rimpython)); + m_rimPre.push_back(RimItem("look",rimpython)); + m_rimPre.push_back(RimItem("talk",rimpython)); + m_rimPre.push_back(RimItem("imaginary",rimpython)); + m_rimEcos.push_back(RimItem("create",rimpython)); + m_rimEcos.push_back(RimItem("look",rimpython)); + m_rimEcos.push_back(RimItem("talk",rimpython)); + m_rimEcos.push_back(RimItem("imaginary",rimpython)); + m_rimPost.push_back(RimItem("sound",rimpython)); + m_rimPost.push_back(RimItem("sight",rimpython)); + m_rimPost.push_back(RimItem("info",rimpython)); + Galileo::log(2,1405, "Pegasus: Added RimPython as a RIM"); + m_rim = rimpython; + } } return true; } ************* 105,110 *** --- 123,131 ---- delete m_rim; } if(Config::inst()->getItem("pegasus","rim") == "rimchat"){ + delete m_rim; + } + if(Config::inst()->getItem("pegasus","rim") == "rimpython"){ delete m_rim; } }
- stage.conf
(stage/sys/) Add the following to the config:
[pegasus] rim = "rimpython"
2. Playing text based WereWolf
Disclaimer: This has nothing to do with the official WorldForge
WereWolf
and is a simple server-aided implementation (server narrates and filters
completely) of the social game with the same name. (This will hopefully keep
th3walrus from biting me. ;-)
2.1 Instructions
- Gather at least four people wanting to play werewolf in STAGE (in-game).
- Say: "start the werewolf session"
- Everyone is given their true identity and night falls.
- During the night seers, healers and werewolves act. Speech is filtered
so only werewolves hear other werewolves.
- seer
/look /who/- reveals the true identity of a character.- healer
/me charms /who/- protects a character from werewolves that night.- werewolf
Can speak with each other during the night.
/me votes for /who/- determines who you will vote for, even votes result in no attack.
When all actions are done the night ends.
- When the day comes the deeds done during the night are uncovered and
the villagepeople can vote to lynch someone.
/me votes for /who/- casts a vote, the status is then echoed to everyone. When no votes are left to be cast night falls. - If all werewolves or townspeople are dead the game ends otherwise it repeats.
Also, dead people can always talk to each other, hear werewolves and see their votes.
2.2 Bugs and Limitations
- Please note that all id matching is case sensitive.
- If someone gets disconnected or leaves the game is left in a non-finishable state.
- There is no vote changing; once all votes are counted, night/day ends that very instant. That's more of a pegasus restriction than a game limitation since no timeouts can occur (there are no timers).
3. Writing a game
Currently there are no helpers and you have to keep all data structures in python (read as: don't use it yet). And it is likely to break as soon as Lee cleans up the pegasus or rim code.
3.1 Checklist
- Create a new game module.
- Implement a world with logic.
- Make your game the default one.
3.2 The logic
Currently the magic happends in rimpython.py, when creating a new game
you essentially create a new game_*.py edit rimpython.py so it
imports your module and change createWorld() so it instantiates a world
from your module.
On init createWorld(id) is called, this is mainly a hack to pass a
worldid to python and allowing easy reloading of the game (explained more
below).
To handle objects that come from pegasus you simply define a callable object
(function or SomeClass.__call__), this will be called when the appropriate op
arrives from pegasus. A typical function definition would look like:
def look(op):
the function name called is determined by the first parent present in the incoming op.
When the op has been processed you should return a dict (or sequence of dicts) representation of the outgoing ops, all other return values are ignored.
3.3 Bugs and Limitations
Please note that entity registration currently uses the evil feature that info operations are parsed on their way out to register in-game ids, hopefully that won't work any longer when you read this. Also there is some evil id magic to allow reloading of the rim.
3.4 Development Helpers
I currently log all incoming and outgoing ops (to/from rimpython) to
rimpython.log this can be extremely helpful when you're wondering where
things bork.
To speed thing up I shortened the development cycle to edit-reload-test, to
reload you need to /load debug (in silence-py) and
/remote:reload, after that you need to recreate any characters so
they will be registered again.
| Current Issue: February 2003, Recent Issues: January 2003, November 2002, October 2002 |