diff --git a/docs/sphinx/source/wiki/Attributes.rst b/docs/sphinx/source/wiki/Attributes.rst index f7f19b467d..147199e3c5 100644 --- a/docs/sphinx/source/wiki/Attributes.rst +++ b/docs/sphinx/source/wiki/Attributes.rst @@ -75,29 +75,15 @@ Attributes like you would any normal Python property: This looks like any normal Python assignment, but calls ``db`` behind the scenes for you. -Assigning attributes this way is intuitive and makes for slightly less -to write. There is a drawback to using this short-form though: Database -objects and typeclasses *already* have a number of Python methods and -properties defined on themselves. If you use one of those already-used -names with this short form you will not be setting a new Attribute but -will infact be editing an existing engine property. - -For example, the property ``self.location`` on yourself is tied directly -to the ``db_location`` database field and will not accept anything but -an ``ObjectDB`` object or it will raise a traceback. ``self.delete`` is -a method handling the deletion of objects, and so on. The reason these -are available is of course that you may *want* to overload these -functions with your own implementations - this is one of the main powers -of Evennia. But if you blindly do e.g. ``self.msg = "Hello"`` you will -happily be overloading the core ``msg()`` method and be in a world of -pain. - -Using ``db`` will always work like you expect. ``self.db.msg = 'Hello'`` -will create a new Attribute ``msg`` without affecting the core method -named ``msg()`` at all. So in principle, whereas you can use the -short-form for simple testing, it's best to use ``db`` when you want -Attributes and skip it only when you explicitly want to edit/overload -something in the base classes. +Note however that this form stands the chance of overloading already +existing properties on typeclasses and their database objects. +``rose.msg()`` is for example an already defined method for sending +messages. Doing ``rose.msg = "Ouch"`` will overload the method with a +string and will create all sorts of trouble down the road (the engine +uses ``msg()`` a lot to send text to you). Using +``rose.db.msg = "Ouch"`` will always do what you expect and is usually +the safer bet. And it also makes it visually clear at all times when you +are saving to the database and not. Persistent vs non-persistent ---------------------------- @@ -117,8 +103,10 @@ situations though. simply writes to memory, it doesn't hit the database at all. It should be said that with the speed and quality of hardware these days, this point is less likely to be of any big concern except for - the most extreme of situations. The default database even runs in RAM - if possible, alleviating the need to write to disk. + the most extreme of situations. Modern database systems cache data + very efficiently for speed. Our default database even runs completely + in RAM if possible, alleviating much of the need to write to disk + during heavy loads. - You *want* to loose your state when logging off. Maybe you are testing a buggy `Script `_ that does potentially harmful stuff to your character object. With non-persistent storage @@ -205,29 +193,31 @@ example, you can do :: # saving data + obj.db.mydict = "key":"test0" obj.db.mydict["key"] = "test1" - obj.db.mylist[34] = "test2" + obj.db.mylist = [0,1,2,3] + obj.db.mylist[3] = "test2" obj.db.mylist.append("test3") # retrieving data obj.db.mydict["key"] # returns "test1" - obj.db.mylist[34] # returns "test2 + obj.db.mylist[3] # returns "test2 obj.db.mylist[-1] # returns "test3" and it will work fine, thanks to a lot of magic happening behind the -scenes. What will *not* work however is editing *nested* -lists/dictionaries in-place. This is due to the way Python referencing -works. Consider the following: +scenes. What will *not* work however is *assigning nested +lists/dictionaries in-place*. This is due to the way Python referencing +works, no way around it alas. Consider the following: :: obj.db.mydict = 1:2:3 This is a perfectly valid nested dictionary and Evennia will store it -just fine. +just fine. Retrieving this data will also work normally: :: - obj.db.mydict[1][2] # correctly returns 3 + val = obj.db.mydict[1][2] # correctly returns 3 However: @@ -237,9 +227,10 @@ However: will not work - trying to edit the nested structure will fail silently and nothing will have changed. No, this is not consistent with normal -Python operation, it's where the database magic fails. All is not lost -however. In order to change a nested structure, you simply need to use a -temporary variable: +Python operation, it's where the database magic fails. Sorry, but there +does not seem to be a way around this (if you know one, let us know!) +All is not lost however. In order to change a nested structure, you +simply need to use a temporary variable: :: @@ -250,7 +241,7 @@ temporary variable: # save back to database obj.db.mydict = mydict # test - obj.db.mydict[1][2] # now correctly returns "test" + val = obj.db.mydict[1][2] # now correctly returns "test" mydict was updated and recreated in the database. diff --git a/docs/sphinx/source/wiki/Commands.rst b/docs/sphinx/source/wiki/Commands.rst index 0e1787cbe4..f53006ab94 100644 --- a/docs/sphinx/source/wiki/Commands.rst +++ b/docs/sphinx/source/wiki/Commands.rst @@ -621,7 +621,7 @@ non-commands as text input. - New session connection ('cmdhandler.CMD\_LOGINSTART'). This command name should be put in the ``settings.CMDSET_UNLOGGEDIN``. Whenever a new connection is established, this command is always called on the - the server (default is to show the login screen). + server (default is to show the login screen). Below is an example of redefining what happens when the player don't give any input (e.g. just presses return). Of course the new system diff --git a/docs/sphinx/source/wiki/Communications.rst b/docs/sphinx/source/wiki/Communications.rst index 93232fbda7..1802b1f3d3 100644 --- a/docs/sphinx/source/wiki/Communications.rst +++ b/docs/sphinx/source/wiki/Communications.rst @@ -33,15 +33,9 @@ Properties defined on ``Msg`` to. - ``channels`` - a list of target Channels to send to. - ``message`` - the actual text being sent -- ``date_sent`` - when message was sent. +- ``date_sent`` - when message was sent (auto-created). - ``locks`` - a `lock definition `_. -The following is currently unimplemented in Evennia (stay tuned): - -- hide*from*sender - bool if message should be hidden from sender -- hide*from*receivers - list of receiver objects to hide message from -- hide*from*channels - list of channels objects to hide message from - You create new messages in code using ``src.utils.create.create_message.`` @@ -64,7 +58,9 @@ There are three default channels created in stock Evennia - ``MUDinfo``, ``MUDconnections`` and ``Public``. Two first ones are server-related messages meant for Admins, the last one is open to everyone to chat on (all new players are automatically joined to it when logging in, useful -for asking questions). +for asking questions). The default channels created are defined by +``settings.CHANNEL_PUBLIC``, ``settings.CHANNEL_MUDINFO`` and +``settings.CHANNEL_CONNECTINFO``. You create new channels with ``src.utils.create.create_channel()``. diff --git a/docs/sphinx/source/wiki/DeveloperCentral.rst b/docs/sphinx/source/wiki/DeveloperCentral.rst index d82baf68fd..a8d0d603f9 100644 --- a/docs/sphinx/source/wiki/DeveloperCentral.rst +++ b/docs/sphinx/source/wiki/DeveloperCentral.rst @@ -70,6 +70,12 @@ Programming Evennia - `Adding a Command prompt `_ - `Running processes asynchronously `_ +Game implementation hints +------------------------- + +- `Creating a Zoning system `_ +- `Implementing cooldowns for commands `_ + Work in Progress - Developer brainstorms and whitepages ------------------------------------------------------- diff --git a/docs/sphinx/source/wiki/DirectoryOverview.rst b/docs/sphinx/source/wiki/DirectoryOverview.rst index e55cc01083..646c7275c8 100644 --- a/docs/sphinx/source/wiki/DirectoryOverview.rst +++ b/docs/sphinx/source/wiki/DirectoryOverview.rst @@ -24,7 +24,10 @@ up-to-date documentation is the online wiki however. Read ``sphinx/README`` for instructions on building the ReST documentation, based on a current snapshot of the wiki. This can be -browsed offline or made into a PDF for printing etc. +browsed offline or made into a PDF for printing etc. Since these files +are automatically converted directly from the wiki files, there may be +formatting problems here and there, especially if trying to convert to +printable format. You can create the Evennia *autodocs* by following the instructions in ``doxygen/README``. This will make use of the source code itself to @@ -66,22 +69,14 @@ the server. evennia.py manage.py gamesrc/ commands/ - basecommand.py - basecmdset.py examples/ - cmdset_red_button.py scripts/ - basescript.py examples/ - red_button_sripts.py objects/ - baseobjects.py examples/ - red_button.py world/ examples/ - batch_cmds.ev - batch_code.py + conf/ ``game/gamesrc/`` ~~~~~~~~~~~~~~~~~ @@ -126,18 +121,17 @@ Button* object itself. ``gamesrc/world/`` ^^^^^^^^^^^^^^^^^^ -``gamesrc/world/``, finally, contains all the rest that make up your -world. This is where you would put your own custom economic system, -combat mechanic, emote-parser or what have you; organized in whatever -way you like. Just remember that if you create new folders under -``world``, they must contain an empty file ``__init__.py``, or Python -will not know how to import modules from them. The ``world`` folder is -also where Evennia's `batch processors `_ by -default look for their input files. These allow you to build your world -offline using your favourite text editor rather than have to do it -online over a command line. The `Batch-Command -processor `_ expects files ending with -``.ev``, whereas the more advanced `Batch-Code +``gamesrc/world/``, contains all the rest that make up your world. This +is where you would put your own custom economic system, combat mechanic, +emote-parser or what have you; organized in whatever way you like. Just +remember that if you create new folders under ``world``, they must +contain an empty file ``__init__.py``, or Python will not know how to +import modules from them. The ``world`` folder is also where Evennia's +`batch processors `_ by default look for their +input files. These allow you to build your world offline using your +favourite text editor rather than have to do it online over a command +line. The `Batch-Command processor `_ +expects files ending with ``.ev``, whereas the more advanced `Batch-Code processor `_ takes ``.py`` with some special formatting. @@ -145,6 +139,17 @@ formatting. creates a *Red Button* object in *Limbo* using their respective special syntax. +``gamesrc/conf/`` +^^^^^^^^^^^^^^^^^ + +``gamesrc/world/`` holds optional extension modules for the Evennia +engine. Certain functionality in the server is meant to be extended, and +in order to allow you to do this without modifying the server itself, it +imports files from this directory. Modifying these are optionally and +you can usually change a variable in ``game/settings.py`` to change +which module Evennia is looking for. There are dummy example files in +here, read their headers for usage instructions. + The ``src/`` directory ---------------------- diff --git a/docs/sphinx/source/wiki/EvenniaIntroduction.rst b/docs/sphinx/source/wiki/EvenniaIntroduction.rst index 5b70931941..b350bd16b9 100644 --- a/docs/sphinx/source/wiki/EvenniaIntroduction.rst +++ b/docs/sphinx/source/wiki/EvenniaIntroduction.rst @@ -8,8 +8,7 @@ and actions performed in the virtual world. Players typically interact with each other and the world by typing commands that resemble a natural language.*" - `Wikipedia `_ -Evennia introduction -==================== +Evennia introduction= If you are reading this, it's quite likely you are dreaming of creating and running a text-based massively-multiplayer game @@ -54,15 +53,8 @@ commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on. Or why not create a new and better command system of your own design. -There is already a default django website as well as an ajax web client -shipping with Evennia. You can also edit the database from the browser -using the admin interface. Apart from telnet, SSH, SSL and web -connections, you can connect e.g. IRC and IMC2 channels to evennia's -in-game channels so that your players can chat with people "outside" the -game. - Can I test it somewhere? ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ There are Evennia-based muds under development but they are still not publicly available. If you do try to install Evennia (it's not hard), it @@ -74,6 +66,63 @@ tutorial takes only one single in-game command to install as explained If you didn't see it before, here is also a `screenshot `_ of Evennia running. +Brief summary of features +========================= + +Technical +~~~~~~~~~ + +- Game development is done by the server importing your normal Python + modules. Specific server features are implemented by overloading + hooks that the engine calls appropriately. +- All game entities are simply Python classes that handles database + negotiations behind the scenes without you needing to worry. +- Command sets are stored on individual objects (including characters) + to offer unique functionality and object-specific commands. Sets can + be updated and modified on the fly to expand/limit player input + options during play. +- Scripts are used to offer asynchronous/timed execution abilities. + Scripts can also be persistent. There are easy mechanisms to thread + particularly long-running processes. +- In-game communication channels are modular and can be modified to any + functionality, including mailing systems and full logging of all + messages. +- Server can be fully rebooted/reloaded without users disconnecting. +- A session (player) can freely connect/disconnect from game-objects, + offering an easy way to implement multi-character systems and + puppeting. +- All source code is extensively documented. +- Unit-testing suite, including tests of default commands and plugins + +Default content +~~~~~~~~~~~~~~~ + +- Basic classes for Objects, Characers, Rooms and Exits +- Basic login system, using the Player's login name as their in-game + Character's name for simplicity +- "MUX-like" command set with administration, building, puppeting, + channels and social commands +- In-game Tutorial +- Contributions folder with working, but optional, code such as + alternative login, menus, character generation and more + +Standards/Protocols supported +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Telnet with mud-specific extensions (MCCP, MSSP, TTYPE) +- SSH +- SSL +- TCP/Comet, JavaScript browser webclient included +- HTTP - Website served by in-built webserver and connected to same + database as game. +- IRC/IMC2 - external IRC and/or IMC2 channels can be connected to + in-game chat channels +- ANSI, xterm256 colours +- Several different databases supported (SQLite3, MySQL, ...) + +For more extensive feature information, see +`here `_. + What you need to know to work with Evennia ========================================== diff --git a/docs/sphinx/source/wiki/Links.rst b/docs/sphinx/source/wiki/Links.rst index a23512e424..f89d805e65 100644 --- a/docs/sphinx/source/wiki/Links.rst +++ b/docs/sphinx/source/wiki/Links.rst @@ -32,6 +32,33 @@ Third-party Evennia links - `Evennia on PyPi `_ +General mud/game development ideas and discussions +-------------------------------------------------- + +- `MudLab `_ mud design discussion forum +- `MudConnector `_ mud listing and forums +- `MudBytes `_ mud listing and forums +- `Top Mud bytes `_ mud listing and forums +- `MudStandards wiki `_ + is an attempt at gathering protocol standards for MUD servers. + +- `Planet Mud-Dev `_ is a blog + aggregator following blogs of current MUD development around the + 'net. +- Mud Dev mailing list archive + (`mirror1 `_),(`mirror2 `_) + - Influential mailing list active 1996-2004. Advanced game design + discussions. +- `Imaginary + Realities `_ is + an e-magazine on game/MUD design which were active 1998-2001. + Interesting articles. + +- `Lost Garden `_ is a game development + blog with long and interesting articles (not MUD-specific) +- `What Games Are `_ is a blog about general + game design (not MUD-specific) + Frameworks ---------- diff --git a/docs/sphinx/source/wiki/Locks.rst b/docs/sphinx/source/wiki/Locks.rst index 89a17a7956..e9d33864f7 100644 --- a/docs/sphinx/source/wiki/Locks.rst +++ b/docs/sphinx/source/wiki/Locks.rst @@ -63,19 +63,9 @@ Defining locks Defining a lock (i.e. an access restriction) in Evennia is done by adding simple strings of lock definitions to the object's ``locks`` -property using ``obj.locks.add()``. Such a *lockstring* formally looks -like this: +property using ``obj.locks.add()``. -:: - - access_type:[NOT] func1([arg1,..])[[AND|OR][ NOT] func2([arg1,...])[...]] - -where ``[..]`` marks optional parts. AND, OR and NOT are not case -sensitive and excess spaces are ignored. ``func1, func2`` etc are -special *lock functions* available to the lock system. - -This form of writing may look complicated, so let's immediately give -some much nicer examples: +Here are some examples of lock strings: :: @@ -83,7 +73,17 @@ some much nicer examples: edit:all() # let everyone edit get: not attr(very_weak) or perm(Wizard) # only those who are not "very_weak" or are Wizards may pick this up -So, a lockstring consists of the type of restriction (the +Formally, a lockstring has the following syntax: + +:: + + access_type:[not] func1([arg1,..])[[and|or][ not] func2([arg1,...])[...]] + +where ``[..]`` marks optional parts. AND, OR and NOT are not case +sensitive and excess spaces are ignored. ``func1, func2`` etc are +special *lock functions* available to the lock system. + +So, a lockstrings consists of the type of restriction (the ``access_type``), a colon (``:``) and then a list of function calls that determine what is needed to pass the lock. Each function returns either ``True`` or ``False``. AND/OR and NOT works like normal Python to diff --git a/docs/sphinx/source/wiki/Scripts.rst b/docs/sphinx/source/wiki/Scripts.rst index d750399119..faf8c2881c 100644 --- a/docs/sphinx/source/wiki/Scripts.rst +++ b/docs/sphinx/source/wiki/Scripts.rst @@ -26,7 +26,7 @@ leaving the remaining poor characters in darkness once again. By combining state-changes with timers one can make a room look different during nighttime than it does during the day. Weather and seasons might come and go. But one can also achieve more complex things -such as state-AI systems that make mobs move around and possibly persue +such as state-AI systems that make mobs move around and possibly pursue characters between rooms. ... In short, Scripts make the game world *tick*. Scripts are @@ -130,6 +130,30 @@ find longer descriptions of these in ``gamesrc/scripts/basescript.py``. - ``at_stop()`` - this is called when the script stops for whatever reason. It's a good place to do custom cleanup. +Running methods (usually called automatically by the engine, but +possible to also invoke manually) + +- ``start()`` - this will start the script. This is called + automatically whenever you add a new script to a handler. + ``at_start()`` will be called. +- ``stop()`` - this will stop the script and delete it. Removing a + script from a handler will stop it auomatically. ``at_stop()`` will + be called. +- ``pause()`` - this pauses a running script, rendering it inactive, + but not deleting it. Timers are saved and can be resumed. This is + called automatically when the server reloads. No hooks are called - + this is a suspension of the script, not a change of state. +- ``unpause()`` - resumes a previously paused script. Timers etc are + restored to what they were before pause. The server unpauses all + paused scripts after a server reload. No hooks are called - as far as + the script is concerned, it never stopped running. +- ``time_until_next_repeat()`` - for timed scripts, this returns the + time in seconds until it next fires. Returns None if not a timed + script. + +Example script +-------------- + :: import random @@ -173,10 +197,18 @@ Or, from in-game, use the ``@script`` command: @script here = weather.Weather -Further notes -------------- +Global scripts +-------------- -Should you *really* need to create a script unrelated to a particular -Object (this is called a *Global* script), you can create it with -``src.utils.create.create_script()`` and refrain from supplying an -object to store it on. See that module for more info. +You can create scripts that are not attached to a given object - +*Global* scripts. You can create such a script with +``src.utils.create.create_script()`` by refrainnig from supplying an +object to store it on. + +:: + + from src.utils.create import create_script + create_script(globals.MyGlobalEconomy, key="economy", obj=None) + +Assuming ``game.gamesrc.scripts.global.MyGlobalEconomy`` can be found, +this will create and start it as a global script. diff --git a/docs/sphinx/source/wiki/Typeclasses.rst b/docs/sphinx/source/wiki/Typeclasses.rst index 0d2b7513f4..a846c5e8b9 100644 --- a/docs/sphinx/source/wiki/Typeclasses.rst +++ b/docs/sphinx/source/wiki/Typeclasses.rst @@ -21,12 +21,14 @@ basically means that they are (almost) normal Python classes that hide underlying database models ... ... and that's basically all you *really* need to know about how -typeclasses work behind the scenes. To work with them you should know -that all the listed game entities inherit a common interface from the -typeclass system, properties you can *always* expect a typeclassed -entity to have *beyond* the more specialized properties unique to each -sub-type. Typeclasses also do some special things with their in-built -class methods that you shouldn't edit. +typeclasses work behind the scenes. + +To work with them you should however know that all the listed game +entities inherit a common interface from the typeclass system, +properties you can *always* expect a typeclassed entity to have *beyond* +the more specialized properties unique to each sub-type. Typeclasses +also do some special things with their in-built class methods that you +shouldn't edit. Properties available to all typeclassed entities (Players, Objects, Scripts) @@ -97,7 +99,7 @@ a few things that you need to remember however: or you *will* crash the server! You have been warned. How typeclasses actually work ------------------------------ +============================= \_You don't need to read this section to use typeclassed entities, but it might be useful if you want to do advanced things or are interested