diff --git a/docs/README.txt b/docs/README.txt index a5b53ef066..9f4aaf4466 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -1,14 +1,19 @@ -=========== -DOCS README -=========== -* Evennia docs and manual +EVENNIA DOCUMENTATION +===================== - - The most updated documentation is found in the online wiki, - http://code.google.com/p/evennia/wiki/Index - + - Evennia is extensively documented. Our manual is the + continuously updating online wiki, + + https://github.com/evennia/evennia/wiki + + - Snapshots of the manual are also mirrored in reST + form to ReadTheDocs: + + http://evennia.readthedocs.org/en/latest/ + - You can also ask for help from the evennia community, http://groups.google.com/group/evennia @@ -17,45 +22,11 @@ DOCS README #evennia on the Freenode network - ------------------------- -* Sphinx Manuals ------------------------- - - The folder docs/sphinx contains a source tree with Evennia's online wiki - formatted into reStructuredText for easy (and good looking!) offline - browsing or printing. - - To build the sources you need to install Sphinx. Linux users can get it - through their package managers (in Debian it's called python-sphinx). Or - you can download it here: - - http://sphinx.pocoo.org/index.html - - Go into docs/sphinx and run - - make html - - You will see a lot of output (and probably some errors too, Evennia's docs - are not formatted to reST format by default). When done, point your - web browser to docs/sphinx/build/html/index.html to see the nice manual. - - If you don't want html output, you can output to a host of other formats, - use just "make" for a list of options. - - - Note: In docs/sphinx are two more dirs, wiki2rest and src2rest. These - can be used to create reST-formatted documentation from raw sources. - They depend on a host of external libraries however, so best stay away - from them unless you are an Evennia dev. Read the headers of the - respective *.py files for instructions. - - ------------------- * Doxygen auto-docs ------------------- - In docs/doxygen you can build the developer auto-docs + You can build the developer auto-docs (a fancy searchable index of the entire source tree). This makes use of doxygen, a doc generator that parses the source tree and creates docs on the fly. @@ -63,12 +34,14 @@ DOCS README - Install doxygen (v1.7+) Doxygen is available for most platforms from + http://www.stack.nl/~dimitri/doxygen/ + or through your package manager in Linux. - Run - > doxygen config.dox + doxygen config.dox This will create the auto-docs in a folder 'doxygen/html'. @@ -82,12 +55,62 @@ DOCS README will be created with the latex sources. With the latex processing system installed, then run - > make + make in the newly created folder to create the pdf. Be warned however that the pdf docs are >340 pages long! - - Doxyfile is lavishly documented and allows for plenty of - configuration to get the docs to look the way you want. - You can also output to other formats suitable for various - developer environments, Windows help files etc. + - Doxyfile is allows for plenty of configuration to get the + docs to look the way you want. You can also output to other + formats suitable for various developer environments, Windows + help files etc. + +------------------------ +* Sphinx Manuals +------------------------ + + If you want to build the reST manuals yourself, you basically need to + convert the wiki. First place yourself in a location where you want + to clone the wiki repo to, then clone it: + + git clone https://github.com/evennia/evennia.wiki.git + + - Enter this directory and check out the sphinx branch: + + git checkout sphinx + + This branch has, apart from all the wiki pages (*.md files), also has a + an extra directory sphinx/ that will hold the converted data. + + - You need Pandoc for the markdown-to-reST conversion: + + http://johnmacfarlane.net/pandoc/installing.html + + You need a rather recent version. The versions coming with some linux + repos are too old to support "github-flavoured markdown" conversion. + See that page for getting the Haskill build environment in that case. + + - You also need sphinx, + + http://sphinx-doc.org/ + + You can most likely get it with 'pip install sphinx' under Linux. + + - With all this in place, go to the pylib/ folder and run the + converter script: + + python update_rest_docs.py + + If all goes well, you will see all the wiki pages getting converted. + The converted *.rst files will end up in the sphinx/ directory. + + - Finally, go to sphinx/ and run + + make html + + If sphinx is installed, this will create the html files in + sphinx/.build. To look at them, point your browser to + + /sphinx/.build/index.html + + diff --git a/docs/config.dox b/docs/config.dox new file mode 100644 index 0000000000..54e910a5e1 --- /dev/null +++ b/docs/config.dox @@ -0,0 +1,288 @@ +# Doxyfile 1.8.1.2 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "Evennia" +PROJECT_NUMBER = Git-Beta +PROJECT_BRIEF = Python MUD development system +PROJECT_LOGO = ../../src/web/media/images/evennia_logo_small.png +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../.. +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.py +RECURSIVE = YES +EXCLUDE = ../../docs +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = 0*.py +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 8 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = YES +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/docs/doxygen/config.dox b/docs/doxygen/config.dox deleted file mode 100644 index 1e74706122..0000000000 --- a/docs/doxygen/config.dox +++ /dev/null @@ -1,1716 +0,0 @@ -# Doxyfile 1.7.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = Evennia - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = SVN-Alpha - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = Python MUD server - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = ../../src/web/media/images/evennia_logo_small.png - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = ../../ - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.py - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = docs */migrate/ - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/docs/sphinx/Makefile b/docs/sphinx/Makefile deleted file mode 100644 index 6027ca32be..0000000000 --- a/docs/sphinx/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Evennia.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Evennia.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Evennia" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Evennia" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/sphinx/README.txt b/docs/sphinx/README.txt deleted file mode 100644 index a5425a8c1c..0000000000 --- a/docs/sphinx/README.txt +++ /dev/null @@ -1,18 +0,0 @@ - - -Wiki convertion and autodocs ----------------------------- - -The source/ directory contains Evennia's wiki documentation converted -to ReST form. This can be built to a html document by installing -python-sphinx (sphinx-doc.org) and running 'make html' from this -directory. The output will appear in under build/ - point your browser -to the index.html file. - -If you want to (re-)build the documentation yourself, wiki2rest/ -contains programs for converting Evennia's wiki documentation to ReST -files. Read the header of wiki2rest.py for setting up the converter. - -The src2rest folder contains a reprecated program for building -documented ReST source code from Evennia's documentation. You can -arguably get as good autodocs using doxygen. diff --git a/docs/sphinx/make.bat b/docs/sphinx/make.bat deleted file mode 100644 index 0cffde5278..0000000000 --- a/docs/sphinx/make.bat +++ /dev/null @@ -1,170 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Evennia.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Evennia.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/docs/sphinx/source/conf.py b/docs/sphinx/source/conf.py deleted file mode 100644 index e7ec5179fe..0000000000 --- a/docs/sphinx/source/conf.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Evennia documentation build configuration file, created by -# sphinx-quickstart on Sat Sep 10 14:19:20 2011. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. - -EVENNIA_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) -sys.path.insert(0, EVENNIA_ROOT) -sys.path.insert(0, os.path.dirname(EVENNIA_ROOT)) # also import top container -os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings' - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['.templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Evennia' -copyright = u'2012, Evennia-development team' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = 'Beta' -# The full version, including alpha/beta/rc tags. -release = 'Beta' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = "../../../src/web/media/images/evennia_logo_small.png" - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = "../../../src/web/media/images/favicon.ico" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['.static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Evenniadoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Evennia.tex', u'Evennia Documentation', - u'Evennia-devs', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -latex_logo = "../../../src/web/media/images/evennia_logo_small.png" - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'evennia', u'Evennia Documentation', - [u'Evennia-devs'], 1) -] diff --git a/docs/sphinx/source/contents.rst b/docs/sphinx/source/contents.rst deleted file mode 100644 index 34771bba49..0000000000 --- a/docs/sphinx/source/contents.rst +++ /dev/null @@ -1,74 +0,0 @@ - -Alphabetical page index -======================= - -.. toctree:: - :titlesonly: - - wiki/AddingCommandTutorial - wiki/AddingObjectTypeclassTutorial - wiki/AdminDocs - wiki/ApacheConfig - wiki/AsyncProcess - wiki/Attributes - wiki/Banning - wiki/BatchCodeProcessor - wiki/BatchCommandProcessor - wiki/BatchProcessors - wiki/BuilderDocs - wiki/BuildingPermissions - wiki/BuildingQuickstart - wiki/Caches - wiki/ChoosingAnSQLServer - wiki/CodingIntroduction - wiki/CodingUtils - wiki/Colours - wiki/CommandCooldown - wiki/CommandPrompt - wiki/Commands - wiki/Communications - wiki/ConnectionScreen - wiki/Contributing - wiki/DefaultCommandHelp - wiki/DeveloperCentral - wiki/DirectoryOverview - wiki/evAPI - wiki/EvenniaDevel - wiki/EvenniaIntroduction - wiki/ExecutePythonCode - wiki/GamePlanning - wiki/GettingHelp - wiki/GettingStarted - wiki/HelpSystem - wiki/IMC2 - wiki/Index - wiki/Internationalization - wiki/IRC - wiki/Licensing - wiki/Locks - wiki/Nicks - wiki/Objects - wiki/OnlineSetup - wiki/Players - wiki/PortalAndServer - wiki/Quirks - wiki/RemovingColour - wiki/RSS - wiki/Scripts - wiki/ServerConf - wiki/SessionProtocols - wiki/SoftCode - wiki/StartStopReload - wiki/TextEncodings - wiki/TickerScripts - wiki/Tutorials - wiki/TutorialWorldIntroduction - wiki/Typeclasses - wiki/UnitTesting - wiki/UpdatingYourGame - wiki/UsingMUXAsAStandard - wiki/VersionControl - wiki/WebFeatures - wiki/Workshop - wiki/WorkshopDefaultGame - wiki/Zones diff --git a/docs/sphinx/source/index.rst b/docs/sphinx/source/index.rst deleted file mode 100644 index 2abcd4ebe8..0000000000 --- a/docs/sphinx/source/index.rst +++ /dev/null @@ -1,35 +0,0 @@ -.. Evennia documentation master file, created by - sphinx-quickstart on Sat Sep 10 14:19:20 2011. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Evennia's documentation! -=================================== - -`Evennia `_ is a barebones Python -MUD/MUX/MU\* creation system and server. It is using modern technologies and offering -great freedom to design the multi-user online text game of your dreams. You -code your game using normal Python modules - can't get more flexible -than that! - -This Sphinx-based (reST) documentation is built from the `online wiki `_ at regular -intervals. - - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - Enter Manual - How to give and get help - Links - Alphabetical Page index - -.. Code -.. ----- -.. .. toctree:: -.. :titlesonly: - -.. Browse Code - - diff --git a/docs/sphinx/source/wiki/AddingCommandTutorial.rst b/docs/sphinx/source/wiki/AddingCommandTutorial.rst deleted file mode 100644 index 2909791dea..0000000000 --- a/docs/sphinx/source/wiki/AddingCommandTutorial.rst +++ /dev/null @@ -1,188 +0,0 @@ -Adding a new command - a step by step guide -=========================================== - -This is a quick first-time tutorial expanding on the -`Commands `_ documentation. - -Let's assume you have just downloaded Evennia and want to try to add a -new command. This is the fastest way to do it. - -Tell Evennia where to look for custom commands/cmdsets ------------------------------------------------------- - -We will tell Evennia that you want to override the default cmdset with -new additional commands of your own. - -#. Go to ``game/gamesrc/commands``. -#. There is a subfolder here named ``examples``. *Copy* the files - ``examples/command.py`` and ``examples/cmdset.py`` to your current - directory (game/gamesrc/commands). You can rename them as you please, - but in this example we assume you don't. -#. Edit ``game/settings.py``, adding the following line: - - ``CMDSET_CHARACTER="game.gamesrc.commands.cmdset.CharacterCmdSet"`` - -Evennia will now look for default commands in the ``CharacterCmdSet`` -class of your newly copied module. You only need to do this once. - -Creating a custom command -------------------------- - -#. Edit your newly copied ``game/gamesrc/commands/command.py``. This - template already imports everything you need. -#. Create a new class in ``command.py`` that inherits from - ``MuxCommand``. Let's call it ``CmdEcho`` in this example. -#. Set the class variable ``key`` to a good command name, like ``echo``. -#. Set the ``locks`` property on the command to a suitable - [Locks#Defining\_locks lockstring]. If you are unsure, use - ``"cmd:all()"``. -#. Give your class a useful *\_doc\_* string, this acts as the help - entry for the command. -#. Define a class method ``func()`` that does stuff. Below is an example - how it all could look. - -:: - - # file game/gamesrc/commands/command.py - #[...] - from ev import default_cmds - class CmdEcho(default_cmds.MuxCommand): - """ - Simple command example - - Usage: - echo - - This command simply echoes text back to the caller. - """ - - key = "echo" - locks = "cmd:all()" - - def func(self): - "This actually does things" - if not self.args: - self.caller.msg("You didn't enter anything!") - else: - self.caller.msg("You gave the string: '%s'" % self.args) - -Adding the Command to a default Cmdset --------------------------------------- - -The command is not available to use until it is part of a Command Set. -In this example we will go the easiest route and add it to the default -Character command set we already prepared. - -#. Edit your recently copied ``game/gamesrc/commands/cmdset.py`` -#. In this copied module you will find the ``DefaultCmdSet`` class - already imported and prepared for you. Import your new command module - here with ``from game.gamesrc.commands.command import CmdEcho``. -#. Add a line ``self.add(CmdEcho())`` to ``CharacterCmdSet``, in the - ``at_cmdset_creation`` method (the template tells you where). This is - approximately how it should look at this point: - -:: - - # file gamesrc/commands/cmdset.py - #[...] - from game.gamesrc.commands.command import CmdEcho - #[...] - class CharacterCmdSet(default_cmds.CharacterCmdSet): - - key = DefaultCharacter - - def at_cmdset_creation(self): - - # this first adds all default commands - super(DefaultSet, self).at_cmdset_creation() - - # all commands added after this point will extend or - # overwrite the default commands. - self.add(CmdEcho()) - -#. Reboot/restart Evennia (``@reload`` from inside the game). You should - now be able to use your new ``echo`` command from inside the game. - Use ``help echo`` to see the documentation for the command. - -If you have trouble, make sure to check the log for error messages -(probably due to syntax errors in your command definition). - -Adding new commands to the default cmdset in the future now only -involves creating the function class and adding it to the cmdset in the -same place. If you want to overload existing default commands (such as -``look`` or ``get``), just add your new command with the same key as the -old one - it will overload the default one. Just remember that you must -``@reload`` the server before you see any changes. - -See `Commands `_ for many more details and possibilities -when defining Commands and using Cmdsets in various ways. - -Adding the command to specific object types -------------------------------------------- - -You do not *have* to expand the ``CharacterCmdSet``, it's just the -easiest example. The cmdset system is very generic. You can create your -own cmdsets and add them to objects as you please (just how to control -how they merge with the existing set is described in detail in the -[Commands#Command\_Sets Command Set documentation]). - -:: - - # file gamesrc/commands/cmdset.py - #[...] - from game.gamesrc.commands.command import CmdEcho - #[...] - class MyCmdSet(default_cmds.CmdSet): - - key = MyCmdSet - - def at_cmdset_creation(self): - self.add(CmdEcho()) - -Now you just need to add this to an object. To test things (as -superuser) you can do - -:: - - @py self.cmdset.add("cmdset.MyCmdSet") - -This will add the cmdset (and the echo command) to yourself so you can -test it. This is not permanent though, if you do a ``@reload`` the -merger will be gone. You *can* add the ``permanent=True`` keyword to the -``cmdset.add`` call. This will however only make the new merged cmdset -permanent on that single object, not on other objects of that type, -which is usually what you want. - -To make sure all new created objects get your new merged set, put the -``cmdset.add`` call in your custom `Typeclass `_' -``at_object_creation`` method: - -:: - - from ev import Object - class MyObject(Object): - - def at_object_creation(self): - "called when the object is first created" - self.cmdset.add("cmdset.MyCmdSet") - - -All new objects of this typeclass will now start with this cmdset. - -*Note:* An important caveat with this is that ``at_object_creation`` is -only called *once*, when the object is first created. This means that if -you already have existing objects in your databases using that -typeclass, they will not have been initiated the same way. There are -many ways to update them; since it's a one-time update you can usually -just simply loop through them. As superuser, try the following: - -:: - - @py [obj.cmdset.add("cmdset.MyCmdSet") for obj in - ev.managers.typeclass_search("game.gamesrc.objects.objects.mytypeclass.MyTypeClass"] - -This goes through all objects in your database having the right -typeclass, adding the new cmdset to each. The good news is that you only -have to do this if you want to post-add cmdsets. If you just want to add -a new command, you can just add that command to the cmdset's -``at_cmdset_creation`` and @reload. diff --git a/docs/sphinx/source/wiki/AddingObjectTypeclassTutorial.rst b/docs/sphinx/source/wiki/AddingObjectTypeclassTutorial.rst deleted file mode 100644 index 4807ee6260..0000000000 --- a/docs/sphinx/source/wiki/AddingObjectTypeclassTutorial.rst +++ /dev/null @@ -1,219 +0,0 @@ -Creating your own object classes -================================ - -Evennia comes with a few very basic classes of in-game entities: - -:: - - Object - | - Character - Room - Exit - -The more specific object-types are just children of the basic ``Object`` -class (technically these are all `Typeclassed `_ -entities, but for this tutorial, just treat them as normal Python -classes). - -For your own game you will most likely want to expand on these very -simple beginnings. It's normal to want your Characters to have various -attributes. Maybe Rooms should hold extra information or even *all* -Objects in your game should have properties not included in basic -Evennia. - -First a brief overview of how Evennia handles its object classes. The -default classes are defined under ``src/objects/objects.py``. You can -look at them there or you can bring up a Python prompt and interactively -examine ``ev.Object``, ``ev.Room`` etc. - -You will create your own object classes in ``game/gamesrc/objects``. You -should normally inherit from the default classes (normal Python class -inheritance) and go from there. Once you have a working new class you -can immediately start to create objects in-game inheriting from that -class. - -If you want to change the *default* object classes, there is one more -step. Evennia's default commands and internal creation mechanisms look -at a range of variables in your ``settings.py`` file to determine which -are the "default" classes. These defaults are used by the vanilla -creation commands if you don't specify the typeclass specifically. They -are also used as a fallback by Evennia if there are errors in other -typeclasses, so make sure that your new default class is bug-free. - -The following sections spells this out more explicitly. - -Create a new Typeclass ----------------------- - -This is the simplest case. Say you want to create a new "Heavy" object -that characters should not have the ability to pick up. - -#. Go to ``game/gamesrc/objects/``. It should already contain a - directory ``examples/``. -#. Create a new module here, named ``heavy.py``. Alternatively you can - copy ``examples/object.py`` up one level and rename that file to - ``heavy.py`` instead - you will then have a template to start from. -#. Code away in the ``heavy.py`` module, implementing the heavy - functionality. See `Objects `_ for more details and the - example class below. Let's call the typeclass simply "``Heavy``\ ". -#. Once you are done, log into the game with a build-capable account and - do ``@create/drop rock:heavy.Heavy`` to drop a new heavy "rock" - object in your location. Next try to pick it up. *Note - the - superuser (User #1) will ignore all locks. Always test functionality - like this with a non-superuser character.* - -That's it. Below is a ``Heavy`` Typeclass that you could try. Note that -the `lock `_ and `Attribute `_ here set in -the typeclass could just as well have been set using commands in-game, -so this is a *very* simple example. We also add a custom -[Commands#Command\_Sets Command set] to it. - -:: - - # file game/gamesrc/objects/heavy.py - from ev import Object - # let's assume we defined our own cmdset earlier - from game.gamesrc.commands.mycmdsets import HeavySet - - class Heavy(Object): - "Heavy object" - def at_object_creation(self): - "Called whenever a new object is created" - # lock the object down by default - self.locks.add("get:false()") - # the default "get" command looks for this Attribute in order - # to return a customized error message (we just happen to know - # this, you'd have to look at the code of the 'get' command to - # find out). - self.db.get_err_msg = "This is too heavy for you to pick up." - # expand the default cmdset with your own custom set (defined elsewhere) - self.cmdset.add(HeavySet) - -Change Default Rooms, Exits, Character Typeclass ------------------------------------------------- - -This is only slightly more complex than creating any other Typeclass. In -fact it only includes one extra step - telling Evennia to use the new -default. - -Let's say we want to change Rooms to use our new typeclass ``MyRoom``. - -#. Create a new module in ``game/gamesrc/objects/myroom.py`` and code - your ``MyRoom`` typeclass as described in the previous section. Make - sure to test it by digging a few rooms of this class (e.g. - ``@dig Hall:myroom.MyRoom``). -#. Once you are sure the new class works as it should, edit - ``game/settings.py`` and add - ``BASE_ROOM_TYPECLASS="game.gamesrc.objects.myroom.MyRoom"``. -#. Reload Evennia. - -For example the ``@dig`` and ``@tunnel`` commands will henceforth use -this new default when digging new rooms whenever you don't give a -typeclass explicitly. For the other sub-types, change -``BASE_CHARACTER_TYPECLASS`` (used by character creation commands) and -``BASE_EXIT_TYPECLASS`` (used by ``@dig``/``@tunnel`` etc) respectively. - -Change the default Object Typeclass ------------------------------------ - -Changing the root ``Object`` class works identically to changing the -``Character``, ``Room`` or ``Exit`` typeclass. After having created your -new typeclass, set ``settings.BASE_OBJECT_TYPECLASS`` to point to your -new class. Let's say you call your new default ``Object`` class -``MyObject``. - -There however one important further thing to remember: ``Characters``, -``Rooms`` and ``Exits`` will still inherit from the *old* ``Object`` at -this point (not ``MyObject``). This is by design - depending on your -type of game, you may not need some or all of these subclasses to -inherit any of the new stuff you put in ``MyObject``. - -If you do want that however, you need to also overload these subclasses. -For each of the ``Character``, ``Room`` and ``Exit`` you want to -customize, do the following: - -#. Create a new module in ``game/gamesrc/``, e.g. ``mycharacter.py`` - etc. A good flexible solution for overloading only parts of the - default is to make inheriting classes *multi-inherited* (see below). - As a place-holder you can make the class empty for now (just put - ``pass`` in it). -#. In your ``settings.py`` file, add and define - ``BASE_CHARACTER_TYPECLASS``, ``BASE_ROOM_TYPECLASS`` and - ``BASE_EXIT_TYPECLASS`` to point to your new typeclasses. -#. Reload Evennia. - -This will give you maximum flexibility with creating and expanding your -own types of rooms, characters and exit objects (or not). Below is an -example of a new ``myroom.py``: - -:: - - # file gamesrc/objects/myroom.py - from ev import Object - from gamesrc.objects.myobject import MyObject - # we use multi-inheritance, this will primarily use MyObject, - # falling back to the default Object for things MyObject do - # not overload - class MyRoom(MyObject, Object): - "My own expandable room class" - pass - -Updating existing objects -========================= - -Let's say you have already created a slew of objects (Characters, Rooms, -what have you). Now you change the default typeclass for that type of -object (as described above). Unfortunately those old objects will not -know about this yet. If you want to update them you have to do this -manually. Luckily you only have to do this once, but it's a good case -for planning your game and its base typeclasses *before* starting to -build stuff. - -Typeclassed objects have a useful method called ``swap_typeclass``. All -you need to do is to flip through all existing objects, calling this. -Here is an example of how to do it using some Django magic: - -:: - - from django.conf import settings - import ev - - old_default = "src.objects.objects.Object" - new_default = "game.gamesrc.objects.myobj.MyObject" - - # use Django to query the database for all objects with the - # old typeclass path (typeclass path is stored in a database - # field 'db_typeclass_path)' - - for obj in ev.managers.objects.filter(db_typeclass_path=old_default): - obj.swap_typeclass(new_default) - -Above we use one of the Django database managers to query the database. -We are looking for the main thing typeclasses store in the database, -namely the full python path to the typeclass. We find all objects still -using the old typeclass and swap them to the new on. For more on Django -database access, see the Django manual and/or peruse ``ev.managers``. - -Notes -===== - -All above examples puts each class in its own module. This makes it easy -to find, but it is really up to you how you organize things. There is -nothing stopping you from putting all base classes into one module, for -example. - -Also remember that Python may dynamically rename module classes as they -are imported. So if you feel it annoying to have to refer to your new -default as ``MyObject`` all the time, you can also import them to -another name like in the below example: - -:: - - from ev import Object as BaseObject - from gamesrc.objects.myobject import MyObject as Object - class MyRoom(Object, BaseObject): - [...] - -This doesn't actually change the meaning of the code, but might make the -relationships clearer inside a module. diff --git a/docs/sphinx/source/wiki/AdminDocs.rst b/docs/sphinx/source/wiki/AdminDocs.rst deleted file mode 100644 index 9b7e35d056..0000000000 --- a/docs/sphinx/source/wiki/AdminDocs.rst +++ /dev/null @@ -1,39 +0,0 @@ -Administrative Documentation -============================ - -The following pages are aimed at game administrators -- the higher-ups -that possess shell access and/or are responsible for the game. - -Installation and Early Life ---------------------------- - -- `Choosing an SQL Server `_ -- `Getting Started - Installing Evennia `_ -- `Starting, stopping, reloading and resetting - Evennia `_ -- `Keeping your game up to date `_ -- `Making your game available online `_ - -Customizing the server ----------------------- - -- `Changing the Settings `_ -- `Change Evennia's language `_ -- `Apache webserver configuration `_ (optional) -- `Changing text encodings used by the server `_ -- `How to connect Evennia to IRC channels `_ -- `How to connect Evennia to an IMC2 network `_ -- `How to connect Evennia to RSS feeds `_ - -Administrating the running game -------------------------------- - -- `Banning `_ and deleting users - -Working with Evennia --------------------- - -- `Setting up your work environment with version - control `_ -- `First steps coding with Evennia `_ - diff --git a/docs/sphinx/source/wiki/ApacheConfig.rst b/docs/sphinx/source/wiki/ApacheConfig.rst deleted file mode 100644 index 5473138e46..0000000000 --- a/docs/sphinx/source/wiki/ApacheConfig.rst +++ /dev/null @@ -1,119 +0,0 @@ -Apache Configuration -==================== - -This is an optional section only relevant for advanced users preferring -to use a third-party web server to power Evennia's front-end. For most -users the in-built Twisted web server should be enough. The in-built -server works out of the box without any extra configuration. Note that -the ajax web client will probably *not* work (at least not without -tweaking) on a third-party web server. - -You can run Evennia's web front end with -`apache2 `_ and -`mod\_wsgi `_. However, there seems -to be no reason why the codebase should not also work with other modern -web servers like nginx/lighttpd + gunicorn, Tornado, uwsgi, etc. - -Note that the Apache instructions below might be slightly outdated. If -something is not working right, or you use Evennia with a different -server, please let us know. - -SQLite Note ------------ - -It's important to note that on Windows, you will be unable to run the -game and your web presence at the same time due to evennia.db3 being -locked while one has it opened. While Linux/Unix will let you run both -concurrently, there **may** be issues with simultaneous read/writes by -the game and the web front-end. The best bet to any game wishing to -power their web presence with Evennia is to use Postgres, MySQL, Oracle, -or any other supported full-blown relational database. - -mod\_wsgi Setup ---------------- - -Install mod\_wsgi -~~~~~~~~~~~~~~~~~ - -mod\_wsgi is an excellent, secure, and high-performance way to serve -Python projects. Code reloading is a breeze, Python modules are executed -as a user of your choice (which is a great security win), and mod\_wsgi -is easy to set up on most distributions. - -For the sake of brevity, this guide will refer you to mod\_wsgi's -`installation -instructions `_ -page, as their guides are great. For those that are running Debian or -Ubuntu, you may install the entire stack with the following command: - -``sudo aptitude install libapache2-mod-wsgi`` - -This should install apache2 (if it isn't already), mod\_wsgi, and load -the module. On Fedora or CentOS, you'll do this with ``yum`` and a -similar package name that you'll need to search for. On Windows, you'll -need to download and install apache2 and mod\_wsgi binaries. - -Copy and modify the VHOST -~~~~~~~~~~~~~~~~~~~~~~~~~ - -After mod\_wsgi is installed, copy the -``evennia/game/web/utils/evennia_wsgi_apache.conf`` file to your apache2 -vhosts/sites folder. On Debian/Ubuntu, this is -``/etc/apache2/sites-enabled/``. Make your modifications **after** -copying the file there. - -Read the comments and change the paths to point to the appropriate -locations within your setup. - -Restart/Reload Apache -~~~~~~~~~~~~~~~~~~~~~ - -You'll then want to reload or restart apache2. On Debian/Ubuntu, this -may be done via: - -``sudo /etc/init.d/apache2 restart`` or -``sudo /etc/init.d/apache2 reload`` - -Enjoy -~~~~~ - -With any luck, you'll be able to point your browser at your domain or -subdomain that you set up in your vhost and see the nifty default -Evennia webpage. If not, read the hopefully informative error message -and work from there. Questions may be directed to our `Evennia Community -site `_. - -A note on code reloading -~~~~~~~~~~~~~~~~~~~~~~~~ - -If your mod\_wsgi is set up to run on daemon mode (as will be the case -by default on Debian and Ubuntu), you may tell mod\_wsgi to reload by -using the ``touch`` command on -``evennia/game/web/utils/apache_wsgi.conf``. When mod\_wsgi sees that -the file modification time has changed, it will force a code reload. Any -modifications to the code will not be propagated to the live instance of -your site until reloaded. - -If you are not running in daemon mode or want to force the issue, simply -restart or reload apache2 to apply your changes. - -Further notes and hints: -~~~~~~~~~~~~~~~~~~~~~~~~ - -If you get strange (and usually uninformative) ``Permission denied`` -errors from Apache, make sure that your ``evennia`` directory is located -in a place the webserver may actually access. For example, some Linux -distributions may default to very restrictive access permissions on a -user's ``/home`` directory. - -One user commented that they had to add the following to their Apache -config to get things to work. Not confirmed, but worth trying if there -are trouble. - -:: - - /evennia/game/web"> - Options +ExecCGI - Allow from all - - diff --git a/docs/sphinx/source/wiki/AsyncProcess.rst b/docs/sphinx/source/wiki/AsyncProcess.rst deleted file mode 100644 index cb9d584007..0000000000 --- a/docs/sphinx/source/wiki/AsyncProcess.rst +++ /dev/null @@ -1,261 +0,0 @@ -Asynchronous code -================= - -*This is considered an advanced topic.* - -Synchronous versus Asynchronous -------------------------------- - -Most code operate *synchronously*. This means that each statement in -your code gets processed and finishes before the next can begin. This -makes for easy-to-understand code. It is also a *requirement* in many -cases - a subsequent piece of code often depend on something calculated -or defined in a previous statement. - -Consider this piece of code: - -:: - - print "before call ..." - long_running_function() - print "after call ..." - -When run, this will print ``"before call ..."``, after which the -``long_running_function`` gets to work for however long time. Only once -that is done, the system prints ``"after call ..."``. Easy and logical -to follow. Most of Evennia work in this way. Most of the time we want to -make sure that commands get executed in strict order after when they -where entered. - -The main problem is that Evennia is a multi-user server. It swiftly -switches between dealing with player input in the order it is sent to -it. So if one user, say, run a command containing that -``long_running_function``, *all* other players are effectively forced to -wait until it finishes ... hardly an ideal solution. - -Now, it should be said that on a modern computer system this is rarely -an issue. Very few commands run so long that other users notice it. And -as mentioned, most of the time you *want* to enforce all commands to -occur in strict sequence. - -When delays do become noticeable and you don't care which order the -command actually completes, you can run it *asynchronously*. This makes -use of the ``run_async()`` function in ``src/utils/utils.py``. - -:: - - from ev import utils - print "before call ..." - utils.run_async(long_running_function) - print "after call ..." - -Now, when running this you will find that the program will not wait -around for ``long_running_function`` to finish. Infact you will see -``"before call ..."`` and ``"after call ..."`` printed out right away. -The long-running function will run in the background and you (and other -users) can go on as normal. - -Customizing asynchronous operation ----------------------------------- - -A complication with using asynchronous calls is what to do with the -result from that call. What if ``long_running_function`` returns a value -that you need? It makes no real sense to put any lines of code after the -call to try to deal with the result from ``long_running_function`` above -- as we saw the ``"after call ..."`` got printed long before -``long_running_function`` was finished, making that line quite pointless -for processing any data from the function. Instead one has to use -*callbacks*. - -``utils.run_async`` takes reserved arguments. - -- ``at_return(r)`` (the *callback*) is called when the asynchronous - function (``long_running_function`` above) finishes successfully. The - argument ``r`` will then be the return value of that function (or - ``None``). Example: - - :: - - def at_return(r): - print r - -- ``at_return_kwargs`` - an optional dictionary that will be fed as - keyword arguments to the ``at_return`` callback. -- ``at_err(e)`` (the *errback*) is called if the asynchronous function - fails and raises an exception. This exception is passed to the - errback wrapped in a *Failure* object ``e``. If you do not supply an - errback of your own, Evennia will automatically add one that silently - writes errors to the evennia log. An example of an errback is found - below: - - :: - - def at_err(e): - print "There was an error:", str(e) - -- ``at_err_kwargs`` - an optional dictionary that will be fed as - keyword arguments to the ``at_err`` errback. - -An example of making an asynchronous call from inside a -`Command `_ definition: - -:: - - from ev import utils - from game.gamesrc.commands.basecommand import Command - - class CmdAsync(Command): - - key = "asynccommand" - - def func(self): - - def long_running_function(): - #[... lots of time-consuming code - return final_value - - def at_return(r): - self.caller.msg("The final value is %s" % r) - - def at_err(e): - self.caller.msg("There was an error: %s" % e) - - # do the async call, setting all callbacks - utils.run_async(long_running_function, at_return, at_err) - -That's it - from here on we can forget about ``long_running_function`` -and go on with what else need to be done. *Whenever* it finishes, the -``at_return`` function will be called and the final value will pop up -for us to see. If not we will see an error message. - -Process Pool ------------- - -The ``ProcPool`` is an Evennia subsystem that launches a pool of -processes based on the `ampoule `_ -package (included with Evennia). When active, ``run_async`` will use -this pool to offload its commands. ``ProcPool`` is deactivated by -default, it can be turned on with ``settings.PROCPOOL_ENABLED``. *It -should be noted that the default SQLite3 database is not suitable for -for multiprocess operation. So if you use ``ProcPool`` you should -consider switching to another database such as MySQL or PostgreSQL.* - -The Process Pool makes several additional options available to -``run_async``. - -The following keyword arguments make sense when ``ProcPool`` is active: - -- ``use_thread`` - this force-reverts back to thread operation (as - above). It effectively deactivates all additional features - ``ProcPool`` offers. -- ``proc_timeout`` - this enforces a timeout for the running process in - seconds; after this time the process will be killed. -- ``at_return``, ``at_err`` - these work the same as above. - -In addition to feeding a single callable to ``run_async``, the first -argument may also be a source string. This is a piece of python source -code that will be executed in a subprocess via ``ProcPool``. Any extra -keyword arguments to ``run_async`` that are not one of the reserved ones -will be used to specify what will be available in the execution -environment. - -There is one special variable used in the remove execution: ``_return``. -This is a function, and all data fed to ``_return`` will be returned -from the execution environment and appear as input to your ``at_return`` -callback (if it is defined). You can call ``_return`` multiple times in -your code - the return value will then be a list. - -Example: - -:: - - from src.utils.utils import run_async - - source = """ - from time import sleep - sleep(5) # sleep five secs - val = testvar + 5 - _return(val) - _return(val + 5) - """ - - # we assume myobj is a character retrieved earlier - # these callbacks will just print results/errors - def callback(ret): - myobj.msg(ret) - def errback(err): - myobj.msg(err) - testvar = 3 - - # run async - run_async(source, at_return=callback, at_err=errback, testvar=testvar) - - # this will return '[8, 13]' - -You can also test the async mechanism from in-game using the ``@py`` -command: - -:: - - @py from src.utils.utils import run_async;run_async("_return(1+2)",at_return=self.msg) - -Note: The code execution runs without any security checks, so it should -not be available to unprivileged users. Try -``contrib.evlang.evlang.limited_exec`` for running a more restricted -version of Python for untrusted users. This will use ``run_async`` under -the hood. - -delay ------ - -The ``delay`` function is a much simpler sibling to ``run_async``. It is -in fact just a way to delay the execution of a command until a future -time. This is equivalent to something like ``time.sleep()`` except delay -is asynchronous while ``sleep`` would lock the entire server for the -duration of the sleep. - -:: - - def callback(obj): - obj.msg("Returning!") - delay(10, caller, callback=callback) - -This will delay the execution of the callback for 10 seconds. This -function is explored much more in `Command Duration -Tutorial `_. - -Assorted notes --------------- - -Note that the ``run_async`` will try to launch a separate thread behind -the scenes. Some databases, notably our default database SQLite3, does -*not* allow concurrent read/writes. So if you do a lot of database -access (like saving to an Attribute) in your function, your code might -actually run *slower* using this functionality if you are not careful. -Extensive real-world testing is your friend here. - -Overall, be careful with choosing when to use asynchronous calls. It is -mainly useful for large administration operations that has no direct -influence on the game world (imports and backup operations come to -mind). Since there is no telling exactly when an asynchronous call -actually ends, using them for in-game commands is to potentially invite -confusion and inconsistencies (and very hard-to-reproduce bugs). - -The very first synchronous example above is not *really* correct in the -case of Twisted, which is inherently an asynchronous server. Notably you -might find that you will *not* see the first ``before call ...`` text -being printed out right away. Instead all texts could end up being -delayed until after the long-running process finishes. So all commands -will retain their relative order as expected, but they may appear with -delays or in groups. - -Further reading ---------------- - -Technically, ``run_async`` is just a very thin and simplified wrapper -around a `Twisted -Deferred `_ -object; the wrapper sets up a separate thread and assigns a default -errback also if none is supplied. If you know what you are doing there -is nothing stopping you from bypassing the utility function, building a -more sophisticated callback chain after your own liking. diff --git a/docs/sphinx/source/wiki/Attributes.rst b/docs/sphinx/source/wiki/Attributes.rst deleted file mode 100644 index 28923b0eff..0000000000 --- a/docs/sphinx/source/wiki/Attributes.rst +++ /dev/null @@ -1,342 +0,0 @@ -Attributes -========== - -When performing actions in Evennia it is often important that you store -data for later. If you write a menu system, you have to keep track of -the current location in the menu tree so that the player can give -correct subsequent commands. If you are writing a combat system, you -might have a combattant's next roll get easier dependent on if their -opponent failed. Your characters will probably need to store -roleplaying-attributes like strength and agility. And so on. - -`Typeclassed `_ game entities -(`Players `_, `Objects `_ and -`Scripts `_) always have *Attributes* associated with -them. Attributes are used to store any type of data 'on' such entities. -This is different from storing data in properties already defined on -entities (such as ``key`` or ``location``) - these have very specific -names and require very specific types of data (for example you couldn't -assign a python *list* to the ``key`` property no matter how hard you -tried). ``Attributes`` come into play when you want to assign arbitrary -data to arbitrary names. - -Saving and Retrieving data --------------------------- - -To save persistent data on a Typeclassed object you normally use the -``db`` (DataBase) operator. Let's try to save some data to a *Rose* (an -`Object `_): - -:: - - # saving - rose.db.has_thorns = True - # getting it back - is_ouch = rose.db.has_thorns - -This looks like any normal Python assignment, but that ``db`` makes sure -that an *Attribute* is created behind the scenes and is stored in the -database. Your rose will continue to have thorns throughout the life of -the server now, until you deliberately remove them. - -To be sure to save **non-persistently**, i.e. to make sure NOT to create -a database entry, you use ``ndb`` (NonDataBase). It works in the same -way: - -:: - - # saving - rose.ndb.has_thorns = True - # getting it back - is_ouch = rose.ndb.has_thorns - -Strictly speaking, ``ndb`` has nothing to do with ``Attributes``, -despite how similar they look. No ``Attribute`` object is created behind -the scenes when using ``ndb``. In fact the database is not invoked at -all since we are not interested in persistence. - -You can also ``del`` properties on ``db`` and ``ndb`` as normal. This -will for example delete an ``Attribute``: - -:: - - del rose.db.has_thorns - -Both ``db`` and ``ndb`` defaults to offering an ``all()`` method on -themselves. This returns all associated attributes or non-persistent -properties. - -:: - - list_of_all_rose_attributes = rose.db.all() - list_of_all_rose_ndb_attrs = rose.ndb.all() - -If you use ``all`` as the name of an attribute, this will be used -instead. Later deleting your custom ``all`` will return the default -behaviour. - -Properties of Attributes ------------------------- - -An Attribute object is stored in the database. It has the following -properties: - -- ``key`` - the name of the Attribute. When doing e.g. - ``obj.db.attrname = value``, this property is set to ``attrname``. -- ``value`` - this is the value of the Attribute. This value can be - anything which can be pickled - objects, lists, numbers or what have - you (see - [Attributes#What\_types\_of\_data\_can\_I\_save\_in\_an\_Attribute - this section] for more info). In the example - ``obj.db.attrname = value``, the ``value`` is stored here. -- ``category`` - this is an optional property that is set to None for - most Attributes. Setting this allows to use Attributes for different - functionality. This is usually not needed unless you want to use - Attributes for very different functionality (`Nicks `_ is - an example of using Attributes in this way). To modify this property - you need to use the [Attributes#The\_Attribute\_Handler Attribute - Handler]. -- ``strvalue`` - this is a separate value field that only accepts - strings. This severaly limits the data possible to store, but allows - for easier database lookups. This property is usually not used except - when re-using Attributes for some other purpose - (`Nicks `_ use it). It is only accessible via the - [Attributes#The\_Attribute\_Handler Attribute Handler]. - -Non-database attributes have no equivalence to category nor strvalue. - -The Attribute Handler ---------------------- - -The Attribute handler is what is used under the hood to manage the -Attributes on an object. It is accessible as ``obj.attributes``. For -most operations, the ``db`` or ``ndb`` wrappers are enough. But -sometimes you won't know the attribute name beforehand or you need to -manipulate your Attributes in more detail. The Attribute handler has the -following methods (the argument lists are mostly shortened; you can see -the full call signatures in ``src.typeclasses.models``): - -- ``attributes.has(...)`` - this checks if the object has an Attribute - with this key. This is equivalent to doing ``obj.db.key``. -- ``get(...)`` - this retrieves the given Attribute. Normally the - ``value`` property of the Attribute is returned, but the method takes - keywords for returning the Attribute object itself. By supplying an - ``accessing_object`` oto the call one can also make sure to check - permissions before modifying anything. -- ``add(...)`` - this adds a new Attribute to the object. An optional - `lockstring `_ can be supplied here to restrict future - access and also the call itself may be checked against locks. -- ``remove(...)`` - Remove the given Attribute. This can optionally be - made to check for permission before performing the deletion. -- ``clear(...)`` - removes all Attributes from object. -- ``all(...)`` - returns all Attributes (of the given category) - attached to this object. - -See [Attributes#Locking\_and\_checking\_Attributes this section] for -more about locking down Attribute access and editing. - -There is an equivalent ``nattribute`` handler for managing non-database -Attributes. This has the same methods but is much simpler since it does -not concern itself with category nor strvalue. It also offers no concept -of access control. - -Persistent vs non-persistent ----------------------------- - -So *persistent* data means that your data will survive a server reboot, -whereas with *non-persistent* data it will not ... - -... So why would you ever want to use non-persistent data? The answer -is, you don't have to. Most of the time you really want to save as much -as you possibly can. Non-persistent data is potentially useful in a few -situations though. - -- You are worried about database performance. Since Evennia caches - Attributes very aggressively, this is not an issue unless you are - reading *and* writing to your Attribute very often (like many times - per second). Reading from an already cached Attribute is as fast as - reading any Python property. But even then this is not likely - something to worry about: Apart from Evennia's own caching, modern - database systems themselves also 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. -- A more valid reason for using non-persistent data is if you *want* to - loose your state when logging off. Maybe you are storing throw-away - data that are re-initialized at server startup. Maybe you are - implementing some caching of your own. Or maybe you are testing a - buggy `Script `_ that does potentially harmful stuff to - your character object. With non-persistent storage you can be sure - that whatever is messed up, it's nothing a server reboot can't clear - up. -- You want to implement a fully or partly *non-persistent world*. Who - are we to argue with your grand vision! - -What types of data can I save in an Attribute? ----------------------------------------------- - -Evennia uses the ``pickle`` module to serialize Attribute data into the -database. So if you store a single object (that is, not an iterable list -of objects), you can practically store any Python object that can be -`pickled `_. - -If you store many objects however, you can only store them using normal -Python structures (i.e. in either a *tuple*, *list*, *dictionary* or -*set*). All other iterables (such as custom containers) are converted to -*lists* by the Attribute (see next section for the reason for this). -Since you can nest dictionaries, sets, lists and tuples together in any -combination, this is usually not much of a limitation. - -There is one notable type of object that cannot be pickled - and that is -a Django database object. These will instead be stored as a wrapper -object containing the ID and its database model. It will be read back to -a new instantiated `typeclass `_ when the Attribute is -accessed. Since erroneously trying to save database objects in an -Attribute will lead to errors, Evennia will try to detect database -objects by analyzing the data being stored. This means that Evennia must -recursively traverse all iterables to make sure all database objects in -them are stored safely. So for efficiency, it can be a good idea to -avoid deeply nested lists with objects if you can. - -*Note that you could fool the safety check if you for example created -custom, non-iterable classes and stored database objects in them. So to -make this clear - saving such an object is **not supported** and will -probably make your game unstable. Store your database objects using -lists, tuples, dictionaries, sets or a combination of the four and you -should be fine.* - -Examples of valid attribute data: - -:: - - # a single value - obj.db.test1 = 23 - obj.db.test1 = False - # a database object (will be stored as dbref) - obj.db.test2 = myobj - # a list of objects - obj.db.test3 = [obj1, 45, obj2, 67] - # a dictionary - obj.db.test4 = {'str':34, 'dex':56, 'agi':22, 'int':77} - # a mixed dictionary/list - obj.db.test5 = {'members': [obj1,obj2,obj3], 'enemies':[obj4,obj5]} - # a tuple with a list in it - obj.db.test6 = (1,3,4,8, ["test", "test2"], 9) - # a set will still be stored and returned as a list [1,2,3,4,5]! - obj.db.test7 = set([1,2,3,4,5]) - # in-situ manipulation - obj.db.test8 = [1,2,{"test":1}] - obj.db.test8[0] = 4 - obj.db.test8[2]["test"] = 5 - # test8 is now [4,2,{"test":5}] - -Example of non-supported save: - -:: - - # this will fool the dbobj-check since myobj (a database object) is "hidden" - # inside a custom object. This is unsupported and will lead to unexpected - # results! - class BadStorage(object): - pass - bad = BadStorage() - bad.dbobj = myobj - obj.db.test8 = bad # this will likely lead to a traceback - -Retrieving Mutable objects --------------------------- - -A side effect of the way Evennia stores Attributes is that Python Lists, -Dictionaries and Sets are handled by custom objects called PackedLists, -PackedDicts and PackedSets. These behave just like normal lists and -dicts except they have the special property that they save to the -database whenever new data gets assigned to them. This allows you to do -things like ``self.db.mylist[4]`` = val without having to extract the -mylist Attribute into a temporary variable first. - -There is however an important thing to remember. If you retrieve this -data into another variable, e.g. ``mylist2 = obj.db.mylist``, your new -variable (``mylist2``) will *still* be a PackedList! This means it will -continue to save itself to the database whenever it is updated! This is -important to keep in mind so you are not confused by the results. - -:: - - obj.db.mylist = [1,2,3,4] - mylist = obj.db.mylist - mylist[3] = 5 # this will also update database - print mylist # this is now [1,2,3,5] - print mylist.db.mylist # this is also [1,2,3,5] - -To "disconnect" your extracted mutable variable from the database you -simply need to convert the PackedList or PackedDict to a normal Python -list or dictionary. This is done with the builtin ``list()`` and -``dict()`` functions. In the case of "nested" lists and dicts, you only -have to convert the "outermost" list/dict in order to cut the entire -structure's connection to the database. - -:: - - obj.db.mylist = [1,2,3,4] - mylist = list(obj.db.mylist) # convert to normal list - mylist[3] = 5 - print mylist # this is now [1,2,3,5] - print obj.db.mylist # this remains [1,2,3,4] - -Remember, this is only valid for mutable iterables - lists and dicts and -combinations of the two. -`Immutable `_ objects (strings, -numbers, tuples etc) are already disconnected from the database from the -onset. So making the outermost iterable into a tuple is also a way to -stop any changes to the structure from updating the database. - -:: - - obj.db.mytup = (1,2,[3,4]) - obj.db.mytup[0] = 5 # this fails since tuples are immutable - obj.db.mytup[2][1] = 5 # this works but will NOT update database since outermost iterable is a tuple - print obj.db.mytup[2][1] # this still returns 4, not 5 - mytup1 = obj.db.mytup - # mytup1 is already disconnected from database since outermost - # iterable is a tuple, so we can edit the internal list as we want - # without affecting the database. - -Locking and checking Attributes -------------------------------- - -Attributes are normally not locked down by default, but you can easily -change that for individual Attributes (like those that may be -game-sensitive in games with user-level building). - -First you need to set a *lock string* on your Attribute. Lock strings -are specified `here `_. The relevant lock types are - -- *attrread* - limits who may read the value of the Attribute -- *attredit* - limits who may set/change this Attribute - -You cannot use the ``db`` handler to modify Attribute object (such as -setting a lock on them) - The ``db`` handler will return the Attribute's -*value*, not the Attribute object itself. Instead you use -``get_attribute_obj`` (see next section) which allows you to set the -lock something like this: - -:: - - obj.attributes.get("myattr", return_obj=True).locks.add("attread:all();attredit:perm(Wizards)") - -A lock is no good if nothing checks it -- and by default Evennia does -not check locks on Attributes. You have to add a check to your -commands/code wherever it fits (such as before setting an Attribute). - -:: - - # in some command code where we want to limit - # setting of a given attribute name on an object - attr = obj.attributes.get(attrname, return_obj=True, accessing_obj=caller, default=None, default_access=False) - if not attr: - caller.msg("You cannot edit that Attribute!") - return - # edit the Attribute here - -The same keywords are available to use with ``obj.attributes.set()`` and -``obj.attributes.remove()``, those will check for the *attredit* lock -type. diff --git a/docs/sphinx/source/wiki/Banning.rst b/docs/sphinx/source/wiki/Banning.rst deleted file mode 100644 index 3993e23fe9..0000000000 --- a/docs/sphinx/source/wiki/Banning.rst +++ /dev/null @@ -1,132 +0,0 @@ -Sometimes it's just not worth the grief ... -=========================================== - -Whether due to abuse, blatant breaking of your rules, or some other -reason you will eventually find no other recourse but to kick out a -particularly troublesome player. The default command set has admin tools -to handle this, primarily ``@ban, @unban`` and ``@boot``. - -Creating a ban -============== - -Say we have a troublesome player "YouSuck" - this is a guy that refuse -common courtesy - an abusive and spammy account that is clearly created -by some bored internet hooligan only to cause grief. You have tried to -be nice. Now you just want this troll gone. - -Name ban --------- - -The easiest is to block the account YouSuck from ever connecting again. - -:: - - @ban YouSuck - -This will lock the name YouSuck (as well as 'yousuck' and any other -combination), and next time they try to log in with this name the server -will not let them! - -You can also give a reason so you remember later why this was a good -thing (the banned player will never see this) - -:: - - @ban YouSuck:This is just a troll. - -If you are sure this is just a spam account, you might even consider -deleting the player account outright: - -:: - - @delplayer YouSuck - -Generally banning the name is the easier and safer way to stop the use -of an account -- if you change your mind you can always remove the block -later whereas a deletion is permanent. - -IP ban ------- - -Just because you block YouSuck's name might not mean the trolling human -behind that account gives up. They can just create a new account -YouSuckMore and be back at it. One way to make things harder for them is -to tell the server to not allow connections from their particular IP -address. - -First, when the offending player is online, check which IP address they -use. This you can do with the ``who`` command, which will show you -something like this: - -:: - - Player Name On for Idle Room Cmds Host - YouSuck 01:12 2m 22 212 237.333.0.223 - -The "Host" bit is the IP address from which the player is connecting. -Use this to define the ban instead of the name: - -:: - - @ban 237.333.0.223 - -This will stop YouSuck connecting from his computer. Note however that -IP addresses might change easily - either due to how the player's -Internet Service Provider operates or by the user simply changing -computer. You can make a more general ban by putting asterisks ``*`` as -wildcards for the groups of three digits in the address. So if you -figure out that YouSuck mainly connects from 237.333.0.223, -237.333.0.225 and 237.333.0.256 (only changes in the local subnet), it -might be an idea to put down a ban like this to include any number in -that subnet: - -:: - - @ban 237.333.0.* - -You should combine the IP ban with a name-ban too of course, so the -account YouSuck is truly locked regardless of from where they connect. - -Be careful with too general IP bans however (more asterisks above). If -you are unlucky you could be blocking out innocent players who just -happen to connect from the same subnet as the offender. - -Booting -======= - -YouSuck is not really noticing all this banning yet though - and won't -until having logged out and tries to log back in again. Let's help the -troll along. - -:: - - @boot YouSuck - -Good riddance. You can give a reason for booting too (to be echoed to -the player before getting kicked out). - -:: - - @boot YouSuck:Go troll somewhere else. - -Lifting a ban -============= - -Give the ``@unban`` (or ``@ban``) command without any arguments and you -will see a list of all currently active bans: - -:: - - Active bans - id name/ip date reason - 1 yousuck Fri Jan 3 23:00:22 2020 This is just a Troll. - 2 237.333.0.* Fri Jan 3 23:01:03 2020 YouSuck's IP. - -Use the ``id`` from this list to find out which ban to lift. - -:: - - @unban 2 - - Cleared ban 2: 237.333.0.* - diff --git a/docs/sphinx/source/wiki/BatchCodeProcessor.rst b/docs/sphinx/source/wiki/BatchCodeProcessor.rst deleted file mode 100644 index 02a9d28979..0000000000 --- a/docs/sphinx/source/wiki/BatchCodeProcessor.rst +++ /dev/null @@ -1,247 +0,0 @@ -The Batch-Code processor -======================== - -For an introduction and motivation to using batch processors, see -`here `_. This page describes the Batch-*code* -processor. The Batch-*command* one is covered -`here `_. - -Basic Usage ------------ - -The batch-command processor is a superuser-only function, invoked by - -:: - - > @batchcode path.to.batchcodefile - -Where ``path.to.batchcodefile`` is the path to a *batch-code file*. Such -a file should have a name ending in "``.py``\ " (but you shouldn't -include that when you batch-run the file from the game below). The path -is given like a python path relative to a folder you define to hold your -batch files, set by ``BATCH_IMPORT_PATH`` in your settings. Default -folder is ``game/gamesrc/world``. So if you want to run the example -batch file in ``game/gamesrc/world/examples/batch_code.py``, you could -simply use - -:: - - > @batchcommand examples.batch_code - -This will try to run through the entire batch file in one go. For more -gradual, *interactive* control you can use the ``/interactive`` switch. -The switch ``/debug`` will put the processor in *debug* mode. Read below -for more info. - -The batch file --------------- - -A batch-code file is mostly a normal Python source file. The only thing -separating a batch file from any standard Python module is that the code -is wrapped into *blocks* using a special syntax. These blocks allow the -batch processor more control over execution, especially when using the -processor's *interactive* mode. In interactive mode these blocs allow -the batchcode runner to pause and only execute certain blocks at a time. -There is however nothing stopping you from coding everything in one -single block if you don't want to split things up into chunks like this. - -Here are the rules of syntax of the batch-command ``*.py`` file. - -- ``#HEADER`` as the first on a line marks the start of a *header* - block. This is intended to hold imports and variables that might be - of use for other blocks. All python code defined in a header block - will always be inserted at the top of all ``#CODE`` blocks in the - file. You may have more than one ``#HEADER`` block, but that is - equivalent to having one big one. Comments in ``#HEADER`` blocks are - stripped out before merging. -- ``#CODE`` as the first on a line marks the start of a *code* block. - Code blocks contain functional python code. ``#HEADER`` blocks are - added to the top of code blocks at runtime. -- ``#CODE (info) obj1, obj2, ...`` is an optional form of the code - block header. The ``(info)`` field gives extra info about what's - going on in the block and is displayed by the batch processor. The - ``obj1, obj2, ...`` parts are optional object labels used by the - processor's *debug* mode in order to auto-delete objects after a test - run. -- ``#INSERT path.filename`` as the first on a line loads the contents - of another batch-code file into this one. Its ``#CODE`` blocks will - be executed as if they were defined in this file, but they will not - share ``#HEADER``\ s with the current file, but only use its own, if - any. -- A new ``#HEADER``, ``#CODE`` or ``#INSERT`` (or the end of the file) - ends a previous block. Text before the first block are ignored. -- A ``#`` that is not starting a ``#HEADER``, ``#CODE`` or ``#INSERT`` - instruction is considered a comment. -- Inside a block, normal Python syntax rules apply. For the sake of - indentation, each block acts as a separate python module. -- The variable ``caller`` is always made available to the script, - pointing to the object executing the batchcommand. - -Below is a version of the example file found in -``game/gamesrc/world/examples/batch_code.py``. - -:: - - # - # This is an example batch-code build file for Evennia. - # - - #HEADER - - # This will be included in all other #CODE blocks - - from src.utils import create, search - from game.gamesrc.objects.examples import red_button - from game.gamesrc.objects import baseobjects - - limbo = search.objects(caller, 'Limbo', global_search=True)[0] - - - #CODE (create red button) - - red_button = create.create_object(red_button.RedButton, key="Red button", - location=limbo, aliases=["button"]) - - # caller points to the one running the script - caller.msg("A red button was created.") - - # importing more code from another batch-code file - #INSERT examples.batch_code_insert - - #CODE (create table and chair) table, chair - - table = create.create_object(baseobjects.Object, key="Blue Table", location=limbo) - chair = create.create_object(baseobjects.Object, key="Blue Chair", location=limbo) - - string = "A %s and %s were created. If debug was active, they were deleted again." - caller.msg(string % (table, chair)) - -This uses Evennia's Python API to create three objects in sequence. - -Debug mode ----------- - -Try to run the example script with - -:: - - > @batchcode/debug examples.batch_code - -The batch script will run to the end and tell you it completed. You will -also get messages that the button and the two pieces of furniture where -created. Look around and you should see the button there. But you won't -see any chair nor a table! This is because we ran this with the -``/debug`` switch. The debug mode of the processor is intended to be -used when you test out a script. Maybe you are looking for bugs in your -code or try to see if things behave as they should. Running the script -over and over would then create an ever-growing stack of buttons, chairs -and tables, all with the same name. You would have to go back and -painstakingly delete them later. The debug mode simply tries to -automatically delete the objects that where created so as to not crowd -the room with unwanted objects. - -The second ``#CODE`` block supplies the variable names ``table`` and -``chair``, which match the actual variables we later assign our new -ojects to. In debug mode the batch-code processor will look for these -references and simply run ``delete()`` on them. Since the -button-creating block does not define any such variables the processor -can't help us there - meaning the button stays also in debug mode. - -Interactive mode ----------------- - -Interactive mode works very similar to the `batch-command processor -counterpart `_. It allows you more step-wise -control over how the batch file is executed. This is useful for -debugging or for picking and choosing only particular blocks to run. Use -``@batchcommand`` with the ``/interactive`` flag to enter interactive -mode. - -:: - - > @batchcode/interactive examples.batch_code - -You should see the following: - -:: - - 01/02: #CODE (create red button) [...] (hh for help) - -This shows that you are on the first ``#CODE`` block, the first of only -two commands in this batch file. Observe that the block has *not* -actually been executed at this point! - -To take a look at the full code snippet you are about to run, use ``ll`` -(a batch-processor version of ``look``). - -:: - - from src.utils import create, search - from game.gamesrc.objects.examples import red_button - from game.gamesrc.objects import baseobjects - - limbo = search.objects(caller, 'Limbo', global_search=True)[0] - - red_button = create.create_object(red_button.RedButton, key="Red button", - location=limbo, aliases=["button"]) - - # caller points to the one running the script - caller.msg("A red button was created.") - -Compare with the example code given earlier. Notice how the content of -``#HEADER`` has been pasted at the top of the ``#CODE`` block. Use -``pp`` to actually execute this block (this will create the button and -give you a message). Use ``nn`` (next) to go to the next command. Use -``hh`` for a list of commands. - -If there are tracebacks, fix them in the batch file, then use ``rr`` to -reload the file. You will still be at the same code block and can rerun -it easily with ``pp`` as needed. This makes for a simple debug cycle. It -also allows you to rerun individual troublesome blocks - as mentioned, -in a large batch file this can be very useful (don't forget the -``/debug`` mode either). - -Use ``nn`` and ``bb`` (next and back) to step through the file; e.g. -``nn 12`` will jump 12 steps forward (without processing any blocks in -between). All normal commands of Evennia should work too while working -in interactive mode. - -Limitations and Caveats ------------------------ - -The batch-code processor is by far the most flexible way to build a -world in Evennia. There are however some caveats you need to keep in -mind. - -- *Safety*. Or rather the lack of it. There is a reason only - *superusers* are allowed to run the batch-code processor by default. - The code-processor runs *without any Evennia security checks* and - allows full access to Python. If an untrusted party could run the - code-processor they could execute arbitrary python code on your - machine, which is potentially a very dangerous thing. If you want to - allow other users to access the batch-code processor you should make - sure to run Evennia as a separate and very limited-access user on - your machine (i.e. in a 'jail'). By comparison, the batch-command - processor is much safer since the user running it is still 'inside' - the game and can't really do anything outside what the game commands - allow them to. -- *You cannot communicate between code blocks*. Global variables won't - work in code batch files, each block is executed as stand-alone - environments. Similarly you cannot in one ``#CODE`` block assign to - variables from the ``#HEADER`` block and expect to be able to read - the changes from another ``#CODE`` block (whereas a python execution - limitation, allowing this would also lead to very hard-to-debug code - when using the interactive mode). The main issue with this is when - building e.g. a room in one code block and later want to connect that - room with a room you built in another block. To do this, you must - perform a database search for the name of the room you created (since - you cannot know in advance which dbref it got assigned). This sounds - iffy, but there is an easy way to handler this - use object aliases. - You can assign any number of aliases to any object. Make sure that - one of those aliases is unique (like "room56") and you will - henceforth be able to always find it later by searching for it from - other code blocks regardless of if the main name is shared with - hundreds of other rooms in your world (coincidentally, this is also - one way of implementing "zones", should you want to group rooms - together). - diff --git a/docs/sphinx/source/wiki/BatchCommandProcessor.rst b/docs/sphinx/source/wiki/BatchCommandProcessor.rst deleted file mode 100644 index 2835c96850..0000000000 --- a/docs/sphinx/source/wiki/BatchCommandProcessor.rst +++ /dev/null @@ -1,222 +0,0 @@ -The Batch-Command processor -=========================== - -For an introduction and motivation to using batch processors, see -`here `_. This page describes the Batch-*command* -processor. The Batch-*code* one is covered -`here `_. - -Basic Usage ------------ - -The batch-command processor is a superuser-only function, invoked by - -:: - - > @batchcommand path.to.batchcmdfile - -Where ``path.to.batchcmdfile`` is the path to a *batch-command file* -with the "``.ev``\ " file ending. This path is given like a python path -relative to a folder you define to hold your batch files, set with -``BATCH_IMPORT_PATH`` in your settings. Default folder is -``game/gamesrc/world``. So if you want to run the example batch file in -``game/gamesrc/world/examples/batch_cmds.ev``, you could use - -:: - - > @batchcommand examples.batch_cmds - -A batch-command file contains a list of Evennia in-game commands -separated by comments. The processor will run the batch file from -beginning to end. Note that *it will not stop if commands in it fail* -(there is no universal way for the processor to know what a failure -looks like for all different commands). So keep a close watch on the -output, or use *Interactive mode* (see below) to run the file in a more -controlled, gradual manner. - -The batch file --------------- - -The batch file is a simple plain-text file containing Evennia commands. -Just like you would write them in-game, except you have more freedom -with line breaks. - -Here are the rules of syntax of an ``*.ev`` file. You'll find it's -really, really simple: - -- All lines having the ``#`` (hash)-symbol *as the first one on the - line* are considered *comments*. All non-comment lines are treated as - a command and/or their arguments. -- Comment lines have an actual function -- they mark the *end of the - previous command definition*. So never put two commands directly - after one another in the file - separate them with a comment, or the - second of the two will be considered an argument to the first one. - Besides, using plenty of comments is good practice anyway. -- A line that starts with the word ``#INSERT`` is a comment line but - also signifies a special instruction. The syntax is - ``#INSERT `` and tries to import a given batch-cmd - file into this one. The inserted batch file (file ending ``.ev``) - will run normally from the point of the ``#INSERT`` instruction. -- Extra whitespace in a command definition is *ignored*. -- A completely empty line translates in to a line break in texts. Two - empty lines thus means a new paragraph (this is obviously only - relevant for commands accepting such formatting, such as the - ``@desc`` command). -- The very last command in the file is not required to end with a - comment. -- You *cannot* nest another ``@batchcommand`` statement into your batch - file. If you want to link many batch-files together, use the - ``#INSERT`` batch instruction instead. You also cannot launch the - ``@batchcode`` command from your batch file, the two batch processors - are not compatible. - -Below is a version of the example file found in -``game/gamesrc/commands/examples/batch_cmds.ev``. - -:: - - # - # This is an example batch build file for Evennia. - # - - # This creates a red button - @create button:examples.red_button.RedButton - # (This comment ends input for @create) - # Next command. Let's create something. - @set button/desc = - This is a large red button. Now and then - it flashes in an evil, yet strangely tantalizing way. - - A big sign sits next to it. It says: - - - ----------- - - Press me! - - ----------- - - - ... It really begs to be pressed! You - know you want to! - - # This inserts the commands from another batch-cmd file named - # batch_insert_file.ev. - #INSERT examples.batch_insert_file - - - # (This ends the @set command). Note that single line breaks - # and extra whitespace in the argument are ignored. Empty lines - # translate into line breaks in the output. - # Now let's place the button where it belongs (let's say limbo #2 is - # the evil lair in our example) - @teleport #2 - # (This comments ends the @teleport command.) - # Now we drop it so others can see it. - # The very last command in the file needs not be ended with #. - drop button - -To test this, run ``@batchcommand`` on the file. A button will be -created, described and dropped in Limbo. All commands will be executed -by the user calling the command. *Note that if you interact with the -button, you might find that its description changes, loosing your -custom-set description above. This is just the way this particular -object works.* - -Interactive mode ----------------- - -Interactive mode allows you to more step-wise control over how the batch -file is executed. This is useful for debugging and also if you have a -large batch file and is only updating a small part of it -- running the -entire file again would be a waste of time (and in the case of -``@create``-ing objects you would to end up with multiple copies of -same-named objects, for example). Use ``@batchcommand`` with the -``/interactive`` flag to enter interactive mode. - -:: - - > @batchcommand/interactive examples.batch_cmds - -You will see this: - -:: - - 01/04: @create button:examples.red_button.RedButton (hh for help) - -This shows that you are on the ``@create`` command, the first out of -only four commands in this batch file. Observe that the command -``@create`` has *not* been actually processed at this point! - -To take a look at the full command you are about to run, use ``ll`` (a -batch-processor version of ``look``). Use ``pp`` to actually process the -current command (this will actually ``@create`` the button) -- and make -sure it worked as planned. Use ``nn`` (next) to go to the next command. -Use ``hh`` for a list of commands. - -If there are errors, fix them in the batch file, then use ``rr`` to -reload the file. You will still be at the same command and can rerun it -easily with ``pp`` as needed. This makes for a simple debug cycle. It -also allows you to rerun individual troublesome commands - as mentioned, -in a large batch file this can be very useful. Do note that in many -cases, commands depend on the previous ones (e.g. if ``@create`` in the -example above had failed, the following commands would have had nothing -to operate on). - -Use ``nn`` and ``bb`` (next and back) to step through the file; e.g. -``nn 12`` will jump 12 steps forward (without processing any command in -between). All normal commands of Evennia should work too while working -in interactive mode. - -Limitations and Caveats ------------------------ - -The batch-command processor is great for automating smaller builds or -for testing new commands and objects repeatedly without having to write -so much. There are several caveats you have to be aware of when using -the batch-command processor for building larger, complex worlds though. - -The main issue is that when you run a batch-command script you (*you*, -as in your superuser character) are actually moving around in the game -creating and building rooms in sequence, just as if you had been -entering those commands manually, one by one. You have to take this into -account when creating the file, so that you can 'walk' (or teleport) to -the right places in order. - -This also means there are several pitfalls when designing and adding -certain types of objects. Here are some examples: - -- *Rooms that changes your `cmdset `_*: Imagine that you - build a 'dark' room, which severely limits the cmdsets of those - entering it (maybe you have to find the light switch to proceed). In - your batch script you would create this room, then teleport to it - - and promptly be shifted into the dark state where none of your normal - build commands work ... -- *Auto-teleportation*: Rooms that automatically teleport those that - enter them to another place (like a trap room, for example). You - would be teleported away too. -- *Mobiles*: If you add aggressive mobs, they might attack you, drawing - you into combat. If they have AI they might even follow you around - when building - or they might move away from you before you've had - time to finish describing and equipping them! - -The solution to all these is to plan ahead. Make sure that superusers -are never affected by whatever effects are in play. Add an on/off switch -to objects and make sure it's always set to *off* upon creation. It's -all doable, one just needs to keep it in mind. - -Assorted notes --------------- - -The fact that you build as 'yourself' can also be considered an -advantage however, should you ever decide to change the default command -to allow others than superusers to call the processor. Since normal -access-checks are still performed, a malevolent builder with access to -the processor should not be able to do all that much damage (this is the -main drawback of the `batch-code processor `_) - -`GNU Emacs `_ users might find it -interesting to use emacs' *evennia mode*. This is an Emacs major mode -found in ``src/utils/evennia-mode.el``. It offers correct syntax -highlighting and indentation with ```` when editing ``.ev`` files -in Emacs. See the header of that file for installation instructions. diff --git a/docs/sphinx/source/wiki/BatchProcessors.rst b/docs/sphinx/source/wiki/BatchProcessors.rst deleted file mode 100644 index 2698b56e4b..0000000000 --- a/docs/sphinx/source/wiki/BatchProcessors.rst +++ /dev/null @@ -1,103 +0,0 @@ -Batch Processors - overview -=========================== - -Building a game world is a lot of work, especially when starting out. -Rooms should be created, descriptions have to be written, objects must -be detailed and placed in their proper places. In many traditional MUD -setups you had to do all this online, line by line, over a telnet -session. - -Evennia already moves away from much of this by shifting the main coding -work to external Python modules. But also building would be helped if -one could do some or all of it externally. Enter Evennia's *batch -command processors* (there are two of them). The processors allows you, -as a game admin, to build your game completely offline in normal text -files (*batch files*) that the processors understands. Then, when you -are ready, you use the processors to read it all into Evennia (and into -the database) in one go. - -You can of course still build completely online should you want to - -this is certainly the easiest way to go when learning and for small -build projects. But for major building work, the advantages of using the -batch-processors are many: - -- It's hard to compete with the comfort of a modern desktop text - editor; Compared to a traditional MUD line input, you can get much - better overview and many more features. Also, accidentally pressing - Return won't immediately commit things to the database. -- You might run external spell checkers on your batch files. In the - case of one of the batch-processors (the one that deals with Python - code), you could also run external debuggers and code analyzers on - your file to catch problems before feeding it to Evennia. -- The batch files (as long as you keep them) are records of your work. - They make a natural starting point for quickly re-building your world - should you ever decide to start over. -- If you are an Evennia developer, using a batch file is a fast way to - setup a test-game after having reset the database. -- The batch files might come in useful should you ever decide to - distribute all or part of your world to others. - -There are two batch processors, the Batch-*command* processor and the -Batch-*code* processor. The first one is the simpler of the two. It has -the advantage of you not needing to know any programming - you basically -just list game commands in a text file. The code-processor on the other -hand is much more powerful but also more complex - it lets you to use -Evennia's API to code your world in full-fledged Python code. - -- The `Batch-command processor `_ -- The `Batch-code processor `_ - -If you plan to use international characters in your batchfiles you are -wise to read about *file encodings* below. - -A note on File Encodings ------------------------- - -As mentioned, both the processors take text files as input and then -proceeds to process them. As long as you stick to the standard -`ASCII `_ character set (which means -the normal English characters, basically) you should not have to worry -much about this section. - -Many languages however use characters outside the simple ``ASCII`` -table. Common examples are various apostrophes and umlauts but also -completely different symbols like those of the greek or cyrillic -alphabets. - -First, we should make it clear that Evennia itself handles international -characters just fine. It (and Django) uses -`unicode `_ strings internally. - -The problem is that when reading a text file like the batchfile, we need -to know how to decode the byte-data stored therein to universal unicode. -That means we need an *encoding* (a mapping) for how the file stores its -data. There are many, many byte-encodings used around the world, with -opaque names such as ``Latin-1``, ``ISO-8859-3`` or ``ARMSCII-8`` to -pick just a few examples. Problem is that it's practially impossible to -determine which encoding was used to save a file just by looking at it -(it's just a bunch of bytes!). You have to *know*. - -With this little introduction it should be clear that Evennia can't -guess but has to *assume* an encoding when trying to load a batchfile. -The text editor and Evennia must speak the same "language" so to speak. -Evennia will by default first try the international ``UTF-8`` encoding, -but you can have Evennia try any sequence of different encodings by -customizing the ``ENCODINGS`` list in your settings file. Evennia will -use the first encoding in the list that do not raise any errors. Only if -none work will the server give up and return an error message. - -You can often change the text editor encoding (this depends on your -editor though), otherwise you need to add the editor's encoding to -Evennia's ``ENCODINGS`` list. If you are unsure, write a test file with -lots of non-ASCII letters in the editor of your choice, then import to -make sure it works as it should. - -More help with encodings can be found in the entry `Text -Encodings `_ and also in the Wikipedia article -`here `_. - -**A footnote for the batch-code processor**: Just because *Evennia* can -parse your file and your fancy special characters, doesn't mean that -*Python* allows their use. Python syntax only allows international -characters inside *strings*. In all other source code only ``ASCII`` set -characters are allowed. diff --git a/docs/sphinx/source/wiki/BuilderDocs.rst b/docs/sphinx/source/wiki/BuilderDocs.rst deleted file mode 100644 index 3ed748bf42..0000000000 --- a/docs/sphinx/source/wiki/BuilderDocs.rst +++ /dev/null @@ -1,29 +0,0 @@ -Builder Documentation -===================== - -This section contains information useful to world builders. - -Building basics ---------------- - -- `Default in-game commands `_ -- `Building Quick-start `_ -- `Giving build permissions to others `_ -- `Adding colour `_ -- `Customizing the connection screen `_ - -Advanced building and World building ------------------------------------- - -- `Overview of batch processors `_ - - - `Batch-command processor `_ - - `Batch-code processor `_ - -- `Adding zones `_ - -The Tutorial world ------------------- - -- `Introduction and setup `_ - diff --git a/docs/sphinx/source/wiki/BuildingPermissions.rst b/docs/sphinx/source/wiki/BuildingPermissions.rst deleted file mode 100644 index 86c3b7a1cb..0000000000 --- a/docs/sphinx/source/wiki/BuildingPermissions.rst +++ /dev/null @@ -1,81 +0,0 @@ -Giving permissions to your staff -================================ - -*OBS: This gives only a brief introduction to the access system. Locks -and permissions are fully detailed* `here `_. - -The super user --------------- - -There are strictly speaking two types of users in Evennia, the *super -user* and everyone else. The superuser is the first user you create, -object #1. This is the all-powerful server-owner account. A superuser -account has access to everything and no locks affect them. Technically -the superuser not only has all access, it even bypasses the permission -checks entirely. This makes the superuser impossible to lock out, but -makes it unsuitable to actually play-test the game's locks and -restrictions with. Usually there is no need to have but one superuser. - -Assigning permissions ---------------------- - -Whereas permissions can be used for anything, those put in -settings.PERMISSION\_HIERARCHY will have a ranking relative each other -as well. By default Evennia creates the following hierarchy: - -#. *Immortals* - these basically have all the same access as superusers - (except that they do not sidestep the Permission system). Assign only - to really trusted server-admin staff. -#. *Wizards* can do everything except affecting the server functions - itself. So a wizard couldn't reload or shutdown the server for - example. They also cannot execute arbitrary Python code on the - console or import files from the hard drive. -#. *Builders* has all the build commands, but cannot affect other - players or mess with the server. -#. *PlayerHelpers* are almost like a normal *Player*, but they can also - add help files to the database. -#. *Players* is the default group that new players end up in. A new - player have permission to use tells, to use and create new channels. - -A user having a certain level of permission automatically have access to -locks specifying access of a lower level. - -To assign a new permission from inside the game, you need to be able to -use the ``@perm`` command. This is an *Immortal*-level command, but it -could in principle be made lower-access since it only allows assignments -equal or lower to your current level (so you cannot use it to escalate -your own permission level). So, assuming you yourself have *Immortal* -access (or is superuser), you assign a new player "Tommy" to your core -staff with the command - -:: - - @perm/add *Tommy = Immortals - -The ``*`` makes sure to put the permission on the *Player* and not on -any eventual *Character* that may also be named Tommy. This is usually -what you want since the Player will then remain an Immortal regardless -of which Character they are currently controlling. To limit permission -to a per-Character level you should instead use *quelling* (see below). - -Quelling your permissions -------------------------- - -When developing it can be useful to check just how things would look had -your permission-level been lower. For this you can use *quelling*. -Normally, when you puppet a Character you are using your Player-level -permission. So even if your Character only has *Players* level -permissions, your *Immortals*-level Player will take precedence. With -the ``@quell`` command you can change so that the Character's permission -takes precedence instead: - -:: - - @quell - -This will allow you to test out the game using the current Character's -permission level. A developer or builder can thus in principle maintain -several test characters, all using different permission levels. Note -that you cannot escalate your permissions this way; If the Character -happens to have a *higher* permission level than the Player, the -Player's permission will still be used. diff --git a/docs/sphinx/source/wiki/BuildingQuickstart.rst b/docs/sphinx/source/wiki/BuildingQuickstart.rst deleted file mode 100644 index 35da4ff20a..0000000000 --- a/docs/sphinx/source/wiki/BuildingQuickstart.rst +++ /dev/null @@ -1,354 +0,0 @@ -Building Quick-start -==================== - -The default `command `_ definitions coming with Evennia -follows a style `similar `_ to that of MUX, so -the commands should be familiar if you used any such code bases before. -If you haven't, you might be confused by the use of ``@`` all over. This -is just a naming convention - commands related to out-of-character or -admin-related actions tend to start with ``@``, the symbol has no -meaning of its own. - -The default commands have the following style (where ``[...]`` marks -optional parts): - -:: - - command[/switch/switch...] [arguments ...] - -A *switch* is a special, optional flag to the command to make it behave -differently. It is always put directly after the command name, and -begins with a forward slash (``/``). The *arguments* are one or more -inputs to the commands. It's common to use an equal sign (``=``) when -assigning something to an object. - -Below are some examples of commands. Use ``help `` for learning -more about each command and their detailed options. - -Stepping down from godhood --------------------------- - -If you just installed Evennia, your very first player account is called -user #1, also known as the *superuser* or *god user*. This user is very -powerful, so powerful that it will override many game restrictions such -as locks. This can be useful, but it also hides some functionality that -you might want to test. - -To temporarily step down from your superuser position you can use the -``@quell`` command: - -:: - - > @quell - -This will make you start using the permission of your current -`Character `_ instead of your superuser level. If you -didn't change any settings your game Character should have an *Immortal* -level permission - high as can be without bypassing locks like the -superuser does. This will work fine for the examples on this page. Use -``@unquell`` to get back to superuser status again afterwards. - -Creating an object ------------------- - -Basic objects can be anything -- swords, flowers and non-player -characters. They are created using the ``@create`` command: - -:: - - > @create box - -This created a new 'box' (of the default object type) in your inventory. -Use the command ``inventory`` (or ``i``) to see it. Now, 'box' is a -rather short name, let's is give a few aliases. - -:: - - > @name box = very large box;box;very;crate - -We now actually renamed the box to *very large box* (and this is what we -will see when looking at it), but we will also recognize it by any of -the other names we give - like *crate* or simply *box* as before. We -could have given these aliases directly after the name in the -``@create`` command, this is true for all creation commands - you can -always tag on a list of ;-separated aliases to the name of your new -object. If you had wanted to not change the name itself, but to only add -aliases, you could have used the ``@alias`` command. - -We are currently carrying the box. Let's drop it. - -:: - - > drop box - -Hey presto - there it is on the ground, in all its normality (you can -also create & drop in one go using the ``/drop`` switch, like this: -``@create/drop box``). - -:: - - > examine box - -This will show some technical details about the box object (you can -normally just write ``ex`` as a short for ``examine``). - -Try to ``look`` at the box to see the (default) description. - -:: - - > look box - -Let's add some flavor. - -:: - - > @describe box = This is a large and very heavy box. - -If you try the ``get`` command we will pick up the box. So far so good, -but if we really want this to be a large and heavy box, people should -*not* be able to run off with it that easily. To prevent this we need to -lock it down. This is done by assigning a *Lock* to it. Make sure the -box was dropped in the room, then try this: - -:: - - > @lock box = get:false() - -Locks are a rather `big topic `_, but for now that will do -what we want. This will lock the box so noone can lift it. The exception -is superusers, they override all locks and will pick it up anyway. Make -sure you are quelling your superuser powers and try to get the box now: - -:: - - > get box - You can't get that. - -Think the default error message looks dull? The ``get`` command looks -for an `Attribute `_ named ``get_err_msg`` for -returning a nicer error message (we just happen to know this, you would -need to peek into the code for the ``get`` command to find out). You set -attributes using the ``@set`` command: - -:: - - > @set box/get_err_msg = It's way too heavy for you to lift. - -Try to get it now and you should see a nicer error message echoed back -to you. - -Get a personality ------------------ - -`Scripts `_ are powerful things that allows time-dependent -effects on objects. To try out a first script, let's put one on -ourselves. There is an example script in -``game/gamesrc/scripts/examples/bodyfunctions.py`` that is called -``BodyFunctions``. To add this to us we will use the ``@script`` -command: - -:: - - > @script self = examples.bodyfunctions.BodyFunctions - -(note that you don't have to give the full path as long as you are -pointing to a place inside the ``gamesrc/scripts`` directory). Wait a -while and you will notice yourself starting making random observations. - -:: - - > @script self - -This will show details about scripts on yourself (also ``examine`` -works). You will see how long it is until it "fires" next. Don't be -alarmed if nothing happens when the countdown reaches zero - this -particular script has a randomizer to determine if it will say something -or not. So you will not see output every time it fires. - -When you are tired of your character's "insights", kill the script with - -:: - - > @script/stop self = examples.bodyfunctions.BodyFunctions - -Pushing your buttons --------------------- - -If we get back to the box we made, there is only so much fun you can do -with it at this point. It's just a dumb generic object. If you renamed -it to ``stone`` and changed its description noone would be the wiser. -However, with the combined use of custom -`Typeclasses `_, `Scripts `_ and -object-based `Commands `_, you could expand it and other -items to be as unique, complex and interactive as you want. - -Let's take an example. So far we have only created objects that use the -default object typeclass named simply ``Object``. Let's create an object -that is a little more interesting. Under ``game/gamesrc/objects/`` there -is a directory ``examples`` with a module ``red_button.py``. It contains -the enigmatic RedButton typeclass. - -Let's make us one of *those*! - -:: - - > @create/drop button:examples.red_button.RedButton - -We import the RedButton python class the same way you would import it in -Python except Evennia defaults to looking in ``game/gamesrc/objects/`` -so you don't have to write the full path every time. There you go - one -red button. - -The RedButton is an example object intended to show off a few of -Evennia's features. You will find that the `Scripts `_ and -`Commands `_ controlling it are scattered in -``examples``-folders all across ``game/gamesrc/``. - -If you wait for a while (make sure you dropped it!) the button will -blink invitingly. Why don't you try to push it ...? Surely a big red -button is meant to be pushed. You know you want to. - -Making yourself a house ------------------------ - -The main command for shaping the game world is ``@dig``. For example, if -you are standing in Limbo you can dig a route to your new house location -like this: - -:: - - > @dig house = large red door;door;in, to the outside;out - -This will create a new room named 'house'. It will also directly create -an exit from your current location named 'large red door' and a -corresponding exit named 'to the outside' in the house room leading back -to Limbo. We also define a few aliases to those exits, so people don't -have to write the full thing all the time. - -If you wanted to use normal compass directions (north, west, southwest -etc), you could do that with ``@dig`` too. But Evennia also has a -limited version of ``@dig`` that helps for compass directions (and also -up/down and in/out). It's called ``@tunnel``: - -:: - - > @tunnel sw = cliff - -This will create a new room "cliff" with an exit "southwest" leading -there and a path "northeast" leading back from the cliff to your current -location. - -You can create new exits from where you are using the ``@open`` command: - -:: - - > @open north;n = house - -This opens an exit ``north`` to the previously created room ``house``. - -If you have many rooms named ``house`` you will get a list of matches -and have to select which one you want to link to. You can also give its -database (#dbref) number, which is unique to every object. This can be -found with the ``examine`` command or by looking at the latest -constructions with ``@objects``. - -Follow the north exit to your 'house' or ``@teleport`` to it: - -:: - - > north - -or: - -:: - - > @teleport house - -To manually open an exit back to Limbo (if you didn't do so with the -``@dig`` command): - -:: - - > @open door = limbo - -(or give limbo's dbref which is #2) - -Reshuffling the world ---------------------- - -You can find things using the ``@find`` command. Assuming you are back -at ``Limbo``, let's teleport the *large box to our house*. - -:: - - > @teleport box = house - very large box is leaving Limbo, heading for house. - Teleported very large box -> house. - -We can still find the box by using @find: - -:: - - > @find box - One Match(#1-#8): - very large box(#8) - src.objects.objects.Object - -Knowing the #dbref of the box (#8 in this example), you can grab the box -and get it back here without actually yourself going to ``house`` first: - -:: - - > @teleport #8 = here - -(You can usually use ``here`` to refer to your current location. To -refer to yourself you can use ``self`` or ``me``). The box should now be -back in Limbo with you. - -We are getting tired of the box. Let's destroy it. - -:: - - > @destroy box - -You can destroy many objects in one go by giving a comma-separated list -of objects (or their #dbrefs, if they are not in the same location) to -the command. - -Adding a help entry -------------------- - -An important part of building is keeping the help files updated. You can -add, delete and append to existing help entries using the ``@sethelp`` -command. - -:: - - > @sethelp/add MyTopic = This help topic is about ... - -Adding a World --------------- - -After this brief introduction to building you may be ready to see a more -fleshed-out example. Evennia comes with a tutorial world for you to -explore. - -First you need to switch back to *superuser* by using the ``@unquell`` -command. Next, place yourself in ``Limbo`` and run the following -command: - -:: - - > @batchcommand contrib.tutorial_world.build - -This will take a while (be patient and don't re-run the command). You -will see all the commands used to build the world scroll by as the world -is built for you. - -You will end up with a new exit from Limbo named *tutorial*. Apart from -being a little solo-adventure in its own right, the tutorial world is a -good source for learning Evennia building (and coding). - -Read -`contrib/tutorial\_world/build.ev `_ -to see exactly how it's built, step by step. See also more info about -the tutorial world `here `_. diff --git a/docs/sphinx/source/wiki/Caches.rst b/docs/sphinx/source/wiki/Caches.rst deleted file mode 100644 index 5d86fa0888..0000000000 --- a/docs/sphinx/source/wiki/Caches.rst +++ /dev/null @@ -1,151 +0,0 @@ -Caches -====== - -*Note: This is an advanced topic. You might want to skip it on a first -read-through.* - -Evennia is a fully persistent system, which means that it will store -things in the database whenever its state changes. Since accessing the -database i comparably expensive, Evennia uses an extensive *caching* -scheme. Caching normally means that once data is read from the database, -it is stored in memory for quick retrieval henceforth. Only when data -changes will the database be accessed again (and the cache updated). - -With a few exceptions, caching are primarily motivated by speed and to -minimize bottlenecks found by profiling the server. Some systems must -access certain pieces of data often, and going through the django API -over and over builds up. Depending on operation, individual speedups of -hundreds of times can be achieved by clever caching. - -The price for extended caching is memory consumption and added -complexity. This page tries to explain the various cache strategies in -place. Most users should not have to worry about them, but if you ever -try to "bang the metal" with Evennia, you should know what you are -seeing. - -All caching schemes except Idmapper is centralized in -``src/server.caches/py``. You can turn off all caches handled by that -module by use of the ``GAME_CACHE_TYPE`` setting. - -The default ``@server`` command will give a brief listing of the memory -usage of most relevant caches. - -Idmapper --------- - -Evennia's django object model is extended by *idmapper* functionality. -The idmapper is an external third-party system that sits in -``src/utils/idmapper``. The idmapper is an on-demand memory mapper for -all database models in the game. This means that a given database object -is represented by the same memory area whenever it is accessed. This may -sound trivial but it is not - in plain Django there is no such -guarantee. Doing something like ``objdb.test = "Test"`` (were objdb is a -django model instance) would be unsafe and most likely the ``test`` -variable would be lost next time the model is retrieved from the -database. As Evennia ties `Typeclasses `_ to django -models, this would be a catastophy. - -Idmapper is originally a memory saver for django websites. In the case -of a website, object access is brief and fleeting - not so for us. So we -have extended idmapper to never loose its reference to a stored object -(not doing this was the cause of a very long-standing, very hard-to-find -bug). - -Idmapper is an on-demand cache, meaning that it will only cache objects -that are actually accessed. Whereas it is possible to clean the idmapper -cache via on-model methods, this does not necessarily mean its memory -will be freed - this depends on any lingering references in the system -(this is how Python's reference counting works). If you ever need to -clean the idmapper cache, the safest way is therefore a soft-reload of -the server (via e.g. the ``@reload`` command). - -Most developers will not need to care with the idmapper cache - it just -makes models work intuitively. It is visible mostly in that many -database models in Evennia inherit from -``src.utils.idmapper.models.SharedMemoryModel``. - -On-object variable cache ------------------------- - -All database fields on all objects in Evennia are cached by use of -`Python -properties `_. -So when you do ``name = obj.key``, you are actually *not* directly -accessing a database field "key" on the object. What you are doing is -actually to access a handler. This handler reads the field ``db_key`` -and caches its value for next time it using a call to the the -``server.caches`` module. - -The naming scheme is consistent, so a given field property ``obj.foo`` -is always a handler for a database field ``obj.db_key.`` The handler -methods for the property are always named ``obj.foo_get()``, -``obj.foo_set()`` and ``obj.foo_del()`` (all are not always needed). - -Apart from caching, property handlers also serves another function - -they hide away Django administration. So doing ``obj.key = "Peter"`` -will not only assign (and cache) the string "Peter" in the database -field ``obj.db_key``, it will also call ``obj.save()`` for you in order -to update the database. - -Hiding away the model fields presents one complication for developers, -and that is searching using normal django methods. Basically, if you -search using e.g. the standard django ``filter`` method, you must search -for ``db_key``, not ``key``. Only the former is known by django, the -latter will give an invalid-field error. If you use Evennia's own search -methods you don't need to worry about this, they look for the right -things behind the scenes for you. - -Content cache -~~~~~~~~~~~~~ - -A special case of on-object caching is the *content* cache. Finding the -"contents" of a particular location turns out to be a very common and -pretty expensive operation. Whenever a person moves, says something or -does other things, "everyone else" in a given location must be informed. -This means a database search for which objects share the location. - -``obj.contents`` is a convenient container that at every moment contains -a cached list of all objects "inside" that particular object. It is -updated by the ``location`` property. So ``obj1.location = obj2`` will -update ``obj2.contents`` on the fly to contain ``obj1``. It will also -remove ``obj1`` from the ``contents`` list of its previous location. -Testing shows that when moving from one room to another, finding and -messaging everyone in the room took up as much as *25%* of the total -computer time needed for the operation. After caching ``contents``, -messaging now takes up *0.25%* instead ... - -The contents cache should be used at all times. The main thing to -remember is that if you were to somehow bypass the ``location`` handler -(such as by setting the ``db_location`` field manually), you will bring -the cache and database out of sync until you reload the server. - -Typeclass cache -~~~~~~~~~~~~~~~ - -All typeclasses are cached on the database model. This allows for quick -access to the typeclass through ``dbobj.typeclass``. Behind the scenes -this operation will import the typeclass definition from a path stored -in ``db_typeclass_path`` (available via the property handler -``typeclass_path``). All checks and eventual debug messages will be -handled, and the result cached. - -The only exception to the caching is if the typeclass module had some -sort of syntax error or other show-stopping bug. The default typeclass -(as defined in ``settings``) will then be loaded instead. The error will -be reported and *no* caching will take place. This is in order to keep -reloading the typeclass also next try, until it is fixed. - -On-object Attribute cache -------------------------- - -`Attribute `_ lookups on objects are also cached. This -means that after the first access or assignment, ``obj.db.attrname`` is -as fast as accessing any normal python property - this removes the -necessity for subsequent database look-ups in order to retrieve -attributes. Both ``db`` and ``ndn`` work the same way in this regard. - -Due to the possibility of storing objects in Attributes, the system -cannot cache the value of data stored in the Attribute (this would allow -for the system not detecting a stored Object being deleted elsewhere - -it would still be accessible from the Attribute). So having to re-access -such objects every load does incur a minor speed penalty. diff --git a/docs/sphinx/source/wiki/ChoosingAnSQLServer.rst b/docs/sphinx/source/wiki/ChoosingAnSQLServer.rst deleted file mode 100644 index 29beadc4c6..0000000000 --- a/docs/sphinx/source/wiki/ChoosingAnSQLServer.rst +++ /dev/null @@ -1,79 +0,0 @@ -Choosing an SQL Server -====================== - -Since Evennia uses `Django `_, most of our -notes are based off of what we know from the community and their -documentation. While the information below may be useful, you can always -find the most up-to-date and "correct" information at Django's `Notes -about supported -Databases `_ -page. - -SQLite3 -------- - -This is the default database used, and for the vast majority of Evennia -installs it will probably be more than adequate. It's definitely -recommended for most of your development. No server process is needed, -the administrative overhead is tiny (as is resource consumption). The -database will appear as a simple file (``game/evennia.db3``) and since -we run SQLite as an in-memory process without any socket overhead, it -might well be faster than Postgres/MySQL unless your database is huge. - -The drawback with SQLite3 is that it does not work very well will -multiple concurrent threads or processes. This has to do with -file-locking clashes of the database file. So for a production server -making heavy use of process- or threadpools (or when using a third-party -webserver like Apache), a more full-featured database may be the better -choice. - -Postgres --------- - -This is Django's recommended database engine, While not as fast as -SQLite for normal usage, it will scale better than SQLite, especially if -your game has an very large database and/or extensive web presence -through a separate server process. - -**Warning:** Postgres has issues with Evennia on some installs at the -moment. `Issue -151 `_ outlines -this. If unsure, avoid Postgres for now. - -MySQL ------ - -MySQL *may* be slightly faster than Postgres depending on your setup and -software versions involved. Older versions of MySQL had some -peculiarities though, so check out Django's `Notes about supported -Databases `_ -to make sure you use the correct version. - -Others ------- - -No testing has been performed with Oracle, but it is also supported. -There are community maintained drivers for `MS -SQL `_ and possibly a few others -(found via our friend, Google). - -Inspecting database data -======================== - -If you know SQL you can easily get command line access to your database -like this: - -:: - - python game/gamesrc.py dbshell - -This will drop you into the command line interface for your respective -database. - -There are also a host of easier graphical interfaces for the various -databases. For SQLite3 we recommend `SQLite -manager `_. -This is a plugin for the -`Firefox `_ web browser -making it usable across all operating systems. Just use it to open the -game/evennia.db3 file. diff --git a/docs/sphinx/source/wiki/CodingIntroduction.rst b/docs/sphinx/source/wiki/CodingIntroduction.rst deleted file mode 100644 index 7f75e689f5..0000000000 --- a/docs/sphinx/source/wiki/CodingIntroduction.rst +++ /dev/null @@ -1,63 +0,0 @@ -Evennia coding introduction -=========================== - -Evennia allows for a lot of freedom when designing your game - but to -code efficiently you still need to adopt some best practices as well as -find a good place to start to learn. - -Here are some pointers to get you going. - -Code in \`game/gamesrc\`, not in \`src/\` ------------------------------------------ - -You will create and code your game by adding Python modules in -``game/gamesrc/`` (see the `directory -overview `_). This is your home. You should -*never* need to modify anything under ``src/`` (anything you download -from us, really). Treat ``src/`` as a kind of library. You import useful -functionality from here. If you see code you like, copy&paste it out -into ``game/gamesrc`` and edit it there. - -If you find that ``src/`` *doesn't* support some functionality you need, -make a `Feature -Request `_ about it. Same -goes for `bugs `_. If you -add features or fix bugs yourself, please consider -`contributing `_ your changes upstream! - -Learn with \`ev\` ------------------ - -Learn the `ev interface `_. This is a great way to explore -what Evennia has to offer. For example, start an interactive python -shell, import ``ev`` and just look around. - -You can complement your exploration by peeking at the sections of the -much more detailed `Developer Central `_. The -`Tutorials `_ section also contains a growing collection -of system- or implementation-specific help. - -Plan before you code --------------------- - -Before you start coding away at your dream game, take a look at our -`game planning hints and tips `_ page. It might -hopefully help you avoid some common pitfalls and time sinks. - -Docs are here to help you -------------------------- - -Some people find reading documentation extremely dull and shun it out of -principle. That's your call, but reading docs really *does* help you, -promise! Evennia's documentation is pretty thorough and knowing what is -possible can often give you a lot of new cool game ideas. That said, if -you can't find the answer in the docs, don't be shy to ask questions! -The `discussion -group `_ and -the `irc chat `_ are -there for you. - -The most important point ------------------------- - -And finally, of course, have fun! diff --git a/docs/sphinx/source/wiki/CodingUtils.rst b/docs/sphinx/source/wiki/CodingUtils.rst deleted file mode 100644 index fd3b5a93f6..0000000000 --- a/docs/sphinx/source/wiki/CodingUtils.rst +++ /dev/null @@ -1,256 +0,0 @@ -Utils -===== - -Evennia comes with many utilities to help with common coding tasks. Some -of these are part of the command interface but most can be found in the -``src/utils/`` folder. They are used all over the server, but offer help -for many common tasks when coding your own game as well. This is not a -complete list, check the module for more goodies. - -Search ------- - -A common thing to do is to search for objects. The most common time one -needs to do this is inside a command body. There it's easiest to use the -``search`` method defined on all objects. This will search for objects -in the same location and inside the caller: - -:: - - obj = self.caller.search(objname) - -Give the keyword ``global_search=True`` to extend search to encompass -entire database. Also aliases with be matched by this search. You will -find multiple examples of this functionality in the default command set. - -If you need to search for objects in a code module you can use the -functions in ``src.utils.search``. You can access these as shortcuts -``ev.search_*``. - -:: - - from ev import search_object - obj = search_object(objname) - -``utils.search`` contains properties to the relevant database search -method. They are really just shortcuts to the django-database search -methods, like ``ObjectDB.objects.search()``. - -**Note:** If you are a Django wizz, you might be tempted to use Django's -database search functions directly (using ``filter``, ``get`` etc). Just -remember that such operations will give you a django model whereas -Evennia's manager methods will give you a typeclass. It's easy to -convert between them with ``dbobj.typeclass`` and ´typeclass.dbobj´, -but you should remember this distinction. If you stick with Evennia's -search methods you will always get typeclasses back. - -Create ------- - -Apart from the in-game build commands (``@create`` etc), you can also -build all of Evennia's game entities directly in code (for example when -defining new create commands). This *must* be done using -``src.utils.create`` or their shortcuts ``ev.create_*``- these functions -are responsible for setting up all the background intricacies of the -typeclass system and other things. Creating database instances using raw -Django will *not* work. Examples: - -:: - - import ev - # - myobj = ev.create_objects("game.gamesrc.objects.myobj.MyObj", key="MyObj") - myscr = ev.create_script("game.gamesrc.scripts.myscripts.MyScript", obj=myobj) - help = ev.create_help_entry("Emoting", "Emoting means that ...") - msg = ev.create_message(senderobj, [receiverobj], "Hello ...") - chan = ev.create_channel("news") - player = ev.create_player("Henry", "henry@test.com", "H@passwd") - -Each of these create functions have a host of arguments to further -customize the created entity. See ``src/utils/create.py`` for more -information. - -Logging -------- - -Normally you can use Python ``print`` statements to see output to the -terminal (if you started Evennia in *interactive mode* with the -i -switch). This should only be used for debugging though, for real output, -use the logger - it will log to the terminal in interactive mode, to the -log file otherwise. - -:: - - from ev import logger - # - logger.log_errmsg("This is an Error!") - logger.log_warnmsg("This is a Warning!") - logger.log_infomsg("This is normal information") - logger.log_depmsg("This feature is deprecated") - -There is also a special log-message type that is intended to be called -from inside a traceback - this can be very useful for relaying the -traceback message back to log without having it kill the server. - -:: - - try: - # [some code that may fail...] - except Exception: - logger.log_trace("This text will be appended to the traceback info") - -inherits\_from() ----------------- - -This useful function takes two arguments - an object to check and a -parent. It returns ``True`` if object inherits from parent *at any -distance* (as opposed to Python's in-built ``is_instance()`` that will -only catch immediate dependence). This function also accepts as input -any combination of classes, instances or python-paths-to-classes. - -Note that Python code should usually work with `duck -typing `_. But in Evennia's -case it can sometimes be useful to check if an object inherits from a -given `Typeclass `_ as a way of identification. Say -for example that we have a typeclass *Animal*. This has a subclass -*Felines* which in turns is a parent to *HouseCat*. Maybe there are a -bunch of other animal types too, like horses and dogs. Using -``inherits_from`` will allow you to check for all animals in one go: - -:: - - from ev import utils - if (utils.inherits_from(obj, "game.gamesrc.objects.animals.Animal"): - obj.msg("The bouncer stops you in the door. He says: 'No talking animals allowed.'") - -delay() -------- - -This is a thin wrapper around a Twisted construct called a *deferred*. -It simply won't return until a given number of seconds have passed, at -which time it will trigger a given callback with whatever argument. This -is a small and lightweight (non-persistent) alternative to a full -`Script `_. Contrary to a Script it can also handle -sub-second timing precision (although this is not something you should -normally need to worry about). - -Some text utilities -------------------- - -In a text game, you are naturally doing a lot of work shuffling text -back and forth. Here is a *non-complete* selection of text utilities -found in ``src/utils/utils.py`` (shortcut ``ev.utils``). If nothing else -it can be good to look here before starting to develop a solution of -your own. - -fill() -~~~~~~ - -This flood-fills a text to a given width (shuffles the words to make -each line evenly wide). It also indents as needed. - -:: - - outtxt = fill(intxt, width=78, indent=4) - -crop() -~~~~~~ - -This function will crop a very long line, adding a suffix to show the -line actually continues. This can be useful in listings when showing -multiple lines would mess up things. - -:: - - intxt = "This is a long text that we want to crop." - outtxt = crop(intxt, width=19, suffix="[...]") - # outtxt is now "This is a long text[...]" - -dedent() -~~~~~~~~ - -This solves what may at first glance appear to be a trivial problem with -text - removing indentations. It is used to shift entire paragraphs to -the left, without disturbing any further formatting they may have. A -common case for this is when using Python triple-quoted strings in code -- they will retain whichever indentation they have in the code, and to -make easily-readable source code one usually don't want to shift the -string to the left edge. - -:: - - #python code is entered at a given indentation - intxt = """ - This is an example text that will end - up with a lot of whitespace on the left. - It also has indentations of - its own.""" - outtxt = dedent(intxt) - # outtxt will now retain all internal indentation - # but be shifted all the way to the left. - -Normally you do the dedent in the display code (this is for example how -the help system homogenizes help entries). - -time\_format() -~~~~~~~~~~~~~~ - -This function takes a number of seconds as input and converts it to a -nice text output in days, hours etc. It's useful when you want to show -how old something is. It converts to four different styles of output -using the *style* keyword: - -- style 0 - ``5d:45m:12s`` (standard colon output) -- style 1 - ``5d`` (shows only the longest time unit) -- style 2 - ``5 days, 45 minutes`` (full format, ignores seconds) -- style 3 - ``5 days, 45 minutes, 12 seconds`` (full format, with - seconds) - -text conversion() -~~~~~~~~~~~~~~~~~ - -Evennia supplies two utility functions for converting text to the -correct encodings. ``to_str()`` and ``to_unicode()``. The difference -from Python's in-built ``str()`` and ``unicode()`` operators are that -the Evennia ones makes use of the ``ENCODINGS`` setting and will try -very hard to never raise a traceback but instead echo errors through -logging. See `TextEncodings `_ for more info. - -format\_table() -~~~~~~~~~~~~~~~ - -This function creates nicely formatted tables - columns of text all -lined up. It will automatically widen each column so all entries fit. - -To use it, you need to create a list of lists - each sublist contains -the content of one column. The result will be a list of ready-formatted -strings to print. - -:: - - # title line - cols = [["num"],["x"],["y"]] - # creating a dummy table with integers - for i in range(3): - cols[0].append(i) - cols[1].append(i+1) - cols[2].append(i+2) - # format the table (returns list with rows) - ftable = format_table(cols, extra_space=3) - # print the rows, making header bright white - for irow, row in enumerate(ftable): - if irow == 0: # header - print "{w%s{x" % row - else: - print row - # Output (no colors shown): - # - # num x y - # 1 2 3 - # 2 3 4 - # 3 4 5 - # - -Note that you cannot add colour codes to the input to ``format_table`` - -these would mess up the width of each column. Instead you can add this -to the output when printing. diff --git a/docs/sphinx/source/wiki/Colours.rst b/docs/sphinx/source/wiki/Colours.rst deleted file mode 100644 index fd031a8c64..0000000000 --- a/docs/sphinx/source/wiki/Colours.rst +++ /dev/null @@ -1,58 +0,0 @@ -Adding Colour to your game -========================== - -*Note that the Docs does not display colour the way it would look on the -screen.* - -Evennia supports the ``ANSI`` standard for displaying text. This means -that you can put markers in your text and if the user's -client/console/display supports those markers, they will see the text in -the specified colour. Remember that whereas there is, for example, one -special marker meaning "yellow", which colour (hue) of yellow is -*actually* displayed on the user's screen depends on the settings of -their particular mud client/viewer. They could even swap around the -colours displayed if they wanted to. or turn them off altogether. Some -clients don't support colour from the onset - text games are also played -with special reading equipment by people who are blind or have otherwise -diminished eyesight. So a good rule of thumb is to use colour to enhance -your game, but don't *rely* on it to display critical information. If -you are coding the game, you can add functionality to let users disable -colours as they please, as described `here `_. - -Adding colour to in-game text is easy. You just put in special markers -in your text that tell Evennia when a certain colour begins and when it -ends. There are two markup styles. The traditional(?) one use ``%c#`` to -mark colour: - -:: - - This is a %crRed text%cn This is normal text again. - %cRThis text has red background%cn this is normal text. - -``%c#`` - markup works like a switch that is on until you actively turn -it off with ``%cn`` (this returns the text to your default setting). -Capital letters mean background colour, lower-case means letter-colour. -So ``%cR`` means a red area behind your normal-colour text. If you -combine red background with red foreground text - ``%cR%cr``, you get a -solid red block with no characters visible! Similarly, ``%cR%cx`` gives -red background with black text. ``%ch`` 'hilights' your current text, so -grey becomes white, dark yellow becomes bright yellow etc. - -The drawback of the ``%cs`` style has to do with how Python formats -strings - the ``%`` is used in Python to create special text formatting, -and combining that with colour codes easily leads to messy and -unreadable code. It is thus often easier to use ``{#`` style codes: - -:: - - This is a {rBright red text{n This is normal text again - -The ``{x`` format don't include background colour, it only colours the -foreground text. The basic rule is that lower-case letter means bright -(hilighted) colour, whereas the upper-case one is for darker colour. So -``{g`` means bright green and ``{G`` means dark green. ``{n`` returns to -normal text colour. The equivalent in ``%c``-style markup is ``%cg%ch`` -for bright green and ``%cg`` for dark green. - -You can find a list of all the parsed ``ANSI``-colour codes in -``src/utils/ansi.py``. diff --git a/docs/sphinx/source/wiki/CommandCooldown.rst b/docs/sphinx/source/wiki/CommandCooldown.rst deleted file mode 100644 index c6d288abf8..0000000000 --- a/docs/sphinx/source/wiki/CommandCooldown.rst +++ /dev/null @@ -1,95 +0,0 @@ -*This tutorial requires that you first well understand how -`Commands `_ work.* - -Cooldowns -========= - -Some types of games want to limit how often a command can be run. If a -character casts the spell *Firestorm*, you might not want them to spam -that command over and over. Or in an advanced combat system, a massive -swing may offer a chance of lots of damage at the cost of not being able -to re-do it for a while. Such effects are called *cooldowns*. - -Evennia allows for many ways to implement cooldowns. Here are some -ideas. - -Simplest way - single-command, non-persistent cooldown ------------------------------------------------------- - -This little recipe will limit how often a particular command can be run. -Since Commands are class instances, and those are cached in memory, a -command instance will remember things you store on it. So just store the -current time of execution! Next time the command is run, it just needs -to check if it has that time stored, and compare it with the current -time to see if a desired delay has passed. - -:: - - import time - from ev import default_cmds - - class CmdSpellFirestorm(default_cmds.MuxCommand): - """ - Spell - Firestorm - - Usage: - cast firestorm - - This will unleash a storm of flame. You can only release one - firestorm every five minutes (assuming you have the mana). - """ - key = "cast firestorm" - locks = "cmd:isFireMage()" - - def func(self): - "Implement the spell" - - # check cooldown (5 minute cooldown) - if hasattr(self, "lastcast") and time.time()-self.lastcast < 5*60: - self.caller.msg("You need to wait before casting this spell again.") - return - - #[the spell effect is implemented] - - # if the spell was successfully cast, store the casting time - self.lastcast = time.time() - -We just check the ``lastcast`` flag, and update it if everything works -out. Simple and very effective since everything is just stored in -memory. The drawback of this simple scheme is that it's non-persistent. -If you do ``@reload``, the cache is cleaned and all such ongoing -cooldowns will be forgotten. It is also limited only to this one -command, other commands cannot (easily) check for this value. - -Persistent cooldown -------------------- - -This is essentially the same mechanism as the simple one above, except -we use the database to store the information which means the cooldown -will survive a server reload/reboot. Since commands themselves have no -representation in the database, you need to use the caster for the -storage. - -:: - - #[...] - # check cooldown (5 minute cooldown) - lastcall = self.caller.db.firestorm_lastcast # returns None if not exist yet - if lastcast and time.time() - lastcast < 5*60: - self.caller.msg("You need to wait before casting this spell again.") - return - - #[the spell effect is implemented] - - # if the spell was successfully cast, store the casting time - self.caller.db.firestorm_lastcast = time.time() - -Since we are storing as an `Attribute `_, we need to -identify the variable as ``firestorm_lastcast`` so we are sure we get -the right one (we'll likely have other skills with cooldowns after all). -But this method of using cooldowns also has the advantage of working -*between* commands - you can for example let all fire-related spells -check the same cooldown to make sure the casting of *Firestorm* blocks -all fire-related spells for a while. Or, in the case of taking that big -swing with the sword, this could now block all other types of attacks -for a while before the warrior can recover. diff --git a/docs/sphinx/source/wiki/CommandPrompt.rst b/docs/sphinx/source/wiki/CommandPrompt.rst deleted file mode 100644 index 7ac6901980..0000000000 --- a/docs/sphinx/source/wiki/CommandPrompt.rst +++ /dev/null @@ -1,144 +0,0 @@ -Adding a command prompt -======================= - -A *prompt* is quite common in MUDs. The prompt display useful details -about your character that you are likely to want to keep tabs on at all -times, such as health, magical power etc. It might also show things like -in-game time, weather and so on. - -Prompt after the command ------------------------- - -One common form of prompt appears after every command you send. So, say -you enter the look command; you would then get the result of the look -command, followed by the prompt. As an example:  - -:: - - > look - You see nothing special. - HP:10, SP:20, MP: 5 - -MUD clients can be set to detect prompts like this and display them in -various client-specific ways. - -To add this kind of "after-every-command-prompt", you can use the -``at_post_cmd()`` hook. This is to be defined on the Command class and -Evennia will always call it right after ``func()`` has finished -executing. For this to appear after every command you enter, it's best -to put this in the parent for your own commands. You can also put it -only in certain commands (might not be too useful to show it if you are -doing game administration for example). - -:: - - class MyCommand(Command): - - [...] - - def at_post_cmd(self): - - # we assume health/stamina/magic are just stored - # as simple attributes on the character. - - hp = self.caller.db.hp - sp = self.caller.db.sp - mp = self.caller.db.mp - - self.caller.msg("HP: %i, SP: %i, MP: %i" % (hp, sp, mp)) - -Note that if you are using the default commands, they will *not* display -a command prompt after this change - they are inheriting from -``src.commands.default.muxcommand.MuxCommand``. If you want to modify -default commands you need to copy&paste the default command definitions -to ``game/gamesrc/commands`` and modify them so they inherit from your -new parent (and re-point Evennia to use your custom versions as -described `here `_). If you only want to add -the hook and don't need to change anything else you can just create -stubs in modules in ``game/gamesrc/commands`` on this form: - -:: - - from ev import default_cmds - from game.gamesrc.commands.basecommand import MyCommand - - class CmdLook(MyCommand, default_cmds.CmdLook): - pass - - class CmdGet(MyCommand, default_cmds.CmdGet): - pass - -This multiple inheritance should make use of your custom ``at_post_cmd`` -hook while otherwise using the default command's code. This type of -overload is useful not only for adding prompts but for many different -forms of overloading default functionality. - -Prompt on the same line ------------------------ - -Another, more advanced type of prompt is one that appears before the -return of every command, on the same line: - -:: - - > look - HP: 10, SP:20, MP:5 -- You see nothing special. - -Now, there is an ``at_pre_cmd()`` hook analogous to the hook from last -section except called just *before* parsing of the command. But putting -prompt code in that would just have the prompt appear on the *line -before* the function return: - -:: - - > look - HP:10, SP:20, MP: 5 - You see nothing special. - -... which might be cool too, but is not what we wanted. To have the -prompt appear on the same line as the return, we need to change how -messages are returned to the player. This means a slight modification to -our *Character typeclass* (see [Objects#Characters here] on how to -change the default Character class to your custom one). - -All in-game commands use the ``object.msg()`` method for communicating -with the player (this is usually called as ``self.caller.msg()`` inside -command classes). This method is defined in ``src/objects/models.py``, -on the ``ObjectDB`` base class. This is the signature of ``msg()`` -method: - -:: - - def msg(self, outgoing_message, from_obj=None, data=None): - ... - -The only argument we are interested in here is the ``outgoing_message``, -which contains the text that is about to be passed on to the player. We -want to make sure that ``msg()`` always tack our prompt in front of the -``outgoing_message`` before sending it on. This is done by simply -overloading the ``msg()`` method in our custom Character class. On your -custom Character typeclass add this: - -:: - - def msg(self, outgoing_message, from_obj=None, data=None): - - # prepend the prompt in front of the message - - hp = self.db.hp - sp = self.db.sp - mp = self.db.mp - prompt = "%i, %i, %i -- " % (hp, sp, mp) - outgoing_message = prompt + outgoing_message - - # pass this on to the original msg() method on the database object - - self.dbobj.msg(outgoing_message, from_obj=from_obj, data=data) - -Note that this solution will *always* give you the prompt, also if you -use admin commands, which could get annoying. You might want to have -some attribute defined on your character for turning on/off the prompt -(the msg() method could look for it to determine if it should add the -prompt or not). You can of course also name the above method -``msg_prompt()`` and make sure that only commands that *should* return a -prompt call that method. diff --git a/docs/sphinx/source/wiki/Commands.rst b/docs/sphinx/source/wiki/Commands.rst deleted file mode 100644 index 6d951534a0..0000000000 --- a/docs/sphinx/source/wiki/Commands.rst +++ /dev/null @@ -1,375 +0,0 @@ -Command system -============== - -The basic way for users to communicate with the game is through -*Commands*. These can be commands directly related to the game world -such as *look*, *get*, *drop* and so on, or administrative commands such -as *examine* or *@dig*. - -The `default commands `_ coming with Evennia -are 'MUX-like' in that they use @ for admin commands, support things -like switches, syntax with the '=' symbol etc, but there is nothing that -prevents you from implementing a completely different command scheme for -your game. You can find the default commands in -``src/commands/default``. You should not edit these directly - they will -be updated by the Evennia team as new features are added. Rather you -should look to them for inspiration and inherit your own designs from -them. - -There are two components to having a command running - the *Command* -class and the *Command Set*. - -A *Command* is a python class containing all the functioning code for -what a command does - for example, a *get* command would contain code -for picking up objects. - -A *Command Set* (often referred to as a CmdSet) is like a container for -one or more Commands. A given Command can go into any number of -different command sets. By putting the command set on a character object -you will make all the commands therein available to use by that -character. You can also store command sets on normal objects if you want -users to be able to use the object in various ways. Consider a "Tree" -object with a cmdset defining the commands *climb* and *chop down*. Or a -"Clock" with a cmdset containing the single command *check time*. - -This page goes into full detail about how to use Commands. There is also -a step-by-step `beginner's tutorial `_ that -will get you started quickly without the explanations. - -Defining a Command ------------------- - -All commands are implemented as normal Python classes inheriting from -the base class ``Command`` (``ev.Command``). You will find that this -base class is very "bare". The default commands of Evennia actually -inherit from a child of ``Command`` called ``MuxCommand`` - this is the -class that knows all the mux-like syntax like ``/switches``, splitting -by "=" etc. Below we'll avoid mux-specifics and use the base ``Command`` -class directly. - -:: - - # basic Command definition - from ev import Command - class MyCmd(Command): - """ - This is the help-text for the command - """ - key = "mycommand" - def parse(self): - # parsing the command line here - def func(self): - # executing the command here - -You define a new command by assigning a few class-global properties on -your inherited class and overloading one or two hook functions. The full -gritty mechanic behind how commands work are found towards the end of -this page; for now you only need to know that the command handler -creates an instance of this class and uses that instance whenever you -use this command - it also dynamically assigns the new command instance -a few useful properties that you can assume to always be available. - -Properties assigned to the command instance at run-time -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Let's say player *Bob* with a character *BigGuy* enters the command -*look at sword*. After the system having successfully identified this a -the "look" command and determined that *BigGuy* really has access to a -command named ``look``, it chugs the ``look`` command class out of -storage and either loads an existing Command instance from cache or -creates one. After some more checks it then assigns it the following -properties: - -- ``caller`` - a reference to the object executing the command - this - is normally the Character\_BigGuy\_, not his Player *Bob* ! If you - want to do something to the player (*Bob*) in your command, do so - through ``caller.player``. (Since cmdsets can be put directly on - Players, caller *can* be a Player object as well, such commands are - usually quite specific though). -- ``cmdstring`` - the matched key for the command. This would be *look* - in our example. -- ``args`` - this is the rest of the string, except the command name. - So if the string entered was *look at sword*, ``args`` would be "*at - sword*\ ". -- ``obj`` - the game `Object `_ on which this command is - defined. This need not be the caller, but since ``look`` is a common - (default) command, this is probably defined directly on *BigGuy* - so - ``obj`` will point to BigGuy. Otherwise ``obj`` could be a Player or - any interactive object with commands defined on it, like in the - example of the "check time" command defined on a "Clock" object or a - `red - button `_ - that you can "``push``\ ". -- ``cmdset`` - this is a reference to the merged CmdSet (see below) - from which this command was matched. This variable is rarely used, - it's main use is for the `auto-help system `_ - (*Advanced note: the merged cmdset need NOT be the same as - BigGuy.cmdset. The merged set can be a combination of the cmdsets - from other objects in the room, for example*). -- ``sessid`` - this is an integer identifier for the Session triggering - this command, if any. This is seldomly needed directly. -- ``raw_string`` - this is the raw input coming from the user, without - stripping any surrounding whitespace. The only thing that is stripped - is the ending newline marker. - -Defining your own command classes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Beyond the properties Evennia always assigns to the command at runtime -(listed above), your job is to define the following class properties: - -- ``key`` (string) - the identifier for the command, like ``look``. - This should (ideally) be unique. A key can consist of more than one - word, like "press button" or "pull left lever". -- ``aliases`` (optional list) - a list of alternate names for the - command (``["l", "glance", "see"]``). Same name rules as for ``key`` - applies. -- ``locks`` (string) - a `lock definition `_, usually on - the form ``cmd:``. Locks is a rather big topic, so until - you learn more about locks, stick to giving the lockstring - ``"cmd:all()"`` to make the command available to everyone (if you - don't put a lock string, this will be assigned for you). -- ``help_category`` (optional string) - setting this helps to structure - the auto-help into categories. If none is set, this will be set to - *General*. -- ``save_for_next`` (optional boolean). This defaults to ``False``. If - ``True``, a copy of this command object (along with any changes you - have done to it) will be stored by the system and can be accessed by - the next command by retrieving ``self.caller.ndb.last_cmd``. The next - run command will either clear or replace the storage. -- 'arg\_regex' (optional raw string): This should be given as a `raw - regular expression string `_. - The regex will be compiled by the system at runtime. This allows you - to customize how the part *immediately following* the command name - (or alias) must look in order for the parser to match for this - command. Normally the parser is highly efficient in picking out the - command name, also as the beginning of a longer word (as long as the - longer word is not a command name in it self). So ``"lookme"`` will - be parsed as the command ``"look"`` followed by the argument - ``"me"``. By using ``arg_regex`` you could for example force the - parser to require a space to follow the command name (regex string - for this would be ``r"\s.*?|$"``). In that case, only ``"look me"`` - will work whereas ``"lookme"`` will lead to an "command not found" - error. -- ``func_parts`` (optional list of methods). Not defined by default, - used if it exists. This list of methods will be called in sequence, - each given a chance to yield execution. This allows for multi-part - long-running commands. See `Commands with a - Duration `_ for a practial presentation of how - to use this. -- ``auto_help`` (optional boolean). Defaults to ``True``. This allows - for turning off the - [`HelpSystem `_\ #Command\_Auto-help\_system - auto-help system] on a per-command basis. This could be useful if you - either want to write your help entries manually or hide the existence - of a command from ``help``'s generated list. - -You should also implement at least two methods, ``parse()`` and -``func()`` (You could also implement ``perm()``, but that's not needed -unless you want to fundamentally change how access checks work). - -``parse()`` is intended to parse the arguments (``self.args``) of the -function. You can do this in any way you like, then store the result(s) -in variable(s) on the command object itself (i.e. on ``self``). To take -an example, the default mux-like system uses this method to detect -"command switches" and store them as a list in ``self.switches``. Since -the parsing is usually quite similar inside a command scheme you should -make ``parse()`` as generic as possible and then inherit from it rather -than re-implementing it over and over. In this way, the default -``MuxCommand`` class implements a ``parse()`` for all child commands to -use. - -``func()`` is called right after ``parse()`` and should make use of the -pre-parsed input to actually do whatever the command is supposed to do. -This is the main body of the command. - -Finally, you should always make an informative `doc -string `_ -(``__doc__``) at the top of your class. This string is dynamically read -by the `Help system `_ to create the help entry for -this command. You should decide on a way to format your help and stick -to that. - -Below is how you define a simple alternative "``smile``\ " command: - -:: - - from ev import Command - - class CmdSmile(Command): - """ - A smile command - - Usage: - smile [at] [] - grin [at] [] - - Smiles to someone in your vicinity or to the room - in general. - - (This initial string (the __doc__ string) - is also used to auto-generate the help - for this command) - """ - - key = "smile" - aliases = ["smile at", "grin", "grin at"] - locks = "cmd:all()" - help_category = "General" - - def parse(self): - "Very trivial parser" - self.target = self.args.strip() - - def func(self): - "This actually does things" - caller = self.caller - if not self.target or self.target == "here": - string = "%s smiles." % caller.name - caller.location.msg_contents(string, exclude=caller) - caller.msg("You smile.") - else: - target = caller.search(self.target) - if not target: - # caller.search handles error messages - return - string = "%s smiles to you." % caller.name - target.msg(string) - string = "You smile to %s." % target.name - caller.msg(string) - string = "%s smiles to %s." % (caller.name, target.name) - caller.location.msg_contents(string, exclude=[caller,target]) - -The power of having commands as classes and to separate ``parse()`` and -``func()`` lies in the ability to inherit functionality without having -to parse every command individually. For example, as mentioned the -default commands all inherit from ``MuxCommand``. ``MuxCommand`` -implements its own version of ``parse()`` that understands all the -specifics of MUX-like commands. Almost none of the default commands thus -need to implement ``parse()`` at all, but can assume the incoming string -is already split up and parsed in suitable ways by its parent. - -Command Sets ------------- - -All commands in Evennia are always grouped together into *Command Sets* -(CmdSets). A particular ``Command`` class definition can be part of any -number of different CmdSets. CmdSets can be stored either on game -`Sessions `_, `Objects `_ or on -`Players `_. - -When a user issues a command, it is matched against the contents of all -cmdsets available to the user at the moment, -[Commands#Adding\_and\_merging\_command\_sets merged together]. The -currently valid command sets are collected from the following sources, -in this order: - -- The active cmdset on the character object -- The cmdsets of objects carried by the character -- The cmdset of the current location -- The cmdset(s) of objects in the current location (this includes - exits) -- The channel commandset -- The cmdset defined on the Player object controlling the character - -The default ``CmdSet`` shipping with Evennia is automatically added to -all new characters and contains commands such as ``look``, ``drop``, -``@dig`` etc. You can find it defined in -``src/commands/default/cmdset_character.py``, but it is also referenced -by importing ``ev.default_cmds`` and accessing its property -``CharacterCmdset``. Players have a cmdset called ``PlayerCmdSet`` that -can also be found from the same place. There is finally an "unloggedin" -cmdset, "UnloggedinCmdSet", that is used before the Player has -authenticated to the game. The path to these three standard command sets -are defined in settings, as ``CMDSET_UNLOGGEDIN``, ``CMDSET_CHARACTER`` -and ``CMDSET_PLAYER``. You can create any number of command sets besides -those to fit your needs. - -A CmdSet is, as most things in Evennia, defined as a Python class -inheriting from the correct parent (``ev.CmdSet`` or -``src.commands.cmdset.CmdSet``). The CmdSet class only needs to define -one method, called ``at_cmdset_creation()``. All other class parameters -are optional, but are used for more advanced set manipulation and coding -(see the [Commands#Merge\_rules merge rules] section). - -:: - - from ev import CmdSet - from game.gamesrc.commands import mycommands - class MyCmdSet(CmdSet): - def at_cmdset_creation(self): - """ - The only thing this method should need - to do is to add commands to the set. - """ - self.add(mycommands.MyCommand1()) - self.add(mycommands.MyCommand2()) - self.add(mycommands.MyCommand3()) - -The CmdSet's ``add()`` method can also take another CmdSet as input. In -this case all the commands from that CmdSet will be appended to this one -as if you added them line by line: - -:: - - at_cmdset_creation(): - ... - self.add(AdditionalCmdSet) # adds all command from this set - ... - -If you added your command to an existing cmdset (like to the default -cmdset), that set is already loaded into memory. You need to make the -server aware of the code changes: - -:: - - @reload - -You should now be able to use the command. - -If you created a new, fresh cmdset, this must be added to an object in -order to make the commands within available. A simple way to temporarily -test a cmdset on yourself is use the ``@py`` command to execute a python -snippet: - -:: - - @py self.cmdset.add('game.gamesrc.commands.mycmdset.MyCmdSet') - -This will stay with you until you ``@reset`` or ``@shutdown`` the -server, or you run - -:: - - @py self.cmdset.delete('game.gamesrc.commands.mycmdset.MyCmdSet') - -For a quick tutorial on setting up things more permanently read the -`Step by step -tutorial `_ -for a different way of approaching it. Generally you can customize which -command sets are added to your objects by using ``self.cmdset.add()`` or -``self.cmdset.add_default()``. - -Properties on command sets -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are a few extra flags one can set on CmdSets in order to modify -how they work. All are optional and will be set to defaults otherwise. -Since many of these relate to *merging* cmdsets you might want to read -up on [Commands#Adding\_and\_merging\_command\_sets next section] for -some of these to make sense. - -- ``key`` (string) - an identifier for the cmdset. This is optional but - should be unique; it is used for display in lists but also to - identify special merging behaviours using the - ``key_mergetype' dictionary below. * ``\ mergetype\ `` (string) - one of "_Union_", "_Intersect_", "_Replace_" or "_Remove_". * ``\ priority\ `` (int) - Higher priority sets will take priority during merging. Evennia default sets have priorities between ``\ 0\ `` and ``\ 9\ ``, where ``\ 0\ `` are most commands and ``\ 8\ `` or ``\ 9\ `` are used for special things like channel-commands and exit-commands. * ``\ key\_mergetype\ `` (dict) - a dict of ``\ key:mergetype\ `` pairs. This allows this cmdset to merge differently with certain named cmdsets. If the cmdset to merge with has a ``\ key\ `` matching an entry in ``\ key\_mergetype\ ``, it will not be merged according to the setting in ``\ mergetype\ `` but according to the mode in this dict. * ``\ duplicates\ `` (bool, default False) - when merging same-priority cmdsets containing same-key commands, the cmdset being merged "onto" the old one will take precedence. The result will be unique commands. If this flag is set the merged set can have multiple commands with the same key. This will usually lead to multi-match errors for the player. This is is useful e.g. for on-object cmdsets (example: There is a ``\ red - button\ `` and a ``\ green - button\ `` in the room. Both have a ``\ press - button\ `` command, in cmdsets with the same priority. This flag makes sure that just writing ``\ press - button\ `` will force the Player to define just which object's command was intended). * ``\ no\_objs\ `` this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from objects around the player (nor from rooms) when building the merged set. Exit commands will still be included. * ``\ no\_exits\ `` - this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from exits. * ``\ is\_exit\ `` (bool) - this marks the cmdset as being used for an in-game exit. This allows the cmdhandler to easily disregard this cmdset when other cmdsets have their ``\ no\_exits\ `` flag set. It is set directly by the Exit object as part of initializing its cmdset. * ``\ no\_channels\ `` (bool) - this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from available in-game channels. * ``\ is\_channel\ `` (bool)- this marks the cmdset as being used for an in-game exit. It allows the cmdhandler to easily disregard this cmdset when other cmdsets have their ``\ no\_channels\ `` flag set. It is set directly by the Channel object as part of initializing its cmdset. == Default command sets == Evennia comes with four default cmdsets, used at different parts of the game. You can freely add more and/or expand on these as you see fit. * _DefaultUnloggedin_ (``\ src.commands.default.cmdset\_unloggedin.UnloggedinCmdSet\ ``) - this cmdset holds the commands used before you have authenticated to the server, such as the login screen, connect, create character and so on. * _DefaultSession_ (``\ src.commands.default.cmdset\_session.SessionCmdSet\ `` - this is stored on the [Session] once authenticated. This command set holds no commands by default. It is meant to hold session-specific OOC things, such as character-creation systems. * _DefaultPlayer_ (``\ src.commands.default.cmdset\_player.PlayerCmdSet\ ``) - this is stored on the [Player] and contains account-centric OOC commands, such as the commands for sending text to channels or admin commands for staff. * _DefaultCharacter_ (``\ src.commands.default.cmdset\_character.CharacterCmdSet\ ``) - this is finally stored on Character objects and holds all IC commands available to that Character. This is the biggest cmdset. For it to be available to the player, the Character must be puppeted. Except for the unloggedin cmdset, cmdsets stored on these various levels dre merged "downward" in the connection hierarchy. So when merging (with the same priority), Session cmdsets are merged first, followed by Player and finally Character (so Character command overrule Player commands which overrule Session commands as it were). See the next section for details about merge rules. ==Adding and merging command sets == _Note: This is an advanced topic. It's useful to know about, but you might want to skip it if this is your first time learning about commands._ !CmdSets have the special ability that they can be _merged_ together into new sets. This would happen if you, for example, did ``\ object.cmdset.add(MyCmdSet)\ `` on an object that already had a command set defined on it. The two sets will be evaluated and a temporary, _merged set_ will be created out of the commands in both sets. Only the commands in this merged set is from that point available to use. Which of the ingoing commands end up in the merged set is defined by the _merge rule_ and the relative _priorities_ of the two sets. Removing the latest added set will restore things back to the way it was before the addition. !CmdSets are non-destructively stored in a stack inside the cmdset handler on the object. This stack is parsed to create the "combined" cmdset active at the moment. The very first cmdset in this stack is called the _Default cmdset_ and is protected from accidental deletion. Running ``\ obj.cmdset.delete()\ `` will never delete the default set. Instead one should add new cmdsets on top of the default to "hide" it, as described below. Use the special ``\ obj.cmdset.delete\_default()\ `` only if you really know what you are doing. !CmdSet merging is an advanced feature useful for implementing powerful game effects. Imagine for example a player entering a dark room. You don't want the player to be able to find everything in the room at a glance - maybe you even want them to have a hard time to find stuff in their backpack! You can then define a different !CmdSet with commands that override the normal ones. While they are in the dark room, maybe the ``\ look\ `` and ``\ inv\ `` commands now just tell the player they cannot see anything! Another example would be to offer special combat commands only when the player is in combat. Or when being on a boat. Or when having taken the super power-up. All this can be done on the fly by merging command sets. === Merge rules === To understand how sets merge, we need to define a little lingo. Let's call the first command set *A* and the second *B*. We will merge *A* onto *B*, so in code terms the command would be ``\ object.cdmset.add(A)\ ``, where we assume *B* was already the active cmdset on ``\ object\ `` since earlier. We let the *A* set have higher priority than *B*. A priority is simply an integer number. Default is 0, Evennia's in-built high-prio commands (intended to overrule others) have values of 9 or 10. Both sets contain a number of commands named by numbers, like ``\ A1, - A2\ `` for set *A* and ``\ B1, B2, B3, - B4\ `` for *B*. So for that example both sets contain commands with the same keys 1 and 2, whereas commands 3 and 4 are unique to *B*. To describe a merge between these sets, we would write {{{A1,A2 + B1,B2,B3,B4 = ?}}} where ``?\ `` is a list of commands that depend on which merge type *A* has, and which relative priorities the two sets have. By convention, we read this statement as "New command set *A* is merged onto the old command set *B* to form *?*". Below are the available merge types and how they work. Names are partly borrowed from [http://en.wikipedia.org/wiki/Set_theory Set theory]. *Union* (default) - The two cmdsets are merged so that as many commands as possible from each cmdset ends up in the merged cmdset. Same-key commands are merged by priority. {{{ # Union A1,A2 + B1,B2,B3,B4 = A1,A2,B3,B4 }}} *Intersect* - Only commands found in _both_ cmdsets (i.e. which have the same keys) end up in the merged cmdset, with the higher-priority cmdset replacing the lower one's commands. {{{ # Intersect A1,A3,A5 + B1,B2,B4,B5 = A1,A5 }}} *Replace* - The commands of the higher-prio cmdset completely replaces the lower-priority cmdset's commands, regardless of if same-key commands exist or not. {{{ # Replace A1,A3 + B1,B2,B4,B5 = A1,A3 }}} *Remove* - The high-priority command sets removes same-key commands from the lower-priority cmdset. They are not replaced with anything, so this is a sort of filter that prunes the low-prio set using the high-prio one as a template. {{{ # Remove A1,A3 + B1,B2,B3,B4,B5 = B2,B4,B5 }}} Besides ``\ priority\ `` and ``\ mergetype\ ``, a command set also takes a few other variables to control how they merge: * _duplicates_ (bool) - determines what happens when two sets of equal priority merge. Default is that the new set in the merger (i.e. *A* above) automatically takes precedence. But if _duplicates_ is true, the result will be a merger with more than one of each name match. This will usually lead to the player receiving a multiple-match error higher up the road, but can be good for things like cmdsets on non-player objects in a room, to allow the system to warn that more than one 'ball' in the room has the same 'kick' command defined on it, so it may offer a chance to select which ball to kick ... Allowing duplicates only makes sense for _Union_ and _Intersect_, the setting is ignored for the other mergetypes. * _key_mergetypes_ (dict) - allows the cmdset to define a unique mergetype for particular cmdsets, identified by their cmdset-key. Format is ``\ {CmdSetkey:mergetype}``. Priorities still apply. Example: ``\ {'Myevilcmdset','Replace'}\ `` which would make sure for this set to always use 'Replace' on ``\ Myevilcmdset\ `` only, no matter what _mergetype_ is set to. More advanced cmdset example: {{{ class MyCmdSet(CmdSet): key = "MyCmdSet" priority = 4 mergetype = "Replace" key_mergetypes = {'MyOtherCmdSet':'Union'} def at_cmdset_creation(self): """ The only thing this method should need to do is to add commands to the set. """ self.add(mycommands.MyCommand1()) self.add(mycommands.MyCommand2()) self.add(mycommands.MyCommand3()) }}} == System commands == _Note: This is an advanced topic. Skip it if this is your first time learning about commands._ There are several command-situations that are exceptional in the eyes of the server. What happens if the player enters an empty string? What if the 'command' given is infact the name of a channel the user wants to send a message to? Or if there are multiple command possibilities? Such 'special cases' are handled by what's called _system commands_. A system command is defined in the same way as other commands, except that their name (key) must be set to one reserved by the engine (the names are defined at the top of ``\ src/commands/cmdhandler.py\ ``). You can find (unused) implementations of the system commands in ``\ src/commands/default/system\_commands.py\ ``. Since these are not (by default) included in any ``\ CmdSet\ `` they are not actually used, they are just there for show. When the special situation occurs, Evennia will look through all valid ``\ CmdSet\ ``s for your custom system command. Only after that will it resort to its own, hard-coded implementation. Here are the exceptional situations that triggers system commands. You can find the command keys they use as properties on ``\ ev.syscmdkeys\ `` * No input (``\ syscmdkeys.CMD\_NOINPUT\ ``) - the player just pressed return without any input. Default is to do nothing, but it can be useful to do something here for certain implementations such as line editors that interpret non-commands as text input (an empty line in the editing buffer). * Command not found (``\ syscmdkeys.CMD\_NOMATCH\ ``) - No matching command was found. Default is to display the "Huh?" error message. * Several matching commands where found (``\ syscmdkeys.CMD\_MULTIMATCH\ ``) - Default is to show a list of matches. * User is not allowed to execute the command (``\ syscmdkeys.CMD\_NOPERM\ ``) - Default is to display the "Huh?" error message. * Channel (``\ syscmdkeys.CMD\_CHANNEL\ ``) - This is a [Communications Channel] name of a channel you are subscribing to - Default is to relay the command's argument to that channel. Such commands are created by the Comm system on the fly depending on your subscriptions. * New session connection ('syscmdkeys.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 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 command must be added to a cmdset as well before it will work. {{{ from ev import syscmdkeys, Command class MyNoInputCommand(Command): "Usage: Just press return, I dare you" key = syscmdkeys.CMD_NOINPUT def func(self): self.caller.msg("Don't just press return like that, talk to me!") }}} == Dynamic Commands == _Note: This is an advanced topic._ Normally Commands are created as fixed classes and used without modification. There are however situations when the exact key, alias or other properties is not possible (or impractical) to pre-code ([Commands#Exits Exits] is an example of this). To create a dynamic command use the following call: {{{ cmd = MyCommand(key="newname", aliases=["test", "test2"], locks="cmd:all()", ...) }}} _All_ keyword arguments you give to the Command constructor will be stored as a property on the command object. This will overload eventual existing properties defined on the parent class. Normally you would define your class as normal and only overload things like ``\ key\ `` and ``\ aliases\ `` at run-time. But you could in principle also send method objects as keyword arguments in order to make your command completely customized at run-time. == Exits == _Note: This is an advanced topic._ Exits are examples of the use of a [Commands#Dynamic_Commands Dynamic Command]. The functionality of [Objects Exit] objects in Evennia is not hard-coded in the engine. Instead Exits are normal [Typeclasses typeclassed] objects that auto-creates a [Commands#CmdSets CmdSet] on themselves when they load. This cmdset has a single dynamically created Command with the same properties (key, aliases and locks) as the Exit object itself. When entering the name of the exit, this dynamic exit-command is triggered and (after access checks) moves the Character to the exit's destination. Whereas you could customize the Exit object and its command to achieve completely different behaviour, you will usually be fine just using the appropriate ``\ traverse\_\ **`` hooks on the Exit object. But if you are interested in really changing how things work under the hood, check out ``\ src.objects.objects\ `` for how the ``\ Exit\ `` typeclass is set up. == How commands actually work == _Note: This is an advanced topic mainly of interest to server developers._ Any time the user sends text to Evennia, the server tries to figure out if the text entered corresponds to a known command. This is how the command handler sequence looks for a logged-in user: # A user (the _caller_) enters a string of text and presses enter. * If input is an empty string, resend command as ``\ CMD\_NOINPUT\ ``. If no such command is found in cmdset, ignore. * If command.key matches ``\ settings.IDLE\_COMMAND\ ``, update timers but don't do anything more. # Evennia's _commandhandler_ gathers the !CmdSets available to _caller_ at the time: * The caller's own currently active !CmdSet. * The active !CmdSets of eventual objects in the same location (if any). This includes commands on [Objects#Exits Exits]. * Sets of dynamically created _System commands_ representing available [Communications Channels]. * !CmdSet defined on the _caller.player_ (OOC cmdset). # All !CmdSets _of the same priority_ are merged together in groups. Grouping avoids order-dependent issues of merging multiple same-prio sets onto lower ones. # All the grouped !CmdSets are _merged_ in reverse priority into one combined !CmdSet according to each set's merge rules. # Evennia's _command parser_ takes the merged cmdset and matches each of its commands (using its key and aliases) against the beginning of the string entered by _caller_. This produces a set of candidates. # The _cmd parser_ next rates the matches by how many characters they have and how many percent matches the respective known command. Only if candidates cannot be separated will it return multiple matches. * If multiple matches were returned, resend as ``\ CMD\_MULTIMATCH\ ``. If no such command is found in cmdset, return hard-coded list of matches. * If no match was found, resend as ``\ CMD\_NOMATCH\ ``. If no such command is found in cmdset, give hard-coded error message. # If a single command was found by the parser, the correct command class is plucked out of storage and instantiated. # It is checked that the caller actually has access to the command by validating the _lockstring_ of the command. If not, it is not considered as a suitable match it is resent as ``\ CMD\_NOPERM\ `` is created. If no such command is found in cmdset, use hard-coded error message. # If the new command is tagged as a channel-command, resend as ``\ CMD\_CHANNEL\ ``. If no such command is found in cmdset, use hard-coded implementation. # Assign several useful variables to the command instance. # Call ``\ at\_pre\_command()\ `` on the command instance. # Call ``\ parse()\ `` on the command instance. This is is fed the remainder of the string, after the name of the command. It's intended to pre-parse the string int a form useful for the ``\ func()\ `` method. # 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 a Twisted [http://twistedmatrix.com/documents/current/core/howto/defer.html deferred]. Evennia does not use this return value at all by default. If you do, you must thus do so asynchronously, using callbacks. {{{ # in command class func() def callback(ret, caller): caller.msg("Returned is %s" % ret) deferred = self.execute_command("longrunning") deferred.addCallback(callback, self.caller) }}} This is probably not relevant to any but the most advanced/exotic designs (one might use it to create a "nested" command structure for example). The ``\ save\_for\_next\ ```` - class variable can be used to implement state-persistent commands. - For example it can make a command operate on "it", where it is - determined by what the previous command operated on.** - diff --git a/docs/sphinx/source/wiki/Communications.rst b/docs/sphinx/source/wiki/Communications.rst deleted file mode 100644 index 3c473e2db2..0000000000 --- a/docs/sphinx/source/wiki/Communications.rst +++ /dev/null @@ -1,150 +0,0 @@ -Communications -============== - -Apart from moving around in the game world and talking, players might -need other forms of communication. This is offered by Evennia's ``Comm`` -system. Stock evennia implements a 'MUX-like' system of channels, but -there is nothing stopping you from changing things to better suit your -taste. - -Comms rely on two main database objects - ``Msg`` and ``Channel``. There -is also the ``TempMsg`` which mimics the API of a ``Msg`` but has no -connection to the database. - -Msg ---- - -The ``Msg`` object is the basic unit of communication in Evennia. A -message works a little like an e-mail; it always has a sender (a -`Player `_) and one or more recipients. The recipients may -be either other Players, or a *Channel* (see below). You can mix -recipients to send the message to both Channels and Players if you like. - -Once created, a ``Msg`` is normally not changed. It is peristently saved -in the database. This allows for comprehensive logging of -communications, both in channels, but also for allowing -senders/receivers to have 'mailboxes' with the messages they want to -keep. - -Properties defined on \`Msg\` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``senders`` - this is a reference to one or many - `Player `_ or `Objects `_ (normally - *Characters*) sending the message. This could also be an *External - Connection* such as a message coming in over IRC/IMC2 (see below). - There is usually only one sender, but the types can also be mixed in - any combination. -- ``receivers`` - a list of target `Players `_, - `Objects `_ (usually *Characters*) or *Channels* to - send the message to. The types of receivers can be mixed in any - combination. -- ``header`` - this has a max-length of 128 characters. This could be - used to store mime-type information for this type of message (such as - if it's a mail or a page), but depending on your game it could also - instead be used for the subject line or other types of header info - you want to track. Being an indexed field it can be used for quick - look-ups in the database. -- ``message`` - the actual text being sent. -- ``date_sent`` - when message was sent (auto-created). -- ``locks`` - a `lock definition `_. -- ``hide_from`` - this can optionally hold a list of objects, players - or channels to hide this ``Msg`` from. This relationship is stored in - the database primarily for optimization reasons, allowing for quickly - post-filter out messages not intended for a given target. There is no - in-game methods for setting this, it's intended to be done in code. - -You create new messages in code using ``ev.create_message`` (or -``src.utils.create.create_message.``) - -!TempMsg --------- - -``src.comms.models`` contains a class called ``TempMsg`` which mimics -the API of ``Msg`` but is not connected to the database. It's not used -by default but you could use it in code to send non-persistent messages -to systems expecting a ``Msg`` (like *Channels*, see the example in the -next section). - -Channels --------- - -Channels are `Typeclassed `_ entities, which mean they -can be easily extended and their functionality modified. To change which -channel typeclass Evennia uses, change -settings.BASE\_CHANNEL\_TYPECLASS. - -Channels act as generic distributors of messages. Think of them as -"switch boards" redistributing ``Msg`` objects. Internally they hold a -list of "listening" objects and any ``Msg`` (or ``TempMsg`` sent to the -channel will be distributed out to all channel listeners. Channels have -`Locks `_ to limit who may listen and/or send messages -through them. - -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). The default channels created are defined by -``settings.CHANNEL_PUBLIC``, ``settings.CHANNEL_MUDINFO`` and -``settings.CHANNEL_CONNECTINFO``. - -You create new channels with ``ev.create_channel`` (or -``src.utils.create.create_channel``). - -In code, messages are sent to a channel using the ``msg`` or ``tempmsg`` -methods of channels: - -:: - - channel.msg(msgobj, header=None, senders=None, persistent=True) - -The argument ``msgobj`` can be either a string, a previously constructed -``Msg`` or a ``TempMsg`` - in the latter cases all the following -keywords are ignored. If ``msgobj`` is a string, the other keywords are -used for creating a new ``Msg`` or ``TempMsg`` on the fly, depending on -if ``persistent`` is set or not. Default is to use ``TempMsg`` for -channel communication (i.e. not save everything to the database). - -:: - - # assume we have a 'sender' object and a channel named 'mychan' - - # send and store Msg in database - from src.utils import create - mymsg = create.create_message(sender, "Hello!", channels=[mychan]) - # use the Msg object directly, no other keywords are needed - mychan.msg(mymsg) - - # Send a non-persistent message to a channel - mychan.msg("Hello!", senders=[sender]) - - # send a message to list, save it to the database - # (note how the senders keyword can also be used - # without a list if there is only one sender) - mychan.msg("Hello!", senders=sender, persistent=True) - -On a more advanced note, when a player enters something like -``ooc Hello!`` (where ``ooc`` is the name/alias of a channel), this is -treated as a `System Command `_ by Evennia. You may -completely customize how this works by defining a system command with -your own code. See `Commands `_ for more details. - -Properties defined on \`Channel\` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` - main name for channel -- ``aliases`` - alternative native names for channels -- ``desc`` - optional description of channel (seen in listings) -- ``keep_log`` (bool) - if the channel should store messages (default) -- ``locks`` - A `lock definition `_. Channels normally use - the access\_types ``send, admin`` and ``listen``. - -External Connections -==================== - -Channels may also communicate through what is called an *External -Connection*. Whereas normal users send messages through in-game Evennia -commands, an external connection instead takes data from a remote -location. `IMC2 `_ and `IRC `_ connections make use -of this. diff --git a/docs/sphinx/source/wiki/ConnectionScreen.rst b/docs/sphinx/source/wiki/ConnectionScreen.rst deleted file mode 100644 index 8b7a6e0fee..0000000000 --- a/docs/sphinx/source/wiki/ConnectionScreen.rst +++ /dev/null @@ -1,50 +0,0 @@ -The Connection Screen -===================== - -When you first connect to your game you are greeted by Evennia's default -connection screen. It welcomes you, gives you the server version and -tells you how to connect. - -:: - - - ============================================================== - Welcome to Evennia, version Beta-ra4d24e8a3cab+! - - If you have an existing account, connect to it by typing: - connect - If you need to create an account, type (without the <>'s): - create - - If you have spaces in your username, enclose it in quotes. - Enter help for more info. look will re-show this screen. - ============================================================== - -Effective, but not very exciting. You will most likely want to change -this to be more unique for your game. - -You can customize the connection screen easily. If you look in -``game/gamesrc/conf/examples/`` you will find a module named -``connection_screens.py``. Copy this module up one level (to -``game/gamesrc/conf/``) and set ``settings.CONNECTION_SCREEN_MODULE`` to -point to your new module. - -Evennia looks into this module for globally defined strings (only). -These strings are used as connection screens and shown to the user at -startup. If more than one screen is defined in the module, a random -screen will be picked from among those available. - -Evennia's default screen is imported as ``DEFAULT_SCREEN`` from -``src.commands.connection_screen``. Remove the import at the top or -redefine ``DEFAULT_SCREEN`` to get rid of the default. There is a -commented-out example screen in the module that you can start from. You -can define and import things as normal into the module, but remember -that *all* global strings will be picked up and potentially used as a -connection screen. - -You can also customize the `commands `_ available during -the connection screen (``connect``, ``create`` etc). These commands are -a bit special since when the screen is running the player is not yet -logged in. A command is made available at the login screen by adding -them to the command set specified by settings.CMDSET\_UNLOGGEDIN. The -default commands are found in ``src/commands/default/unloggedin.py``. diff --git a/docs/sphinx/source/wiki/Contributing.rst b/docs/sphinx/source/wiki/Contributing.rst deleted file mode 100644 index 33a3a25c81..0000000000 --- a/docs/sphinx/source/wiki/Contributing.rst +++ /dev/null @@ -1,109 +0,0 @@ -Contributing to Evennia -======================= - -Wanna help out? Great! Here's how. - -Contributing by spreading the word ----------------------------------- - -Even if you are not keen on working on the server code yourself, just -spreading the word is a big help - it will help attract more people -which leads to more feedback, motivation and interest. Rating and -writing a review on places like -`ohloh `_, talk about what you do in a -blog post or in mud forums, that kind of thing. - -Contributing with Documentation -------------------------------- - -Evennia depends heavily on good documentation and we are always looking -for extra eyes and hands to improve it. Even small things such as fixing -typos are a great help! - -The documentation is a wiki and to edit it you need wiki-contributor -access. We are happy to give this - just ask (on the forum/mailing list -or in the chat channel) if you want to help out. Otherwise, it goes a -long way just pointing out wiki errors so devs can fix them (in an Issue -or just over chat/forum). You can also commit wiki changes over -Mercurial - just go to the wiki repository -`here `_ and -then continue from point ``2`` below. - -Contributing with Code through a clone repository -------------------------------------------------- - -We always need more eyes and hands on the code. Even if you don't feel -confident with tackling any major bugs or features, just correcting -typos, adjusting formatting or simply using the thing helps us a lot in -improving things. - -The most elegant way to contribute code to Evennia is to use Mercurial -to create an online *clone* of the Evennia repository and make your -changes to that. Here's how to create your own clone (you only need to -do this once): - -#. Go to the - `Checkout `_ page. -#. If you are logged in, you should see a button named *Create a Clone*. - Click that. -#. You are asked to fill in a few fields. Name your clone repository - something useful, like "Johns-evennia-fixes". Give a brief summary, - like "my repo for contributing to Evennia". Accept. -#. Your new repo is created. You should see it appear in the `clone-repo - list `_. This is - actually your own mini-version of the Evennia page! -#. Choose your repo and you will find it has its own Checkout page. Use - the command shown there to get a local copy of your clone to your - computer. - -Once you have an online clone and a local copy of it: - -#. Make sure that you have edited Mercurial's config file (``hgrc``) and - under the header ``[ui]`` added the line - ``username=Yourname ``. This is important for proper - crediting and eventual conversions. See the first point of the - `Mercurial - Quickstart `_. -#. Code away on your computer, fixing bugs or whatnot (you can be - offline for this). Commit your code to your local clone as you work, - as often as you like. There are some suggestions for setting up a - sane local work environment with Mercurial - `here `_. -#. When you have something you feel is worthwhile (or just want to ask - people's opinions or make an online backup), *push* your local code - up to your online repository with Mercurial. -#. Let people know what you did - talk and discuss. If you think your - changes should be merged into main Evennia (maybe you have made - bugfixes, added new features etc), make a new - `Issue `_ using the - "Merge Request" template. Try to separate features with different - commits, so it's possible to pick individual features. - -From your online repo, Evennia devs can then, assuming the change is -deemed good, pick and merge your work into Evennia proper. Mercurial -will automatically make sure you get proper credit for your contribution -in the source code history. - -Contributing with Patches -------------------------- - -To help with Evennia development it's recommended to do so using a clone -repository as described above. But for small, well isolated fixes you -are also welcome to submit your suggested Evennia fixes/addendums as -*patches*. You can use `normal -patches `_, -but it might be easier to use mercurial's own patch mechanism. Make sure -you have committed your latest fixes first, then - -:: - - hg export tip > mypatch.patch - -This will create a patch file ``mypatch.patch`` that can be imported by -others with ``hg import mypatch.patch``. Depending on what fits best, -post your patch to the `issue -tracker `_ or to the -`discussion forum `_. -Please avoid pasting the full patch text directly in your post though, -best is to use a site like `Pastebin `_ and just -supply the link. diff --git a/docs/sphinx/source/wiki/DefaultCommandHelp.rst b/docs/sphinx/source/wiki/DefaultCommandHelp.rst deleted file mode 100644 index f45a128dc2..0000000000 --- a/docs/sphinx/source/wiki/DefaultCommandHelp.rst +++ /dev/null @@ -1,2499 +0,0 @@ -Commands in Evennia's default command set -========================================= - -*Note: This wiki page is auto-generated from the current status of the -code base and should not be edited manually.* - -The commands are ordered after their given help category, which should -usually match a module in ``src/commands/default``. So for example, the -code for a command in the "General" category is most likely to be found -in ``src/commands/default/general.py``. - -The commands that make up the default [Commands#Command\_Sets command -set] are divided into three sub-sets after which objects they are -defined on. - -- A *Player Command* is a command in the PlayerCmdset, available only - on Players, not on Objects/Characters. Since Players control - Characters, the Player and Character cmdsets are normally merged - together and the difference is not noticeable. Use e.g. the ``@ooc`` - command to disconnect from the current character and see only the - Player cmdset. Same-keyed command on the Character has higher - priority than its Player equivalent, allowing to overload the OOC - commands on a per-Character basis. -- An *Unloggedin Command* sits in UnloggedinCmdset. They are specific - to the login screen, before the session (User) has authenticated. -- All other commands are *On-Character* commands, commands defined in - CharacterCmdset and available in the game. - -The full set of available commands (all three sub-sets above) currently -contains 92 commands in 6 categories. More information about how -commands work can be found in the `Command `_ -documentation. - -Admin ------ - -`Link to Python -module `_ - -@ban -~~~~ - -- ``key`` = ``@ban`` -- ``aliases`` = ``@bans`` -- `locks `_ = ``cmd:perm(ban) or perm(Immortals)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - ban a player from the server - - Usage: - @ban [ [: reason]] - - Without any arguments, shows numbered list of active bans. - - This command bans a user from accessing the game. Supply an - optional reason to be able to later remember why the ban was put in - place - - It is often to - prefer over deleting a player with @delplayer. If banned by name, - that player account can no longer be logged into. - - IP (Internet Protocol) address banning allows to block all access - from a specific address or subnet. Use the asterisk (*) as a - wildcard. - - Examples: - @ban thomas - ban account 'thomas' - @ban/ip 134.233.2.111 - ban specific ip address - @ban/ip 134.233.2.* - ban all in a subnet - @ban/ip 134.233.*.* - even wider ban - - A single IP filter is easy to circumvent by changing the computer - (also, some ISPs assign only temporary IPs to their users in the - first placer. Widening the IP block filter with wildcards might be - tempting, but remember that blocking too much may accidentally - also block innocent users connecting from the same country and - region. - - - -@boot -~~~~~ - -- ``key`` = ``@boot`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(boot) or perm(Wizards)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @boot - - Usage - @boot[/switches] [: reason] - - Switches: - quiet - Silently boot without informing player - port - boot by port number instead of name or dbref - - Boot a player object from the server. If a reason is - supplied it will be echoed to the user unless /quiet is set. - - -@delplayer (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@delplayer`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(delplayer) or perm(Immortals)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - delplayer - delete player from server - - Usage: - @delplayer[/switch] [: reason] - - Switch: - delobj - also delete the player's currently - assigned in-game object. - - Completely deletes a user from the server database, - making their nick and e-mail again available. - - -@emit -~~~~~ - -- ``key`` = ``@emit`` -- ``aliases`` = ``@remit, @pemit`` -- `locks `_ = ``cmd:perm(emit) or perm(Builders)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @emit - - Usage: - @emit[/switches] [, , ... =] - @remit [, , ... =] - @pemit [, , ... =] - - Switches: - room : limit emits to rooms only (default) - players : limit emits to players only - contents : send to the contents of matched objects too - - Emits a message to the selected objects or to - your immediate surroundings. If the object is a room, - send to its contents. @remit and @pemit are just - limited forms of @emit, for sending to rooms and - to players respectively. - - -@perm -~~~~~ - -- ``key`` = ``@perm`` -- ``aliases`` = ``@setperm`` -- `locks `_ = ``cmd:perm(perm) or perm(Immortals)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @perm - set permissions - - Usage: - @perm[/switch] [= [,,...]] - @perm[/switch] * [= [,,...]] - - Switches: - del : delete the given permission from or . - player : set permission on a player (same as adding * to name) - - This command sets/clears individual permission strings on an object - or player. If no permission is given, list all permissions on . - - -@unban -~~~~~~ - -- ``key`` = ``@unban`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(unban) or perm(Immortals)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - remove a ban - - Usage: - @unban - - This will clear a player name/ip ban previously set with the @ban - command. Use this command without an argument to view a numbered - list of bans. Use the numbers in this list to select which one to - unban. - - - -@userpassword (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@userpassword`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(newpassword) or perm(Wizards)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @userpassword - - Usage: - @userpassword = - - Set a player's password. - - -@wall -~~~~~ - -- ``key`` = ``@wall`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(wall) or perm(Wizards)`` -- `help\_category `_ = ``Admin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @wall - - Usage: - @wall - - Announces a message to all connected players. - - -Building --------- - -`Link to Python -module `_ - -@alias -~~~~~~ - -- ``key`` = ``@alias`` -- ``aliases`` = ``@setobjalias`` -- `locks `_ = ``cmd:perm(setobjalias) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Adding permanent aliases - - Usage: - @alias [= [alias[,alias,alias,...]]] - - Assigns aliases to an object so it can be referenced by more - than one name. Assign empty to remove all aliases from object. - Observe that this is not the same thing as aliases - created with the 'alias' command! Aliases set with @alias are - changing the object in question, making those aliases usable - by everyone. - - -@batchcode -~~~~~~~~~~ - -- ``key`` = ``@batchcode`` -- ``aliases`` = ``@batchcodes`` -- `locks `_ = ``cmd:superuser()`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Build from batch-code file - - Usage: - @batchcode[/interactive] - - Switch: - interactive - this mode will offer more control when - executing the batch file, like stepping, - skipping, reloading etc. - debug - auto-delete all objects that has been marked as - deletable in the script file (see example files for - syntax). This is useful so as to to not leave multiple - object copies behind when testing out the script. - - Runs batches of commands from a batch-code text file (*.py). - - - -@batchcommands -~~~~~~~~~~~~~~ - -- ``key`` = ``@batchcommands`` -- ``aliases`` = ``@batchcmd, @batchcommand`` -- `locks `_ = ``cmd:perm(batchcommands) or superuser()`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Build from batch-command file - - Usage: - @batchcommands[/interactive] - - Switch: - interactive - this mode will offer more control when - executing the batch file, like stepping, - skipping, reloading etc. - - Runs batches of commands from a batch-cmd text file (*.ev). - - - -@cmdsets -~~~~~~~~ - -- ``key`` = ``@cmdsets`` -- ``aliases`` = ``@listcmsets`` -- `locks `_ = ``cmd:perm(listcmdsets) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - list command sets on an object - - Usage: - @cmdsets [obj] - - This displays all cmdsets assigned - to a user. Defaults to yourself. - - -@copy -~~~~~ - -- ``key`` = ``@copy`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(copy) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @copy - copy objects - - Usage: - @copy[/reset] [= new_name][;alias;alias..][:new_location] [,new_name2 ...] - - switch: - reset - make a 'clean' copy off the object, thus - removing any changes that might have been made to the original - since it was first created. - - Create one or more copies of an object. If you don't supply any targets, - one exact copt of the original object will be created with the name *_copy. - - -@cpattr -~~~~~~~ - -- ``key`` = ``@cpattr`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(cpattr) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cpattr - copy attributes - - Usage: - @cpattr[/switch] / = / [,/,/,...] - @cpattr[/switch] / = [,,,...] - @cpattr[/switch] = / [,/,/,...] - @cpattr[/switch] = [,,,...] - - Switches: - move - delete the attribute from the source object after copying. - - Example: - @cpattr coolness = Anna/chillout, Anna/nicety, Tom/nicety - -> - copies the coolness attribute (defined on yourself), to attributes - on Anna and Tom. - - Copy the attribute one object to one or more attributes on another object. - If you don't supply a source object, yourself is used. - - -@create -~~~~~~~ - -- ``key`` = ``@create`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(create) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @create - create new objects - - Usage: - @create[/drop] objname[;alias;alias...][:typeclass], objname... - - switch: - drop - automatically drop the new object into your current - location (this is not echoed). This also sets the new - object's home to the current location rather than to you. - - Creates one or more new objects. If typeclass is given, the object - is created as a child of this typeclass. The typeclass script is - assumed to be located under game/gamesrc/types and any further - directory structure is given in Python notation. So if you have a - correct typeclass object defined in - game/gamesrc/types/examples/red_button.py, you could create a new - object of this type like this: - - @create button;red : examples.red_button.RedButton - - - -@desc -~~~~~ - -- ``key`` = ``@desc`` -- ``aliases`` = ``@describe`` -- `locks `_ = ``cmd:perm(desc) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @desc - describe an object or room - - Usage: - @desc [ =] >description> - - Setts the "desc" attribute on an - object. If an object is not given, - describe the current room. - - -@destroy -~~~~~~~~ - -- ``key`` = ``@destroy`` -- ``aliases`` = ``@del, @delete`` -- `locks `_ = ``cmd:perm(destroy) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @destroy - remove objects from the game - - Usage: - @destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...] - - switches: - override - The @destroy command will usually avoid accidentally - destroying player objects. This switch overrides this safety. - examples: - @destroy house, roof, door, 44-78 - @destroy 5-10, flower, 45 - - Destroys one or many objects. If dbrefs are used, a range to delete can be - given, e.g. 4-10. Also the end points will be deleted. - - -@dig -~~~~ - -- ``key`` = ``@dig`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(dig) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @dig - build and connect new rooms to the current one - - Usage: - @dig[/switches] roomname[;alias;alias...][:typeclass] - [= exit_to_there[;alias][:typeclass]] - [, exit_to_here[;alias][:typeclass]] - - Switches: - tel or teleport - move yourself to the new room - - Examples: - @dig kitchen = north;n, south;s - @dig house:myrooms.MyHouseTypeclass - @dig sheer cliff;cliff;sheer = climb up, climb down - - This command is a convenient way to build rooms quickly; it creates the - new room and you can optionally set up exits back and forth between your - current room and the new one. You can add as many aliases as you - like to the name of the room and the exits in question; an example - would be 'north;no;n'. - - -@examine -~~~~~~~~ - -- ``key`` = ``@examine`` -- ``aliases`` = ``examine, @ex, ex, exam`` -- `locks `_ = ``cmd:perm(examine) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - examine - detailed info on objects - - Usage: - examine [[/attrname]] - examine [*[/attrname]] - - Switch: - player - examine a Player (same as adding *) - - The examine command shows detailed game info about an - object and optionally a specific attribute on it. - If object is not specified, the current location is examined. - - Append a * before the search string to examine a player. - - - -@examine (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@examine`` -- ``aliases`` = ``examine, @ex, ex, exam`` -- `locks `_ = ``cmd:perm(examine) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - examine - detailed info on objects - - Usage: - examine [[/attrname]] - examine [*[/attrname]] - - Switch: - player - examine a Player (same as adding *) - - The examine command shows detailed game info about an - object and optionally a specific attribute on it. - If object is not specified, the current location is examined. - - Append a * before the search string to examine a player. - - - -@find -~~~~~ - -- ``key`` = ``@find`` -- ``aliases`` = ``locate, @locate, search, @search, find`` -- `locks `_ = ``cmd:perm(find) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - find objects - - Usage: - @find[/switches] [= dbrefmin[-dbrefmax]] - - Switches: - room - only look for rooms (location=None) - exit - only look for exits (destination!=None) - char - only look for characters (BASE_CHARACTER_TYPECLASS) - - Searches the database for an object of a particular name or dbref. - Use *playername to search for a player. The switches allows for - limiting object matches to certain game entities. Dbrefmin and dbrefmax - limits matches to within the given dbrefs, or above/below if only - one is given. - - -@help -~~~~~ - -- ``key`` = ``@help`` -- ``aliases`` = ``@sethelp`` -- `locks `_ = ``cmd:perm(PlayerHelpers)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @help - edit the help database - - Usage: - @help[/switches] [,category[,locks]] = - - Switches: - add - add or replace a new topic with text. - append - add text to the end of topic with a newline between. - merge - As append, but don't add a newline between the old - text and the appended text. - delete - remove help topic. - force - (used with add) create help topic also if the topic - already exists. - - Examples: - @sethelp/add throw = This throws something at ... - @sethelp/append pickpocketing,Thievery = This steals ... - @sethelp/append pickpocketing, ,attr(is_thief) = This steals ... - - This command manipulates the help database. A help entry can be created, - appended/merged to and deleted. If you don't assign a category, the - "General" category will be used. If no lockstring is specified, default - is to let everyone read the help file. - - - -@home -~~~~~ - -- ``key`` = ``@home`` -- ``aliases`` = ``@sethome`` -- `locks `_ = ``cmd:perm(@home) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @home - control an object's home location - - Usage: - @home [= home_location] - - The "home" location is a "safety" location for objects; they - will be moved there if their current location ceases to exist. All - objects should always have a home location for this reason. - It is also a convenient target of the "home" command. - - If no location is given, just view the object's home location. - - -@link -~~~~~ - -- ``key`` = ``@link`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(link) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @link - connect objects - - Usage: - @link[/switches] = - @link[/switches] = - @link[/switches] - - Switch: - twoway - connect two exits. For this to work, BOTH - and must be exit objects. - - If is an exit, set its destination to . Two-way operation - instead sets the destination to the *locations* of the respective given - arguments. - The second form (a lone =) sets the destination to None (same as - the @unlink command) and the third form (without =) just shows the - currently set destination. - - -@lock -~~~~~ - -- ``key`` = ``@lock`` -- ``aliases`` = ``lock, @locks, locks`` -- `locks `_ = ``cmd: perm(@locks) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - lock - assign a lock definition to an object - - Usage: - @lock [ = ] - or - @lock[/switch] object/ - - Switch: - del - delete given access type - view - view lock associated with given access type (default) - - If no lockstring is given, shows all locks on - object. - - Lockstring is on the form - 'access_type:[NOT] func1(args)[ AND|OR][ NOT] func2(args) ...] - Where func1, func2 ... valid lockfuncs with or without arguments. - Separator expressions need not be capitalized. - - For example: - 'get: id(25) or perm(Wizards)' - The 'get' access_type is checked by the get command and will - an object locked with this string will only be possible to - pick up by Wizards or by object with id 25. - - You can add several access_types after oneanother by separating - them by ';', i.e: - 'get:id(25);delete:perm(Builders)' - - -@mvattr -~~~~~~~ - -- ``key`` = ``@mvattr`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(mvattr) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @mvattr - move attributes - - Usage: - @mvattr[/switch] / = / [,/,/,...] - @mvattr[/switch] / = [,,,...] - @mvattr[/switch] = / [,/,/,...] - @mvattr[/switch] = [,,,...] - - Switches: - copy - Don't delete the original after moving. - - Move an attribute from one object to one or more attributes on another - object. If you don't supply a source object, yourself is used. - - -@name -~~~~~ - -- ``key`` = ``@name`` -- ``aliases`` = ``@rename`` -- `locks `_ = ``cmd:perm(rename) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - cname - change the name and/or aliases of an object - - Usage: - @name obj = name;alias1;alias2 - - Rename an object to something new. - - - -@open -~~~~~ - -- ``key`` = ``@open`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(open) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @open - create new exit - - Usage: - @open [;alias;alias..][:typeclass] [,[;alias;..][:typeclass]]] = - - Handles the creation of exits. If a destination is given, the exit - will point there. The argument sets up an exit at the - destination leading back to the current room. Destination name - can be given both as a #dbref and a name, if that name is globally - unique. - - - -@script -~~~~~~~ - -- ``key`` = ``@script`` -- ``aliases`` = ``@addscript`` -- `locks `_ = ``cmd:perm(script) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - attach scripts - - Usage: - @script[/switch] [= ] - - Switches: - start - start all non-running scripts on object, or a given script only - stop - stop all scripts on objects, or a given script only - - If no script path/key is given, lists all scripts active on the given - object. - Script path can be given from the base location for scripts as given in - settings. If adding a new script, it will be started automatically - (no /start switch is needed). Using the /start or /stop switches on an - object without specifying a script key/path will start/stop ALL scripts on - the object. - - -@set -~~~~ - -- ``key`` = ``@set`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(set) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @set - set attributes - - Usage: - @set / = - @set / = - @set / - @set */attr = - - Sets attributes on objects. The second form clears - a previously set attribute while the last form - inspects the current value of the attribute - (if any). - - The most common data to save with this command are strings and - numbers. You can however also set Python primities such as lists, - dictionaries and tuples on objects (this might be important for - the functionality of certain custom objects). This is indicated - by you starting your value with one of {c'{n, {c"{n, {c({n, {c[{n - or {c{ {n. - Note that you should leave a space after starting a dictionary ('{ ') - so as to not confuse the dictionary start with a colour code like \{g. - Remember that if you use Python primitives like this, you must - write proper Python syntax too - notably you must include quotes - around your strings or you will get an error. - - - -@tag -~~~~ - -- ``key`` = ``@tag`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(tag) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - handles tagging - - Usage: - @tag[/del] [= [:]] - @tag/search - - Switches: - search - return all objects - del - remove the given tag. If no tag is specified, - clear all tags. - - Manipulates and lists tags on objects. Tags allow for quick - grouping of and searching for objects. If only is given, - list all tags on the object. If /search is used, list objects - with the given tag. - The category can be used for grouping tags themselves. - - -@tel -~~~~ - -- ``key`` = ``@tel`` -- ``aliases`` = ``@teleport`` -- `locks `_ = ``cmd:perm(teleport) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - teleport object to another location - - Usage: - @tel/switch [ =] - - Examples: - @tel Limbo - @tel/quiet box Limbo - @tel/tonone box - - Switches: - quiet - don't echo leave/arrive messages to the source/target - locations for the move. - intoexit - if target is an exit, teleport INTO - the exit object instead of to its destination - tonone - if set, teleport the object to a None-location. If this - switch is set, is ignored. - Note that the only way to retrieve - an object from a None location is by direct #dbref - reference. - - Teleports an object somewhere. If no object is given, you yourself - is teleported to the target location. - -@tunnel -~~~~~~~ - -- ``key`` = ``@tunnel`` -- ``aliases`` = ``@tun`` -- `locks `_ = ``cmd: perm(tunnel) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - dig in often-used directions - - Usage: - @tunnel[/switch] [= roomname[;alias;alias;...][:typeclass]] - - Switches: - oneway - do not create an exit back to the current location - tel - teleport to the newly created room - - Example: - @tunnel n - @tunnel n = house;mike's place;green building - - This is a simple way to build using pre-defined directions: - {wn,ne,e,se,s,sw,w,nw{n (north, northeast etc) - {wu,d{n (up and down) - {wi,o{n (in and out) - The full names (north, in, southwest, etc) will always be put as - main name for the exit, using the abbreviation as an alias (so an - exit will always be able to be used with both "north" as well as - "n" for example). Opposite directions will automatically be - created back from the new room unless the /oneway switch is given. - For more flexibility and power in creating rooms, use @dig. - - -@typeclass -~~~~~~~~~~ - -- ``key`` = ``@typeclass`` -- ``aliases`` = ``@type, @parent`` -- `locks `_ = ``cmd:perm(typeclass) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @typeclass - set object typeclass - - Usage: - @typclass[/switch] [= ] - @type '' - @parent '' - - Switch: - reset - clean out *all* the attributes on the object - - basically making this a new clean object. - force - change to the typeclass also if the object - already has a typeclass of the same name. - Example: - @type button = examples.red_button.RedButton - - View or set an object's typeclass. If setting, the creation hooks - of the new typeclass will be run on the object. If you have - clashing properties on the old class, use /reset. By default you - are protected from changing to a typeclass of the same name as the - one you already have, use /force to override this protection. - - The given typeclass must be identified by its location using - python dot-notation pointing to the correct module and class. If - no typeclass is given (or a wrong typeclass is given). Errors in - the path or new typeclass will lead to the old typeclass being - kept. The location of the typeclass module is searched from the - default typeclass directory, as defined in the server settings. - - - -@unlink -~~~~~~~ - -- ``key`` = ``@unlink`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(unlink) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @unlink - unconnect objects - - Usage: - @unlink - - Unlinks an object, for example an exit, disconnecting - it from whatever it was connected to. - - -@wipe -~~~~~ - -- ``key`` = ``@wipe`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(wipe) or perm(Builders)`` -- `help\_category `_ = ``Building`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @wipe - clears attributes - - Usage: - @wipe [/attribute[/attribute...]] - - Example: - @wipe box - @wipe box/colour - - Wipes all of an object's attributes, or optionally only those - matching the given attribute-wildcard search string. - - -Comms ------ - -`Link to Python -module `_ - -@cboot (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@cboot`` -- ``aliases`` = ```` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cboot - - Usage: - @cboot[/quiet] = [:reason] - - Switches: - quiet - don't notify the channel - - Kicks a player or object from a channel you control. - - - -@ccreate (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@ccreate`` -- ``aliases`` = ``channelcreate`` -- `locks `_ = ``cmd:not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @ccreate - channelcreate - Usage: - @ccreate [;alias;alias...] = description - - Creates a new channel owned by you. - - -@cdesc (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@cdesc`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cdesc - set channel description - - Usage: - @cdesc = - - Changes the description of the channel as shown in - channel lists. - - -@cdestroy (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@cdestroy`` -- ``aliases`` = ```` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cdestroy - - Usage: - @cdestroy - - Destroys a channel that you control. - - -@cemit (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@cemit`` -- ``aliases`` = ``@cmsg`` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cemit - send a message to channel - - Usage: - @cemit[/switches] = - - Switches: - noheader - don't show the [channel] header before the message - sendername - attach the sender's name before the message - quiet - don't echo the message back to sender - - Allows the user to broadcast a message over a channel as long as - they control it. It does not show the user's name unless they - provide the /sendername switch. - - - -@channels (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@channels`` -- ``aliases`` = - ``comlist, channellist, all channels, channels, @clist, chanlist`` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @clist - - Usage: - @channels - @clist - comlist - - Lists all channels available to you, whether you listen to them or not. - Use 'comlist' to only view your current channel subscriptions. - Use addcom/delcom to join and leave channels - - -@clock (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@clock`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @clock - changes channel access restrictions - - Usage: - @clock [= ] - - Changes the lock access restrictions of a channel. If no - lockstring was given, view the current lock definitions. - - -@cwho (Player command) -~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@cwho`` -- ``aliases`` = ```` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @cwho - - Usage: - @cwho - - List who is connected to a given channel you have access to. - - -@imc2chan (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@imc2chan`` -- ``aliases`` = ```` -- `locks `_ = - ``cmd:serversetting(IMC2_ENABLED) and pperm(Immortals)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - imc2chan - link an evennia channel to imc2 - - Usage: - @imc2chan[/switches] = - - Switches: - /disconnect - this clear the imc2 connection to the channel. - /remove - " - /list - show all imc2<->evennia mappings - - Example: - @imc2chan myimcchan = ievennia - - Connect an existing evennia channel to a channel on an IMC2 - network. The network contact information is defined in settings and - should already be accessed at this point. Use @imcchanlist to see - available IMC channels. - - - -@imcinfo (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@imcinfo`` -- ``aliases`` = ``@imcchanlist, @imcwhois, @imclist`` -- `locks `_ = - ``cmd: serversetting(IMC2_ENABLED) and pperm(Wizards)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - imcinfo - package of imc info commands - - Usage: - @imcinfo[/switches] - @imcchanlist - list imc2 channels - @imclist - list connected muds - @imcwhois - whois info about a remote player - - Switches for @imcinfo: - channels - as @imcchanlist (default) - games or muds - as @imclist - whois - as @imcwhois (requires an additional argument) - update - force an update of all lists - - Shows lists of games or channels on the IMC2 network. - - -@irc2chan (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@irc2chan`` -- ``aliases`` = ```` -- `locks `_ = - ``cmd:serversetting(IRC_ENABLED) and pperm(Immortals)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @irc2chan - link evennia channel to an IRC channel - - Usage: - @irc2chan[/switches] = <#irchannel> - - Switches: - /disconnect - this will delete the bot and remove the irc connection - to the channel. - /remove - " - /list - show all irc<->evennia mappings - - Example: - @irc2chan myircchan = irc.dalnet.net 6667 myevennia-channel evennia-bot - - This creates an IRC bot that connects to a given IRC network and channel. - It will relay everything said in the evennia channel to the IRC channel and - vice versa. The bot will automatically connect at server start, so this - comman need only be given once. The /disconnect switch will permanently - delete the bot. To only temporarily deactivate it, use the {w@services{n - command instead. - - -@rss2chan (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@rss2chan`` -- ``aliases`` = ```` -- `locks `_ = - ``cmd:serversetting(RSS_ENABLED) and pperm(Immortals)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @rss2chan - link evennia channel to an RSS feed - - Usage: - @rss2chan[/switches] = - - Switches: - /disconnect - this will stop the feed and remove the connection to the - channel. - /remove - " - /list - show all rss->evennia mappings - - Example: - @rss2chan rsschan = http://code.google.com/feeds/p/evennia/updates/basic - - This creates an RSS reader that connects to a given RSS feed url. Updates - will be echoed as a title and news link to the given channel. The rate of - updating is set with the RSS_UPDATE_INTERVAL variable in settings (default - is every 10 minutes). - - When disconnecting you need to supply both the channel and url again so as - to identify the connection uniquely. - - -addcom (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``addcom`` -- ``aliases`` = ``aliaschan, chanalias`` -- `locks `_ = ``cmd:not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - addcom - subscribe to a channel with optional alias - - Usage: - addcom [alias=] - - Joins a given channel. If alias is given, this will allow you to - refer to the channel by this alias rather than the full channel - name. Subsequent calls of this command can be used to add multiple - aliases to an already joined channel. - - -allcom (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``allcom`` -- ``aliases`` = ```` -- `locks `_ = ``cmd: not pperm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - allcom - operate on all channels - - Usage: - allcom [on | off | who | destroy] - - Allows the user to universally turn off or on all channels they are on, - as well as perform a 'who' for all channels they are on. Destroy deletes - all channels that you control. - - Without argument, works like comlist. - - -delcom (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``delcom`` -- ``aliases`` = ``delaliaschan, delchanalias`` -- `locks `_ = ``cmd:not perm(channel_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - delcom - unsubscribe from channel or remove channel alias - - Usage: - delcom - - If the full channel name is given, unsubscribe from the - channel. If an alias is given, remove the alias but don't - unsubscribe. - - -imctell (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``imctell`` -- ``aliases`` = ``imc2tell, imc2page, imcpage`` -- `locks `_ = ``cmd: serversetting(IMC2_ENABLED)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - imctell - send a page to a remote IMC player - - Usage: - imctell User@MUD = - imcpage " - - Sends a page to a user on a remote MUD, connected - over IMC2. - - -page (Player command) -~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``page`` -- ``aliases`` = ``tell`` -- `locks `_ = ``cmd:not pperm(page_banned)`` -- `help\_category `_ = ``Comms`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - page - send private message - - Usage: - page[/switches] [,,... = ] - tell '' - page - - Switch: - last - shows who you last messaged - list - show your last of tells/pages (default) - - Send a message to target user (if online). If no - argument is given, you will get a list of your latest messages. - - -General -------- - -`Link to Python -module `_ - -@charcreate (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@charcreate`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Create a character - - Usage: - @charcreate [= desc] - - Create a new character, optionally giving it a description. You - may use upper-case letters in the name - you will nevertheless - always be able to access your character using lower-case letters - if you want. - - -@color (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@color`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - testing colors - - Usage: - @color ansi|xterm256 - - Print a color map along with in-mud color codes, while testing what is - supported in your client. Choices are 16-color ansi (supported in most - muds) or the 256-color xterm256 standard. No checking is done to determine - your client supports color - if not you will see rubbish appear. - - -@encoding (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@encoding`` -- ``aliases`` = ``@encode`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - encoding - set a custom text encoding - - Usage: - @encoding/switches [] - - Switches: - clear - clear your custom encoding - - - This sets the text encoding for communicating with Evennia. This is mostly - an issue only if you want to use non-ASCII characters (i.e. letters/symbols - not found in English). If you see that your characters look strange (or you - get encoding errors), you should use this command to set the server - encoding to be the same used in your client program. - - Common encodings are utf-8 (default), latin-1, ISO-8859-1 etc. - - If you don't submit an encoding, the current encoding will be displayed - instead. - - -@ic (Player command) -~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@ic`` -- ``aliases`` = ``@puppet`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Switch control to an object - - Usage: - @ic - - Go in-character (IC) as a given Character. - - This will attempt to "become" a different object assuming you have - the right to do so. Note that it's the PLAYER character that puppets - characters/objects and which needs to have the correct permission! - - You cannot become an object that is already controlled by another - player. In principle can be any in-game object as long - as you the player have access right to puppet it. - - -@ooc (Player command) -~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@ooc`` -- ``aliases`` = ``@unpuppet`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - go ooc - - Usage: - @ooc - - Go out-of-character (OOC). - - This will leave your current character and put you in a incorporeal OOC state. - - -@password (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@password`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @password - set your password - - Usage: - @password = - - Changes your password. Make sure to pick a safe one. - - -@players -~~~~~~~~ - -- ``key`` = ``@players`` -- ``aliases`` = ``@listplayers`` -- `locks `_ = ``cmd:perm(listplayers) or perm(Wizards)`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @players - give a summary of all registed Players - - Usage: - @players [nr] - - Lists statistics about the Players registered with the game. - It will list the amount of latest registered players - If not given, defaults to 10. - - -@quell (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@quell`` -- ``aliases`` = ``@unquell`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Quelling permissions - - Usage: - quell - unquell - - Normally the permission level of the Player is used when puppeting a - Character/Object to determine access. This command will switch the lock - system to make use of the puppeted Object's permissions instead. This is - useful mainly for testing. - Hierarchical permission quelling only work downwards, thus a Player cannot - use a higher-permission Character to escalate their permission level. - Use the unquell command to revert back to normal operation. - - -@quit (Player command) -~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@quit`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - quit - - Usage: - @quit - - Switch: - all - disconnect all connected sessions - - Gracefully disconnect your current session from the - game. Use the /all switch to disconnect from all sessions. - - -access -~~~~~~ - -- ``key`` = ``access`` -- ``aliases`` = ``hierarchy, groups`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - access - show access groups - - Usage: - access - - This command shows you the permission hierarchy and - which permission groups you are a member of. - - -drop -~~~~ - -- ``key`` = ``drop`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - drop - - Usage: - drop - - Lets you drop an object from your inventory into the - location you are currently in. - - -get -~~~ - -- ``key`` = ``get`` -- ``aliases`` = ``grab`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - get - - Usage: - get - - Picks up an object from your location and puts it in - your inventory. - - -give -~~~~ - -- ``key`` = ``give`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - give away things - - Usage: - give = - - Gives an items from your inventory to another character, - placing it in their inventory. - - -help -~~~~ - -- ``key`` = ``help`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - The main help command - - Usage: - help - help list - help all - - This will search for help on commands and other - topics related to the game. - - -help (Player command) -~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``help`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - The main help command - - Usage: - help - help list - help all - - This will search for help on commands and other - topics related to the game. - - -home -~~~~ - -- ``key`` = ``home`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(home) or perm(Builders)`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - home - - Usage: - home - - Teleports you to your home location. - - -inventory -~~~~~~~~~ - -- ``key`` = ``inventory`` -- ``aliases`` = ``i, inv`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - inventory - - Usage: - inventory - inv - - Shows your inventory. - - -look -~~~~ - -- ``key`` = ``look`` -- ``aliases`` = ``l, ls`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - look - - Usage: - look - look - look * - - Observes your location or objects in your vicinity. - - -look (Player command) -~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``look`` -- ``aliases`` = ``l, ls`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - ooc look - - Usage: - look - - Look in the ooc state. - - -nick -~~~~ - -- ``key`` = ``nick`` -- ``aliases`` = ``@nick, nicks, nickname, alias`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Define a personal alias/nick - - Usage: - nick[/switches] = [] - alias '' - - Switches: - object - alias an object - player - alias a player - clearall - clear all your aliases - list - show all defined aliases (also "nicks" works) - - Examples: - nick hi = say Hello, I'm Sarah! - nick/object tom = the tall man - - A 'nick' is a personal shortcut you create for your own use. When - you enter the nick, the alternative string will be sent instead. - The switches control in which situations the substitution will - happen. The default is that it will happen when you enter a - command. The 'object' and 'player' nick-types kick in only when - you use commands that requires an object or player as a target - - you can then use the nick to refer to them. - - Note that no objects are actually renamed or changed by this - command - the nick is only available to you. If you want to - permanently add keywords to an object for everyone to use, you - need build privileges and to use the @alias command. - - -pose -~~~~ - -- ``key`` = ``pose`` -- ``aliases`` = ``:, emote`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - pose - strike a pose - - Usage: - pose - pose's - - Example: - pose is standing by the wall, smiling. - -> others will see: - Tom is standing by the wall, smiling. - - Describe an action being taken. The pose text will - automatically begin with your name. - - -say -~~~ - -- ``key`` = ``say`` -- ``aliases`` = ``", '`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - say - - Usage: - say - - Talk to those in your current location. - - -who (Player command) -~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``who`` -- ``aliases`` = ``doing`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``General`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - who - - Usage: - who - doing - - Shows who is currently online. Doing is an alias that limits info - also for those with all permissions. - - -System ------- - -`Link to Python -module `_ - -@about -~~~~~~ - -- ``key`` = ``@about`` -- ``aliases`` = ``@version`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @about - game engine info - - Usage: - @about - - Display info about the game engine. - - -@objects -~~~~~~~~ - -- ``key`` = ``@objects`` -- ``aliases`` = ``@listobjects, @stats, @db, @listobjs`` -- `locks `_ = ``cmd:perm(listobjects) or perm(Builders)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @objects - Give a summary of object types in database - - Usage: - @objects [] - - Gives statictics on objects in database as well as - a list of latest objects in database. If not - given, defaults to 10. - - -@py -~~~ - -- ``key`` = ``@py`` -- ``aliases`` = ``!`` -- `locks `_ = ``cmd:perm(py) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Execute a snippet of python code - - Usage: - @py - - Switch: - time - output an approximate execution time for - - Separate multiple commands by ';'. A few variables are made - available for convenience in order to offer access to the system - (you can import more at execution time). - - Available variables in @py environment: - self, me : caller - here : caller.location - ev : the evennia API - inherits_from(obj, parent) : check object inheritance - - You can explore The evennia API from inside the game by calling - ev.help(), ev.managers.help() etc. - - {rNote: In the wrong hands this command is a severe security risk. - It should only be accessible by trusted server admins/superusers.{n - - - -@py (Player command) -~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@py`` -- ``aliases`` = ``!`` -- `locks `_ = ``cmd:perm(py) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Execute a snippet of python code - - Usage: - @py - - Switch: - time - output an approximate execution time for - - Separate multiple commands by ';'. A few variables are made - available for convenience in order to offer access to the system - (you can import more at execution time). - - Available variables in @py environment: - self, me : caller - here : caller.location - ev : the evennia API - inherits_from(obj, parent) : check object inheritance - - You can explore The evennia API from inside the game by calling - ev.help(), ev.managers.help() etc. - - {rNote: In the wrong hands this command is a severe security risk. - It should only be accessible by trusted server admins/superusers.{n - - - -@reload (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@reload`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(reload) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Reload the system - - Usage: - @reload [reason] - - This restarts the server. The Portal is not - affected. Non-persistent scripts will survive a @reload (use - @reset to purge) and at_reload() hooks will be called. - - -@reset (Player command) -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@reset`` -- ``aliases`` = ``@reboot`` -- `locks `_ = ``cmd:perm(reload) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Reset and reboot the system - - Usage: - @reset - - A cold reboot. This works like a mixture of @reload and @shutdown, - - all shutdown hooks will be called and non-persistent scrips will - be purged. But the Portal will not be affected and the server will - automatically restart again. - - -@scripts -~~~~~~~~ - -- ``key`` = ``@scripts`` -- ``aliases`` = ``@listscripts, @globalscript`` -- `locks `_ = ``cmd:perm(listscripts) or perm(Wizards)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Operate and list global scripts, list all scrips. - - Usage: - @scripts[/switches] [] - - Switches: - start - start a script (must supply a script path) - stop - stops an existing script - kill - kills a script - without running its cleanup hooks - validate - run a validation on the script(s) - - If no switches are given, this command just views all active - scripts. The argument can be either an object, at which point it - will be searched for all scripts defined on it, or an script name - or dbref. For using the /stop switch, a unique script dbref is - required since whole classes of scripts often have the same name. - - Use @script for managing commands on objects. - - -@server -~~~~~~~ - -- ``key`` = ``@server`` -- ``aliases`` = ``@serverload, @serverprocess`` -- `locks `_ = ``cmd:perm(list) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - server load and memory statistics - - Usage: - @serverload - - This command shows server load statistics and dynamic memory - usage. - - Some Important statistics in the table: - - {wServer load{n is an average of processor usage. It's usually - between 0 (no usage) and 1 (100% usage), but may also be - temporarily higher if your computer has multiple CPU cores. - - The {wResident/Virtual memory{n displays the total memory used by - the server process. - - Evennia {wcaches{n all retrieved database entities when they are - loaded by use of the idmapper functionality. This allows Evennia - to maintain the same instances of an entity and allowing - non-persistent storage schemes. The total amount of cached objects - are displayed plus a breakdown of database object types. Finally, - {wAttributes{n are cached on-demand for speed. The total amount of - memory used for this type of cache is also displayed. - - - -@service -~~~~~~~~ - -- ``key`` = ``@service`` -- ``aliases`` = ``@services`` -- `locks `_ = ``cmd:perm(service) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @service - manage services - - Usage: - @service[/switch] - - Switches: - list - shows all available services (default) - start - activates or reactivate a service - stop - stops/inactivate a service (can often be restarted) - delete - tries to permanently remove a service - - Service management system. Allows for the listing, - starting, and stopping of services. If no switches - are given, services will be listed. Note that to operate on the - service you have to supply the full (green or red) name as given - in the list. - - -@shutdown (Player command) -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``@shutdown`` -- ``aliases`` = ```` -- `locks `_ = ``cmd:perm(shutdown) or perm(Immortals)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @shutdown - - Usage: - @shutdown [announcement] - - Gracefully shut down both Server and Portal. - - -@time -~~~~~ - -- ``key`` = ``@time`` -- ``aliases`` = ``@uptime`` -- `locks `_ = ``cmd:perm(time) or perm(Players)`` -- `help\_category `_ = ``System`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - @time - - Usage: - @time - - Server time statistics. - - -Unloggedin ----------- - -`Link to Python -module `_ - -\_\_unloggedin\_look\_command (Unloggedin command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``__unloggedin_look_command`` -- ``aliases`` = ``look, l`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``Unloggedin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - This is an unconnected version of the look command for simplicity. - - This is called by the server and kicks everything in gear. - All it does is display the connect screen. - - -connect (Unloggedin command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``connect`` -- ``aliases`` = ``co, conn, con`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``Unloggedin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Connect to the game. - - Usage (at login screen): - connect playername password - connect "player name" "pass word" - - Use the create command to first create an account before logging in. - - If you have spaces in your name, enclose it in quotes. - - -create (Unloggedin command) -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``create`` -- ``aliases`` = ``cr, cre`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``Unloggedin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - Create a new account. - - Usage (at login screen): - create - create "player name" "pass word" - - This creates a new player account. - - If you have spaces in your name, enclose it in quotes. - - -help (Unloggedin command) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``help`` -- ``aliases`` = ``h, ?`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``Unloggedin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - This is an unconnected version of the help command, - for simplicity. It shows a pane of info. - - -quit (Unloggedin command) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``key`` = ``quit`` -- ``aliases`` = ``q, qu`` -- `locks `_ = ``cmd:all()`` -- `help\_category `_ = ``Unloggedin`` -- [`HelpSystem `_\ #Auto-help\_system Auto-help] - (``__doc__ string``) = - -:: - - We maintain a different version of the quit command - here for unconnected players for the sake of simplicity. The logged in - version is a bit more complicated. - - diff --git a/docs/sphinx/source/wiki/DeveloperCentral.rst b/docs/sphinx/source/wiki/DeveloperCentral.rst deleted file mode 100644 index 10f31665bf..0000000000 --- a/docs/sphinx/source/wiki/DeveloperCentral.rst +++ /dev/null @@ -1,80 +0,0 @@ -Developer Central -================= - -This page serves as a central nexus for useful information regarding -coding using the Evennia codebase or developing the codebase itself. -Everyone is welcome to `help -out `_! If you have -any questions, please feel free to ask them in the `Forum/Discussion -Group `_. If you want more docs on a -particular issue, consider filling out our `online -form `_ -and tell us! Bugs should be reported to the `Issue -tracker `_. You can find -more links to Evennia resources from the `Links `_ page. - -General Evennia development information ---------------------------------------- - -- `Introduction to coding with Evennia `_ -- `Evennia Licensing FAQ `_ -- `Contributing to Evennia `_ -- `Code Style - Guide `_ - (Important!) -- `Policy for 'MUX-like' default commands `_ -- `Setting up a Mercurial environment for - coding `_ -- `Planning your own Evennia game `_ -- `First steps coding Evennia `_ - -Evennia Component Documentation -------------------------------- - -- `ev - the flat API `_ - -- `Directory Overview `_ -- `Portal and Server `_ -- `Session `_ -- `Commands `_ -- `Typeclass system `_ - - - `Objects `_ - - `Scripts `_ - - `Players `_ - - [Communications#Channels Channels] - - `Attributes `_ - -- `Locks and Permissions `_ -- `Communications `_ -- `Help System `_ -- `Nicks `_ -- `Tags `_ -- `Sessions and Protocols `_ -- `Caches `_ -- `Web features `_ -- `Out-of-band communication `_ -- `Configuration and module plugins `_ - -Programming Evennia -------------------- - -- `Running and Testing Python code from inside the - game `_ -- `Useful coding utilities `_ -- `Running and writing unit tests for Evennia `_ -- `Running processes asynchronously `_ -- `Expanding Evennia with new database models `_ - -Work in Progress - Developer brainstorms and whitepages -------------------------------------------------------- - -*In this section, contributors may suggest, discuss and plan out new -features and ideas. Items here may or may not make it into Evennia down -the road.* - -- `Basic game system implementation `_ - (inactive) -- `Rtclient protocol `_ (deprecated) -- `Change log `_ of big Evennia updates over time - diff --git a/docs/sphinx/source/wiki/DirectoryOverview.rst b/docs/sphinx/source/wiki/DirectoryOverview.rst deleted file mode 100644 index 473bcb765d..0000000000 --- a/docs/sphinx/source/wiki/DirectoryOverview.rst +++ /dev/null @@ -1,332 +0,0 @@ -Evennia directory overview -========================== - -:: - - evennia/ - ev.py - contrib/ - docs/ - game/ - locale/ - src/ - -Evennia's main directory (``evennia``) is divided into five sub -directories - ``src/``, ``game/``, ``contrib/`` , ``locale`` and -``doc/``. The first two are the most important ones. ``game/`` is the -place where you will create your own game, whereas ``src/`` is the home -of the Evennia server itself. Your code should usually just import -resources from ``src/`` and not change anything in there. - -All directories contain files ending in ``.py``. These are Python -*modules* and are the basic units of Python code. The roots of -directories also have empty files named ``__init__.py``. These are -required by Python so as to be able to find and import modules in other -directories. When you have run Evennia at least once you will find that -there will also be ``.pyc`` files appearing, these are pre-compiled -binary versions of the ``.py`` files to speed up execution. - -The file ``ev.py`` is important to remember. This is the home of -Evennia's flat API, essentially a set of shortcuts to various important -places in ``src/``. By importing ``ev`` from your code in ``game/`` you -have access to most important Evennia systems without *having* to know -where everything is located, as described in the following sections. - -The \`docs/\` directory ------------------------ - -This contains Evennia's offline documentation. The main source of -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. 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 -create a nice browsable web-index of all the sources and comments. In -the same way you could in theory also create nice ``LaTeX``-formatted -PDFs of the Evennia source (all 400+ pages of it ...). - -The \`locale/\` directory -------------------------- - -This contains internationalization strings for translating the Evennia -core server to different languages. See -`Internationalization `_ for more -information. - -The \`contrib/\` ("contributions") directory --------------------------------------------- - -This directory contains various stand-alone code snippets that are -potentially useful but which are deemed too game-specific to be a -regular part of the server. Modules in ``contrib/`` are not used unless -you explicitly import and use them. The contrib folder also contains the -`Tutorial World `_ game example. See -``contrib/README`` for more information. - -The \`game/\` directory ------------------------ - -``game/`` contains everything related to a particular game world. If you -ever wanted to start over with a new game implementation you could -replace the ``game`` directory and start from scratch. The root of this -directory contains the all-important ``manage.py`` and ``evennia.py`` -which you need in order to `get started `_ and run -the server. - -:: - - game/ - evennia.py - manage.py - - gamesrc/ - commands/ - examples/ - scripts/ - examples/ - objects/ - examples/ - world/ - examples/ - conf/ - -\`game/gamesrc/\` -~~~~~~~~~~~~~~~~~ - -``game/gamesrc`` is where you will be spending most of your time. All -the things going into your own dream game should be put here, by adding -Python modules. Throughout the ``gamesrc`` directories are ``examples`` -folders that all define different aspects of an example -`object `_ called *Red Button*. This is a button that -blinks and does interesting stuff when pressed. It's designed to combine -many different systems and to show off several advanced features of -Evennia. - -\`gamesrc/commands/\` -^^^^^^^^^^^^^^^^^^^^^ - -``gamesrc/commands/`` contains modules for defining -`Commands `_. In ``commands/examples`` you will find -templates for starting to define your own commands and cmdsets. Copy -these out into the parent ``command`` folder and work from there. - -\`gamesrc/scripts/\` -^^^^^^^^^^^^^^^^^^^^ - -``gamesrc/scripts/`` holds everything related to -`Scripts `_. ``scripts/examples`` holds templates you can -make copies of and build from to define your own scripts. - -\`gamesrc/objects/\` -^^^^^^^^^^^^^^^^^^^^ - -``gamesrc/objects/`` should contain the definitions for all your -`Objects `_. ``objects/examples`` contain templates for -*Object* as well as its three basic subclasses *Character*, *Room* and -*Exit*. Make copies of these templates to have somthing to start from -when defining your own in-game entities. - -\`gamesrc/world/\` -^^^^^^^^^^^^^^^^^^ - -``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. - -``world/examples/`` contains one batch file for each processor. Each -creates a *Red Button* object in *Limbo* using their respective special -syntax. - -\`gamesrc/conf/\` -^^^^^^^^^^^^^^^^^ - -``gamesrc/conf/`` holds optional extension modules for the Evennia -engine. It is empty by default, but in ``conf/examples/`` are templates -for the various config files that the server undertands. Each template -file contains instructions for how you should use them; copy out the -ones you want into the ``conf/`` directory and edit them there. - -The \`src/\` directory ----------------------- - -``src/`` contains the main running code of the Evennia server. You can -import files directly from here, but normally you will probably find it -easier to use the shortcuts in the top-level ``ev`` module. - -You should never modify anything in this folder directly since it might -be changed when we release updates. If you want to use some code as a -base for your own work (such as new commands), copy the relevant code -out into your own modules in ``game/gamesrc`` instead. If you find bugs -or features missing, file a bug report or send us a message. - -:: - - src/ - settings_defaults.py - - commands/ - comms/ - help/ - objects/ - locks/ - players/ - scripts/ - server/ - portal/ - typeclasses/ - utils/ - web/ - -Most of the folders in ``src/`` are technically "Django apps", -identified by containing a file ``models.py`` and usually -``managers.py``. A Django *model* is a template for how to save data to -the database. In order to offer full-persistence, Evennia uses models -extensively. The *manager* is used to conveniently access objects in the -database. Even if you don't know Django, you can easily use the methods -in the respective managers by accessing them through the *objects* -property of each corresponding model. Example: in -``src/objects/models.py`` there is a model named ``ObjectDB``. In the -same folder, there is also a manager found in -``src/objects/managers.py``. To access one of the manager's methods, -such as ``object_search()``, you would need to do -``ObjectDB.objects.object_search(...)``. - -All Django app folders also have a file ``admin.py``. This tells -Django's web features to automatically build a nice web-based admin -interface to the database. This means that you can add/edit/delete -objects through your browser. - -In the root of the ``src`` directory lies the ``settings_defaults.py`` -file. This is the main configuration file of Evennia. You should -copy&paste entries from this file to your ``game/settings.py`` file if -you want to customize any setting. - -\`src/commands/\` -~~~~~~~~~~~~~~~~~ - -This directory contains the `command system `_ of -Evennia. It defines basic command function, parsing and command-set -handling. - -``commands/default/`` holds a multitude of modules that together form -Evennia's default ('`MUX-like `_\ ') command -set. The files ``game/gamesrc/basecommand.py`` and -``game/gamesrc/basecmdset.py`` both link to their respective parents -here. If you want to edit a default command, copy&paste the respective -module to ``game/gamesrc/commands/`` and edit the default cmdset to -point to your copy. - -\`src/comms/\` -~~~~~~~~~~~~~~ - -``src/comms/`` defines all aspects of OOC -`communication `_, notably *channels*, *messages* -and the basic operators for connecting external listeners to channels. - -\`src/help/\` -~~~~~~~~~~~~~ - -This defines the `help system `_ of Evennia, the -command auto-help as well as the database-centric storage of in-game -help files. - -\`src/objects/\` -~~~~~~~~~~~~~~~~ - -``src/objects/`` defines how the in-game `objects `_ are -stored, found and handled in the database. - -\`src/locks/\` -~~~~~~~~~~~~~~ - -This directory defines the powerful `lock system `_ of -Evennia, a system that serves to restrict access to objects. The default -lock functions are found here. - -\`src/players/\` -~~~~~~~~~~~~~~~~ - -The `Player `_ is the OOC-represention of the person -connected to the game. This directory defines the database handling and -methods acting on the Player object. - -\`src/scripts/\` -~~~~~~~~~~~~~~~~ - -``src/scripts/`` defines all aspects of `Scripts `_ - how -they are activated, repeated and stored in-memory or in-database. The -main engine scripts (e.g. for keeping track of game-time, uptime and -connection timeouts) are also defined here. - -\`src/server/\` -~~~~~~~~~~~~~~~ - -This directory is the heart of Evennia. It holds the server process -itself (started from ``game/evennia.py``). Its subfolder ``portal/`` -holds the portal and all `sessions and -protocols `_ that allow users to connect to the -game. - -\`src/typeclasses/\` -~~~~~~~~~~~~~~~~~~~~ - -``src/typeclasses/`` defines the `Typeclass system `_ -that permeates Evennia, allowing coders to interact with normal Python -classes instead of caring about the underlying database implementation. -This directory is rarely accessed directly, rather both Objects, Scripts -and Players all inherit from its core classes. Also -`attributes `_ are defined here, being an vital part of -the typeclass system. - -\`src/utils/\` -~~~~~~~~~~~~~~ - -``src/utils/`` is a useful directory that contains helper functions for -the MUD coder. The ``utils/create.py`` module for example gathers -methods for creating all sorts of database models (objects, scripts, -help entries etc) without having to go into the respective database -managers directly. ``utils/search.py`` search a similar function for -searching the database. This directory also contains many helper modules -for parsing and converting data in various ways. - -\`src/web/\` -~~~~~~~~~~~~ - -This directory contains features related to running Evennia's `web site -and ajax web client `_. It will be customizable by the -user, but it's currently not established how to conveniently hook into -this from game/, so for the moment the suggested way is to make a copy -of this directory in ``game/gamesrc``, re-link the right settings in -your settings file and edit things from there. - -Assorted notes -============== - -Whereas ``game/gamesrc/`` contains a set of directories already, you -might find that another structure suits your development better. For -example, it could sometimes be easier to put all the commands and -scripts a certain object needs in the same module as that object, rather -than slavishly split them out into their respective directories and -import. Don't be shy to define your own directory structure as needed. A -basic rule of thumb should nevertheless be to avoid code-duplication. So -if a certain script or command could be useful for other objects, break -it out into its own module and import from it. Don't forget that if you -add a new directory, it must contain an ``__init__.py`` file (it can be -empty) in order for Python to recognize it as a place it can import -modules from. diff --git a/docs/sphinx/source/wiki/EvenniaDevel.rst b/docs/sphinx/source/wiki/EvenniaDevel.rst deleted file mode 100644 index a79398b9a5..0000000000 --- a/docs/sphinx/source/wiki/EvenniaDevel.rst +++ /dev/null @@ -1,149 +0,0 @@ -This page serves as a changelog of the various bigger updates of Evennia -over time. - -Devel-clone as of October 2013 -============================== - -*This update focused on moving the webserver into Server as well as -functioning OOB and reworked Attributes and Tags. Channels became -Typeclassed.* - -*This clone has **not** yet merged with main. This text is copied from -the mailing list post.* - -New features ------------- - -These are features that either don't affect existing APIs or introduce -new, non-colliding ones. - -- The webserver was moved from Portal into Server, for reasons outlined - in `earlier - posts `_. -- Out-Of-Band (OOB) functionality. This uses the MSDP protocol to - communicate with supported third-party clients (the webclient does - not currently support OOB). The new OOBhandler supports tracking of - variables and most of the default commands recommended by the MSDP - protocol. GMCP support is not part of this update. From the API side, - it means the msg() method have a new keyword 'oob', such as - msg(oob=("send",{"key":"val"}) -- Comm Channels are now Typeclassed entities. This means they can be - customized much more than before using hooks and inheritance. - src.comms.comms.py contains the new default channel typeclass and - hooks. Settings. DEFAULT\_COMM\_TYPECLASS define the default - typeclass. -- Most database field wrappers have been moved into the - SharedMemoryObject metaclass. This makes the handling of database - fields consistent and also makes the source code of models - considerably shorter with less boiler plate. All database fields are - updated individually now instead of having to save the entire - database object every time a field changes. The API is otherwise - unchanged - you still use obj.key="name" to save to the obj.db\_key - database field, for example. A new feature is that you can now give - dbrefs to fields holding objects in order to store that object in the - field. So self.location = "#44" should work. -- Attributes have three new fields: data, strvalue and category. All - are optional. The first can be used for arbitrary string data (it is - used by nick for the nick replacement). The second field, strvalue, - is used for storing a value known to always be a string (as opposed - to the normal value field which is pickled). This offers easier - optimization and makes Attributes useful for more things. Category - can be used to group Attributes (for example when they are used as - Nicks by the nickhandler). Normal operations are not affected. - Attributes are also now stored as a m2m fields on objects rather than - via a reverse lookup. -- obj.tags is a new handler on all typeclassed objects. A Tag is unique - and indexed and can be attached to any number of objects. It allows - to tag and group any entity/entities for quick lookup later. Like all - handlers you use get/add/remove/clear/all to manipulate tags. -- obj.nicks works similarly to before but it uses Attributes under the - hood (using strvalue and data fields for nick replacement and - category to determine which type of replacement to do). -- Sessions can also have their own cmdsets when the player has logged - in. - -There are a few other new settings in settings\_default, notably related -to OOB and caching. - -- New, reworked cache system. - -Deprecations ------------- - -These are features that have changed but where the old way still works - -for now. - -- Attributes are handled by the attributehandler (obj.attributes or - obj.db), which means that the old on-object methods are all - deprecated. Use of an deprecated method will result in a - DeprecationWarning in your log. Note that obj.db works the same as - before, it can (and should) replace all of these unless you are - looking to operate on an Attribute you don't know the name of before - execution. - - - obj.has\_attribute(attrname) -> obj.attributes.has(attrname) - - obj.get\_attribute(attrname) -> obj.attributes.get(attrname) - - obj.set\_attribute(attrname, value) -> - obj.attributes.add(attrname, value) - - obj.del\_attribute(attrname) -> obj.attributes.remove(attrname). - There is also obj.attributes.clear() to remove all Attributes from - obj. - - obj.get\_all\_attributes() -> obj.attributes.all() - - obj.secure\_attr(attrname) -> obj.attributes.get(attrname, - accessing\_obj=aobj, default\_access=True). The new - get/set/remove/clear/all methods have these optional keywords to - turn it into an access check. Setting default\_access=False will - fail the check if no accessing\_obj is given. - - obj.attr() - this was just a wrapper for the above commands, use - the new ones instead. - - obj.nattr() is replaced by the obj.nattributes handler instead. - obj.ndb works the same as before. - -The usage of Aliases as 'tags' alluded to in the tutorials (e.g. for -zones) should now be handled by Tags instead, they are intended for this -purpose. - -Incompatibilities ------------------ - -These are features/APIs that have changed to behave differently from -before. Using the old way will lead to errors. - -- Minimum Django version was upped from 1.4 to 1.5. -- User+PlayerDB -> PlayerDB. This means that - django.contrib.auth.models.User is no longer used and all references - to it should be changed to src.players.models.PlayerDB, which now - holds all authorization information for a player account. Note that - not all 3rd party Django apps have yet updated to allow a custom - User-model. So there may be issues there (one such app known to have - issues is DjangoBB). -- msg(text, data=None) has changed its API to - ``msg(text=None, ``\ args, - ****\ kwargs)\ ``. This makes no difference for most calls (basically anything just sending text). But if you used protocol options, such as msg(text,data={"raw":True}) you should now instead use msg(text, raw=True). * obj.permissions="perm" used to add "perm" to a hidden list of permissions behind the scenes. This no longer works since permissions is now a full handler and should be called like this: obj.permissions.set("perm"). The handler support the normal get/add/remove/all as other handlers. Permissions now use Tags under the hood. * obj.aliases="alias" used to add 'alias' to a hidden handler. This no longer works as obj.aliases is now a full handler: obj.aliases.set("alias"). This works like other handlers. Aliases now use Tags under the hood. * All portal-level modules have moved from being spread out all over src.server into a new sub-folder src.server.portal. Change your imports as required. * The default search/priority order for cmdsets have changed now that Sessions may also have cmdsets. Cmdsets are merged in the order session-player-puppet, which means that the puppet-level cmdset will default to overiding player-level cmdsets which in turn overrides session-level ones. * Messages (using the msg() method) used to relay data puppet->player->session. Now, puppet-level relays data directly to the session level, without passing the player-level. This makes it easier to customize msg at each respective level separately, but if you overloaded player.msg() with the intent to affect all puppeted objects, you need to change this. * If you used src.server.caches for anything (unlikely if you are not a core dev), the APIs of that has changed a lot. See that module. == Known Issues == * Whereas this merge will resolve a number of Issues from the list, most fixed ones will be feature requests up to this point. There are many known Issues which have not been touched. Some may be resolved as a side effect of other changes but many probably won't. This will come gradually. The wiki is of course also not updated yet, this will likely not happen until after this clone has been merged into main branch. For now, if you have usage questions, ask them here or on IRC. = Devel clone as of May 2013 = _This update centered around making a player able to control multiple characters at the same time (the multplayer_mode=2 feature)._ _ This clone was merged with main branch. This text is copied from the mailing list post._ == Things you have to update manually:== If you have partially overloaded and import the default cmdsets into game/gamesrc, you have to update to their new names and locations: * src.commands.default.cmdset_default.DefaultCmdSet changed name to src.commands.default.cmdset_character.CharacterCmdSet * src.commands.default.cmdset_ooc.OOCCmdSet changed name to src.commands.default.cmdset_player.PlayerCmdSet (in the same way ev.default_cmds now holds CharacterCmdSet and PlayerCmdSet instead of the old names) Note that if you already named your own cmdset class differently and have objects using those cmdsets in the database already, you should keep the old name for your derived class so as to not confuse existing objects. Just change the imports. The migrations will detect if any objects are using the old defaults and convert them to the new paths automatically. Also the settings file variable names have changed: * settings.CMDSET_DEFAULT has changed to settings.CMDSET_CHARACTER * settings.CMDSET_OOC has changed to settings.CMDSET_PLAYER The system will warn you at startup if your settings file contains the old names. If you have extensively modified Object Typeclasses, you need to update your hooks: * obj.at_first_login(), at_pre_login(), at_post_login() and at_disconnect() are removed. They no longer make sense since the Player is no longer auto-tied to a Character (except in MULTISESSION_MODE=0 and 1 where this is retained as a special case). All "first time" effects and "at login" effects should now only be done on the same-named hooks on the Player, not on the Character/Object. * New hooks on the Object are obj.at_pre_puppet(player), at_post_puppet(), at_pre_unpuppet() and at_post_unpuppet(player). These are now used for effects involving the Character going "into" the game world. So the default move from a None-location (previously in at_pre_login()) is now located in at_pre_puppet() instead and will trigger when the Player connects/disconnects to/from the Object/Character only. The Permission Hierarchy lock function (perm) has changed in an important way: * Previously, the perm() lock function checked permission only on the Character, even if a Player was connected. This potentially opens up for escalation exploits and is also rather confusing now that the Player and Character is more decoupled (which permission is currently used?) * perm() now checks primarily the Player for a hierarchy permission (Players, Builders, Admins etc, the stuff in settings.PERMISSION_HIERARCHY). Other types of permissions (non-hierarchical) are checked first against Player and then, if the Player does not have it, on the Character. * The @quell command was moved from a contrib into the main distribution. It allows Players to force hierarchical permission checks to only take the currently puppeted Character into account and not the Player. This is useful for staff testing features with lower permissions than normal. Note that one can only downgrade one's Player permission this way - this avoids Player's escalating their permissions through controlling a high-perm Character. Superusers can never be quelled, same as before. This is not a show-stopper, but nevertheless an important change: * settings.ALLOW_MULTISESSION was removed and is now replaced with MULTISESSION_MODE which can have a value of 0, 1 or 2. == Other Changes to be aware of== * Many-Characters-per-Player multisession mode. See the previous post here. * Player.character does still exist for backwards compatability but it is now only valid in MULTISESSION_MODE 0 or 1. Also this link will be meaninless when the Player goes OOC - the Player-Object link is now completely severed (before it remained). For MULTISESSION_MODE=2, you must use Player.get_character(sessid). See src.commands.default.player.py for details on how to get the Character now. * The @ic and @ooc and @ooclook commands use an Attribute ``\ \_playable\_characters\ `` to store a list of "your" characters. This is not hard-coded but only used by those commands. This is by default only used for listing convenience - locks are now the only thing blocking other users from puppeting your characters when you are not around. Keeping a list like this is now the only safe way to relate Characters with a given Player when that Player is offline. * Character typeclass has new hooks at_pre_puppet * ObjectDB.search() has a changed api: search(ostring, global_search=False, use_nicks=False, typeclass=None, location=None, attribute_name=None, quiet=False, exact=False. The changes here are the removal of the global_dbref keyword and that ignore_errors keyword was changed to quiet. More importantly the search function now always only return Objects (it could optionally return Players before). This means it no longer accepts the ``\ **playername\ `` syntax out of the box. To search for Players, use src.utils.search.player_search (you can always look for the asterisk manually in the commands where you want it). This makes the search method a lot more streamlined and hopefully consistent with expectations. * object.player is now only defined when the Player is actually online (before the connection would remain also when offline). Contrary to before it now always returns a Player typeclass whenever it's defined (Issue 325) * object.sessid is a new field that is always set together with character.player. * object.msg() has a new api: msg(self, message, from_obj=None, data=None, sessid=0). In reality this is used mostly the same as before unless wanting to send to an unexpected session id. Since the object stores the sessid of the connected Player's session, leaving the keywords empty will populate them with sensible defaults. * player.msg() also has changed: msg(self, outgoing_string, from_obj=None, data=None, sessid=None). The Player cannot easily determine the valid sessid on its own, so for Player commands, the sessid needs to be supplied or the msg will go to all sessions connected to the Player. In practice however, one uses the new Command.msg wrapper below: * command.msg is a new wrapper. It's call api looks like this: msg(self, msg="", to_obj=None, from_obj=None, data=None, sessid=Noneall_sessions=False). This will solve the problem of having to remember any sessids for Player commands, since the command object itself remembers the sessid of its caller now. In a Player command, just use self.msg(string). To clarify, this is just a convenience wrapper instead of calling self.caller.msg(string, sessid=self.sessid) - that works identically but is a little more to write. * The prettytable module is now included with Evennia. It was modified to handle Evennia's special ANSI color markers and is now the recommended way to output good-looking ASCII tables over using the old src.utils.format_table (which is still around) == Other changes == * New internal Attribute storage, using PickledFields rather than a custom solution; this now also allows transparent lookups of Attribute data directly on the database level (you could not do this (easily) before since the data is internally pickled). * Updated all unittests to cover the default commands again, also with a considerably speedup. * Plenty of cleanups and bug fixes all over * Removed several deprecation warnings from moving to Django 1.4+ and a few others. * Updated all examples in game/gamesrc and the various APIs = Status update as of December 2012 = _Mostly bug fixes and various cleanup this update. This is copied from the mailing list post._ Latest pushes to the repository fixes a few things in the Tutorial world. Notably the torch/splinter will light properly again now - which means you will be not be forever entombed under ground. Also I sometimes found that I couldn't solve the final puzzle. This is now fixed and you will now again be able to finish your quest by wreaking some well-deserved vengeance on that pesky Ghostly Apparition. I hadn't looked at the tutorial in a while which revealed a bunch of other small inconsistencies in how the Character was cleaned up afterwards, as well as some other small things, all now fixed. The tutorial world is meant to be a nice first look into what Evennia can do, so if you do come across further strangeness in it, don't be shy to report it. Also, it may be worth lingering on the west half of the swaying bridge longer than you should, just to see what happens. In other news, there is now a "give" command in the default cmdset; it's very simple (for example the receiver have no choice but to accept what is given to them) but it helped debug the Tutorial world and is a neat command to build from anyway. If you didn't notice, the latest changes places more strict regulation on how to reference database references from the default cmdset. Before you could do things like "ex 2" and expect to get Limbo. You will now have to do "ex #2", allowing objects to have numbered names as well (this was a feature request). The upshot is that the explicit dbref-search can be made global whereas key-searches can remain local. This is handled by a new keyword to object.search called "global_dbref". This means you can do things like "ex #23" and examine the object with dbref=23 wherever it is in the game. But you can also do "ex north" and not get a multi-match for every north exit in the game, but only the north in your current location. Thanks to Daniel Benoy for the feature request suggesting this. There might be more build commands were this is useful, they will be updated as I come across them or people report it. = Status update as of October 2011 = _This was an update related to the changes to persistence and other things on the docket. This text is copied from the mailing list post._ Here are some summaries of what's going on in the Evennia source at the moment: ==Admin interface == The admin interface backend is being revamped as per issue 174. Interface is slowly getting better with more default settings and some pointless things being hidden away or given more sensible labels. It's still rough and some things, like creating a new Player is hardly intuitive yet (although it does work, it requires you to create three separate models (User-Player-Character) explicitly at this point). I'm also seeing a bunch of formatting errors under django1.3, not sure if this is media-related or something fishy with my setups, not everyone seems to see this (see issue 197 if you want to help test). ==FULL_PERSISTENCE setting== ... is no more. FULL_PERSISTENCE=True is now always in effect. The feature to activate this setting was added at a time when the typeclass system's caching mechanism was, to say the least, wasteful. This meant that many problems with FULL_PERSISTENCE=False were hidden (it "just worked" and so was an easy feature to add). This is no longer the case. It's not worth the effort to support the False setting in parallel. Like before you can still assign non-persistent data by use of the ndb operator. ==Typeclass handling== Typeclasses are handled and managed and cached in a better way. Object.typeclass now actually returns the full instantiated typeclass object, not its class like before (you had to manually initiate it like dbobj.typeclass(dbobj)). The main reason for this change is that the system now allows very efficient calls to hook methods. The at_init() hook will now be called whenever any object is inititated - and it's very efficient; initiation will only happen whenever an entity is actually used in some ways and thus being cached (so an object in a seldomly-visited room might never be initiated, just as it should be). ==Support for out-of-band communication== Nothing is done in the server with this yet, but I plan to have a generalized way to implementing out-of-band protocols to communicate with custom clients, via e.g. GMCP or MCP or similar. There are some efforts towards defining at least one of those protocols behind the scenes, but time will tell what comes of it. = Devel branch as of September 2011 = _This update concerned the creation of the Server/Portal structure._ _This update has been merged into main. The text is copied from the mailing list post._ * Evennia was split into two processes: Server and Portal. The Server is the core game driver, as before. The Portal is a stand-alone program that handles incoming connections to the MUD. The two communicate through an AMP connection. * Due to the new Portal/Server split, the old reload mechanism is no more. Reloading is now done much more efficiently - by rebooting the Server part. Since Players are connected to the Portal side, they will not be disconnected. When Server comes back up, the two will sync their sessions automatically. @reload has been fixed to handle the new system. * The controller script evennia.py has been considerably revamped to control the Portal and Server processes. Tested also on WinXP. Windows process control works, but stopping from command line requires python2.7. Restarting from command line is not supported on Windows (use @restart from in-game). * Courtesy of user raydeejay, the server now supports internationalization (i18n) so messages can be translated to any language. So far we don't have any languages translated, but the possibility is there. * @reload will not kill "persistent" scripts and will call _at_server_reload()_ hooks. New @reset command will work like an old server shutdown except it automatically restarts. @shutdown will kill both Server and Portal (no auto-restart) * Lots of fixes and cleanup related to fixing these systems. Also the tutorial_world has seen some bugs fixed that became more obvious with the new reload system. * Wiki was updated to further explain the new features. = Update as of May 2011 = _This update marks the creation of the 'contrib' folder and some first contribs. The text is copied from the original mailing list post._ r1507 Adds the "evennia/contrib" folder, a repository of code snippets that are useful for the coder, but optional since they might not be suitable or needed for all types of games. Think of them as building blocks one could use or expand on or have as inspiration for one's own designs. For me, these primarily help me to test and debug Evennia's API features. So far, I've added the following optional modules in evennia/contrib: * Evennia ``\ MenuSystem\ `` - A base set of classes and cmdsets for creating in-game multiple-choice menus in Evennia. The menu tree can be of any depth. Menu options can be numbered or given custom keys, and each option can execute code. Also contains a yes/no question generator function. This is intended to be used by commands and presents a y/n question to the user for accepting an action. Includes a simple new command 'menu' for testing and debugging. * Evennia Lineeditor - A powerful line-by-line editor for editing text in-game. Mimics the command names of the famous VI text editor. Supports undo/redo, search/replace, regex-searches, buffer formatting, indenting etc. It comes with its own help system. (Makes minute use of the ``\ MenuSystem\ `` module to show a y/n question if quitting without having saved). Includes a basic command '@edit' for activating the editor. * Talking_NPC - An example of a simple NPC object with which you can strike a menu-driven conversation. Uses the ``\ MenuSystem\ `` to allow conversation options. The npc object defines a command 'talk' for starting the (brief) conversation. Creating these, I was happy to see that one can really create quite powerful system without any hacking of the server at all - this could all be implemented rather elegantly using normal commands, cmdsets and typeclasses. I fixed a bunch of bugs and outstanding refactorings. For example, as part of testing out the line-editor, I went back and refurbished the cmdparser - it is now much more straight forward (less bug prone) and supports a much bigger variation of command syntaxes. It's so flexible I even removed the possibility to change its module from settings - it's much easier to simply use command.parse() if you want to customize parsing later down the line. The parser is now also considerably more effective. This is due to an optimization resulting from our use of cmdsets - rather than going through X number of possible command words and store all combinations for later matching, we now do it the other way around - we merge all cmdsets first, then parse the input looking only for those command names/aliases that we know we have available. This makes for much easier and more effective code. It also means that you can identify commands also if they are missing following whitespace (as long as the match is unique). So the parser would now both understand "look me" as well as "lookme", for example. = Update as of April 2011 = _This update adds the ability to disconnect from one's puppet and go OOC._ r1484 implements some conceptual changes to the Evennia structure. If you use South, you need to run "manage.py migrate", otherwise you probably have to reset the databases from scratch. As previously desribed, Evennia impments a strict separation between Player objects (OOC, Out-of-character) objects and Characers (IC In-Character) objects. Players have no existence in the game world, they are abstract representations of connected player sessions. Characters (and all other Objects) have a game-world representation - they can be looked at, they have a location etc. They also used to be the only entities to be able to host cmdsets. This is all well and good as long as you only act as one character - the one that is automatically created for you when you first connect to Evennia. But what if you want to control _another_ character (puppet)? This is where the problems start. Imagine you are an Admin and decide on puppeting a random object. Nothing stops you from doing so, assuming you have the permissions to do so. It's also very easy to change which object you control in Evennia - just switch which object the Player's "character" property points to, and vice-versa for the Objects "player" property (there are safe helper methods for this too). So now you have become the new object. But this object has no commandset defined on it! Not only is now your Admin permissions gone, you can't even get back out, since this object doesn't have a @puppet (or equivalent) command defined for you to use! On the other hand, it's not a bad idea to be able to switch to an object with "limited" capabilities. If nothing else, this will allow Admins to play the game as a "non-privileged" character if they want - as well as log into objects that have unique commands only suitable for that object (become the huge robot and suddenly have access to the "fire cannon" command sounds sweet, doesn't it?) Having pondered how to resolve this in a flexible way, Player objects now also has a cmdsethandler and can store cmdsets, the same way as Objects can. Players have a default set of commands defined by settings.CMDSET_OOC. These are applied with a low priority, so same-named commands in the puppeted object will override the ooc command. The most important bit is that commands @ic (same as @puppet) as well as @ooc are now in the OOC command set and always available should you "become" an Object without a cmdset of its own. @ooc will leave your currently controlled character and put you in an "OOC" state where you can't do much more than chat on channels and read help files. @ic will put you back in control of your character again. Admins can @ic to any object on which they pass the "puppet" access lock restriction. You still need to go IC for most of your non-comm administrative tasks, that's the point. For your own game, the ooc state would be a great place for a Character selection/creation screen, for example. =Update as of March 2011 = _This update introduced the new lock/permission system, replacing an old one where lock and permission where used interchangeably (most confusing). Text was copied from the original mailing list post._ r1346 Adds several revisions to Evennia. Here are a few highlights: == A revised lock/permission system == The previous system combined permissions with locks into one single string called "permissions". While potentially powerful it muddled up what was an access restriction and what was a key. Having a unit "permission" that both dealt with access and limiting also made it very difficult to let anyone but superusers access to change it. The old system also defaulted to giving access, which made for hard-to-detect security holes. Having pondered this for a while the final straw was when I found that I myself didn't fully understand the system I myself wrote - that can't be a good sign. ^_^; So, the new system has several changes in philosophy: * All Evennia entities (commands, objects, scripts, channels etc) have multiple "locks" defined on them. A lock is an "access rule" that limits a certain type of access. There might be one access rule (lock) for "delete", another for "examine" or "edit" but any sort of lock is possible, such as "owner" or "get". No more mix-up between permissions and locks. Permissions should now be read as "keys" and are just one way of many to authenticate. * Locks are handled by the "locks" handler, such as locks.add(), locks.remove() etc. There is also a convenience function access() that takes the place of the old has_perm() (which is not a fitting name anymore since permissions doesn't work the way they did). * A lock is defined by a call to a set of lock functions. These are normal python functions that take the involved objects as arguments and establishes if access should be granted or not. * A system is locked by default. Access is only obtained if a suitable lock grants it. * All entities now receive a basic set of locks at creation time (otherwise noone besides superuser would have any access) In practice it works like this: You try to delete myobject by calling @delete myobject. @delete calls myobject.access(caller, 'delete'). The lockhandler looks up a lock with the access type "delete" and returns a True of False. == Permissions == Only Objects and Players have a "permissions" property anymore, and this is now only used for key strings. A permission has no special standing now - a lock can use any attribute or property to establish access. Permissions do have some nice extra security features out of the box though. * controlled from @perm, which can be a high-permission command now that locks are separate. * settings.PERMISSION_HIERARCHY is a tuple of permission strings such as ("Players", "Builders", "Wizards"). The perm() lock function will make sure that higher permissions automatically grants the permissions of those below. == General fixes == As part of testing and debugging the new lock system I fixed a few other issues: * @reload now asynchonously updates all the objects in the database. This means that you can do nifty things like updating cmdsets on the fly without a server reload! * Some 30 new unittest cases for commands and locks. Command unittests were refined a lot. This also meant finding plenty of minor bugs in those commands. * Some inconsistencies in the server/session system had been lingering behind. Fixed now. * Lots of small fixes. The wiki is almost fully updated (including the auto-updating command list!), but there might still be text around referring to the old way of doing things. Fix it if you see it. And as usual, report bugs to the issue tracker. =Devel branch as of September 2010= _This update added the twisted webserver and webclient. It also moved the default cmdset to src/._ _This has been merged into main. The text is copied from the original mailing list post._ Starting with r1245, the underlying server structure of Evennia has changed a bit. The details of protocol implementation should probably mostly be of interest for Evennia developers, but the additions of new web features should be of interest to all. Maybe the most immediate change you'll notice is that Evennia now defaults to opening two ports, one for telnet and another for a webserver. Yep, Evennia now runs and serves its web presence with its very own Twisted webserver. The webserver, which makes use of Twisted's wsgi features to seamlessly integrate with Django's template system, is found in src/server/webserver.py. The Twisted webserver should be good for most needs. You can of course still use Apache if you really want, but there is now at least no need to use Django's "test server" at all, it all runs by default. All new protocols should now inherit from src.server.session.Session, a generic class that incoorporate the hooks Evennia use to communicate with all player sessions, such as at_connect(), at_disconnect(), at_data_in(), at_data_out() etc. The all-important msg() function still handles communication from your game to the session, this now also takes an optional keyword 'data' to carry eventual extra parameters that certain protocols might have need for (data is intentionally very vaguely specified, but could for example be instructions from your code for updating a graphical client in some way). Two protocols are currently written using this new scheme - the standard telnet protocol (now found separately as server/telnet.py) and a web mud client protocol in server/webclient.py. The web mud client (which requires the web server to be running too) allows for a player to connect to your game through a web browser. You can test it from your newly started game's website. Technically it uses an ajax long polling scheme (sometimes known as 'comet'). The client part running in the browser is a javascript program I wrote using the jQuery javascript library (included in src/web/, although any client and library could be used). The django integration allows for an interesting hybrid, where the Django templating system can be used both for the game website and the client, while the twisted asynchronous reactor handles the real time updating of the client. Please note that the default javascript web client is currently very rough - both it and the underlying protocol still needs work. But it should serve as a hint as to what kind of stuff is possible. The wiki will be updated as the details stabilize. Unrelated to the new web stuff (but noticeable for game devs) is that the default command set was moved from game/gamesrc/commands/default to src/commands/default since some time. The reason for this change was to make it clearer that these commands are part of the default distribution (i.e. might be updated when you update Evennia) and should thus not be edited by admins - like all things in src/. All this did was to make what was always the best-practice more explicit: To extend the default set, make your own modules in game/gamesrc/commands, or copy them from the default command set. The basecmd.py and basecmdset.py have been updated to clearer explain how to extend things. = Devel branch as of August 2010= _This update was a major rewrite of the orginal Evennia, introducing Typeclasses and Scripts as well as Commands, CmdSets and many other features._ _Note: The devel branch merged with trunk as of r970 (aug2010). So if you are new to Evennia, this page is of no real interest to you._ == Introduction == The Evennia that has been growing in trunk for the last few years is a wonderful piece of software, with which you can do very nice coding work. It has however grown 'organically', adding features here and there by different coders at different times, and some features (such as my State system) were bolted onto an underlying structure for which it was never originally intended. Meanwhile Evennia is still in an alpha stage and not yet largely used. If one needs to do a cleanup/refactoring and homogenization of the code, now is the time time to do it. So I set out to do just that. The "devel-branch" of Evennia is a clean rework of Evennia based on trunk. I should point out that the main goal has been to make system names consistent, to add all features in a fully integrated way, and to give all subsystems a more common API for the admin to work against. This means that in the choice between a cleaner implementation and backwards-compatability with trunk, the latter has had to stand back. However, you'll hopefully find that converting old codes shouldn't be too hard. Another goal is to further push Evennia as a full-fledged barebones system for _any_ type of mud, not just MUX. So you'll find far more are now user-configurability now than ever before (MUX remains the default though). Devel is now almost ready for merging with the main trunk, but it needs some more eyes to look at it first. If you are brave and want to help report bugs, you can get it from the _griatch_ branch with {{{svn checkout http://evennia.googlecode.com/svn/branches/griatch evennia-devel}}} ==Concepts changed from trunk to devel== ===Script parent -> Typeclasses === The biggest change is probably that script parents have been replaced by _typeclasses_. Both handle the abstraction of in-game objects without having to create a separate database model for each (i.e. it allows objects to be anything from players to apples, rooms and swords all with the same django database model). A script parent in trunk was a class stored in a separate module together with a 'factory' function that the engine called. The admin had to always remember if they were calling a function on the database model or if it in fact sat on the script parent (the call was made through something called the "scriptlink"). By contrast, a typeclass is a normal python class that inherits from the _!TypeClass_ parent. There are no other required functions to define. This class uses __getattribute__ and __setattr__ transparently behind the scenes to store data onto the persistent django object. Also the django model is aware of the typeclass in the reverse direction. The admin don't really have to worry about this connection, they can usually consider the two objects (typeclass and django model) to be one. So if you have your 'apple' typeclass, accessing, say the 'location', which is stored as a persistent field on the django model, you can now just do ``\ loc - = - apple.location\ `` without caring where it is stored. The main drawback with any typeclass/parent system is that it adds an overhead to all calls, and this overhead might be slightly larger with typeclasses than with trunk's script parents although I've not done any testing. You also need to use Evennia's supplied ``\ create\ `` methods to create the objects rather than to create objects with plain Django by instantiating the model class; this so that the rather complex relationships can be instantiated safely behind the scenes. == Command functions + !StateCommands-> Command classes + !CmdSets == In trunk, there was one default group of commands in a list GLOBAL_CMD_TABLE. Every player in game used this. There was a second dictionary GLOBAL_STATE_TABLE that held commands valid only for certain _states_ the player might end up in - like entering a dark room, a text editor, or whatever. The problem with this state system, was that it was limited in its use - every player could ever only be in one state at a time for example, never two at the same time. The way the system was set up also explicitly made states something unique to players - an object could not offer different commands dependent on its state, for example. In devel, _every_ command definition is grouped in what's called a _!CmdSet_ (this is, like most things in Devel, defined as a class). A command can exist in any number of cmdsets at the same time. Also the 'default' group of commands belong to a cmdset. These command sets are no longer stored globally, but instead locally on each object capable of launching commands. You can add and new cmdsets to an object in a stack-like way. The cmdsets support set operations (Union, Difference etc) and will merge together into one cmdset with a unique set of commands. Removing a cmdset will re-calculate those available commands. This allows you to do things like the following (impossible in trunk): A player is walking down a corridor. The 'default' cmdset is in play. Now he meets an enemy. The 'combat' cmdset is merged onto (and maybe replacing part of) the default cmdset, giving him new combat-related commands only available during combat. The enemy hits him over the head, dazing him. The "Dazed" cmdset is now added on top of the previous ones - maybe he now can't use certain commands, or might even get a garbled message if trying to use 'look'. After a few moments the dazed state is over, and the 'Dazed' cmdset is removed, returning us to the combat mode we were in before. And so on. Command definitions used to be functions, but are now classes. Instead of relying on input arguments, all relevant variables are stored directly on the command object at run-time. Also parsing and function execution have been split into two methods that are very suitable for subclassing (an example is all the commands in the default set which inherits from the !MuxCommand class - that's the one knowing about MUX's special syntax with /switches, '=' and so on, Evennia's core don't deal with this at all!). Example of new command definition: {{{ class CmdTest(Command): def func(self): self.caller.msg("This is the test!") }}} == Events + States -> Scripts == The Event system of Evennia used to be a non-persistent affair; python objects that needed to be explicitly called from code when starting. States allowed for mapping different groups of commands to a certain situations (see !CmdSets above for how commands are now always grouped). _Scripts_ (warning: Not to be confused with the old _script parents_!) are persistent database objects now and are only deleted on a server restart if explicitly marked as non-persistent. A script can have a time-component, like Events used to have, but it can also work like an 'Action' or a 'State' since a script constantly checks if it is still 'valid' and if not will delete itself. A script handles everything that changes with time in Evennia. For example, all players have a script attached to them that assigns them the default cmdset when logging in. Oh, and Scripts have typeclasses too, just like Objects, and carries all the same flexibility of the Typeclass system. ==User + player -> User + Player + character == In trunk there is no clear separation between the User (which is the django model representing the player connecting to the mud) and the player object. They are both forced to the same dbref and are essentially the same for most purposes. This has its advantages, but the problem is configurability for different game types - the in-game player object becomes the place to store also OOC info, and allowing a player to have many characters is a hassle (although doable, I have coded such a system for trunk privately). Devel-branch instead separate a "player character" into three tiers: * The User (Django object) * The PlayerDB (User profile + Player typeclass) * The ObjectDB (+ Character typeclass) User is not something we can get out of without changing Django; this is a permission/password sensitive object through which all Django users connect. It is not configurable to any great extent except through it's _profile_, a django feature that allows you to have a separate model that configures the User. We call this profile 'PlayerDB', and for almost all situations we deal with this rather than User. PlayerDB can hold attributes and is typeclassed just like Objects and Scripts (normally with a typeclass named simply _Player_) allowing very big configurability options (although you can probably get away with just the default setup and use attributes for all but the most exotic designs). The Player is an OOC entity, it is what chats on channels but is not visible in a room. The last stage is the in-game ObjectDB model, typeclassed with a class called 'Character' by default. This is the in-game object that the player controls. The neat thing with this separation is that the Player object can easily switch its Character object if desired - the two are just linking to each other through attributes. This makes implementing multi-character game types much easier and less contrived than in the old system. == Help database -> command help + help database == Trunk stores all help entries in the database, including those created dynamically from the command's doc strings. This forced a system where the auto-help creation could be turned off so as to not overwrite later changes made by hand. There was also a mini-language that allowed for creating multiple help entries from the ``\ \_\_doc\_\_\ `` string. Devel-branch is simpler in this regard. All commands are _always_ using ``\ \_\_doc\_\_\ `` on the fly at run time without hitting the database (this makes use of cmdsets to only show help for commands actually available to you). The help database is stand-alone and you can add entries to it as you like, the help command will look through both sources of help entries to match your query. ==django-perms + locks -> permission/locks== Trunk relies on Django's user-permissions. These are powerful but have the disadvantage of being 'app-centric' in a way that makes sense for a web app, not so much for a mud. The devel-branch thus implements a completely stand-alone permission system that incoorperate both permissions and locks into one go - the system uses a mini-language that has a permission string work as a keystring in one situation and as a complex lock (calling python lock functions you can define yourself) in another. The permission system is working on a fundamental level, but the default setup probably needs some refinements still. ==Mux-like comms -> Generic comms == The trunk comm system is decidedly MUX-like. This is fine, but the problem is that much of that mux-likeness is hard-coded in the engine. Devel just defines three objects, Channel and Msg and an object to track connections between players and channels (this is needed to easily delete/break connections). How they interact with each other is up to the commands that use them, making the system completely configurable by the admin. All ooc messages - to channels or to players or both at the same time, are sent through use of the Msg object. This means a full log of all communications become possible to keep. Other uses could be an e-mail like in/out box for every player. The default setup is still mux-like though. ==Hard-coded parsing -> user customized parsing== Essentially all parts of parsing a command from the command line can be customized. The main parser can be replaced, as well as error messages for multiple-search matches. There is also a considerable difference in handling exits and channels - they are handled as commands with their separate cmdsets and searched with the same mechanisms as any command (almost any, anyway). ==Aliases -> Nicks== Aliases (that is, you choosing to for yourself rename something without actually changing the object itself) used to be a separate database table. It is now a dictionary 'nicks' on the Character object - that replace input commands, object names and channel names on the fly. And due to the separation between Player and Character, it means each character can have its own aliases (making this a suitable start for a recog system too, coincidentally). ==Attributes -> properties == To store data persistently in trunk requires you to call the methods ``\ get\_attribute\_value(attr)\ `` and ``\ set\_attribute(attr, - value)\ ``. This is available for in-game Objects only (which is really the only data type that makes sense anyway in Trunk). Devel allows attribute storage on both Objects, Scripts and Player objects. The attribute system works the same but now offers the option of using the ``\ db\ `` (for database) directly. So in devel you could now just do: {{{ obj.db.attr = value value = obj.db.attr }}} And for storing something non-persistently (stored only until the server reboots) you can just do {{{ obj.attr = value value = obj.attr }}} The last example may sound trivial, but it's actually impossible to do in trunk since django objects are not guaranteed to remain the same between calls (only stuff stored to the database is guaranteed to remain). Devel makes use of the third-party ``\ idmapper\ `` functionality to offer this functionality. This used to be a very confusing thing to new Evennia admins. _All_ database fields in Devel are now accessed through properties that handle in/out data storage. There is no need to save() explicitly anymore; indeed you should ideally not need to know the actual Field names. ==Always full persistence -> Semi/Full persistence == In Evennia trunk, everything has to be saved back/from the database at all times, also if you just need a temporary storage that you'll use only once, one second from now. This enforced full persistency is a good thing for most cases - especially for web-integration, where you want the world to be consistent regardless of from where you are accessing it. Devel offer the ability to yourself decide this; since semi-persistent variables can be stored on objects (see previous section). What actually happens is that such variables are stored on a normal python object called ``\ ndb\ `` (non-database), which is transparently accessed. This does not touch the database at all. Evennia-devel offers a setting ``\ FULL\_PERSISTENCE\ `` that switches how the server operates. With this off, you have to explicitly assign attributes to database storage with e.g. ``\ obj.db.attr - = value\ ``, whereas normal assignment (``\ obj.attr = - value\ ``) will be stored non-persistent. With ``\ FULL\_PERSISTENT\ `` on however, the roles are reversed. Doing ``\ obj.attr - = - value\ `` will now actually be saving to database, and you have to explicitly do ``\ obj.ndb.attr - = - value\ `` if you want non-persistence. In the end it's a matter of taste and of what kind of game/features you are implementing. Default is to use full persistence (but all of the engine explicitly put out ``\ db\ `` and ``\ ndb\ `` making it work the same with both). ==Commonly used functions/concept that changed names== There used to be that sending data to a player object used a method ``\ emit\_to()\ ``, whereas sending data to a session used a method ``\ msg()\ ``. Both are now called ``\ msg()\ ``. Since there are situations where it might be unclear if you receive a session or a player object (especially during login/logout), you can now use simply use ``\ msg()\ `` without having to check (however, you _can_ still use ``\ emit\_to\ `` for legacy code, it's an alias to msg() now). Same is true with emit_to_contents() -> msg_to_contents(). ``\ source\_object\ `` in default commands are now consistently named _caller_ instead. ``\ obj.get\_attribute\_value(attr)\ `` is now just ``\ obj.get\_attribute(attr)\ `` (but see the section on Attributes above, you should just use ``\ obj.db.attr\ `` to access your attribute). ==How hard is it to convert from trunk to devel?== It depends. Any game logic game modules you have written (AI codes, whatever) should ideally not do much more than take input/output from evennia. These can usually be used straight off. Commands and Script parents take more work but translate over quite cleanly since the idea is the same. For commands, you need to make the function into a class and add the parse(self) and func(self) methods (parse should be moved into a parent class so you don't have to use as much double code), as well as learn what variable names is made available (see the commands in ``\ gamesrc/commands/default\ `` for guidance). You can make States into !CmdSets very easy - just listing the commands needed for the state in a new !CmdSet. Script parents are made into Typeclasses by deleting the factory function and making them inherit from a !TypeClassed object (such as Object or Player) like the ones in ``\ gamesrc/typeclasses/basetypes.py\ ``, and then removing all code explicitly dealing with script parents. Converting to the new Scripts (again, don't confuse with the old _script parents_!) is probably the trickiest, since they are a more powerful incarnation of what used to be two separate things; States and Events. See the examples in the ``\ gamesrc/scripts/\ ```` - for some ideas.** - - Better docs on all of this will be forthcoming. - - Things not working/not implemented in devel (Aug 2010) - ------------------------------------------------------ - - All features planned to go into Devel are finished. There are a few - features available in Trunk that is not going to work in Devel until - after it merges with Trunk: - - \* IMC2/IRC support is not implemented.\* Attribute-level - permissions are not formalized in the default cmdset.\* Some of - the more esoteric commands are not converted. - - Please play with it and report bugs to our bug tracker! - - diff --git a/docs/sphinx/source/wiki/EvenniaIntroduction.rst b/docs/sphinx/source/wiki/EvenniaIntroduction.rst deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/sphinx/source/wiki/ExecutePythonCode.rst b/docs/sphinx/source/wiki/ExecutePythonCode.rst deleted file mode 100644 index cb1ba9e59a..0000000000 --- a/docs/sphinx/source/wiki/ExecutePythonCode.rst +++ /dev/null @@ -1,157 +0,0 @@ -The \`@py\` command -=================== - -The ``@py`` command supplied with the default command set of Evennia -allows you to execute Python commands directly from inside the game. An -alias to ``@py`` is simply "``!``\ ". *Access to the ``@py`` command -should be severely restricted*. This is no joke - being able to execute -arbitrary Python code on the server is not something you should entrust -to just anybody. - -:: - - @py 1+2 - <<< 3 - -Available variables -------------------- - -A few local variables are made available when running ``@py``. These -offer entry into the running system. - -- **self** / **me** - the calling object (i.e. you) -- **here** - the current caller's location -- **obj** - a dummy `Object `_ instance -- **ev** - Evennia's flat API - through this you can access all of - Evennia. - -Returning output ----------------- - -This is an example where we import and test one of Evennia's utilities -found in ``src/utils/utils.py``, but also accessible through -``ev.utils``: - -:: - - @py from ev import utils; utils.time_format(33333) - <<< Done. - -Note that we didn't get any return value, all we where told is that the -code finished executing without error. This is often the case in more -complex pieces of code which has no single obvious return value. To see -the output from the ``time_format()`` function we need to tell the -system to echo it to us explicitly with ``self.msg()``. - -:: - - @py from ev import utils; self.msg(utils.time_format(33333)) - 09:15 - <<< Done. - -If you were to use Python's standard ``print``, you will see the result -in your current ``stdout`` (your terminal by default), *if* you are -running Evennia in *interactive mode* (with the ``-i`` flag). - -Finding objects ---------------- - -A common use for ``@py`` is to explore objects in the database, for -debugging and performing specific operations that are not covered by a -particular command. - -Locating an object is best done using ``self.search()``: - -:: - - @py self.search("red_ball") - <<< Ball - - @py self.search("red_ball").db.color = "red" - <<< Done. - - @py self.search("red_ball").db.color - <<< red - -``self.search()`` is by far the most used case, but you can also search -other database tables for other Evennia entities like scripts or -configuration entities. To do this you can use the generic search -entries found in ``ev.search_*``. - -:: - - @py ev.search_script("sys_game_time") - <<< [] - -(Note that since this becomes a simple statement, we don't have to wrap -it in ``self.msg()`` to get the output). You can also use the database -model managers directly (accessible through the ``objects`` properties -of database models or as ``ev.managers.*``). This is a bit more flexible -since it gives you access to the full range of database search methods -defined in each manager. - -:: - - @py ev.managers.scripts.script_search("sys_game_time") - <<< [] - -The managers are useful for all sorts of database studies. - -:: - - @py ev.managers.configvalues.all() - <<< [, , ...] - -In doing so however, keep in mind the difference between `Typeclasses -and Database Objects `_: Using the search commands in -the managers will return *TypeClasses*. Using Django's default search -methods (``get``, ``filter`` etc) will return *Database objects*. This -distinction can often be disregarded, but as a convention you should try -to stick with the manager search functions and work with TypeClasses in -most situations. - -:: - - # this uses Evennia's manager method get_id(). - # It returns a Character typeclass instance - @py ev.managers.objects.get_id(1).__class__ - <<< Character - - # this uses the standard Django get() query. - # It returns a django database model instance. - @py ev.managers.objects.get(id=1).__class__ - <<< - -Running a Python Parser outside the game -======================================== - -``@py`` has the advantage of operating inside a running server, where -you can test things in real time. Much of this *can* be done from the -outside too though. - -Go to the ``game`` directory and get into a new terminal. - -:: - - python manage.py shell - -Your default Python intrepeter will start up, configured to be able to -work with and import all modules of your Evennia installation. From here -you can explore the database and test-run individual modules as desired. -Most of the time you can get by with just the ``ev`` module though. A -fully featured Python interpreter like -`iPython `_ allow you to work over -several lines, but also has lots of other editing features, usch as -tab-completion and ``__doc__``-string reading. - -:: - - $ python manage.py shell - - IPython 0.10 -- An enhanced Interactive Python - ... - - In [1]: import ev - In [2]: ev.managers.objects.all() - Out[3]: [, , ...] - diff --git a/docs/sphinx/source/wiki/GamePlanning.rst b/docs/sphinx/source/wiki/GamePlanning.rst deleted file mode 100644 index 27950c8018..0000000000 --- a/docs/sphinx/source/wiki/GamePlanning.rst +++ /dev/null @@ -1,185 +0,0 @@ -Game development tips and tricks -================================ - -So you have Evennia up and running. You have a great game idea in mind. -Now it's time to start cracking! But where to start? Here are some ideas -for a workflow. Note that the suggestions on this page are just that - -suggestions. Also, they are primarily aimed at a lone hobby designer or -a small team developing a game in their free time. - -Phases of Evennia game development -================================== - -Below are some minimal steps for getting the first version of a new game -world going with players. It's worth to at least make the attempt to do -these steps in order even if you are itching to jump ahead in the -development cycle. On the other hand, you should also make sure to keep -your work fun for you, or motivation will falter. Making a full game is -a lot of work as it is, you'll need all your motivation to make it a -reality. - -Remember that *99.99999% of all great game ideas never lead to an online -game*. So your first all overshadowing goal is to beat those odds and -get *something* out the door! *Even* if it's a scaled-down version of -your dream game, lacking many "must-have" features! It's better to get -it out there and expand on it later than to code in isolation forever -until you burn out, lose interest or your hard drive crashes. - -Like is common with online games, getting a game out the door does not -mean you are going to be "finished" with the game - most MUDs add -features gradually over the course of years - it's often part of the -fun! - -1: Planning ------------ - -This is what you do before having coded a single line or built a single -room. Many prospective game developers are very good at *parts* of this -process, namely in defining what their world is "about": The theme, the -world concept, cool monsters and so on. This is by all means important - -yes critical to the appeal of your game. But it's unfortunately not -enough to make your game a reality. To do that you must have an idea of -how to actually map those great ideas onto Evennia. - -A good start is to begin by planning out the basic primitives of the -game and what they need to be able to do. - -- **Rooms** - consider the most basic room in your game. How "big" is - it in a game sense? What should Players be able to do inside it? Is a - simple description enough? Can it be dark (description - changed/hidden)? Should it have smells, sounds? Weather? Different - terrain? How are those to be conveyed? Are there special "magic" - rooms that do things to people entering? Can a person hide in the - room? Should all rooms have the ability to be this complex or should - there be different types of rooms? Evennia allows you to change the - very concept of rooms should you be very ambitious, but is that a - road you really want to go down for your project? -- **Objects** - consider the most basic (non-player-controlled) object - in your game. What should a Player be able to do with it? Smash it? - If so, will it need some measure of its health? Does it have weight - or volume (so you cannot carry an infinite amount of them)? How do - you handle multiple identical objects? Try to give rough - classifications. Is a weapon a different type of object or are you - supposed to be able to fight with a chair as well? What about - NPCs/mobs, should they have some sort of AI? -- **Systems** - These are the behind-the-scenes features that exist in - your game, often without being represented by a specific in-game - object. For a role playing game, you need to define chances of - success ("rolls") for example. Will weather messages be random in - every room or should it follow some sort of realistic pattern over - all rooms? Do you have a game-wide economy - if so, how is that - supposed to work? If magic is dependent on the position of the - planets, the planets must change with time. What about spreading - rumors? Mail boxes? Bulletin boards? -- **Characters** - to do all those things with the rooms, objects and - systems in the game, what will the Characters need to have? What - skill will decide if they can "hide" in a room? Wield a chair as a - weapon? How to tell how much they can carry or which objects they can - smash? Can they gain experience and how? How about skills, classes, - attributes? - -A MUD's a lot more involved than you would think and these things hang -together in a complex web. It can easily become overwhelming and it's -tempting to want *all* functionality right out of the door. Try to -identify the basic things that "make" your game and focus on them for -the first release. Make a list. Keep future expansions in mind but limit -yourself. - -2: Coding ---------- - -This is the actual work of creating the "game" part of your game. Many -"game-designer" types tend to gloss over this bit and jump directly to -**Building**. Vice-versa, many "game-coder" types tend to jump directly -to this part without doing the **Planning** first. Neither is good and -*will* lead to you having to redo all your hard work at least once, -probably more. - -Evennia's `Developer Central `_ is focused on how -to perform this bit of the development. Evennia tries hard to make this -part easier for you, but there is no way around the fact that if you -want anything but a very basic Talker-type game you *will* have to bite -the bullet and code your game (or find a coder willing to do it for -you). Even if you won't code anything yourself, as a designer you need -to at least understand the basic paradigms of Evennia, such as objects, -commands and scripts and how they hang together. We recommend you go -through the `Tutorial World `_ in detail -(as well as skimming its code) to get at least a feel for what is -involved behind the scenes. - -During Coding you look back at the things you wanted during the -**Planning** phase and try to implement them. Don't be shy to update -your plans if you find things easier/harder than you thought. The -earlier you revise problems, the easier they will be to fix. -`Here `_ are some hints for setting up a sane -coding environment. - -"Tech Demo" Building -~~~~~~~~~~~~~~~~~~~~ - -This is an integral part of your Coding. It might seem obvious to -experienced coders, but it cannot be emphasized enough that you should -*test* things on a *small* scale before putting your untested code into -a large game-world. The earlier you test, the easier and cheaper it will -be to fix bugs and even rework things that didn't work out the way you -thought they would. You might even have to go back to the **Planning** -phase if your ideas can't handle their meet with reality. - -This means building singular in-game examples. Make one room and one -object of each important type and test they work as they should in -isolation, then add more if they are supposed to interact with each -other in some way. Build a small series of rooms to test how mobs move -around ... and so on. In short, a test-bed for your growing code. It -should be done gradually until you have a fully functioning (if not -guaranteed bug-free) miniature tech demo that shows *all* the features -you want in the first release of your game. There does not need to be -any game play or even a theme to your tests, but the more testing you do -on this small scale, the less headaches you will have in the next phase. - -3: World Building ------------------ - -Up until this point we've only had a few tech-demo objects in the -database. This step is the act of populating the database with a larger, -thematic world. Too many would-be developers jump to this stage too soon -and then have to go back and rework things on already existing objects. -Evennia's typeclass system does allow you to edit the properties of -existing objects, but some hooks are only called at object creation, and -you are in for a *lot* of unnecessary work if you build stuff en masse -without having the underlying code systems in some reasonable shape -first. - -So, at this point the "game" bit (Coding + Testing) should be more or -less complete, *at least to the level of your initial release*. Building -often involves non-coders, so you also get to test whatever custom build -systems you have made at this point. You don't have to complete your -entire world in one go - just enough to make the game's "feel" come -across - an actual world where the intended game play can be tested and -roughly balanced. You can always add new areas later, so limit yourself. - -Alpha Release -------------- - -As mentioned, don't hold onto your world more than necessary. *Get it -out there* with a huge *Alpha* flag and let people try it! Call upon -your alpha-players to try everything - they *will* find ways to break -your game in ways that you never could have imagined. In Alpha you might -be best off to focus on inviting friends and maybe other MUD developers, -people who you can pester to give proper feedback and bug reports (there -*will* be bugs, there is no way around it). Follow the quick -instructions `here `_ to make your game visible -online. - -Beta Release/Perpetual Beta ---------------------------- - -Once things stabilize in Alpha you can move to *Beta* and let more -people in. Many MUDs are in `perpetual -beta `_, meaning they are -never considered "finished", but just repeat the cycle of Planning, -Coding, Testing and Building over and over as new features get -implemented or Players come with suggestions. As the game designer it's -up to you to perfect your vision. - -Congratulations, at this point you have joined the small, exclusive -crowd who have made their dream game a reality! diff --git a/docs/sphinx/source/wiki/GettingHelp.rst b/docs/sphinx/source/wiki/GettingHelp.rst deleted file mode 100644 index 869afd04fb..0000000000 --- a/docs/sphinx/source/wiki/GettingHelp.rst +++ /dev/null @@ -1,15 +0,0 @@ -Getting Help -============ - -The best way to get help is via our `Google -Group `_. Simply post a message with a clear -question and you are more than likely to receive a response. This way -issues can be tracked over time too. - -If you want more direct discussions with developers and other users, -consider dropping into our IRC chat channel -`#evennia `_ on the -Freenode network. Please note however that you have to be patient if you -don't get any response immediately; we are all in very different time -zones and many have busy personal lifes. So you might have to lurk about -for a while - but if you are patient you'll get noticed eventually! diff --git a/docs/sphinx/source/wiki/GettingStarted.rst b/docs/sphinx/source/wiki/GettingStarted.rst deleted file mode 100644 index f5c86ae992..0000000000 --- a/docs/sphinx/source/wiki/GettingStarted.rst +++ /dev/null @@ -1,431 +0,0 @@ -Getting Started -=============== - -This will help you download, install and start Evennia for the first -time. - -*Note: You don't need to make anything visible to the 'net in order to -run and test out Evennia. Apart from installing and updating you don't -even need to have an internet connection. Of course you'll probably want -to put your game online once it matures enough, but until then it works -fine to develop and play around completely in the sanctity and isolation -of your local machine.* - -Quick start ------------ - -For you who are extremely impatient, here's the gist of getting a -vanilla Evennia install running. - -#. *Get the pre-requisites (Python, Django, Twisted, South and - Mercurial)*. -#. *Start a command terminal/dos prompt and change directory to where - you want to have your 'evennia' folder appear*. -#. ``hg clone https://code.google.com/p/evennia/ evennia`` -#. *Change directory to evennia/game*. -#. ``python manage.py`` -#. ``python manage.py syncdb`` -#. ``python manage.py migrate`` -#. ``python evennia.py -i start`` - -Evennia should now be running and you can connect to it by pointing a -web browser to ``http://localhost:8000`` or a MUD telnet client to -``localhost:4000``. - -Read on for more detailed instructions and configurations. - -Prerequisites -------------- - -As far as operating systems go, any system with Python support should -work. - -- Linux/Unix -- Windows (2000, XP, Vista, Win7, Win8) -- Mac OSX (>=10.5 recommended) - -If you run into problems, or have success running Evennia on another -platform, please let us know. - -You'll need the following packages and minimum versions in order to run -Evennia: - -- **`Python `_** (v2.6+, not supporting v3.x). - - - Windows users are recommended to use - `ActivePython `_ - instead. - -- **`Twisted `_** (v11.0+) - - - `ZopeInterface `_ - (v3.0+) - usually included in Twisted packages - - Windows users might also need - `pywin32 `_. - -- **`Django `_** (v1.5+) - - - `PIL `_ (Python Image - Library) - often distributed with Django. - -- **`South `_** (v0.8+) - - - South is used to track and apply changes to the database's - structure. - -To download/update Evennia: - -- **`Mercurial `_** - -Optional: - -- **`PyPy `_** (v1.7+) - - - Optional faster implementation of Python. See - [`GettingStarted `_\ #Optional:\ *Running\_under\_PyPy - here] for how to run Evennia under PyPy.* - - Installing pre-requisites - ------------------------- - - **All platforms** can set up an \_virtual Python environment and - install Evennia to that. All you need pre-installed is Python. - Setup is described in detail - [`GettingStarted `_\ #Optional:\ *A\_separate\_installation\_environment\_with\_virtualenv - here]. Windows users will probably want to go the ActivePython - route instead (see below) since there are issues with installing - certain extensions under Windows.* - - **Linux** package managers should usually handle all this for you. - Python itself is definitely available through all distributions. - On Debian-derived systems (such as Ubuntu) you can do something - like this (as root) to get all you need: - - :: - - apt-get install python python-django python-twisted mercurial python-django-south - - (Gentoo note: Gentoo (and maybe other distros?) seems to - distribute Twisted in multiple packages. Beyond the main twisted - package you will also need to get at least twisted-conch and - twisted-web too).\ ** - - Distributions can usually not keep fully up-to-date with the - latest security fixes. So for an online server it is highly - recommended to use Python's - `easy\_install `_ - or the newer - `pip `_ to get - some or all of the dependencies instead: - - :: - - easy_install django twisted pil mercurial south - - :: - - pip install django twisted pil mercurial south - - If you already have Python and have downloaded Evennia, the - package comes with a ``requirements.txt`` file. This can be used - with ``pip`` to install the remaining dependencies. This is useful - for automated build systems: - - :: - - pip install -r requirements.txt - - **Mac** users should be able to get most dependencies through - ``easy_install`` or ``pip`` like Linux users do. All interaction - is done from a terminal window. There are some reports that you - might need to get the - `Xcode `_ development system - to install the packages that requires extension compiling. You can - also retrieve the dependencies directly and install them through - their native installers or python setups. Some users have reported - problems compiling the ``PIL`` library on Mac, it's however not - strictly required in order to use Django (it's used for images). - - **Windows** users should first and foremost recognize that the - Evennia server is run from the command line, something which some - might not be familiar with (based on the questions we have - received). In the Windows launch menu, just start \_All Programs - -> Accessories -> command prompt and you will get the Windows - command line interface. There are plenty of online tutorials on - using the Windows command line, one example is found - `here `_. - -Windows users may want to install -`ActivePython `_ -instead of the usual Python. Get the 32-bit version (it seems the 64-bit -one won't let you download any packages without paying for a "Business" -license). If ActivePython is installed, you can use -`pypm `_ in the -same manner as ``easy_install``/``pip`` above. This *greatly* simplifies -getting started on Windows - this platform defaults to lacking sane -developer tools and package management. - -After installing ActivePython you may need to restart the terminal/DOS -window to make the pypm command available on the command line. Then -write: - -:: - - pypm install Django Twisted PIL Mercurial South - -This installs everything you need in one go. - -Windows users not using ActivePython or virtual environments will have -to manually download and install the packages in turn (including their -own dependencies in the list above). Most have normal Windows -installers, but in some cases you'll need to know how to use the Windows -command prompt to execute python install scripts (it's usually not -harder than running ``python setup.py install`` from the downloaded -package's folder). - -Step 1: Obtaining the Server ----------------------------- - -To download Evennia you need the Mercurial client to grab a copy of the -source. - -For command-line Mercurial client users, something like this will do the -trick (first place yourself in a directory where you want a new folder -``evennia`` to be created): - -:: - - hg clone https://code.google.com/p/evennia/ evennia - -(Mercurial is abbreviated ``hg`` since this is the chemical symbol for -mercury). - -In the future, you just do - -:: - - hg pull - hg update - -from your ``evennia/`` directory to obtain the latest updates. - -If you use a graphical Mercurial client, use the equivalent buttons to -perform the above operations. See -`here `_ for more -advanced suggestions to set up a development environment with Mercurial. - -Step 2: Setting up the Server ------------------------------ - -From within the Evennia ``game`` directory (``evennia/game/``, if you -followed the Mercurial instructions above) type the following to trigger -the automatic creation of an empty ``settings.py`` file. - -:: - - python manage.py - -Your new ``settings.py`` file will just be an empty template initially. -In ``evennia/src/settings_default.py`` you will find the settings that -may be copied/pasted into your ``settings.py`` to override the defaults. -This will be the case if you want to adjust paths or use something other -than the default SQLite3 database engine. You *never* want to modify -``settings_default.py`` directly - as the server is developed, this file -might be overwritten with new versions and features. - -If you would like to use something other than the default SQLite setup -(which works "out of the box"), you'll need to copy the ``DATABASE_*`` -variables from ``settings_defaults.py`` and paste them to -``settings.py``, making your modifications there. - -*Note that the settings.py file is in fact a normal python module which -imports the default settings. This means that all variables have been -set to default values by the time you get to change things. So to -customize a particular variable you have to copy&paste it to your -settings file - and you have to do so also for variables that depend on -that variable (if any), or the dependent variables will remain at the -default values.* - -Finally, enter the following command in a terminal or shell to create -the database file (in the case of SQLite3) and populate the database -with the standard tables and values: - -:: - - python manage.py syncdb - -You will see a lot of spammy install messages. If all goes well, you're -ready to continue to the next step. If not, look at the error messages -and double-check your ``settings.py`` file. - -Next you migrate the database to the current revision: - -:: - - python manage.py migrate - -This can take a while. When we make changes to the database schema in -the future (we announce this on the homepage) you just need to re-run -this command to have your existing database converted for you. - -Step 3: Starting and Stopping the Server ----------------------------------------- - -To start the server, make sure you're in the ``evennia/game`` directory -and execute ``evennia.py`` like this: - -:: - - python evennia.py -i start - -(The ``-i`` flag means that the server starts in *interactive mode*, as -a foreground process. You will see debug/log messages directly in the -terminal window instead of logging them to a file.) - -You should be asked to create a superuser. Make **sure** you create a -superuser here when asked, this becomes your login name for the -superuser (owner) account in game. It will ask for email address and -password. The email address does not have to be an existing one. - -After entering the superuser information, the server and portal will -start for the first time. Evennia will quickly run some first-time -configurations, restart once and then be running. - -To stop Evennia, do: - -:: - - python evennia.py stop - -See `Running -Evennia `_ for -more advanced options on controlling Evennia's processes. - -Step 4: Connecting to the server --------------------------------- - -The Evennia server is now up and running. You should be able to login -with any mud client or telnet client using the email address and -password you specified when syncing the database. If you are just -testing the server out on your local machine, the server name will most -likely be ``localhost`` whereas the port used by default is ``4000``. - -If the defaults are not changed, Evennia will also start its own -Twisted-based web server on port 8000. Point your web browser to -``http://localhost:8000/``. The *admin interface* allows you to edit the -game database online and you can connect directly to the game by use of -the ajax web client. - -Welcome to Evennia! Why not try `building -something `_ next? - -Optional: A separate installation environment with virtualenv -============================================================= - -Apart from installing the packages and versions as above, you can also -set up a very easy self-contained Evennia install using the -`virtualenv `_ program. If you -are unsure how to get it, just grab the -`virtualenv.py `_ -file and run it directly in the terminal with ``python virtualenv.py``. - -Virtualenv sets aside a folder on your harddrive as a stand-alone Python -environment. It should work both on Linux/Unix and Windows. First, -install Python as normal, then get virtualenv and install it so you can -run it from the command line. This is an example for setting up Evennia -in an isolated new folder *mudenv*: - -:: - - virtualenv mudenv - -Or, if you grabbed ``virtualenv.py`` and is running it directly: - -:: - - python virtualenv.py mudenv - -Followed by - -:: - - cd mudenv - -Now we should be in our new directory *mudenv*. Next we activate the -virtual environment in here. - -:: - - # for Linux/Unix: - source bin/activate - # for Windows: - \Scripts\activate.bat - -The virtual environment within our *mudenv* folder is now active. Things -will not seem to have changed very much, and indeed they haven't - the -only difference is that python programs will now look to the python -installation in this folder instead of the system-centric ones. - -Next we get all the requirements with *pip*, which is included with -virtualenv: - -:: - - pip install django twisted pil mercurial south - -These newly installed packages are *only* localized to the virtual -environment, they do not affect the normal versions of programs you run -in the rest of your system. So you could for example experiment with -bleeding-edge, unstable libraries or go back to older versions without -having to worry about messing up other things. It's also very easy to -uninstall the whole thing in one go - just delete your ``mudenv`` -folder. - -You can now refer to **Step 1** above and continue on from there to -install Evennia into *mudenv*. In the future, just go into the folder -and activate it before starting or working with Evennia. - -Optional: Running under !PyPy -============================= - -Evennia can also be run under `PyPy `_, a fast -alternative implementation of standard Python. Evennia under PyPy -generally takes longer to start but may run faster (just how much is -currently untested so feel free to report your findings). - -You first need to download and install PyPy. See the -`PyPy `_ homepage for instructions. This may be the -most tricky step depending on your operating system. - -The easiest way to set up Evennia for running under pypy is to do so in -a separate *virtualenv*. First get the virtualenv program as described -in the previous section and create your virtual environment like this: - -:: - - virtualenv mudenv --python=/usr/bin/pypy - -Replace ``/usr/bin/pypy`` with the full path to your PyPy binary on your -system. - -Next you activate and set up the virtual environment as normal. Make -sure to install all dependencies to the virtual environment. If ``pip`` -aborts with a message about "dependence is already satisfied", use the ---upgrade option. This way PyPy-enhanced versions of the dependencies -will be installed wherever applicable. - -Download and configure Evennia as usual. Then just start it like this: - -:: - - pypy evennia.py -i start - -Inside the game you can do the following (as superuser) to test that -PyPy is working: - -:: - - @py import __pypy__ - -If this works Evennia is running under pypy. If you get an ImportError -there was some problem and normal Python is still being used. diff --git a/docs/sphinx/source/wiki/HelpSystem.rst b/docs/sphinx/source/wiki/HelpSystem.rst deleted file mode 100644 index 6ea683b9c8..0000000000 --- a/docs/sphinx/source/wiki/HelpSystem.rst +++ /dev/null @@ -1,136 +0,0 @@ -Help system -=========== - -An important part of Evennia is the online help system. This allows the -players and staff alike to learn how to use the game's commands as well -as other information pertinent to the game. The help system has many -different aspects, from the normal editing of help entries from inside -the game, to auto-generated help entries during code development using -the *auto-help system*. - -Viewing the help database -------------------------- - -The main command is ``help``. - -:: - - help [searchstring] - -This will show a list of help entries, ordered after categories. You -will find two sections, *Command help entries* and *Other help entries* -(initially you will only have the first one). You can use help to get -more info about an entry; you can also give partial matches to get -suggestions. If you give category names you will only be shown the -topics in that category. - -Command Auto-help system ------------------------- - -One important use of the help system is to teach the use of in-game -commands. Evennia offers a dynamically updated help system for all your -commands, new and old, known simply as the *auto-help system*. Only -commands that you and your character can actually currently use are -picked up by the auto-help system. That means an admin will see a -considerably larger amount of help topics than a normal player when -using the ``help`` command. - -The auto-help system uses the ``__doc__`` strings of your command -definitions and formats this to a nice-looking help entry. This makes -for a very easy way to keep the help updated - just document your -commands well abd updating the help file is just a ``@reload`` away. -There is no need to manually create and maintain help database entries -for commands; as long as you keep the docstrings updated your help will -be dynamically updated for you as well. - -Example (from a module with command definitions): - -:: - - class CmdMyCmd(Command): - """ - mycmd - my very own command - - Usage: - mycmd[/switches] - - Switches: - test - test the command - run - do something else - - This is my own command that does things to you when you - supply it with arguments. - - """ - ... - help_category = "Building" - ... - -The text at the very top of the command class definition is the class' -``__doc__``-string and will be shown to users looking for help. Try to -use a consistent format - all default commands are using the structure -shown above. You should also supply the ``help_category`` class property -if you can; this helps to group help entries together for easier finding -(if you don't supply a help\_category, "General" will be assumed). - -Other help entries (entries stored in database) ------------------------------------------------ - -Not all help entries concern commands. You will also probably need help -entries describing how your particular game is played - its rules, world -descriptions and other types of information not covered by the auto-help -system. Such entries are manually added to the database by staff and -will appear under a heading "Other help" whenever you have any. Instead -of being generated from the code by Evennia, these entries are stored in -the database as a ``HelpEntry``. - -A help entry consists of four parts: - -- The *topic*. This is the name of the help entry. This is what players - search for when they are looking for help. The topic can contain - spaces and also partual matches will be found. -- The *help category*. Examples are *Administration*, *Building*, - *Comms* or *General*. This is an overall grouping of similar help - topics, used by the engine to give a better overview. -- The *text* - the help text itself, of any length. -- locks - a `lock definition `_. This can be used to limit - access to this help entry, maybe because it's staff-only or otherwise - meant to be restricted. Help commands check for ``access_type``\ s - ``view`` and ``edit``. An example of a lock string would be - ``view:perm(Builders)``. - -You can create new help entries in code by using -``src.utils.create.create_help_entry()``: - -:: - - from src.utils import create - entry = create.create_help_entry("emote", - "Emoting is important because ...", - category="Roleplaying", locks="view:all()"): - -From inside the game those with the right permissions can use the -``@sethelp`` command to add and modify help entries. - -:: - - > @sethelp/add emote = The emote command is ... - -Using ``@sethelp`` you can add, delete and append text to existing -entries. By default new entries will go in the *General* help category. -You can change this using a different form of the ``@sethelp`` command: - -:: - - > @sethelp/add emote, Roleplaying = Emoting is important because ... - -If the category *Roleplaying* did not already exist, it is created and -will appear in the help index. - -You can, finally, define a lock for the help entry by following the -category with a `lock definition `_: - -:: - - > @sethelp/add emote, Roleplaying, view:all() = Emoting is important because ... - diff --git a/docs/sphinx/source/wiki/HowToGetAndGiveHelp.rst b/docs/sphinx/source/wiki/HowToGetAndGiveHelp.rst deleted file mode 100644 index 73c9f937b0..0000000000 --- a/docs/sphinx/source/wiki/HowToGetAndGiveHelp.rst +++ /dev/null @@ -1,64 +0,0 @@ -How to \_get\_ Help -=================== - -If you cannot find what you are looking for in the `online -documentation `_, here's what to do: - -- If you think the documentation is not clear enough, fill in our quick - little `online - form `_ - and say so (no login required). Maybe the docs need to be improved or - a new tutorial added! Note that this form will help you by helping us - improve documentation, but you cannot get direct, specific answers - back from it. -- If you have trouble with a missing feature or a problem you think is - a bug, go to the `issue - tracker `_. If you - can't find the issue already reported, file a new one by filling in - the handy form. -- If you need help, want to start a discussion or get input on - something, make a post in our `forum `_. This is - technically a 'mailing list', but you don't need to use e-mail; you - can post and read all messages just as easily from your browser via - the online interface. -- If you want more direct discussions with developers and other users, - consider dropping into our IRC chat channel - `#evennia `_ on the - *Freenode* network. Please note however that you have to be patient - if you don't get any response immediately; we are all in very - different time zones and many have busy personal lives. So you might - have to lurk about for a while - you'll get noticed eventually! - -How to \_give\_ Help -==================== - -Evennia is a completely un-funded project. It relies on the time donated -by its users and developers in order to progress. - -The first and easiest way you as a user can help us out is by taking -part in `community -discussions `_ and by giving -feedback on what is good or bad. Report bugs you find and features you -lack to our `issue -tracker `_. Just the -simple act of letting developers know you are out there using their -program is worth a lot. - -If you'd like to help develop Evennia more hands-on, here are some ways -to get going: - -- Look through our `online documentation wiki `_ and see if - you can help improve or expand the documentation (even small things - like fixing typos!). -- Send a message to our - `forum `_ and/or our `IRC - chat `_ asking about - what needs doing, along with what your interests and skills are. -- Take a look at our `issue - tracker `_ and see if - there's something you feel like taking on. -- Check out the `Contributing `_ page on how to - contribute with code in practice. - -See `Contributing to Evennia `_ for more detailed -information. diff --git a/docs/sphinx/source/wiki/IMC2.rst b/docs/sphinx/source/wiki/IMC2.rst deleted file mode 100644 index c87cd0fd38..0000000000 --- a/docs/sphinx/source/wiki/IMC2.rst +++ /dev/null @@ -1,119 +0,0 @@ -IMC2 -==== - -`IMC2 `_, *InterMud -Communications, protocol version 2*, is a protocol that allows -individual mud games (Evennia-powered or not) to connect to a remote -server for the purpose of IRC-like communication with other games. By -connecting your MUD to IMC, you and your admins/players will be able to -communicate with players on other muds connected to the network! Note -that you can use IMC2 also if your Evennia install is only running -locally on your computer -all you need is an internet connection. - -Evennia's IMC implementation is special in that it integrates Evennia's -normal channel system with IMC. The basic principle is that you -"connect" an IMC channel to an existing Evennia channel. Users on the -IMC network will then see what is said on the channel and vice versa. - -Joining the IMC network ------------------------ - -To configure IMC, you first need to activate it by setting -``IMC2_ENABLED=True`` in your settings file. This will make several new -IMC-related commands available to a privileged user. Since the IMC -network will need to know your mud's name, make sure you have also set -``settings.SERVERNAME`` to the mud name you want. - -Next you need to register your mud at a IMC2 network. We suggest the -`MudBytes IMC2 network `_. You can -join for free -`here `_. On that -page, follow the following steps: - -#. From the drop-down list, select "Other unsupported IMC2 version", - then click Submit -#. You will get to a form. In "Short Mud name" you need to enter the - name of your mud as defined by ``settings.SERVERNAME``. -#. Give client- and server passwords to anything you want, but remember - them. -#. Give an admin e-mail. This shouldn't be too critical. -#. Choose a server. It shouldn't really matter which you choose, as long - as you remember what you picked (Evennia's development channel - ``ievennia`` is found on ``Server01``). Click "Join". - -You have now created an account on the Mudbytes IMC network and are -ready to go on. - -Now fill in the rest of the IMC2 information in your settings file - -give the network name and port, as well as the client- and server -passwords you used when registering on mudbytes. - -For testing, you can connect your mud client to the IMC mini-mud called -*Talon* on ``talon.mudbytes.net:2000``. This works pretty much like an -IRC client. - -Creating an Evennia channel ---------------------------- - -Evennia maps in-game channels to remote IMC channels. This means that -you get all of the features of the local comm system for remote IMC -channels as well (channel history, permissions-based channel entry, -etc.) - -Let's create a dedicated Evennia channel to host imc communications (you -could also use an existing channel like ``ooc`` if you wanted): - -:: - - @ccreate imc2 = This is connected to an IMC2 channel! - -You should join the channel automatically. - -Setting up a Channel \`<->\` IMC2 binding ------------------------------------------ - -Evennia developers have an open-access IMC channel called ``ievennia`` -on ``Server01`` of the Mudbytes network. For Evennia development we -recommend you connect to this for sharing evennia anecdotes! - -Activating IMC2 have made new commands available, the one you need is -``@imc2chan``. You use this to create a permanent link between an IMC -channel and an existing Evennia channel of your choice. You can use the -``imcchanlist`` to see which IMC channels are available on the network. - - Let's connect our new ``imc2`` channel to the ``ievennia`` channel - on Server01. - -:: - - @imc2chan imc2 = ievennia - -To test, use the IMC mud *Talon*, make sure you "listen" to -``ievennia``, then write something to the channel. You should see the -text appear in Evennia's ``imc2`` channel and vice versa. - -Administration and notes ------------------------- - -You can view all your IMC-to-Evennia mappings using ``@imc2chan/list``. -To permanently remove a connection, use ``@imc2chan`` with the -``/delete`` switch like this: - -:: - - @imc2chan/delete imc2 = ievennia - -A single Evennia channel may *listen* to any number of remote IMC -channels. Just use ``@imc2chan`` to add more connections. Your channel -can however only ever *send* to one IMC2 channel and that is the first -one you link to it (``ievennia`` in this example). - -The ``@imclist`` command will list all other MUDs connected to the -network (not including yourself). - -Talk between IRC and IMC ------------------------- - -This is easy - just bind IMC to the same evennia channel that IRC binds -to. The process of binding IRC channels is described in more detail -`here `_. diff --git a/docs/sphinx/source/wiki/IRC.rst b/docs/sphinx/source/wiki/IRC.rst deleted file mode 100644 index 25c85ef716..0000000000 --- a/docs/sphinx/source/wiki/IRC.rst +++ /dev/null @@ -1,118 +0,0 @@ -IRC -=== - -`IRC (Internet Relay -Chat) `_ is a long -standing chat protocol used by many open-source projects for -communicating in real time. By connecting one of Evennia's -`Channels `_ to an IRC channel you can communicate -also with people not on an mud themselves. Note that you can use IRC -also if you are only running your Evennia MUD locally on your computer -(your game don't need to be open to the public)! All you need is an -internet connection. For IRC operation you also need -`twisted.words `_. This -is available simply as a package *python-twisted-words* in many Linux -distros, or directly downloadable from the link. - -Configuring IRC ---------------- - -To configure IRC, you'll need to activate it in your settings file. You -do this by copying the ``IRC_ENABLED`` flag from -``evennia/src/config_defaults.py`` into your -``evennia/game/settings.py`` and setting it to ``True``. - -Start Evennia and log in as a privileged user. You should now have a new -command availabele: ``@irc2chan``. This command is called like this: - -:: - - @irc2chan[/switches] = <#irchannel> - -If you already know how IRC works, this should be pretty self-evident to -use. Read the help entry for more features. - -Setting up IRC, step by step ----------------------------- - -You can connect IRC to any Evennia channel, but for testing, let's set -up a new channel ``irc``. - -:: - - @ccreate irc = This is connected to an irc channel! - -You will automatically join the new channel. - -Next we will create a connection to an external IRC network and channel. -There are many, many IRC nets. -`Here `_ is a list -of some of the biggest ones, the one you choose is not really very -important unless you want to connect to a particular channel (also make -sure that the network allows for "bots" to connect). - -For testing, we choose the *Freenode* network, ``irc.freenode.net``. We -will connect to a test channel, let's call it *#myevennia-test* (an IRC -channel always begins with ``#``). It's best if you pick an obscure -channel name that didn't exist previously - if it didn't exist it will -be created for you. *Don't* connect to ``#evennia`` for testing and -debugging, that is Evennia's official chat channel! - -(By the way, you *are* welcome to connect your game to ``#evennia`` once -you have everything working - it can be a good way to get help and -ideas. But if you do, please do so with an in-game channel open only to -your game admins and developers). - -The *port* needed depends on the network. For Freenode this is ``6667``. - -What will happen is that your Evennia server will connect to this IRC -channel as a normal user. This "user" (or "bot") needs a name, which you -must also supply. Let's call it "mud-bot". - -To test that the bot connects correctly you also want to log onto this -channel with a separate, third-party IRC client. There are hundreds of -such clients available. If you use Firefox, the *Chatzilla* plugin is -good and easy. There are also web-based clients like *Mibbit* that you -can try. Once you have connected to a network, the command to join is -usually ``/join channelname`` (don't forget the #). - -Next we connect Evennia with the IRC channel. - -:: - - @irc2chan irc = irc.freenode.net 6667 #myevennia-test mud-bot - -Evennia will now create a new IRC bot ``mud-bot`` and connect it to the -IRC network and the channel #myevennia. If you are connected to the IRC -channel you will soon see the user *mud-bot* connect. - -Write something in the Evennia channel *irc*. - -:: - - irc Hello, World! - [irc] Anna: Hello, World! - -If you are viewing your IRC channel with a separate IRC client you -should see your text appearing there, spoken by the bot: - -:: - - mud-bot> [irc] Anna: Hello, World! - -Write ``Hello!`` in your IRC client window and it will appear in your -normal channel, marked with the name of the IRC channel you used -(#evennia here). - -:: - - - [irc] Anna@#myevennia-test: Hello! - -Your Evennia gamers can now chat with users on external IRC channels! - -Talking between IRC and IMC ---------------------------- - -You can easily connect IRC and IMC by simply connecting them to the same -Evennia channel. IMC connections are described `here `_. diff --git a/docs/sphinx/source/wiki/Index.rst b/docs/sphinx/source/wiki/Index.rst deleted file mode 100644 index 0b76ef7ebd..0000000000 --- a/docs/sphinx/source/wiki/Index.rst +++ /dev/null @@ -1,34 +0,0 @@ -Evennia Documentation -===================== - -This is Evennia's manual. You should hopefully find all you need to know -about coding with, extending and using the codebase among these pages. -If you have trouble with unclear documentation, fill in our quick -`online form `_ and tell us so - maybe more -details or a new tutorial is needed! - -The documentation is divided into several main categories. If you are -new, it might be an idea to browse the sections in the order they are -listed. If you get stuck or feel the urge to improve things, see the -section on `how to get and give help `_. - -Sections --------- - -- A `Lengthier introduction `_ to what - Evennia is. - -- The `Getting Started `_ page helps with - downloading, installing and setting up Evennia for the first time. -- The `Administrative Documentation `_ covers the - practicalities of running and maintaining an Evennia game once it is - in place. -- The `Builder Docs `_ section contains instructions - for starting to build a game world using Evennia. -- The `Developer Central `_ covers - implementation details and guides of interest for game-world coders - as well as for current and prospective Evennia developers. -- The `Tutorials & Examples `_ section summarizes help - pages on a step-by-step or tutorial format. Some of these are - reachable from their respective sections as well. - diff --git a/docs/sphinx/source/wiki/Internationalization.rst b/docs/sphinx/source/wiki/Internationalization.rst deleted file mode 100644 index 6c01bc8d9e..0000000000 --- a/docs/sphinx/source/wiki/Internationalization.rst +++ /dev/null @@ -1,79 +0,0 @@ -Internationalization -==================== - -*Internationalization* (often abbreviated *i18n* since there are 18 -characters between the first "i" and the last "n" in that word) allows -Evennia's core server to return texts in other languages than English - -without anyone having to go in and add it manually. Take a look at the -``locale`` directory of the Evennia installation, there you will find -which languages are currently supported. - -Note, what is translated in this way are hard-coded strings from the -server, things like "Connection closed" or "Server restarted" - things -that Players will see and which game devs are not supposed to change on -their own. So stuff seen in the log file or on stdout will not be -translated. It also means that the default command set is *not* -translated. The reason for this is that commands are *intended* to be -modified by users. Adding *i18n* code to commands tend to add complexity -to code that will be changed anyway. One of the goals of Evennia is to -keep the user-changeable code as clean and easy-to-read as possible. - -Changing server language ------------------------- - -Change language by adding the following to your ``game/settings.py`` -file: - -:: - - USE_I18N = True - LANGUAGE_CODE = 'en' - -Here ``'en'`` should be changed to the abbreviation for one of the -supported languages found in ``locale/``. Restart the server to activate -i18n. - -Translating Evennia -------------------- - -If you cannot find your language in ``locale/`` it's because noone has -translated it yet. Alternatively you might have the language but find -the translation bad ... You are welcome to help improve the situation! - -To start a new translation, place yourself in Evennia's root directory -and run - -:: - - django-admin makemessages -l - -where ```` is the two-letter locale code for the language -you want, like 'sv' for Swedish or 'es' for Spanish. - -Next head to ``locale//LC_MESSAGES`` and edit the -``*.po`` file you find there. There is no need to edit this file using a -normal text editor -- best is to use a po-file editor from the web -(search the web for "po editor" for many free alternatives). - -The concept of translating is simple, it's just a matter of taking the -english strings you find in the ``*.po`` file and add your language's -translation best you can. The ``*.po`` format (and many supporting -editors) allow you to mark translations as "fuzzy". This tells the -system (and future translators) that you are unsure about the -translation, or that you couldn't find a translation that exactly -matched the intention of the original text. - -Finally, you need to compile your translation into a more efficient -form. - -:: - - 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 -developer list (or push it into your own repository clone) so we can -integrate your translation into Evennia! diff --git a/docs/sphinx/source/wiki/Licensing.rst b/docs/sphinx/source/wiki/Licensing.rst deleted file mode 100644 index d34b4b1660..0000000000 --- a/docs/sphinx/source/wiki/Licensing.rst +++ /dev/null @@ -1,42 +0,0 @@ -Evennia License FAQ -=================== - -Evennia is licensed under the very friendly -`BSD `_ (3-clause) license. -You can find the license as ``LICENSE.txt`` in the Evennia root -directory. You can also read the full license file -`here `_ -(it's not long). - -Q: When creating a game using Evennia, what does the license permit me to do with it? -------------------------------------------------------------------------------------- - -**A:** It's your own game world to do with as you please! Keep it to -yourself or re-distribute it under any license of your choice - or sell -it and become filthy rich for all we care. - -Q: I have modified Evennia itself, what does the license say about that? ------------------------------------------------------------------------- - -**A:** The BSD license allows you to do whatever you want with your -modified Evennia, including re-distributing or selling it, as long as -you include our license and copyright info in the ``LICENSE.txt`` file -along with your distribution. - -... Of course, if you make bug fixes or add some new snazzy feature we -*softly nudge* you to make those changes available so they can be added -to the core Evennia package for everyone's benefit. The license don't -require you to do it, but that doesn't mean we can't still greatly -appreciate it if you do! - -Q: Can I re-distribute the Evennia server package along with my custom game implementation? -------------------------------------------------------------------------------------------- - -**A:** Sure. As long as the text in LICENSE.txt is included. - -Q: What about Contributions? ----------------------------- - -The contributions in ``evennia/contrib`` are considered to be released -under the same license as Evennia itself unless the individual -contributor has specifically defined otherwise. diff --git a/docs/sphinx/source/wiki/Links.rst b/docs/sphinx/source/wiki/Links.rst deleted file mode 100644 index 7899f1b0d3..0000000000 --- a/docs/sphinx/source/wiki/Links.rst +++ /dev/null @@ -1,137 +0,0 @@ -External links and resources -============================ - -This is a list of resources that may be useful for Evennia users and -developers. - -Evennia links -------------- - -- `Evennia's main portal page `_ (RSS feeds to - updates) -- `Evennia forums `_ -- `Evennia Commit - Log `_ (hg commit - notification) -- `Sequential source update - list `_ (easily see - what was changed in each update) -- `Evennia mailing list `_ - (better web interface can be found from the portal) -- `Evennia development blog `_ - -Third-party Evennia links -------------------------- - -- `Evennia's manual on - ReadTheDocs `_ (also - convert to PDF) -- `Hosting Evennia on - Webfaction `_ -- `Evennia on Ohloh `_ -- `Evennia on OpenHatch `_ -- `Evennia on - PyPi `_ - -- `Avaloria `_ (MUD under - development, using Evennia) -- `Winter's Oasis `_ (MUCK under - development, using Evennia) -- `Latitude `_ (MUCK under - development, using Evennia) - -- `notimetoplay - post `_ - about Evennia - -General mud/game development ideas and discussions --------------------------------------------------- - -- `MudLab `_ mud design discussion forum -- `MudConnector `_ mud listing and forums -- `MudBytes `_ mud listing and forums -- `Top Mud Sites `_ 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 (including - Evennia) 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. -- `Mud-dev wiki `_ is a slowly growing - resource on MUD creation -- `Nick Gammon's hints - thread `_ - holds a very useful list of things to think about when starting your - new MUD. - -- `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) -- `The Alexandrian `_ is a blog about - tabletop roleplaying and board games, but with lots of general - discussion about rule systems and game balance that could be - applicable also for MUDs. - -Litterature ------------ - -- Richard Bartle *Designing Virtual Worlds* (`amazon - page `_) - - Essential reading for the design of any persistent game world, - written by the co-creator of the original game *MUD*. Discusses - basically everything you need to think about and more. -- Richard Cantillon *An Essay on Economic Theory* (`free - pdf `_) - - A very good English translation of *Essai sur la Nature du Commerce - en Général*, one of the foundations of modern economic theory. - Written in 1730 but the translation is annotated and is very easy to - follow for a modern reader. Required reading if you think of - implementing a sane game economic system. -- David M. Beazley *Python Essential Reference (4th ed)* (`amazon - page `_) - - Our recommended book on Python; it not only efficiently summarizes - the language but is also an excellent reference to the standard - library for more experienced Python coders. - -Frameworks ----------- - -- `Django's homepage `_ - - - `Documentation `_ - - `Code `_ - -- `Twisted homepage `_ - - - `Documentation `_ - - `Code `_ - -Tools ------ - -- `Mercurial tutorial `_ -- `Another, pretty funny, Mercurial tutorial `_ -- `Sphinx manual `_ (compile - documentation) -- `Doxygen `_ (build auto-docs) - -Python Info ------------ - -- `Python Website `_ - - - `Documentation `_ - - `Tutorial `_ - - `Library Reference `_ - - `Language Reference `_ - - diff --git a/docs/sphinx/source/wiki/Locks.rst b/docs/sphinx/source/wiki/Locks.rst deleted file mode 100644 index cd42c2ec1a..0000000000 --- a/docs/sphinx/source/wiki/Locks.rst +++ /dev/null @@ -1,498 +0,0 @@ -Locks -===== - -For most games it is a good idea to restrict what people can do. In -Evennia such restrictions are applied and checked by something called -*locks*. All Evennia entities (`commands `_, -`objects `_, `scripts `_, -`players `_, `help system `_, -[Communications#Msg messages] and [Communications#Channels channels]) -are accessed through locks. - -A lock can be thought of as an "access rule" restricting a particular -use of an Evennia entity. Whenever another entity wants that kind of -access the lock will analyze that entity in different ways to determine -if access should be granted or not. Evennia implements a "lockdown" -philosophy - all entities are inaccessible unless you explicitly define -a lock that allows some or full access. - -Let's take an example: An object has a lock on itself that restricts how -people may "delete" that object. Apart from knowing that it restricts -deletion, the lock also knows that only players with the specific ID of, -say, '34' are allowed to delete it. So whenever a player tries to run -@delete on the object, the @delete command makes sure to check if this -player is really allowed to do so. It calls the lock, which in turn -checks if the player's id is 34. Only then will it allow @delete to go -on with its job. - -Setting and checking a lock ---------------------------- - -The in-game command for setting locks on objects is ``@lock``: - -:: - - > @lock obj = - -The ```` is a string on a certain form that defines the -behaviour of the lock. We will go into more detail on how -```` should look in the next section. - -Code-wise, Evennia handles locks through what is usually called -``locks`` on all relevant entities. This is a handler that allows you to -add, delete and check locks. - -:: - - myobj.locks.add() - -One can call ``locks.check()`` to perform a lock check, but to hide the -underlying implementation all objects also have a convenience function -called ``access``. This should preferably be used. In the example below, -``accessing_obj`` is the object requesting the 'delete' access whereas -``obj`` is the object that might get deleted. This is how it would (and -do) look from inside the ``@delete`` command: - -:: - - if not obj.access(accessing_obj, 'delete'): - accessing_obj.msg("Sorry, you may not delete that.") - return - -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()``. - -Here are some examples of lock strings (not including the quotes): - -:: - - delete:id(34) # only allow obj #34 to delete - 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 - -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 lockstring 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 work as they do normally in -Python. If the total result is True, the lock is passed. - -You can create several lock types one after the other by separating them -with a semicolon (``;``) in the lockstring. The string below is -identical to the first two rows of the previous example: - -:: - - delete:id(34);edit:all() - -Valid access\_types -~~~~~~~~~~~~~~~~~~~ - -An ``access_type``, the first part of a lockstring, defines what kind of -capability a lock controls, such as "delete" or "edit". You may in -principle name your ``access_type`` anything as long as it is unique for -the particular object. Access\_types are not case-sensitive. - -If you want to make sure the lock is used however, you should pick -``access_type`` names that you (or the default command set) actually -tries, as in the example of ``@delete`` above that uses the 'delete' -``access_type``. - -Below are the access\_types checked by the default commandset. - -- `Commands `_: ``cmd`` - this defines who may call this - command at all. -- `Objects `_: - - - ``control`` - who is the "owner" of the object. Can set locks, - delete it etc. Defaults to the creator of the object. - - ``call`` - who may call object-commands on this object. - - ``examine`` - who may examine this object's properties. - - ``delete`` - who may delete the object. - - ``edit`` - who may edit properties and attributes of the object. - - ``get``- who may pick up the object and carry it around. - - ``puppet`` - who may "become" this object and control it as their - "character". - - ``attrcreate`` - who may create new attributes on the object - (default True) - -- [Objects#Characters Characters]: ```` -- [Objects#Exits Exits]: ```` + ``traverse`` - who may - pass the exit. -- `Players `_: - - - ``examine`` - who may examine the player's properties. - - ``delete`` - who may delete the player. - - ``edit`` - who may edit the player's attributes and properties. - - ``msg`` - who may send messages to the player. - - ``boot`` - who may boot the player. - -- `Attributes `_: (*only checked by - ``obj.secure_attr``*) - - - ``attrread`` - see/access attribute - - ``attredit`` - change/delete attribute - -- [Communications#Channels Channels]: - - - ``control`` - who is administrating the channel. This means the - ability to delete the channel, boot listeners etc. - - ``send`` - who may send to the channel. - - ``listen`` - who may subscribe and listen to the channel. - -- `HelpEntry `_: - - - ``examine`` - who may view this help entry (usually everyone) - - ``edit`` - who may edit this help entry. - -So to take an example, whenever an exit is to be traversed, a lock of -the type *traverse* will be checked. Defining a suitable lock type for -an exit object would thus involve a lockstring -``traverse: ``. - -Lock functions -~~~~~~~~~~~~~~ - -You are not allowed to use just any function in your lock definition; -you are infact only allowed to use those functions defined in one of the -modules given in ``settings.LOCK_FUNC_MODULES``. All functions in any of -those modules will automatically be considered a valid lock function. -The default ones are found in ``src/locks/lockfuncs.py`` or via -``ev.lockfuncs``. - -A lock function must always accept at least two arguments - the -*accessing object* (this is the object wanting to get access) and the -*accessed object* (this is the object with the lock). Those two are fed -automatically as the first two arguments the function when the lock is -checked. Any arguments explicitly given in the lock definition will -appear as extra arguments. - -:: - - # A simple example lock function. Called with e.g. id(34) - - def id(accessing_obj, accessed_obj, *args, **kwargs): - if args: - wanted_id = args[0] - return accessing_obj.id == wanted_id - return False - -(Using the ``*`` and ``**`` syntax causes Python to magically put all -extra arguments into a list ``args`` and all keyword arguments into a -dictionary ``kwargs`` respectively. If you are unfamiliar with how -``*args`` and ``**kwargs`` work, see the Python manuals). - -Some useful default lockfuncs (see ``src/locks/lockfuncs.py`` for more): - -- ``true()/all()`` - give access to everyone -- ``false()/none()/superuser()`` - give access to noone. Superusers - bypass the check entirely. -- ``perm(perm)`` - this tries to match a given ``permission`` property, - on a Player firsthand, on a Character second. See [Locks#Permissions - below]. -- ``perm_above(perm)`` - like ``perm`` but requires a "higher" - permission level than the one given. -- ``id(num)/dbref(num)`` - checks so the access\_object has a certain - dbref/id. -- ``attr(attrname)`` - checks if a certain - `Attribute `_ exists on accessing\_object. -- ``attr(attrname, value)`` - checks so an attribute exists on - accessing\_object *and* has the given value. -- ``attr_gt(attrname, value)`` - checks so accessing\_object has a - value larger (``>``) than the given value. -- ``attr_ge, attr_lt, attr_le, attr_ne`` - corresponding for ``>=``, - ``<``, ``<=`` and ``!=``. -- ``holds(objid)`` - checks so the accessing objects contains an object - of given name or dbref. -- ``pperm(perm)``, ``pid(num)/pdbref(num)`` - same as ``perm``, - ``id/dbref`` but always looks for permissions and dbrefs of - *Players*, not on Characters. - -Checking simple strings ------------------------ - -Sometimes you don't really need to look up a certain lock, you just want -to check a lockstring. A common use is inside Commands, in order to -check if a user has a certain permission. The lockhandler has a method -``check_lockstring(accessing_obj, lockstring, bypass_superuser=False)`` -that allows this. - -:: - - # inside command definition - if not self.caller.locks.check_lockstring(self.caller, "dummy:perm(Wizards)"): - self.caller.msg("You must be Wizard or higher to do this!" - return - -Note here that the ``access_type`` can be left to a dummy value since -this method does not actually do a Lock lookup. - -Default locks -------------- - -Evennia sets up a few basic locks on all new objects and players (if we -didn't, noone would have any access to anything from the start). This is -all defined in the root `Typeclasses `_ of the -respective entity, in the hook method ``basetype_setup()`` (which you -usually don't want to edit unless you want to change how basic stuff -like rooms and exits store their internal variables). This is called -once, before ``at_object_creation``, so just put them in the latter -method on your child object to change the default. Also creation -commands like ``@create`` changes the locks of objects you create - for -example it sets the ``control`` lock\_type so as to allow you, its -creator, to control and delete the object. - -Permissions -=========== - -A *permission* is simply a list of text strings stored on the property -``permissions`` on ``Objects`` and ``Players``. Permissions can be used -as a convenient way to structure access levels and hierarchies. It is -set by the ``@perm`` command. - -:: - - @perm *Tommy = Builders - -Note the use of the asterisk ``*`` above. For the ``@perm`` command it -means assigning to the `Player `_ Tommy instead of any -`Character `_ that also happens to be named Tommy. Putting -permissions on the Player guarantees that they are kept regardless of -which Character they are currently puppeting. - -All new players are given a default set of permissions defined by -``settings.PERMISSION_PLAYER_DEFAULT``. - -Selected permission strings can be organized in a *permission hierarchy* -by editing the tuple ``settings.PERMISSION_HIERARCHY``. Evennia's -default permission hierarchy is as follows: - -:: - - Immortals - Wizards - Builders - PlayerHelpers - Players # this is what all new Players start with by default - -The main use of this is that if you use the lock function ``perm()`` -mentioned above, a lock check for a particular permission in the -hierarchy will *also* grant access to those with *higher* hierarchy -access. So if you have the permission "Wizards" you will also pass a -lock defined as ``perm(Builders)`` or any of those levels below -"Wizards". When doing an access check from an `Object `_ -or Character, the ``perm()`` lock function will always first use the -permissions of any Player connected to that Object before checking for -permissions on the Object. In the case of hierarchical permissions -(Wizards, Builders etc), the Player permission will always be used (this -stops a Player from escalating their permission by puppeting a -high-level Character). If the permission looked for is not in the -hierarchy, an exact match is required, first on the Player and if not -found there (or if no Player is connected), then on the Object itself. - -Below is an example of an object without any connected player - -:: - - obj1.permissions = ["Builders", "cool_guy"] - obj2.locks.add("enter:perm_above(Players) and perm(cool_guy)") - - obj2.access(obj1, "enter") # this returns True! - -And one example of a puppet with a connected player: - -:: - - player.permissions = ["Players"] - puppet.permissions = ["Builders", "cool_guy"] - obj2.locks.add("enter:perm_above(Players) and perm(cool_guy)") - - obj2.access(puppet, "enter") # this returns False! - -Superusers ----------- - -There is normally only one *superuser* account and that is the one first -created when starting Evennia (User #1). This is sometimes known as the -"Owner" or "God" user. A superuser has more than full access - it -completely *bypasses* all locks so no checks are even run. This allows -for the superuser to always have access to everything in an emergency. -But it also hides any eventual errors you might have made in your lock -definitions. So when trying out game systems you should use a secondary -character rather than #1 so your locks get tested correctly. - -Quelling --------- - -The ``@quell`` command can be used to enforce the ``perm()`` lockfunc to -ignore permissions on the Player and instead use the permissions on the -Character only. This can be used e.g. by staff to test out things with a -lower permission level. Return to the normal operation with -``@unquell``. Note that quelling will use the smallest of any -hierarchical permission on the Player or Character, so one cannot -escalate one's Player permission by quelling to a high-permission -Character. Also, the superuser cannot be quelled. - -More Lock definition examples -============================= - -:: - - examine: attr(eyesight, excellent) or perm(Builders) - -You are only allowed to do *examine* on this object if you have -'excellent' eyesight or is a Builder. - -:: - - # lock for the tell command - cmd: not perm(no_tell) - -Locks can be used to implement highly specific bans. This will allow -everyone *not* having the "permission" ``no_tell`` to use the ``tell`` -command. Just give a player the "permission" ``no_tell`` to disable -their use of this particular command henceforth. - -:: - - open: holds('the green key') or perm(Builder) - -This could be called by the ``open`` command on a "door" object. The -check is passed if you are a Builder or has the right key in your -inventory. - -:: - - # this limits what commands are visible to the user - cmd: perm(Builders) - -Evennia's command handler looks for a lock of type ``cmd`` to determine -if a user is allowed to even call upon a particular command or not. When -you define a command, this is the kind of lock you must set. See the -default command set for lots of examples. - -:: - - dbref = caller.id - lockstring = "control:id(%s);examine:perm(Builders);delete:id(%s) or perm(Wizards);get:all()" % (dbref, dbref) - new_obj.locks.add(lockstring) - -This is how the ``@create`` command sets up new objects. In sequence, -this permission string sets the owner of this object be the creator (the -one running ``@create``). Builders may examine the object whereas only -Wizards and the creator may delete it. Everyone can pick it up. - -A complete example of setting locks on an object -================================================ - -Assume we have two objects - one is ourselves (not superuser) and the -other is an `Object `_ called ``box``. - -:: - - > @create/drop box - > @desc box = "This is a very big and heavy box." - -We want to limit which objects can pick up this heavy box. Let's say -that to do that we require the would-be lifter to to have an attribute -*strength* on themselves, with a value greater than 50. We assign it to -ourselves to begin with. - -:: - - > @set self/strength = 45 - -Ok, so for testing we made ourselves strong, but not strong enough. Now -we need to look at what happens when someone tries to pick up the the -box - they use the ``get`` command (in the default set). This is defined -in ``game/gamesrc/commands/default/general.py``. In its code we find -this snippet: - -:: - - if not obj.access(caller, 'get'): - if obj.db.get_err_msg: - caller.msg(obj.db.get_err_msg) - else: - caller.msg("You can't get that.") - return - -So the ``get`` command looks for a lock with the type *get* (not so -surprising). It also looks for an `Attribute `_ on the -checked object called *get\_err\_msg* in order to return a customized -error message. Sounds good! Let's start by setting that on the box: - -:: - - > @set box/get_err_msg = You are not strong enough to lift this box. - -Next we need to craft a Lock of type *get* on our box. We want it to -only be passed if the accessing object has the attribute *strength* of -the right value. For this we would need to create a lock function that -checks if attributes have a value greater than a given value. Luckily -there is already such a one included in evennia (see -``src/permissions/lockfuncs.py``), called ``attr_gt``. - -So the lock string will look like this: ``get:attr_gt(strength, 50)``. -We put this on the box now: - -:: - - @lock box = get:attr_gt(strength, 50) - -Try to ``get`` the object and you should get the message that we are not -strong enough. Increase your strength above 50 however and you'll pick -it up no problem. Done! A very heavy box! - -If you wanted to set this up in python code, it would look something -like this: - -:: - - from ev import create_object - - box = create_object(None, key="box") - box.locks.add("get:attr_gt(strength, 50)") - - # or we can assign locks right away - box = create_object(None, key="box", locks="get:attr_gt(strength, 50)") - - # set the attributes - box.db.desc = "This is a very big and heavy box." - box.db.get_err_msg = "You are not strong enough to lift this box." - - # one heavy box, ready to withstand all but the strongest... - -On Django's permission system -============================= - -Django also implements a comprehensive permission/security system of its -own. The reason we don't use that is because it is app-centric (app in -the Django sense). Its permission strings are of the form -``appname.permstring`` and it automatically adds three of them for each -database model in the app - for the app src/object this would be for -example 'object.create', 'object.admin' and 'object.edit'. This makes a -lot of sense for a web application, not so much for a MUD, especially -when we try to hide away as much of the underlying architecture as -possible. - -The django permissions are not completely gone however. We use it for -logging in users (the ``User`` object tied to `Players `_ -is a part of Djangos's auth system). It is also used exclusively for -managing Evennia's web-based admin site, which is a graphical front-end -for the database of Evennia. You edit and assign such permissions -directly from the web interface. It's stand-alone from the permissions -described above. diff --git a/docs/sphinx/source/wiki/Nicks.rst b/docs/sphinx/source/wiki/Nicks.rst deleted file mode 100644 index b934f2d59c..0000000000 --- a/docs/sphinx/source/wiki/Nicks.rst +++ /dev/null @@ -1,110 +0,0 @@ -Nicks -===== - -*Nicks*, short for *Nicknames* is a system allowing an object (usually a -`Player Character `_) to assign custom replacement names -for other game entities. - -Nicks are not to be confused with *Aliases*. Setting an Alias on a game -entity actually changes an inherent attribute on that entity, and -everyone in the game will be able to use that alias to address the -entity thereafter. A *Nick* on the other hand, is an alternate name *you -alone* can use to refer to that entity. The nicknamed entitity is not -changed in any way. The principle is very simple - Evennia simply scans -your input looking for a defined nick and replaces it with the full, -"real" name before passing it on. In the default system nicks are -controlled with the simple ``nick`` command, but the system can be -expanded for other uses too. - -Default Evennia use Nicks in three flavours that determine when Evennia -actually tries to do the substitution. - -- inputline - replacement is attempted whenever you write anything on - the command line. This is the default. -- objects - replacement is only attempted when referring an object -- players - replacement is only attempted when referring a player - -Here's how to use it in the default command set (using the ``nick`` -command): - -:: - - nick ls = look - -This is a good one for unix/linux users who are accustomed to using the -``ls`` command in their daily life. It is equivalent to -``nick/inputline ls = look``. - -:: - - nick/object mycar2 = The red sports car - -With this example, substitutions will only be done specifically for -commands expecting an object reference, such as - -:: - - look mycar2 - -becomes equivalent to "``look The red sports car``\ ". - -:: - - nick/players tom = Thomas Johnsson - -This is useful for commands searching for players explicitly: - -:: - - @find *tom - -One can use nicks to speed up input. Below we add ourselves a quicker -way to build red buttons. In the future just writing *rb* will be enough -to execute that whole long string. - -:: - - nick rb = @create button:examples.red_button.RedButton - -Nicks could also be used as the start for building a "recog" system -suitable for an RP mud. - -:: - - nick/player Arnold = The mysterious hooded man - -Coding with nicks ------------------ - -Nicks are are stored as the ``Nick`` database model and are referred -from the normal Evennia `object `_ through the ``nicks`` -property - this is known as the NickHandler. The NickHandler offers -effective error checking, searches and conversion. - -:: - - # A command/channel nick: - object.nicks.add("greetjack", "tell Jack = Hello pal!") - - # An object nick: - obj.nicks.add("rose", "The red flower", nick_type="object") - - # An player nick: - obj.nicks.add("tom", "Tommy Hill", nick_type="player") - - # My own custom nick type (handled by my own game code somehow): - obj.nicks.add("hood", "The hooded man", nick_type="my_identsystem") - - # get back the translated nick: - full_name = obj.nicks.get("rose", nick_type="object") - - # delete a previous set nick - object.nicks.del("rose", nick_type="object") - -In a command definition you can reach the nick handler through -``self.caller.nicks``. See the ``nick`` command in -``game/gamesrc/commands/default/general.py`` for more examples. - -As a last note, The Evennia `channel `_ alias -systems are using nicks with the ``nick_type="channel"`` in order to -allow users to create their own custom aliases to channels. diff --git a/docs/sphinx/source/wiki/Objects.rst b/docs/sphinx/source/wiki/Objects.rst deleted file mode 100644 index 99434579d9..0000000000 --- a/docs/sphinx/source/wiki/Objects.rst +++ /dev/null @@ -1,45 +0,0 @@ -Objects -======= - -All in-game objects in Evennia, be it characters, chairs, monsters, -rooms or hand grenades are represented by an Evennia *Object*. Objects -form the core of Evennia and is probably what you'll spend most time -working with. Objects are `TypeClassed `_ entities. - -How to create your own object types ------------------------------------ - -An Evennia Object is, per definition, a Python class that includes -``src.objects.objects.Object`` among its parents (if you are aware of -how typeclasses work, this is a typeclass linked to the ``ObjectDB`` -database model). In your code you can however conveniently refer to -``ev.Object`` instead. - -Here's how to define a new Object typeclass in code: - -:: - - from ev import Object - - class Rose(Object): - """ - This creates a simple rose object - """ - def at_object_creation(self): - "this is called only once, when object is first created" - # add a persistent attribute 'desc' to object (this is pretty silly). - self.db.desc = "This is a pretty rose with thorns." - -Save your class to a module under ``game/gamesrc/objects``, say -``flowers.py``. Now you just need to point to the class *Rose* with the -``@create`` command to make a new rose: - -:: - - > @create/drop MyRose:flowers.Rose - -What the ``@create`` command actually *does* is to use -``ev.create_object`` (a shortcut to -src.utils.create.create\_object()\ ``): {{{ from ev import create_object new_rose = create_object("game.gamesrc.objects.flowers.Rose", key="MyRose") }}} (The ``\ @create\ `` command will auto-append the most likely path to your typeclass, if you enter the call manually you have to give the full path to the class. The ``\ create.create\_object\ `` function is powerful and should be used for all coded object creating (so this is what you use when definig your own building commands). Check out the ``\ ev.create\_\ **`` functions for how to build other entities like [Scripts]). This particular Rose class doesn't really do much, all it does it make sure the attribute ``\ desc\ ``(which is what the ``\ look\ `` command looks for) is pre-set, which is pretty pointless since you will usually want to change this at build time (using the ``\ @desc\ `` command). The ``\ Object\ `` typeclass offers many more hooks that is available to use though - see next section. If you define a new Object class (inheriting from the base one), and wants the default create command (``\ @create\ ``) to default to that instead, set ``\ BASE\_OBJECT\_TYPECLASS\ `` in ``\ settings.py\ `` to point to your new class. == Properties and functions on Objects == Beyond those properties assigned to all [Typeclasses typeclassed] objects, the Object also has the following custom properties: * ``\ aliases\ `` - a list of alternative names for the object. Aliases are stored in the database and can be searched for very fast. The ``\ aliases\ `` property receives and returns lists - so assign to it like normal, e.g. ``\ obj.aliases=['flower', -'red -blossom']\ `` * ``\ location\ `` - a reference to the object currently containing this object. * ``\ home\ `` is a backup location. The main motivation is to have a safe place to move the object to if its ``\ location\ `` is destroyed. All objects should usually have a home location for safety. * ``\ destination\ `` - this holds a reference to another object this object links to in some way. Its main use is for [Objects#Exits Exits], it's otherwise usually unset. * ``\ nicks\ `` - as opposed to aliases, a [Nicks Nick] holds a convenient nickname replacement for a real name, word or sequence, only valid for this object. This mainly makes sense if the Object is used as a game character - it can then store briefer shorts, example so as to quickly reference game commands or other characters. Nicks are stored in the database and are a bit more complex than aliases since they have a _type_ that defines where Evennia tries to do the substituion. In code, use nicks.get(alias, type) to get a nick, or nicks.add(alias, realname) to add a new one. * ``\ player\ `` - this holds a reference to a connected [Players Player] controlling this object (if any). Note that this is set also if the controlling player is _not_ currently online - to test if a player is online, use the ``\ has\_player\ `` property instead. * ``\ sessions\ `` - if ``\ player\ `` field is set _and the player is online_, this is a list of all active sessions (server connections) to contact them through (it may be more than one if multiple connections are allowed in settings). * ``\ permissions\ `` - a list of [Locks permission strings] for defining access rights for this Object. * ``\ has\_player\ `` - a shorthand for checking if an _online_ player is currently connected to this object. * ``\ contents\ `` - this returns a list referencing all objects 'inside' this object (i,e. which has this object set as their ``\ location\ ``). * ``\ exits\ `` - this returns all objects inside this object that are _Exits_, that is, has the ``\ destination\ `` property set. The last two properties are special: * ``\ cmdset\ `` - this is a handler that stores all [Commands#Command_Sets command sets] defined on the object (if any). * ``\ scripts\ `` - this is a handler that manages [Scripts scripts] attached to the object (if any). The Object also has a host of useful utility functions. See the function headers in ``\ src/objects/objects.py\ `` for their arguments and more details. * ``\ msg()\ `` - this function is used to send messages from the server to a player connected to this object. * ``\ msg\_contents()\ `` - calls ``\ msg\ `` on all objects inside this object. * ``\ search()\ `` - this is a convenient shorthand to search for a specific object, at a given location or globally. It's mainly useful when defining commands (in which case the object executing the command is named ``\ caller\ `` and one can do ``\ caller.search()\ `` to find objects in the room to operate on). * ``\ execute\_cmd()\ `` - Lets the object execute the given string as if it was given on the command line. * ``\ move\_to\ `` - perform a full move of this object to a new location. This is the main move method and will call all relevant hooks, do all checks etc. * ``\ clear\_exits()\ `` - will delete all [Objects#Exits Exits] to _and_ from this object. * ``\ clear\_contents()\ `` - this will not delete anything, but rather move all contents (except Exits) to their designated ``\ Home\ `` locations. * ``\ delete()\ `` - deletes this object, first calling ``\ clear\_exits()\ `` and ``\ clear\_contents()\ ``. The Object Typeclass defines many more _hook methods_ beyond ``\ at\_object\_creation\ ``. Evennia calls these hooks at various points. When implementing your custom objects, you will inherit from the base parent and overload these hooks with your own custom code. See ``\ src.objects.objects\ `` for an updated list of all the available hooks. == Subclasses of _Object_ == There are three special subclasses of _Object_ in default Evennia - _Characters_, _Rooms_ and _Exits_. The reason they are separated is because these particular object types are fundamental, something you will always need and in some cases requires some extra attention in order to be recognized by the game engine (there is nothing stopping you from redefining them though). In practice they are all pretty similar to the base Object. === Characters === Characters are objects controlled by [Players]. When a new Player logs in to Evennia for the first time, a new ``\ Character\ `` object is created and the Player object is assigned to the ``\ player\ `` attribute. A ``\ Character\ `` object must have a [Commands#Command_Sets Default Commandset] set on itself at creation, or the player will not be able to issue any commands! If you just inherit your own class from ``\ ev.Character\ `` and make sure the parent methods are not stopped from running you should not have to worry about this. You can change the default typeclass assigned to new Players in your settings with ``\ BASE\_CHARACTER\_TYPECLASS\ ``. === Rooms === _Rooms_ are the root containers of all other objects. The only thing really separating a room from any other object is that they have no ``\ location\ `` of their own and that default commands like ``\ @dig\ `` creates objects of this class - so if you want to expand your rooms with more functionality, just inherit from ``\ ev.Room\ ``. Change the default used by ``\ @dig\ `` with ``\ BASE\_ROOM\_TYPECLASS\ ``. === Exits === _Exits_ are objects connecting other objects (usually _Rooms_) together. An object named _North_ or _in_ might be an exit, as well as _door_, _portal_ or _jump out the window_. An exit has two things that separate them from other objects. Firstly, their _destination_ property is set and points to a valid object. This fact makes it easy and fast to locate exits in the database. Secondly, exits define a special [Commands Transit Command] on themselves when they are created. This command is named the same as the exit object and will, when called, handle the practicalities of moving the character to the Exits's _destination_ - this allows you to just enter the name of the exit on its own to move around, just as you would expect. The exit functionality is all defined on the Exit typeclass, so you could in principle completely change how exits work in your game (it's not recommended though, unless you really know what you are doing). Exits are [Locks locked] using an access_type called _traverse_ and also make use of a few hook methods for giving feedback if the traversal fails. See ``\ ev.Exit\ `` for more info, that is also what you should inherit from to make custom exit types. Change the default class used by e.g. ``\ @dig\ `` and ``\ @open\ `` by editing ``\ BASE\_EXIT\_TYPECLASS\ `` in your settings. == Further notes == For a more advanced example of a customized object class, see ``\ game/gamesrc/objects/examples/red\_button.py\ ````.** diff --git a/docs/sphinx/source/wiki/OnlineSetup.rst b/docs/sphinx/source/wiki/OnlineSetup.rst deleted file mode 100644 index 2c6e85abe6..0000000000 --- a/docs/sphinx/source/wiki/OnlineSetup.rst +++ /dev/null @@ -1,199 +0,0 @@ -Making your game available online -================================= - -Evennia development can be made also without any internet connection -(except to download updates). At some point however, you are likely to -want to make your game visible online, either as part of making it -public or to allow other developers or beta testers access to it. - -Using your own computer as a server ------------------------------------ - -By far the simplest and probably cheapest option. Evennia will run on -your own, home computer. Moreover, since Evennia is its own web server, -you don't need to install anything extra to also run its website. - -**Advantages** - -- Free (except for internet cost and electrical bill) -- Full control over the server/hardware (it sits right there!) -- Easy to set up. -- Also suitable for quick setups - e.g. to briefly show off results to - your collaborators. - -**Disadvantages** - -- You need a good internet connection, ideally without any - upload/download limits/costs. -- If you want to run a full game this way, your computer needs to - always be on. It could be noisy, and as mentioned, the electrical - bill is worth considering. -- No support or safety - if your house burns down, so will your game. - Also, you are yourself responsible for backups etc (some would - consider this an advantage). -- Home IP numbers are often dynamically allocated, so for permanent - online time you need to set up a DNS to always re-point to the right - place (see below). - -Set up your own machine as a server -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Making Evennia available from your own machine is mainly a matter of -configuring eventual firewalls to let Evennia's ports through. With -Evennia running, note which ports it is using (defaults are 4000 for -telnet and 8000 for webclient, we assume them below). - -#. Go to `http://www.whatismyip.com/ `_ (or - similar site). They should tell you which IP address you are - connecting from, e.g. ``230.450.0.222``. -#. In your web browser, go to ``http://230.450.0.222:8000``, where the - last ``:8000`` is the webclient port Evennia uses. If you see - Evennia's website and can connect to the webclient - -congrats, - that's it! Try to connect with a traditional MUD-client to the telnet - port too, just to make sure. -#. Most likely you won't see the Evennia website right away though. This - is probably because you have a firewall blocking the ports we need. - There could also be a hardware-router between your computer and the - Internet - in that case the IP address we see "from the outside" is - actually the router's IP, not that of your computer on your local - network. - - - You need to let Evennia data out through your router/firewall. How - you do that varies with manufacturer and software. But in - principle you should look for something called "Port forwarding" - or similar. You want to route port 8000/4000 from your computer to - an "outgoing port" that the world can see. That latter port does - *not* have to have the same number as the internal port! For - example, you might want to connect port 8000 to an outgoing port - 80 - this is the port HTTP requests use and web browsers - automatically look for. If you use port 80 you won't have to - specify the port number in the url of your browser. If you run - other web servers on your machine, that could be an issue though. - - I found that I had to reboot my router for this to take effect, so - worth trying if you still cannot get to the Evennia website - through your browser. - -#. At this point you should be able to invite people to play your game - on ``http://230.450.0.222:8000`` or via telnet to ``230.450.0.222`` - on port ``4000``. - -A complication with using a specific IP address like this is that your -home IP might not remain the same. Many ISPs (Internet Service -Providers) allocates a dynamic IP to you which could change at any time. -When that happens, that IP you told people to go to will be worthless. -Also, that long string of numbers is not very pretty, is it? It's hard -to remember and not easy to use in marketing your game. What you need is -to alias it to a more sensible domain name - an alias that follows you -around also when the IP changes. - -#. To set up a domain name alias, we recommend starting with a free - domain name from `FreeDNS `_. Once you - register there (it's free) you have access to tens of thousands - domain names that people have "donated" to allow you to use for your - own sub domain. For example, ``strangled.net`` is one of those - available domains. So tying our IP address to ``strangled.net`` using - the subdomain ``evennia`` would mean that one could henceforth direct - people to - `http://evennia.strangled.net:8000 `_ - for their gaming needs - far easier to remember! -#. So how do we make this new, nice domain name follow us also if our IP - changes? For this we need to set up a little program on our computer. - It will check whenever our ISP decides to change our IP and tell - FreeDNS that. There are many alternatives to be found from FreeDNS:s - homepage, one that works on multiple platforms is - `inadyn `_. Get it from their page or, - in Linux, through something like - -:: - - apt-get install inadyn - -#. Next, you login to your account on FreeDNS and go to the - `Dynamic `_ page. You should have - a list of your subdomains. Click the ``Direct URL`` link and you'll - get a page with a text message. Ignore that and look at the URL of - the page. It should be ending in a lot of random letters. Everything - after the question mark is your unique "hash". Copy this string. -#. You now start inadyn with the following command (Linux): - -:: - - inadyn --dyndns_system default@freedns.afraid.org -a , & - - where ```` would be ``evennia.strangled.net`` and - ```` the string of numbers we copied from FreeDNS. The ``&`` - means we run in the background (might not be valid in other - operating systems). ``inadyn`` will henceforth check for changes - every 60 seconds. You should put the ``inadyn`` command string in a - startup script somewhere so it kicks into gear whenever your - computer starts. - -Remote hosting --------------- - -Your normal "web hotel" will probably not be enough to run Evennia. A -web hotel is normally aimed at a very specific usage - delivering web -pages, at the most with some dynamic content. The "Python scripts" they -refer to on their home pages are usually only intended to be CGI-like -scripts launched by their webserver. Even if they allow you shell access -(so you can install the Evennia dependencies in the first place), -resource usage will likely be very restricted. Running a full-fledged -game server like Evennia will probably be shunned upon or be outright -impossible. If you are unsure, contact your web hotel and ask about -their policy on you running third-party servers that will want to open -custom ports. - -The options you probably need to look for are *shell account services* -or *VPS:es*. A "Shell account" service means that you get a shell -account on a server and can log in like any normal user. By contrast, a -*VPS* (Virtual Private Server) service usually means that you get -``root`` access, but in a virtual machine. - -**Advantages** - -- Shell accounts/VPS offer more flexibility than your average web hotel - - it's the ability to log onto a shared computer away from home. -- Usually runs a Linux flavor, making it easy to install Evennia. -- Support. You don't need to maintain the server hardware. If your - house burns down, at least your game stays online. Many services - guarantee a certain level of up-time and might also do regular - backups for you (this varies). -- Gives a fixed domain name, so no need to mess with IP addresses. - -**Disadvantages** - -- Might be pretty expensive (more so than a web hotel) -- Linux flavors might feel unfamiliar to users not used to ssh/PuTTy - and the Linux command line. -- You are probably sharing the server with many others, so you are not - completely in charge. CPU usage might be limited. Also, if the server - people decides to take the server down for maintenance, you have no - choice but to sit it out (but you'll hopefully be warned ahead of - time). - -Set up Evennia on a remote shell account/VPS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Assuming you know how to connect to your account over ssh/PuTTy you -should be able to follow the `Getting Started `_ -instructions normally. Ports might be an issue, so make sure you know -which ports are available to use. - -If you don't have root access in a virtual machine (but just a normal -user-shell account), you will probably *not* have all resources easily -available. You need root to use ``apt-get`` for example. In that case -you should be able set up a virtualenv install instead, see the last -section of `Getting Started `_ for more info. - -To find commercial solutions, just scour the web for shell access/VPS in -your region. One user has for example reported some success with -`Webfaction `_. - -Worth checking out is a free hosting offer especially aimed at MUDs -`here `_. An account and some activity -at `MUDbytes `_ is required (that's a good -forum to join anyway if you are interested in MUDs). On this -mud-specific server you can reserve ports to use as well. From their -page it's however unclear which resources are available (only gcc is -listed), so one probably needs to use a virtualenv setup to get all -dependencies. diff --git a/docs/sphinx/source/wiki/Players.rst b/docs/sphinx/source/wiki/Players.rst deleted file mode 100644 index 055ec17106..0000000000 --- a/docs/sphinx/source/wiki/Players.rst +++ /dev/null @@ -1,130 +0,0 @@ -Players -======= - -All *gamers* (real people) that opens a game `Session `_ -on Evennia are doing so through an object called *Player*. The Player -object has no in-game representation, it represents the account the -gamer has on the game. In order to actually get on the game the Player -must *puppet* an `Object `_ (normally a Character). - -Just how this works depends on the configuration option -``MULTISESSION_MODE``. There are three multisession modes, described in -the diagram below: - -|image0| - -From left to right, these show ``MULTISESSION_MODE`` 0, 1 and 2. In all -cases the gamer connects to the `Portal `_ with -one or more sessions - this could be a telnet connection, webclient, ssh -or some of the other protocols Evennia supports. - -- In mode 0 (leftmost), each Player can only hold one session at a - time. This is the normal mode for many legacy muds. -- In mode 1 (middle), each Player can hold any number of sessions but - they are all treated equal. This means all giving a command in one - client is doing exactly the same thing as doing so in any other - connected client. All sessions will see the same output and e.g. - giving the @quit command will kill all sessions. -- In mode 2 (right) each Player can hold any number of sessions and - they are kept separate from one another. This allows a single player - to puppet any number of Characters and Objects. - -Apart from storing login information and other account-specific data, -the Player object is what is chatting on -`Channels `_. It is also a good place to store -`Permissions `_ to be consistent between different in-game -characters as well as configuration options. Players are -`TypeClassed `_ entities defaulting to use -``settings.BASE_PLAYER_TYPECLASS``. They also hold a -`CmdSet `_ defaulting to the set defined by -``settings.CMDSET_PLAYER``. - -Logged into default Evennia, you can use the ``@ooc`` command to leave -your current `Character `_ and go into OOC mode. You are -quite limited in this mode, basically it works like a simple chat -program. It acts as a staging area for switching between Characters (if -your game supports that) or as a safety mode if your Character gets -deleted. Use ``@ic`` to attempt to puppet a Character. - -Note that the Player object can and often do have a different set of -[Locks#Permissions Permissions] from the Character they control. -Normally you should put your permissions on the Player level - this will -overrule permissions set on the Character level (unless ``@quell``-ing -is used). - -How to create your own Player types ------------------------------------ - -You will usually not want more than one Player typeclass for all new -players (but you could in principle create a system that changes a -player's typeclass dynamically). - -An Evennia Player is, per definition, a Python class that includes -``src.players.player.Player`` among its parents (if you are aware of how -`Typeclasses `_ work, this is a typeclass linked to -the ``PlayerDB`` database model). You can also inherit from -``ev.Player`` which is a shortcut. - -Here's how to define a new Player typeclass in code: - -:: - - from ev import Player - class ConfigPlayer(Player): - """ - This creates a Player with some configuration options - """ - at_player_creation(self): - "this is called only once, when player is first created" - self.db.real_name = None # this is set later - self.db.real_address = None # " - self.db.config_1 = True # default config - self.db.config_2 = False # " - self.db.config_3 = 1 # " - # ... whatever else our game needs to know - -There is no pre-made folder in ``game/gamesrc`` to store custom player -typeclasses. Make your own folder or store it in ``gamesrc/objects`` -(remember that if you make your own folder you need to add an empty -``__init__.py`` file so that you can import the file later). To change -which object becomes the Player object for new players, set the variable -``BASE_PLAYER_TYPECLASS`` in your ``settings.py`` file. - -Properties on Players ---------------------- - -Beyond those properties assigned to all typeclassed objects (see -`Typeclasses `_), the Player also has the following -custom properties: - -- ``user`` - a unique link to a ``User`` Django object, representing - the logged-in user. -- ``obj`` - an alias for ``character``. -- ``name`` - an alias for ``user.username`` -- ``sessions`` - a list of all connected Sessions (physical - connections) this object listens to. The so-called session-id (used - in many places) is found as a property ``sessid`` on each Session - instance. -- ``is_superuser`` (bool: True/False) - if this player is a superuser. - -Special handlers: - -- ``cmdset`` - This holds all the current `Commands `_ - of this Player. By default these are the commands found in the cmdset - defined by ``settings.CMDSET_PLAYER``. -- ``nicks`` - This stores and handles `Nicks `_, in the - same way as nicks it works on Objects. For Players, nicks are - primarily used to store custom aliases for [Communications#Channels - Channels]. - -Selection of special methods (see ``src.player.models`` for details): - -- ``get_puppet`` - get a currently puppeted object connected to the - Player and a given given session id, if any. -- ``puppet_object`` - connect a session to a puppetable Object. -- ``unpuppet_object`` - disconnect a session from a puppetable Object. -- ``msg`` - send text to the Player -- ``execute_cmd`` - runs a command as if this Player did it. -- ``search`` - search for Players. - -.. |image0| image:: https://lh5.googleusercontent.com/-9XuiTr2UAbo/UZDxNLFUobI/AAAAAAAAB3I/1wArg9P-KnQ/w898-h293-no/evennia_player_sessions2.png diff --git a/docs/sphinx/source/wiki/PortalAndServer.rst b/docs/sphinx/source/wiki/PortalAndServer.rst deleted file mode 100644 index 39c44f781e..0000000000 --- a/docs/sphinx/source/wiki/PortalAndServer.rst +++ /dev/null @@ -1,69 +0,0 @@ -Portal and Server layout -======================== - -Evennia consists of two processes, known as *Portal* and *Server*. They -can be controlled from inside the game or from the command line as -described `here `_. - -If you are new to the concept, the main purpose of separating the two is -to have players connect to the Portal but keep the MUD running on the -Server. This way one can restart/reload the game (the Server part) -without Players getting disconnected. - -|image0| - -The Server and Portal are glued together via an AMP (Asynchronous -Messaging Protocol) connection. This allows the two programs to -communicate seamlessly. - -Portal and Server Sessions --------------------------- - -*note: This is not really necessary to understand if you are new to -Evennia.* - -New Player connections are listened for and handled by the Portal using -the `protocols `_ it understands (such as telnet, -ssh, webclient etc). When a new connection is established, a *Portal -Session* is created on the Portal side. This session object looks -different depending on which protocol is used to connect, but all still -have a minimum set of attributes that are generic to all sessions. - -These common properties are piped from the Portal, through AMP, to the -*Server*, which is now informed a new connection has been established. -On the Server side, a *Server Session* object is created to represent -this. There is only one type of Server Session. It looks the same -regardless of how the Player connects. - -From now on, there is a one-to-one match between the Server Session on -one side of the AMP connection and the Portal Session on the other. Data -arriving to the Portal Session is sent on to its mirror Server session -and vice versa. - -During certain situations, the portal- and server-side sessions are -"synced" with each other: - -- The Player closes their client, killing the Portal Session. The - Portal syncs with the Server to make sure the corresponding Server - Session is also deleted. -- The Player quits from inside the game, killing the Server Session. - The Server then syncs with the Portal to make sure to close the - Portal connection cleanly. -- The Server is rebooted/reset/shutdown - The Server Sessions are - copied over ("saved") to the Portal side. When the Server comes back - up, this data is returned by the Portal so the two are again in sync. - This way a Player's login status and other connection-critical things - can survive a server reboot (assuming the Portal is not stopped at - the same time, obviously). - -Sessionhandlers ---------------- - -Both the Portal and Server each have a *sessionhandler* to manage the -connections. These handlers contain all methods for relaying data across -the AMP bridge. All types of Sessions hold a reference to their -respective Sessionhandler (the property is called ``sessionhandler``) so -they can relay data. See `protocols `_ for more -info on building new protocols. - -.. |image0| image:: https://2498159658166209538-a-1802744773732722657-s-sites.googlegroups.com/site/evenniaserver/file-cabinet/evennia_server_portal.png diff --git a/docs/sphinx/source/wiki/Quirks.rst b/docs/sphinx/source/wiki/Quirks.rst deleted file mode 100644 index d2a31f3e47..0000000000 --- a/docs/sphinx/source/wiki/Quirks.rst +++ /dev/null @@ -1,114 +0,0 @@ -Evennia Quirks -============== - -This is a list of various problems or stumbling blocks that people often -ask about or report when using (or trying to use) Evennia. These are -common stumbling blocks, non-intuitive behaviour and common newbie -mistakes when working with Evennia. They are not Evennia bugs. - -Actual Evennia bugs should be reported in -`Issues `_. - -Editing code directly in \`src/\` ---------------------------------- - -Don't do this. Doing local changes to ``src`` will eventually conflict -with changes done by the Evennia developers. Rather you should import -``src``-modules into your own custom modules in ``game/gamesrc`` (or -copy&paste them over if you want to expand on the defaults). Next you -re-point the relevant links in your ``settings`` file to point to your -custom modules instead of the default ones. - -If you want to expand the web interface, copy the entire ``src/web`` -folder over to ``game/gamesrc`` and change the media links in your -``settings`` file. - -If you find that ``src`` lacks some functionality you need, make an -`Issue `_ of the type -*Feature Request*. Or become a part of the Evennia development and -submit your own additions to the core. - -Create typeclassed object by calling the typeclass --------------------------------------------------- - -Alas, you cannot create a new Typeclass by just initializing the -classname. So ``obj = Object()`` won't do what you want. Whereas -Evennia's Typeclasses behave *pretty much* like normal Python classes, -this is one of the situations where they don't. You need to use -Evennia's create functions to add new objects. So use e.g. -``ev.create_object()``, ``ev.create_script()`` etc. (these are defined -in ``src/utils/create.py``). This will set up the Typeclass database -connection behind the scenes. - -In the same vein, you cannot overload ``__init__()``, ``__setattr__`` or -``__getattribute__`` on Typeclasses. Use the hook methods -(``at_object_creation()`` etc) instead. - -Web admin to create new Player ------------------------------- - -If you use the default login system and is trying to use the Web admin -to create a new Player account, you need to consider which -MULTIPLAYER\_MODE you are in. If you are in MULTIPLAYER\_MODE 0 or 1, -the login system expects each Player to also have a Character object -named the same as the Player - there is no character creation screen by -default. If using the normal mud login screen, a Character with the same -name is automatically created and connected to your Player. From the web -interface you must do this manually. - -So, when creating the Player, make sure to also create the Character -*from the same form* as you create the Player from. This should set -everything up for you. Otherwise you need to manually set the "player" -property on the Character and the "character" property on the Player to -point to each other. You must also set the lockstring of the Character -to allow the Player to "puppet" this particular character. - -Mutable attributes and their connection to the database -------------------------------------------------------- - -When storing a mutable object (usually a list or a dictionary) in an -Attribute - -:: - - object.db.mylist = [1,2,3] - -you should know that the connection to the database is retained also if -you later extract that Attribute into another variable (what is stored -and retrieved is actually a ``PackedList`` or a ``PackedDict`` that -works just like their namesakes except they save themselves to the -database when changed). So if you do - -:: - - alist = object.db.mylist - alist.append(4) - -this updates the database behind the scenes, so both ``alist`` and -``object.db.mylist`` are now ``[1,2,3,4]``. If you don't want this, -convert the mutable object to its normal Python form. - -:: - - blist = list(object.db.mylist) - blist.append(4) - -The property ``blist`` is now ``[1,2,3,4]`` whereas ``object.db.mylist`` -remains unchanged. You'd need to explicitly re-assign to the ``mylist`` -Attribute in order to update the database. If you store nested mutables -you only need to convert the "outermost" one in order to "break" the -connection to the database like this. - -General shakiness of the web admin ----------------------------------- - -Since focus has been on getting the underlying python core to work -efficiently, the web admin is not quite as stable nor easy to use as -we'd like at this point. Also, the web-based html code is, while -working, not very pretty or clean. These are areas where we'd much -appreciate getting more input and help. - -Known upstream bugs -=================== - -There are no known upstream bugs at this time. diff --git a/docs/sphinx/source/wiki/RSS.rst b/docs/sphinx/source/wiki/RSS.rst deleted file mode 100644 index f7d8f497dc..0000000000 --- a/docs/sphinx/source/wiki/RSS.rst +++ /dev/null @@ -1,66 +0,0 @@ -RSS -=== - -`RSS `_ is a format for easily -tracking updates on websites. The principle is simple - whenever a site -is updated, a small text file is updated. An RSS reader can then -regularly go online, check this file for updates and let the user know -what's new. - -Evennia allows for connecting any number of RSS feeds to any number of -in-game channels. Updates to the feed will be conveniently echoed to the -channel. There are many potential uses for this: For example the MUD -might use a separate website to host its forums. Through RSS, the -players can then be notified when new posts are made. Another example is -to let everyone know you updated your dev blog. Admins might also want -to track the latest Evennia updates through our own RSS feed -`here `_. - -Configuring RSS ---------------- - -To use RSS, you first need to install the -`feedparser `_ python module. It -should be easily available through most distributions as -*python-feedparser*, otherwise you can download it directly. - -Next you activate RSS support in your config file by settting -``RSS_ENABLED=True``. - -Start/reload Evennia as a privileged user. You should now have a new -command available, ``@rss2chan``: - -:: - - @rss2chan = - -Setting up RSS, step by step ----------------------------- - -You can connect RSS to any Evennia channel, but for testing, let's set -up a new channel "rss". - -:: - - @ccreate rss = RSS feeds are echoed to this channel! - -Let's connect Evennia's code-update feed to this channel. Its full url -is ``http://code.google.com/feeds/p/evennia/updates/basic``. - -:: - - @rss2chan rss = http://code.google.com/feeds/p/evennia/updates/basic - -That's it, really. New Evennia updates will now show up as a one-line -title and link in the channel. Give the ``@rss2chan`` command on its own -to show all connections. To remove a feed from a channel, you specify -the connection again (see the list) but add the ``/delete`` switch: - -:: - - @rss2chan/delete rss = http://code.google.com/feeds/p/evennia/updates/basic - -You can connect any number of RSS feeds to a channel this way. You could -also connect them to the same channels as `IRC `_ and/or -`IMC2 `_ to have the feed echo to external chat channels as -well. diff --git a/docs/sphinx/source/wiki/RemovingColour.rst b/docs/sphinx/source/wiki/RemovingColour.rst deleted file mode 100644 index 6ee8e60c76..0000000000 --- a/docs/sphinx/source/wiki/RemovingColour.rst +++ /dev/null @@ -1,74 +0,0 @@ -Tutorial: Removing colour from your game -======================================== - -This is a small tutorial for customizing your character objects, using -the example of letting users turn on and off ansii colour parsing. - -In the Building guide's `Colours `_ page you can learn how -to add Colour to your game by using special markup. Colours enhance the -gaming experience, but not all users want colour. Examples would be -users working from clients that don't support colour, or people with -various seeing disabilities that rely on screen readers to play your -game. - -So here's how to allow those users to remove colour. It basically means -you implementing a simple configuration system for your characters. This -is the basic sequence: - -#. Define your own default character typeclass, inheriting from - Evennia's default. -#. Set an attribute on the character to control markup on/off. -#. Set your custom character class to be the default for new players. -#. Overload the ``msg()`` method on the typeclass and change how it uses - markup. -#. Create a custom command to allow users to change their setting. - -Setting up a custom Typeclass ------------------------------ - -Create a new module in ``game/gamesrc/objects`` named, for example, -``mycharacter.py``. - -In your new module, create a new `typeclass `_ -inheriting from ``ev.Character``. - -:: - - from ev import Character - - class ColourableCharacter(Character): - at_object_creation(self): - # set a colour config value - self.db.config_colour = True - -Above we set a simple config value as an `attribute `_. - -Let's make sure that new characters are created of this type. Edit your -``game/settings.py`` file and add/change ``BASE_CHARACTER_TYPECLASS`` to -point to your new character class. Observe that this will only affect -*new* characters, not those already created. You have to convert already -created characters to the new typeclass by using the ``@typeclass`` -command (try on a secondary character first though, to test that -everything works - you don't want to render your root user unusable!). - -:: - - @typeclass/reset/force Bob = mycharacter.ColourableCharacter - -``@typeclass`` changes Bob's typeclass and runs all its creation hooks -all over again. The ``/reset`` switch clears all attributes and -properties back to the default for the new typeclass - this is useful in -this case to avoid ending up with an object having a "mixture" of -properties from the old typeclass and the new one. ``/force`` might be -needed if you edit the typeclass and want to update the object despite -the actual typeclass name not having changed. - -Overload the \`msg()\` method ------------------------------ - -Next we need to overload the ``msg()`` method. What we want is to check -the configuration value before calling the main function. The ``msg`` -method call is found in -``src/objects/objects.py' and is called like this: {{{ msg(message, from_obj=None, data=None) }}} As long as we define a method on our custom object with the same name and keep the same number of arguments/keywords we will overload the original. Here's how it could look: {{{ from ev import ansi msg(self, message, from_obj=None, data=None): "our custom msg()" if not self.db.config_colour: # if config_colour is False, strip ansi colour message = ansi.parse_ansi(message, strip_ansi=True) self.dbobj.msg(message, from_obj, data) }}} Above we create a custom version of the ``\ msg()\ `` method that cleans all ansi characters if the config value is not set to True. Once that's done, we pass it all on to the normal ``\ msg()\ `` on the database object (``\ ObjectDB\ ``) to do its thing. The colour strip is done by the ansi module itself by giving the ``\ strip\_ansi\ `` keyword to ``\ ansi.parse\_ansi\ ``. Since we put this custom ``\ msg()\ `` in our typeclass ``\ ColourableCharacter\ ``, it will be searched for and called rather than the default method on ``\ ObjectDB\ `` (which we now instead call manually). There we go! Just flip the attribute ``\ config\_colour\ `` to False and your users will not see any colour. As superuser (assuming you use the Typeclass ``\ ColourableCharacter\ ``) you can test this with the ``\ @py\ `` command: {{{ @py self.db.config_colour = False }}} ==Custom colour config command == For completeness, let's add a custom command so users can turn off their colour display themselves if they want. In ``\ game/gamesrc/commands\ ``, reate a new file, call it for example ``\ configcmds.py\ `` (it's likely that you'll want to add other commands for configuration down the line). You can also copy/rename the command template from ``\ game/gamesrc/commands/examples\ ``. {{{ from ev import default_cmds class ConfigColourCmd(default_cmds.MuxCommand): """ Configures your colour Usage: @setcolour on|off This turns ansii-colours on/off. Default is on. """ key = "@setcolour" aliases = ["@setcolor"] def func(self): "Implements the command" if not self.args or not self.args in ("on", "off"): self.caller.msg("Usage: @setcolour on|off") return if self.args == "on": self.caller.db.config_colour = True else: self.caller.db.config_colour = False self.caller.msg("Colour was turned %s." % self.args) }}} Lastly, we make this command available to the user by adding it to the default command set. Easiest is to add it to copy the template file from ``\ gamesrc/commands/examples\ ``, set ``\ settings.CMDSET\_DEFAULT\ `` to point to, and then add your module to the end of ``\ DefaultCmdSet\ `` in that new module. {{{ from game.gamesrc.commands import configcmds class DefaultCmdSet(cmdset_default.DefaultCmdSet): key = "DefaultMUX" def at_cmdset_creation(self): super(DefaultCmdSet, self).at_cmdset_creation() self.add(configcmds.ConfigColourCmd()) }}} When adding a new command to a cmdset like this you need to run the ``\ @reload\ ```` -command (or reboot the server). From here on out, your users should be -able to turn on or off their colour as they please. diff --git a/docs/sphinx/source/wiki/Scripts.rst b/docs/sphinx/source/wiki/Scripts.rst deleted file mode 100644 index c23f285a77..0000000000 --- a/docs/sphinx/source/wiki/Scripts.rst +++ /dev/null @@ -1,236 +0,0 @@ -Scripts -======= - -*Scripts* are the out-of-character siblings to the in-character -`Objects `_. The name "Script" might suggest that they can -only be used to script the game but this is only part of their -usefulness (in the end we had to pick a single name for them). Scripts -are full Typeclassed database entities, just like Objects - with all the -advantages this entails. Likewise they can also store arbitrary -*Attributes*. - -Scripts can be used for many different things in Evennia: - -- They can attach to Objects to influence them in various ways - or - exist independently of any one in-game entity. -- They can work as timers and tickers - anything that may change with - Time. But they can also have no time dependence at all. -- They can describe State changes. -- They can act as data stores for storing game data persistently in the - database. -- They can be used as OOC stores for sharing data between groups of - objects. - -The most obvious use of Scripts may be to use them as *timers* or -*Events*. Consider a script running on the object ``Grandfather Clock``. -The script has a timer that tells it to fire every hour. This allows the -clock to chime regularly. The script might even regulate how often the -clock must be rewound so it won't stop. - -Scripts may act as changeable *States*. Consider for example creating a -'dark' room. It has two scripts assigned on it - one ``DarkState`` -script, and one ``BrightState`` script. When characters enter the dark -room, it assigns a custom `Cmdset `_ to them. This -command set defines the parameters of the state they describe. In this -case it limits their actions because of the darkness. After the -characters have stumbled around for a while, someone brings up a torch. -As a light source is now in the room, ``DarkState`` reacts to this by -shutting down itself and handing over control to the ``BrightState`` -script that restores normal commands. Finally, when the character with -the torch leaves the room, the ``BrightState`` script detects this and -obediently hands control back to the ``DarkState``, 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 pursue -characters between rooms. - -Scripts are also excellent places to store game data in an OOC way. A -groupd of objects may share date by use of a Script object they all hold -references to. - -In short, Scripts can be used for a lot of things. - -How to create and test your own Script types --------------------------------------------- - -In-game you can try out scripts using the ``@script`` command. Try the -following: - -:: - - > @script self = examples.bodyfunctions.BodyFunctions - -This should cause some random messages. Add the ``/stop`` switch to the -above command to kill the script again. You can use the ``@scripts`` -command to list all active scripts in the game. Evennia creates a few -default ones. - -Custom script modules are usually stored in ``game/gamesrc/scripts``. As -a convenience you can inherit sripts from ``ev.Script``. - -If you add scripts to `Objects `_ the script can then -manipulate the object as desired. The script is added to the object's -*script handler*, called simply ``scripts``. The handler takes care of -all initialization and startup of the script for you. - -:: - - # add script to myobj's scripthandler - myobj.scripts.add("game.gamesrc.scripts.myscripts.CoolScript") - # alternative way - from ev import create_script - create_script("game.gamesrc.scripts.myscripts.CoolScript", obj=myobj) - -A script does not have to be connected to an in-game object. Such -scripts are called *Global scripts*. You can create global scripts by -simply not supplying an object to store it on: - -:: - - # adding a global script - from ev import create_script - create_script("game.gamesrc.scripts.globals.MyGlobalEconomy", key="economy", obj=None) - -Assuming the Script ``game.gamesrc.scripts.globals.MyGlobalEconomy`` -exists, this will create and start it as a global script. - -Properties and functions defined on Scripts -------------------------------------------- - -A Script has all the properties of a typeclassed object, such as ``db`` -and ``ndb``\ (see `Typeclasses `_). Setting ``key`` is -useful in order to manage scripts (delete them by name etc). These are -usually set up in the Script's typeclass, but can also be assigned on -the fly as keyword arguments to ``ev.create_script``. - -- ``desc`` - an optional description of the script's function. Seen in - script listings. -- ``interval`` - how often the script should run. If ``interval == 0`` - (default), it runs forever, without any repeating (it will not accept - a negative value). -- ``start_delay`` - (bool), if we should wait ``interval`` seconds - before firing for the first time or not. -- ``repeats`` - How many times we should repeat, assuming - ``interval > 0``. If repeats is set to ``<= 0``, the script will - repeat indefinitely. -- ``persistent``- if this script should survive a server *reset* or - server *shutdown*. (You don't need to set this for it to survive a - normal reload - the script will be paused and seamlessly restart - after the reload is complete). - -There is one special property: - -- ``obj`` - the `Object `_ this script is attached to (if - any). You should not need to set this manually. If you add the script - to the Object with ``myobj.scripts.add(myscriptpath)`` or give - ``myobj`` as an argument to the ``utils.create.create_script`` - function, the ``obj`` property will be set to ``myobj`` for you. - -It's also imperative to know the hook functions. Normally, overriding -these are all the customization you'll need to do in Scripts. You can -find longer descriptions of these in ``src/scripts/scripts.py``. - -- ``at_script_creation()`` - this is usually where the script class - sets things like ``interval`` and ``repeats``; things that control - how the script runs. It is only called once - when the script is - first created. -- ``is_valid()`` - determines if the script should still be running or - not. This is called when running ``obj.scripts.validate()``, which - you can run manually, but which also Evennia calls during certain - situations such as reloads. This is also useful for using scripts as - state managers. If the method returns ``False``, the script is - stopped and cleanly removed. -- ``at_start()`` - this is called when the script starts or is - unpaused. For persistent scripts this is at least once ever server - startup. Note that this will *always* be called right away, also if - ``start_delay`` is ``True``. -- ``at_repeat()`` - this is called every ``interval`` seconds, or not - at all. It is called right away at startup, unless ``start_delay`` is - ``True``, in which case the system will wait ``interval`` seconds - before calling. -- ``at_stop()`` - this is called when the script stops for whatever - reason. It's a good place to do custom cleanup. -- ``at_server_reload()`` - this is called whenever the server is - warm-rebooted (e.g. with the ``@reload`` command). It's a good place - to save non-persistent data you might want to survive a reload. -- ``at_server_shutdown()`` - this is called when a system reset or - systems shutdown is invoked. - -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 automatically. ``at_stop()`` will - be called. -- ``pause()`` - this pauses a running script, rendering it inactive, - but not deleting it. All properties are saved and timers can be - resumed. This is called automatically when the server reloads. No - hooks are called - as far as the script knows, it never stopped - - this is a suspension of the script, not a change of state. -- ``unpause()`` - resumes a previously paused script. The at\_start() - hook will be called to allow it to reclaim its internal state. Timers - etc are restored to what they were before pause. The server unpauses - all paused scripts after a server reload. -- ``time_until_next_repeat()`` - for timed scripts, this returns the - time in seconds until it next fires. Returns ``None`` if - ``interval==0``. - -Example script --------------- - -:: - - import random - from ev import Script - class Weather(Script): - "Displays weather info. Meant to be attached to a room." - def at_script_creation(self): - "Called once, during initial creation" - self.key = "weather_script" - self.desc = "Gives random weather messages." - self.interval = 60 * 5 # every 5 minutes - self.persistent = True - def at_repeat(self): - "called every self.interval seconds." - rand = random.random() - if rand < 0.5: - weather = "A faint breeze is felt." - elif rand < 0.7: - weather = "Clouds sweep across the sky." - else: - weather = "There is a light drizzle of rain." - # send this message to everyone inside the object this - # script is attached to (likely a room) - self.obj.msg_contents(weather) - -This is a simple weather script that we can put on an object. Every 5 -minutes it will tell everyone inside that object how the weather is. - -To activate it, just add it to the script handler (``scripts``) on an -`Room `_. That object becomes ``self.obj`` in the example -above. Here we put it on a room called ``myroom``: - -:: - - myroom.scripts.add(weather.Weather) - -In code you can also use the create function directly if you know how to -locate the room you want: - -:: - - from ev import create_script - create_script('game.gamesrc.scripts.weather.Weather', obj=myroom) - -Or, from in-game, use the ``@script`` command: - -:: - - @script here = weather.Weather - diff --git a/docs/sphinx/source/wiki/ServerConf.rst b/docs/sphinx/source/wiki/ServerConf.rst deleted file mode 100644 index 57a69d168c..0000000000 --- a/docs/sphinx/source/wiki/ServerConf.rst +++ /dev/null @@ -1,115 +0,0 @@ -Evennia Server Configurations -============================= - -Evennia runs out of the box without any changes to its settings. But -there are several important ways to customize the server and expand it -with your own plugins. - -Settings file -------------- - -The "Settings" file referenced throughout the documentation is the file -``game/settings.py``. This is automatically created on the first run of -``manage.py syncdb`` (see the `GettingStarted `_ -page). The settings file is actually a normal Python module. It's pretty -much empty from the start, it just imports all default values from -``src/settings_default.py`` into itself. - -You should never edit ``src/settings_default.py``. Rather you should -copy&paste the variables you want to change into ``settings.py`` and -edit them there. This will overload the previously imported defaults. - -In code, the settings is accessed through - -:: - - from django.conf import settings - # or (shorter): - from ev import settings - # example: - servername = settings.SERVER_NAME - -Each setting appears as a property on the imported ``settings`` object. -You can also explore all possible options with ``ev.settings_full`` -(this also includes advanced Django defaults that are not not touched in -default Evennia). - -It should be pointed out that when importing ``settings`` into your code -like this, it will be *read only*. You cannot edit your settings in -code. The only way to change an Evennia setting is to edit -``game/settings.py`` directly. You most often need to restart the server -(possibly also the Portal) before a changed setting becomes available. - -\`game/gamesrc/conf\` directory -------------------------------- - -The ``game/gamesrc/conf/examples/`` directory contains module templates -for customizing Evennia. Common for all these is that you should *copy* -the template up one level (to ``game/gamesrc/conf/``) and edit the copy, -not the original. You then need to change your settings file to point -the right variable at your new module. Each template header describes -exactly how to use it and which settings variable needs to be changed -for Evennia to be able to locate it. - -- ``at_initial_setup.py`` - this allows you to add a custom startup - method to be called (only) the very first time Evennia starts (at the - same time as user #1 and Limbo is created). It can be made to start - your own global scripts or set up other system/world-related things - your game needs to have running from the start. -- ``at_server_startstop.py`` - this module contains two functions that - Evennia will call every time the Server starts and stops respectively - - this includes stopping due to reloading and resetting as well as - shutting down completely. It's a useful place to put custom startup - code for handlers and other things that must run in your game but - which has no database persistence. -- ``connection_screens.py`` - all global string variables in this - module are interpreted by Evennia as a greeting screen to show when a - Player first connects. If more than one string variable is present in - the module a random one will be picked. -- ``lockfuncs.py`` - this is one of many possible modules to hold your - own "safe" *lock functions* to make available to Evennia's `lock - system `_. -- ``mssp.py`` - this holds meta information about your game. It is used - by MUD search engines (which you often have to register with) in - order to display what kind of game you are running along with - statistics such as number of online players and online status. -- ``portal_services_plugin.py`` - this allows for adding your own - custom servies/protocols to the Portal. It must define one particular - function that will be called by Evennia at startup. There can be any - number of service plugin modules, all will be imported and used if - defined. More info can be found - `here `_. -- ``server_services_plugin.py`` - this is equivalent to the previous - one, but used for adding new services to the Server instead. More - info can be found - `here `_. - -Some other Evennia systems can be customized by plugin modules but has -no explicit template in ``conf/examples``: - -- *command parser* - a custom module can be used to totally replace - Evennia's default command parser. All this does is to split the - incoming string into "command name" and "the rest". It also handles - things like error messages for no-matches and multiple-matches among - other things that makes this more complex than it sounds. The default - parser is *very* generic, so you are most often best served by - modifying things further down the line (on the command parse level) - than here. -- *search-return handler* - this can be used to replace how Evennia - handles search results from most of Evennia's in-game searches (most - importantly ``self.caller.search`` in commands). It handles the - echoing of errors. -- *multimatch handler* - this plugin replaces the handling of multiple - match errors in searching. By default it allows for separating - between same-named matches by use of numbers. Like understanding that - "2-ball" should match the second "ball" object if there are two of - them. - -!ServerConf ------------ - -There is a special database model called ServerConf that stores server -internal data and settings such as current player count (for interfacing -with the webserver), startup status and many other things. It's rarely -of use outside the server core itself but may be good to know about if -you are an Evennia developer. diff --git a/docs/sphinx/source/wiki/SessionProtocols.rst b/docs/sphinx/source/wiki/SessionProtocols.rst deleted file mode 100644 index 818e37c8d5..0000000000 --- a/docs/sphinx/source/wiki/SessionProtocols.rst +++ /dev/null @@ -1,314 +0,0 @@ -Portal Sessions and Protocols -============================= - -*Note: This is considered an advanced topic and is mostly of interest to -users planning to implement their own custom client protocol.* - -A *Portal Session* is the basic data object representing an external -connection to the Evennia `Portal `_ -- usually a -human player running a mud client of some kind. The way they connect - -the language the player's client and Evennia use to talk to each other - -is called the connection *Protocol*. The most common such protocol for -MUD:s is the *Telnet* protocol. All Portal Sessions are stored and -managed by the Portal's *sessionhandler*. - -It's technically sometimes hard to separate the concept of *Session* -from the concept of *Protocol* since both depend heavily on the other. - -Protocols and Sessions both belong in ``src/server/``, so adding new -protocols is one of the rare situations where development needs to -happen in ``src/`` (in fact, if you do add a new useful protocol, -consider contacting Evennia devs so we can include it in the main -Evennia distribution!). - -Protocols ---------- - -Writing a stable communication protocol from scratch is not something -we'll cover here, it's no trivial task. The good news is that Twisted -offers implementations of many common protocols, ready for adapting. - -Writing a protocol implementation in Twisted usually involves creating a -class inheriting from a suitable Twisted parent, then overloading the -methods that particular protocol requires so that it talks to Evennia. -Whenever a new connection is made via this protocol, an instance of this -class will be called. As various states change, specific-named methods -on the class will be called (what they are named depends on the Twisted -implementation). - -A straight-forward protocol (like Telnet) is assumed to at least have -the following components (although the actual method names might vary): - -- ``connectionMade`` - called when a new connection is made. This must - call ``self.init_session()`` with three arguments: an *identifier* - for the protocol type (e.g. the string 'telnet' or 'ssh'), the *IP - address* of the client connecting, and a reference to the - *sessionhandler*. The sessionhandler is by convention made available - by storing it on the protocol's *Factory* in - ``src/server/portal.py``, see that file for examples. Doing it this - way avoids many possible recursive import issues. -- ``connectionLost`` - called when connection is dropped for whatever - reason. This must call ``self.sessionhandler.disconnect(self)`` so - the handler can make sure the disconnect is reported to the rest of - the system. -- ``getData`` - data arriving from the player to Evennia. This should - apply whatever custom formatting this protocol needs, then relay the - data to ``self.sessionhandler.data_in(self, msg, data)``. -- ``sendLine`` - data from Server to Player. This is called by hook - ``data_out()`` below. - -See an example of this in -`server/telnet.py `_. - -These might not be as clear-cut in all protocols, but the principle is -there. These four basic components - however they are accessed - links -to the *Portal Session*, which is the actual common interface between -the different low-level protocols and Evennia. - -Portal Sessions ---------------- - -A *Portal Session* is an Evennia-specific thing. It must be a class -inheriting from ``src.server.session.Session``. If you read the Telnet -example above, the Protocol and Session are infact sometimes -conveniently implemented in the same class through multiple inheritance. -At startup the Portal creates and adds the Portal Session to its -*sessionhandler*. While doing so, the session also gets assigned a -property ``sessionhandler`` that refers to that very handler. This is -important since the handler holds all methods relevant for sending and -receiving data to and from the Server. - -Whereas we don't know the method names of a Twisted Protocol (this can -vary from protocol to protocol), the Session has a strict naming scheme -that may not change; it is the glue that connects the Protocol to -Evennia (along with some other convenient features). - -The Session class must implement the following method hooks (which must -be named exactly like this): - -- ``disconnect()`` - called when manually disconnecting. Must call the - protocol-specific disconnect method (e.g. ``connectionLost`` above) -- ``data_out(string="", data=None)`` - data from Evennia to player. - This method should handle any protocol-specific processing before - relaying data on to a send-method like ``self.sendLine()`` mentioned - above. ``string`` is normally a raw text string with formatting. - ``data`` can be a collection of any extra information the server want - to give to the protocol- it's completely up to the Protocol to handle - this. To take an example, telnet assumes ``data`` to be either - ``None`` or a dictionary with flags for how the text should be - 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 to which the server responds - 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 it 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, stamina and maybe some skill values. 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 functions: - -:: - - # the caller is automatically added as first argument - def get_health(character): - "Get health, stored as simple attribute" - return character.db.health - def get_stamina(character): - "Get stamina level, stored as simple attribute" - return character.db.stamina - def get_skill(character, skillname, master=False): - """we assume skills are stored as a dictionary - stored in an attribute. Master skills are - stored separately (for whatever reason)""" - if master: - return character.db.skills_master.get(skillname, "NoSkill") - return character.db.skills.get(skillname, "NoSkill") - -Done, the functions will return what we want assuming Characters do -store this information in our game. 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_STAMINA: - # call get_mana(char) - outdict["get_stamina"] = ([], {}) - elif GET_MASTER_SKILL_SMITH: - # call get_skill(char, "smithing", master=True) - outdict["get_skill"] = (["smithing"], {'master':True}) - - [...] - - self.sessionhandler.oob_data_out(outdict) - -The Server will properly accept this and call the relevant functions to -get their return values for the health, stamina and skill. The return -values will be packed in a dictionary keyed by function name before -being passed back to the Portal. We need to define -``oob_data_out(data)`` in our portal protocol to catch this: - -:: - - def oob_data_out(self, data): - # the indata is a dictionary {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 ... - [...] - # send off using the protocols send method (this is telnet) - sendLine(outstring) - -As seen, ``oob_data`` takes the values and formats into a form the -protocol understands before sending it off. - -Implementing auto-sending -~~~~~~~~~~~~~~~~~~~~~~~~~ - -To have the Server update the client regularly, simply create a global -`Script `_ 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)``. -Loop over all relevant sessions. The Server will treat this like a -Portal call and data will be sent back to be handled by the portal as -normal. - -Adding custom Protocols -======================= - -Evennia has a plugin-system that allows you to add new custom Protocols -without editing any files in ``src/``. To do this you need to add the -protocol as a new "service" to the application. - -Take a look at for example ``src/server/portal.py``, notably the -sections towards the end of that file. These are where the various -in-built services like telnet, ssh, webclient etc are added to the -Portal (there is an equivalent but shorter list in -``src/server.server.py``. - -To add a new service of your own (for example your own custom client -protocol) to e.g. the Portal, create a new module in -``game/gamesrc/conf/``. Let's call it ``myproc_plugin.py``. We need to -tell the Server or Portal that they need to import this module. In -``game/settings.py``, add one of the following: - -:: - - # add to the Server - SERVER_SERVICES_PLUGIN_MODULES.append('game.gamesrc.conf.myproc_plugin') - # or, if you want to add to the Portal - PORTAL_SERVICES_PLUGIN_MODULES.append('game.gamesrc.conf.myproc_plugin') - -This module can contain whatever you need to define your protocol, but -it *must* contain a function ``start_plugin_services(app)``. This is -called by the Portal as part of its upstart. The function -``start_plugin_services`` must contain all startup code the server need. -The ``app`` argument is a reference to the Portal application itself so -the custom service can be added to it. The function should not return -anything. - -This is how it can look: - -:: - - # game/gamesrc/conf/myproc_plugin.py - - # here the new Portal Twisted protocol is defined - class MyOwnFactory( ... ): - [...] - - # some configs - MYPROC_ENABLED = True # convenient off-flag to avoid having to edit settings all the time - MY_PORT = 6666 - - def start_plugin_services(portal): - "This is called by the Portal during startup" - if not MYPROC_ENABLED: - return - # output to list this with the other services at startup - print " myproc: %s" % MY_PORT - - # some setup (simple example) - factory = MyOwnFactory() - my_service = internet.TCPServer(MY_PORT, factory) - # all Evennia services must be uniquely named - my_service.setName("MyService") - # add to the main portal application - portal.services.addService(my_service) - -One the module is defined and targeted in settings, just reload the -server and your new protocol/services should start with the others. - -Assorted notes -============== - -To take two examples, Evennia supports the *telnet* protocol as well as -*webclient*, a custom ajax protocol. You'll find that whereas telnet is -a textbook example of a Twisted protocol as seen above, the ajax client -protocol looks quite different due to how it interacts with the -webserver through long-polling (comet) style requests. All the necessary -parts mentioned above are still there, but implemented in very different -ways. diff --git a/docs/sphinx/source/wiki/SoftCode.rst b/docs/sphinx/source/wiki/SoftCode.rst deleted file mode 100644 index fc2d646e20..0000000000 --- a/docs/sphinx/source/wiki/SoftCode.rst +++ /dev/null @@ -1,198 +0,0 @@ -On MUX and Softcode: A brief overview -===================================== - -Evennia was originally created in order to provide a MUX/MUSH-style -development environment without the kludgery of softcode. Although it -has since grown to be adaptable to any style of MU\ ``*`` it still ships -with 'MUX-like' default commands. - -This document will provide a quick overview of what softcode is, why it -drove us to write Evennia, and why we instead use Python. - -Softcode is a very simple programming language that was created for -in-game development on TinyMUD derivatives such as MUX, PennMUSH, -TinyMUSH, and RhostMUSH. The idea is that by providing a stripped down, -minimalistic language for in-game use, you can allow quick and easy -building and game development to happen without having to learn C/C++. -There is an added benefit of not having to have to hand out shell access -to all developers, and permissions can be used to alleviate many -security problems. - -Writing and installing softcode is done through a MUD client. As is -such, it is not a formatted language. Each softcode function is a single -line of varying size. Some functions can be a half of a page long due to -this, which is obviously not very readable. The lack of formatting is -one of the big reasons Evennia exists today. Bigger projects tend to -choke under their own weight after time unless your entire staff has a -good understanding of functional programming practices. - -Examples of Softcode --------------------- - -Here is a simple 'Hello World!' command: - -:: - - @set me=HELLO_WORLD.C:$hello:@pemit %#=Hello World! - -Pasting this into a MUX/MUSH and typing 'hello' will theoretically yield -'Hello World!', assuming certain flags are not set on your player -object. - -Setting attributes is done via ``@set``. Softcode also allows the use of -the ampersand (``&``) symbol. This shorter version looks like this: - -:: - - &HELLO_WORLD.C me=$hello:@pemit %#=Hello World! - -Perhaps I want to break the Hello World into an attribute which is -retrieved when emitting: - -:: - - &HELLO_VALUE.D me=Hello World - &HELLO_WORLD.C me=$hello:@pemit %#=[v(HELLO_VALUE.D)] - -The v() function returns the HELLO\_VALUE.D attribute on the object that -the command resides (``me``, which is yourself in this case). This -should yield the same output as the first example. - -If you are still curious about how Softcode works, take a look at some -external resources: - -- `http://www.tinymux.com/wiki/index.php/Softcode `_ -- `http://www.duh.com/discordia/mushman/man2x1 `_ - -Problems with Softcode ----------------------- - -Softcode is excellent at what it was intended for: simple things. It is -an incredible tool if used for its intended purposes - an interactive -object, a room with ambiance, simple global commands, simple economies -and coded systems. However, once you start to try to write something -like a complex combat system or a higher end economy, you're likely to -find yourself buried under a mountain of functions that span various -objects and are of various length. - -Not to mention, softcode is not an inherently fast language. It is not -compiled, it is parsed with each calling of a function. While MUX and -MUSH parsers have jumped light years ahead of where they were even seven -or eight years ago, they can still stutter under the weight of the more -complex systems if not designed properly. - -To further illustrate the lack of readability for building larger -systems in softcode, here is another example, PennMush softcode this -time, for implementing an "+info" command (it allows you to store pages -of extra character info that is later confirmed by admins and can be -viewed by other players): - -:: - - &INC`SET u(ifo)=@include u(ifo)/INC`TARGET;@include \ - u(ifo)/INC`FILENAME;@assert strlen(%q)=@nspemit \ - %#=announce(INFO)%BERROR: Info file name empty.;@switch/inline \ - gt(strlen(setr(attr,u(u(ifo)/FUN`FINDFILE,%q,%q))),0)=1,{@assert \ - or(isadmin(%#),strmatch(%q,%#))=@nspemit \ - %#=announce(INFO)%BERROR: You may not change another's Info \ - files.;@switch/inline \ - or(getstat(%q/%q`FLAGS,Hidden),getstat(%q/%q`FLAGS,Approved))=1,{@assert \ - isadmin(%#)=@nspemit %#=announce(INFO)%BERROR: That Info File may not \ - be changed by you.}},0,{@break gt(strlen(%q),18)=@nspemit \ - %#=ERROR: Info names are limited to 18 characters or less.;@break \ - regmatchi(%q,\\|)=@nspemit %#=ERROR: Pipe symbols are not \ - allowed in info names.;@break regmatchi(%q,\/)=@nspemit \ - %#=ERROR: Slashes symbols are not allowed in info names.;@assert \ - strlen(%1)=ERROR: Text field empty. To delete an +info file, use \ - +info/delete.};&[strfirstof(%q,setr(attr,D`INFOFILE`[nextslot(%q,D`INFOFILE)]))] \ - %q=%q;&%q`CONTENTS %q=%1;th \ - setstat(%q/%q`FLAGS,SetBy,%#);th \ - setstat(%q/%q`FLAGS,SetOn,secs());@switch/inline \ - strmatch(%#,%q)=1,{@nspemit %#=announce(INFO)%BYou set your \ - %q Info File},{@nspemit %#=announce(INFO)%BYou set \ - [name(%q)]'s %q Info File!;@nspemit \ - %q=announce(INFO)%B%n set your %q Info File!} - -(Note that the softcode is actually all one line, it was split to be -viewable on this wiki). Below is the rough Evennia equivalent -functionality as an Evennia command method, written by the same softcode -author after a week of learning Evennia: - -:: - - def switch_set(self,target,files,rhs,isadmin): - if self.caller is not target and not isadmin: - self.caller.msg("ERROR: You may not set that person's files.") - return - if not self.rhs: - self.caller.msg("ERROR: No info file contents entered to set.") - return - for info in files: - if not re.match('^[\w-]+$', info.lower().strip()): - self.caller.msg("ERROR: File '" + info + \ - "' could not be set: may only use alphanumeric characters, -, and spaces in info names.") - elif self.files.get(info.lower().strip(),{}).get("approved",None) is True: - self.caller.msg("ERROR: File '" + info.strip() + "' could not be set: file is approved.") - else: - self.files[info.lower().strip()] = {"contents":rhs, "setby":self.caller, - "seton":"timestamp", "displayname":info.strip()} - if target is self.caller: - self.caller.msg("Info File '" + info.strip() + "' set!") - else: - self.caller.msg("Info File '" + info.strip() + "' set!") - target.caller.msg(self.caller.key + " set your '" + info.strip() + "' info file!") - target.db.infofiles = dict(self.files) - return - -The details of the implementation are unimportant, the difference in -readability is the main point here. - -Changing Times --------------- - -Now that starting text-based games is easy and an option for even the -most technically inarticulate, new projects are a dime a dozen. People -are starting new MUDs every day with varying levels of commitment and -ability. Because of this shift from fewer, larger, well-staffed games to -a bunch of small, one or two developer games, some of the benefit of -softcode fades. - -Softcode is great in that it allows a mid to large sized staff all work -on the same game without stepping on one another's toes. As mentioned -before, shell access is not necessary to develop a MUX or a MUSH. -However, now that we are seeing a lot more small, one or two-man shops, -the issue of shell access and stepping on each other's toes is a lot -less. - -Our Solution -============ - -For the hobbyist who would like the option to use a full-featured -language, we created Evennia. We are no longer bound to single lines of -softcode. Game developers now have access to the entire library of -Python modules out there in the wild. Our complex systems may be -organized neatly into modules, sub-modules, or even broken out into -entire Python packages. - -So what is *not* included in Evennia proper is a MUX/MOO-like online -player building system. Advanced coding and building in Evennia is -primarily intended to be done outside the game, in full-fledged Python -modules. We feel that with a small development team you are better off -using a professional source-control system (svn, git, bazaar, mercurial -etc) anyway. - -Your Solution -============= - -Adding very advanced and flexible building commands to your game will -probably often be enough to satisfy most creative builders. However, if -you really, *really* want to offer online coding there is of course -nothing stopping you from adding that to Evennia, no matter our -recommendations. You could even re-implement MUX' softcode in Python -should you be very ambitious. - -There is an experimental restricted python environment named *Evlang* to -be found in our *contrib* folder. Being in this folder means it's not a -part of the core server and is completely optional to use. Evlang could -serve as a starting point if you want to go down the route of simple -online player coding. diff --git a/docs/sphinx/source/wiki/StartStopReload.rst b/docs/sphinx/source/wiki/StartStopReload.rst deleted file mode 100644 index 96f1a1a771..0000000000 --- a/docs/sphinx/source/wiki/StartStopReload.rst +++ /dev/null @@ -1,104 +0,0 @@ -Running Evennia -=============== - -You control Evennia from ``game/`` using the ``evennia.py`` program. -Below are described the various management options. You can also start -the program without any arguments or use the *menu* option to get a -multiple-choice menu instead. - -:: - - python evennia.py menu - -Starting Evennia ----------------- - -Evennia consists of two components, the Evennia `Server and -Portal `_. Briefly, the *Server* is what is -running the mud. It handles all game-specific things but don't care -exactly how players connect, only that they have. The *Portal* is a -gateway to which players connect. It knows everything about telnet, ssh, -webclient protocols etc but very little about the game. Both are -required for a functioning mud. - -:: - - python evennia.py start - -The above command automatically starts both Portal and Server at the -same time, logging to the log files in ``game/log``. - -If you rather see error messages etc directly in the terminal (useful -for quickly debugging your code), you use the -i (interactive) flag: - -:: - - python evennia.py -i start - -This will start the *Server* in interactive mode. The Portal will -continue to log to its log file. This is normally what you want unless -you are debugging the Portal. - -You can also start the two components one at a time. - -:: - - python evennia.py start server - python evennia.py start portal - -Adding -i to either of these explicit commands will start that component -in interactive mode so it logs to the terminal rather than to log file. - -Reloading ---------- - -The act of *reloading* means the *Server* program is shut down and then -restarted again. In the default cmdset you initiate a reload by using -the ``@reload`` command from inside the game. The game will be briefly -paused for all players as the server comes back up (since they are all -connected to the *Portal*, their connections are not lost). - -Reloading is as close to a "warm reboot" you can get. It reinitializes -all code of Evennia, but doesn't kill "persistent" scripts. It also -calls ``at_server_reload()`` hooks on all objects so you can save -eventual temporary properties you want. - -You can also reload the server from outside the game (not available in -Windows): - -:: - - python evennia.py reload - -Resetting ---------- - -*Resetting* is the equivalent of a "cold reboot" of the server - it will -restart but will behave as if it was fully shut down. You initiate a -reset using the ``@reset`` command from inside the game. As with a -reload, no players will be disconnected during a shutdown. It will -however purge all non-persistent scripts and will call -``at_server_shutdown()`` hooks. It can be a good way to clean unsafe -scripts during development, for example. - -A reset is equivalent to - -:: - - python evennia.py stop server - python evennia.py start server - -Shutting down -------------- - -A full shutdown closes Evennia completely, both Server and Portal. All -players will be booted and systems saved and turned off cleanly. From -inside the game you initiate a shutdown with the ``@shutdown`` command. - -From command line you do - -:: - - python.py evennia.py stop - -You will see messages of both Server and Portal closing down. diff --git a/docs/sphinx/source/wiki/TextEncodings.rst b/docs/sphinx/source/wiki/TextEncodings.rst deleted file mode 100644 index fc2dfc2b35..0000000000 --- a/docs/sphinx/source/wiki/TextEncodings.rst +++ /dev/null @@ -1,64 +0,0 @@ -Notes on text encodings -======================= - -Evennia is a text-based game server. This makes it important to -understand how it actually deals with data in the form of text. - -Text *byte encodings* describe how a string of text is actually stored -in the computer - that is, the particular sequence of bytes used to -represent the letters of your particular alphabet. A common encoding -used in English-speaking languages is the *ASCII* encoding. This -describes the letters in the English alphabet (Aa-Zz) as well as a bunch -of special characters. For describing other character sets (such as that -of other languages with other letters than English), sets with names -such as *Latin-1*, *ISO-8859-3* and *ARMSCII-8* are used. There are -hundreds of different byte encodings in use around the world. - -In contrast to the byte encoding is the *unicode representation*. The -unicode is an internationally agreed-upon table describing essentially -all available letters you could ever want to print. Everything from -English to Chinese alphabets and all in between. So what Evennia (as -well as Python and Django) does is to store everything in Unicode -internally, but then converts the data to one of the encodings whenever -outputting data to the user. - -The problem is that when receiving a string of bytes from a user it's -impossible for Evennia to guess which encoding was used - it's just a -bunch of bytes! Evennia must know the encoding in order to convert back -and from the correct unicode representation. - -How to customize encodings -========================== - -As long as you stick to the standard ASCII character set (which means -the normal English characters, basically) you should not have to worry -much about this section. - -If you want to build your game in another language however, or expect -your users to want to use special characters not in ASCII, you need to -consider which encodings you want to support. - -As mentioned, there are many, many byte-encodings used around the world. -It should be clear at this point that Evennia can't guess but has to -assume or somehow be told which encoding you want to use to communicate -with the server. Basically the encoding used by your client must be the -same encoding used by the server. This can be customized in two -complementary ways. - -#. Point users to the default ``@encoding`` command. This allows them to - themselves set which encoding they (and their client of choice) uses. - Whereas data will remain stored as unicode internally in Evennia, all - data received from and sent to this particular player will be - converted to the given format before transmitting. -#. As a back-up, in case the user-set encoding translation is erroneous - or fails in some other way, Evennia will fall back to trying with the - names defined in the settings variable ``ENCODINGS``. This is a list - of encoding names Evennia will try, in order, before giving up and - giving an encoding error message. - -Note that having to try several different encodings every input/output -adds unneccesary overhead. Try to guess the most common encodings you -players will use and make sure these are tried first. The International -*UTF-8* encoding is what Evennia assumes by default (and also what -Python/Django use normally). See the Wikipedia article -`here `_ for more help. diff --git a/docs/sphinx/source/wiki/TickerScripts.rst b/docs/sphinx/source/wiki/TickerScripts.rst deleted file mode 100644 index 651023b8fc..0000000000 --- a/docs/sphinx/source/wiki/TickerScripts.rst +++ /dev/null @@ -1,232 +0,0 @@ -Ticker Scripts ("Heartbeats") -============================= - -A common way to implement a dynamic MUD is by using "tickers", also -known as "heartbeats". A ticker is a timer that fires ("ticks" at a -given interval. The tick triggers updates in various game systems. -Tickers are very common or even unavoidable in other mud code bases, -where many systems are hard coded to rely on the concept of the global -'tick'. Evennia has no such notion - the use of tickers (or not) is very -much up to your game and which requirements you have. -`Scripts `_ are powerful enough to act as any type of -counter you want and the "ticker recipe" is just one convenient (and -occationally effective) way of cranking the wheels. - -When \_not\_ to use tickers ---------------------------- - -First, let's consider when *not* to use tickers. Even if you are used to -habitually relying on tickers for everything in other code bases, stop -and think about what you really need them for. Notably you should -*never* try implement a ticker to *catch changes*. Think about it - you -might have to run the ticker every second to react to the change fast -enough. Most likely nothing will have changed most of the time. So you -are doing pointless calls (since skipping the call gives the same result -as doing it). Making sure nothing's changed might even be -computationally expensive depending on the complexity of your system. -Not to mention that you might need to run the check on every object in -the database. Every second. Just to maintain status quo. - -Rather than checking over and over on the off-chance that something -changed, consider a more proactive approach. Can you maybe implement -your rarely changing system to *itself* report its change *whenever* it -happens? It's almost always much cheaper/efficient if you can do things -"on demand". Evennia itself uses hook methods for this very reason. The -only real "ticker"-like thing in the default set is the one that saves -the uptime (which of course *always* changes every call). - -So, in summary, if you consider a ticker script that will fire very -often but which you expect to do nothing 99% of the time, ponder if you -can handle things some other way. A self-reporting solution is usually -cheaper also for fast-updating properties. The main reason you do need a -ticker is rather when the timing itself is important. - -Ticker example - night/day system -================================= - -Let's take the example of a night/day system. The way we want to use -this is to have all outdoor rooms echo time-related messages to the -room. Things like "The sun sets", "The church bells strike midnight" and -so on. - -One could imagine every `Room `_ in the game having a -script running on themselves that fire regularly. It's however much -better (easier to handle and using a lot less computing resources) to -use a single, global, ticker script. You create a "global" Script the -way you would any Script except you don't assign it to any particular -object. - -To let objects use this global ticker, we will utilize a *subscription -model*. In short this means that our Script holds an internal list of -"subscribing" rooms. Whenever the Script fires it loops through this -list and calls a given method on the subscribed object. - -:: - - from ev import Script - class TimeTicker(Script): - """ - This implements a subscription model - """ - def at_script_creation(self): - "Called when script is created" - self.key = "daynight_ticker" - self.interval = 60 * 60 * 2 # every two hours - self.persistent = True - # storage of subscriptions - self.db.subscriptions = [] - def subscribe(self, obj): - "add object to subscription" - if obj not in self.db.subscriptions: - self.db.subscriptions.append(obj) - def unsubscribe(self, obj): - "remove object from subscription" - try: - del_ind = self.db.subscriptions.index(obj) - del self.db.subscriptions[del_ind] - except ValueError: - pass - def list_subscriptions(self): - "echo all subscriptions" - return self.db.subscriptions - def at_repeat(self): - "called every self.interval seconds" - for obj in self.db.subscriptions: - obj.echo_daynight() - -This depends on your subscribing weather rooms defining the -``echo_daynight()`` method (presumably outputting some sort of message). - -It's worth noting that the simple recipe above can be used for all sorts -of tickers. Rooms are maybe not likely to unsubscribe very often, but -consider a mob that "deactivates" when Characters are not around for -example. - -This particular TimeTicker-example could be further optimized. All -subscribed rooms are after all likely to echo the same time related -text. So this text can be pre-set already at the Script level and echoed -to each room directly. This way the subscribed objects won't need a -custom ``echo_daynight()`` method at all. - -Here's the more efficient example (only showing the new stuff). - -:: - - ... - ECHOES = ["The sun rises in the east.", - "It's mid-morning", - "It's mid-day", ...] - - class TimerTicker(Script): - ... - def at_script_creation(self): - ... - self.db.timeindex = 0 - ... - def at_repeat(self): - "called every self.repeat seconds" - echo = ECHOES[self.db.timeindex] - # msg_contents() is a standard method, so this - # ticker works with any object. - for obj in self.db.subscriptions: - obj.msg_contents(echo) - # resetting/stepping the counter - if self.db.timeindex == len(ECHOES) - 1: - self.db.timeindex = 0 - else: - self.db.timeindex += 1 - -Note that this ticker is unconnected to Evennia's default global in-game -time script, and will thus be out of sync with that. A more advanced -example would entail this script checking the current game time (in -``at_script_creation()`` or in ``at_start()``) so it can pick a matching -starting point in its cycle. - -Testing the night/day ticker ----------------------------- - -Tickers are really intended to be created and handled from your custom -commands or in other coded systems. An "outdoor" room typeclass would -probably subscribe to the ticker itself from its -``at_object_creation()`` hook. Same would be true for mobs and other -objects that could respond to outside stimuli (such as the presence of a -player) in order to subscribe/unsubscribe. - -There is no way to create a global script using non-superuser commands, -and even if you could use ``@script`` to put it on an object just to -test things out, you also need a way to subscribe objects to it. - -With ``@py`` this would be something like this: - - :: - - @py ev.create_script(TimeTicker) # if persistent=True, this only needs to be done once - @py ev.search_script("daynight_ticker").subscribe(self.location) - - -If you think you will use these kind of ticker scripts a lot, you might -want to create your own command for adding/removing subscriptions to -them. Here is a complete example: - -:: - - import ev - class CmdTicker(ev.default_cmds.MuxCommand): - """ - adds/remove an object to a given ticker - - Usage: - @ticker[/switches] tickerkey [= object] - Switches: - add (default) - subscribe object to ticker - del - unsubscribe object from ticker - - This adds an object to a named ticker Script, - if such a script exists. Such a script must have - subsribe/unsubscripe functionality. If no object is - supplied, a list of subscribed objects for this ticker - will be returned instead. - """ - key = "@ticker" - locks = "cmd:all()" - help_category = "Building" - - def func(self): - if not self.args: - self.caller.msg("Usage: @ticker[/switches] tickerkey [= object]") - return - tickerkey = self.lhs - # find script - script = ev.search_scripts(tickerkey) - if not script: - self.caller.msg("Ticker %s could not be found." % tickerkey) - return - # all ev.search_* methods always return lists - script = script[0] - # check so the API is correct - if not (hasattr(script, "subscribe") - and hasattr(script, "unsubscribe") - and hasattr(script, "list_subscriptions"): - self.caller.msg("%s can not be subscribed to." % tickerkey) - return - if not self.rhs: - # no '=' found, just show the subs - subs = [o.key for o in script.list_subscripionts()] - self.caller.msg(", ".join(subs)) - return - # get the object to add - obj = self.caller.search(self.rhs) - if not obj: - # caller.search handles error messages - return - elif 'del' in self.switches: - # remove a sub - script.unsubscribe(obj) - self.caller.msg("Unsubscribed %s from %s." % (obj.key, tickerkey) - else: - # default - add subscription - script.subscribe(obj) - self.caller.msg("Subscribed %s to ticker %s." % (obj.key, tickerkey)) - -This looks longer than it is, most of the length comes from comments and -the doc string. diff --git a/docs/sphinx/source/wiki/TutorialWorldIntroduction.rst b/docs/sphinx/source/wiki/TutorialWorldIntroduction.rst deleted file mode 100644 index a614340c04..0000000000 --- a/docs/sphinx/source/wiki/TutorialWorldIntroduction.rst +++ /dev/null @@ -1,136 +0,0 @@ -Tutorial World Introduction -=========================== - -The *Tutorial World* is, quite simply, a small example of Evennia usage -for you to learn from. It's also a functioning (if small) game - a -single-player quest area with some 20 rooms that you can explore on your -quest to find a mythical weapon. - -The source code is fully documented and you can find the whole thing in -``contrib/tutorial_world``. - -Some features exemplified by the tutorial world: - -- Tutorial command, giving "behind-the-scenes" help for every room and - some of the special objects -- Hidden exits -- Objects with multiple custom interactions -- Large-area rooms -- Outdoor weather rooms -- Dark room, needing light source -- Puzzle object -- Multi-room puzzle -- Aggressive mobile with roam, pursue and battle state-engine AI -- Weapons, also used by mobs -- Simple combat system with attack/defend commands -- Object spawn -- Teleporter trap rooms - -Install -------- - -The tutorial world consists of a a few modules in -``contrib/tutorial_world/`` containing custom -`Typeclasses `_ for `rooms and -objects `_, associated `commands `_ and a -few custom `scripts `_ to make things tick. - -These reusable bits and pieces are then put together into a functioning -game area ("world" is maybe too big a word for such a small zone) using -a `batch script `_ called ``build.ev``. To -install, log into the server as the superuser (user #1) and run: - -:: - - @batchcommand contrib.tutorial_world.build - -The world will be built (this might take a while, so don't rerun the -command even if it seems the system has frozen). After finishing you -will end up back in Limbo with a new exit called ``tutorial``. - -An alternative is - -:: - - @batchcommand/interactive contrib.tutorial_world.build - -with the /interactive switch you are able to step through the building -process at your own pace to see what happens in detail. - -To play the tutorial "correctly", you should *not* do so as superuser. -The reason for this is that many game systems ignore the presence of a -superuser and will thus not work as normal. Log out, then reconnect. -From the login screen, create a new, non-superuser character for playing -instead. As superuser you can of course examine things "under the hood" -later if you want. - -Gameplay --------- - -*To get into the mood of this miniature quest, imagine you are an -adventurer out to find fame and fortune. You have heard rumours of an -old castle ruin by the coast. In its depth a warrior princess was buried -together with her powerful magical weapon - a valuable prize, if it's -true. Of course this is a chance to adventure that you cannot turn -down!* - -*You reach the ocean in the midst of a raging thunderstorm. With wind -and rain screaming in your face you stand where the moor meets the sea -along a high, rocky coast ...* - -- Look at everything. -- Some objects are interactive in more than one way. Use the normal - ``help`` command to get a feel for which commands are available at - any given time. (use the command ``tutorial`` to get insight behind - the scenes of the tutorial). -- In order to fight, you need to first find some type of weapon. - - - *slash* is a normal attack - - *stab* launches an attack that makes more damage but has a lower - chance to hit. - - *defend* will lower the chance to taking damage on your enemy's - next attack. - -- You *can* run from a fight that feels too deadly. Expect to be chased - though. -- Being defeated is a part of the experience ... - -Uninstall ---------- - -Uninstalling the tutorial world basically means deleting all the rooms -and objects it consists of. First, move out of the tutorial area. - -:: - - @find tut#01 - @find tut#17 - -This should locate the first and last rooms created by ``build.ev`` - -*Intro* and *Outro*. If you installed normally, everything created -between these two numbers should be part of the tutorial. Note their -dbref numbers, for example 5 and 80. Next we just delete all objects in -that range: - -:: - - @del 5-80 - -You will see some errors since some objects are auto-deleted and so -cannot be found when the delete mechanism gets to them. That's fine. You -should have removed the tutorial completely once the command finishes. - -Notes ------ - -When reading and learning from the code, keep in mind that *Tutorial -World* was created with a very specific goal: to install easily and to -not permanently modify the rest of the server. It therefore goes to some -length to use only temporary solutions and to clean up after itself. -None of the basic typeclasses are modified more than temporarily. This -means the tutorial sometimes needs to solve things in a more complex -fashion than really needed. - -When coding your own game you'd of course not have such considerations - -you'd just customize the base typeclasses to always work just the way -you want and be done with it. diff --git a/docs/sphinx/source/wiki/Tutorials.rst b/docs/sphinx/source/wiki/Tutorials.rst deleted file mode 100644 index 5fe320b910..0000000000 --- a/docs/sphinx/source/wiki/Tutorials.rst +++ /dev/null @@ -1,54 +0,0 @@ -Evennia Tutorials -================= - -This is a summary of Evennia documentation available on a step-by-step -or tutorial-like format. - -Building --------- - -More building details are found in the `Builder -Docs `_. - -- `Tutorial: Building Quick-start `_ - -Coding basics -------------- - -More details about coding with Evennia is found in the `Developer -Central `_. - -- `First Steps Coding with Evennia `_ - this is - partly duplicated in the following two tutorials using different - words. -- `Tutorial: Adding a new default - command `_ -- `Tutorial: Adding new Object typeclasses and - defaults `_ - -Implementation ideas --------------------- - -Before starting to code your own game we recommend you read the -`Planning Your own game `_ page for some ideas of -organizing your workflow. There is also plenty of more information in -the `Developer Central `_. - -- `Tutorial: Removing Colour from your game (typeclass method - overloading) `_ -- `Tutorial: Adding a Command prompt `_ -- `Tutorial: Creating a Zoning system `_ -- `Hints: Implementing cooldowns for commands `_ -- `Hints: Designing commands that take time to - finish `_ -- `Hints: Ticker Scripts `_ - -Examples --------- - -See also ``evennia/contrib/`` and the example directories under -``game/gamesrc/``. - -- `The Tutorial - World `_ - diff --git a/docs/sphinx/source/wiki/Typeclasses.rst b/docs/sphinx/source/wiki/Typeclasses.rst deleted file mode 100644 index 34799d4f01..0000000000 --- a/docs/sphinx/source/wiki/Typeclasses.rst +++ /dev/null @@ -1,307 +0,0 @@ -Typeclassed entities -==================== - -How do you represent different objects in a game? What makes a bear -different from a stone, a character different from a house or a AI -script different from a script handling light and darkness? How do you -store such differences in the database? One way would be to create new -database tables for each type. So a bear would have a database field -"claws" and the stone would have fields specifying its weight and colour -... and you'd soon go crazy with making custom database manipulations -for all infinite combinations. - -Evennia instead uses very generic and simple database models and -"decorates" these with normal Python classes that specify their -functionality. Using Python classes means you get all the flexibility of -Python object management for free. - -There are four main game 'entities' in Evennia that are what we call -*typeclassed*. They are `Players `_, -`Objects `_, `Scripts `_ and -[Communications#Channels Channels]. This means that they are *almost* -normal Python classes - they behave and can be inherited from etc just -like normal Python classes. But whenever they store data they are infact -transparently storing this data into the database. - -|image0| - -In the above diagram, each of the Typeclassed entities are connected to -a *database model*. This handles all database interaction for you -without you needing to worry. The database model class is not changing. -But the Typeclass connected to it *can*. The typeclass roots (Object, -Script and Player) can have any number of subclasses to describe various -objects - above are some examples from the default distribution. - -The good news is that you should only need to worry about the typeclass -level, not about what happens behind the scenes with the database. - -It's easy to work with Typeclasses - just create a new class inheriting -from one of the base Typeclasses: - -:: - - from ev import Object - - class Furniture(Object): - # this defines what 'furniture' is - -Properties available to all typeclassed entities (Players, Objects, Scripts, Channels) --------------------------------------------------------------------------------------- - -All typeclassed entities share a few very useful properties and methods. - -- ``key`` - the main identifier for the entity, say 'Rose', 'myscript' - or 'Paul'. ``name`` is an alias that can also be used. -- ``date_created`` - time stamp when this object was created. -- ``locks`` - the `lockhandler `_ that manages access - restrictsions. Use locks.add(), locks.get() etc. -- ``dbref`` - the database id (database ref) of the object. This is a - unique integer. You can usually also use ``id``. -- ``is_typeclass(typeclass, exact=False)`` - Checks if this object has - a typeclass mathing the one given. If exact is False, it will accept - parents matching as well. -- ``delete()`` - Deletes the object -- ``swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)`` - - this will swap the object to another typeclass. You may choose to - clean out all attributes (this may be necessary if the new typeclass - is very different from the old one). The ``no_default`` dictates what - happens if the swap fails - if set it will revert back to the - pre-swap typeclass, otherwise it will fall back to the default class - as defined in your settings file. - -There are three further properties that warrant special mention: - -- ``db`` (DataBase) - this is the interface to the `Attribute - system `_, allowing for *persistently* storing your - own custom data on the entity (i.e. data that will survive a server - restart). -- ``ndb`` (NotDataBase) - this is equivalent to the functionality of - ``db`` but is used to store *non-peristent* data (i.e. data that will - be lost on server restart). -- ``dbobj`` - this is a reference to the *Database object* connected to - this typeclass (reversely, ``dbobj.typeclass`` is a reference back to - this very typeclass). - -As said, each of the typeclassed entities then extend this list with -their own properties. Go to the pages for `Objects `_, -`Scripts `_ and `Players `_ respectively for -more info. - -Things to remember when using !TypeClasses ------------------------------------------- - -Typeclasses *mostly* behave like normal Python classes - you can -add/overload custom methods and inherit your own classes from them - -most things you'd expect to be able to do with a Python class. There are -a few things that you need to remember however: - -- Create new instances of typeclasses using ``ev.create_*`` instead of - just initializing the typeclass. So use - ``ev.create_object(MyTypeclass, ...)`` to create a new object of the - type ``MyTypeclass``. Doing ``obj = MyTypeclass()`` will not work. -- Evennia will look for and call especially named *hook methods* on the - typeclass in different situations. Just define a new method on the - class named correctly and Evennia will call it appropriately. Hooks - are your main way to interact with the server. Available hook methods - are listed in the resepective base modules in ``game/gamesrc/``. -- Don't use the normal ``__init__()`` to set up your typeclass. It is - used by Evennia to set up the mechanics of the Typeclass system. Use - the designated hook method instead, such as ``at_object_creation()``, - ``at_player_creation()`` or ``at_script_creation()``. -- Don't re-implement the python special class methods - ``__setattr__()``, ``__getattribute__()`` and ``__delattr__()``. - These are used extensively by the Typeclass system. -- Some property names cannot be assigned to a Typeclassed entity due to - being used for internal Typeclass operations. If you try, you will - get an error. These property names are *id*, *dbobj*, *db*, *ndb*, - *objects*, *typeclass*, *attr*, *save* and *delete*. -- Even if they are not explicitly protected, you should not redefine - the "type" of the default typeclass properties listed above and on - each typeclassed entity (such as trying to store an integer in the - ``key`` property). These properties are often called by the engine - expecting a certain type of return, and some are even tied directly - to the database and will thus return errors if given a value of the - wrong type. -- *Advanced note*: If you are doing advanced coding you might (very - rarely) find that overloading ``__init__``, ``_setattr__`` etc allows - for some functionality not possible with hooks alone. You *can* do it - if you know what you are doing, but you *must* then remember to use - Python's built-in function ``super()`` to call the parent method too, - or you *will* crash the server! You have been warned. - -How typeclasses actually work -============================= - -*This is considered an advanced section. Skip it on your first -read-through unless you are really interested in what's going on under -the hood.* - -All typeclassed entities actually consist of two (three) parts: - -#. The *Typeclass* (a normal Python class with customized get/set - behaviour) -#. The *Database model* (Django model) -#. (`Attributes `_) - -The *Typeclass* is an almost normal Python class, and holds all the -flexibility of such a class. This is what makes the class special, some -of which was already mentioned above: - -- It inherits from ``src.typeclasses.typeclass.TypeClass``. -- ``__init__()`` is reserved for various custom startup procedures. -- It always initiates a property ``dbobj`` that points to a *Database - model*. -- It redefines python's normal ``__getattribute__()``, - ``__setattr__()`` and ``__delattr__`` on itself to relay all data on - itself to/from ``dbobj`` (i.e. to/from the database model). - -The related *Database model* in turn communicates data in and out of the -the database. The Database model holds the following (typeclass-related) -features: - -- It inherits from ``src.typeclasses.models.TypedObject`` (this - actually implements a - `idmapper `_-type model. - If that doesn't mean anything to you, never mind). -- It has a field ``typelclass_path`` that gives the python path to the - *Typeclass* associated with this particular model instance. -- It has a property *typeclass* that dynamically imports and loads the - *Typeclass* from ``typeclass_path``, and assigns itself to the - Typeclass' ``dbobj`` property. -- It redefines ``__getattribute__()`` to search its typeclass too, - while avoiding loops. This means you can search either object and - find also data stored on the other. - -The *Attributes* are not really part of the typeclass scheme, but are -very important for saving data without having to change the database -object itself. They are covered in a separate entry -`here `_. - -Why split it like this? ------------------------ - -The *Database model* (Django model) allows for saving data to the -database and is a great place for storing persistent data an object -might need during and between sessions. But it is not suitable for -representing all the various objects a game needs. You *don't* want to -have to redefine a new database representation just because a -``CarObject`` needs to look and behave differently than a -``ChairObject``. So instead we keep the database model pretty "generic", -and only put database Fields on it that we know that *all* objects would -need (or that require fast and regular database searches). Examples of -such fields are "key" and "location". - -Enter the *Typeclass*. For lack of a better word, a typeclass -"decorates" a Django database model. Through the re-definition of the -class' get/set methods, the typeclass constantly communicates behind the -scenes with the Django model. The beauty of it is that this is all -hidden from you, the coder. As long as you don't overwrite the few magic -methods listed above you can deal with the typeclass almost as you would -any normal Python class. You can extend it, inherit from it, and so on, -mostly without caring that it is infact hiding a full persistent -database representation. So you can now create a typeclass-class -*Flowers* and then inherit a bunch of other typeclass-classes from that -one, like *Rose*, *Tulip*, *Sunflower*. As your classes are instantiated -they will each secretly carry a reference to a database model to which -all data *actually* goes. We, however, can treat the two as if they -where one. - -Below is a schematic of the database/typeclass structure. - -|image1| - -Let's see how object creation looks like in an example. - -#. We have defined a Typeclass called *Rose* in - ``game.gamesrc.objects.flower.Rose``. It inherits from - ``game.gamesrc.objects.baseobjects.Object``, which is a grandchild of - ``src.typeclasses.typeclass.TypeClass``. So the rose a typeclassed - object, just as it should be. -#. Using a command we create a new *Rose* instance *RedRose* (e.g. with - ``@create redrose:flowers.Rose``). -#. A new database model is created and given the key *RedRose*. Since - this is an `Object `_ typeclass (rather than a Script - or Player), the database model used is - ``src.objects.models.ObjectDB``, which inherits directly from - ``src.typeclasses.models.TypedObject``). -#. This new Django-model instance receives the python-path to the *Rose* - typeclass and stores it as a string on itself (in a database field - ``typeclass_path``). When the server restarts in the future, the - database model will restart from this point. -#. The database model next *imports* the Typeclass from its stored path - and creates a new instance of it in memory. It stores a reference to - this instance of *Rose* (*RedRose*)in a property called - ``typeclass``. -#. As *Rose* is instantiated, its ``__init__()`` method is called. What - this does it to make sure to store the back-reference to the Django - model on our new *Rose* instance. This back-reference is called - ``dbobj``. -#. The creation method next runs the relevant startup hooks on the - typeclass, such as ``at_object_creation()``. - -Using the ``.db`` operator of Typeclasses will store Attributes of the -right type in the database. So ``RedRose.db.thorns = True`` will create -a new Attribute named "thorns" where the boolean value ``True`` will be -stored. - -On the other hand, storing RedRose.thorns will just store the data as a -normal property (the Typeclass will actually transparently relay this so -it's always stored on the database model). Due to caching reasons but -also for the sake of clarity and readability, it's strongly recommended -that you store temporary variables using the ``ndb`` operator, such as -``RedRose.ndb.newly_planted=True``. - -In the opposite direction, reading properties can also mean accessing -methods that you want to overload. For example, the ``ObjectDB`` -database model holds a method ``msg`` that you might want to overload -with your own version. - -So accessing ``RedRose.msg`` will *first* search the RedRose typeclass -to see if it holds a custom ``msg`` and only if it fails it will -continue on to search the properties on the database object. An example -of a Typeclass overloading ``msg`` is found -[`CommandPrompt `_\ #Prompt\_on\_the\_same\_line -here]. This is another good reason for using ``db/ndb`` handlers - they -make it clear if you are creating/reading an Attribute and is not trying -to access a method on the class. - -Here is a diagram exemplifying Attribute access: - -|image2| - -Caveats of the typeclass system -------------------------------- - -While there are many advantages to the typeclass system over working -with Django models directly, there are also some caveats to remember. - -Be careful when not using Evennia's search and create methods. Almost -all code in evennia (including default commands) assume that what is -returned from searches or creates are Typeclasses, not Django models -(i.e. the first of the two in the pair). This is what you get if you use -any of the model manager methods, and also the create/search functions -in ``src.utils.create`` and ``src.utils.search``. Old Django-gurus will -find it tempting to use Django's in-build database query methods, such -as ``ObjectDB.objects.filter()`` to get data. This works, but the result -will then of course *not* be a typeclass but a Django model object (a -query). You can easily convert between them with ``dbobj.typeclass`` and -``typeclass.dbobj``, but you should be aware of this distinction. - -:: - - obj = ObjectDB.objects.get_id(1) # custom evennia manager method. This returns the typeclass. - obj = ObjectDB.objects.get(1) # standard Django. Returns a Django model object. - -Even more important to know for Django affectionados: Evennia's custom -methods return *lists* where you with normal Django methods would expect -``Query`` objects (e.g. from the ``filter()`` method). As long as you -don't confuse what result type you are dealing with (for example you -cannot 'link' ``list``\ s together the way you can ``Querysets``), you -should be fine. - -Read the ``manager.py`` files in each relevant folder under ``src/`` to -see which database access methods are available. - -.. |image0| image:: https://lh4.googleusercontent.com/-jMrRjLRQiHA/UZIKiDgGECI/AAAAAAAAB3Y/YUzHZlgVFTY/w480-h282-no/typeclasses_overview.png -.. |image1| image:: https://lh4.googleusercontent.com/-HNUhh6xCYpY/UZISHoSucxI/AAAAAAAAB4I/2ThUbuAbosg/w865-h634-no/typeclasses2a.png -.. |image2| image:: https://lh5.googleusercontent.com/-oCqy1f1ZFRA/UZIWeg0ll8I/AAAAAAAAB4g/-ewUvQ439y4/w681-h634-no/typeclasses2.png diff --git a/docs/sphinx/source/wiki/UnitTesting.rst b/docs/sphinx/source/wiki/UnitTesting.rst deleted file mode 100644 index 789e19e2d6..0000000000 --- a/docs/sphinx/source/wiki/UnitTesting.rst +++ /dev/null @@ -1,128 +0,0 @@ -Unit Testing -============ - -*This topic is mainly of interest to people interested in helping to -develop Evennia itself.* - -Unit testing means testing components of a program in isolation from -each other to make sure every part works on its own before using it with -others. Extensive testing helps avoid new updates causing unexpected -side effects as well as alleviates general code rot (a more -comprehensive wikipedia article on unit testing can be found -`here `_). - -A typical unit test calls some component of Evennia with a given input, -looks at the result and makes sure that this result looks as expected. -Rather than having lots of stand-alone test programs, Evennia makes use -of a central *test runner*. This is a program that gathers all available -tests all over the Evennia source code (called *test suites*) and runs -them all in one go. Errors and tracebacks are reported. - -Running the test suite ----------------------- - -To run the Evennia test suite, go to the ``game/`` folder and issue the -command - - ``python manage.py test`` - -A temporary database will be instantiated to manage the tests. If -everything works out you will see how many tests were run and how long -it took. If something went wrong you will get error messages. - -Writing new tests ------------------ - -Evennia's test suite makes use of Django unit test system, which in turn -relies on Python's *unittest* module. Evennia's test modules are always -named ``tests.py`` and should be located in different sub folders of -``src/`` depending on which system they are testing. You can find an -example of a testing module in ``src/objects/tests.py``. - -Inside the ``tests.py`` module you create classes inheriting from -``django.test.TestCase`` (later versions of Django will use -``django.utils.unittest.TestCase`` instead). A ``TestCase`` class is -used to test a single aspect or component in various ways. Each test -case contains one ore more *test methods* - these define the actual -tests to run. You can name the test methods anything you want as long as -the name starts with "``test_``\ ". Your ``TestCase`` class can also -have a method SetUp(). This is run before each test, setting up whatever -preparations the test methods need. - -To test the results, you use special methods of the ``TestCase`` class. -Many of those start with "``assert``\ ", such as ``assertEqual`` or -``assertTrue``. - -Example of a ``TestCase`` class (inside a file ``tests.py``): - -:: - - - # testing a simple funcion - - try: - # this is an optimized version only available in later Django versions - from django.utils.unittest import TestCase - except ImportError: - # if the first fail, we use the old version - from django.test import TestCase - - # the function we want to test - from mypath import myfunc - - TestObj(unittest.TestCase): - "This tests a function myfunc." - - def test_return_value(self): - "test method. Makes sure return value is as expected." - expected_return = "This is me being nice." - actual_return = myfunc() - # test - self.assertEqual(expected_return, actual_return) - def test_alternative_call(self): - "test method. Calls with a keyword argument." - expected_return = "This is me being baaaad." - actual_return = myfunc(bad=True) - # test - self.assertEqual(expected_return, actual_return) - -The above example is very simplistic, but you should get the idea. Look -at ``src/objects/tests.py`` for more realistic examples of tests. You -might also want to read the `documentation for the unittest -module `_. - -Testing in-game Commands ------------------------- - -In-game Commands are a special case. Tests for the default commands are -put in ``src/commands/default/tests.py``. This test suite is executed as -part of running the ``objects`` test suite (since it lies outside -Django's normal "app" structure). It also supplies a few convenience -functions for executing commands (notably creating a "fake" player -session so as to mimic an actual command call). It also makes several -test characters and objects available. For example ``char1`` is a -"logged in" Character object that acts as the one calling the command. - -Each command tested should have its own ``TestCase`` class. Inherit this -class from the ``CommandTest`` class in the same module to get access to -the command-specific utilities mentioned. - -:: - - class TestSet(CommandTest): - "tests the @set command by simple call" - def test_call(self): - self.execute_command("@set self/testval = mytestvalue") - # knowing what @set does, our test character (char1) should - # by now have a new attribute 'testval' with the value 'mytestvalue'. - self.assertEqual("mytestvalue", self.char1.db.testval) - -A note on adding new tests --------------------------- - -Having an extensive tests suite is very important for avoiding code -degradation as Evennia is developed. Only a small fraction of the -Evennia codebase is covered by test suites at this point. Writing new -tests is not hard, it's more a matter of finding the time to do so. So -adding new tests is really an area where everyone can contribute, also -with only limited Python skills. diff --git a/docs/sphinx/source/wiki/UpdatingYourGame.rst b/docs/sphinx/source/wiki/UpdatingYourGame.rst deleted file mode 100644 index 7a1bb53620..0000000000 --- a/docs/sphinx/source/wiki/UpdatingYourGame.rst +++ /dev/null @@ -1,126 +0,0 @@ -Updating your Game -================== - -Fortunately, it's extremely easy to keep your Evennia server up-to-date -via Mercurial. If you haven't already, see the `Getting Started -guide `_ and get everything running. There are many -ways to get told when to update: You can subscribe to the RSS feed or -manually check up on the feeds from -`http://www.evennia.com `_. You can also join -the `Evennia Commit -Log `_ group, which -will send you an email when the server repository changes. - -When you're wanting to apply updates, simply ``cd`` to your ``evennia`` -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 -and either right click and find your client's pull function, or use one -of the menus (if applicable). - -You can review the latest changes with - -:: - - hg log - -or the equivalent in the graphical client. The log tends to scroll past -quite quickly, so if you are in linux it might be an idea to *pipe* the -output to a text reader like ``less`` -(`here `_ is a more -permanent solution): - -:: - - hg log | less - -You can also see the latest changes online -`here `_. - -Resetting your database ------------------------ - -Should you ever want to start over completely from scratch, there is no -need to re-download Evennia or anything like that. You just need to -clear your database. Once you are done, you just rebuild it from scratch -as described in step 2 of the `Getting Started -guide `_. - -First stop a running server with ``game/python evennia.py stop``. - -If you run the default ``SQlite3`` database (to change this you need to -edit your ``settings.py`` file), the database is actually just a normal -file in ``game/`` called ``evennia.db3``. Simply delete that file - -that's it. - -Regardless of which database system you use, you can reset your database -via ``game/manage.py``. Since Evennia consists of many separate -components you need to clear the data from all of them: - -:: - - python manage.py reset server objects players scripts comms help web auth - -Django also offers an easy way to start the database's own management -should we want more direct control: - -:: - - python manage.py dbshell - -In e.g. MySQL you can then do something like this (assuming your MySQL -database is named "Evennia": - -:: - - mysql> DROP DATABASE Evennia; - mysql> exit - -A Note on Schema Migration --------------------------- - -If and when an Evennia update modifies the database *schema* (that is, -the under-the-hood details as to how data is stored in the database), -you must update your existing database correspondingly to match the -change. If you don't, the updated Evennia will complain that it cannot -read the database properly. Whereas schema changes should become more -and more rare as Evennia matures, it may still happen from time to time. - -One way to handle this is to apply the changes manually to your database -using the database's command line. This often means adding/removing new -tables or fields as well as possibly convert existing data to match what -the new Evennia version expects. It should be quite obvious that this -quickly becomes cumbersome and error-prone. If your database doesn't -contain anything critical yet it's probably easiest to simply reset it -and start over rather than to bother converting. - -Enter `South `_. South keeps track of -changes in the database schema and applies them automatically for you. -Basically, whenever the schema changes we also distribute small files -called "migrations" with the source. Those tell South exactly how to -repeat that change so you don't have to do so manually. - -Using South is optional, but if you do install it, Evennia *will* use -South automatically. See the correct section of -`GettingStarted `_ on how to install South and the -slightly different way to start a clean database server when South is -used (you have to give the ``mange.py migrate`` command as well as -``manage.py syncdb``). - -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`` after you pulled the latest stuff, or read the -online list), you go to ``game/`` and run this command: - -:: - - python manage.py migrate - -This will convert your database to the new schema and you should be set -to go. diff --git a/docs/sphinx/source/wiki/UsingMUXAsAStandard.rst b/docs/sphinx/source/wiki/UsingMUXAsAStandard.rst deleted file mode 100644 index 461287accb..0000000000 --- a/docs/sphinx/source/wiki/UsingMUXAsAStandard.rst +++ /dev/null @@ -1,102 +0,0 @@ -The 'MUX-like' default of Evennia -================================= - -Evennia is a highly customizable codebase. Among many things, its -command structure and indeed the very way that commands look can all be -changed by you. If you like the way, say, DikuMUDs handle things, you -could emulate that with Evennia. Or LPMuds, or MOOs. Or if you are -ambitious you could design a whole new style, perfectly fitting your own -dreams of the ideal MUD. - -We do offer a default however. The default Evennia setup tend to -resemble `MUX2 `_, and its cousins -`PennMUSH `_, -`TinyMUSH `_, and -`RhostMUSH `_. By default we emulate these -Tiny derivatives (MUX2, Penn, etc) in the user interface and building -commands. We believe these codebases have found a good way to do things -in terms of building and administration. We hope this will also make it -more familiar for new users coming from those communities to start using -Evennia. - -However, Evennia has taken a completely different stance on how admins -extend and improve their games. Instead of implementing a special -in-game language (SoftCode), all game extension is done through Python -modules, like the rest of Evennia. This gives the admin practically -unlimited power to extend the game leveraging the full power of a mature -high level programming language. You can find a more elaborate -discussion about our take on MUX SoftCode `here `_. - -Documentation policy --------------------- - -All the commands in the default command sets have their doc-strings -formatted on a similar form: - -:: - - """ - Short header - - Usage: - key[/switches, if any] [] - - Switches: - switch1 - description - switch2 - description - - Examples: - usage example and output - - Longer documentation detailing the command. - - """ - -The ``Switches`` and ``Examples`` headers can be skipped if not needed. -Here is the ``nick`` command as an example: - -:: - - """ - Define a personal alias/nick - - Usage: - nick[/switches] = [] - alias '' - - Switches: - object - alias an object - player - alias a player - clearall - clear all your aliases - list - show all defined aliases (also "nicks" works) - - Examples: - nick hi = say Hello, I'm Sarah! - nick/object tom = the tall man - - A 'nick' is a personal shortcut you create for your own use [...] - - """ - -For commands that *require arguments*, the policy is for it to return a -``Usage`` string if the command is entered without any arguments. So for -such commands, the Command body should contain something to the effect -of - -:: - - if not self.args: - self.caller.msg("Usage: nick[/switches] = []") - return - -WWMD - What Would MUX Do? -------------------------- - -Our original policy for implementing the default commands was to look at -MUX2's implementation and base our command syntax on that. This means -that many default commands have roughly similar syntax and switches as -MUX commands. There are however many differences between the systems and -readability and usability has taken priority (frankly, the MUX syntax is -outright arcane in places). So the default command sets can be -considered to implement a "MUX-like" dialect - whereas the overall feel -is familiar, the details may differ considerably. diff --git a/docs/sphinx/source/wiki/VersionControl.rst b/docs/sphinx/source/wiki/VersionControl.rst deleted file mode 100644 index 6cab2c9921..0000000000 --- a/docs/sphinx/source/wiki/VersionControl.rst +++ /dev/null @@ -1,257 +0,0 @@ -Setting up a coding environment with version control -==================================================== - -Version control software allows you to easily backtrack changes to your -code, help with sharing your development efforts and more. Even if you -are not contributing to Evennia itself, but is "just" developing your -own game, having a version control system in place is a good idea. If -you want more info, start with the wikipedia article about it -`here `_. Note that this -page deals with commands in the Linux operating system. Details may vary -for other systems. - -Note: This is only one suggested way to use Mercurial by using separate -local clones. You could set up any number of different workflows if it -suited you better. See `here `_ for -some more examples. - -Using Mercurial -=============== - -`Mercurial `_ (abbreviated as ``hg`` -after the chemical symbol for mercury) is a version control system -written mainly in Python. It's available for all major platforms. - -First, identify to mercurial by creating a new file ``.hgrc`` in your -home directory and put the following content in it: - -:: - - [ui] - username = MyName - -You can put a nickname here too if you want. This is just so the system -knows how to credit new revisions. - -Setting up ----------- - -We will here assume you are downloading Evennia for the first time. We -will set up a simple environment for hacking your game in. In the end it -will look like this: - -:: - - evennia/ - evennia-main - evennia-mygame - -Create a new folder ``evennia`` and clone Evennia into it as -``evennia-main``: - -:: - - hg clone https://code.google.com/p/evennia/ evennia-main - -A new folder ``evennia-main`` has appeared. In it you will find the -entire Evennia source repository, including all its commit history - -it's really a full copy of what's available on the web. - -We'll let ``evennia-main`` only contain the "clean" Evennia install - -it's a good debugging tool to tell you if a bug you find is due to your -changes or also visible in the core server. We'll develop our game in -another repository instead: - -:: - - hg clone evennia-main evennia-mygame - -This will create a new repository ``evennia-mygame`` on your machine. In -this directory you now code away, adding and editing things to your -heart's content to make your dream game. - -Example work flow ------------------ - -First we make sure our copy of Evennia is up-to-date. Go to -``evennia-main``: - -:: - - cd evennia-main - hg pull - -Mercurial goes online and gets the latest Evennia revision from the -central repository, merging it automatically into your repository. It -will tell you that you need to ``update`` to incoorporate the latest -changes. Do so. - -:: - - hg update - -So ``evennia-main`` is now up-to-date. If you want, you can review the -changes and make sure things work as they should. Finally go to -``evennia-mygame`` and pull the changes into that as well. - -:: - - - cd ../evennia-mygame - hg commit # (only if you had any changes) - hg pull ../evennia-main - hg update - -You can now continue to hack away in ``evennia-mygame`` to build your -game. Maybe you define new commands, economic systems, create batchfiles -or what have you. If you create any new files, you must tell Mercurial -to track them by using the ``add`` command: - -:: - - hg add - -Check the current status of the version control with - -:: - - hg status - -If you don't get any return value, you haven't made any changes since -last commit. Otherwise you will get a list of modified files. - -It's usually a good idea to commit your changes often - it's fast and -only local - you will never commit anything online. This gives you a -"save" snapshot of your work that you can get back to. - -:: - - hg commit - -This will open a text editor where you can add a message detailing your -changes. These are the messages you see in the Evennia update/log list. -If you don't want to use the editor you can set the message right away -with the ``-m`` flag: - -:: - - hg commit -m "This should fix the bug Sarah talked about." - -If you did changes that you wish you hadn't, you can easily get rid of -everything since your latest commit: - -:: - - hg revert --all - -Instead of ``--all`` you can also choose to revert individual files. - -You can view the full log of committed changes with - -:: - - hg log - -See the Mercurial manuals for learning more about useful day-to-day -commands, and special situations such as dealing with text collisions -etc. - -Sharing your code with the world -================================ - -The most common case of this is when you have fixed an Evennia bug and -want to make the fix available to Evennia maintainers. But you can also -share your work with other people on your game-development team if you -aren't worried about the changes being publicly visible. - -Let's take the example of debugging Evennia. Go online and create an -"online clone" of Evennia as described `here `_. Pull -this repo to your local machine -- so if your clone is named -``my-evennia-fixes``, you do something like this: - -:: - - hg clone https://@code.google.com/r/my-evennia-fixes evennia-fixes - -You will now have a new folder ``evennia-fixes``. Let's assume we want -to use this to push bug fixes to Evennia. It works like any other -mercurial repository except you also have push-rights to your online -clone from it. When working, you'd first update it to the latest -upstream Evennia version: - -:: - - cd evennia-main - hg pull - hg update - cd ../evennia-fixes - hg pull ../evennia-main - hg update - -Now you fix things in ``evennia-fixes``. Commit your changes as -described above. Make sure to make clear and descriptive commit messages -so it's easy to see what you intended. You can do any number of commits -as you work. Once you are at a stage where you want to show what you did -to the world, you push all the so-far committed changes to your online -clone: - -:: - - hg push - -(You'd next need to tell Evennia devs that they should merge your -brilliant changes into Evennia proper. Create a new -`Issue `_ of type *Merge -Request*, informing them of this.) - -Apart from supporting Evennia itself you can have any number of online -clones for different purposes, such as sharing game code or collaborate -on solutions. Just pull stuff from whichever relevant local repository -you have (like ``evennia-mygame``) and push to a suitably named online -clone so people can get to it. - -Sharing your code only with a small coding team -=============================================== - -Creating a publicly visible online clone might not be what you want for -all parts of your development process - you may prefer a more private -venue when sharing your revolutionary work with your team. - -An online hosting provider offering private repositories is probably -your best bet. For example, if all your contributors are registered on -`BitBucket `_, that service offers free -"private" repositories that you could use for this. - -An alternative simple way to share your work with a limited number of -people is to use mercurial's own simple webserver and let them connect -directly to your machine: - -:: - - cd evennia-mygame - hg serve -p 8500 - -(the port was changed because the default port is 8000 and that is -normally used by Evennia's own webserver). Find out the IP address of -your machine visible to the net (make sure you know your firewall setup -etc). Your collaborators will then be able to first review the changes -in their browser: - -:: - - firefox http://192.168.178.100:8500 - -and pull if they like what they see: - -:: - - hg pull http://192.168.178.100:8500 - -See `here `_ for more -information on using ``hg serve``. - -Mercurial's in-built webserver is *very* simplistic and not particularly -robust. It only allows one connection at a time, lacks authorization and -doesn't even allow your collaborators to ``push`` data to you (there is -nothing stopping them to set up a server of their own so you can pull -from them though). diff --git a/docs/sphinx/source/wiki/WebFeatures.rst b/docs/sphinx/source/wiki/WebFeatures.rst deleted file mode 100644 index 2882d6e9de..0000000000 --- a/docs/sphinx/source/wiki/WebFeatures.rst +++ /dev/null @@ -1,74 +0,0 @@ -Web Features -============ - -Evennia is its own webserver and hosts a default website and browser -webclient. - -Editing the Web site --------------------- - -The Evennia website is a Django application that ties in with the MUD -database. It allows you to, for example, tell website visitors how many -players are logged into the game at the moment, how long the server has -been up and any other database information you may want. The dynamic -website application is located in ``src/web/website`` whereas you will -find the html files in ``src/web/templates/prosimii``. Static media such -as images, css and javascript files are served from ``src/web/media``. - -You can access the website during development by going to -``http://localhost:8000``. - -Since it's not recommended to edit files in ``src/`` directly, we need -to devise a way to allow website customization from ``game/gamesrc``. -This is not really finalized at the current time (it will be easier to -share media directories in Django 1.3) so for now, your easiest course -of action is as follows: - -#. Copy the entire ``src/web`` directory into ``game/gamesrc/`` and do - your modifications to the copy. Make sure to retain permissions so - the server can access the directory (in linux you can do this with - something like ``cp -ra src/web game/gamesrc/``) -#. Re-link all relevant path variables to the new location. In settings - add the following lines: - -:: - - ROOT_URLCONF = "game.gamesrc.web.urls" - TEMPLATE_DIRS = (os.path.join(GAME_DIR, "gamesrc", "web", "templates", ACTIVE_TEMPLATE),) - MEDIA_ROOT = os.path.join(GAME_DIR, "gamesrc", "web", "media"`). - -#. Reload the server (you want to also restart the Portal at this point - to make sure it picks up the new web location). - -You should now have a separate website you can edit as you like. Be -aware that updates we do to ``src/web`` will not transfer automatically -to your copy, so you'll need to apply updates manually. - -Web client ----------- - -Evennia comes with a MUD client accessible from a normal web browser. It -is technically a javascript client polling an asynchronous webserver -through long-polling (this is also known as a *COMET* setup). The -webclient server is defined in ``src/server/webclient`` and is not -something that should normally need to be edited unless you are creating -a custom client. The client javascript, html and css files are located -under the respective folders of ``src/web/``. - -The webclient uses the `jQuery `_ javascript -library. This is imported automatically over the internet when running -the server. If you want to run the client without an internet -connection, you need to download the library from the jQuery homepage -and put it in ``src/web/media/javascript``. Then edit -``src/web/templates/prosimii/webclient.html`` and uncomment the line: - -:: - - - -(edit it to match the name of the ``*.js`` for the jQuery version you -downloaded). - -The webclient requires the webserver to be running and is then found on -``http://localhost:8000/webclient``. For now it's best to follow the -procedure suggested in the previous section if you want to customize it. diff --git a/docs/sphinx/source/wiki/Workshop.rst b/docs/sphinx/source/wiki/Workshop.rst deleted file mode 100644 index f960922801..0000000000 --- a/docs/sphinx/source/wiki/Workshop.rst +++ /dev/null @@ -1,129 +0,0 @@ -rtclient protocol -================= - -*Note: Most functionality of a webcliebnt implementation is already -added to trunk as of Nov 2010. That implementation does however not use -a custom protocol as suggested below. Rather it parses telnet-formatted -ansi text and converts it to html. Custom client operations (such as -opening windows or other features not relevant to telnet or other -protocols) should instead eb handled by a second "data" object being -passed to the server through the msg() method.* - -rtclient is an extended and bastardized telnet protocol that processes -html and javascript embedded in the telnet session. - -rtclient is implemented by the Teltola client, a web-based html/js -telnet client that is being integrated with Evennia and is written in -twisted/python. - -There are two principle aspects to the rtclient protocol, mode control -and buffering. - -Modes -===== - -Unencoded Mode --------------- - -All output is buffered until ascii char 10, 13, or 255 is encountered or -the mode changes or no output has been added to the buffer in the last -1/10th second and the buffer is not blank. When this occurs, the client -interprets the entire buffer as plain text and flushes the buffer. - -HTML Mode ---------- - -All output is buffered. When the mode changes, the client then parses -the entire buffer as HTML. - -Javascript Mode ---------------- - -All output is buffered. When the mode changes, the client then parses -the entire buffer as Javascript. - -Sample Sessions -=============== - -# start html mode, send html, force buffer flush - -:: - - session.msg(chr(240) + "

Test

" + chr(242) + chr(244)) - -# same as above, but realize that msg sends end-of-line # automatically -thus sending the buffer via AUTO\_CHNK - -:: - - session.msg(chr(240) + "

Test

" + chr(242)) - -# more elaborate example sending javascript, html, and unbuffered text # -note we are using the tokens imported instead of the constants - -:: - - from game.gamesrc.teltola.RTClient import HTML_TOKEN, JAVASCRIPT_TOKEN, UNENCODED_TOKEN - hello_world_js = "alert('hello world');" - welcome_html = "

Hello World

" - session.msg("".join([JAVASCRIPT_TOKEN, hello_world_js, HTML_TOKEN, welcome_html, UNENCODED_TOKEN,"Hello there."])) - -:: - - session.msg(chr(243)) - session.msg(my_text_with_line_breaks) - session.msg(chr(244)) - -Values of Tokens -================ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| chr() value \| name \| function | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 240 \| HTML\_TOKEN \| lets client know it is about to receive HTML | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 241 \| JAVASCRIPT\_TOKEN \| lets client know it is about to receive javascript | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 242 \| UNENCODED\_TOKEN \| lets client know it is about to receive plain telnet text | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 243 \| NO\_AUTOCHUNK\_TOKEN \| applies to unencoded mode only, prevents the chunking of text at end-of-line characters so that only mode changes force the buffer to be sent to the client | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 244 \| AUTOCHUNK\_TOKEN \| applies to unencoded mode only, enables automatic chunking of text by end-of-line characters and by non-blank buffers not having been written to in the last 1/10th second | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -identifying as an rtclient --------------------------- - -rtclients send the text rtclient\\n immediately after connection so that -the server may enable rtclient extensions - -Buffering Control ------------------ - -Unbuffered output is not supported. There are two different buffering -methods supported. The default method is called AUTOCHUNK and applies -only to unencoded data (see data encoding section below). JAVASCRIPT and -HTML data is always treated as NO\_AUTOCHUNK. - -NO\_AUTOCHUNK -~~~~~~~~~~~~~ - -Contents are never sent to the client until the encoding mode changes -(for example, switching from HTML to UNENCODED will send the HTML -buffer) or the buffering mode changes (for example, one could set -NO\_AUTOCHUNK, send some text, and set NO\_AUTOCHUNK again to force a -flush. - -AUTOCHUNK -~~~~~~~~~ - - It sends the buffer to the client as unencoded text whenever one of - two things happen: - -**the buffer is non-blank but hasn't had anything added to it very -recently (about 1/10th of a second)** the buffer ends with an -end-of-line character (10, 13, 255) - -Autochunking strips end-of-line characters and the client adds in its -own EOL! If you would like to preserve them, send them from within -NO\_AUTOCHUNK. diff --git a/docs/sphinx/source/wiki/WorkshopDefaultGame.rst b/docs/sphinx/source/wiki/WorkshopDefaultGame.rst deleted file mode 100644 index b357d24fe2..0000000000 --- a/docs/sphinx/source/wiki/WorkshopDefaultGame.rst +++ /dev/null @@ -1,297 +0,0 @@ -**Status Update**:*There does not seem to be any active development on -this by the original initiator (rcaskey). As far as I know there is no -active game code written apart from a Smaug area converter (how -complete?). If anyone is willing to continue with this particular idea, -they are welcome to do so. I will help out but I don't know anything -about Smaug myself. In the interim I will chalk this one down as being a -stalled project. /Griatch* - -Introduction -============ - -This is(was?) an initiative to create a "base" game system to be shipped -with Evennia in a "contrib" folder. The game is an independent -re-implementation of the basic stuff of the -`SMAUG `_ system. No code from the original will -be used, and no licensed content will be included in the release. For -easy testing of content, rcaskey's SMAUG importer will be used. - -TODO, first prototype -===================== - -The first stage serves to establish a prototype implementation - -something that shows the parts hanging together, but with only a subset -of the functionality. - -#. Create custom `TypeClasses `_ supporting the SMAUG - system: - - - Object->SmaugObject->SmaugBeing->SmaugCharacter,Character - - Object->SmaugObject->SmaugBeing->SmaugMob-> ... - - Object->SmaugObject->SmaugThing-> ... - -#. Create limited subclasses or attributes on objects - - - Limited classes/races (1-2?) - - Skills (`_. Tags -are short labels that you attach to objects. They make it very easy to -retrieve groups of objects. An object can have any number of different -tags. So let's attach the relevant tag to our forest: - -:: - - forestobj.tags.add("magicalforest", category="zone") - -You could add this manually, or automatically during creation somehow -(you'd need to modify your @dig command for this, most likely). - -Henceforth you can then easily retrieve only objects with a given tag: - -:: - - import ev - rooms = ev.managers.Tags.get_objs_with_tag("magicalforest", category="zone") # (error here) - -Zones using Aliases -~~~~~~~~~~~~~~~~~~~ - -All objects have a *key* property, stored in the database. This is the -primary name of the object. But it can also have any number of *Aliases* -connected to itself. This allows Players to refer to the object using -both key and alias - a "big red door" can also be referred to as the -alias "door". Aliases are actually separate database entities and are as -such very fast to search for in the database, about as fast as searching -for the object's primary key in fact. - -This makes Aliases another candidate for implementing zones. All you -need to do is to come up with a consistent aliasing scheme. Here's one -suggestion: - -:: - - #zonename|key - -There is nothing special about this format; it's just a string we store -- a way to clump the zone-name and the room-key together in a "tag" we -can easily find and match against later. We could have used a format -like ``"zonename.key"`` or ``"ZONE:zonename,ROOMNAME:key"`` or some -other combination if we liked that better. So, using our suggested -format we assume we (arbitrarily) divide our forest example into the -zones ``magicforest`` and ``normalforest``. These are the added aliases -we use for the respective *Meadow* 's: - -:: - - #magicforest|meadow - #normalforest|meadow - -The primary key of each will still be *Meadow*, and players will still -see that name. We can also add any number of other Aliases to each -meadow if we want. But we will also henceforth always be able to -uniquely identify the right meadow by prepending its primary key name -with ``#zonename|``. - -Enforcing zones ---------------- - -Maybe you feel that this usage of aliases for zones is loose and ad-hoc. -It is indeed, and there is no guarantee that a builder would follow the -naming convention - unless you force them. And you can do that easily by -changing for example the ``@dig`` `Command `_ to require -the zone to be given: - -:: - - @dig zone|roomname:typeclass = north;n, south;s - -Just have the ``@dig`` command auto-add an alias of the correct format -and hey-presto! A functioning zone system! An even more convenient way -to enforce zones would be for the new room to inherit the zone from the -room we are building from. - -Overload the default ``search`` method on a typeclass for further -functionality: - -:: - - def search(self, ostring, zone=None, *args, **kwargs): - if zone: - ostring = "#%s|%s" % (ostring, zone) - return self.dbobj.search(ostring, *args, **kwargs) - -You will then be able to do, from commands: - -:: - - meadow_obj = self.caller.search("meadow", zone="magicforest") - -and be sure you are getting the magical meadow, not the normal one. - -You could also easily build search queries searching only for rooms with -aliases starting with ``#magicforest|``. This would allow for easy -grouping and retrieving of all rooms in a zone for whatever need to -have. - -Evennia's open solution to zones means that you have much more power -than in most MUD systems. There is for example no reason why you have to -group and organize only rooms with this scheme. - -Using typeclasses and inheritance for zoning --------------------------------------------- - -The aliasing system above doesn't instill any sort of functional -difference between a magical forest room and a normal one - it's just an -abitrary way to attach tags to objects for quick retrieval later. To -enforce differences you will need to use -`Typeclasses `_. If you know that a certain typeclass -of room will always be in a certain zone you could even hard-code the -zone in the typeclass rather than enforce the ``@dig`` command to do it: - -:: - - class MagicalForestRoom(Room) - def at_object_creation(self): - ... - self.aliases.add("#magicforest|%s" % self.key) - ... - class NormalForestRoom(Room) - def at_object_creation(self): - ... - self.aliases.add("#normalforest|%s" % self.key) - ... - -Of course, an alternative way to implement zones themselves is to have -all rooms/objects in a zone inherit from a given typeclass parent - and -then limit your searches to objects inheriting from that given parent. -The effect would be the same and you wouldn't need to implement any -ad-hoc aliasing scheme; but you'd need to expand the search -functionality to properly search the inheritance tree. diff --git a/docs/sphinx/source/wiki/evAPI.rst b/docs/sphinx/source/wiki/evAPI.rst deleted file mode 100644 index ea4fab58ab..0000000000 --- a/docs/sphinx/source/wiki/evAPI.rst +++ /dev/null @@ -1,105 +0,0 @@ -\`ev\` - Evennia's flat API -=========================== - -Evennia consists of many components, some of which interact in rather -complex ways. One such example is the Typeclass system which is -implemented across four different folders in ``src/``. This is for -efficiency reasons and to avoid code duplication, but it means that it -can be a bit of a hurdle to understand just what connects to what and -which properties are actually available/inherited on a particular game -entity you want to use. - -Evennia's ``ev`` API (Application Programming Interface) tries to help -with this. ``ev.py`` sits in evennia's root directory which means you -can import it from your code simply with ``import ev``. The ``ev`` -module basically implements shortcuts to the innards of ``src/``. The -goal is to give a very "flat" structure (as opposed to a deeply nested -one). Not only is this a Python recommendation, it also makes it much -easier to see what you have. - -Exploring \`ev\` ----------------- - -To check out evennia interactively, it's recommended you use a more -advanced Python interpreter, like `ipython `_. With -ipython you can easily read module headers and help texts as well as -list possible completions. - -Start a python interactive shell, then get ``ev``: - -:: - - import ev - -In ipython we can now do for example ``ev?`` to read the API's help -text. Using eg. ``ev.Object?`` will read the documentation for the -``Object`` typeclass. Use ``??`` to see source code. Tab on ``ev.`` to -see what ``ev`` contains. - -Some highlights ---------------- - -- ``Object, Player, Script, Room, Character, Exit`` - direct links to - the most common base classes in Evennia. -- ``search_*`` - shortcuts to the search functions in - ``src.utils.search``, such as ``search_object()`` or - ``search_script()`` -- ``create_*`` - are convenient links to all object-creation functions. - Note that all Typeclassed objects *must* be created with methods such - as these (or their parents in ``src.utils.create``) to make - Typeclasses work. -- ``managers`` - this is a container object that groups shortcuts to - initiated versions of Evennia's django *managers*. So - ``managers.objects`` is in fact equivalent to ``ObjectDB.objects`` - and you can do ``managers.objects.all()`` to get a list of all - database objects. The managers allows to explore the database in - various ways. To use, do ``from ev import manager`` and access the - desired manager on the imported ``managers`` object. -- default\_cmds - this is a container on ``ev`` that groups all default - commands and command sets under itself. Do - ``from ev import default_cmds`` and you can then access any default - command from the imported ``default_cmds`` object. -- ``utils, logger, gametime, ansi`` are various utilities. Especially - utils contains many useful functions described - `here `_. -- ``syscmdkeys`` is a container that holds all the system-command keys - needed to define system commands. Similar to the ``managers`` - container, you import this and can then access the keys on the - imported ``syscmdkeys`` object. - -To remember when importing from \`ev\` --------------------------------------- - -Properties on ``ev`` are *not* modules in their own right. They are just -shortcut properties stored in the ``ev.py`` module. That means that you -cannot use dot-notation to ``import`` nested module-names over ``ev``. -The rule of thumb is that you cannot use ``import`` for more than one -level down. Hence you can do - -:: - - import ev - print ev.default_cmds.CmdLook - -or import one level down - -:: - - from ev import default_cmds - print default_cmds.CmdLook - -but you *cannot* import two levels down - -:: - - from ev.default_cmds import CmdLook # error! - -This will give you an ``ImportError`` telling you that the module -``default_cmds`` cannot be found. This is not so strange - -``default_cmds`` is just a variable name in the ``ev.py`` module, it -does not exist outside of it. - -As long as you keep this in mind, you should be fine. If you really want -full control over which level of package you import you can always -bypass ``ev`` and import directly from ``src/``. If so, look at -``ev.py`` to see where it imports from. diff --git a/docs/sphinx/src2rest/src2rest.py b/docs/sphinx/src2rest/src2rest.py deleted file mode 100755 index 42ddfea43b..0000000000 --- a/docs/sphinx/src2rest/src2rest.py +++ /dev/null @@ -1,64 +0,0 @@ -# /usr/bin/python -# -# Auto-generate reST documentation for Sphinx from Evennia source -# code. -# -# Uses etinenned's sphinx autopackage script. Install it to folder -# "autogen" in this same directory: -# -# hg clone https://bitbucket.org/etienned/sphinx-autopackage-script autogen -# -# Create a directory tree "code/" containing one directory for every -# package in the PACKAGE dictionary below. Make sure EVENNIA_DIR -# points to an Evennia root dir. Then just run this script. A new -# folder sphinx/source/code will be created with the reST sources. -# -# Note - this is not working very well at the moment, not all sources -# seems to be properly detected and you get lots of errors when -# compiling. To nevertheless make a link to the code from the doc -# front page, edit docs/sphinx/sources/index.rst to reference -# code/modules. -# - - -import os, subprocess, shutil - -EVENNIA_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) - -SPHINX_DIR = os.path.join(os.path.join(EVENNIA_DIR, "docs"), "sphinx") -SPHINX_SRC_DIR = os.path.join(SPHINX_DIR, "source") -SPHINX_CODE_DIR = os.path.join(SPHINX_SRC_DIR, "code") - -CONVERT_DIR = os.path.join(SPHINX_DIR, 'src2rest') -AUTOGEN_EXE = os.path.join(CONVERT_DIR, os.path.join("autogen", "generate_modules.py")) - -def src2rest(): - """ - Run import - """ - try: - shutil.rmtree(SPHINX_CODE_DIR) - print "Emptied old %s." % SPHINX_CODE_DIR - except OSError: - pass - os.mkdir(SPHINX_CODE_DIR) - - inpath = EVENNIA_DIR - outpath = SPHINX_CODE_DIR - excludes = [r".*/migrations/.*", r"evennia\.py$", r"manage\.py$", - r"runner\.py$", r"server.py$", r"portal.py$"] - - subprocess.call(["python", AUTOGEN_EXE, - "-n", "Evennia", - "-d", outpath, - "-s", "rst", - "-f", - inpath] + excludes) - -if __name__ == '__main__': - - try: - src2rest() - except Exception, e: - print e - print "Make sure to read the header of this file so that it's properly set up." diff --git a/docs/sphinx/wiki2rest/wiki2rest.py b/docs/sphinx/wiki2rest/wiki2rest.py deleted file mode 100755 index ffb0af0a1c..0000000000 --- a/docs/sphinx/wiki2rest/wiki2rest.py +++ /dev/null @@ -1,208 +0,0 @@ -#! /usr/bin/python -# -# Converts Evennia's google-style wiki pages to reST documents -# -# Setting up to run: -# -# 1) Install pandoc (converts from html to reST): -# -# apt-get install pandoc (debian) -# or download from -# http://johnmacfarlane.net/pandoc/ -# -# 2) Retrieve wiki files (*.wiki) from Google code by mercurial. Make sure -# to retrieve them into a subdirectory wiki here: -# -# hg clone https://code.google.com/p/evennia.wiki wiki -# -# Regular Usage: -# -# 1) Make sure to pull/update the wiki files into wiki/ so you have the latest. -# 2) Run wiki2rest.py. Temporary work folders html and rest will be created, so make sure you -# have the rights to create directories here. The contents -# of rest/ will automatically be copied over to docs/sphinx/source/wiki. -# 3) From docs/sphinx, run e.g. "make html" to build the documentation from the reST sources. -# - -import sys, os, subprocess, re, urllib, shutil - -# Setup - -EVENNIA_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) - - -SPHINX_DIR = os.path.join(os.path.join(EVENNIA_DIR, "docs"), "sphinx") -SPHINX_SRC_DIR = os.path.join(SPHINX_DIR, "source") -SPHINX_WIKI_DIR = os.path.join(SPHINX_SRC_DIR, "wiki") -CONVERT_DIR = os.path.join(SPHINX_DIR, "wiki2rest") - -WIKI_DIR = os.path.join(CONVERT_DIR, "wiki") -HTML_DIR = os.path.join(CONVERT_DIR, "html") -REST_DIR = os.path.join(CONVERT_DIR, "rest") -WIKI2HTML_DIR = os.path.join(CONVERT_DIR, "wiki2html") -PANDOC_EXE = "pandoc" -RUBY_EXE = "ruby" - -WIKI_ROOT_URL = "http://code.google.com/p/evennia/wiki/" -WIKI_CRUMB_URL = "/p/evennia/wiki/" - -# files to not convert (no file ending) -NO_CONVERT = ["SideBar", "Screenshot"] - - -#------------------------------------------------------------ -# This is a version of the importer that imports Google html pages -# directly instead of going through the ruby converter. Alas, while -# being a lot cleaner in implementation, this seems to produce worse -# results in the end (both visually and with broken-link issues), so -# not using it at this time. -# -# See the wiki2html at the bottom for the ruby-version. -#------------------------------------------------------------ - -def fetch_google_wiki_html_files(): - """ - Acquire wiki html pages from google code - """ - # use wiki repo to find html filenames - html_urls = dict([(re.sub(r"\.wiki", "", fn), WIKI_ROOT_URL + re.sub(r"\.wiki", "?show=content", fn)) - for fn in os.listdir(WIKI_DIR) if fn.endswith(".wiki")]) - - #html_urls = {"Index":html_urls["Index"]} #SR! - - html_pages = {} - for name, html_url in html_urls.items(): - print "urllib: fetching %s ..." % html_url - f = urllib.urlopen(html_url) - s = f.read() - s = clean_html(s) - html_pages[name] = s #clean_html(f.read()) - f.close() - - # saving html file for debugging - f = open(os.path.join(HTML_DIR, "%s.html" % name), 'w') - f.write(s) - f.close() - - return html_pages - -def clean_html(htmlstring): - """ - Clean up html properties special to google code and not known by pandoc - """ - # remove wikiheader tag (searches over many lines). Unfortunately python <2.7 don't support - # DOTALL flag in re.sub ... - matches = re.findall(r'
.*?
.*?.*?', htmlstring, re.DOTALL) - for match in matches: - htmlstring = htmlstring.replace(match, "") - #htmlstring = re.sub(r'
.*?
.*?.*?', "", htmlstring, re.DOTALL) - # remove prefix from urls - htmlstring = re.sub('href="' + WIKI_CRUMB_URL, 'href="', htmlstring) - # remove #links from headers - htmlstring = re.sub(r'(.*?)( html ..." - subprocess.call(["python", "wikify.py", "-r", "-e", "-m", "-c", "-a", "-s", "wiki", "-d", "html"]) - - # convert from html to rest with pandoc - htmlfilenames = [fn for fn in os.listdir(HTML_DIR) - if fn.endswith(".html") and not re.sub(r".html", "", fn) in NO_CONVERT] - - print " pandoc: converting html -> ReST ..." - for filename in htmlfilenames: - - htmlfilename = os.path.join(HTML_DIR, filename) - - # cleanup of code - string = "".join(open(htmlfilename, 'r').readlines()) - string = re.sub(r'

[A-Za-z0-9 .-\:]*

', "", string) - string = re.sub(r"<wiki:toc max_depth="[0-9]*" />", "", string) - string = re.sub(r"<wiki:toc max_depth

"[0-9]*" />

", "", string) - string = re.sub(r"

#settings Featured

", "", string) - string = re.sub(r'

Featured

', "", string) - string = re.sub(r'<wiki:comment>', "", string) - string = re.sub(r'</wiki:comment>', "", string) - string = re.sub(r'<wiki:comment>[<>;a-zA\/\n-&Z0-9 ]*</wiki:comment>', "", string) - f = open(htmlfilename, 'w') - f.write(string) - f.close() - - rstfilename = os.path.join(REST_DIR, re.sub(r".html$", ".rst", filename)) - #print "pandoc: converting %s -> %s" % (htmlfilename, rstfilename) - subprocess.call([PANDOC_EXE, "--from=html", "--to=rst", "-o", rstfilename, htmlfilename]) - -# main program -if __name__ == "__main__": - - print "creating/cleaning output dirs ...", - try: - shutil.rmtree(REST_DIR) - os.mkdir(REST_DIR) - except OSError: - os.mkdir(REST_DIR) - try: - shutil.rmtree(HTML_DIR) - os.mkdir(HTML_DIR) - except Exception: - os.mkdir(HTML_DIR) - try: - shutil.rmtree(SPHINX_WIKI_DIR) - except Exception: - # this is created by copy mechanism. - pass - print "done." - print "running conversions ..." - - try: - wiki2rest() - except Exception, e: - print e - print "Make sure to read this file's header to make sure everything is correctly set up. " - sys.exit() - - print "... conversions finished (make sure there are no error messages above)." - print "copying rest data to %s ..." % SPHINX_WIKI_DIR - shutil.copytree(REST_DIR, SPHINX_WIKI_DIR) - print "... done. You can now build the docs from the sphinx directory with e.g. 'make html'." diff --git a/docs/sphinx/wiki2rest/wikify.py b/docs/sphinx/wiki2rest/wikify.py deleted file mode 100644 index fe88bca370..0000000000 --- a/docs/sphinx/wiki2rest/wikify.py +++ /dev/null @@ -1,962 +0,0 @@ -#!/usr/bin/python -# -# wikify.py - Convert from wikitext to HTML -# Based on large portions of JeremyRuston's TiddlyWiki JS Wikifier -# Changed to GoogleCode wiki syntax, python by Michael Crawford -""" Convert wikitext to HTML """ - -# Jeremy's license: -# Copyright (c) UnaMesa Association 2004-2007 -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, this -# list of conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# Neither the name of the UnaMesa Association nor the names of its contributors may be -# used to endorse or promote products derived from this software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# My license: -# Copyright (c) Data Unity 2007 -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, this -# list of conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# Neither the name of the Data Unity nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import re, os, os.path, htmlentitydefs, urllib - - -class _HTML: - """ An HTML node factory factory. """ - - class Node: - """ An HTML element. """ - def __init__(self, parent, tagname, text="", attribs={}, empty=False, **kwargs): - self.tagname = tagname - self.attribs = dict(attribs) - self.children = list() - self.empty = empty - if text != "": - self.appendText(text) - if parent is not None: - parent.children.append(self) - self.parent = parent - - def appendText(self, text): - if text == "": return - _HTML.Text(self, text) - - def __str__(self): - attrs = " ".join([ '%s="%s"' % i for i in self.attribs.iteritems() ]) - if attrs: attrs = " " + attrs - if self.empty: - return "<%s%s/>" % (self.tagname, attrs) - - children = "".join([str(c) for c in self.children]) - return "<%s%s>%s" % (self.tagname, attrs, children, self.tagname) - - def isInside(self, tagname): - k = self - while k is not None: - if k.tagname == tagname: - return True - k = k.parent - return False - - class Text: - """ Simple text node. """ - entities = [ (k,v) - for k,v in htmlentitydefs.entitydefs.iteritems() - if k != "amp" and k[0] != "#" ] - - def __init__(self, parent, text=""): - self.text = self._clean(text) - if parent is not None: - parent.children.append(self) - - def _clean(self, text): - text = text.replace("&", "&") - for k,v in self.entities: - text = text.replace(v, "&%s;" % k) - return text - - def __str__(self): - return self.text - - - def __getattr__(self, attr): - """ Return an element constructor using the attribute as the tagname """ - def factory(parent=None, **kwargs): - return self.Node(parent, attr, **kwargs) - return factory - -HTML = _HTML() - -URLSTR = r"(?:file|http|https|mailto|ftp|irc|news|data):[^\s'\"]+(?:/|\b)" -URL = re.compile(URLSTR, re.M) -IMGURLSTR = r".+((\.[Pp][Nn][Gg])|(\.[Gg][Ii][Ff])|(\.[Jj][Pp][Ee]?[Gg]))" -IMGURL = re.compile(IMGURLSTR, re.M) -YOUTUBESTR = r"http://www.youtube.com/watch\?v=([A-Za-z0-9_-]+)" -YOUTUBEURL = re.compile(YOUTUBESTR, re.M) -YOUTUBEREPL = r'' -VIDEOURLSTR = r".+((\.[Aa][Vv][Ii])|(\.[Mm][Oo][Vv])|(\.[Mm][Pp][Ee]?[Gg]))" -VIDEOURL = re.compile(VIDEOURLSTR, re.M) -VIDEOREPL = r'' -CODEURLSTR = r"http://([^\.]+).googlecode.com/svn/trunk/([^#]+)#((?:(?:(?:[\d]+)?\-)?[\d]+)|(?:[\d]+\-?))((?:\:(?:[\:]|[^\W])+))?" -CODEURL = re.compile(CODEURLSTR, re.M) -CODEREPL = r'
svn://%(site)s/trunk/%(file)s
%(lines)s
' - -def GoogleCode_ReadSVNFile(wikifier, domain, path, start, end): - """ Try to read a file from subversion for inclusion in the wiki. """ - - gcurl = "http://%s.googlecode.com/svn/trunk/%s" % (domain,path) - fdata = urllib.urlopen(gcurl).readlines() - return gcurl, fdata[start-1:end] - - -def GoogleCode_IsExternalLink(wikifier, link): - """ See if the link points outside of the wiki. """ - - if GoogleCode_Exists(wikifier, link): - return False; - - if URL.match(link): - return True - - if '.' in link or '\\' in link or '/' in link or '#' in link: - return True - - return False - -def GoogleCode_Exists(wikifier, wikipage): - """ See if a wiki page exists inside this wiki. """ - path = os.path.join(wikifier.srcdir, "%s.wiki" % wikipage) - if os.path.exists(path): - return True - return False - - -def GoogleCode_Heading(wikifier, termRegExp=None, **kwargs): - termMatch = termRegExp.search(wikifier.source, wikifier.nextMatch) - if termMatch is None: return - if (len(wikifier.output.children) and - "br" == getattr(wikifier.output.children[-1], 'tagname', '')): - wikifier.output.children.pop(-1) - if (len(wikifier.output.children) and - "br" == getattr(wikifier.output.children[-1], 'tagname', '')): - wikifier.output.children.pop(-1) - output = HTML.Node(wikifier.output, "h%i" % wikifier.matchLength) - wikifier.outputText(output, wikifier.nextMatch, termMatch.start()) - wikifier.nextMatch = termMatch.end() - -def GoogleCode_SimpleElement(wikifier, termRegExp=None, tagName=None, **kwargs): - if wikifier.output.isInside(tagName): - wikifier.outputText(wikifier.output, wikifier.matchStart, wikifier.nextMatch) - return - elif wikifier.source[wikifier.nextMatch-1] == "_": - wikifier.outputText(wikifier.output, wikifier.matchStart, wikifier.nextMatch-1) - - if termRegExp.search(wikifier.source, wikifier.nextMatch) is None: return - output = HTML.Node(wikifier.output, tagName, **kwargs) - wikifier.subWikifyTerm(output, termRegExp) - #if wikifier.source[wikifer.nextMatch-2] == "_": - # wikifier.nextMatch -= 1 - -def GoogleCode_Blockquote(wikifier, termRegExp=None, **kwargs): - sibs = wikifier.output.children - if len(sibs) and getattr(sibs[-1], 'tagname', None) == "blockquote": - wikifier.subWikifyTerm(sibs[-1], termRegExp) - else: - output = HTML.blockquote(wikifier.output, **kwargs) - wikifier.subWikifyTerm(output, termRegExp) - -def GoogleCode_Codeblock(wikifier, tagName=None, termRegExp=None, initRegExp=None, **kwargs): - if 'attribs' not in kwargs: - kwargs['attribs'] = {} - - kwargs['attribs']['name'] = 'code' - if 'class' not in kwargs['attribs']: - kwargs['attribs']['class'] = wikifier.defaultHiLang.lower() - else: - kwargs['attribs']['class'] += " " + wikifier.defaultHiLang.lower() - - output = HTML.Node(wikifier.output, tagName, **kwargs) - tcount = 1 - matchStart = wikifier.nextMatch - # Find the matching terminator - while tcount > 0: - nextTermMatch = termRegExp.search(wikifier.source, wikifier.nextMatch) - nextInitMatch = initRegExp.search(wikifier.source, wikifier.nextMatch) - - if not nextTermMatch: - # No terminator. Syntax error, just ignore it. - matchEnd = matchStart - tcount = 0 - break - elif not nextInitMatch or nextTermMatch.start() <= nextInitMatch.start(): - # Terminator goes first. - nextMatch = nextTermMatch - tcount -= 1 - if tcount > 0: - matchEnd = nextMatch.end() - else: - matchEnd = nextMatch.start() - else: - nextMatch = nextInitMatch - tcount += 1 - matchEnd = nextMatch.end() - - wikifier.nextMatch = nextMatch.end() - - # Copy the content - wikifier.outputText(output, matchStart, matchEnd) - - if "\n" not in wikifier.source[matchStart:matchEnd]: - output.tagname = "code" - -def GoogleCode_WikiWord(wikifier, **kwargs): - if wikifier.matchStart > 0: - # Make sure we're at the start of a word? - preRegExp = re.compile("[!A-Za-z0-9]", re.M) - preMatch = preRegExp.search(wikifier.source, wikifier.matchStart-1) - if (preMatch is not None and - preMatch.start() == wikifier.matchStart-1): - wikifier.outputText(wikifier.output,wikifier.matchStart,wikifier.nextMatch) - return - - if wikifier.source[wikifier.matchStart] == "!": - wikifier.outputText(wikifier.output,wikifier.matchStart+1,wikifier.nextMatch) - elif GoogleCode_Exists(wikifier, wikifier.matchText): - # Full link, everybody sees it - HTML.a(wikifier.output, text=wikifier.matchText, attribs={"href": wikifier.matchText + wikifier.suffix}) - elif wikifier.autolink: - # Partial link - only authorized users - wikifier.outputText(wikifier.output,wikifier.matchStart,wikifier.nextMatch) - link = HTML.a(wikifier.output, text="?", attribs={"href": wikifier.matchText + wikifier.suffix}) - else: - wikifier.outputText(wikifier.output,wikifier.matchStart,wikifier.nextMatch) - -def GoogleCode_LineBreak(wikifier, **kwargs): - sibs = wikifier.output.children - if wikifier.multibreak: - HTML.p(wikifier.output, **kwargs) - elif len(sibs) and (not hasattr(sibs[-1], 'tagname') or - sibs[-1].tagname == "img"): - # Only after an inline or header block. - HTML.p(wikifier.output, **kwargs) - HTML.p(wikifier.output, **kwargs) - -def GoogleCode_PrettyLink(wikifier, lookaheadRegExp=None, **kwargs): - lookMatch = lookaheadRegExp.search(wikifier.source, wikifier.matchStart) - if lookMatch and lookMatch.start() == wikifier.matchStart: - text = lookMatch.group(1) - link = text - if lookMatch.group(2): - # Pretty bracketted link - text = lookMatch.group(2) - if GoogleCode_IsExternalLink(wikifier, link): - # External link - attribs={"href":link, "target": "_blank" } - else: - # Internal link - attribs={"href":link + wikifier.suffix} - - e = HTML.a(wikifier.output, attribs=attribs) - - if URL.match(text): - HTML.img(e, attribs={'src':text, - 'border': '0'}) - HTML.br(wikifier.output) - else: - HTML.Text(e, text) - else: - if GoogleCode_IsExternalLink(wikifier, text): - # External link - attribs={"href":link, "target": "_blank" } - else: - # Internal link - attribs={"href":text + wikifier.suffix} - - # Simple bracketted link - e = HTML.a(wikifier.output, text=text, attribs=attribs) - wikifier.nextMatch = lookMatch.end() - -def GoogleCode_UrlLink(wikifier, **kwargs): - attribs = {"href": wikifier.matchText} - if GoogleCode_IsExternalLink(wikifier, wikifier.matchText): - attribs["target"] = "_blank" - - if IMGURL.match(wikifier.matchText): - HTML.img(wikifier.output, attribs={'src':wikifier.matchText}) - HTML.br(wikifier.output) - elif YOUTUBEURL.match(wikifier.matchText): - match = YOUTUBEURL.match(wikifier.matchText) - # Raw html ;) - wikifier.output.children.append(YOUTUBEREPL % match.group(1)) - elif VIDEOURL.match(wikifier.matchText): - # Raw html ;) - wikifier.output.children.append(VIDEOREPL % wikifier.matchText) - elif CODEURL.match(wikifier.matchText): - # Raw html ;) - # http://([^\.]+).googlecode.com/svn/trunk/([^\#]+)#([^\:]+)(?:\:([^\W]+))? - - codeMatch = CODEURL.match(wikifier.matchText) - parts = { "class": (codeMatch.group(4) or "").lower()[1:], - "file": codeMatch.group(2), - "site": codeMatch.group(1)} - - lines = codeMatch.group(3) - if '-' in lines: - lines = lines.split('-') - lines[0] = int(lines[0]) - lines[1] = int(lines[1]) - else: - lines = [int(lines), int(lines)] - - parts['class'] += ":firstline[%i]" % lines[0] - url, parts['lines'] = GoogleCode_ReadSVNFile(wikifier, parts['site'], - parts['file'], *lines) - parts['url'] = url - parts['lines'] = "".join(parts['lines']) - - wikifier.output.children.append(CODEREPL % parts) - else: - HTML.a(wikifier.output, text=wikifier.matchText, attribs=attribs) - - -def GoogleCode_Table(wikifier, sepRegExp=None, termRegExp=None, **kwargs): - sibs = wikifier.output.children - if len(sibs) and getattr(sibs[-1], 'tagname', None) == "table": - table = sibs[-1] - else: - table = HTML.table(wikifier.output) - row = HTML.tr(table) - - termMatch = termRegExp.search(wikifier.source, wikifier.matchStart) - if termMatch is None: - termEnd = termStart = len(wikifier.source) - else: - termStart, termEnd = termMatch.start(), termMatch.end() - - # Skip over the leading separator - sepMatch = sepRegExp.search(wikifier.source, wikifier.matchStart) - wikifier.nextMatch = wikifier.matchStart = sepMatch.end() - sepMatch = sepRegExp.search(wikifier.source, wikifier.matchStart) - attribs = { "style": "border: 1px solid #aaa; padding: 5px;" } - - while sepMatch and sepMatch.end() <= termStart: - cell = HTML.td(row, attribs=attribs) - wikifier.subWikifyTerm(cell, sepRegExp) - wikifier.nextMatch = sepMatch.end() - sepMatch = sepRegExp.search(wikifier.source, wikifier.nextMatch) - - wikifier.nextMatch = termEnd - - -def GoogleCode_List(wikifier, lookaheadRegExp=None, termRegExp=None, **kwargs): - currLevel = 0 - currType = None - stack = [wikifier.output] - indents = [currLevel] - wikifier.nextMatch = wikifier.matchStart - - lookMatch = lookaheadRegExp.search(wikifier.source, wikifier.nextMatch) - while lookMatch and lookMatch.start() == wikifier.nextMatch: - # See what kind of list it is - if lookMatch.group(1): - listType = "ul" - itemType = "li" - elif lookMatch.group(2): - listType = "ol" - itemType = "li" - - listLevel = len(lookMatch.group(0)) - wikifier.nextMatch += len(lookMatch.group(0)) - - # Check for any changes in list type or indentation - if listLevel > currLevel: - # Indent further - indents.append(listLevel) - if currLevel == 0: - target = stack[-1] - else: - target = stack[-1].children[-1] - - stack.append(HTML.Node(target, listType)) - - elif listLevel < currLevel: - # Indent less - while indents[-1] > listLevel: - stack.pop(-1) - indents.pop(-1) - - elif listLevel == currLevel and listType != currType: - # Same level, different kind of list - stack.pop(-1) - stack.append(HTML.Node(stack[-1].children[-1], listType)) - - currLevel = listLevel - currType = listType - - # Output the item - output = HTML.Node(stack[-1],itemType) - wikifier.subWikifyTerm(output,termRegExp) - - # Roll again - lookMatch = lookaheadRegExp.search(wikifier.source, wikifier.nextMatch) - - - -GoogleCodeWikiFormat = [ - { - "name": "tablerow", - "match": r"^(?:\|\|.+\|\|)", - "termRegExp": re.compile(r"(\n)", re.M), - "sepRegExp": re.compile(r"(\|\|)", re.M), - "handler": GoogleCode_Table - }, - - { "name": "heading", - "match": r"^={1,6}", - "termRegExp": re.compile(r"([=]+)", re.M), - "handler": GoogleCode_Heading - }, - - { "name": "list", - "match": r"^(?:[ ]+)(?:[\*#])", - "lookaheadRegExp": re.compile(r"^(?:[ ]+)(?:(\*)|(#))",re.M), - "termRegExp": re.compile(r"(\n)", re.M), - "handler": GoogleCode_List - }, - - - - { "name": "blockquote", - "match": r"^(?:[ ]+)", - "termRegExp": re.compile(r"(\n)", re.M), - "handler": GoogleCode_Blockquote, - "tagName": "blockquote" - }, - - { "name": "codeword", - "match": r"\`", - "initRegExp": re.compile(r"(\`)", re.M), - "termRegExp": re.compile(r"(\`)", re.M), - "handler": GoogleCode_Codeblock, - "tagName": "code" - }, - - { "name": "codeblock", - "match": r"\{\{\{", - "initRegExp": re.compile(r"(\{\{\{)", re.M), - "termRegExp": re.compile(r"(\}\}\})", re.M), - "handler": GoogleCode_Codeblock, - "tagName": "pre", - "attribs": { "class": "codeblock" } - }, - - { "name": "bold", - "match": r"[\*]", - "termRegExp": re.compile(r"([\*])", re.M), - "handler": GoogleCode_SimpleElement, - "tagName": "b" - }, - - { "name": "italic", - "match": r"(?:[^\w\b]|^)[\_]", - "termRegExp": re.compile(r"([\_])[^\w\b]", re.M), - "handler": GoogleCode_SimpleElement, - "tagName": "i" - }, - - { "name": "strike", - "match": r"\~\~", - "termRegExp": re.compile(r"(\~\~)", re.M), - "handler": GoogleCode_SimpleElement, - "tagName": "strike" - }, - - { "name": "superscript", - "match": r"\^", - "termRegExp": re.compile(r"(\^)", re.M), - "handler": GoogleCode_SimpleElement, - "tagName": "sup" - }, - - { "name": "subscript", - "match": r",,", - "termRegExp": re.compile(r"(,,)", re.M), - "handler": GoogleCode_SimpleElement, - "tagName": "sub" - }, - - { "name": "prettyLink", - "match": r"\[(?:(?:[A-Za-z][A-Za-z0-9\_\-]+)|(?:(?:file|http|https|mailto|ftp|irc|news|data):[^\s'\"]+(?:/|\b)))(?: .*?)?\]", - "lookaheadRegExp": re.compile(r'\[(.*?)(?: (.*?))?\]', re.M), - "handler": GoogleCode_PrettyLink - }, - - { "name": "wikiword", - "match": r"(?:\!?(?:[A-Z]+[a-z]+[A-Z][A-Za-z]*)|(?:[A-Z]{2,}[a-z]+))", - "handler": GoogleCode_WikiWord - }, - - { "name": "urlLink", - "match": URLSTR, - "handler": GoogleCode_UrlLink - }, - - { "name": "linebreak", - "match": r"\n\n", - "handler": GoogleCode_LineBreak, - "empty": True - }, - -] - - - -class Wikifier: - - def __init__(self, formatters, autolink=False, srcdir=os.getcwd(), - multibreak=False, tabwidth=8, suffix=".html", - hiLang="Python"): - # Create the master regex - forms = [ "(%s)" % r['match'] for r in formatters ] - self.formatterRegExp = re.compile("|".join(forms), re.M) - # Save the individual format handlers - self.formatters = formatters - self.autolink = autolink - self.srcdir = srcdir - self.multibreak = multibreak and True or False - self.tabwidth = tabwidth - self.suffix = suffix - self.defaultHiLang = hiLang - - def _clean(self, text): - text = text.replace("\r\n", "\n") - - # Out, out, damned tabs - text = text.replace("\t", " " * self.tabwidth) - - if not self.multibreak: - # Remove redundant line breaks - tlen = len(text) + 1 - while tlen > len(text): - tlen = len(text) - text = text.replace("\n\n\n", "\n\n") - - while text.startswith("#"): - # Process any wiki-headers - line, text = text.split("\n", 1) - self._header(line) - - return text - - def _header(self, line): - tagname, content = line.split(" ", 1) - if tagname == "#summary": - self.summary = content - elif tagname == "#labels": - self.labels = tuple(content.split(",")) - - def wikify(self, source, labels=None, summary=None): - self.labels = labels - self.summary = summary - # Clean up the content - self.source = self._clean(source) - self.nextMatch = 0 - # Do it - self.output = HTML.div(None) - self.subWikifyUnterm() - - return "".join([str(c) for c in self.output.children]) - - def findMatch(self, source, start): - return self.formatterRegExp.search(source, start) - - def subWikifyUnterm(self, output=None): - oldOutput = self.output - if output is not None: - self.output = output - - match = self.findMatch(self.source, self.nextMatch) - while match: - # Output any text before the match - if match.start() > self.nextMatch: - self.outputText(self.output, self.nextMatch, match.start()) - - # Set the match parameters for the handler - self.matchStart = match.start() - self.matchLength = len(match.group(0)) - self.matchText = match.group(0) - self.nextMatch = match.end() - - # Figure out which sub-group matched (zero-indexed) - t,submatch = [ (t,s) for t, s in enumerate(match.groups()) if s ][0] - - # Handle it - self.formatters[t]['handler'](self, **self.formatters[t]) - - # Go back for more matches - match = self.findMatch(self.source, self.nextMatch) - - if self.nextMatch < len(self.source): - self.outputText(self.output, self.nextMatch, len(self.source)) - self.nextMatch = len(self.source) - - # Restore the destination node - self.output = oldOutput - - def subWikifyTerm(self, output, termRegExp): - oldOutput = self.output - if output is not None: - self.output = output - - # Get the first matches for the formatter and terminator RegExps - termMatch = termRegExp.search(self.source, self.nextMatch) - if termMatch: - match = self.findMatch(self.source[:termMatch.start()], self.nextMatch) - else: - match = self.findMatch(self.source, self.nextMatch) - - while termMatch or match: - # If the terminator comes before the next formatter match, we're done - if termMatch and (not match or termMatch.start() <= match.start()): - if termMatch.start() > self.nextMatch: - self.outputText(self.output,self.nextMatch,termMatch.start()) - self.matchText = termMatch.group(1) - self.matchLength = len(self.matchText) - self.matchStart = termMatch.start() - self.nextMatch = self.matchStart + self.matchLength - self.output = oldOutput - return - - # Output any text before the match - if match.start() > self.nextMatch: - self.outputText(self.output, self.nextMatch, match.start()) - - # Set the match parameters for the handler - self.matchStart = match.start() - self.matchLength = len(match.group(0)) - self.matchText = match.group(0) - self.nextMatch = match.end() - - # Figure out which sub-group matched (zero-indexed) - t,submatch = [ (t,s) for t, s in enumerate(match.groups()) if s ][0] - - # Handle it - self.formatters[t]['handler'](self, **self.formatters[t]) - - termMatch = termRegExp.search(self.source, self.nextMatch) - if termMatch: - match = self.findMatch(self.source[:termMatch.start()], self.nextMatch) - else: - match = self.findMatch(self.source, self.nextMatch) - - if self.nextMatch < len(self.source): - self.outputText(self.output, self.nextMatch,len(self.source)) - self.nextMatch = len(self.source) - - self.output = oldOutput - - - def outputText(self, output, startPos, endPos): - HTML.Text(output, self.source[startPos:endPos]) - - -DEFAULT_TEMPLATE = ''' - - - - - -
- - - -
-
- -%(toc)s -
- - %(title)s - -
- %(summary)s -
- -
- %(wiki)s -
- -
-
- - -''' - -DEFAULT_TEMPLATE = ''' - - - - - -
- %(summary)s -
-
- %(wiki)s -
- - -''' - - -def wikify(pages, options=None): - # See options definition below. - # Pass any object with those (potential) attributes - srcdir = getattr(options, 'srcdir', os.getcwd()) - destdir = getattr(options, 'destdir', None) - - # Find all requested files - onlyStale = False - if getattr(options, 'all', False): - pages = [ k for k in os.listdir(srcdir) - if k.endswith(".wiki") ] - onlyStale = True - if destdir is None: - destdir = os.getcwd() - - # Create the magic 8-ball - w = Wikifier(GoogleCodeWikiFormat, - autolink=getattr(options, 'autolink', False), - tabwidth=getattr(options, 'tabwidth', 8), - multibreak=getattr(options, 'multibreak', False), - srcdir=srcdir, - suffix=".html") - - rets = [] - for wikiname in pages: - # Clean up the page name - if wikiname.endswith(".wiki"): - wikiname = wikiname[:-5] - - wikifilename = os.path.join(srcdir, "%s.wiki" % wikiname) - if onlyStale: - # See if the output is fresh, and if so, skip it - wikidestname = os.path.join(destdir, "%s.html" % wikiname) - try: - sstat = os.stat(wikifilename) - except: - continue - try: - dstat = os.stat(wikidestname) - except: - pass - else: - if dstat.st_mtime > sstat.st_mtime: - continue - - # Load the wiki content - wikifilename = os.path.join(srcdir, "%s.wiki" % wikiname) - wikisrc = file(wikifilename).read() - - # Ask a question - wikified = w.wikify(wikisrc) - - reFind = re.compile(r'\s*([^\<]*[\S])\s*') - strRepl = r'>\g<2>>' - - # Number the sections - if getattr(options, 'number', True): - sectstack = [] - matches = [] - curLevel = 0 - match = reFind.search(wikified) - while match is not None: - level = int(match.group(1)) - - while level > len(sectstack): - sectstack.append(1) - - while len(sectstack) > level: - sectstack.pop(-1) - - if curLevel >= level: - sectstack[-1] += 1 - curLevel = len(sectstack) - - sectnum = ".".join([str(n) for n in sectstack]) + "." - matches.append((sectnum, match)) - match = reFind.search(wikified, match.end()) - - matches.reverse() - for sectnum, match in matches: - wikified = wikified[:match.start()+4] + sectnum + " " + wikified[match.start()+4:] - - - # Generate the TOC - if getattr(options, 'toc', True): - matches = [ '%s: Contents' % wikiname ] - for match in reFind.findall(wikified): - if int(match[0]) > getattr(options, 'levels', 3): continue - indent = " " * ((int(match[0])) * 2) - - href = "#" + match[1] - anchor = '%s%s' % (indent, href, match[1]) - matches.append(anchor) - toc = "
".join(matches) - else: - toc = "" #-e -d /home/adam/src/CSpaceWiki/ - - # Generate the body links - if getattr(options, 'links', True): - wikified = reFind.sub(strRepl, wikified) - - # Find a summary - summary = "" - if w.summary is not None: - summary = w.summary - - if not getattr(options, 'raw', False): - # Fill the template - wikified = options.template % { - "toc": toc, - "title": wikiname, - "wiki": wikified, - "summary": summary } - - # Save it or write it - if destdir is not None: - outputname = os.path.join(destdir, "%s.html" % wikiname) - file(outputname,"w").write(wikified) - - mainpage = getattr(options, 'mainpage', 'MainPage') - if wikiname == mainpage: - rets.append((wikiname, outputname)) - outputname = os.path.join(destdir, "index.html") - file(outputname,"w").write(wikified) - - wikified = outputname - rets.append((wikiname, wikified)) - return rets - -if __name__ == "__main__": - from optparse import OptionParser - import sys - - parser = OptionParser() - - # Output format options - parser.add_option("-t", "--template", dest="template", - help="use TPLTFILE to wrap wiki output", metavar="TPLTFILE") - parser.add_option("-n", "--number", dest="number", metavar="NUMSTART", - help="number the headings in the body and table of contents starting with level NUMSTART") - parser.add_option("-l", "--levels", dest="levels", type="int", - help="create toc to depth LEVELS", metavar="LEVELS") - parser.add_option("-c", "--skiptoc", dest="toc", action="store_false", - help="leave toc out, even if template has slot") - parser.add_option("-u", "--unlink", dest="links", action="store_false", - help="don't create named anchors for toc links") - parser.add_option("-a", "--autolink", dest="autolink", action="store_false", - help="autolink wiki words that don't exist") - parser.add_option("-w", "--tabwidth", dest="tabwidth", type="int", - help="replace tabs by WIDTH spaces", metavar="WIDTH") - parser.add_option("-m", "--multibreak", dest="multibreak", action="store_true", - help="don't collapse multiple line breaks") - parser.add_option("-r", "--raw", dest="raw", action="store_true", - help="raw wiki translation -- no wrapping, no toc, no links") - parser.add_option("-p", "--mainpage", dest="mainpage", metavar="PAGENAME", - help="set main page to PAGENAME") - - # Batch / Location options - parser.add_option("-s", "--srcdir", dest="srcdir", - help="wiki format sources in SRCDIR", metavar="SRCDIR") - parser.add_option("-d", "--destdir", dest="destdir", - help="write html output into DESTDIR", metavar="DESTDIR") - parser.add_option("-e", "--stale", dest="all", action="store_true", - help="convert all wiki files that are stale or missing from DESTDIR") - - - parser.set_default('toc', True) - parser.set_default('links', True) - parser.set_default('template', None) - parser.set_default('number', False) - parser.set_default('levels', 3) - parser.set_default('tabwidth', 8) - parser.set_default('multibreak', False) - parser.set_default('mainpage', "MainPage") # Identity of index - - parser.set_default('srcdir', os.getcwd()) - parser.set_default('destdir', None) - parser.set_default('all', False) - - # Parse the command line - (options, args) = parser.parse_args() - - if options.template is None: - options.template = DEFAULT_TEMPLATE - elif os.path.exists(options.template): - options.template = file(options.template).read() - else: - print "Template not found: %s" % options.template - parser.print_usage() - sys.exit() - #sys.exit() - for wikiname, htmldata in wikify(args, options): - if options.destdir: - #print wikiname + ":", - if htmldata is not None: - pass - #print htmldata - else: - print "Complete." - elif htmldata is not None: - print htmldata - - -