mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 04:57:16 +02:00
Updated reST documentation.
This commit is contained in:
parent
329a13bf8a
commit
4b29114a83
6 changed files with 169 additions and 19 deletions
|
|
@ -616,6 +616,29 @@ command must be added to a cmdset as well before it will work.
|
|||
def func(self):
|
||||
self.caller.msg("Don't just press return like that, talk to me!")
|
||||
|
||||
Exits
|
||||
-----
|
||||
|
||||
*Note: This is an advanced topic.*
|
||||
|
||||
The functionality of `Exit <Objects.html>`_ objects in Evennia is not
|
||||
hard-coded in the engine. Instead Exits are normal typeclassed objects
|
||||
that auto-creates a ``CmdSet`` on themselves when they are loaded. This
|
||||
cmdset has a single command with the same name (and aliases) as the Exit
|
||||
object itself. So what happens when a Player enters the name of the Exit
|
||||
on the command line is simply that the command handler, in the process
|
||||
of searching all available commands, also picks up the command from the
|
||||
Exit object(s) in the same room. Having found the matching command, it
|
||||
executes it. The command then makes sure to do all checks and eventually
|
||||
move the Player across the exit as appropriate. This allows exits to be
|
||||
extremely flexible - the functionality can be customized just like one
|
||||
would edit any other command.
|
||||
|
||||
Admittedly, you will usually be fine just using the appropriate
|
||||
``traverse_*`` hooks. But if you are interested in really changing how
|
||||
things work under the hood, check out ``src.objects.objects`` for how
|
||||
the default ``Exit`` typeclass is set up.
|
||||
|
||||
How commands actually work
|
||||
--------------------------
|
||||
|
||||
|
|
@ -684,3 +707,14 @@ Call ``func()`` on the command instance. This is the functional body of
|
|||
the command, actually doing useful things.
|
||||
|
||||
Call ``at_post_command()`` on the command instance.
|
||||
|
||||
Assorted notes
|
||||
--------------
|
||||
|
||||
The return value of ``Command.func()`` *is* safely passed on should one
|
||||
have some very specific use case in mind. So one could in principle do
|
||||
``value = obj.execute_cmd(cmdname)``. Evennia does not use this
|
||||
functionality at all by default (all default commands simply returns
|
||||
``None``) and it's probably not relevant to any but the most
|
||||
advanced/exotic designs (one might use it to create a "nested" command
|
||||
structure for example).
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ and running a text-based massively-multiplayer game
|
|||
your very own. You might just be starting to think about it, or you
|
||||
might have lugged around that *perfect* game in your mind for years ...
|
||||
you know *just* how good it would be, if you could only make it come to
|
||||
reality. We know how you feel. That is, after all why Evennia came to
|
||||
reality. We know how you feel. That is, after all, why Evennia came to
|
||||
be.
|
||||
|
||||
Evennia is in principle a MUD-building system: a bare-bones Python
|
||||
|
|
@ -33,11 +33,11 @@ will in that case all be optional.
|
|||
|
||||
What we *do* however, is to provide a solid foundation for all the
|
||||
boring database, networking, and behind-the-scenes administration stuff
|
||||
that all online games need whether they like it or not. Evennia is by
|
||||
default *fully persistent*, that means things you drop on the ground
|
||||
somewhere will still be there a dozen server reboots later. Through
|
||||
Django, we support a large variety of different database systems (the
|
||||
default of which is created for you automatically).
|
||||
that all online games need whether they like it or not. Evennia is
|
||||
*fully persistent*, that means things you drop on the ground somewhere
|
||||
will still be there a dozen server reboots later. Through Django we
|
||||
support a large variety of different database systems (a database is
|
||||
created for you automatically if you use the defaults).
|
||||
|
||||
Using the full power of Python throughout the server offers some
|
||||
distinct advantages. All your coding, from object definitions and custom
|
||||
|
|
@ -104,11 +104,11 @@ manual <http://code.google.com/p/evennia/wiki/Index>`_ with lots of
|
|||
examples. But while Python is a relatively easy programming language, it
|
||||
still represents a learning curve if you are new to programming. You
|
||||
should probably sit down with a Python beginner's
|
||||
`tutorial <http://docs.python.org/tutorial/tutorial>`_ (there are plenty
|
||||
of them on the web if you look around) so you at least know know what
|
||||
you are seeing. To efficiently code your dream game in Evennia you don't
|
||||
need to be a Python guru, but you do need to be able to read example
|
||||
code containing at least these basic Python features:
|
||||
`tutorial <http://docs.python.org/tutorial/>`_ (there are plenty of them
|
||||
on the web if you look around) so you at least know what you are seeing.
|
||||
To efficiently code your dream game in Evennia you don't need to be a
|
||||
Python guru, but you do need to be able to read example code containing
|
||||
at least these basic Python features:
|
||||
|
||||
- Importing python modules
|
||||
- Using variables, `conditional
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ Evennia:
|
|||
|
||||
**Python** (http://www.python.org)
|
||||
|
||||
- Version 2.5+ strongly recommended, although 2.3 or 2.4 **may** work.
|
||||
Obs- Python3.x is not supported yet.
|
||||
- Version 2.5+. Obs- Python3.x is not supported yet.
|
||||
- The default database system SQLite3 only comes as part of Python2.5
|
||||
and later.
|
||||
- Windows users are recommended to use ActivePython
|
||||
|
|
@ -97,8 +96,8 @@ Installing pre-requisites
|
|||
|
||||
**Linux** package managers should usually handle all this for you.
|
||||
Python itself is definitely available through all distributions. On
|
||||
Debian-derived systems you can do something like this (as root) to get
|
||||
all you need:
|
||||
Debian-derived systems (such as Ubuntu) you can do something like this
|
||||
(as root) to get all you need:
|
||||
|
||||
::
|
||||
|
||||
|
|
@ -164,6 +163,7 @@ In the future, you just do
|
|||
::
|
||||
|
||||
hg pull
|
||||
hg update
|
||||
|
||||
from your ``evennia/`` directory to obtain the latest updates.
|
||||
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ form.
|
|||
|
||||
::
|
||||
|
||||
django-admin.py compilemessages
|
||||
django-admin compilemessages
|
||||
|
||||
This will go through all languages and create/update compiled files
|
||||
(``*.mo``) for them. This needs to be done whenever a ``*.po`` file is
|
||||
updated.
|
||||
|
||||
When you are done, send the ``*.po`` and \*.mo file to the Evennia
|
||||
When you are done, send the ``*.po`` and ``*.mo`` file to the Evennia
|
||||
developer list (or push it into your own repository clone) so we can
|
||||
integrate your translation into Evennia!
|
||||
|
|
|
|||
|
|
@ -99,6 +99,121 @@ be named exactly like this):
|
|||
parsed. From inside Evennia, ``data_out`` is often called with the
|
||||
alias ``msg`` instead.
|
||||
|
||||
Out-of-band communication
|
||||
-------------------------
|
||||
|
||||
Out-of-band communication (OOB) is data being sent to and fro the
|
||||
player's client and the server on the protocol level, often due to the
|
||||
request of the player's client software rather than any sort of active
|
||||
input by the player. There are two main types:
|
||||
|
||||
- Data requested by the client which the server responds to
|
||||
immediately. This could for example be data that should go into a
|
||||
window that the client just opened up.
|
||||
- Data the server sends to the client to keep ut up-to-date. A common
|
||||
example of this is something like a graphical health bar - *whenever*
|
||||
the character's health status changes the server sends this data to
|
||||
the client so it can update the bar graphic. This sending could also
|
||||
be done on a timer, for example updating a weather map regularly.
|
||||
|
||||
To communicate to the client, there are a range of protocols available
|
||||
for MUDs, supported by different clients, such as MSDP and GMCP. They
|
||||
basically implements custom telnet negotiation sequences and goes into a
|
||||
custom Evennia Portal protocol so Evennia can understand it.
|
||||
|
||||
It then needs to translate each protocol-specific function into an
|
||||
Evennia function name - specifically a name of a module-level function
|
||||
you define in the module given by ``settings.OOB_FUNC_MODULE``. These
|
||||
function will get the session/character as first argument but is
|
||||
otherwise completely free of form. The portal packs all function names
|
||||
and eventual arguments they need in a dictionary and sends them off to
|
||||
the Server by use of the ``sessionhandler.oob_data_in()`` method. On the
|
||||
Server side, the dictionary is parsed, and the correct functions in
|
||||
``settings.OOB_FUNC_MODULE`` are called with the given arguments. The
|
||||
results from this function are again packed in a dictionary (keyed by
|
||||
function name) and sent back to the portal. It will appear in the Portal
|
||||
session's ``oob_data_out(data)`` method.
|
||||
|
||||
So to summarize: To implement a Portal protocol with OOB communication
|
||||
support, you need to first let your normal ``getData`` method somehow
|
||||
parse out the special protocol format format coming in from the client
|
||||
(MSDP, GMCP etc). It needs to translate what the client wants into
|
||||
function names matching that in the ``OOB_FUNC_MODULE`` - these
|
||||
functions need to be created to match too of course. The function name
|
||||
and arguments are packed in a dictionary and sent off to the server via
|
||||
``sessionhandler.oob_data_in()``. Finally, the portal session must
|
||||
implement ``oob_data_out(data)`` to handle the data coming back from
|
||||
Server. It will be a dictionary of return values keyed by the function
|
||||
names.
|
||||
|
||||
Example of out-of-band calling sequence
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's say we want our client to be able to request the character's
|
||||
current health. In our Portal protocol we somehow parse the incoming
|
||||
data stream and figure out what the request for health looks like. We
|
||||
map this to the Evennia ``get_health`` function.
|
||||
|
||||
We point ``settings.OOB_FUNC_MODULE`` to someplace in ``game/`` and
|
||||
create a module there with the following function:
|
||||
|
||||
::
|
||||
|
||||
# the caller is always added as first argument
|
||||
# we also assume health is stored as a simple
|
||||
# attribute on the character here.
|
||||
def get_health(character):
|
||||
return character.db.health
|
||||
|
||||
Done, this function will do just what we want. Let's finish up the first
|
||||
part of the portal protocol:
|
||||
|
||||
::
|
||||
|
||||
# this method could be named differently depending on the
|
||||
# protocol you are using (this is telnet)
|
||||
def lineReceived(self, string):
|
||||
# (does stuff to analyze the incoming string) outdict =
|
||||
if GET_HEALTH:
|
||||
# call get_health(char)
|
||||
outdict["get_health"] = ([], )
|
||||
elif GET_MANA:
|
||||
# call get_mana(char)
|
||||
outdict["get_mana"] = ([], )
|
||||
elif GET_CONFIG:
|
||||
# call get_config(char, 2, hidden=True)
|
||||
outdict["get_config"] = ([2], 'hidden':True) [...] self.sessionhandler.oob_data_out(outdict)
|
||||
|
||||
The server will properly accept this and call get\_health and get the
|
||||
right value for the health. We need to define an ``oob_data_out(data)``
|
||||
in our portal protocol to catch the return value:
|
||||
|
||||
::
|
||||
|
||||
def oob_data_out(self, data):
|
||||
# the indata is a dicationary funcname:retval outstring = ""
|
||||
for funcname, retval in data.items():
|
||||
if funcname == 'get_health':
|
||||
# convert to the right format for sending back to client, store
|
||||
# in outstring ...
|
||||
[...]
|
||||
|
||||
Above, once the dict is parsed and the return values properly put in a
|
||||
format the client will understand, send the whole thing off using the
|
||||
protocol's relevant send method.
|
||||
|
||||
Implementing auto-sending
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To have the Server update the client regularly, simply create a global
|
||||
`Script <Scripts.html>`_ that upon each repeat creates the request
|
||||
dictionary (basically faking a request from the portal) and sends it
|
||||
directly to
|
||||
``src.server.sessionhandler.oob_data_in(session.sessid, datadict)``.
|
||||
Repeat for all sessions. All specified OOB functions are called as
|
||||
normal and data will be sent back to be handled by the portal just as if
|
||||
the portal initiated the request.
|
||||
|
||||
Assorted notes
|
||||
--------------
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ root directory and type:
|
|||
::
|
||||
|
||||
hg pull
|
||||
hg update
|
||||
|
||||
Assuming you've got the command line client. If you're using a graphical
|
||||
client, you will probably want to navigate to the ``evennia`` directory
|
||||
|
|
@ -112,8 +113,8 @@ used (you have to give the ``mange.py migrate`` command as well as
|
|||
|
||||
Once you have a database ready and using South, you work as normal.
|
||||
Whenever a new Evennia update tells you that the database schema has
|
||||
changed (check ``hg log`` or the online list), you go to ``game/`` and
|
||||
run this command:
|
||||
changed (check ``hg log`` after you pulled the latest stuff, or read the
|
||||
online list), you go to ``game/`` and run this command:
|
||||
|
||||
::
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue