diff --git a/docs/Makefile b/docs/Makefile index ff42f7fa68..0493d9760c 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -11,6 +11,7 @@ SPHINXBUILD ?= sphinx-build SPHINXMULTIVERSION ?= sphinx-multiversion SPHINXAPIDOC ?= sphinx-apidoc SPHINXAPIDOCOPTS = --tocfile evennia-api --module-first --force -d 6 --separate --templatedir=$(SOURCEDIR)/_templates/ +SPHINXAPIDOCOPTSQUICK = --tocfile evennia-api --module-first -d 6 --separate --templatedir=$(SOURCEDIR)/_templates/ SPHINXAPIDOCENV = members,undoc-members,show-inheritance SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../evennia/*/tests/* ../evennia/*/tests.py @@ -28,9 +29,12 @@ QUICKFILES= help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @echo "Evennia-specific: " - @echo " $(cblue)install$(cnorm) to get build requirements" + @echo " $(cblue)install$(cnorm) to get doc build requirements" @echo " $(cblue)clean$(cnorm) to remove remnants of a previous build" + @echo " $(cblue)quick$(cnorm) to build local docs but skip the autodocs (for quick testing)" + @echo " $(cblue)quickstrict$(cnorm) to build like 'quick' but abort immediately on any error" @echo " $(cblue)local$(cnorm) to build local html docs of the current branch (no multiversion)." + @echo " $(cblue)localupdate$(cnorm) to build local html docs (only update changes) @echo " $(cblue)mv-local$(cnorm) to build multiversion html docs, without deploying (req: local git commit first)" @echo " $(cblue)deploy$(cnorm) to deploy previously built multiversion docs online (req: commit and github push access)" @echo " $(cblue)release$(cnorm) to build + deploy multiversion docs online (req: commit and github push access)" @@ -66,6 +70,10 @@ _autodoc-index: make _clean_api_index @EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTS) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE) make _reformat_apidoc_headers + pylib/api_rst2md.py + +_quick_autodoc-index: + @EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTSQUICK) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE) _multiversion-autodoc-index: make _autodoc-index @@ -102,6 +110,7 @@ pdf: @echo "To see result, open evennia/docs/build/latex/evennia.pdf in a PDF reader." quick: + make _quick_autodoc-index make _quick-html-build $(FILES) @echo "" @echo "Documentation built (single version, no autodocs)." @@ -120,7 +129,7 @@ local: @echo "" @echo "Documentation built (single version)." @echo "To see result, open evennia/docs/build/html/index.html in a browser." - + # build only that which updated since last run (no clean or index-creation) localupdate: make _check-env diff --git a/docs/README.md b/docs/README.md index e03798c613..30c165b152 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,7 +27,7 @@ own work-branch, make your changes to files in `evennia/docs/source/` and make a The sources in `evennia/docs/source/` are built into a pretty documentation using the [Sphinx][sphinx] static generator system. To do so locally you need to either use a system with `make` (Linux/Unix/Mac or [Windows-WSL][Windows-WSL]). Lacking that, you could -in principle also run the sphinx build-commands manually - read the `evennia/docs/Makefile` to see +in principle also run the sphinx build-commands manually - read the `evennia/docs/Makefile` to see which commands are run by `make`. You don't necessarily _have_ to build the docs locally to contribute. But @@ -164,26 +164,26 @@ available at `https://evennia.github.io/evennia/`. The format is [Markdown][commonmark-help] (Commonmark). While markdown supports a few alternative forms for some of these, we try to stick to the below forms for consistency. -## Italic/Bold +## Italic/Bold We generally use underscores for italics and double-asterisks for bold: - `_Italic text_` - `**Bold Text**` -## Headings +## Headings We use `#` to indicate sections/headings. The more `#` the more of a sub-heading it is (will get smaller and smaller font). - `# Heading` - `## SubHeading` -- `## SubSubHeading` +- `## SubSubHeading` > Don't reuse the same heading/subheading name over and over in the same document. While Markdown does not prevent -it, it makes it impossible to link to those duplicates properly (see next section). +it, it makes it impossible to link to those duplicates properly (see next section). -## Lists +## Lists One can create both bullet-point lists and numbered lists: @@ -198,34 +198,34 @@ One can create both bullet-point lists and numbered lists: 3. Numbered point three ``` -## Notes +## Notes A note can be used to enphasise important things. It's added by starting one or more lines with `>`. ``` -> Note: This is an important -> thing to remember. +> Note: This is an important +> thing to remember. ``` -## Links +## Links -- `[linktext](url_or_ref)` - gives a clickable link `linktext`. +- `[linktext](url_or_ref)` - gives a clickable link `linktext`. The `url_or_ref` can either be a full `http://...` url or an internal _reference_. For example, use -`[my document](My-Document)` to link to the document `evennia/docs/source/My-Document.md`. Avoid using +`[my document](My-Document)` to link to the document `evennia/docs/source/My-Document.md`. Avoid using full `http://` linking unless really referring to an external resource. - `[linktext](ref#heading-name)` -You can point to sub-sections (headings) in a document by using a single `#` and the name of the +You can point to sub-sections (headings) in a document by using a single `#` and the name of the heading, replacing spaces with dashes. So to refer to a heading `## Cool Stuff` inside `My-Document` would be a link `[cool stuff](My-Document#Cool-Stuff)`. - `[linktext][linkref]` - refer to a reference defined later in the document. -Urls can get long and if you are using the same url in many places it can get a little cluttered. So you can also put +Urls can get long and if you are using the same url in many places it can get a little cluttered. So you can also put the url as a 'footnote' at the end of your document -and refer to it by putting your reference within square brackets `[ ]`. Here's an example: +and refer to it by putting your reference within square brackets `[ ]`. Here's an example: ``` This is a [clickable link][mylink]. This is [another link][1]. @@ -238,7 +238,7 @@ This is a [clickable link][mylink]. This is [another link][1]. ``` -### Special references +### Special references The Evennia documentation supports some special reference shortcuts in links: @@ -246,11 +246,11 @@ The Evennia documentation supports some special reference shortcuts in links: - `github:` - a shortcut for the full path to the Evennia repository on github. This will refer to the `master` branch by default: - + [link to objects.py](github:evennia/objects/objects.py) This will remap to https://github.com/evennia/evennia/blob/master/evennia/objects/objects.py. -- To refer to the `develop` branch, start the url with `develop/`: +- To refer to the `develop` branch, start the url with `develop/`: [link to objects.py](github:develop/evennia/objects/objects.py) @@ -260,37 +260,37 @@ The Evennia documentation supports some special reference shortcuts in links: [link to api for objects.py](api:evennia.objects) - This will create a link to the auto-generated `evennia/source/api/evennia.objects.rst` document. + This will create a link to the auto-generated `evennia/source/api/evennia.objects.rst` document. Since api-docs are generated alongside the documentation, this will always be the api docs for the - current version/branch of the docs. + current version/branch of the docs. #### Bug reports/feature request -- `issue`, `bug-report`, `feature-request` - links to the same github issue select page. +- `issue`, `bug-report`, `feature-request` - links to the same github issue select page. If you find a problem, make a [bug report](issue)! This will generate a link to https://github.com/evennia/evennia/issues/new/choose. - - > For some reason these particular shortcuts gives a warning during documentation compilation. This - > can be ignored. + + > For some reason these particular shortcuts gives a warning during documentation compilation. This + > can be ignored. ## Verbatim text -It's common to want to mark something to be displayed verbatim - just as written - without any -Markdown parsing. In running text, this is done using backticks (\`), like \`verbatim text\` becomes `verbatim text`. +It's common to want to mark something to be displayed verbatim - just as written - without any +Markdown parsing. In running text, this is done using backticks (\`), like \`verbatim text\` becomes `verbatim text`. If you want to put the verbatim text on its own line, you can do so easily by simply indenting -it 4 spaces (add empty lines on each side for readability too): +it 4 spaces (add empty lines on each side for readability too): ``` -This is normal text +This is normal text - This is verbatim text + This is verbatim text -This is normal text +This is normal text ``` Another way is to use triple-backticks: @@ -304,29 +304,29 @@ Everything within these backticks will be verbatim. ## Code blocks -A special case is code examples - we want them to get code-highlighting for readability. This is done by using +A special case is code examples - we want them to get code-highlighting for readability. This is done by using the triple-backticks and specify which language we use: ```` ```python def a_python_func(x): - return x * x - -``` + return x * x + +``` ```` ## ReST blocks -Markdown is easy to read and use. But while it does most of what we need, there are some things it's -not quite as expressive as it needs to be. For this we need to fall back to the [ReST][ReST] markup -language which the documentation system uses under the hood. This is done by specifying `eval_rst` as -the name of the `language` of a literal block: +Markdown is easy to read and use. But while it does most of what we need, there are some things it's +not quite as expressive as it needs to be. For this we need to fall back to the [ReST][ReST] markup +language which the documentation system uses under the hood. This is done by specifying `eval_rst` as +the name of the `language` of a literal block: ```` ```eval_rst - This will be evaluated as ReST. + This will be evaluated as ReST. ``` ```` @@ -334,7 +334,7 @@ There is also a short-hand form for starting a [ReST directive][ReST-directives] ```` ```directive:: possible-option - + Content that *must* be indented for it to be included in the directive. New lines are ignored except if separated by an empty line. @@ -348,64 +348,64 @@ See below for examples of this. This will display a one-line note that will pop even more than a normal `> note`. ```` -```important:: +```{important} This is important because it is! ``` ```` #### Warning -A warning block is used to draw attention to particularly dangerous things, or features easy to +A warning block is used to draw attention to particularly dangerous things, or features easy to mess up. ```` -```warning:: - Be careful about this ... +```warning + Be careful about this ... ```` #### Version changes and deprecations -These will show up as one-line warnings that suggest an added, changed or deprecated +These will show up as one-line warnings that suggest an added, changed or deprecated feature beginning with particular version. ```` -```versionadded:: 1.0 +```{versionadded} 1.0 ``` ```` ```` -```versionchanged:: 1.0 +```{versionchanged} 1.0 How the feature changed with this version. ``` ```` ```` -```deprecated:: 1.0 +```{deprecated} 1.0 ``` ```` -#### Sidebar +#### Sidebar This will display an informative sidebar that floats to the side of regular content. This is useful for example to remind the reader of some concept relevant to the text. ```` -```sidebar:: Things to remember +```{sidebar} Things to remember - There can be bullet lists - in here. Headers with indented blocks: - like this + like this Will end up as full sub-headings: in the sidebar. ``` ```` -> Remember that for ReST-directives, the content within the triple-backticks _must_ be indented to ->some degree or the content will just appear outside of the directive as regular text. +> Remember that for ReST-directives, the content within the triple-backticks _must_ be indented to +>some degree or the content will just appear outside of the directive as regular text. -#### Tables +#### Tables A table is specified using [ReST table syntax][ReST-tables]: @@ -438,9 +438,9 @@ or the more flexible but verbose ``` ```` -#### A more flexible code block +#### A more flexible code block -The regular Markdown codeblock is usually enough but for more direct control over the style, one +The regular Markdown codeblock is usually enough but for more direct control over the style, one can also specify the code block explicitly in `ReST`. for more flexibility. It also provides a link to the code block, identified by its name. @@ -464,9 +464,9 @@ for more flexibility. It also provides a link to the code block, identified by i ```` Here, `:linenos:` turns on line-numbers and `:emphasize-lines:` allows for emphasizing certain lines in a different color. The `:caption:` shows an instructive text and `:name:` is used to reference this -block through the link that will appear (so it should be unique for a give document). +block through the link that will appear (so it should be unique for a give document). -> The default markdown syntax will actually generate a code-block ReST instruction like this +> The default markdown syntax will actually generate a code-block ReST instruction like this > automatically for us behind the scenes. The automatic generation can't know things like emphasize-lines > or caption since that's not a part of the Markdown specification. diff --git a/docs/pylib/api_rst2md.py b/docs/pylib/api_rst2md.py new file mode 100755 index 0000000000..5bb3bc00f6 --- /dev/null +++ b/docs/pylib/api_rst2md.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +""" +Remap autodoc API rst files to md files and wrap their contents. + +""" + +from glob import glob +from os.path import abspath, join as pathjoin, dirname +from os import rename + + +def _rst2md(filename_rst): + + with open(filename_rst, 'r') as fil: + # read rst file, reformat and save + txt = fil.read() + with open(filename_rst, 'w') as fil: + txt = "```{eval-rst}\n" + txt + "\n```" + fil.write(txt) + + # rename .rst file to .md file + filename, _ = filename_rst.rsplit('.', 1) + filename_md = filename + ".md" + rename(filename_rst, filename_md) + + +if __name__ == "__main__": + apidir = pathjoin(dirname(dirname(abspath(__file__))), "source", "api") + for filename_rst in glob(pathjoin(apidir, "*.rst")): + _rst2md(filename_rst) + print(" Converted {apidir}/*.rst files to .md files".format(apidir=apidir)) diff --git a/docs/pylib/auto_link_remapper.py b/docs/pylib/auto_link_remapper.py index 2ec27ac02d..0b971492bc 100644 --- a/docs/pylib/auto_link_remapper.py +++ b/docs/pylib/auto_link_remapper.py @@ -19,13 +19,19 @@ _NO_REMAP_STARTSWITH = [ "http://", "https://", "github:", - "api:", "feature-request", "report-bug", "issue", "bug-report", ] - +# remove these prefixes from the url +_STRIP_PREFIX = [ + "../../api/", + "../api/", + "./api/", + "api/", + "api:", +] TXT_REMAPS = { "Developer Central": "Evennia Components overview", "Getting Started": "Setup Quickstart", @@ -54,6 +60,8 @@ URL_REMAPS = { "./Default-Command-Help": "api:evennia.commands.default#modules", "../Components/Default-Command-Help": "api:evennia.commands.default#modules", "../../../Components/Default-Command-Help": "api:evennia.commands.default#modules", + "./Locks.md#permissions": "Permissions", + "modules": "Default-Commands.md", } _USED_REFS = {} @@ -123,11 +131,11 @@ def auto_link_remapper(no_autodoc=False): # normal reference-links [txt](urls) ref_regex = re.compile( - r"\[(?P[\w -\[\]\`]+?)\]\((?P.+?)\)", re.I + re.S + re.U + re.M + r"\[(?P[\n\w -\[\]\`]+?)\]\((?P.+?)\)", re.I + re.S + re.U + re.M ) # in document references ref_doc_regex = re.compile( - r"\[(?P[\w -\`]+?)\]:\s+?(?P.+?)(?=$|\n)", re.I + re.S + re.U + re.M + r"\[(?P[\n\w -\`]+?)\]:\s+?(?P.+?)(?=$|\n)", re.I + re.S + re.U + re.M ) def _sub(match): @@ -139,27 +147,38 @@ def auto_link_remapper(no_autodoc=False): txt = TXT_REMAPS.get(txt, txt) url = URL_REMAPS.get(url, url) + for strip_prefix in _STRIP_PREFIX: + if url.startswith(strip_prefix): + url = url[len(strip_prefix):] + if any(url.startswith(noremap) for noremap in _NO_REMAP_STARTSWITH): + # skip regular http/s urls etc return f"[{txt}]({url})" - if "http" in url and "://" in url: - urlout = url - else: - fname, *part = url.rsplit("/", 1) - fname = part[0] if part else fname + if url.startswith("evennia."): + # api link - we want to remove legacy #reference and remove .md + if '#' in url: + _, url = url.rsplit('#', 1) + if url.endswith(".md"): + url, _ = url.rsplit('.', 1) + return f"[{txt}]({url})" + + fname, *part = url.rsplit("/", 1) + fname = part[0] if part else fname + fname, *anchor = fname.rsplit("#", 1) + if ".md" in fname: fname = fname.rsplit(".", 1)[0] - fname, *anchor = fname.rsplit("#", 1) - if not _CURRFILE.endswith("toc.md"): - _USED_REFS[fname] = url + if not _CURRFILE.endswith("toc.md"): + _USED_REFS[fname] = url - if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]: - cfilename = _CURRFILE.rsplit("/", 1)[-1] - urlout = docref_map[_CURRFILE][fname] + ("#" + anchor[0] if anchor else "") - if urlout != url: - print(f" {cfilename}: [{txt}]({url}) -> [{txt}]({urlout})") - else: - urlout = url + if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]: + cfilename = _CURRFILE.rsplit("/", 1)[-1] + urlout = docref_map[_CURRFILE][fname] + ".md" + ("#" + anchor[0].lower() if anchor else "") + if urlout != url: + print(f" {cfilename}: [{txt}]({url}) -> [{txt}]({urlout})") + else: + urlout = url return f"[{txt}]({urlout})" @@ -172,11 +191,19 @@ def auto_link_remapper(no_autodoc=False): txt = TXT_REMAPS.get(txt, txt) url = URL_REMAPS.get(url, url) + for strip_prefix in _STRIP_PREFIX: + if url.startswith(strip_prefix): + url = url[len(strip_prefix):] + if any(url.startswith(noremap) for noremap in _NO_REMAP_STARTSWITH): return f"[{txt}]: {url}" if "http" in url and "://" in url: urlout = url + elif url.startswith("evennia."): + # api link - we want to remove legacy #reference + if '#' in url: + _, urlout = url.rsplit('#', 1) else: fname, *part = url.rsplit("/", 1) fname = part[0] if part else fname @@ -217,12 +244,12 @@ def auto_link_remapper(no_autodoc=False): print(f" -- Auto-corrected links in {count} documents.") for (fname, src_url) in sorted(toc_map.items(), key=lambda tup: tup[0]): - if fname not in _USED_REFS: + if fname not in _USED_REFS and not src_url.startswith("api/"): print(f" ORPHANED DOC: no refs found to {src_url}.md") # write tocfile with open(_TOC_FILE, "w") as fil: - fil.write("# Toc\n") + fil.write("```{toctree}\n") if not no_autodoc: fil.write("- [API root](api/evennia-api.rst)") @@ -232,14 +259,14 @@ def auto_link_remapper(no_autodoc=False): if ref == "toc": continue - if not "/" in ref: - ref = "./" + ref + # if not "/" in ref: + # ref = "./" + ref - linkname = ref.replace("-", " ") - fil.write(f"\n- [{linkname}]({ref})") + # linkname = ref.replace("-", " ") + fil.write(f"\n{ref}") # - [{linkname}]({ref})") # we add a self-reference so the toc itself is also a part of a toctree - fil.write("\n\n```toctree::\n :hidden:\n\n toc\n```") + fil.write("\n```\n\n```{toctree}\n :hidden:\n\ntoc\n```") print(" -- Auto-Remapper finished.") diff --git a/docs/pylib/update_default_cmd_index.py b/docs/pylib/update_default_cmd_index.py new file mode 100644 index 0000000000..5d864981d0 --- /dev/null +++ b/docs/pylib/update_default_cmd_index.py @@ -0,0 +1,111 @@ +# +# This creates a Google wiki page for all default commands with __doc__ strings. +# +# Import this from a Django-aware shell, then call run_update. +# +# + +from os.path import dirname, abspath, join as pathjoin +from evennia.utils.utils import ( + mod_import, variable_from_module, callables_from_module +) + +__all__ = ("run_update") + + +PAGE = """ + +# Default Commands + +The full set of default Evennia commands currently contains {ncommands} commands in {nfiles} source +files. Our policy for adding default commands is outlined [here](Using-MUX-as-a-Standard). The +[Commands](Commands) documentation explains how Commands work as well as make new or customize +existing ones. Note that this page is auto-generated. Report problems to the [issue +tracker](github:issues). + +```{{note}} +Some game-states adds their own Commands which are not listed here. Examples include editing a text +with [EvEditor](EvEditor), flipping pages in [EvMore](EvMore) or using the +[Batch-Processor](Batch-Processors)'s interactive mode. +``` + +{alphabetical} + +""" + +def run_update(no_autodoc=False): + + if no_autodoc: + return + + cmdsets = ( + ("evennia.commands.default.cmdset_character", "CharacterCmdSet"), + ("evennia.commands.default.cmdset_account", "AccountCmdSet"), + ("evennia.commands.default.cmdset_unloggedin", "UnloggedinCmdSet"), + ("evennia.commands.default.cmdset_session", "SessionCmdSet"), + ) + cmd_modules = ( + "evennia.commands.default.account", + "evennia.commands.default.batchprocess", + "evennia.commands.default.building", + "evennia.commands.default.comms", + "evennia.commands.default.general", + "evennia.commands.default.help", + "evennia.commands.default.syscommandsyyp", + "evennia.commands.default.system", + "evennia.commands.default.unloggedin", + ) + + cmds_per_cmdset = {} + cmd_to_cmdset_map = {} + for modname, cmdsetname in cmdsets: + cmdset = variable_from_module(modname, variable=cmdsetname)() + cmdset.at_cmdset_creation() + cmds_per_cmdset[cmdsetname] = cmdset.commands + for cmd in cmdset.commands: + cmd_to_cmdset_map[f"{cmd.__module__}.{cmd.__class__.__name__}"] = cmdset + + cmds_per_module = {} + cmd_to_module_map = {} + cmds_alphabetically = [] + for modname in cmd_modules: + module = mod_import(modname) + cmds_per_module[module] = [ + cmd for cmd in callables_from_module(module).values() if cmd.__name__.startswith("Cmd")] + for cmd in cmds_per_module[module]: + cmd_to_module_map[cmd] = module + cmds_alphabetically.append(cmd) + cmds_alphabetically = list(sorted(cmds_alphabetically, key=lambda c: c.key)) + + cmd_infos = [] + for cmd in cmds_alphabetically: + aliases = f" [{', '.join(cmd.aliases)}]" if cmd.aliases else "" + cmdlink = f"[**{cmd.key}**{aliases}]({cmd.__module__}.{cmd.__name__})" + category = f"help-category: _{cmd.help_category.capitalize()}_" + cmdset = cmd_to_cmdset_map.get(f"{cmd.__module__}.{cmd.__name__}", None) + if cmdset: + cmodule = cmdset.__module__ + cname = cmdset.__class__.__name__ + cmdsetlink = f"cmdset: [{cname}]({cmodule}.{cname}), " + else: + # we skip commands not in the default cmdsets + continue + + cmd_infos.append(f"{cmdlink} ({cmdsetlink}{category})") + + txt = PAGE.format( + ncommands=len(cmd_to_cmdset_map), + nfiles=len(cmds_per_module), + alphabetical="\n".join(f"- {info}" for info in cmd_infos)) + + outdir = pathjoin(dirname(dirname(abspath(__file__))), "source", "Components") + fname = pathjoin(outdir, "Default-Commands.md") + + with open(fname, 'w') as fil: + fil.write(txt) + + print(" -- Updated Default Command index.") + + +if __name__ == "__main__": + run_update() diff --git a/docs/requirements.txt b/docs/requirements.txt index cba2a17f50..848933a1d4 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,10 +2,11 @@ sphinx==3.2.1 sphinx-multiversion==0.2.4 -# lunr==0.5.8 +myst-parser==0.15.2 +myst-parser[linkify]==0.15.2 # recommonmark custom branch with evennia-specific fixes -git+https://github.com/evennia/recommonmark.git@evennia-mods#egg=recommonmark +# git+https://github.com/evennia/recommonmark.git@evennia-mods#egg=recommonmark # sphinxcontrib-lunrsearch custom branch with evennia-specific fixes -git+https://github.com/evennia/sphinxcontrib-lunrsearch.git@evennia-mods#egg=sphinxcontrib-lunrsearch +# git+https://github.com/evennia/sphinxcontrib-lunrsearch.git@evennia-mods#egg=sphinxcontrib-lunrsearch diff --git a/docs/source/Coding/Coding-Introduction.md b/docs/source/Coding/Coding-Introduction.md index 0bbf340739..73e8936ee8 100644 --- a/docs/source/Coding/Coding-Introduction.md +++ b/docs/source/Coding/Coding-Introduction.md @@ -5,18 +5,18 @@ 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. -### Start with the tutorial +## Start with the tutorial -It's highly recommended that you jump in on the [Starting Tutorial](../Howto/Starting/Part1/Starting-Part1). Even if +It's highly recommended that you jump in on the [Starting Tutorial](../Howto/Starting/Part1/Starting-Part1.md). Even if you only the beginning or some part of it, it covers much of the things needed to get started. -### Python +## Python Evennia is developed using Python. Even if you are more of a designer than a coder, it is wise to learn how to read and understand basic Python code. If you are new to Python, or need a refresher, -take a look at our [Python introduction](../Howto/Starting/Part1/Python-basic-introduction). +take a look at our [Python introduction](../Howto/Starting/Part1/Python-basic-introduction.md). -### Explore Evennia interactively +## Explore Evennia interactively When new to Evennia it can be hard to find things or figure out what is available. Evennia offers a special interactive python shell that allows you to experiment and try out things. It's recommended @@ -35,13 +35,13 @@ This will open an Evennia-aware python shell (using ipython). From within this s evennia. That is, enter `evennia.` and press the `` key. This will show you all the resources made -available at the top level of Evennia's "flat API". See the [flat API](../Evennia-API) page for more +available at the top level of Evennia's "flat API". See the [flat API](../Evennia-API.md) page for more info on how to explore it efficiently. -#### Jupyter Notebook Support +### Jupyter Notebook Support You can also explore evennia interactively in a [Jupyter notebook](https://jupyter.readthedocs.io/en/latest/index.html#). This offers -an in-browser view of your code similar to Matlab or similar programs. There are +an in-browser view of your code similar to Matlab or similar programs. There are a few extra steps that must be taken in order for this to work: # [open a new console/terminal] @@ -51,7 +51,7 @@ a few extra steps that must be taken in order for this to work: Next, `cd` to your game folder. _It's important that you are in the _root_ of this folder for the next command_: - evennia shell_plus --notebook & + evennia shell_plus --notebook & The `&` at the end starts the process as a background process on Linux/Unix. Skip it if your OS doesn't support this syntax. Your browser should now open @@ -59,7 +59,7 @@ with the Jupyter interface. If not, open a browser to the link given on the command line. In the window, open the `new` menu in the top right and start a `Django Shell-Plus` notebook (or -open an existing one if you had one from before). In the first cell you must initialize +open an existing one if you had one from before). In the first cell you must initialize Evennia like so: ```python @@ -71,13 +71,13 @@ _Note that the above initialization must be run every time a new new notebook/ke After this you can import and access all of the Evennia system, same as with `evennia shell`. -#### More exploration +### More exploration -You can complement your exploration by peeking at the sections of the much more detailed -[Evennia Component overview](../Components/Components-Overview). The [Tutorials](../Howto/Howto-Overview) section also contains a growing collection +You can complement your exploration by peeking at the sections of the much more detailed +[Evennia Component overview](../Components/Components-Overview.md). The [Tutorials](../Howto/Howto-Overview.md) section also contains a growing collection of system- or implementation-specific help. -### Use a python syntax checker +## Use a python syntax checker Evennia works by importing your own modules and running them as part of the server. Whereas Evennia should just gracefully tell you what errors it finds, it can nevertheless be a good idea for you to @@ -89,12 +89,12 @@ many python syntax checkers out there. A fast and easy one is every possible problem - some bugs or problems will only appear when you actually run the code. But using such a checker can be a good start to weed out the simple problems. -### Plan before you code +## Plan before you code -Before you start coding away at your dream game, take a look at our [Game Planning](../Howto/Starting/Part2/Game-Planning) +Before you start coding away at your dream game, take a look at our [Game Planning](../Howto/Starting/Part2/Game-Planning.md) page. It might hopefully help you avoid some common pitfalls and time sinks. -### Code in your game folder, not in the evennia/ repository +## Code in your game folder, not in the evennia/ repository As part of the Evennia setup you will create a game folder to host your game code. This is your home. You should *never* need to modify anything in the `evennia` library (anything you download @@ -103,9 +103,9 @@ it out into your game folder and edit it there. If you find that Evennia doesn't support some functionality you need, make a [Feature Request](github:issue) about it. Same goes for [bugs][bug]. If you add features or fix bugs -yourself, please consider [Contributing](../Contributing) your changes upstream! +yourself, please consider [Contributing](../Contributing.md) your changes upstream! -### Learn to read tracebacks +## Learn to read tracebacks Python is very good at reporting when and where things go wrong. A *traceback* shows everything you need to know about crashing code. The text can be pretty long, but you usually are only interested @@ -124,7 +124,7 @@ module holding your custom class. Since such a module is not valid Python, Evenn all. Instead of crashing, Evennia will then print the full traceback to the terminal/console and temporarily fall back to the safe `DefaultObject` until you fix the problem and reload. -### Docs are here to help you +## 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 @@ -133,7 +133,7 @@ can't find the answer in the docs, don't be shy to ask questions! The [discussio group](https://sites.google.com/site/evenniaserver/discussions) and the [irc chat](https://webchat.freenode.net/?channels=evennia) are also there for you. -### The most important point +## The most important point And finally, of course, have fun! diff --git a/docs/source/Coding/Coding-Overview.md b/docs/source/Coding/Coding-Overview.md index 96533b2a3d..f2a950f155 100644 --- a/docs/source/Coding/Coding-Overview.md +++ b/docs/source/Coding/Coding-Overview.md @@ -7,24 +7,24 @@ to you, but some things may still be useful. ## Find your way -- [Directory-Overview](../Howto/Starting/Part1/Gamedir-Overview) -- [Quirks of Evennia](./Quirks) +- [Directory-Overview](../Howto/Starting/Part1/Gamedir-Overview.md) +- [Quirks of Evennia](./Quirks.md) ## Setting up a workflow -- [Setting up PyCharm](./Setting-up-PyCharm) -- [Using Version-Control](./Version-Control) -- [Updating Evennia sources](./Updating-Your-Game) +- [Setting up PyCharm](./Setting-up-PyCharm.md) +- [Using Version-Control](./Version-Control.md) +- [Updating Evennia sources](./Updating-Your-Game.md) ## Coding away -- [Coding Introduction](./Coding-Introduction) -- [Ways to Debug](./Debugging) -- [Adding unit-tests](./Unit-Testing) -- [Things to remember when importing from evennia](./Flat-API) +- [Coding Introduction](./Coding-Introduction.md) +- [Ways to Debug](./Debugging.md) +- [Adding unit-tests](./Unit-Testing.md) +- [Things to remember when importing from evennia](./Flat-API.md) ## Advanced concepts -- [Continuous Integration](./Continuous-Integration) - - [Using Travis](./Using-Travis) -- [Profiling](./Profiling) +- [Continuous Integration](./Continuous-Integration.md) + - [Using Travis](./Using-Travis.md) +- [Profiling](./Profiling.md) diff --git a/docs/source/Coding/Continuous-Integration.md b/docs/source/Coding/Continuous-Integration.md index 5cb49891cc..db9bcc2e65 100644 --- a/docs/source/Coding/Continuous-Integration.md +++ b/docs/source/Coding/Continuous-Integration.md @@ -27,7 +27,7 @@ Among those you will need: * A Continuous Integration Environment. * I recommend [TeamCity](https://www.jetbrains.com/teamcity/) which has an in-depth [Setup Guide](https://confluence.jetbrains.com/display/TCD8/Installing+and+Configuring+the+TeamCity+Server) -* [Source Control](./Version-Control) +* [Source Control](./Version-Control.md) * This could be Git or SVN or any other available SC. ## Linux TeamCity Setup diff --git a/docs/source/Coding/Flat-API.md b/docs/source/Coding/Flat-API.md index 58b22fd6a8..6e41757c5e 100644 --- a/docs/source/Coding/Flat-API.md +++ b/docs/source/Coding/Flat-API.md @@ -1,7 +1,7 @@ # Things to remember about the flat API The flat API is a series of 'shortcuts' on the `evennia` main library root (defined in -`evennia/__init__.py`). Its componentas are documented [as part of the auto-documentation](../Evennia-API). +`evennia/__init__.py`). Its componentas are documented [as part of the auto-documentation](../Evennia-API.md). ## To remember when importing from `evennia` diff --git a/docs/source/Coding/Profiling.md b/docs/source/Coding/Profiling.md index f7e70f1da1..51716a1051 100644 --- a/docs/source/Coding/Profiling.md +++ b/docs/source/Coding/Profiling.md @@ -58,7 +58,7 @@ through the launcher: This will start Evennia with the Server component running (in daemon mode) under cProfile. You could instead try `--profile` with the `portal` argument to profile the Portal (you would then need to -[start the Server separately](../Setup/Start-Stop-Reload)). +[start the Server separately](../Setup/Start-Stop-Reload.md)). Please note that while the profiler is running, your process will use a lot more memory than usual. Memory usage is even likely to climb over time. So don't @@ -127,7 +127,7 @@ game with simulated players (aka "bots" or "dummies"). Once connected, these dummies will semi-randomly perform various tasks from a list of possible actions. Use `Ctrl-C` to stop the Dummyrunner. -```warning:: +```{warning} You should not run the Dummyrunner on a production database. It will spawn many objects and also needs to run with general permissions. diff --git a/docs/source/Coding/Quirks.md b/docs/source/Coding/Quirks.md index d631d7a3b3..0e2274a588 100644 --- a/docs/source/Coding/Quirks.md +++ b/docs/source/Coding/Quirks.md @@ -4,7 +4,7 @@ This is a list of various quirks or common stumbling blocks that people often ask about or report when using (or trying to use) Evennia. They are not bugs. -### Forgetting to use @reload to see changes to your typeclasses +## Forgetting to use @reload to see changes to your typeclasses Firstly: Reloading the server is a safe and usually quick operation which will *not* disconnect any accounts. @@ -13,7 +13,7 @@ New users tend to forget this step. When editing source code (such as when tweak commands or adding new commands to command sets) you need to either use the in-game `@reload` command or, from the command line do `python evennia.py reload` before you see your changes. -### Web admin to create new Account +## Web admin to create new Account If you use the default login system and are trying to use the Web admin to create a new Player account, you need to consider which `MULTIACCOUNT_MODE` you are in. If you are in @@ -28,12 +28,12 @@ the "account" property on the Character and the "character" property on the Acco other. You must also set the lockstring of the Character to allow the Account to "puppet" this particular character. -### Mutable attributes and their connection to the database +## Mutable attributes and their connection to the database When storing a mutable object (usually a list or a dictionary) in an Attribute ```python - object.db.mylist = [1,2,3] + object.db.mylist = [1,2,3] ``` you should know that the connection to the database is retained also if you later extract that @@ -62,16 +62,16 @@ use of `evennia.utils.dbserialize.deserialize`: The property `blist` is now `[1,2,3,4]` whereas `object.db.mylist` remains unchanged. If you want to update the database you'd need to explicitly re-assign the updated data to the `mylist` Attribute. -### Commands are matched by name *or* alias +## Commands are matched by name *or* alias -When merging [command sets](../Components/Commands) it's important to remember that command objects are identified +When merging [command sets](../Components/Commands.md) it's important to remember that command objects are identified *both* by key *or* alias. So if you have a command with a key `look` and an alias `ls`, introducing another command with a key `ls` will be assumed by the system to be *identical* to the first one. This usually means merging cmdsets will overload one of them depending on priority. Whereas this is logical once you know how command objects are handled, it may be confusing if you are just looking at the command strings thinking they are parsed as-is. -### Objects turning to `DefaultObject` +## Objects turning to `DefaultObject` A common confusing error for new developers is finding that one or more objects in-game are suddenly of the type `DefaultObject` rather than the typeclass you wanted it to be. This happens when you @@ -82,7 +82,7 @@ back to the safe `DefaultObject` until you fix the problem and reload. Most erro be caught by any good text editors. Keep an eye on the terminal/console during a reload to catch such errors - you may have to scroll up if your window is small. -### Overriding of magic methods +## Overriding of magic methods Python implements a system of [magic methods](https://docs.python.org/3/reference/datamodel.html#emulating-container-types), usually @@ -104,17 +104,17 @@ can result in very inconsistent and hard-to-diagnose errors. The moral of the story-- it can be dangerous to tinker with magic methods on typeclassed objects. Try to avoid doing so. -### Known upstream bugs +## Known upstream bugs - There is currently (Autumn 2017) a bug in the `zope.interface` installer on some Linux Ubuntu distributions (notably Ubuntu 16.04 LTS). Zope is a dependency of Twisted. The error manifests in the server not starting with an error that `zope.interface` is not found even though `pip list` shows it's installed. The reason is a missing empty `__init__.py` file at the root of the zope -package. If the virtualenv is named "evenv" as suggested in the [Setup Quickstart](../Setup/Setup-Quickstart) +package. If the virtualenv is named "evenv" as suggested in the [Setup Quickstart](../Setup/Setup-Quickstart.md) instructions, use the following command to fix it: ```shell touch evenv/local/lib/python2.7/site-packages/zope/__init__.py ``` - This will create the missing file and things should henceforth work correctly. \ No newline at end of file + This will create the missing file and things should henceforth work correctly. diff --git a/docs/source/Coding/Unit-Testing.md b/docs/source/Coding/Unit-Testing.md index 42df6764f2..0044b4f53a 100644 --- a/docs/source/Coding/Unit-Testing.md +++ b/docs/source/Coding/Unit-Testing.md @@ -74,28 +74,28 @@ To test the results, you use special methods of the `TestCase` class. Many of t "`assert`", such as `assertEqual` or `assertTrue`. Example of a `TestCase` class: - + ```python import unittest - + # the function we want to test from mypath import myfunc - + class TestObj(unittest.TestCase): "This tests a function myfunc." - + def test_return_value(self): - "test method. Makes sure return value is as expected." + "test method. Makes sure return value is as expected." expected_return = "This is me being nice." actual_return = myfunc() - # test + # 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) + self.assertEqual(expected_return, actual_return) ``` You might also want to read the [documentation for the unittest @@ -145,7 +145,7 @@ class in the same module to get access to the command-specific utilities mention self.call(general.CmdLook(), "Char2", "Char2(#7)") "tests the look command by simple call, with target as room" def test_mycmd_room(self): - self.call(general.CmdLook(), "Room", + self.call(general.CmdLook(), "Room", "Room(#1)\nroom_desc\nExits: out(#3)\n" "You see: Obj(#4), Obj2(#5), Char2(#7)") ``` @@ -153,7 +153,7 @@ class in the same module to get access to the command-specific utilities mention ### Unit testing contribs with custom models A special case is if you were to create a contribution to go to the `evennia/contrib` folder that -uses its [own database models](../Concepts/New-Models). The problem with this is that Evennia (and Django) will +uses its [own database models](../Concepts/New-Models.md). The problem with this is that Evennia (and Django) will only recognize models in `settings.INSTALLED_APPS`. If a user wants to use your contrib, they will be required to add your models to their settings file. But since contribs are optional you cannot add the model to Evennia's central `settings_default.py` file - this would always create your @@ -199,7 +199,7 @@ class TestMyModel(EvenniaTest): from django.db.models import loading loading.cache.loaded = False call_command('syncdb', verbosity=0) - + def tearDown(self): settings.configure(**OLD_DEFAULT_SETTINGS) django.setup() @@ -290,11 +290,11 @@ just to show how unit testing works: # mygame/commands/tests.py import unittest - + class TestString(unittest.TestCase): - + """Unittest for strings (just a basic example).""" - + def test_upper(self): """Test the upper() str method.""" self.assertEqual('foo'.upper(), 'FOO') @@ -317,7 +317,7 @@ Let's execute that test to see if it works. . ---------------------------------------------------------------------- Ran 1 test in 0.001s - + OK Destroying test database for alias 'default'... @@ -330,7 +330,7 @@ to see how it looks when it fails. ### Testing commands -```warning:: This is not correct anymore. +```{warning} This is not correct anymore. ``` This section will test the proper execution of the 'abilities' command, as described in the DELETED @@ -349,14 +349,14 @@ already have in `commands` from before. # bottom of mygame/commands/tests.py from evennia.commands.default.tests import CommandTest - + from commands.command import CmdAbilities from typeclasses.characters import Character - + class TestAbilities(CommandTest): - + character_typeclass = Character - + def test_simple(self): self.call(CmdAbilities(), "", "STR: 5, AGI: 4, MAG: 2") ``` @@ -392,7 +392,7 @@ Let's run our new test: .. ---------------------------------------------------------------------- Ran 2 tests in 0.156s - + OK Destroying test database for alias 'default'... diff --git a/docs/source/Coding/Updating-Your-Game.md b/docs/source/Coding/Updating-Your-Game.md index 383e8d6417..617d482ac0 100644 --- a/docs/source/Coding/Updating-Your-Game.md +++ b/docs/source/Coding/Updating-Your-Game.md @@ -2,9 +2,9 @@ Fortunately, it's extremely easy to keep your Evennia server up-to-date. If you haven't already, see -the [Getting Started guide](../Setup/Setup-Quickstart) and get everything running. +the [Getting Started guide](../Setup/Setup-Quickstart.md) and get everything running. -### Updating with the latest Evennia code changes +## Updating with the latest Evennia code changes Very commonly we make changes to the Evennia code to improve things. 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 @@ -30,7 +30,7 @@ the new code affect your game. If you want to be really sure you should run a fu so that both Server and Portal can restart (this will disconnect everyone though, so if you know the Portal has had no updates you don't have to do that). -### Upgrading Evennia dependencies +## Upgrading Evennia dependencies On occasion we update the versions of third-party libraries Evennia depend on (or we may add a new dependency). This will be announced on the mailing list/forum. If you run into errors when starting @@ -40,8 +40,8 @@ version that should not be used in production. Upgrading `evennia` will automatically fetch all the latest packages that it now need. First `cd` to your cloned `evennia` folder. Make sure your `virtualenv` is active and use - - pip install --upgrade -e . + + pip install --upgrade -e . Remember the period (`.`) at the end - that applies the upgrade to the current location (your `evennia` dir). @@ -55,7 +55,7 @@ source-code changes. Follow the upgrade output to make sure it finishes without errors. To check what packages are currently available in your python environment after the upgrade, use - pip list + pip list This will show you the version of all installed packages. The `evennia` package will also show the location of its source code. @@ -72,13 +72,13 @@ When the database schema changes, you just go to your game folder and run evennia migrate > Hint: If the `evennia` command is not found, you most likely need to activate your -[virtualenv](../Glossary#virtualenv). +[virtualenv](../Glossary.md#virtualenv). ## 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 by running +from scratch by running evennia migrate @@ -131,4 +131,4 @@ automatically for you. Basically, whenever the schema changes we distribute smal "migrations" with the source. Those tell the system exactly how to implement the change so you don't have to do so manually. When a migration has been added we will tell you so on Evennia's mailing lists and in commit messages - -you then just run `evennia migrate` to be up-to-date again. +you then just run `evennia migrate` to be up-to-date again. diff --git a/docs/source/Coding/Version-Control.md b/docs/source/Coding/Version-Control.md index 31314e7ec7..06f5df57f3 100644 --- a/docs/source/Coding/Version-Control.md +++ b/docs/source/Coding/Version-Control.md @@ -324,7 +324,7 @@ developer mailing list or IRC chat to see beforehand if your feature is deemed s as a core feature in the engine. When it comes to bug-fixes, other developers may also have good input on how to go about resolving the issue. -To contribute you need to have [forked Evennia](./Version-Control#forking-evennia) first. As described +To contribute you need to have [forked Evennia](./Version-Control.md#forking-evennia) first. As described above you should do your modification in a separate local branch (not in the master branch). This branch is what you then present to us (as a *Pull request*, PR, see below). We can then merge your change into the upstream master and you then do `git pull` to update master usual. Now that the diff --git a/docs/source/Components/Accounts.md b/docs/source/Components/Accounts.md index c6956f841b..619ab892ba 100644 --- a/docs/source/Components/Accounts.md +++ b/docs/source/Components/Accounts.md @@ -1,45 +1,45 @@ # Accounts -All *users* (real people) that starts a game [Session](./Sessions) on Evennia are doing so through an +All *users* (real people) that starts a game [Session](./Sessions.md) on Evennia are doing so through an object called *Account*. The Account object has no in-game representation, it represents a unique -game account. In order to actually get on the game the Account must *puppet* an [Object](./Objects) -(normally a [Character](./Objects#Character)). +game account. In order to actually get on the game the Account must *puppet* an [Object](./Objects.md) +(normally a [Character](./Objects.md#characters)). Exactly how many Sessions can interact with an Account and its Puppets at once is determined by -Evennia's [MULTISESSION_MODE](./Sessions#Multisession-mode) setting. +Evennia's [MULTISESSION_MODE](./Sessions.md#multisession-mode) setting. Apart from storing login information and other account-specific data, the Account object is what is -chatting on [Channels](./Communications). It is also a good place to store [Permissions](./Locks) to be +chatting on [Channels](./Communications.md). It is also a good place to store [Permissions](./Locks.md) to be consistent between different in-game characters as well as configuration options. The Account -object also has its own [CmdSet](./Command-Sets), the `AccountCmdSet`. +object also has its own [CmdSet](./Command-Sets.md), the `AccountCmdSet`. Logged into default evennia, you can use the `ooc` command to leave your current -[character](./Objects) and go into OOC mode. You are quite limited in this mode, basically it works +[character](./Objects.md) 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 -(re)puppet a Character. +(re)puppet a Character. Note that the Account object can have, and often does have, a different set of -[Permissions](./Locks#Permissions) from the Character they control. Normally you should put your +[Permissions](./Permissions.md) from the Character they control. Normally you should put your permissions on the Account level - this will overrule permissions set on the Character level. For the permissions of the Character to come into play the default `quell` command can be used. This allows for exploring the game using a different permission set (but you can't escalate your permissions this way - for hierarchical permissions like `Builder`, `Admin` etc, the *lower* of the -permissions on the Character/Account will always be used). +permissions on the Character/Account will always be used). ## How to create your own Account types You will usually not want more than one Account typeclass for all new accounts (but you could in -principle create a system that changes an account's typeclass dynamically). +principle create a system that changes an account's typeclass dynamically). An Evennia Account is, per definition, a Python class that includes `evennia.DefaultAccount` among its parents. In `mygame/typeclasses/accounts.py` there is an empty class ready for you to modify. -Evennia defaults to using this (it inherits directly from `DefaultAccount`). +Evennia defaults to using this (it inherits directly from `DefaultAccount`). -Here's an example of modifying the default Account class in code: +Here's an example of modifying the default Account class in code: -```python +```python # in mygame/typeclasses/accounts.py from evennia import DefaultAccount @@ -51,7 +51,7 @@ Here's an example of modifying the default Account class in code: self.db.config_1 = True # default config self.db.config_2 = False # " self.db.config_3 = 1 # " - # ... whatever else our game needs to know ``` Reload the server with `reload`. + # ... whatever else our game needs to know ``` Reload the server with `reload`. ``` @@ -65,7 +65,7 @@ using `py`: ``` py [account.at_account_creation() for account in evennia.managers.accounts.all()] ``` -You should now see the Attributes on yourself. +You should now see the Attributes on yourself. > If you wanted Evennia to default to a completely *different* Account class located elsewhere, you @@ -76,8 +76,8 @@ You should now see the Attributes on yourself. ## Properties on Accounts -Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses)), the -Account also has the following custom properties: +Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses.md)), the +Account 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`. @@ -91,12 +91,12 @@ as - `is_superuser` (bool: True/False) - if this account is a superuser. Special handlers: -- `cmdset` - This holds all the current [Commands](./Commands) of this Account. By default these are +- `cmdset` - This holds all the current [Commands](./Commands.md) of this Account. By default these are the commands found in the cmdset defined by `settings.CMDSET_ACCOUNT`. -- `nicks` - This stores and handles [Nicks](./Nicks), in the same way as nicks it works on Objects. +- `nicks` - This stores and handles [Nicks](./Nicks.md), in the same way as nicks it works on Objects. For Accounts, nicks are primarily used to store custom aliases for -[Channels](./Communications#Channels). - +[Channels](./Channels.md). + Selection of special methods (see `evennia.DefaultAccount` for details): - `get_puppet` - get a currently puppeted object connected to the Account and a given session id, if any. @@ -104,4 +104,4 @@ Selection of special methods (see `evennia.DefaultAccount` for details): - `unpuppet_object` - disconnect a session from a puppetable Object. - `msg` - send text to the Account - `execute_cmd` - runs a command as if this Account did it. -- `search` - search for Accounts. \ No newline at end of file +- `search` - search for Accounts. diff --git a/docs/source/Components/Attributes.md b/docs/source/Components/Attributes.md index d718eb0c79..3c6e373cd8 100644 --- a/docs/source/Components/Attributes.md +++ b/docs/source/Components/Attributes.md @@ -7,8 +7,8 @@ can give correct subsequent commands. If you are writing a combat system, you mi 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](./Typeclasses) game entities ([Accounts](./Accounts), [Objects](./Objects), -[Scripts](./Scripts) and [Channels](./Communications)) always have *Attributes* associated with them. +[Typeclassed](./Typeclasses.md) game entities ([Accounts](./Accounts.md), [Objects](./Objects.md), +[Scripts](./Scripts.md) and [Channels](./Communications.md)) 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 @@ -16,12 +16,12 @@ specific names and require very specific types of data (for example you couldn't want to assign arbitrary data to arbitrary names. **Attributes are _not_ secure by default and any player may be able to change them unless you -[prevent this behavior](./Attributes#locking-and-checking-attributes).** +[prevent this behavior](./Attributes.md#locking-and-checking-attributes).** ## The .db and .ndb shortcuts 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](./Objects)): +try to save some data to a *Rose* (an [Object](./Objects.md)): ```python # saving @@ -87,13 +87,13 @@ The handlers have normal access methods that allow you to manage and retrieve `A returned, but the method takes keywords for returning the Attribute object itself. By supplying an `accessing_object` to 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](./Locks) can be +- `add(...)` - this adds a new Attribute to the object. An optional [lockstring](./Locks.md) 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 [this section](./Attributes#locking-and-checking-attributes) for more about locking down Attribute +See [this section](./Attributes.md#locking-and-checking-attributes) for more about locking down Attribute access and editing. The `Nattribute` offers no concept of access control. Some examples: @@ -118,23 +118,23 @@ An Attribute object is stored in the database. It has the following properties: 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 - [this section](./Attributes#What_types_of_data_can_I_save_in_an_Attribute) for more info). In the + [this section](./Attributes.md#what-types-of-data-can-i-save-in-an-attribute) 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](./Nicks) is an example of using + to use Attributes for very different functionality ([Nicks](./Nicks.md) is an example of using Attributes - in this way). To modify this property you need to use the [Attribute -Handler](Attributes#The_Attribute_Handler). + in this way). To modify this property you need to use the +[Attribute Handler](./Attributes.md#the-attributehandler). - `strvalue` - this is a separate value field that only accepts strings. This severely 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](./Nicks) use it). It is only - accessible via the [Attribute Handler](./Attributes#The_Attribute_Handler). + except when re-using Attributes for some other purpose ([Nicks](./Nicks.md) use it). It is only + accessible via the [Attribute Handler](./Attributes.md#the-attributehandler). There are also two special properties: -- `attrtype` - this is used internally by Evennia to separate [Nicks](./Nicks), from Attributes (Nicks +- `attrtype` - this is used internally by Evennia to separate [Nicks](./Nicks.md), from Attributes (Nicks use Attributes behind the scenes). - `model` - this is a *natural-key* describing the model this Attribute is attached to. This is on the form *appname.modelclass*, like `objects.objectdb`. It is used by the Attribute and @@ -162,7 +162,7 @@ default during heavy loads. - A more valid reason for using non-persistent data is if you *want* to lose 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](./Scripts) that + are implementing some caching of your own. Or maybe you are testing a buggy [Script](./Scripts.md) 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. @@ -192,7 +192,7 @@ not a big deal. But if you are accessing the Attribute as part of some big loop amount of reads/writes you should first extract it to a temporary variable, operate on *that* and then save the result back to the Attribute. If you are storing a more complex structure like a `dict` or a `list` you should make sure to "disconnect" it from the database before looping over it, -as mentioned in the [Retrieving Mutable Objects](./Attributes#retrieving-mutable-objects) section +as mentioned in the [Retrieving Mutable Objects](./Attributes.md#retrieving-mutable-objects) section below. ### Storing single objects @@ -248,7 +248,7 @@ containing dicts, etc. Since you can use any combination of the above iterables, this is generally not much of a limitation. -Any entity listed in the [Single object](./Attributes#Storing-Single-Objects) section above can be +Any entity listed in the [Single object](./Attributes.md#storing-single-objects) section above can be stored in the iterable. > As mentioned in the previous section, database entities (aka typeclasses) are not possible to @@ -355,7 +355,7 @@ already disconnected from the database from the onset. 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 [Locks](./Locks). +First you need to set a *lock string* on your Attribute. Lock strings are specified [Locks](./Locks.md). The relevant lock types are - `attrread` - limits who may read the value of the Attribute diff --git a/docs/source/Components/Batch-Code-Processor.md b/docs/source/Components/Batch-Code-Processor.md index 054d44e833..403900887c 100644 --- a/docs/source/Components/Batch-Code-Processor.md +++ b/docs/source/Components/Batch-Code-Processor.md @@ -1,7 +1,7 @@ # Batch Code Processor -For an introduction and motivation to using batch processors, see [here](./Batch-Processors). This +For an introduction and motivation to using batch processors, see [here](./Batch-Processors.md). This page describes the Batch-*code* processor. The Batch-*command* one is covered [here](Batch-Command- Processor). @@ -191,7 +191,7 @@ connect that room with a room you built in the current block. There are two ways - Perform a database search for the name of the room you created (since you cannot know in advance which dbref it got assigned). The problem is that a name may not be unique (you may have a lot of "A -dark forest" rooms). There is an easy way to handle this though - use [Tags](./Tags) or *Aliases*. You +dark forest" rooms). There is an easy way to handle this though - use [Tags](./Tags.md) or *Aliases*. You can assign any number of tags and/or aliases to any object. Make sure that one of those tags or aliases is unique to the room (like "room56") and you will henceforth be able to always uniquely search and find it later. diff --git a/docs/source/Components/Batch-Command-Processor.md b/docs/source/Components/Batch-Command-Processor.md index 5175db986a..db4acb8968 100644 --- a/docs/source/Components/Batch-Command-Processor.md +++ b/docs/source/Components/Batch-Command-Processor.md @@ -1,7 +1,7 @@ # Batch Command Processor -For an introduction and motivation to using batch processors, see [here](./Batch-Processors). This +For an introduction and motivation to using batch processors, see [here](./Batch-Processors.md). This page describes the Batch-*command* processor. The Batch-*code* one is covered [here](Batch-Code- Processor). @@ -152,7 +152,7 @@ when creating the file, so that you can 'walk' (or teleport) to the right places This also means there are several pitfalls when designing and adding certain types of objects. Here are some examples: -- *Rooms that change your [Command Set](./Command-Sets)*: Imagine that you build a 'dark' room, which +- *Rooms that change your [Command Set](./Command-Sets.md)*: 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 ... @@ -172,7 +172,7 @@ The fact that you build as 'yourself' can also be considered an advantage howeve 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](Batch-Code-Processor)) +Processor](./Batch-Code-Processor.md)) - [GNU Emacs](https://www.gnu.org/software/emacs/) users might find it interesting to use emacs' *evennia mode*. This is an Emacs major mode found in `evennia/utils/evennia-mode.el`. It offers diff --git a/docs/source/Components/Batch-Processors.md b/docs/source/Components/Batch-Processors.md index b7b3ee02e1..9b6cfc0403 100644 --- a/docs/source/Components/Batch-Processors.md +++ b/docs/source/Components/Batch-Processors.md @@ -35,8 +35,8 @@ just list in-game commands in a text file. The code-processor on the other hand powerful but also more complex - it lets you use Evennia's API to code your world in full-fledged Python code. -- The [Batch Command Processor](./Batch-Command-Processor) -- The [Batch Code Processor](./Batch-Code-Processor) +- The [Batch Command Processor](./Batch-Command-Processor.md) +- The [Batch Code Processor](./Batch-Code-Processor.md) If you plan to use international characters in your batchfiles you are wise to read about *file encodings* below. @@ -73,7 +73,7 @@ need to add the editor's encoding to Evennia's `ENCODINGS` list. If you are unsu 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](../Concepts/Text-Encodings) and also in the +More help with encodings can be found in the entry [Text Encodings](../Concepts/Text-Encodings.md) and also in the Wikipedia article [here](https://en.wikipedia.org/wiki/Text_encodings). **A footnote for the batch-code processor**: Just because *Evennia* can parse your file and your diff --git a/docs/source/Components/Bootstrap-Components-and-Utilities.md b/docs/source/Components/Bootstrap-Components-and-Utilities.md index 2d4c124a32..4cb46b0e35 100644 --- a/docs/source/Components/Bootstrap-Components-and-Utilities.md +++ b/docs/source/Components/Bootstrap-Components-and-Utilities.md @@ -2,8 +2,8 @@ Bootstrap provides many utilities and components you can use when customizing Evennia's web presence. We'll go over a few examples here that you might find useful. -> Please take a look at either [the basic web tutorial](../Howto/Starting/Part5/Add-a-simple-new-web-page) or ->[the web character view tutorial](../Howto/Web-Character-View-Tutorial) +> Please take a look at either [the basic web tutorial](../Howto/Starting/Part5/Add-a-simple-new-web-page.md) or +>[the web character view tutorial](../Howto/Web-Character-View-Tutorial.md) > to get a feel for how to add pages to Evennia's website to test these examples. ## General Styling @@ -77,4 +77,4 @@ width of the page - Evennia's base site uses the former. ### Forms [Forms](https://getbootstrap.com/docs/4.0/components/forms/) are highly customizable with Bootstrap. For a more in-depth look at how to use forms and their styles in your own Evennia site, please read -over [the web character gen tutorial.](../Howto/Web-Character-Generation) \ No newline at end of file +over [the web character gen tutorial.](../Howto/Web-Character-Generation.md) \ No newline at end of file diff --git a/docs/source/Components/Channels.md b/docs/source/Components/Channels.md index f7463b7bcf..8cb3abb8d0 100644 --- a/docs/source/Components/Channels.md +++ b/docs/source/Components/Channels.md @@ -7,8 +7,8 @@ _Channels_ allows Evennia's to act as a fancy chat program. When a player is connected to a channel, sending a message to it will automatically distribute it to every other subscriber. -Channels can be used both for chats between [Accounts](./Accounts) and between -[Objects](./Objects) (usually Characters). Chats could be both OOC +Channels can be used both for chats between [Accounts](./Accounts.md) and between +[Objects](./Objects.md) (usually Characters). Chats could be both OOC (out-of-character) or IC (in-charcter) in nature. Some examples: - A support channel for contacting staff (OOC) @@ -20,7 +20,7 @@ Channels can be used both for chats between [Accounts](./Accounts) and between - Group telephathy (IC) - Walkie talkies (IC) -```versionchanged:: 1.0 +```{versionchanged} 1.0 Channel system changed to use a central 'channel' command and nicks instead of auto-generated channel-commands and -cmdset. ChannelHandler was removed. @@ -30,7 +30,8 @@ Channels can be used both for chats between [Accounts](./Accounts) and between ## Using channels in-game In the default command set, channels are all handled via the mighty -[channel command](api:evennia.commands.default.comms.CmdChannel), `channel` (or +[channel +command](evennia.commands.default.comms.CmdChannel), `channel` (or `chan`). By default, this command will assume all entities dealing with channels are `Accounts`. @@ -66,7 +67,7 @@ system automatically sets up an personal alias so you can do this instead: public Hello world -```warning:: +```{warning} This shortcut will not work if the channel-name has spaces in it. So channels with long names should make sure to provide a one-word alias as @@ -91,7 +92,7 @@ But you can also use your alias with the `channel` command: channel foo Hello world! -> What happens when aliasing is that a [nick](./Nicks) is created that maps your +> What happens when aliasing is that a [nick](./Nicks.md) is created that maps your > alias + argument onto calling the `channel` command. So when you enter `foo hello`, > what the server sees is actually `channel foo = hello`. The system is also > clever enough to know that whenever you search for channels, your channel-nicks @@ -140,10 +141,10 @@ Banning adds the user to the channels blacklist. This means they will not be able to _rejoin_ if you boot them. You will need to run `channel/boot` to actually kick them out. -See the [Channel command](api:evennia.commands.default.comms.CmdChannel) api +See the [Channel command](evennia.commands.default.comms.CmdChannel) api docs (and in-game help) for more details. -Admin-level users can also modify channel's [locks](./Locks): +Admin-level users can also modify channel's [locks](./Locks.md): channel/lock buildchannel = listen:all();send:perm(Builders) @@ -158,7 +159,7 @@ Channels use three lock-types by default: #### Restricting channel administration -By default everyone can use the channel command ([evennia.commands.default.comms.CmdChannel](api:evennia.commands.default.comms.CmdChannel)) +By default everyone can use the channel command ([evennia.commands.default.comms.CmdChannel](evennia.commands.default.comms.CmdChannel)) to create channels and will then control the channels they created (to boot/ban people etc). If you as a developer does not want regular players to do this (perhaps you want only staff to be able to spawn new channels), you can @@ -170,7 +171,7 @@ The default `help` command has the following `locks` property: locks = "cmd:not perm(channel_banned); admin:all(); manage:all(); changelocks: perm(Admin)" ``` -This is a regular [lockstring](./Locks). +This is a regular [lockstring](./Locks.md). - `cmd: pperm(channel_banned)` - The `cmd` locktype is the standard one used for all Commands. an accessing object failing this will not even know that the command exists. The `pperm()` lockfunc @@ -204,14 +205,14 @@ access-denied error when trying to use use these switches. ## Allowing Characters to use Channels -The default `channel` command ([evennia.commands.default.comms.CmdChannel](api:evennia.commands.default.comms.CmdChannel)) -sits in the `Account` [command set](./Command-Sets). It is set up such that it will +The default `channel` command ([evennia.commands.default.comms.CmdChannel](evennia.commands.default.comms.CmdChannel)) +sits in the `Account` [command set](./Command-Sets.md). It is set up such that it will always operate on `Accounts`, even if you were to add it to the `CharacterCmdSet`. It's a one-line change to make this command accept non-account callers. But for convenience we provide a version for Characters/Objects. Just import -[evennia.commands.default.comms.CmdObjectChannel](api:evennia.commands.default.comms.CmdObjectChannel) +[evennia.commands.default.comms.CmdObjectChannel](evennia.commands.default.comms.CmdObjectChannel) and inherit from that instead. ## Customizing channel output and behavior @@ -248,13 +249,13 @@ For most common changes, the default channel, the recipient hooks and possibly overriding the `channel` command will get you very far. But you can also tweak channels themselves. -Channels are [Typeclassed](./Typeclasses) entities. This means they are -persistent in the database, can have [attributes](./Attributes) and [Tags](./Tags) +Channels are [Typeclassed](./Typeclasses.md) entities. This means they are +persistent in the database, can have [attributes](./Attributes.md) and [Tags](./Tags.md) and can be easily extended. To change which channel typeclass Evennia uses for default commands, change `settings.BASE_CHANNEL_TYPECLASS`. The base command class is -[`evennia.comms.comms.DefaultChannel`](api:evennia.comms.comms.DefaultChannel). +[`evennia.comms.comms.DefaultChannel`](evennia.comms.comms.DefaultChannel). There is an empty child class in `mygame/typeclasses/channels.py`, same as for other typelass-bases. @@ -299,11 +300,11 @@ details. ## Channel logging -```versionchanged:: 0.7 +```{versionchanged} 0.7 Channels changed from using Msg to TmpMsg and optional log files. ``` -```versionchanged:: 1.0 +```{versionchanged} 1.0 Channels stopped supporting Msg and TmpMsg, using only log files. ``` @@ -325,7 +326,7 @@ channel's `at_post_channel_msg` method. Channels have all the standard properties of a Typeclassed entity (`key`, `aliases`, `attributes`, `tags`, `locks` etc). This is not an exhaustive list; -see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details. +see the [Channel api docs](evennia.comms.comms.DefaultChannel) for details. - `send_to_online_only` - this class boolean defaults to `True` and is a sensible optimization since people offline people will not see the message anyway. @@ -334,8 +335,8 @@ see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details. `mygame/server/logs/`). You should usually not change this. - `channel_prefix_string` - this property is a string to easily change how the channel is prefixed. It takes the `channelname` format key. Default is `"[{channelname}] "` - and produces output like `[public] ...``. -- `subscriptions` - this is the [SubscriptionHandler](api:evennia.comms.comms#SubscriptionHandler), which + and produces output like `[public] ...`. +- `subscriptions` - this is the [SubscriptionHandler](evennia.comms.models.SubscriptionHandler), which has methods `has`, `add`, `remove`, `all`, `clear` and also `online` (to get only actually online channel-members). - `wholist`, `mutelist`, `banlist` are properties that return a list of subscribers, @@ -345,7 +346,7 @@ see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details. This pattern accepts an `{alias}` formatting marker. Don't mess with this unless you really want to change how channels work. - `channel_msg_nick_replacement` - this is a string on the [nick replacement -- form](Nicks). It accepts the `{channelname}` formatting tag. This is strongly tied to the +- form](./Nicks.md). It accepts the `{channelname}` formatting tag. This is strongly tied to the `channel` command and is by default `channel {channelname} = $1`. Notable `Channel` hooks: diff --git a/docs/source/Components/Coding-Utils.md b/docs/source/Components/Coding-Utils.md index a85079dd2d..d1a435ff20 100644 --- a/docs/source/Components/Coding-Utils.md +++ b/docs/source/Components/Coding-Utils.md @@ -29,13 +29,13 @@ If you need to search for objects in a code module you can use the functions in obj = search_object(objname) ``` -- [evennia.search_account](../wiki/evennia.accounts.manager#accountdbmanagersearch_account) -- [evennia.search_object](../wiki/evennia.objects.manager#objectdbmanagersearch_object) -- [evennia.search_object_by_tag](../wiki/evennia.utils.search#search_object_by_tag) -- [evennia.search_script](../wiki/evennia.scripts.manager#scriptdbmanagersearch_script) -- [evennia.search_channel](../wiki/evennia.comms.managers#channeldbmanagersearch_channel) -- [evennia.search_message](../wiki/evennia.comms.managers#msgmanagersearch_message) -- [evennia.search_help](../wiki/evennia.help.manager#helpentrymanagersearch_help) +- [`evennia.search_account`](evennia.accounts.manager.AccountDBManager.search_account) +- [`evennia.search_object`](evennia.objects.manager.ObjectDBManager.search_object) +- [`evennia.search(object)_by_tag`](evennia.utils.search.search_tag) +- [`evennia.search_script`](evennia.scripts.manager.ScriptDBManager.search_script) +- [`evennia.search_channel`](evennia.comms.managers.ChannelDBManager.search_channel) +- [`evennia.search_message`](evennia.comms.managers.MsgManager.search_message) +- [`evennia.search_help`](evennia.help.manager.HelpEntryManager.search_help) Note that these latter methods will always return a `list` of results, even if the list has one or zero entries. @@ -50,12 +50,12 @@ entities directly in code (for example when defining new create commands). myobj = evennia.create_objects("game.gamesrc.objects.myobj.MyObj", key="MyObj") ``` -- [evennia.create_account](../wiki/evennia.utils.create#create_account) -- [evennia.create_object](../wiki/evennia.utils.create#create_object) -- [evennia.create_script](../wiki/evennia.utils.create#create_script) -- [evennia.create_channel](../wiki/evennia.utils.create#create_channel) -- [evennia.create_help_entry](../wiki/evennia.utils.create#create_help_entry) -- [evennia.create_message](../wiki/evennia.utils.create#create_message) +- [`evennia.create_account`](evennia.utils.create.create_account) +- [`evennia.create_object`](evennia.utils.create.create_object) +- [`evennia.create_script`](evennia.utils.create.create_script) +- [`evennia.create_channel`](evennia.utils.create.create_channel) +- [`evennia.create_help_entry`](evennia.utils.create.create_help_entry) +- [`evennia.create_message`](evennia.utils.create.create_message) Each of these create-functions have a host of arguments to further customize the created entity. See `evennia/utils/create.py` for more information. @@ -137,7 +137,7 @@ setting `TIME_GAME_EPOCH` sets the starting game epoch (in seconds). The functio you desire for your game. You can use the `@time` command to view the server time info. You can also *schedule* things to happen at specific in-game times using the -[gametime.schedule](github:evennia.utils.gametime#schedule) function: +[gametime.schedule](evennia.utils.gametime.schedule) function: ```python import evennia @@ -181,13 +181,13 @@ number of seconds. This is a very light wrapper over a Twisted non-persistently, which means that if the server is `@reload`ed before the delay is over, the callback will never run (the server forgets it). If setting `persistent` to True, the delay will be stored in the database and survive a `@reload` - but for this to work it is susceptible to the same -limitations incurred when saving to an [Attribute](./Attributes). +limitations incurred when saving to an [Attribute](./Attributes.md). The `deferred` return object can usually be ignored, but calling its `.cancel()` method will abort the delay prematurely. `utils.delay` is the lightest form of delayed call in Evennia. For other way to create time-bound -tasks, see the [TickerHandler](./TickerHandler) and [Scripts](./Scripts). +tasks, see the [TickerHandler](./TickerHandler.md) and [Scripts](./Scripts.md). > Note that many delayed effects can be achieved without any need for an active timer. For example if you have a trait that should recover a point every 5 seconds you might just need its value when @@ -203,7 +203,7 @@ classes, instances or python-paths-to-classes. Note that Python code should usually work with [duck typing](https://en.wikipedia.org/wiki/Duck_typing). But in Evennia's case it can sometimes be useful -to check if an object inherits from a given [Typeclass](./Typeclasses) as a way of identification. Say +to check if an object inherits from a given [Typeclass](./Typeclasses.md) as a way of identification. Say for example that we have a typeclass *Animal*. This has a subclass *Felines* which in turn has a subclass *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: @@ -274,17 +274,17 @@ need to send byte-data over the wire, `to_str` is the only one you'll need. The difference from Python's in-built `str()` and `bytes()` 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 -[here](../Concepts/Text-Encodings) for more info. +[here](../Concepts/Text-Encodings.md) for more info. ### Ansi Coloring Tools -- [evennia.ansi](api:evennia.utils.ansi) +- [evennia.utils.ansi](evennia.utils.ansi) ## Display utilities ### Making ascii tables -The [EvTable](github:evennia.utils.evtable#evtable) class (`evennia/utils/evtable.py`) can be used +The [EvTable](evennia.utils.evtable.EvTable) class (`evennia/utils/evtable.py`) can be used to create correctly formatted text tables. There is also -[EvForm](github:evennia.utils.evform#evform) (`evennia/utils/evform.py`). This reads a fixed-format +[EvForm](evennia.utils.evform.EvForm) (`evennia/utils/evform.py`). This reads a fixed-format text template from a file in order to create any level of sophisticated ascii layout. Both evtable and evform have lots of options and inputs so see the header of each module for help. @@ -294,4 +294,4 @@ ANSI colour. PrettyTable can be found in `evennia/utils/prettytable/`. See its instructions. ### Menus -- [evennia.EvMenu](github:evennia.utils.evmenu#evmenu) \ No newline at end of file +- [evennia.EvMenu](evennia.utils.evmenu.EvMenu) diff --git a/docs/source/Components/Command-Sets.md b/docs/source/Components/Command-Sets.md index 5b52001185..eef9cf02fd 100644 --- a/docs/source/Components/Command-Sets.md +++ b/docs/source/Components/Command-Sets.md @@ -1,7 +1,7 @@ # Command Sets -Command Sets are intimately linked with [Commands](./Commands) and you should be familiar with +Command Sets are intimately linked with [Commands](./Commands.md) and you should be familiar with Commands before reading this page. The two pages were split for ease of reading. A *Command Set* (often referred to as a CmdSet or cmdset) is the basic unit for storing one or more @@ -11,7 +11,7 @@ classes in a command set is the way to make commands available to use in your ga When storing a CmdSet on an object, you will make the commands in that command set available to the object. An example is the default command set stored on new Characters. This command set contains all the useful commands, from `look` and `inventory` to `@dig` and `@reload` -([permissions](./Locks#Permissions) then limit which players may use them, but that's a separate +([permissions](./Permissions.md) then limit which players may use them, but that's a separate topic). When an account enters a command, cmdsets from the Account, Character, its location, and elsewhere @@ -26,7 +26,7 @@ on. The tutorial world included with Evennia showcases a dark room that replaces commands with its own versions because the Character cannot see. If you want a quick start into defining your first commands and using them with command sets, you -can head over to the [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) which steps through things +can head over to the [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) which steps through things without the explanations. ## Defining Command Sets @@ -112,11 +112,11 @@ back even if all other cmdsets fail or are removed. It is always persistent and by `cmdset.delete()`. To remove a default cmdset you must explicitly call `cmdset.remove_default()`. Command sets are often added to an object in its `at_object_creation` method. For more examples of -adding commands, read the [Step by step tutorial](../Howto/Starting/Part1/Adding-Commands). Generally you can +adding commands, read the [Step by step tutorial](../Howto/Starting/Part1/Adding-Commands.md). Generally you can customize which command sets are added to your objects by using `self.cmdset.add()` or `self.cmdset.add_default()`. -> Important: Commands are identified uniquely by key *or* alias (see [Commands](./Commands)). If any +> Important: Commands are identified uniquely by key *or* alias (see [Commands](./Commands.md)). If any overlap exists, two commands are considered identical. Adding a Command to a command set that already has an identical command will *replace* the previous command. This is very important. You must take this behavior into account when attempting to overload any default Evennia commands with @@ -127,7 +127,7 @@ new one that has a matching alias. There are several extra flags that you 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 the [Adding and Merging Command Sets](./Command-Sets#adding-and-merging- +you might want to read the [Adding and Merging Command Sets](./Command-Sets.md#adding-and-merging- command-sets) 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 @@ -138,7 +138,7 @@ dictionary below. - `priority` (int) - This defines the merge order of the merge stack - cmdsets will merge in rising order of priority with the highest priority set merging last. During a merger, the commands from the set with the higher priority will have precedence (just what happens depends on the [merge -type](Command-Sets#adding-and-merging-command-sets)). If priority is identical, the order in the +type](./Command-Sets.md#adding-and-merging-command-sets)). If priority is identical, the order in the merge stack determines preference. The priority value must be greater or equal to `-100`. Most in- game sets should usually have priorities between `0` and `100`. Evennia default sets have priorities as follows (these can be changed if you want a different distribution): @@ -154,7 +154,7 @@ arguments, there is no collision between exits named the same as a channel even 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. Please note that this is more complex than it may seem due to the [merge -order](Command-Sets#adding-and-merging-command-sets) of command sets. Please review that section +order](./Command-Sets.md#adding-and-merging-command-sets) of command sets. Please review that section before using `key_mergetype`. - `duplicates` (bool/None default `None`) - this determines what happens when merging same-priority cmdsets containing same-key commands together. The`dupicate` option will *only* apply when merging @@ -195,15 +195,15 @@ priority determines what is used. ## Command Sets Searched -When a user issues a command, it is matched against the [merged](./Command-Sets#adding-and-merging- +When a user issues a command, it is matched against the [merged](./Command-Sets.md#adding-and-merging- command-sets) command sets available to the player at the moment. Which those are may change at any time (such as when the player walks into the room with the `Window` object described earlier). The currently valid command sets are collected from the following sources: -- The cmdsets stored on the currently active [Session](./Sessions). Default is the empty +- The cmdsets stored on the currently active [Session](./Sessions.md). Default is the empty `SessionCmdSet` with merge priority `-20`. -- The cmdsets defined on the [Account](./Accounts). Default is the AccountCmdSet with merge priority +- The cmdsets defined on the [Account](./Accounts.md). Default is the AccountCmdSet with merge priority `-10`. - All cmdsets on the Character/Object (assuming the Account is currently puppeting such a Character/Object). Merge priority `0`. @@ -215,14 +215,14 @@ included if `no_objs` option is active in the merge stack. `no_objs` option is active in the merge stack. - The cmdsets of Exits in the location. Merge priority `+101`. Will not be included if `no_exits` *or* `no_objs` option is active in the merge stack. -- The [channel](./Communications) cmdset containing commands for posting to all channels the account +- The [channel](./Communications.md) cmdset containing commands for posting to all channels the account or character is currently connected to. Merge priority `+101`. Will not be included if `no_channels` option is active in the merge stack. Note that an object does not *have* to share its commands with its surroundings. A Character's cmdsets should not be shared for example, or all other Characters would get multi-match errors just by being in the same room. The ability of an object to share its cmdsets is managed by its `call` -[lock](./Locks). For example, [Character objects](./Objects) defaults to `call:false()` so that any +[lock](./Locks.md). For example, [Character objects](./Objects.md) defaults to `call:false()` so that any cmdsets on them can only be accessed by themselves, not by other objects around them. Another example might be to lock an object with `call:inside()` to only make their commands available to objects inside them, or `cmd:holds()` to make their commands available only if they are held. diff --git a/docs/source/Components/Command-System.md b/docs/source/Components/Command-System.md index 4a51de737d..bb79f0a16e 100644 --- a/docs/source/Components/Command-System.md +++ b/docs/source/Components/Command-System.md @@ -1,9 +1,9 @@ # Command System -- [Commands](./Commands) -- [Command Sets](./Command-Sets) -- [Command Auto-help](./Help-System#command-auto-help-system) +- [Commands](./Commands.md) +- [Command Sets](./Command-Sets.md) +- [Command Auto-help](./Help-System.md#command-auto-help-system) See also: -- [Default Command Help](api:evennia.commands.default#modules) -- [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) \ No newline at end of file +- [Default Commands](./Default-Commands.md) +- [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) diff --git a/docs/source/Components/Commands.md b/docs/source/Components/Commands.md index a369371334..983149ba1e 100644 --- a/docs/source/Components/Commands.md +++ b/docs/source/Components/Commands.md @@ -1,22 +1,22 @@ # Commands -Commands are intimately linked to [Command Sets](./Command-Sets) and you need to read that page too to +Commands are intimately linked to [Command Sets](./Command-Sets.md) and you need to read that page too to be familiar with how the command system works. The two pages were split for easy reading. 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](api:evennia.commands.default#modules) coming with Evennia are 'MUX-like' in that they use @ +The [default commands](./Default-Commands.md) 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 `evennia/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](./Command-Sets) (command sets were split into a separate wiki page for ease of reading). +There are two components to having a command running - the *Command* class and the +[Command Set](./Command-Sets.md) (command sets were split into a separate wiki page for ease of reading). 1. 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. @@ -28,8 +28,8 @@ object in various ways. Consider a "Tree" object with a cmdset defining the comm *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. To fully use them you must also read the -page detailing [Command Sets](./Command-Sets). There is also a step-by-step -[Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) that will get you started quickly without the +page detailing [Command Sets](./Command-Sets.md). There is also a step-by-step +[Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) that will get you started quickly without the extra explanations. ## Defining Commands @@ -81,15 +81,15 @@ In Evennia there are three types of objects that may call the command. It is im of this since this will also assign appropriate `caller`, `session`, `sessid` and `account` properties on the command body at runtime. Most often the calling type is `Session`. -* A [Session](./Sessions). This is by far the most common case when a user is entering a command in +* A [Session](./Sessions.md). This is by far the most common case when a user is entering a command in their client. - * `caller` - this is set to the puppeted [Object](./Objects) if such an object exists. If no + * `caller` - this is set to the puppeted [Object](./Objects.md) if such an object exists. If no puppet is found, `caller` is set equal to `account`. Only if an Account is not found either (such as before being logged in) will this be set to the Session object itself. - * `session` - a reference to the [Session](./Sessions) object itself. + * `session` - a reference to the [Session](./Sessions.md) object itself. * `sessid` - `sessid.id`, a unique integer identifier of the session. - * `account` - the [Account](./Accounts) object connected to this Session. None if not logged in. -* An [Account](./Accounts). This only happens if `account.execute_cmd()` was used. No Session + * `account` - the [Account](./Accounts.md) object connected to this Session. None if not logged in. +* An [Account](./Accounts.md). This only happens if `account.execute_cmd()` was used. No Session information can be obtained in this case. * `caller` - this is set to the puppeted Object if such an object can be determined (without Session info this can only be determined in `MULTISESSION_MODE=0` or `1`). If no puppet is found, @@ -97,7 +97,7 @@ this is equal to `account`. * `session` - `None*` * `sessid` - `None*` * `account` - Set to the Account object. -* An [Object](./Objects). This only happens if `object.execute_cmd()` was used (for example by an +* An [Object](./Objects.md). This only happens if `object.execute_cmd()` was used (for example by an NPC). * `caller` - This is set to the calling Object in question. * `session` - `None*` @@ -120,10 +120,10 @@ it the following properties: - `caller` - The character BigGuy, in this example. This is a reference to the object executing the command. The value of this depends on what type of object is calling the command; see the previous section. -- `session` - the [Session](./Sessions) Bob uses to connect to the game and control BigGuy (see also +- `session` - the [Session](./Sessions.md) Bob uses to connect to the game and control BigGuy (see also previous section). - `sessid` - the unique id of `self.session`, for quick lookup. -- `account` - the [Account](./Accounts) Bob (see previous section). +- `account` - the [Account](./Accounts.md) Bob (see previous section). - `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*". Note the space kept - Evennia would correctly @@ -131,7 +131,7 @@ interpret `lookat sword` too. This is useful for things like `/switches` that sh In the `MuxCommand` class used for default commands, this space is stripped. Also see the `arg_regex` property if you want to enforce a space to make `lookat sword` give a command-not-found error. -- `obj` - the game [Object](./Objects) on which this command is defined. This need not be the caller, +- `obj` - the game [Object](./Objects.md) 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 an Account or any interactive object with commands defined on it, like in the example of the "check time" command defined on a "Clock" object. @@ -143,18 +143,18 @@ for example*). - `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. -#### Other useful utility methods: +#### Other useful utility methods: - `.get_help(caller, cmdset)` - Get the help entry for this command. By default the arguments are not used, but they could be used to implement alternate help-display systems. - `.client_width()` - Shortcut for getting the client's screen-width. Note that not all clients will truthfully report this value - that case the `settings.DEFAULT_SCREEN_WIDTH` will be returned. -- `.styled_table(*args, **kwargs)` - This returns an [EvTable](api:evennia.utils#module- +- `.styled_table(*args, **kwargs)` - This returns an [EvTable](module- evennia.utils.evtable) styled based on the session calling this command. The args/kwargs are the same as for EvTable, except styling defaults are set. -- `.styled_header`, `_footer`, `separator` - These will produce styled decorations for +- `.styled_header`, `_footer`, `separator` - These will produce styled decorations for display to the user. They are useful for creating listings and forms with colors adjustable per- user. @@ -169,7 +169,7 @@ key can consist of more than one word, like "press button" or "pull left lever". either matches. This is important for merging cmdsets described below. - `aliases` (optional list) - a list of alternate names for the command (`["glance", "see", "l"]`). Same name rules as for `key` applies. -- `locks` (string) - a [lock definition](./Locks), usually on the form `cmd:`. Locks is a +- `locks` (string) - a [lock definition](./Locks.md), 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 provide a lock string, this will be assigned for you). @@ -181,9 +181,9 @@ by the next command by retrieving `self.caller.ndb.last_cmd`. The next run comma or replace the storage. - `arg_regex` (optional raw string): Used to force the parser to limit itself and tell it when the command-name ends and arguments begin (such as requiring this to be a space or a /switch). This is -done with a regular expression. [See the arg_regex section](./Commands#on-arg_regex) for the details. -- `auto_help` (optional boolean). Defaults to `True`. This allows for turning off the -[auto-help system](./Help-System#command-auto-help-system) on a per-command basis. This could be useful if you +done with a regular expression. [See the arg_regex section](./Commands.md#on-arg_regex) for the details. +- `auto_help` (optional boolean). Defaults to `True`. This allows for turning off the +[auto-help system](./Help-System.md#command-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. - `is_exit` (bool) - this marks the command as being used for an in-game exit. This is, by default, @@ -219,7 +219,7 @@ from this method will be returned from the execution as a Twisted Deferred. Finally, you should always make an informative [doc string](https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring) (`__doc__`) at the top of -your class. This string is dynamically read by the [Help System](./Help-System) to create the help +your class. This string is dynamically read by the [Help System](./Help-System.md) 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: @@ -260,8 +260,8 @@ class CmdSmile(Command): string = f"{caller.key} smiles" else: target = caller.search(self.target) - if not target: - return + if not target: + return string = f"{caller.key} smiles at {target.key}" caller.location.msg_contents(string) @@ -277,7 +277,7 @@ 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. Before you can actually use the command in your game, you must now store it -within a *command set*. See the [Command Sets](./Command-Sets) page. +within a *command set*. See the [Command Sets](./Command-Sets.md) page. ### On arg_regex @@ -428,7 +428,7 @@ will show. > Note again that the `yield` keyword does not store state. If the game reloads while waiting for the user to answer, the user will have to start over. It is not a good idea to use `yield` for -important or complex choices, a persistent [EvMenu](./EvMenu) might be more appropriate in this case. +important or complex choices, a persistent [EvMenu](./EvMenu.md) might be more appropriate in this case. ## System commands @@ -458,7 +458,7 @@ display the "Huh?" error message. 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 [Channel](./Communications) name of a channel you are +- Channel (`syscmdkeys.CMD_CHANNEL`) - This is a [Channel](./Communications.md) 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 @@ -485,7 +485,7 @@ work. 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 ([Exits](./Commands#Exits) is an example of this). +code ([Exits](./Commands.md#exits) is an example of this). To create a command with a dynamic call signature, first define the command body normally in a class (set your `key`, `aliases` to default values), then use the following call (assuming the command @@ -509,10 +509,10 @@ make your command completely customized at run-time. *Note: This is an advanced topic.* -Exits are examples of the use of a [Dynamic Command](./Commands#Dynamic_Commands). +Exits are examples of the use of a [Dynamic Command](./Commands.md#dynamic-commands). -The functionality of [Exit](./Objects) objects in Evennia is not hard-coded in the engine. Instead -Exits are normal [typeclassed](./Typeclasses) objects that auto-create a [CmdSet](./Commands#CmdSets) on +The functionality of [Exit](./Objects.md) objects in Evennia is not hard-coded in the engine. Instead +Exits are normal [typeclassed](./Typeclasses.md) objects that auto-create a [CmdSet](./Command-Sets.md) 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 @@ -610,9 +610,9 @@ cmdset, ignore. - CmdSets defined on the current account, if caller is a puppeted object. - CmdSets defined on the Session itself. - The active CmdSets of eventual objects in the same location (if any). This includes commands -on [Exits](./Objects#Exits). +on [Exits](./Objects.md#exits). - Sets of dynamically created *System commands* representing available -[Communications](./Communications#Channels). +[Communications](./Channels.md) 7. 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. 8. All the grouped CmdSets are *merged* in reverse priority into one combined CmdSet according to diff --git a/docs/source/Components/Communications.md b/docs/source/Components/Communications.md index 21570fa740..b707ca05ba 100644 --- a/docs/source/Components/Communications.md +++ b/docs/source/Components/Communications.md @@ -2,7 +2,7 @@ TODO: Remove this page? -- [Channels](./Channels) - are used for implementing in-game chat rooms. -- [Msg](./Msg)-objects are used for storing messages in the database (email-like) +- [Channels](./Channels.md) - are used for implementing in-game chat rooms. +- [Msg](./Msg.md)-objects are used for storing messages in the database (email-like) and is a building block for implementing other game systems. It's used by the `page` command by default. diff --git a/docs/source/Components/Components-Overview.md b/docs/source/Components/Components-Overview.md index d737b00040..439eacf650 100644 --- a/docs/source/Components/Components-Overview.md +++ b/docs/source/Components/Components-Overview.md @@ -1,54 +1,54 @@ # Core Components These are the 'building blocks' out of which Evennia is built. This documentation is complementary to, and often goes deeper -than, the doc-strings of each component in the [API](../Evennia-API). +than, the doc-strings of each component in the [API](../Evennia-API.md). -## Database entites +## Database entites -- [Typeclasses](./Typeclasses) - - [Sessions](./Sessions) - - [Acccounts](./Accounts) - - [Guests](../Concepts/Guest-Logins) - - [Objects](./Objects) - - [Scripts](./Scripts) - - [Channels and Messages](./Communications) -- [Attributes](./Attributes) -- [Nicks](./Nicks) -- [Tags](./Tags) -- [Spawner and prototypes](./Prototypes) -- [Help entries](./Help-System) +- [Typeclasses](./Typeclasses.md) + - [Sessions](./Sessions.md) + - [Acccounts](./Accounts.md) + - [Guests](../Concepts/Guest-Logins.md) + - [Objects](./Objects.md) + - [Scripts](./Scripts.md) + - [Channels and Messages](./Communications.md) +- [Attributes](./Attributes.md) +- [Nicks](./Nicks.md) +- [Tags](./Tags.md) +- [Spawner and prototypes](./Prototypes.md) +- [Help entries](./Help-System.md) -## Commands +## Commands -- [Command system](./Command-System) - - [Commands](./Commands) - - [Command-Sets](./Command-Sets) - - [The Connection Screen](./Connection-Screen) - - [Available default Commands](api:evennia.commands.default#modules) -- [Batch-Processors](./Batch-Processors) - - [Batch-Code-Processor](./Batch-Code-Processor) - - [Batch-Command-Processor](./Batch-Command-Processor) +- [Available Default Commands](./Default-Commands.md) +- [Command system](./Command-System.md) + - [Commands](./Commands.md) + - [Command-Sets](./Command-Sets.md) + - [The Connection Screen](./Connection-Screen.md) +- [Batch-Processors](./Batch-Processors.md) + - [Batch-Code-Processor](./Batch-Code-Processor.md) + - [Batch-Command-Processor](./Batch-Command-Processor.md) ## Utils and tools -- [Misc Utils](./Coding-Utils) -- [EvEditor](./EvEditor) -- [EvMenu](./EvMenu) -- [EvMore](./EvMore) -- [MonitorHandler](./MonitorHandler) -- [TickerHandler](./TickerHandler) -- [Lock system](./Locks) -- [FuncParser](./FuncParser) +- [Misc Utils](./Coding-Utils.md) +- [EvEditor](./EvEditor.md) +- [EvMenu](./EvMenu.md) +- [EvMore](./EvMore.md) +- [MonitorHandler](./MonitorHandler.md) +- [TickerHandler](./TickerHandler.md) +- [Lock system](./Locks.md) +- [FuncParser](./FuncParser.md) ## Server and network -- [Portal](./Portal-And-Server) - - [Inputfuncs](./Inputfuncs) - - [Outputfuncs](./Outputfuncs) - - [Protocols](../Concepts/Custom-Protocols) -- [Server](./Server) - - [Server conf object](./Server-Conf) -- [Webserver](./Webserver) - - [Webclient](./Webclient) - - [Bootstrap](./Bootstrap-Components-and-Utilities) -- [Signals](./Signals) +- [Portal](./Portal-And-Server.md) + - [Inputfuncs](./Inputfuncs.md) + - [Outputfuncs](./Outputfuncs.md) + - [Protocols](../Concepts/Custom-Protocols.md) +- [Server](./Server.md) + - [Server conf object](../Setup/Server-Conf.md) +- [Webserver](./Webserver.md) + - [Webclient](./Webclient.md) + - [Bootstrap](./Bootstrap-Components-and-Utilities.md) +- [Signals](./Signals.md) diff --git a/docs/source/Components/Connection-Screen.md b/docs/source/Components/Connection-Screen.md index 2f982d92b3..b1056b6a0a 100644 --- a/docs/source/Components/Connection-Screen.md +++ b/docs/source/Components/Connection-Screen.md @@ -1,17 +1,17 @@ # Connection Screen -When you first connect to your game you are greeted by Evennia's default connection screen. +When you first connect to your game you are greeted by Evennia's default connection screen. + - ============================================================== 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. ============================================================== @@ -20,17 +20,17 @@ Effective, but not very exciting. You will most likely want to change this to be your game. This is simple: 1. Edit `mygame/server/conf/connection_screens.py`. -1. [Reload](../Setup/Start-Stop-Reload) Evennia. +1. [Reload](../Setup/Start-Stop-Reload.md) Evennia. Evennia will look into this module and locate all *globally defined strings* in it. These strings are used as the text in your connection screen and are shown to the user at startup. If more than one such string/screen is defined in the module, a *random* screen will be picked from among those available. -### Commands available at the Connection Screen +## Commands available at the Connection Screen -You can also customize the [Commands](./Commands) available to use while the connection screen is +You can also customize the [Commands](./Commands.md) available to use while the connection screen is shown (`connect`, `create` etc). These commands are a bit special since when the screen is running the account is not yet logged in. A command is made available at the login screen by adding them to -`UnloggedinCmdSet` in `mygame/commands/default_cmdset.py`. See [Commands](./Commands) and the -tutorial section on how to add new commands to a default command set. \ No newline at end of file +`UnloggedinCmdSet` in `mygame/commands/default_cmdset.py`. See [Commands](./Commands.md) and the +tutorial section on how to add new commands to a default command set. diff --git a/docs/source/Components/Default-Commands.md b/docs/source/Components/Default-Commands.md new file mode 100644 index 0000000000..2adfb5710c --- /dev/null +++ b/docs/source/Components/Default-Commands.md @@ -0,0 +1,106 @@ + + +# Default Commands + +The full set of default Evennia commands currently contains 97 commands in 9 source +files. Our policy for adding default commands is outlined [here](../Concepts/Using-MUX-as-a-Standard.md). The +[Commands](./Commands.md) documentation explains how Commands work as well as make new or customize +existing ones. Note that this page is auto-generated. Report problems to the [issue +tracker](github:issues). + +```{note} +Some game-states adds their own Commands which are not listed here. Examples include editing a text +with [EvEditor](./EvEditor.md), flipping pages in [EvMore](./EvMore.md) or using the +[Batch-Processor](./Batch-Processors.md)'s interactive mode. +``` + +- [**__unloggedin_look_command** [look, l]](evennia.commands.default.unloggedin.CmdUnconnectedLook) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**about** [version]](evennia.commands.default.system.CmdAbout) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**access** [groups, hierarchy]](evennia.commands.default.general.CmdAccess) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**accounts** [listaccounts, account]](evennia.commands.default.system.CmdAccounts) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**addcom** [chanalias, aliaschan]](evennia.commands.default.comms.CmdAddCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**alias** [setobjalias]](evennia.commands.default.building.CmdSetObjAlias) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**allcom**](evennia.commands.default.comms.CmdAllCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**batchcode** [batchcodes]](evennia.commands.default.batchprocess.CmdBatchCode) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**batchcommands** [batchcmd, batchcommand]](evennia.commands.default.batchprocess.CmdBatchCommands) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**cboot**](evennia.commands.default.comms.CmdCBoot) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**ccreate** [channelcreate]](evennia.commands.default.comms.CmdChannelCreate) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**cdesc**](evennia.commands.default.comms.CmdCdesc) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**cdestroy**](evennia.commands.default.comms.CmdCdestroy) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**channel** [chan, channels]](evennia.commands.default.comms.CmdChannel) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**charcreate**](evennia.commands.default.account.CmdCharCreate) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**chardelete**](evennia.commands.default.account.CmdCharDelete) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**clock**](evennia.commands.default.comms.CmdClock) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**cmdsets** [listcmsets]](evennia.commands.default.building.CmdListCmdSets) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**color**](evennia.commands.default.account.CmdColorTest) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**connect** [co, conn, con]](evennia.commands.default.unloggedin.CmdUnconnectedConnect) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**copy**](evennia.commands.default.building.CmdCopy) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**cpattr**](evennia.commands.default.building.CmdCpAttr) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**create**](evennia.commands.default.building.CmdCreate) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**create** [cre, cr]](evennia.commands.default.unloggedin.CmdUnconnectedCreate) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**cwho**](evennia.commands.default.comms.CmdCWho) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**delcom** [delaliaschan, delchanalias]](evennia.commands.default.comms.CmdDelCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**desc** [describe]](evennia.commands.default.building.CmdDesc) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**destroy** [delete, del]](evennia.commands.default.building.CmdDestroy) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**dig**](evennia.commands.default.building.CmdDig) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**drop**](evennia.commands.default.general.CmdDrop) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**encoding** [encode]](evennia.commands.default.unloggedin.CmdUnconnectedEncoding) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**examine** [exam, ex]](evennia.commands.default.building.CmdExamine) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Building_) +- [**find** [locate, search]](evennia.commands.default.building.CmdFind) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**get** [grab]](evennia.commands.default.general.CmdGet) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**give**](evennia.commands.default.general.CmdGive) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**grapevine2chan**](evennia.commands.default.comms.CmdGrapevine2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**help** [?]](evennia.commands.default.help.CmdHelp) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**help** [h, ?]](evennia.commands.default.unloggedin.CmdUnconnectedHelp) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**home**](evennia.commands.default.general.CmdHome) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**ic** [puppet]](evennia.commands.default.account.CmdIC) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**info**](evennia.commands.default.unloggedin.CmdUnconnectedInfo) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**inventory** [i, inv]](evennia.commands.default.general.CmdInventory) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**irc2chan**](evennia.commands.default.comms.CmdIRC2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**ircstatus**](evennia.commands.default.comms.CmdIRCStatus) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**link**](evennia.commands.default.building.CmdLink) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**lock** [locks]](evennia.commands.default.building.CmdLock) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**look** [l, ls]](evennia.commands.default.account.CmdOOCLook) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**look** [l, ls]](evennia.commands.default.general.CmdLook) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**mvattr**](evennia.commands.default.building.CmdMvAttr) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**name** [rename]](evennia.commands.default.building.CmdName) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**nick** [nickname, nicks]](evennia.commands.default.general.CmdNick) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**objects** [listobjs, listobjects, stats, db]](evennia.commands.default.building.CmdObjects) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**ooc** [unpuppet]](evennia.commands.default.account.CmdOOC) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**open**](evennia.commands.default.building.CmdOpen) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**option** [options]](evennia.commands.default.account.CmdOption) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**page** [tell]](evennia.commands.default.comms.CmdPage) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**password**](evennia.commands.default.account.CmdPassword) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**pose** [:, emote]](evennia.commands.default.general.CmdPose) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**py** [!]](evennia.commands.default.system.CmdPy) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_) +- [**quell** [unquell]](evennia.commands.default.account.CmdQuell) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**quit**](evennia.commands.default.account.CmdQuit) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**quit** [qu, q]](evennia.commands.default.unloggedin.CmdUnconnectedQuit) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**reload** [restart]](evennia.commands.default.system.CmdReload) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_) +- [**reset** [reboot]](evennia.commands.default.system.CmdReset) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_) +- [**rss2chan**](evennia.commands.default.comms.CmdRSS2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_) +- [**say** [", ']](evennia.commands.default.general.CmdSay) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**screenreader**](evennia.commands.default.unloggedin.CmdUnconnectedScreenreader) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_) +- [**scripts** [script]](evennia.commands.default.building.CmdScripts) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**server** [serverload, serverprocess]](evennia.commands.default.system.CmdServerLoad) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**service** [services]](evennia.commands.default.system.CmdService) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**sessions**](evennia.commands.default.account.CmdSessions) (cmdset: [SessionCmdSet](evennia.commands.default.cmdset_session.SessionCmdSet), help-category: _General_) +- [**set**](evennia.commands.default.building.CmdSetAttribute) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**setdesc**](evennia.commands.default.general.CmdSetDesc) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**sethelp**](evennia.commands.default.help.CmdSetHelp) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**sethome**](evennia.commands.default.building.CmdSetHome) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**shutdown**](evennia.commands.default.system.CmdShutdown) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_) +- [**spawn** [olc]](evennia.commands.default.building.CmdSpawn) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**style**](evennia.commands.default.account.CmdStyle) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**tag** [tags]](evennia.commands.default.building.CmdTag) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**tasks** [task, delays]](evennia.commands.default.system.CmdTasks) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**tel** [teleport]](evennia.commands.default.building.CmdTeleport) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**tickers**](evennia.commands.default.system.CmdTickers) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**time** [uptime]](evennia.commands.default.system.CmdTime) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_) +- [**tunnel** [tun]](evennia.commands.default.building.CmdTunnel) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**typeclass** [type, update, parent, typeclasses, swap]](evennia.commands.default.building.CmdTypeclass) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**unlink**](evennia.commands.default.building.CmdUnLink) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) +- [**whisper**](evennia.commands.default.general.CmdWhisper) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_) +- [**who** [doing]](evennia.commands.default.account.CmdWho) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_) +- [**wipe**](evennia.commands.default.building.CmdWipe) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_) + diff --git a/docs/source/Components/EvEditor.md b/docs/source/Components/EvEditor.md index d73a9ebd88..84edec6c5d 100644 --- a/docs/source/Components/EvEditor.md +++ b/docs/source/Components/EvEditor.md @@ -5,15 +5,15 @@ Evennia offers a powerful in-game line editor in `evennia.utils.eveditor.EvEdito mimicking the well-known VI line editor. It offers line-by-line editing, undo/redo, line deletes, search/replace, fill, dedent and more. -### Launching the editor +## Launching the editor -The editor is created as follows: +The editor is created as follows: ```python from evennia.utils.eveditor import EvEditor -EvEditor(caller, - loadfunc=None, savefunc=None, quitfunc=None, +EvEditor(caller, + loadfunc=None, savefunc=None, quitfunc=None, key="") ``` @@ -29,7 +29,7 @@ cleanup and exit messages to the user must be handled by this function. It has no other mechanical function. - `persistent` (default `False`): if set to `True`, the editor will survive a reboot. -### Example of usage +## Example of usage This is an example command for setting a specific Attribute using the editor. @@ -39,7 +39,7 @@ from evennia.utils import eveditor class CmdSetTestAttr(Command): """ - Set the "test" Attribute using + Set the "test" Attribute using the line editor. Usage: @@ -60,12 +60,12 @@ class CmdSetTestAttr(Command): caller.msg("Editor exited") key = f"{self.caller}/test" # launch the editor - eveditor.EvEditor(self.caller, - loadfunc=load, savefunc=save, quitfunc=quit, - key=key) + eveditor.EvEditor(self.caller, + loadfunc=load, savefunc=save, quitfunc=quit, + key=key) ``` -### Persistent editor +## Persistent editor If you set the `persistent` keyword to `True` when creating the editor, it will remain open even when reloading the game. In order to be persistent, an editor needs to have its callback functions @@ -90,7 +90,7 @@ def quit(caller): class CmdSetTestAttr(Command): """ - Set the "test" Attribute using + Set the "test" Attribute using the line editor. Usage: @@ -102,12 +102,12 @@ class CmdSetTestAttr(Command): "Set up the callbacks and launch the editor" key = f"{self.caller}/test" # launch the editor - eveditor.EvEditor(self.caller, - loadfunc=load, savefunc=save, quitfunc=quit, - key=key, persistent=True) + eveditor.EvEditor(self.caller, + loadfunc=load, savefunc=save, quitfunc=quit, + key=key, persistent=True) ``` -### Line editor usage +## Line editor usage The editor mimics the `VIM` editor as best as possible. The below is an excerpt of the return from the in-editor help command (`:h`). @@ -154,7 +154,7 @@ the in-editor help command (`:h`). - longer string, usually not needed to be enclosed in quotes. ``` -### The EvEditor to edit code +## The EvEditor to edit code The `EvEditor` is also used to edit some Python code in Evennia. The `@py` command supports an `/edit` switch that will open the EvEditor in code mode. This mode isn't significantly different @@ -178,4 +178,4 @@ to paste several lines of code that are already correctly indented, for instance To see the EvEditor in code mode, you can use the `@py/edit` command. Type in your code (on one or several lines). You can then use the `:w` option (save without quitting) and the code you have typed will be executed. The `:!` will do the same thing. Executing code while not closing the -editor can be useful if you want to test the code you have typed but add new lines after your test. \ No newline at end of file +editor can be useful if you want to test the code you have typed but add new lines after your test. diff --git a/docs/source/Components/EvMenu.md b/docs/source/Components/EvMenu.md index a0f6a9fbe7..626e25b3b7 100644 --- a/docs/source/Components/EvMenu.md +++ b/docs/source/Components/EvMenu.md @@ -33,7 +33,7 @@ said functions, like `{"nodename": , ...}` ## Launching the menu Initializing the menu is done using a call to the `evennia.utils.evmenu.EvMenu` class. This is the -most common way to do so - from inside a [Command](./Commands): +most common way to do so - from inside a [Command](./Commands.md): ```python # in, for example gamedir/commands/command.py @@ -70,7 +70,7 @@ EvMenu(caller, menu_data, ``` - `caller` (Object or Account): is a reference to the object using the menu. This object will get a - new [CmdSet](./Command-Sets) assigned to it, for handling the menu. + new [CmdSet](./Command-Sets.md) assigned to it, for handling the menu. - `menu_data` (str, module or dict): is a module or python path to a module where the global-level functions will each be considered to be a menu node. Their names in the module will be the names by which they are referred to in the module. Importantly, function names starting with an @@ -107,7 +107,7 @@ after - `startnode_input` (str or (str, dict) tuple): Pass an input text or a input text + kwargs to the start node as if it was entered on a fictional previous node. This can be very useful in order to start a menu differently depending on the Command's arguments in which it was initialized. - - `session` (Session): Useful when calling the menu from an [Account](./Accounts) in + - `session` (Session): Useful when calling the menu from an [Account](./Accounts.md) in `MULTISESSION_MODDE` higher than 2, to make sure only the right Session sees the menu output. - `debug` (bool): If set, the `menudebug` command will be made available in the menu. Use it to list the current state of the menu and use `menudebug ` to inspect a specific state @@ -428,16 +428,15 @@ See `evennia/utils/evmenu.py` for the details of their default implementations. ## Examples: -- **[Simple branching menu](./EvMenu#example-simple-branching-menu)** - choose from options -- **[Dynamic goto](./EvMenu#example-dynamic-goto)** - jumping to different nodes based on response -- **[Set caller properties](./EvMenu#example-set-caller-properties)** - a menu that changes things -- **[Getting arbitrary input](./EvMenu#example-get-arbitrary-input)** - entering text -- **[Storing data between nodes](./EvMenu#example-storing-data-between-nodes)** - keeping states and +- **[Simple branching menu](./EvMenu.md#example-simple-branching-menu)** - choose from options +- **[Dynamic goto](./EvMenu.md#example-dynamic-goto)** - jumping to different nodes based on response +- **[Set caller properties](./EvMenu.md#example-set-caller-properties)** - a menu that changes things +- **[Getting arbitrary input](./EvMenu.md#example-get-arbitrary-input)** - entering text +- **[Storing data between nodes](./EvMenu.md#example-storing-data-between-nodes)** - keeping states and information while in the menu -- **[Repeating the same node](./EvMenu#example-repeating-the-same-node)** - validating within the node +- **[Repeating the same node](./EvMenu.md#example-repeating-the-same-node)** - validating within the node before moving to the next -- **[Full Menu](./EvMenu#example-full-menu):** a complete example -- **[Yes/No prompt](./EvMenu#example-yesno-prompt)** - entering text with limited possible responses +- **[Yes/No prompt](#example-yesno-prompt)** - entering text with limited possible responses (this is *not* using EvMenu but the conceptually similar yet technically unrelated `get_input` helper function accessed as `evennia.utils.evmenu.get_input`). @@ -507,7 +506,7 @@ def enter_guild: This simple callable goto will analyse what happens depending on who the `caller` is. The `enter_guild` node will give you a choice of what to say to the guard. If you try to enter, you will -end up in different nodes depending on (in this example) if you have the right [Tag](./Tags) set on +end up in different nodes depending on (in this example) if you have the right [Tag](./Tags.md) set on yourself or not. Note that since we don't include any 'key's in the option dictionary, you will just get to pick between numbers. @@ -805,7 +804,7 @@ function - for example you can't use other Python keywords like `if` inside the Unless you are dealing with a relatively simple dynamic menu, defining menus with lambda's is probably more work than it's worth: You can create dynamic menus by instead making each node -function more clever. See the [NPC shop tutorial](../Howto/NPC-shop-Tutorial) for an example of this. +function more clever. See the [NPC shop tutorial](../Howto/NPC-shop-Tutorial.md) for an example of this. ## Ask for simple input @@ -906,7 +905,7 @@ return True from the callback to repeat the prompt until you pass whatever check > Note: You *cannot* link consecutive questions by putting a new `get_input` call inside the > callback If you want that you should use an EvMenu instead (see the [Repeating the same -> node](EvMenu#example-repeating-the-same-node) example above). Otherwise you can either peek at the +> node](./EvMenu.md#example-repeating-the-same-node) example above). Otherwise you can either peek at the > implementation of `get_input` and implement your own mechanism (it's just using cmdset nesting) or > you can look at [this extension suggested on the mailing > list](https://groups.google.com/forum/#!category-topic/evennia/evennia-questions/16pi0SfMO5U). @@ -993,9 +992,9 @@ auto-created by the `list_node` decorator. ## Assorted notes -The EvMenu is implemented using [Commands](./Commands). When you start a new EvMenu, the user of the -menu will be assigned a [CmdSet](./Command-Sets) with the commands they need to navigate the menu. +The EvMenu is implemented using [Commands](./Commands.md). When you start a new EvMenu, the user of the +menu will be assigned a [CmdSet](./Command-Sets.md) with the commands they need to navigate the menu. This means that if you were to, from inside the menu, assign a new command set to the caller, *you may override the Menu Cmdset and kill the menu*. If you want to assign cmdsets to the caller as part of the menu, you should store the cmdset on `caller.ndb._menutree` and wait to actually assign it -until the exit node. \ No newline at end of file +until the exit node. diff --git a/docs/source/Components/EvMore.md b/docs/source/Components/EvMore.md index 072950de4f..cbe6bccb21 100644 --- a/docs/source/Components/EvMore.md +++ b/docs/source/Components/EvMore.md @@ -7,7 +7,7 @@ page of text at a time. It is usually used via its access function, `evmore.msg` The name comes from the famous unix pager utility *more* which performs just this function. -### Using EvMore +## Using EvMore To use the pager, just pass the long text through it: @@ -16,7 +16,7 @@ from evennia.utils import evmore evmore.msg(receiver, long_text) ``` -Where receiver is an [Object](./Objects) or a [Account](./Accounts). If the text is longer than the +Where receiver is an [Object](./Objects.md) or a [Account](./Accounts.md). If the text is longer than the client's screen height (as determined by the NAWS handshake or by `settings.CLIENT_DEFAULT_HEIGHT`) the pager will show up, something like this: diff --git a/docs/source/Components/FuncParser.md b/docs/source/Components/FuncParser.md index e17e23bf15..38167f3ac0 100644 --- a/docs/source/Components/FuncParser.md +++ b/docs/source/Components/FuncParser.md @@ -1,16 +1,12 @@ # The Inline Function Parser -``` - -``` - -The [FuncParser](api:evennia.utils.funcparser#evennia.utils.funcparser.FuncParser) extracts and executes +The [FuncParser](evennia.utils.funcparser.FuncParser) extracts and executes 'inline functions' -embedded in a string on the form `$funcname(args, kwargs)`. Under the hood, this will -lead to a call to a Python function you control. The inline function call will be replaced by +embedded in a string on the form `$funcname(args, kwargs)`. Under the hood, this will +lead to a call to a Python function you control. The inline function call will be replaced by the return from the function. -```python +```python from evennia.utils.funcparser import FuncParser def _power_callable(*args, **kwargs): @@ -48,72 +44,72 @@ parser.parse("This is an escaped $$pow(4) and so is this \$pow(3)") The FuncParser can be applied to any string. Out of the box it's applied in a few situations: - _Outgoing messages_. All messages sent from the server is processed through FuncParser and every - callable is provided the [Session](./Sessions) of the object receiving the message. This potentially + callable is provided the [Session](./Sessions.md) of the object receiving the message. This potentially allows a message to be modified on the fly to look different for different recipients. -- _Prototype values_. A [Prototype](./Prototypes) dict's values are run through the parser such that every +- _Prototype values_. A [Prototype](./Prototypes.md) dict's values are run through the parser such that every callable gets a reference to the rest of the prototype. In the Prototype ORM, this would allow builders to safely call functions to set non-string values to prototype values, get random values, reference other fields of the prototype, and more. - _Actor-stance in messages to others_. In the - [Object.msg_contents](api:evennia.objects.objects#DefaultObject.msg_contents) method, + [Object.msg_contents](evennia.objects.objects.DefaultObject.msg_contents) method, the outgoing string is parsed for special `$You()` and `$conj()` callables to decide if a given recipient should see "You" or the character's name. -```important:: +```{important} The inline-function parser is not intended as a 'softcode' programming language. It does not - have things like loops and conditionals, for example. While you could in principle extend it to - do very advanced things and allow builders a lot of power, all-out coding is something + have things like loops and conditionals, for example. While you could in principle extend it to + do very advanced things and allow builders a lot of power, all-out coding is something Evennia expects you to do in a proper text editor, outside of the game, not from inside it. ``` -## Using the FuncParser - -You can apply inline function parsing to any string. The -[FuncParser](api:evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`. +## Using the FuncParser + +You can apply inline function parsing to any string. The +[FuncParser](evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`. ```python from evennia.utils import funcparser parser = FuncParser(callables, **default_kwargs) -parsed_string = parser.parser(input_string, raise_errors=False, - escape=False, strip=False, +parsed_string = parser.parser(input_string, raise_errors=False, + escape=False, strip=False, return_str=True, **reserved_kwargs) # callables can also be passed as paths to modules parser = FuncParser(["game.myfuncparser_callables", "game.more_funcparser_callables"]) ``` -Here, `callables` points to a collection of normal Python functions (see next section) for you to make +Here, `callables` points to a collection of normal Python functions (see next section) for you to make available to the parser as you parse strings with it. It can either be - A `dict` of `{"functionname": callable, ...}`. This allows you do pick and choose exactly which callables to include and how they should be named. Do you want a callable to be available under more than one name? Just add it multiple times to the dict, with a different key. -- A `module` or (more commonly) a `python-path` to a module. This module can define a dict +- A `module` or (more commonly) a `python-path` to a module. This module can define a dict `FUNCPARSER_CALLABLES = {"funcname": callable, ...}` - this will be imported and used like the `dict` above. - If no such variable is defined, _every_ top-level function in the module (whose name doesn't start with - an underscore `_`) will be considered a suitable callable. The name of the function will be the `$funcname` + If no such variable is defined, _every_ top-level function in the module (whose name doesn't start with + an underscore `_`) will be considered a suitable callable. The name of the function will be the `$funcname` by which it can be called. - A `list` of modules/paths. This allows you to pull in modules from many sources for your parsing. - + The other arguments to the parser: -- `raise_errors` - By default, any errors from a callable will be quietly ignored and the result - will be that the failing function call will show verbatim. If `raise_errors` is set, - then parsing will stop and whatever exception happened will be raised. It'd be up to you to handle +- `raise_errors` - By default, any errors from a callable will be quietly ignored and the result + will be that the failing function call will show verbatim. If `raise_errors` is set, + then parsing will stop and whatever exception happened will be raised. It'd be up to you to handle this properly. - `escape` - Returns a string where every `$func(...)` has been escaped as `\$func()`. - `strip` - Remove all `$func(...)` calls from string (as if each returned `''`). -- `return_str` - When `True` (default), `parser` always returns a string. If `False`, it may return - the return value of a single function call in the string. This is the same as using the `.parse_to_any` +- `return_str` - When `True` (default), `parser` always returns a string. If `False`, it may return + the return value of a single function call in the string. This is the same as using the `.parse_to_any` method. - The `**default/reserved_keywords` are optional and allow you to pass custom data into _every_ function call. This is great for including things like the current session or config options. Defaults can be replaced if the user gives the same-named kwarg in the string's function call. Reserved kwargs are always passed, - ignoring defaults or what the user passed. In addition, the `funcparser` and `raise_errors` + ignoring defaults or what the user passed. In addition, the `funcparser` and `raise_errors` reserved kwargs are always passed - the first is a back-reference to the `FuncParser` instance and the second is the `raise_errors` boolean passed into `FuncParser.parse`. - -Here's an example of using the default/reserved keywords: + +Here's an example of using the default/reserved keywords: ```python def _test(*args, **kwargs): @@ -123,15 +119,15 @@ def _test(*args, **kwargs): parser = funcparser.FuncParser({"test": _test}, mydefault=2) result = parser.parse("$test(foo, bar=4)", myreserved=[1, 2, 3]) ``` -Here the callable will be called as +Here the callable will be called as ```python -_test('foo', bar='4', mydefault=2, myreserved=[1, 2, 3], - funcparser=, raise_errors=False) +_test('foo', bar='4', mydefault=2, myreserved=[1, 2, 3], + funcparser=, raise_errors=False) ``` -The `mydefault=2` kwarg could be overwritten if we made the call as `$test(mydefault=...)` -but `myreserved=[1, 2, 3]` will _always_ be sent as-is and will override a call `$test(myreserved=...)`. +The `mydefault=2` kwarg could be overwritten if we made the call as `$test(mydefault=...)` +but `myreserved=[1, 2, 3]` will _always_ be sent as-is and will override a call `$test(myreserved=...)`. The `funcparser`/`raise_errors` kwargs are also always included as reserved kwargs. ## Defining custom callables @@ -144,44 +140,44 @@ def funcname(*args, **kwargs): return something ``` -> The `*args` and `**kwargs` must always be included. If you are unsure how `*args` and `**kwargs` work in Python, +> The `*args` and `**kwargs` must always be included. If you are unsure how `*args` and `**kwargs` work in Python, > [read about them here](https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3). -The input from the innermost `$funcname(...)` call in your callable will always be a `str`. Here's +The input from the innermost `$funcname(...)` call in your callable will always be a `str`. Here's an example of an `$toint` function; it converts numbers to integers. "There's a $toint(22.0)% chance of survival." What will enter the `$toint` callable (as `args[0]`) is the _string_ `"22.0"`. The function is responsible -for converting this to a number so that we can convert it to an integer. We must also properly handle invalid +for converting this to a number so that we can convert it to an integer. We must also properly handle invalid inputs (like non-numbers). If you want to mark an error, raise `evennia.utils.funcparser.ParsingError`. This stops the entire parsing -of the string and may or may not raise the exception depending on what you set `raise_errors` to when you +of the string and may or may not raise the exception depending on what you set `raise_errors` to when you created the parser. -However, if you _nest_ functions, the return of the innermost function may be something other than -a string. Let's introduce the `$eval` function, which evaluates simple expressions using +However, if you _nest_ functions, the return of the innermost function may be something other than +a string. Let's introduce the `$eval` function, which evaluates simple expressions using Python's `literal_eval` and/or `simple_eval`. - "There's a $toint($eval(10 * 2.2))% chance of survival." + "There's a $toint($eval(10 * 2.2))% chance of survival." -Since the `$eval` is the innermost call, it will get a string as input - the string `"10 * 2.2"`. -It evaluates this and returns the `float` `22.0`. This time the outermost `$toint` will be called with -this `float` instead of with a string. +Since the `$eval` is the innermost call, it will get a string as input - the string `"10 * 2.2"`. +It evaluates this and returns the `float` `22.0`. This time the outermost `$toint` will be called with +this `float` instead of with a string. -> It's important to safely validate your inputs since users may end up nesting your callables in any order. +> It's important to safely validate your inputs since users may end up nesting your callables in any order. > See the next section for useful tools to help with this. -In these examples, the result will be embedded in the larger string, so the result of the entire parsing -will be a string: +In these examples, the result will be embedded in the larger string, so the result of the entire parsing +will be a string: ```python parser.parse(above_string) "There's a 22% chance of survival." ``` -However, if you use the `parse_to_any` (or `parse(..., return_str=True)`) and _don't add any extra string around the outermost function call_, +However, if you use the `parse_to_any` (or `parse(..., return_str=True)`) and _don't add any extra string around the outermost function call_, you'll get the return type of the outermost callable back: ```python @@ -194,13 +190,13 @@ parser.parse_to_any("$toint($eval(10 * 2.2)") ### Safe convertion of inputs Since you don't know in which order users may use your callables, they should always check the types -of its inputs and convert to the type the callable needs. Note also that when converting from strings, -there are limits what inputs you can support. This is because FunctionParser strings are often used by -non-developer players/builders and some things (such as complex classes/callables etc) are just not +of its inputs and convert to the type the callable needs. Note also that when converting from strings, +there are limits what inputs you can support. This is because FunctionParser strings are often used by +non-developer players/builders and some things (such as complex classes/callables etc) are just not safe/possible to convert from string representation. -In `evennia.utils.utils` is a helper called -[safe_convert_to_types](api:evennia.utils.utils#evennia.utils.utils.safe_convert_to_types). This function +In `evennia.utils.utils` is a helper called +[safe_convert_to_types](evennia.utils.utils.safe_convert_to_types). This function automates the conversion of simple data types in a safe way: ```python @@ -208,94 +204,94 @@ from evennia.utils.utils import safe_convert_to_types def _process_callable(*args, **kwargs): """ - A callable with a lot of custom options - - $process(expression, local, extra=34, extra2=foo) - + A callable with a lot of custom options + + $process(expression, local, extra=34, extra2=foo) + """ args, kwargs = safe_convert_to_type( - (('py', 'py'), {'extra1': int, 'extra2': str}), + (('py', 'py'), {'extra1': int, 'extra2': str}), *args, **kwargs) - - # args/kwargs should be correct types now + + # args/kwargs should be correct types now ``` In other words, -```python +```python args, kwargs = safe_convert_to_type( (tuple_of_arg_converters, dict_of_kwarg_converters), *args, **kwargs) ``` -Each converter should be a callable taking one argument - this will be the arg/kwarg-value to convert. The -special converter `"py"` will try to convert a string argument to a Python structure with the help of the -following tools (which you may also find useful to experiment with on your own): +Each converter should be a callable taking one argument - this will be the arg/kwarg-value to convert. The +special converter `"py"` will try to convert a string argument to a Python structure with the help of the +following tools (which you may also find useful to experiment with on your own): - [ast.literal_eval](https://docs.python.org/3.8/library/ast.html#ast.literal_eval) is an in-built Python function. It _only_ supports strings, bytes, numbers, tuples, lists, dicts, sets, booleans and `None`. That's it - no arithmetic or modifications of data is allowed. This is good for converting individual values and lists/dicts from the input line to real Python objects. -- [simpleeval](https://pypi.org/project/simpleeval/) is a third-party tool included with Evennia. This - allows for evaluation of simple (and thus safe) expressions. One can operate on numbers and strings - with +-/* as well as do simple comparisons like `4 > 3` and more. It does _not_ accept more complex +- [simpleeval](https://pypi.org/project/simpleeval/) is a third-party tool included with Evennia. This + allows for evaluation of simple (and thus safe) expressions. One can operate on numbers and strings + with `+-/*` as well as do simple comparisons like `4 > 3` and more. It does _not_ accept more complex containers like lists/dicts etc, so this and `literal_eval` are complementary to each other. -```warning:: - It may be tempting to run use Python's in-built ``eval()`` or ``exec()`` functions as converters since - these are able to convert any valid Python source code to Python. NEVER DO THIS unless you really, really - know that ONLY developers will ever modify the string going into the callable. The parser is intended - for untrusted users (if you were trusted you'd have access to Python already). Letting untrusted users - pass strings to ``eval``/``exec`` is a MAJOR security risk. It allows the caller to run arbitrary - Python code on your server. This is the path to maliciously deleted hard drives. Just don't do it and +```{warning} + It may be tempting to run use Python's in-built ``eval()`` or ``exec()`` functions as converters since + these are able to convert any valid Python source code to Python. NEVER DO THIS unless you really, really + know that ONLY developers will ever modify the string going into the callable. The parser is intended + for untrusted users (if you were trusted you'd have access to Python already). Letting untrusted users + pass strings to ``eval``/``exec`` is a MAJOR security risk. It allows the caller to run arbitrary + Python code on your server. This is the path to maliciously deleted hard drives. Just don't do it and sleep better at night. ``` ## Default callables -These are some example callables you can import and add your parser. They are divided into -global-level dicts in `evennia.utils.funcparser`. Just import the dict(s) and merge/add one or +These are some example callables you can import and add your parser. They are divided into +global-level dicts in `evennia.utils.funcparser`. Just import the dict(s) and merge/add one or more to them when you create your `FuncParser` instance to have those callables be available. ### `evennia.utils.funcparser.FUNCPARSER_CALLABLES` These are the 'base' callables. -- `$eval(expression)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_eval)) - - this uses `literal_eval` and `simple_eval` (see previous section) attemt to convert a string expression +- `$eval(expression)` ([code](evennia.utils.funcparser.funcparser_callable_eval)) - + this uses `literal_eval` and `simple_eval` (see previous section) attemt to convert a string expression to a python object. This handles e.g. lists of literals `[1, 2, 3]` and simple expressions like `"1 + 2"`. -- `$toint(number)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_toint)) - +- `$toint(number)` ([code](evennia.utils.funcparser.funcparser_callable_toint)) - always converts an output to an integer, if possible. -- `$add/sub/mult/div(obj1, obj2)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_add)) - - this adds/subtracts/multiplies and divides to elements together. While simple addition could be done with - `$eval`, this could for example be used also to add two lists together, which is not possible with `eval`; +- `$add/sub/mult/div(obj1, obj2)` ([code](evennia.utils.funcparser.funcparser_callable_add)) - + this adds/subtracts/multiplies and divides to elements together. While simple addition could be done with + `$eval`, this could for example be used also to add two lists together, which is not possible with `eval`; for example `$add($eval([1,2,3]), $eval([4,5,6])) -> [1, 2, 3, 4, 5, 6]`. -- `$round(float, significant)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_round)) - +- `$round(float, significant)` ([code](evennia.utils.funcparser.funcparser_callable_round)) - rounds an input float into the number of provided significant digits. For example `$round(3.54343, 3) -> 3.543`. -- `$random([start, [end]])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_random)) - - this works like the Python `random()` function, but will randomize to an integer value if both start/end are +- `$random([start, [end]])` ([code](evennia.utils.funcparser.funcparser_callable_random)) - + this works like the Python `random()` function, but will randomize to an integer value if both start/end are integers. Without argument, will return a float between 0 and 1. -- `$randint([start, [end]])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_randint)) - +- `$randint([start, [end]])` ([code](evennia.utils.funcparser.funcparser_callable_randint)) - works like the `randint()` python function and always returns an integer. -- `$choice(list)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_choice)) - - the input will automatically be parsed the same way as `$eval` and is expected to be an iterable. A random +- `$choice(list)` ([code](evennia.utils.funcparser.funcparser_callable_choice)) - + the input will automatically be parsed the same way as `$eval` and is expected to be an iterable. A random element of this list will be returned. -- `$pad(text[, width, align, fillchar])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_pad)) - +- `$pad(text[, width, align, fillchar])` ([code](evennia.utils.funcparser.funcparser_callable_pad)) - this will pad content. `$pad("Hello", 30, c, -)` will lead to a text centered in a 30-wide block surrounded by `-` characters. -- `$crop(text, width=78, suffix='[...]')` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_crop)) - +- `$crop(text, width=78, suffix='[...]')` ([code](evennia.utils.funcparser.funcparser_callable_crop)) - this will crop a text longer than the width, by default ending it with a `[...]`-suffix that also fits within the width. If no width is given, the client width or `settings.DEFAULT_CLIENT_WIDTH` will be used. -- `$space(num)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_space)) - +- `$space(num)` ([code](evennia.utils.funcparser.funcparser_callable_space)) - this will insert `num` spaces. -- `$just(string, width=40, align=c, indent=2)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_justify)) - +- `$just(string, width=40, align=c, indent=2)` ([code](evennia.utils.funcparser.funcparser_callable_justify)) - justifies the text to a given width, aligning it left/right/center or 'f' for full (spread text across width). - `$ljust` - shortcut to justify-left. Takes all other kwarg of `$just`. - `$rjust` - shortcut to right justify. - `$cjust` - shortcut to center justify. -- `$clr(startcolor, text[, endcolor])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_clr)) - - color text. The color is given with one or two characters without the preceeding `|`. If no endcolor is +- `$clr(startcolor, text[, endcolor])` ([code](evennia.utils.funcparser.funcparser_callable_clr)) - + color text. The color is given with one or two characters without the preceeding `|`. If no endcolor is given, the string will go back to neutral, so `$clr(r, Hello)` is equivalent to `|rHello|n`. ### `evennia.utils.funcparser.SEARCHING_CALLABLES` @@ -304,15 +300,16 @@ These are callables that requires access-checks in order to search for objects. extra reserved kwargs to be passed when running the parser: ```python -parser.parse_to_any(string, caller=, access="control", ...)` + +parser.parse_to_any(string, caller=, access="control", ...) ``` -The `caller` is required, it's the the object to do the access-check for. The `access` kwarg is the - [lock type](./Locks) to check, default being `"control"`. +The `caller` is required, it's the the object to do the access-check for. The `access` kwarg is the + [lock type](./Locks.md) to check, default being `"control"`. -- `$search(query,type=account|script,return_list=False)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_search)) - - this will look up and try to match an object by key or alias. Use the `type` kwarg to - search for `account` or `script` instead. By default this will return nothing if there are more than one +- `$search(query,type=account|script,return_list=False)` ([code](evennia.utils.funcparser.funcparser_callable_search)) - + this will look up and try to match an object by key or alias. Use the `type` kwarg to + search for `account` or `script` instead. By default this will return nothing if there are more than one match; if `return_list` is `True` a list of 0, 1 or more matches will be returned instead. - `$obj(query)`, `$dbref(query)` - legacy aliases for `$search`. - `$objlist(query)` - legacy alias for `$search`, always returning a list. @@ -320,9 +317,9 @@ The `caller` is required, it's the the object to do the access-check for. The `a ### `evennia.utils.funcparser.ACTOR_STANCE_CALLABLES` -These are used to implement actor-stance emoting. They are used by the -[DefaultObject.msg_contents](api:evennia.objects.objects#evennia.objects.objects.DefaultObject.msg_contents) method -by default. +These are used to implement actor-stance emoting. They are used by the +[DefaultObject.msg_contents](evennia.objects.objects.DefaultObject.msg_contents) method +by default. These all require extra kwargs be passed into the parser: @@ -333,16 +330,16 @@ parser.parse(string, caller=, receiver=, mapping={'key': , ...}) Here the `caller` is the one sending the message and `receiver` the one to see it. The `mapping` contains references to other objects accessible via these callables. -- `$you([key])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_you)) - - if no `key` is given, this represents the `caller`, otherwise an object from `mapping` - will be used. As this message is sent to different recipients, the `receiver` will change and this will - be replaced either with the string `you` (if you and the receiver is the same entity) or with the +- `$you([key])` ([code](evennia.utils.funcparser.funcparser_callable_you)) - + if no `key` is given, this represents the `caller`, otherwise an object from `mapping` + will be used. As this message is sent to different recipients, the `receiver` will change and this will + be replaced either with the string `you` (if you and the receiver is the same entity) or with the result of `you_obj.get_display_name(looker=receiver)`. This allows for a single string to echo differently depending on who sees it, and also to reference other people in the same way. - `$You([key])` - same as `$you` but always capitalized. -- `$conj(verb)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_conjugate)) -- conjugates a verb between 4nd person presens to 3rd person presence depending on who +- `$conj(verb)` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) -- conjugates a verb between 4nd person presens to 3rd person presence depending on who sees the string. For example `"$You() $conj(smiles)".` will show as "You smile." and "Tom smiles." depending - on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](api:evennia.utils.verb_conjugation) + on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](evennia.utils.verb_conjugation) to do this, and only works for English verbs. ### Example @@ -377,10 +374,10 @@ result = parser.parse(string) ``` Above we define two callables `_dashline` and `_uptime` and map them to names `"dashline"` and `"uptime"`, -which is what we then can call as `$header` and `$uptime` in the string. We also have access to +which is what we then can call as `$header` and `$uptime` in the string. We also have access to all the defaults (like `$toint()`). -The parsed result of the above would be something like this: +The parsed result of the above would be something like this: This is the current uptime: - ------- 343 seconds ------- + ------- 343 seconds ------- diff --git a/docs/source/Components/Help-System.md b/docs/source/Components/Help-System.md index efe583058a..b5d44ffc03 100644 --- a/docs/source/Components/Help-System.md +++ b/docs/source/Components/Help-System.md @@ -64,7 +64,7 @@ regular code editor, see below). Evennia collects help entries from three sources: - _Auto-generated command help_ - this is literally the doc-strings of - the [Command classes](./Commands). The idea is that the command docs are + the [Command classes](./Commands.md). The idea is that the command docs are easier to maintain and keep up-to-date if the developer can change them at the same time as they do the code. - _Database-stored help entries_ - These are created in-game (using the @@ -93,14 +93,14 @@ All help entries (no matter the source) have the following properties: extra space at beginning and end. A `text` that scrolls off the screen will automatically be paginated by -the [EvMore](./EvMore) pager (you can control this with +the [EvMore](./EvMore.md) pager (you can control this with `settings.HELP_MORE_ENABLED=False`). If you use EvMore and want to control exactly where the pager should break the page, mark the break with the control character `\f`. #### Subtopics -```versionadded:: 1.0 +```{versionadded} 1.0 ``` Rather than making a very long help entry, the `text` may also be broken up @@ -199,7 +199,7 @@ The text at the very top of the command class definition is the class' consistent format - all default commands are using the structure shown above. You can limit access to the help entry by the `view` and/or `read` locks on the -Command. See [the section below](#Locking-help-entries) for details. +Command. See [the section below](./Help-System.md#locking-help-entries) for details. You should also supply the `help_category` class property if you can; this helps to group help entries together for people to more easily find them. See the @@ -209,7 +209,7 @@ used. If you don't want your command to be picked up by the auto-help system at all (like if you want to write its docs manually using the info in the next section -or you use a [cmdset](./Command-Sets) that has its own help functionality) you +or you use a [cmdset](./Command-Sets.md) that has its own help functionality) you can explicitly set `auto_help` class property to `False` in your command definition. @@ -233,8 +233,8 @@ entry = create_help_entry("emote", category="Roleplaying", locks="view:all()") ``` -The entity being created is a [evennia.help.models.HelpEntry](api:evennia.help.models.HelpEntry) -object. This is _not_ a [Typeclassed](./Typeclasses) entity and is not meant to +The entity being created is a [evennia.help.models.HelpEntry](evennia.help.models.HelpEntry) +object. This is _not_ a [Typeclassed](./Typeclasses.md) entity and is not meant to be modified to any great degree. It holds the properties listed earlier. The text is stored in a field `entrytext`. It does not provide a `get_help` method like commands, stores and returns the `entrytext` directly. @@ -244,7 +244,7 @@ this will not return the two other types of help entries. ### File-help entries -```versionadded:: 1.0 +```{versionadded} 1.0 ``` File-help entries are created by the game development team outside of the game. The @@ -369,7 +369,7 @@ help_entry = { ``` -```versionchanged:: 1.0 +```{versionchanged} 1.0 Changed the old 'view' lock to control the help-index inclusion and added the new 'read' lock-type to control access to the entry itself. ``` @@ -377,7 +377,7 @@ help_entry = { ## Customizing the look of the help system This is done almost exclusively by overriding the `help` command -[evennia.commands.default.help.CmdHelp](api:evennia.commands.default.help#CmdHelp). +[evennia.commands.default.help.CmdHelp](evennia.commands.default.help.CmdHelp). Since the available commands may vary from moment to moment, `help` is responsible for collating the three sources of help-entries (commands/db/file) @@ -401,7 +401,7 @@ Once the main entry has been found, subtopics are then searched with simple `==`, `startswith` and `in` matching (there are so relatively few of them at that point). -```versionchanged:: 1.0 +```{versionchanged} 1.0 Replaced the old bag-of-words algorithm with lunr package. ``` diff --git a/docs/source/Components/Inputfuncs.md b/docs/source/Components/Inputfuncs.md index 667d528ef2..c5b0b97e8f 100644 --- a/docs/source/Components/Inputfuncs.md +++ b/docs/source/Components/Inputfuncs.md @@ -1,9 +1,9 @@ # Inputfuncs -An *inputfunc* is an Evennia function that handles a particular input (an [inputcommand](../Concepts/OOB)) from +An *inputfunc* is an Evennia function that handles a particular input (an [inputcommand](../Concepts/OOB.md)) from the client. The inputfunc is the last destination for the inputcommand along the [ingoing message -path](Messagepath#the-ingoing-message-path). The inputcommand always has the form `(commandname, +path](../Concepts/Messagepath.md#the-ingoing-message-path). The inputcommand always has the form `(commandname, (args), {kwargs})` and Evennia will use this to try to find and call an inputfunc on the form ```python @@ -42,7 +42,7 @@ Evennia defines a few default inputfuncs to handle the common cases. These are d This is the most common of inputcommands, and the only one supported by every traditional mud. The argument is usually what the user sent from their command line. Since all text input from the user -like this is considered a [Command](./Commands), this inputfunc will do things like nick-replacement +like this is considered a [Command](./Commands.md), this inputfunc will do things like nick-replacement and then pass on the input to the central Commandhandler. ### echo @@ -134,7 +134,7 @@ to expand. By default the following values can be retrieved: accepted names if given an unfamiliar callback name. This will tell evennia to repeatedly call a named function at a given interval. Behind the scenes -this will set up a [Ticker](./TickerHandler). Only previously acceptable functions are possible to +this will set up a [Ticker](./TickerHandler.md). Only previously acceptable functions are possible to repeat-call in this way, you'll need to overload this inputfunc to add the ones you want to offer. By default only two example functions are allowed, "test1" and "test2", which will just echo a text back at the given interval. Stop the repeat by sending `"stop": True` (note that you must include @@ -155,7 +155,7 @@ This is a convenience wrapper for sending "stop" to the `repeat` inputfunc. This sets up on-object monitoring of Attributes or database fields. Whenever the field or Attribute changes in any way, the outputcommand will be sent. This is using the -[MonitorHandler](./MonitorHandler) behind the scenes. Pass the "stop" key to stop monitoring. Note +[MonitorHandler](./MonitorHandler.md) behind the scenes. Pass the "stop" key to stop monitoring. Note that you must supply the name also when stopping to let the system know which monitor should be cancelled. diff --git a/docs/source/Components/Locks.md b/docs/source/Components/Locks.md index 6d1968810d..7bfc076db3 100644 --- a/docs/source/Components/Locks.md +++ b/docs/source/Components/Locks.md @@ -2,9 +2,9 @@ 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](./Commands), -[Objects](./Objects), [Scripts](./Scripts), [Accounts](./Accounts), [Help System](./Help-System), -[messages](./Communications#Msg) and [channels](./Communications#Channels)) are accessed through locks. +applied and checked by something called *locks*. All Evennia entities ([Commands](./Commands.md), +[Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md), [Help System](./Help-System.md), +[messages](./Msg.md) and [channels](./Channels.md)) 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 @@ -92,9 +92,9 @@ the default command set) actually checks for, as in the example of `delete` abov Below are the access_types checked by the default commandset. -- [Commands](./Commands) +- [Commands](./Commands.md) - `cmd` - this defines who may call this command at all. -- [Objects](./Objects): +- [Objects](./Objects.md): - `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 stored on this Object except for the Object itself. By @@ -109,26 +109,26 @@ something like `call:false()`. - `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) -- [Characters](./Objects#Characters): +- [Characters](./Objects.md#characters): - Same as for Objects -- [Exits](./Objects#Exits): +- [Exits](./Objects.md#exits): - Same as for Objects - `traverse` - who may pass the exit. -- [Accounts](./Accounts): +- [Accounts](./Accounts.md): - `examine` - who may examine the account's properties. - `delete` - who may delete the account. - `edit` - who may edit the account's attributes and properties. - `msg` - who may send messages to the account. - `boot` - who may boot the account. -- [Attributes](./Attributes): (only checked by `obj.secure_attr`) +- [Attributes](./Attributes.md): (only checked by `obj.secure_attr`) - `attrread` - see/access attribute - `attredit` - change/delete attribute -- [Channels](./Communications#Channels): +- [Channels](./Channels.md): - `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](./Help-System): +- [HelpEntry](./Help-System.md): - `examine` - who may view this help entry (usually everyone) - `edit` - who may edit this help entry. @@ -214,10 +214,10 @@ Some useful default lockfuncs (see `src/locks/lockfuncs.py` for more): - `false()/none()/superuser()` - give access to none. Superusers bypass the check entirely and are thus the only ones who will pass this check. - `perm(perm)` - this tries to match a given `permission` property, on an Account firsthand, on a -Character second. See [below](./Locks#permissions). +Character second. See [below](./Permissions.md). - `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](./Attributes) exists on accessing_object. +- `attr(attrname)` - checks if a certain [Attribute](./Attributes.md) 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 @@ -250,7 +250,7 @@ a Lock lookup. ## Default locks Evennia sets up a few basic locks on all new objects and accounts (if we didn't, noone would have -any access to anything from the start). This is all defined in the root [Typeclasses](./Typeclasses) +any access to anything from the start). This is all defined in the root [Typeclasses](./Typeclasses.md) 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 @@ -300,7 +300,7 @@ whereas only Admins 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](./Objects) +Assume we have two objects - one is ourselves (not superuser) and the other is an [Object](./Objects.md) called `box`. > create/drop box @@ -326,7 +326,7 @@ This is defined in `evennia/commands/default/general.py`. In its code we find th ``` So the `get` command looks for a lock with the type *get* (not so surprising). It also looks for an -[Attribute](./Attributes) on the checked object called _get_err_msg_ in order to return a customized +[Attribute](./Attributes.md) 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. diff --git a/docs/source/Components/MonitorHandler.md b/docs/source/Components/MonitorHandler.md index 02959ebed8..9948389427 100644 --- a/docs/source/Components/MonitorHandler.md +++ b/docs/source/Components/MonitorHandler.md @@ -23,10 +23,10 @@ MONITOR_HANDLER.add(obj, fieldname, callback, ``` - - `obj` ([Typeclassed](./Typeclasses) entity) - the object to monitor. Since this must be -typeclassed, it means you can't monitor changes on [Sessions](./Sessions) with the monitorhandler, for + - `obj` ([Typeclassed](./Typeclasses.md) entity) - the object to monitor. Since this must be +typeclassed, it means you can't monitor changes on [Sessions](./Sessions.md) with the monitorhandler, for example. - - `fieldname` (str) - the name of a field or [Attribute](./Attributes) on `obj`. If you want to + - `fieldname` (str) - the name of a field or [Attribute](./Attributes.md) on `obj`. If you want to monitor a database field you must specify its full name, including the starting `db_` (like `db_key`, `db_location` etc). Any names not starting with `db_` are instead assumed to be the names of Attributes. This difference matters, since the MonitorHandler will automatically know to watch diff --git a/docs/source/Components/Msg.md b/docs/source/Components/Msg.md index df7503165f..4e3f46fcfe 100644 --- a/docs/source/Components/Msg.md +++ b/docs/source/Components/Msg.md @@ -1,6 +1,6 @@ # Msg -The [Msg](api:evennia.comms.models.Msg) object represents a database-saved +The [Msg](evennia.comms.models.Msg) object represents a database-saved piece of communication. Think of it as a discrete piece of email - it contains a message, some metadata and will always have a sender and one or more recipients. @@ -14,7 +14,7 @@ good uses for `Msg` objects: - game-wide email stored in 'mailboxes'. -```important:: +```{important} A `Msg` does not have any in-game representation. So if you want to use them to represent in-game mail/letters, the physical letters would never be @@ -25,15 +25,15 @@ good uses for `Msg` objects: ``` -```versionchanged:: 1.0 +```{versionchanged} 1.0 Channels dropped Msg-support. Now only used in `page` command by default. ``` ## Msg in code The Msg is intended to be used exclusively in code, to build other game systems. It is _not_ -a [Typeclassed](./Typeclasses) entity, which means it cannot (easily) be overridden. It -doesn't support Attributes (but it _does_ support [Tags](./Tags)). It tries to be lean +a [Typeclassed](./Typeclasses.md) entity, which means it cannot (easily) be overridden. It +doesn't support Attributes (but it _does_ support [Tags](./Tags.md)). It tries to be lean and small since a new one is created for every message. You create a new message with `evennia.create_message`: @@ -62,7 +62,7 @@ You can search for `Msg` objects in various ways: ### Properties on Msg - `senders` - there must always be at least one sender. This is a set of -- [Account](./Accounts), [Object](./Objects), [Script](./Scripts) +- [Account](./Accounts.md), [Object](./Objects.md), [Script](./Scripts.md) or `str` in any combination (but usually a message only targets one type). Using a `str` for a sender indicates it's an 'external' sender and and can be used to point to a sender that is not a typeclassed entity. This is not used by default @@ -70,17 +70,17 @@ You can search for `Msg` objects in various ways: python-path, for example). While most systems expect a single sender, it's possible to have any number of them. - `receivers` - these are the ones to see the Msg. These are again any combination of - [Account](./Accounts), [Object](./Objects) or [Script](./Scripts) or `str` (an 'external' receiver). + [Account](./Accounts.md), [Object](./Objects.md) or [Script](./Scripts.md) or `str` (an 'external' receiver). It's in principle possible to have zero receivers but most usages of Msg expects one or more. - `header` - this is an optional text field that can contain meta-information about the message. For an email-like system it would be the subject line. This can be independently searched, making this a powerful place for quickly finding messages. - `message` - the actual text being sent. - `date_sent` - this is auto-set to the time the Msg was created (and thus presumably sent). -- `locks` - the Evennia [lock handler](./Locks). Use with `locks.add()` etc and check locks with `msg.access()` +- `locks` - the Evennia [lock handler](./Locks.md). Use with `locks.add()` etc and check locks with `msg.access()` like for all other lockable entities. This can be used to limit access to the contents of the Msg. The default lock-type to check is `'read'`. -- `hide_from` - this is an optional list of [Accounts](./Accounts) or [Objects](./Objects) that +- `hide_from` - this is an optional list of [Accounts](./Accounts.md) or [Objects](./Objects.md) that will not see this Msg. This relationship is available mainly for optimization reasons since it allows quick filtering of messages not intended for a given target. @@ -88,7 +88,7 @@ You can search for `Msg` objects in various ways: ## TempMsg -[evennia.comms.models.TempMsg](api:evennia.comms.models.TempMsg) is an object +[evennia.comms.models.TempMsg](evennia.comms.models.TempMsg) is an object that implements the same API as the regular `Msg`, but which has no database component (and thus cannot be searched). It's meant to plugged into systems expecting a `Msg` but where you just want to process the message without saving diff --git a/docs/source/Components/Nicks.md b/docs/source/Components/Nicks.md index 6cb2fb3355..eb93bb599c 100644 --- a/docs/source/Components/Nicks.md +++ b/docs/source/Components/Nicks.md @@ -1,7 +1,7 @@ # Nicks -*Nicks*, short for *Nicknames* is a system allowing an object (usually a [Account](./Accounts)) to +*Nicks*, short for *Nicknames* is a system allowing an object (usually a [Account](./Accounts.md)) 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 @@ -75,7 +75,7 @@ You can also use [shell-type wildcards](http://www.linfo.org/wildcard.html): ## Coding with nicks Nicks are stored as the `Nick` database model and are referred from the normal Evennia -[object](./Objects) through the `nicks` property - this is known as the *NickHandler*. The NickHandler +[object](./Objects.md) through the `nicks` property - this is known as the *NickHandler*. The NickHandler offers effective error checking, searches and conversion. ```python @@ -101,12 +101,12 @@ offers effective error checking, searches and conversion. In a command definition you can reach the nick handler through `self.caller.nicks`. See the `nick` command in `evennia/commands/default/general.py` for more examples. -As a last note, The Evennia [channel](./Communications) alias systems are using nicks with the +As a last note, The Evennia [channel](./Communications.md) alias systems are using nicks with the `nick_type="channel"` in order to allow users to create their own custom aliases to channels. # Advanced note -Internally, nicks are [Attributes](./Attributes) saved with the `db_attrype` set to "nick" (normal +Internally, nicks are [Attributes](./Attributes.md) saved with the `db_attrype` set to "nick" (normal Attributes has this set to `None`). The nick stores the replacement data in the Attribute.db_value field as a tuple with four fields diff --git a/docs/source/Components/Objects.md b/docs/source/Components/Objects.md index 388b66fb3d..816a913245 100644 --- a/docs/source/Components/Objects.md +++ b/docs/source/Components/Objects.md @@ -3,7 +3,7 @@ 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](./Typeclasses) entities. +spend most time working with. Objects are [Typeclassed](./Typeclasses.md) entities. ## How to create your own object types @@ -48,17 +48,17 @@ thing yourself in code: 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 defining your own building commands). Check out the `ev.create_*` functions for how to build other entities -like [Scripts](./Scripts)). +like [Scripts](./Scripts.md)). 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 or using the -[Spawner](./Prototypes)). The `Object` typeclass offers many more hooks that is available +[Spawner](./Prototypes.md)). The `Object` typeclass offers many more hooks that is available to use though - see next section. ## Properties and functions on Objects -Beyond the properties assigned to all [typeclassed](./Typeclasses) objects (see that page for a list +Beyond the properties assigned to all [typeclassed](./Typeclasses.md) objects (see that page for a list of those), the Object also has the following custom properties: - `aliases` - a handler that allows you to add and remove aliases from this object. Use @@ -67,12 +67,12 @@ of those), the Object also has the following custom properties: - `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 [Exits](./Objects#Exits), it's otherwise usually unset. -- `nicks` - as opposed to aliases, a [Nick](./Nicks) holds a convenient nickname replacement for a +main use is for [Exits](./Objects.md#exits), it's otherwise usually unset. +- `nicks` - as opposed to aliases, a [Nick](./Nicks.md) 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. Use nicks.add(alias, realname) to add a new one. -- `account` - this holds a reference to a connected [Account](./Accounts) controlling this object (if +- `account` - this holds a reference to a connected [Account](./Accounts.md) controlling this object (if any). Note that this is set also if the controlling account is *not* currently online - to test if an account is online, use the `has_account` property instead. - `sessions` - if `account` field is set *and the account is online*, this is a list of all active @@ -87,9 +87,9 @@ object set as their `location`). The last two properties are special: -- `cmdset` - this is a handler that stores all [command sets](./Commands#Command_Sets) defined on the +- `cmdset` - this is a handler that stores all [command sets](./Command-Sets.md) defined on the object (if any). -- `scripts` - this is a handler that manages [Scripts](./Scripts) attached to the object (if any). +- `scripts` - this is a handler that manages [Scripts](./Scripts.md) 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. @@ -104,7 +104,7 @@ 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 [Exits](./Objects#Exits) to *and* from this object. +- `clear_exits()` - will delete all [Exits](./Objects.md#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 @@ -113,8 +113,7 @@ their designated `Home` locations. 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 `evennia.objects.objects` for an -updated list of all the available hooks or the [API for DefaultObject -here](api:evennia.objects.objects#defaultobject). +updated list of all the available hooks or the [API for DefaultObject here](evennia.objects.objects.DefaultObject). ## Subclasses of `Object` @@ -126,10 +125,10 @@ practice they are all pretty similar to the base Object. ### Characters -Characters are objects controlled by [Accounts](./Accounts). When a new Account +Characters are objects controlled by [Accounts](./Accounts.md). When a new Account logs in to Evennia for the first time, a new `Character` object is created and the Account object is assigned to the `account` attribute. A `Character` object -must have a [Default Commandset](./Commands#Command_Sets) set on itself at +must have a [Default Commandset](./Command-Sets.md) set on itself at creation, or the account will not be able to issue any commands! If you just inherit your own class from `evennia.DefaultCharacter` and make sure to use `super()` to call the parent methods you should be fine. In @@ -150,21 +149,21 @@ you to modify. *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 [Transit Command](./Commands) on themselves when they are created. This command is +define a special [Transit Command](./Commands.md) 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 [locked](./Locks) using an access_type called *traverse* and also make use of a few +doing). Exits are [locked](./Locks.md) using an access_type called *traverse* and also make use of a few hook methods for giving feedback if the traversal fails. See `evennia.DefaultExit` for more info. In `mygame/typeclasses/exits.py` there is an empty `Exit` class for you to modify. The process of traversing an exit is as follows: 1. The traversing `obj` sends a command that matches the Exit-command name on the Exit object. The -[cmdhandler](./Commands) detects this and triggers the command defined on the Exit. Traversal always +[cmdhandler](./Commands.md) detects this and triggers the command defined on the Exit. Traversal always involves the "source" (the current location) and the `destination` (this is stored on the Exit object). 1. The Exit command checks the `traverse` lock on the Exit object diff --git a/docs/source/Components/Outputfuncs.md b/docs/source/Components/Outputfuncs.md index 1f00d62238..f0eca56e4b 100644 --- a/docs/source/Components/Outputfuncs.md +++ b/docs/source/Components/Outputfuncs.md @@ -1,3 +1,3 @@ # Outputfuncs -TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB). \ No newline at end of file +TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB.md). \ No newline at end of file diff --git a/docs/source/Components/Permissions.md b/docs/source/Components/Permissions.md index 5de38c2ba3..cac5e05b0f 100644 --- a/docs/source/Components/Permissions.md +++ b/docs/source/Components/Permissions.md @@ -1,15 +1,15 @@ # Permissions A *permission* is simply a text string stored in the handler `permissions` on `Objects` -and `Accounts`. Think of it as a specialized sort of [Tag](./Tags) - one specifically dedicated -to access checking. They are thus often tightly coupled to [Locks](./Locks). +and `Accounts`. Think of it as a specialized sort of [Tag](./Tags.md) - one specifically dedicated +to access checking. They are thus often tightly coupled to [Locks](./Locks.md). Permission strings are not case-sensitive, so "Builder" is the same as "builder" etc. Permissions are used as a convenient way to structure access levels and hierarchies. It is set by the `perm` command and checked by the `PermissionHandler.check` method as well as by the specially the `perm()` and -`pperm()` [lock functions](./Locks). +`pperm()` [lock functions](./Locks.md). All new accounts are given a default set of permissions defined by `settings.PERMISSION_ACCOUNT_DEFAULT`. @@ -22,7 +22,7 @@ In-game, you use the `perm` command to add and remove permissions perm/account/del Tommy = Builders Note the use of the `/account` switch. It means you assign the permission to the -[Accounts](./Accounts) Tommy instead of any [Character](./Objects) that also +[Accounts](./Accounts.md) Tommy instead of any [Character](./Objects.md) that also happens to be named "Tommy". There can be reasons for putting permissions on Objects (especially NPCS), but @@ -32,7 +32,7 @@ of which Character they are currently puppeting. This is especially important to remember when assigning permissions from the *hierarchy tree* (see below), as an Account's permissions will overrule that of its character. So to be sure to avoid confusion you should generally put hierarchy permissions on the Account, -not on their Characters (but see also [quelling](./Locks#Quelling)). +not on their Characters (but see also [quelling](#quelling)). In code, you add/remove Permissions via the `PermissionHandler`, which sits on all typeclassed entities as the property `.permissions`: @@ -73,7 +73,7 @@ that permission to pass. ## Checking permissions It's important to note that you check for the permission of a *puppeted* -[Object](./Objects) (like a Character), the check will always first use the +[Object](./Objects.md) (like a Character), the check will always first use the permissions of any `Account` connected to that Object before checking for permissions on the Object. In the case of hierarchical permissions (Admins, Builders etc), the Account permission will always be used (this stops an Account @@ -99,7 +99,7 @@ _PermissionHandler_, stored as `.permissions` on all typeclassed entities. Using the `.check` method is the way to go, it will take hierarchical permissions into account, check accounts/sessions etc. -```warning +```{warning} Don't confuse `.permissions.check()` with `.permissions.has()`. The .has() method checks if a string is defined specifically on that PermissionHandler. @@ -111,7 +111,7 @@ permissions into account, check accounts/sessions etc. ### Lock funcs While the `PermissionHandler` offers a simple way to check perms, [Lock -strings](Locks) offers a mini-language for describing how something is accessed. +strings](./Locks.md) offers a mini-language for describing how something is accessed. The `perm()` _lock function_ is the main tool for using Permissions in locks. Let's say we have a `red_key` object. We also have red chests that we want to @@ -153,7 +153,6 @@ There are several variations to the default `perm` lockfunc: objects (regardless of hierarchical perm or not). - `pperm_above` - like `perm_above`, but for Accounts only. - ### Some examples Adding permissions and checking with locks diff --git a/docs/source/Components/Portal-And-Server.md b/docs/source/Components/Portal-And-Server.md index e4cc99f6ec..eaf134242c 100644 --- a/docs/source/Components/Portal-And-Server.md +++ b/docs/source/Components/Portal-And-Server.md @@ -2,7 +2,7 @@ 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](../Setup/Start-Stop-Reload). +inside the game or from the command line as described [here](../Setup/Start-Stop-Reload.md). If you are new to the concept, the main purpose of separating the two is to have accounts connect to the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the diff --git a/docs/source/Components/Prototypes.md b/docs/source/Components/Prototypes.md index 3ede8d4ede..9bcaea3605 100644 --- a/docs/source/Components/Prototypes.md +++ b/docs/source/Components/Prototypes.md @@ -2,10 +2,10 @@ The *spawner* is a system for defining and creating individual objects from a base template called a -*prototype*. It is only designed for use with in-game [Objects](./Objects), not any other type of +*prototype*. It is only designed for use with in-game [Objects](./Objects.md), not any other type of entity. -The normal way to create a custom object in Evennia is to make a [Typeclass](./Typeclasses). If you +The normal way to create a custom object in Evennia is to make a [Typeclass](./Typeclasses.md). If you haven't read up on Typeclasses yet, think of them as normal Python classes that save to the database behind the scenes. Say you wanted to create a "Goblin" enemy. A common way to do this would be to first create a `Mobile` typeclass that holds everything common to mobiles in the game, like generic @@ -105,12 +105,12 @@ instead. exist. - `destination` - a valid `#dbref`. Only used by exits. - `permissions` - list of permission strings, like `["Accounts", "may_use_red_door"]` - - `locks` - a [lock-string](./Locks) like `"edit:all();control:perm(Builder)"` + - `locks` - a [lock-string](./Locks.md) like `"edit:all();control:perm(Builder)"` - `aliases` - list of strings for use as aliases - - `tags` - list [Tags](./Tags). These are given as tuples `(tag, category, data)`. - - `attrs` - list of [Attributes](./Attributes). These are given as tuples `(attrname, value, + - `tags` - list [Tags](./Tags.md). These are given as tuples `(tag, category, data)`. + - `attrs` - list of [Attributes](./Attributes.md). These are given as tuples `(attrname, value, category, lockstring)` - - Any other keywords are interpreted as non-category [Attributes](./Attributes) and their values. + - Any other keywords are interpreted as non-category [Attributes](./Attributes.md) and their values. This is convenient for simple Attributes - use `attrs` for full control of Attributes. @@ -119,7 +119,7 @@ Deprecated as of Evennia 0.8: - `ndb_` - sets the value of a non-persistent attribute (`"ndb_"` is stripped from the name). This is simply not useful in a prototype and is deprecated. - `exec` - This accepts a code snippet or a list of code snippets to run. This should not be used - - use callables or [$protfuncs](./Prototypes#protfuncs) instead (see below). + use callables or [$protfuncs](./Prototypes.md#protfuncs) instead (see below). ### Prototype values @@ -160,10 +160,8 @@ that you embed in strings and that has a `$` in front, like "He has $randint(2,5) skulls in a chain around his neck."} ``` At execution time, the place of the protfunc will be replaced with the result of that protfunc being -called (this is always a string). A protfunc works in much the same way as an -[InlineFunc](../Concepts/TextTags#inline-functions) - they are actually -parsed using the same parser - except protfuncs are run every time the prototype is used to spawn a -new object (whereas an inlinefunc is called when a text is returned to the user). +called (this is always a string). A protfunc is a [FuncParser function](./FuncParser.md) run +every time the prototype is used to spawn a new object. Here is how a protfunc is defined (same as an inlinefunc). @@ -233,7 +231,7 @@ A prototype can be defined and stored in two ways, either in the database or as ### Database prototypes -Stored as [Scripts](./Scripts) in the database. These are sometimes referred to as *database- +Stored as [Scripts](./Scripts.md) in the database. These are sometimes referred to as *database- prototypes* This is the only way for in-game builders to modify and add prototypes. They have the advantage of being easily modifiable and sharable between builders but you need to work with them using in-game tools. diff --git a/docs/source/Components/Scripts.md b/docs/source/Components/Scripts.md index cdee64e849..da3c79e50d 100644 --- a/docs/source/Components/Scripts.md +++ b/docs/source/Components/Scripts.md @@ -1,19 +1,19 @@ # Scripts -[Script API reference](api:evennia.scripts.scripts) +[Script API reference](evennia.scripts.scripts) *Scripts* are the out-of-character siblings to the in-character -[Objects](./Objects). Scripts are so flexible that the name "Script" is a bit limiting +[Objects](./Objects.md). Scripts are so flexible that the name "Script" is a bit limiting in itself - but we had to pick _something_ to name them. Other possible names (depending on what you'd use them for) would be `OOBObjects`, `StorageContainers` or `TimerObjects`. -If you ever consider creating an [Object](./Objects) with a `None`-location just to store some game data, +If you ever consider creating an [Object](./Objects.md) with a `None`-location just to store some game data, you should really be using a Script instead. -- Scripts are full [Typeclassed](./Typeclasses) entities - they have [Attributes](./Attributes) and +- Scripts are full [Typeclassed](./Typeclasses.md) entities - they have [Attributes](./Attributes.md) and can be modified in the same way. But they have _no in-game existence_, so no - location or command-execution like [Objects](./Objects) and no connection to a particular - player/session like [Accounts](./Accounts). This means they are perfectly suitable for acting + location or command-execution like [Objects](./Objects.md) and no connection to a particular + player/session like [Accounts](./Accounts.md). This means they are perfectly suitable for acting as database-storage backends for game _systems_: Storing the current state of the economy, who is involved in the current fight, tracking an ongoing barter and so on. They are great as persistent system handlers. @@ -21,22 +21,22 @@ you should really be using a Script instead. to tick the `at_repeat` hook on the Script at a certain interval. The timer can be controlled independently of the rest of the script as needed. This component is optional and complementary to other timing functions in Evennia, like - [evennia.utils.delay](api:evennia.utils.utils#evennia.utils.utils.delay) and - [evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat). + [evennia.utils.delay](evennia.utils.utils.delay) and + [evennia.utils.repeat](evennia.utils.utils.repeat). - Scripts can _attach_ to Objects and Accounts via e.g. `obj.scripts.add/remove`. In the script you can then access the object/account as `self.obj` or `self.account`. This can be used to dynamically extend other typeclasses but also to use the timer component to affect the parent object in various ways. For historical reasons, a Script _not_ attached to an object is referred to as a _Global_ Script. -```versionchanged:: 1.0 +```{versionchanged} 1.0 In previus Evennia versions, stopping the Script's timer also meant deleting the Script object. Starting with this version, the timer can be start/stopped separately and `.delete()` must be called on the Script explicitly to delete it. ``` -### In-game command examples +## In-game command examples There are two main commands controlling scripts in the default cmdset: @@ -52,11 +52,11 @@ The `scripts` command is used to view all scripts and perform operations on them > scripts/pause #11 > scripts/delete #566 -```versionchanged:: 1.0 +```{versionchanged} 1.0 The `addscript` command used to be only `script` which was easy to confuse with `scripts`. ``` -### Code examples +## Code examples Here are some examples of working with Scripts in-code (more details to follow in later sections). @@ -111,13 +111,13 @@ new_script.delete() timed_script.delete() ``` -## Defining new Scripts +# Defining new Scripts A Script is defined as a class and is created in the same way as other -[typeclassed](./Typeclasses) entities. The parent class is `evennia.DefaultScript`. +[typeclassed](./Typeclasses.md) entities. The parent class is `evennia.DefaultScript`. -### Simple storage script +## Simple storage script In `mygame/typeclasses/scripts.py` is an empty `Script` class already set up. You can use this as a base for your own scripts. @@ -162,12 +162,12 @@ evennia.create_script('typeclasses.scripts.MyScript', key="another name", ``` -See the [create_script](api:evennia.utils.create#evennia.utils.create.create_script) and -[search_script](api:evennia.utils.search#evennia.utils.search.search_script) API documentation for more options +See the [create_script](evennia.utils.create.create_script) and +[search_script](evennia.utils.search.search_script) API documentation for more options on creating and finding Scripts. -### Timed Scripts +## Timed Scripts There are several properties one can set on the Script to control its timer component. @@ -229,11 +229,11 @@ The timer component is controlled with methods on the Script class: - `.force_repeat()` - this prematurely forces `at_repeat` to be called right away. Doing so will reset the countdown so that next call will again happen after `interval` seconds. -#### Script timers vs delay/repeat +### Script timers vs delay/repeat If the _only_ goal is to get a repeat/delay effect, the -[evennia.utils.delay](api:evennia.utils.utils#evennia.utils.utils.delay) and -[evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat) functions +[evennia.utils.delay](evennia.utils.utils.delay) and +[evennia.utils.repeat](evennia.utils.utils.repeat) functions should generally be considered first. A Script is a lot 'heavier' to create/delete on the fly. In fact, for making a single delayed call (`script.repeats==1`), the `utils.delay` call is probably always the better choice. @@ -249,9 +249,9 @@ It's also worth noting that once the script object has _already been created_, starting/stopping/pausing/unpausing the timer has very little overhead. The pause/unpause and update methods of the script also offers a bit more fine-control than using `utils.delays/repeat`. -### Script attached to another object +## Script attached to another object -Scripts can be attached to an [Account](./Accounts) or (more commonly) an [Object](./Objects). +Scripts can be attached to an [Account](./Accounts.md) or (more commonly) an [Object](./Objects.md). If so, the 'parent object' will be available to the script as either `.obj` or `.account`. @@ -303,10 +303,10 @@ You can also attach the script as part of creating it: create_script('typeclasses.weather.Weather', obj=myroom) ``` -## Other Script methods +# Other Script methods A Script has all the properties of a typeclassed object, such as `db` and `ndb`(see -[Typeclasses](./Typeclasses)). Setting `key` is useful in order to manage scripts (delete them by name +[Typeclasses](./Typeclasses.md)). 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 `evennia.create_script`. @@ -325,12 +325,12 @@ reload. - `delete()` - same as for other typeclassed entities, this will delete the Script. Of note is that it will also stop the timer (if it runs), leading to the `at_stop` hook being called. -In addition, Scripts support [Attributes](./Attributes), [Tags](./Tags) and [Locks](./Locks) etc like other +In addition, Scripts support [Attributes](./Attributes.md), [Tags](./Tags.md) and [Locks](./Locks.md) etc like other Typeclassed entities. -See also the methods involved in controlling a [Timed Script](#Timed_Scripts) above. +See also the methods involved in controlling a [Timed Script](#timed-scripts) above. -## The GLOBAL_SCRIPTS container +# The GLOBAL_SCRIPTS container A Script not attached to another entity is commonly referred to as a _Global_ script since it't available to access from anywhere. This means they need to be searched for in order to be used. @@ -353,7 +353,7 @@ GLOBAL_SCRIPTS.weather.db.current_weather = "Cloudy" ``` -```warning:: +```{warning} Note that global scripts appear as properties on `GLOBAL_SCRIPTS` based on their `key`. If you were to create two global scripts with the same `key` (even with different typeclasses), the `GLOBAL_SCRIPTS` container will only return one of them (which one depends on order in @@ -389,10 +389,10 @@ GLOBAL_SCRIPTS = { Above we add two scripts with keys `myscript` and `storagescript`respectively. The following dict can be empty - the `settings.BASE_SCRIPT_TYPECLASS` will then be used. Under the hood, the provided dict (along with the `key`) will be passed into `create_script` automatically, so -all the [same keyword arguments as for create_script](api:evennia.utils.create.create_script) are +all the [same keyword arguments as for create_script](evennia.utils.create.create_script) are supported here. -```warning:: +```{warning} Before setting up Evennia to manage your script like this, make sure that your Script typeclass does not have any critical errors (test it separately). If there are, you'll see errors in your log and your Script will temporarily fall back to being a `DefaultScript` type. @@ -413,7 +413,7 @@ That is, if the script is deleted, next time you get it from `GLOBAL_SCRIPTS`, E information in settings to recreate it for you on the fly. -## Hints: Dealing with Script Errors +# Hints: Dealing with Script Errors Errors inside a timed, executing script can sometimes be rather terse or point to parts of the execution mechanism that is hard to interpret. One way to make it diff --git a/docs/source/Components/Server.md b/docs/source/Components/Server.md index 324fd35124..05ca0ca3ab 100644 --- a/docs/source/Components/Server.md +++ b/docs/source/Components/Server.md @@ -1,3 +1,3 @@ # Server component -TODO: This is currently in [Portal-and-Server](./Portal-And-Server). \ No newline at end of file +TODO: This is currently in [Portal-and-Server](./Portal-And-Server.md). \ No newline at end of file diff --git a/docs/source/Components/Sessions.md b/docs/source/Components/Sessions.md index f672f2961e..159612bce2 100644 --- a/docs/source/Components/Sessions.md +++ b/docs/source/Components/Sessions.md @@ -5,14 +5,14 @@ An Evennia *Session* represents one single established connection to the server. Evennia session, it is possible for a person to connect multiple times, for example using different clients in multiple windows. Each such connection is represented by a session object. -A session object has its own [cmdset](./Command-Sets), usually the "unloggedin" cmdset. This is what +A session object has its own [cmdset](./Command-Sets.md), usually the "unloggedin" cmdset. This is what is used to show the login screen and to handle commands to create a new account (or -[Account](./Accounts) in evennia lingo) read initial help and to log into the game with an existing +[Account](./Accounts.md) in evennia lingo) read initial help and to log into the game with an existing account. A session object can either be "logged in" or not. Logged in means that the user has authenticated. When this happens the session is associated with an Account object (which is what holds account-centric stuff). The account can then in turn puppet any number of objects/characters. -> Warning: A Session is not *persistent* - it is not a [Typeclass](./Typeclasses) and has no +> Warning: A Session is not *persistent* - it is not a [Typeclass](./Typeclasses.md) and has no connection to the database. The Session will go away when a user disconnects and you will lose any custom data on it if the server reloads. The `.db` handler on Sessions is there to present a uniform API (so you can assume `.db` exists even if you don't know if you receive an Object or a Session), @@ -26,13 +26,13 @@ Here are some important properties available on (Server-)Sessions - `sessid` - The unique session-id. This is an integer starting from 1. - `address` - The connected client's address. Different protocols give different information here. - `logged_in` - `True` if the user authenticated to this session. -- `account` - The [Account](./Accounts) this Session is attached to. If not logged in yet, this is +- `account` - The [Account](./Accounts.md) this Session is attached to. If not logged in yet, this is `None`. -- `puppet` - The [Character/Object](./Objects) currently puppeted by this Account/Session combo. If +- `puppet` - The [Character/Object](./Objects.md) currently puppeted by this Account/Session combo. If not logged in or in OOC mode, this is `None`. -- `ndb` - The [Non-persistent Attribute](./Attributes) handler. +- `ndb` - The [Non-persistent Attribute](./Attributes.md) handler. - `db` - As noted above, Sessions don't have regular Attributes. This is an alias to `ndb`. -- `cmdset` - The Session's [CmdSetHandler](./Command-Sets) +- `cmdset` - The Session's [CmdSetHandler](./Command-Sets.md) Session statistics are mainly used internally by Evennia. @@ -99,7 +99,7 @@ transparently detect which session was triggering the command (if any) and redir `command.msg()` is often the safest bet. You can get the `session` in two main ways: -* [Accounts](./Accounts) and [Objects](./Objects) (including Characters) have a `sessions` property. +* [Accounts](./Accounts.md) and [Objects](./Objects.md) (including Characters) have a `sessions` property. This is a *handler* that tracks all Sessions attached to or puppeting them. Use e.g. `accounts.sessions.get()` to get a list of Sessions attached to that entity. * A Command instance has a `session` property that always points back to the Session that triggered @@ -132,7 +132,7 @@ changes carefully. *Note: This is considered an advanced topic. You don't need to know this on a first read-through.* -Evennia is split into two parts, the [Portal and the Server](./Portal-And-Server). Each side tracks +Evennia is split into two parts, the [Portal and the Server](./Portal-And-Server.md). Each side tracks its own Sessions, syncing them to each other. The "Session" we normally refer to is actually the `ServerSession`. Its counter-part on the Portal @@ -172,7 +172,7 @@ server reboot (assuming the Portal is not stopped at the same time, obviously). Both the Portal and Server each have a *sessionhandler* to manage the connections. These handlers are global entities 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](../Concepts/Custom-Protocols) for more info +`sessionhandler`) so they can relay data. See [protocols](../Concepts/Custom-Protocols.md) for more info on building new protocols. To get all Sessions in the game (i.e. all currently connected clients), you access the server-side diff --git a/docs/source/Components/Signals.md b/docs/source/Components/Signals.md index a156bfe174..b96d84fcde 100644 --- a/docs/source/Components/Signals.md +++ b/docs/source/Components/Signals.md @@ -69,7 +69,7 @@ be extracted from the `**kwargs` dict in the signal handler. used way for users to themselves create accounts during login. It passes and extra kwarg `ip` with the client IP of the connecting account. - `SIGNAL_ACCOUNT_POST_LOGIN` - this will always fire when the account has authenticated. Sends - extra kwarg `session` with the new [Session](./Sessions) object involved. + extra kwarg `session` with the new [Session](./Sessions.md) object involved. - `SIGNAL_ACCCOUNT_POST_FIRST_LOGIN` - this fires just before `SIGNAL_ACCOUNT_POST_LOGIN` but only if this is the *first* connection done (that is, if there are no previous sessions connected). Also diff --git a/docs/source/Components/Tags.md b/docs/source/Components/Tags.md index 01f8d65748..af9e834898 100644 --- a/docs/source/Components/Tags.md +++ b/docs/source/Components/Tags.md @@ -10,11 +10,11 @@ currently dead. *Tags* are short text labels that you attach to objects so as to easily be able to retrieve and group them. An Evennia entity can be tagged with any number of Tags. On the database side, Tag entities are *shared* between all objects with that tag. This makes them very efficient but also -fundamentally different from [Attributes](./Attributes), each of which always belongs to one *single* +fundamentally different from [Attributes](./Attributes.md), each of which always belongs to one *single* object. In Evennia, Tags are technically also used to implement `Aliases` (alternative names for objects) -and `Permissions` (simple strings for [Locks](./Locks) to check for). +and `Permissions` (simple strings for [Locks](./Locks.md) to check for). ## Properties of Tags (and Aliases and Permissions) @@ -26,7 +26,7 @@ unique key + category combination. When Tags are assigned to game entities, these entities are actually sharing the same Tag. This means that Tags are not suitable for storing information about a single object - use an -[Attribute](./Attributes) for this instead. Tags are a lot more limited than Attributes but this also +[Attribute](./Attributes.md) for this instead. Tags are a lot more limited than Attributes but this also makes them very quick to lookup in the database - this is the whole point. Tags have the following properties, stored in the database: @@ -52,8 +52,8 @@ free up the *category* property for any use you desire. ## Adding/Removing Tags -You can tag any *typeclassed* object, namely [Objects](./Objects), [Accounts](./Accounts), -[Scripts](./Scripts) and [Channels](./Communications). General tags are added by the *Taghandler*. The +You can tag any *typeclassed* object, namely [Objects](./Objects.md), [Accounts](./Accounts.md), +[Scripts](./Scripts.md) and [Channels](./Communications.md). General tags are added by the *Taghandler*. The tag handler is accessed as a property `tags` on the relevant entity: ```python @@ -135,7 +135,7 @@ objs = evennia.search_tag(category="bar") -There is also an in-game command that deals with assigning and using ([Object-](./Objects)) tags: +There is also an in-game command that deals with assigning and using ([Object-](./Objects.md)) tags: @tag/search furniture @@ -166,4 +166,4 @@ That said, tag categories can be useful if you build some game system that uses use tag categories to make sure to separate tags created with this system from any other tags created elsewhere. You can then supply custom search methods that *only* find objects tagged with tags of that category. An example of this -is found in the [Zone tutorial](../Concepts/Zones). \ No newline at end of file +is found in the [Zone tutorial](../Concepts/Zones.md). \ No newline at end of file diff --git a/docs/source/Components/TickerHandler.md b/docs/source/Components/TickerHandler.md index d0a9b2eb96..ad5e88e72c 100644 --- a/docs/source/Components/TickerHandler.md +++ b/docs/source/Components/TickerHandler.md @@ -11,7 +11,7 @@ hard-coded to rely on the concept of the global 'tick'. Evennia has no such noti use tickers is very much up to the need of your game and which requirements you have. The "ticker recipe" is just one way of cranking the wheels. -The most fine-grained way to manage the flow of time is of course to use [Scripts](./Scripts). Many +The most fine-grained way to manage the flow of time is of course to use [Scripts](./Scripts.md). Many types of operations (weather being the classic example) are however done on multiple objects in the same way at regular intervals, and for this, storing separate Scripts on each object is inefficient. The way to do this is to use a ticker with a "subscription model" - let objects sign up to be @@ -98,13 +98,13 @@ The `callable` can be on any form as long as it accepts the arguments you give t > Note that everything you supply to the TickerHandler will need to be pickled at some point to be saved into the database. Most of the time the handler will correctly store things like database -objects, but the same restrictions as for [Attributes](./Attributes) apply to what the TickerHandler +objects, but the same restrictions as for [Attributes](./Attributes.md) apply to what the TickerHandler may store. When testing, you can stop all tickers in the entire game with `tickerhandler.clear()`. You can also view the currently subscribed objects with `tickerhandler.all()`. -See the [Weather Tutorial](../Howto/Weather-Tutorial) for an example of using the TickerHandler. +See the [Weather Tutorial](../Howto/Weather-Tutorial.md) for an example of using the TickerHandler. ### When *not* to use TickerHandler diff --git a/docs/source/Components/Typeclasses.md b/docs/source/Components/Typeclasses.md index f245544180..4ef0cd8c6a 100644 --- a/docs/source/Components/Typeclasses.md +++ b/docs/source/Components/Typeclasses.md @@ -5,8 +5,8 @@ different game entities as Python classes, without having to modify the database schema for every new type. -In Evennia the most important game entities, [Accounts](./Accounts), [Objects](./Objects), -[Scripts](./Scripts) and [Channels](./Communications#Channels) are all Python classes inheriting, at +In Evennia the most important game entities, [Accounts](./Accounts.md), [Objects](./Objects.md), +[Scripts](./Scripts.md) and [Channels](./Channels.md) are all Python classes inheriting, at varying distance, from `evennia.typeclasses.models.TypedObject`. In the documentation we refer to these objects as being "typeclassed" or even "being a typeclass". @@ -48,14 +48,14 @@ module from anywhere, the `typeclass/list` will not find it. To make it known to Evennia you must import that module from somewhere. -### Difference between typeclasses and classes +## Difference between typeclasses and classes All Evennia classes inheriting from class in the table above share one important feature and two important limitations. This is why we don't simply call them "classes" but "typeclasses". 1. A typeclass can save itself to the database. This means that some properties (actually not that many) on the class actually represents database fields and can only hold very specific data types. -This is detailed [below](./Typeclasses#about-typeclass-properties). +This is detailed [below](./Typeclasses.md#about-typeclass-properties). 1. Due to its connection to the database, the typeclass' name must be *unique* across the _entire_ server namespace. That is, there must never be two same-named classes defined anywhere. So the below code would give an error (since `DefaultObject` is now globally found both in this module and in the @@ -82,7 +82,7 @@ both accept arbitrary keyword arguments and use `super` to call its parent:: ``` Apart from this, a typeclass works like any normal Python class and you can -treat it as such. +treat it as such. ## Creating a new typeclass @@ -129,11 +129,11 @@ argument; this can both be the actual class or the python path to the typeclass game directory. So if your `Furniture` typeclass sits in `mygame/typeclasses/furniture.py`, you could point to it as `typeclasses.furniture.Furniture`. Since Evennia will itself look in `mygame/typeclasses`, you can shorten this even further to just `furniture.Furniture`. The create- -functions take a lot of extra keywords allowing you to set things like [Attributes](./Attributes) and -[Tags](./Tags) all in one go. These keywords don't use the `db_*` prefix. This will also automatically +functions take a lot of extra keywords allowing you to set things like [Attributes](./Attributes.md) and +[Tags](./Tags.md) all in one go. These keywords don't use the `db_*` prefix. This will also automatically save the new instance to the database, so you don't need to call `save()` explicitly. -### About typeclass properties +## About typeclass properties An example of a database field is `db_key`. This stores the "name" of the entity you are modifying and can thus only hold a string. This is one way of making sure to update the `db_key`: @@ -178,36 +178,36 @@ returns the string form "#id". The typeclassed entity has several common handlers: - - `tags` - the [TagHandler](./Tags) that handles tagging. Use `tags.add()` , `tags.get()` etc. - - `locks` - the [LockHandler](./Locks) that manages access restrictions. Use `locks.add()`, + - `tags` - the [TagHandler](./Tags.md) that handles tagging. Use `tags.add()` , `tags.get()` etc. + - `locks` - the [LockHandler](./Locks.md) that manages access restrictions. Use `locks.add()`, `locks.get()` etc. - - `attributes` - the [AttributeHandler](./Attributes) that manages Attributes on the object. Use + - `attributes` - the [AttributeHandler](./Attributes.md) that manages Attributes on the object. Use `attributes.add()` etc. - `db` (DataBase) - a shortcut property to the AttributeHandler; allowing `obj.db.attrname = value` - - `nattributes` - the [Non-persistent AttributeHandler](./Attributes) for attributes not saved in the + - `nattributes` - the [Non-persistent AttributeHandler](./Attributes.md) for attributes not saved in the database. - `ndb` (NotDataBase) - a shortcut property to the Non-peristent AttributeHandler. Allows `obj.ndb.attrname = value` Each of the typeclassed entities then extend this list with their own properties. Go to the -respective pages for [Objects](./Objects), [Scripts](./Scripts), [Accounts](./Accounts) and -[Channels](./Communications) for more info. It's also recommended that you explore the available -entities using [Evennia's flat API](../Evennia-API) to explore which properties and methods they have +respective pages for [Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md) and +[Channels](./Communications.md) for more info. It's also recommended that you explore the available +entities using [Evennia's flat API](../Evennia-API.md) to explore which properties and methods they have available. -### Overloading hooks +## Overloading hooks The way to customize typeclasses is usually to overload *hook methods* on them. Hooks are methods that Evennia call in various situations. An example is the `at_object_creation` hook on `Objects`, which is only called once, the very first time this object is saved to the database. Other examples are the `at_login` hook of Accounts and the `at_repeat` hook of Scripts. -### Querying for typeclasses +## Querying for typeclasses Most of the time you search for objects in the database by using convenience methods like the -`caller.search()` of [Commands](./Commands) or the search functions like `evennia.search_objects`. +`caller.search()` of [Commands](./Commands.md) or the search functions like `evennia.search_objects`. You can however also query for them directly using [Django's query language](https://docs.djangoproject.com/en/1.7/topics/db/queries/). This makes use of a _database @@ -245,13 +245,13 @@ matches = ScriptDB.objects.filter(db_key__contains="Combat") When querying from the database model parent you don't need to use `filter_family` or `get_family` - you will always query all children on the database model. -## Updating existing typeclass instances +# Updating existing typeclass instances If you already have created instances of Typeclasses, you can modify the *Python code* at any time - due to how Python inheritance works your changes will automatically be applied to all children once you have reloaded the server. -However, database-saved data, like `db_*` fields, [Attributes](./Attributes), [Tags](./Tags) etc, are +However, database-saved data, like `db_*` fields, [Attributes](./Attributes.md), [Tags](./Tags.md) etc, are not themselves embedded into the class and will *not* be updated automatically. This you need to manage yourself, by searching for all relevant objects and updating or adding the data: @@ -317,7 +317,7 @@ The arguments to this method are described [in the API docs here](github:evennia.typeclasses.models#typedobjectswap_typeclass). -## How typeclasses actually work +# How typeclasses actually work *This is considered an advanced section.* @@ -325,7 +325,7 @@ Technically, typeclasses are [Django proxy models](https://docs.djangoproject.com/en/1.7/topics/db/models/#proxy-models). The only database models that are "real" in the typeclass system (that is, are represented by actual tables in the database) are `AccountDB`, `ObjectDB`, `ScriptDB` and `ChannelDB` (there are also -[Attributes](./Attributes) and [Tags](./Tags) but they are not typeclasses themselves). All the +[Attributes](./Attributes.md) and [Tags](./Tags.md) but they are not typeclasses themselves). All the subclasses of them are "proxies", extending them with Python code without actually modifying the database layout. @@ -334,7 +334,7 @@ Evennia modifies Django's proxy model in various ways to allow them to work with handles this for you using metaclasses). Evennia also makes sure you can query subclasses as well as patches django to allow multiple inheritance from the same base class. -### Caveats +## Caveats Evennia uses the *idmapper* to cache its typeclasses (Django proxy models) in memory. The idmapper allows things like on-object handlers and properties to be stored on typeclass instances and to not diff --git a/docs/source/Components/Web-API.md b/docs/source/Components/Web-API.md index 3668c7ff35..0a38073c3e 100644 --- a/docs/source/Components/Web-API.md +++ b/docs/source/Components/Web-API.md @@ -11,7 +11,7 @@ meant to be accessed in code, by other programs. The API is using [Django Rest Framework][drf]. This automates the process of setting up _views_ (Python code) to process the result of web requests. The process of retrieving data is similar to that explained on the -[Webserver](./Webserver) page, except the views will here return [JSON][json] +[Webserver](./Webserver.md) page, except the views will here return [JSON][json] data for the resource you want. You can also _send_ such JSON data in order to update the database from the outside. @@ -25,7 +25,7 @@ To activate the API, add this to your settings file. The main controlling setting is `REST_FRAMEWORK`, which is a dict. The keys `DEFAULT_LIST_PERMISSION` and `DEFAULT_CREATE_PERMISSIONS` control who may view and create new objects via the api respectively. By default, users with -['Builder'-level permission](./Permissions) or higher may access both actions. +['Builder'-level permission](./Permissions.md) or higher may access both actions. While the api is meant to be expanded upon, Evennia supplies several operations out of the box. If you click the `Autodoc` button in the upper right of the `/api` @@ -74,7 +74,7 @@ permissions: "results": [{"username": "bob",...}] } -Now suppose that you want to use the API to create an [Object](./Objects): +Now suppose that you want to use the API to create an [Object](./Objects.md): >>> data = {"db_key": "A shiny sword"} >>> response = requests.post("https://www.mygame.com/api/objects", @@ -108,7 +108,7 @@ Overall, reading up on [Django Rest Framework ViewSets](https://www.django-rest- other parts of their documentation is required for expanding and customizing the API. -Check out the [Website](./Website) page for help on how to override code, templates +Check out the [Website](./Website.md) page for help on how to override code, templates and static files. - API templates (for the web-display) is located in `evennia/web/api/templates/rest_framework/` (it must be named such to allow override of the original REST framework templates). diff --git a/docs/source/Components/Web-Admin.md b/docs/source/Components/Web-Admin.md index 0d87368f1a..5faf2f82cb 100644 --- a/docs/source/Components/Web-Admin.md +++ b/docs/source/Components/Web-Admin.md @@ -29,7 +29,7 @@ objects are actually stored as a `tuple` with object-unique data. you'll find the field _Serialized string_. This string shows a Python tuple like ('__packed_dbobj__', ('objects', 'objectdb'), '2021:05:15-08:59:30:624660', 358) - + Mark and copy this tuple-string to your clipboard exactly as it stands (parentheses and all). 2. Go to the entity that should have the new Attribute and create the Attribute. In its `value` field, paste the tuple-string you copied before. Save! @@ -86,21 +86,21 @@ Only Superusers can change the `Superuser status` flag, and grant new permissions to accounts. The superuser is the only permission level that is also relevant in-game. `User Permissions` and `Groups` found on the `Account` admin page _only_ affects the admin - they have no connection to the in-game -[Permissions](./Permissions) (Player, Builder, Admin etc). +[Permissions](./Permissions.md) (Player, Builder, Admin etc). For a staffer with `Staff status` to be able to actually do anything, the superuser must grant at least some permissions for them on their Account. This can also be good in order to limit mistakes. It can be a good idea to not allow the `Can delete Account` permission, for example. -```important:: +```{important} If you grant staff-status and permissions to an Account and they still cannot access the admin's content, try reloading the server. ``` -```warning:: +```{warning} If a staff member has access to the in-game ``py`` command, they can just as well have their admin ``Superuser status`` set too. The reason is that ``py`` @@ -112,25 +112,25 @@ the `Can delete Account` permission, for example. ## Customizing the web admin -Customizing the admin is a big topic and something beyond the scope of this +Customizing the admin is a big topic and something beyond the scope of this documentation. See the [official Django docs](https://docs.djangoproject.com/en/3.2/ref/contrib/admin/) for -the details. This is just a brief summary. +the details. This is just a brief summary. -See the [Website](./Website) page for an overview of the components going into +See the [Website](./Website.md) page for an overview of the components going into generating a web page. The Django admin uses the same principle except that Django provides a lot of tools to automate the admin-generation for us. Admin templates are found in `evennia/web/templates/admin/` but you'll find this is relatively empty. This is because most of the templates are just inherited directly from their original location in the Django package -(`django/contrib/admin/templates/`). So if you wanted to override one you'd have +(`django/contrib/admin/templates/`). So if you wanted to override one you'd have to copy it from _there_ into your `mygame/templates/admin/` folder. Same is true for CSS files. The admin site's backend code (the views) is found in `evennia/web/admin/`. It is organized into `admin`-classes, like `ObjectAdmin`, `AccountAdmin` etc. These automatically use the underlying database models to generate useful views -for us without us havint go code the forms etc ourselves. +for us without us havint go code the forms etc ourselves. The top level `AdminSite` (the admin configuration referenced in django docs) is found in `evennia/web/utils/adminsite.py`. @@ -138,7 +138,7 @@ is found in `evennia/web/utils/adminsite.py`. ### Change the title of the admin -By default the admin's title is `Evennia web admin`. To change this, add the +By default the admin's title is `Evennia web admin`. To change this, add the following to your `mygame/web/urls.py`: ```python diff --git a/docs/source/Components/Webserver.md b/docs/source/Components/Webserver.md index 17718ab5c3..549f23c603 100644 --- a/docs/source/Components/Webserver.md +++ b/docs/source/Components/Webserver.md @@ -4,7 +4,7 @@ When Evennia starts it also spins up its own Twisted-based web server. The webserver is responsible for serving the html pages of the game's website. It can also serve static resources like images and music. -The webclient runs as part of the [Server](./Portal-And-Server) process of +The webclient runs as part of the [Server](./Portal-And-Server.md) process of Evennia. This means that it can directly access cached objects modified in-game, and there is no risk of working with objects that are temporarily out-of-sync in the database. @@ -12,17 +12,17 @@ out-of-sync in the database. The webserver runs on Twisted and is meant to be used in a production environment. It leverages the Django web framework and provides: -- A [Game Website](./Website) - this is what you see when you go to +- A [Game Website](./Website.md) - this is what you see when you go to `localhost:4001`. The look of the website is meant to be customized to your game. Users logged into the website will be auto-logged into the game if they do so with the webclient since they share the same login credentials (there is no way to safely do auto-login with telnet clients). -- The [Web Admin](./Web-Admin) is based on the Django web admin and allows you to +- The [Web Admin](./Web-Admin.md) is based on the Django web admin and allows you to edit the game database in a graphical interface. -- The [Webclient](./Webclient) page is served by the webserver, but the actual +- The [Webclient](./Webclient.md) page is served by the webserver, but the actual game communication (sending/receiving data) is done by the javascript client on the page opening a websocket connection directly to Evennia's Portal. -- The [Evennia REST-API](./Web-API) allows for accessing the database from outside the game +- The [Evennia REST-API](./Web-API.md) allows for accessing the database from outside the game (only if `REST_API_ENABLED=True). @@ -62,7 +62,7 @@ it operates independently from Evennia. Small snippets of javascript can be used on a page to have buttons react, make small animations etc that doesn't require the server. -In the case of the [Webclient](./Webclient), Evennia will load the Webclient page +In the case of the [Webclient](./Webclient.md), Evennia will load the Webclient page as above, but the page then initiates Javascript code (a lot of it) responsible for actually displaying the client GUI, allows you to resize windows etc. diff --git a/docs/source/Components/Website.md b/docs/source/Components/Website.md index 0b1eabfbbf..03c345ca0e 100644 --- a/docs/source/Components/Website.md +++ b/docs/source/Components/Website.md @@ -1,14 +1,14 @@ # Game website -When Evennia starts it will also start a [Webserver](./Webserver) as part of the -[Server](./Portal-And-Server) process. This uses [Django](https://docs.djangoproject.com) +When Evennia starts it will also start a [Webserver](./Webserver.md) as part of the +[Server](./Portal-And-Server.md) process. This uses [Django](https://docs.djangoproject.com) to present a simple but functional default game website. With the default setup, -open your browser to [localhost:4001](http://localhost:4001) or [127.0.0.1:4001](http://127.0.0.1:4001) +open your browser to [localhost:4001](http://localhost:4001) or [127.0.0.1:4001](http://127.0.0.1:4001) to see it. The website allows existing players to log in using an account-name and password they previously used to register with the game. If a user logs in with -the [Webclient](./Webclient) they will also log into the website and vice-versa. +the [Webclient](./Webclient.md) they will also log into the website and vice-versa. So if you are logged into the website, opening the webclient will automatically log you into the game as that account. @@ -28,15 +28,15 @@ In the top menu you can find show a list of all channels available to you and allow you to view the latest discussions. Most channels require logging in, but the `Public` channel can also be viewed by non-loggedin users. -- _Help_ - This ties the in-game [Help system](./Help-System) to the website. All +- _Help_ - This ties the in-game [Help system](./Help-System.md) to the website. All database-based help entries that are publicly available or accessible to your account can be read. This is a good way to present a body of help for people to read outside of the game. -- _Play Online_ - This opens the [Webclient](./Webclient) in the browser. +- _Play Online_ - This opens the [Webclient](./Webclient.md) in the browser. - _Admin_ The [Web admin](Web admin) will only show if you are logged in. - _Log in/out_ - Allows you to authenticate using the same credentials you use in the game. -- _Register_ - Allows you to register a new account. This is the same as +- _Register_ - Allows you to register a new account. This is the same as creating a new account upon first logging into the game). ## Modifying the default Website @@ -52,7 +52,7 @@ You'll mostly be doing so in your settings file > DEBUG mode leaks memory (for retaining debug info) and is *not* safe to use > for a production game! -As explained on the [Webserver](./Webserver) page, the process for getting a web +As explained on the [Webserver](./Webserver.md) page, the process for getting a web page is 1. Web browser sends HTTP request to server with an URL @@ -115,7 +115,7 @@ This is the layout of the `mygame/web/` folder relevant for the website: ``` -```versionchanged:: 1.0 +```{versionchanged} 1.0 Game folders created with older versions of Evennia will lack most of this convenient `mygame/web/` layout. If you use a game dir from an older version, @@ -139,7 +139,7 @@ version rather than it using the original. ## Examples of commom web changes -```important:: +```{important} Django is a very mature web-design framework. There are endless internet-tutorials, courses and books available to explain how to use Django. @@ -206,8 +206,8 @@ There's a lot more information to be found in the [Django template language docu ### Change webpage colors and styling -You can tweak the [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) of the entire -website. If you investigate the `evennia/web/templates/website/base.html` file you'll see that we +You can tweak the [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) of the entire +website. If you investigate the `evennia/web/templates/website/base.html` file you'll see that we use the [Bootstrap 4](https://getbootstrap.com/docs/4.6/getting-started/introduction/) toolkit. @@ -220,8 +220,8 @@ The website's custom CSS is found in empty) `custom.css` in the same location. You can override either, but it may be easier to revert your changes if you only add things to `custom.css`. -Copy the CSS file you want to modify to the corresponding location in `mygame/web`. -Modify it and reload the server to see your changes. +Copy the CSS file you want to modify to the corresponding location in `mygame/web`. +Modify it and reload the server to see your changes. You can also apply static files without reloading, but running this in the terminal: @@ -233,8 +233,8 @@ terminal: > Note that before you see new CSS files applied you may need to refresh your > browser without cache (Ctrl-F5 in Firefox, for example). -As an example, add/copy `custom.css` to `mygame/web/static/website/css/` and -add the following: +As an example, add/copy `custom.css` to `mygame/web/static/website/css/` and +add the following: ```css @@ -271,14 +271,14 @@ look in `evennia/web/website/urls.py`. Here we find the following line: ``` -The first `""` is the empty url - root - what you get if you just enter `localhost:4001/` +The first `""` is the empty url - root - what you get if you just enter `localhost:4001/` with no extra path. As expected, this leads to the index page. By looking at the imports -we find the view is in in `evennia/web/website/views/index.py`. +we find the view is in in `evennia/web/website/views/index.py`. -Copy this file to the corresponding location in `mygame/web`. Then tweak your `mygame/web/website/urls.py` +Copy this file to the corresponding location in `mygame/web`. Then tweak your `mygame/web/website/urls.py` file to point to the new file: -```python +```python # in mygame/web/website/urls.py # ... @@ -292,8 +292,8 @@ urlpatterns = [ # ... ``` - -So we just import `index` from the new location and point to it. After a reload + +So we just import `index` from the new location and point to it. After a reload the front page will now redirect to use your copy rather than the original. The frontpage view is a class `EvenniaIndexView`. This is a [Django class-based view](https://docs.djangoproject.com/en/3.2/topics/class-based-views/). @@ -321,7 +321,7 @@ your copy. Just remember to reload. ### Using Flat Pages The absolutely simplest way to add a new web page is to use the `Flat Pages` -app available in the [Web Admin](./Web-Admin). The page will appear with the same +app available in the [Web Admin](./Web-Admin.md). The page will appear with the same styling as the rest of the site. For the `Flat pages` module to work you must first set up a _Site_ (or @@ -337,7 +337,7 @@ experimentation, add the domain `localhost:4001`. Note the `id` of the domain Next you create new pages easily. - Go the `Flat Pages` web admin and choose to add a new flat page. -- Set the url. If you want the page to appear as e.g. `localhost:4001/test/`, then +- Set the url. If you want the page to appear as e.g. `localhost:4001/test/`, then add `/test/` here. You need to add both leading and trailing slashes. - Set `Title` to the name of the page. - The `Content` is the HTML content of the body of the page. Go wild! @@ -348,16 +348,16 @@ You can now go to `localhost:4001/test/` and see your new page! ### Add Custom new page -The `Flat Pages` page doesn't allow for (much) dynamic content and customization. For +The `Flat Pages` page doesn't allow for (much) dynamic content and customization. For this you need to add the needed components yourself. Let's see how to make a `/test/` page from scratch. -- Add a new `test.html` file under `mygame/web/templates/website/`. Easiest is to base - this off an existing file. Make sure to `{% extend base.html %}` if you want to +- Add a new `test.html` file under `mygame/web/templates/website/`. Easiest is to base + this off an existing file. Make sure to `{% extend base.html %}` if you want to get the same styling as the rest of your site. -- Add a new view `testview.py` under `mygame/web/website/views/` (don't name it `test.py` or - Django/Evennia will think it contains unit tests). Add a view there to process +- Add a new view `testview.py` under `mygame/web/website/views/` (don't name it `test.py` or + Django/Evennia will think it contains unit tests). Add a view there to process your page. This is a minimal view to start from (read much more [in the Django docs](https://docs.djangoproject.com/en/3.2/topics/class-based-views/)): ```python @@ -385,7 +385,7 @@ Let's see how to make a `/test/` page from scratch. path("test/", testview.MyTestView.as_view()) ] - ``` + ``` - Reload the server and your new page is available. You can now continue to add all sorts of advanced dynamic content through your view and template! @@ -395,13 +395,13 @@ Let's see how to make a `/test/` page from scratch. All the pages created so far deal with _presenting_ information to the user. It's also possible for the user to _input_ data on the page through _forms_. An example would be a page of fields and sliders you fill in to create a -character, with a big 'Submit' button at the bottom. +character, with a big 'Submit' button at the bottom. Firstly, this must be represented in HTML. The `
...
` is a standard HTML element you need to add to your template. It also has some other requirements, such as `` and often Javascript components as well (but usually Django will help with this). If you are unfamiliar with how HTML forms -work, [read about them here](https://docs.djangoproject.com/en/3.2/topics/forms/#html-forms). +work, [read about them here](https://docs.djangoproject.com/en/3.2/topics/forms/#html-forms). The basic gist of it is that when you click to 'submit' the form, a POST HTML request will be sent to the server containing the data the user entered. It's @@ -412,9 +412,9 @@ On the backend side, we need to specify the logic for validating and processing the form data. This is done by the `Form` [Django class](https://docs.djangoproject.com/en/3.2/topics/forms/#forms-in-django). This specifies _fields_ on itself that define how to validate that piece of data. -The form is then linked into the view-class by adding `form_class = MyFormClass` to +The form is then linked into the view-class by adding `form_class = MyFormClass` to the view (next to `template_name`). -There are several example forms in `evennia/web/website/forms.py`. It's also a good +There are several example forms in `evennia/web/website/forms.py`. It's also a good idea to read [Building a form in Django](https://docs.djangoproject.com/en/3.2/topics/forms/#building-a-form-in-django) on the Django website - it covers all you need. diff --git a/docs/source/Concepts/Async-Process.md b/docs/source/Concepts/Async-Process.md index b2ab53011d..6e4b24525a 100644 --- a/docs/source/Concepts/Async-Process.md +++ b/docs/source/Concepts/Async-Process.md @@ -90,7 +90,7 @@ line quite pointless for processing any data from the function. Instead one has - `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](../Components/Commands) definition: +An example of making an asynchronous call from inside a [Command](../Components/Commands.md) definition: ```python from evennia import utils, Command @@ -139,7 +139,7 @@ sleep. ``` This will delay the execution of the callback for 10 seconds. This function is explored much more in -the [Command Duration Tutorial](../Howto/Command-Duration). +the [Command Duration Tutorial](../Howto/Command-Duration.md). You can also try the following snippet just see how it works: diff --git a/docs/source/Concepts/Banning.md b/docs/source/Concepts/Banning.md index 3da0155058..2c8b5c22c8 100644 --- a/docs/source/Concepts/Banning.md +++ b/docs/source/Concepts/Banning.md @@ -114,14 +114,14 @@ is not what you want in this case. - **cboot mychannel = thomas** -- Boot a subscriber from a channel you control - **clock mychannel = control:perm(Admin);listen:all();send:all()** -- Fine control of access to -your channel using [lock definitions](../Components/Locks). +your channel using [lock definitions](../Components/Locks.md). Locking a specific command (like `page`) is accomplished like so: 1. Examine the source of the command. [The default `page` command class]( https://github.com/evennia/evennia/blob/master/evennia/commands/default/comms.py#L686) has the lock string **"cmd:not pperm(page_banned)"**. This means that unless the player has the 'permission' "page_banned" they can use this command. You can assign any lock string to allow finer customization -in your commands. You might look for the value of an [Attribute](../Components/Attributes) or [Tag](../Components/Tags), your +in your commands. You might look for the value of an [Attribute](../Components/Attributes.md) or [Tag](../Components/Tags.md), your current location etc. 2. **perm/account thomas = page_banned** -- Give the account the 'permission' which causes (in this case) the lock to fail. diff --git a/docs/source/Concepts/Building-Permissions.md b/docs/source/Concepts/Building-Permissions.md index 4ec22d4e5f..728a64f41b 100644 --- a/docs/source/Concepts/Building-Permissions.md +++ b/docs/source/Concepts/Building-Permissions.md @@ -2,7 +2,7 @@ *OBS: This gives only a brief introduction to the access system. Locks and permissions are fully -detailed* [here](../Components/Locks). +detailed* [here](../Components/Locks.md). ## The super user @@ -17,7 +17,7 @@ but one superuser. Whereas permissions can be used for anything, those put in `settings.PERMISSION_HIERARCHY` will have a ranking relative each other as well. We refer to these types of permissions as *hierarchical -permissions*. When building locks to check these permissions, the `perm()` [lock function](../Components/Locks) is +permissions*. When building locks to check these permissions, the `perm()` [lock function](../Components/Locks.md) is used. By default Evennia creates the following hierarchy (spelled exactly like this): 1. **Developers** basically have the same access as superusers except that they do *not* sidestep diff --git a/docs/source/Concepts/Clickable-Links.md b/docs/source/Concepts/Clickable-Links.md index 5a4f9ed262..b0e96c163e 100644 --- a/docs/source/Concepts/Clickable-Links.md +++ b/docs/source/Concepts/Clickable-Links.md @@ -1,8 +1,8 @@ -## Clickable links +# Clickable links Evennia supports clickable links for clients that supports it. This marks certain text so it can be -clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web -browser. To support clickable links, Evennia requires the webclient or an third-party telnet client +clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web +browser. To support clickable links, Evennia requires the webclient or an third-party telnet client with [MXP](http://www.zuggsoft.com/zmud/mxp.htm) support (*Note: Evennia only supports clickable links, no other MXP features*). - `|lc` to start the link, by defining the command to execute. diff --git a/docs/source/Concepts/Colors.md b/docs/source/Concepts/Colors.md index 64b2f9a319..32b3438c1d 100644 --- a/docs/source/Concepts/Colors.md +++ b/docs/source/Concepts/Colors.md @@ -1,7 +1,7 @@ # Colors *Note that the Documentation does not display colour the way it would look on the screen.* - + Color can be a very useful tool for your game. It can be used to increase readability and make your game more appealing visually. @@ -14,13 +14,13 @@ 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](../Howto/Manually-Configuring-Color). +colours as they please, as described [here](../Howto/Manually-Configuring-Color.md). To see which colours your client support, use the default `@color` command. This will list all available colours for ANSI and Xterm256 along with the codes you use for them. You can find a list of all the parsed `ANSI`-colour codes in `evennia/utils/ansi.py`. -### ANSI colours +## ANSI colours Evennia supports the `ANSI` standard for text. This is by far the most supported MUD-color standard, available in all but the most ancient mud clients. The ANSI colours are **r**ed, **g**reen, @@ -28,7 +28,7 @@ available in all but the most ancient mud clients. The ANSI colours are **r**ed, first letter except for black which is abbreviated with the letter **x**. In ANSI there are "bright" and "normal" (darker) versions of each color, adding up to a total of 16 colours to use for foreground text. There are also 8 "background" colours. These have no bright alternative in ANSI -(but Evennia uses the [Xterm256](./TextTags#xterm256-colours) extension behind the scenes to offer +(but Evennia uses the [Xterm256](#xterm256-colours) extension behind the scenes to offer them anyway). To colour your text you put special tags in it. Evennia will parse these and convert them to the @@ -37,7 +37,7 @@ will see the text in the specified colour, otherwise the tags will be stripped ( This works also for non-terminal clients, such as the webclient. For the webclient, Evennia will translate the codes to HTML RGB colors. -Here is an example of the tags in action: +Here is an example of the tags in action: |rThis text is bright red.|n This is normal text. |RThis is a dark red text.|n This is normal text. @@ -49,9 +49,9 @@ Here is an example of the tags in action: "normal". So `|g` is a bright green and `|G` is "normal" (darker) green. - `|[#` is used to add a background colour to the text. The case again specifies if it is "bright" or "normal", so `|[c` starts a bright cyan background and `|[C` a darker cyan background. -- `|!#` is used to add foreground color without any enforced brightness/normal information. - These are normal-intensity and are thus always given as uppercase, such as - `|!R` for red. The difference between e.g. `|!R` and `|R` is that +- `|!#` is used to add foreground color without any enforced brightness/normal information. + These are normal-intensity and are thus always given as uppercase, such as + `|!R` for red. The difference between e.g. `|!R` and `|R` is that `|!R` will "inherit" the brightness setting from previously set color tags, whereas `|R` will always reset to the normal-intensity red. The `|#` format contains an implicit `|h`/`|H` tag in it: disabling highlighting when switching to a normal color, and enabling it for bright ones. So `|btest @@ -67,7 +67,7 @@ set bright/normal explicitly. Technically, `|h|!G` is identical to `|g`. > Note: The ANSI standard does not actually support bright backgrounds like `|[r` - the standard only supports "normal" intensity backgrounds. To get around this Evennia instead implements these -as [Xterm256 colours](./TextTags#xterm256-colours) behind the scenes. If the client does not support +as [Xterm256 colours](#xterm256-colours) behind the scenes. If the client does not support Xterm256 the ANSI colors will be used instead and there will be no visible difference between using upper- and lower-case background tags. @@ -83,11 +83,11 @@ ansi art that uses `|` with a letter directly following it. Use the command - @color ansi + @color ansi to get a list of all supported ANSI colours and the tags used to produce them. -A few additional ANSI codes are supported: +A few additional ANSI codes are supported: - `|/` A line break. You cannot put the normal Python `\n` line breaks in text entered inside the game (Evennia will filter this for security reasons). This is what you use instead: use the `|/` @@ -100,7 +100,7 @@ space. - `|*` This will invert the current text/background colours. Can be useful to mark things (but see below). -##### Caveats of `|*` +### Caveats of `|*` The `|*` tag (inverse video) is an old ANSI standard and should usually not be used for more than to mark short snippets of text. If combined with other tags it comes with a series of potentially @@ -113,11 +113,11 @@ until you declare another tag. This is an example: Normal text, |*reversed text|*, still reversed text. ``` - that is, it will not reverse to normal at the second `|*`. You need to reset it manually: + that is, it will not reverse to normal at the second `|*`. You need to reset it manually: ``` Normal text, |*reversed text|n, normal again. - ``` + ``` * The `|*` tag does not take "bright" colors into account: @@ -167,7 +167,7 @@ four gray tones between solid black and white (`|000`, `|111`, `|222`, `|333` an - `|[=#` - this works in the same way but produces background gray scale tones. If you have a client that supports Xterm256, you can use - + @color xterm256 to get a table of all the 256 colours and the codes that produce them. If the table looks broken up @@ -178,6 +178,6 @@ to activate some features manually. ## More reading -There is an [Understanding Color Tags](../Howto/Understanding-Color-Tags) tutorial which expands on the +There is an [Understanding Color Tags](../Howto/Understanding-Color-Tags.md) tutorial which expands on the use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context. diff --git a/docs/source/Concepts/Concepts-Overview.md b/docs/source/Concepts/Concepts-Overview.md index a170dabda4..eaba407c09 100644 --- a/docs/source/Concepts/Concepts-Overview.md +++ b/docs/source/Concepts/Concepts-Overview.md @@ -1,30 +1,30 @@ # Core Concepts -This documentation cover more over-arching concepts of Evennia, often involving many [Core Components](../Components/Components-Overview) acting together. +This documentation cover more over-arching concepts of Evennia, often involving many [Core Components](../Components/Components-Overview.md) acting together. ## General concepts -- [Asynchronous processing](./Async-Process) -- [On Soft-Code](./Soft-Code) -- [Using MUX as standard for default commands](./Using-MUX-as-a-Standard) +- [Asynchronous processing](./Async-Process.md) +- [On Soft-Code](./Soft-Code.md) +- [Using MUX as standard for default commands](./Using-MUX-as-a-Standard.md) ## Access -- [Multisession modes](./Multisession-modes) -- [Permissions](./Building-Permissions) -- [Banning](./Banning) +- [Multisession modes](./Multisession-modes.md) +- [Permissions](./Building-Permissions.md) +- [Banning](./Banning.md) ## Extending the Server -- [Custom Protocols](./Custom-Protocols) -- [Bootstrap](./Bootstrap-&-Evennia) -- [Creating new models](./New-Models) +- [Custom Protocols](./Custom-Protocols.md) +- [Bootstrap](./Bootstrap-&-Evennia.md) +- [Creating new models](./New-Models.md) ## Text processing -- [Change the language of the server](./Internationalization) -- [Server text-encoding](./Text-Encodings) -- [Text tags](./TextTags) +- [Change the language of the server](./Internationalization.md) +- [Server text-encoding](./Text-Encodings.md) +- [Text tags](./TextTags.md) ## Web features -- [Web features](./Web-Features) +- [Web features](./Web-Features.md) diff --git a/docs/source/Concepts/Custom-Protocols.md b/docs/source/Concepts/Custom-Protocols.md index ce1e2567db..72e5c4f073 100644 --- a/docs/source/Concepts/Custom-Protocols.md +++ b/docs/source/Concepts/Custom-Protocols.md @@ -5,9 +5,9 @@ their own custom client protocol.* -A [PortalSession](../Components/Sessions#Portal-and-Server-Sessions) is the basic data object representing an +A [PortalSession](../Components/Sessions.md#portal-and-server-sessions) is the basic data object representing an external -connection to the Evennia [Portal](../Components/Portal-And-Server) -- usually a human player running a mud client +connection to the Evennia [Portal](../Components/Portal-And-Server.md) -- 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*. @@ -27,7 +27,7 @@ You <-> InputFunc ``` -(See the [Message Path](./Messagepath) for the bigger picture of how data flows through Evennia). The +(See the [Message Path](./Messagepath.md) for the bigger picture of how data flows through Evennia). The parts that needs to be customized to make your own custom protocol is the `Protocol + PortalSession` (which translates between data coming in/out over the wire to/from Evennia internal representation) as well as the `InputFunc` (which handles incoming data). @@ -219,11 +219,11 @@ in our case means sending "foo" across the network. ### Receiving data Just because the protocol is there, does not mean Evennia knows what to do with it. An -[Inputfunc](../Components/Inputfuncs) must exist to receive it. In the case of the `text` input exemplified above, +[Inputfunc](../Components/Inputfuncs.md) must exist to receive it. In the case of the `text` input exemplified above, Evennia alredy handles this input - it will parse it as a Command name followed by its inputs. So handle that you need to simply add a cmdset with commands on your receiving Session (and/or the Object/Character it is puppeting). If not you may need to add your own Inputfunc (see the -[Inputfunc](../Components/Inputfuncs) page for how to do this. +[Inputfunc](../Components/Inputfuncs.md) page for how to do this. 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 diff --git a/docs/source/Concepts/Guest-Logins.md b/docs/source/Concepts/Guest-Logins.md index 38076f2027..505310020a 100644 --- a/docs/source/Concepts/Guest-Logins.md +++ b/docs/source/Concepts/Guest-Logins.md @@ -10,16 +10,16 @@ Guest accounts are turned off by default. To activate, add this to your `game/se GUEST_ENABLED = True Henceforth users can use `connect guest` (in the default command set) to login with a guest account. -You may need to change your [Connection Screen](../Components/Connection-Screen) to inform them of this +You may need to change your [Connection Screen](../Components/Connection-Screen.md) to inform them of this possibility. Guest accounts work differently from normal accounts - they are automatically *deleted* whenever the user logs off or the server resets (but not during a reload). They are literally re- usable throw-away accounts. You can add a few more variables to your `settings.py` file to customize your guests: -- `BASE_GUEST_TYPECLASS` - the python-path to the default [typeclass](../Components/Typeclasses) for guests. +- `BASE_GUEST_TYPECLASS` - the python-path to the default [typeclass](../Components/Typeclasses.md) for guests. Defaults to `"typeclasses.accounts.Guest"`. -- `PERMISSION_GUEST_DEFAULT` - [permission level](../Components/Locks) for guest accounts. Defaults to `"Guests"`, +- `PERMISSION_GUEST_DEFAULT` - [permission level](../Components/Locks.md) for guest accounts. Defaults to `"Guests"`, which is the lowest permission level in the hierarchy. - `GUEST_START_LOCATION` - the `#dbref` to the starting location newly logged-in guests should appear at. Defaults to `"#2` (Limbo). diff --git a/docs/source/Concepts/Internationalization.md b/docs/source/Concepts/Internationalization.md index cbd80d1956..994729158e 100644 --- a/docs/source/Concepts/Internationalization.md +++ b/docs/source/Concepts/Internationalization.md @@ -10,7 +10,7 @@ depending on when a given language was last updated. Below are all languages (besides English) with some level of support. Generally, any language not updated after May 2021 will be missing some translations. -```eval_rst +```{eval-rst} +---------------+----------------------+--------------+ | Language Code | Language | Last updated | @@ -56,7 +56,7 @@ Here `'en'` (the default English) should be changed to the abbreviation for one of the supported languages found in `locale/` (and in the list above). Restart the server to activate i18n. -```important:: +```{important} Even for a 'fully translated' language you will still see English text in many places when you start Evennia. This is because we expect you (the @@ -67,7 +67,7 @@ the server to activate i18n. ``` -```sidebar:: Windows users +```{sidebar} Windows users If you get errors concerning `gettext` or `xgettext` on Windows, see the `Django documentation `_ @@ -88,7 +88,7 @@ translation bad ... You are welcome to help improve the situation! To start a new translation you need to first have cloned the Evennia repositry with GIT and activated a python virtualenv as described on the -[Setup Quickstart](../Setup/Setup-Quickstart) page. +[Setup Quickstart](../Setup/Setup-Quickstart.md) page. Go to `evennia/evennia/` - that is, not your game dir, but inside the `evennia/` repo itself. If you see the `locale/` folder you are in the right place. Make diff --git a/docs/source/Concepts/Messagepath.md b/docs/source/Concepts/Messagepath.md index fa14c7d793..3ab28d46a1 100644 --- a/docs/source/Concepts/Messagepath.md +++ b/docs/source/Concepts/Messagepath.md @@ -25,7 +25,7 @@ The client sends data to Evennia in two ways. - When first connecting, the client can send data to the server about its capabilities. This is things like "I support xterm256 but not unicode" and is mainly used when a Telnet client connects. This is called a "handshake" and - will generally set some flags on the [Portal Session](../Components/Portal-And-Server) that + will generally set some flags on the [Portal Session](../Components/Portal-And-Server.md) that are later synced to the Server Session. Since this is not something the player controls, we'll not explore this further here. - The client can send an *inputcommand* to the server. Traditionally this only @@ -34,7 +34,7 @@ The client sends data to Evennia in two ways. the client may send commands based on a timer or some trigger. Exactly how the inputcommand looks when it travels from the client to Evennia -depends on the [Protocol](./Custom-Protocols) used: +depends on the [Protocol](./Custom-Protocols.md) used: - Telnet: A string. If GMCP or MSDP OOB protocols are used, this string will be formatted in a special way, but it's still a raw string. If Telnet SSL is active, the string will be encrypted. @@ -73,7 +73,7 @@ it belongs. This is then sent over the AMP connection. ### ServerSessionHandler (ingoing) On the Server side, the AMP unpickles the data and associates the session id with the server-side -[Session](../Components/Sessions). Data and Session are passed to the server-side `SessionHandler.data_in`. This +[Session](../Components/Sessions.md). Data and Session are passed to the server-side `SessionHandler.data_in`. This in turn calls `ServerSession.data_in()` ### ServerSession (ingoing) @@ -101,7 +101,7 @@ not found, an error will be raised. ### Inputfunc -The [Inputfunc](../Components/Inputfuncs) must be on the form `func(session, *args, **kwargs)`. An exception is +The [Inputfunc](../Components/Inputfuncs.md) must be on the form `func(session, *args, **kwargs)`. An exception is the `default` inputfunc which has form `default(session, cmdname, *args, **kwargs)`, where `cmdname` is the un-matched inputcommand string. @@ -175,7 +175,7 @@ In the *ServerSessionhandler*, the keywords from the `msg` method are collated i This will intelligently convert different input to the same form. So `msg("Hello")` will end up as an outputcommand `("text", ("Hello",), {})`. -This is also the point where [Inlinefuncs](./TextTags#inline-functions) are parsed, depending on the +This is also the point where the [FuncParser](../Components/FuncParser.md)) is applied, depending on the session to receive the data. Said data is pickled together with the Session id then sent over the AMP bridge. diff --git a/docs/source/Concepts/New-Models.md b/docs/source/Concepts/New-Models.md index d1c2ebcfec..e9e936874b 100644 --- a/docs/source/Concepts/New-Models.md +++ b/docs/source/Concepts/New-Models.md @@ -7,7 +7,7 @@ sufficient for most use cases. But if you aim to build a large stand-alone syste your storage requirements into those may be more complex than you bargain for. Examples may be to store guild data for guild members to be able to change, tracking the flow of money across a game- wide economic system or implement other custom game systems that requires the storage of custom data -in a quickly accessible way. Whereas [Tags](../Components/Tags) or [Scripts](../Components/Scripts) can handle many situations, +in a quickly accessible way. Whereas [Tags](../Components/Tags.md) or [Scripts](../Components/Scripts.md) can handle many situations, sometimes things may be easier to handle by adding your own database model. ## Overview of database tables @@ -81,7 +81,7 @@ you put `myapp` and don't forget the comma at the end of the tuple): evennia migrate This will add your new database table to the database. If you have put your game under version -control (if not, [you should](../Coding/Version-Control)), don't forget to `git add myapp/*` to add all items +control (if not, [you should](../Coding/Version-Control.md)), don't forget to `git add myapp/*` to add all items to version control. ## Defining your models @@ -113,7 +113,7 @@ We create four fields: two character fields of limited length and one text field maximum length. Finally we create a field containing the current time of us creating this object. > The `db_date_created` field, with exactly this name, is *required* if you want to be able to store -instances of your custom model in an Evennia [Attribute](../Components/Attributes). It will automatically be set +instances of your custom model in an Evennia [Attribute](../Components/Attributes.md). It will automatically be set upon creation and can after that not be changed. Having this field will allow you to do e.g. `obj.db.myinstance = mydatastore`. If you know you'll never store your model instances in Attributes the `db_date_created` field is optional. diff --git a/docs/source/Concepts/OOB.md b/docs/source/Concepts/OOB.md index 7f175882a7..1e19118eb6 100644 --- a/docs/source/Concepts/OOB.md +++ b/docs/source/Concepts/OOB.md @@ -8,7 +8,7 @@ window pane. ## Briefly on input/outputcommands Inside Evennia, all server-client communication happens in the same way (so plain text is also an -'OOB message' as far as Evennia is concerned). The message follows the [Message Path](./Messagepath). +'OOB message' as far as Evennia is concerned). The message follows the [Message Path](./Messagepath.md). You should read up on that if you are unfamiliar with it. As the message travels along the path it has a standardized internal form: a tuple with a string, a tuple and a dict: @@ -16,9 +16,9 @@ has a standardized internal form: a tuple with a string, a tuple and a dict: This is often referred to as an *inputcommand* or *outputcommand*, depending on the direction it's traveling. The end point for an inputcommand, (the 'Evennia-end' of the message path) is a matching -[Inputfunc](../Components/Inputfuncs). This function is called as `cmdname(session, *args, **kwargs)` where +[Inputfunc](../Components/Inputfuncs.md). This function is called as `cmdname(session, *args, **kwargs)` where `session` is the Session-source of the command. Inputfuncs can easily be added by the developer to -support/map client commands to actions inside Evennia (see the [inputfunc](../Components/Inputfuncs) page for more +support/map client commands to actions inside Evennia (see the [inputfunc](../Components/Inputfuncs.md) page for more details). When a message is outgoing (at the 'Client-end' of the message path) the outputcommand is handled by @@ -26,7 +26,7 @@ a matching *Outputfunc*. This is responsible for converting the internal Evennia form suitable to send over the wire to the Client. Outputfuncs are hard-coded. Which is chosen and how it processes the outgoing data depends on the nature of the client it's connected to. The only time one would want to add new outputfuncs is as part of developing support for a new Evennia -[Protocol](./Custom-Protocols). +[Protocol](./Custom-Protocols.md). ## Sending and receiving an OOB message @@ -59,12 +59,12 @@ drop any other types of outputfuncs. you turn off telnet completely and only rely on the webclient, you should never rely on non-`text` OOB messages always reaching all targets. -[Inputfuncs](../Components/Inputfuncs) lists the default inputfuncs available to handle incoming OOB messages. To +[Inputfuncs](../Components/Inputfuncs.md) lists the default inputfuncs available to handle incoming OOB messages. To accept more you need to add more inputfuncs (see that page for more info). ## Supported OOB protocols -Evennia supports clients using one of the following protocols: +Evennia supports clients using one of the following protocols: ### Telnet @@ -96,7 +96,7 @@ come `foo_bar`. To send a GMCP command that turns into an Evennia inputcommand w underscore, use the `Core` package. So `Core.Cmdname` becomes just `cmdname` in Evennia and vice versa. -On the wire, a GMCP instruction for `("cmdname", ("arg",), {})` will look like this: +On the wire, a GMCP instruction for `("cmdname", ("arg",), {})` will look like this: IAC SB GMCP "cmdname" "arg" IAC SE @@ -105,7 +105,6 @@ where all the capitalized words are telnet character constants specified in these in the listings below. Input/Outputfunc | GMCP-Command ------------------- `[cmd_name, [], {}]` | Cmd.Name `[cmd_name, [arg], {}]` | Cmd.Name arg `[cmd_na_me, [args],{}]` | Cmd.Na.Me [args] @@ -116,15 +115,14 @@ Since Evennia already supplies default inputfuncs that don't match the names exp common GMCP implementations we have a few hard-coded mappings for those: GMCP command name | Input/Outputfunc name ------------------ -"Core.Hello" | "client_options" -"Core.Supports.Get" | "client_options" -"Core.Commands.Get" | "get_inputfuncs" +"Core.Hello" | "client_options" +"Core.Supports.Get" | "client_options" +"Core.Commands.Get" | "get_inputfuncs" "Char.Value.Get" | "get_value" "Char.Repeat.Update" | "repeat" "Char.Monitor.Update" | "monitor" -#### Telnet + MSDP +#### Telnet + MSDP [MSDP](http://tintin.sourceforge.net/msdp/), the *Mud Server Data Protocol*, is a competing standard to GMCP. The MSDP protocol page specifies a range of "recommended" available MSDP command names. @@ -143,7 +141,6 @@ The various available MSDP constants like `VAR` (variable), `VAL` (value), `ARRA and `TABLEOPEN`/`TABLECLOSE` are specified in `evennia/server/portal/telnet_oob`. Outputfunc/Inputfunc | MSDP instruction -------------------------- `[cmdname, [], {}]` | VAR cmdname VAL `[cmdname, [arg], {}]` | VAR cmdname VAL arg `[cmdname, [args],{}]` | VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE @@ -157,7 +154,7 @@ different `VAR ... VAL` (outside a table) will come out as a second, different c ### SSH -SSH only supports the `text` input/outputcommand. +SSH only supports the `text` input/outputcommand. ### Web client diff --git a/docs/source/Concepts/Soft-Code.md b/docs/source/Concepts/Soft-Code.md index 3e11c74e7e..cb78a93da2 100644 --- a/docs/source/Concepts/Soft-Code.md +++ b/docs/source/Concepts/Soft-Code.md @@ -90,5 +90,5 @@ Adding advanced and flexible building commands to your game is easy and will pro 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. The -[in-game-python](../Contribs/Dialogues-in-events) is an optional +[in-game-python](../Contribs/Dialogues-in-events.md) is an optional pseudo-softcode plugin aimed at developers wanting to script their game from inside it. diff --git a/docs/source/Concepts/TextTags.md b/docs/source/Concepts/TextTags.md index 94d13fe22e..e2c22e5fa3 100644 --- a/docs/source/Concepts/TextTags.md +++ b/docs/source/Concepts/TextTags.md @@ -2,18 +2,19 @@ Evennia understands various extra information embedded in text: -- [Colors](./Colors) - Using `|r`, `|n` etc can be used to mark parts of text with a color. The color will +- [Colors](./Colors.md) - Using `|r`, `|n` etc can be used to mark parts of text with a color. The color will become ANSI/XTerm256 color tags for Telnet connections and CSS information for the webclient. -- [Clickable links](./Clickable-Links) - This allows you to provide a text the user can click to execute an +- [Clickable links](./Clickable-Links.md) - This allows you to provide a text the user can click to execute an in-game command. This is on the form `|lc command |lt text |le`. -- [FuncParser callables](../Components/FuncParser) - These are full-fledged function calls on the form `$funcname(args, kwargs)` +- [FuncParser callables](../Components/FuncParser.md) - These are full-fledged function calls on the form `$funcname(args, kwargs)` that lead to calls to Python functions. The parser can be run with different available callables in different circumstances. The parser is run on all outgoing messages if `settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED=True` (disabled by default). -```toctree:: +```{toctree} +:hidden" - Colors.md - Clickable-Links.md - ../Components/FuncParser.md +Colors.md +Clickable-Links.md +../Components/FuncParser.md ``` \ No newline at end of file diff --git a/docs/source/Concepts/Using-MUX-as-a-Standard.md b/docs/source/Concepts/Using-MUX-as-a-Standard.md index 3fce2fd0a5..bd91a82e8e 100644 --- a/docs/source/Concepts/Using-MUX-as-a-Standard.md +++ b/docs/source/Concepts/Using-MUX-as-a-Standard.md @@ -13,7 +13,7 @@ sets for administration and building. Evennia is *not* a MUX system though. It works very differently in many ways. For example, Evennia deliberately lacks an online softcode language (a policy explained on our [softcode policy -page](Soft-Code)). Evennia also does not shy from using its own syntax when deemed appropriate: the +page](./Soft-Code.md)). Evennia also does not shy from using its own syntax when deemed appropriate: the MUX syntax has grown organically over a long time and is, frankly, rather arcane in places. All in all the default command syntax should at most be referred to as "MUX-like" or "MUX-inspired". diff --git a/docs/source/Concepts/Web-Features.md b/docs/source/Concepts/Web-Features.md index 3fce6d31c2..b6841e82d3 100644 --- a/docs/source/Concepts/Web-Features.md +++ b/docs/source/Concepts/Web-Features.md @@ -42,7 +42,7 @@ Example: To override or modify `evennia/web/website/template/website/index.html` add/modify `mygame/web/template_overrides/website/index.html`. The detailed description on how to customize the website is best described in tutorial form. See the -[Web Tutorial](../Howto/Starting/Part5/Web-Tutorial) for more information. +[Web Tutorial](../Howto/Starting/Part5/Web-Tutorial.md) for more information. ### Overloading Django views @@ -103,7 +103,7 @@ you will also log all requests in `mygame/server/logs/http_requests.log`. Evennia comes with a MUD client accessible from a normal web browser. During development you can try it at `http://localhost:4001/webclient`. -[See the Webclient page](../Components/Webclient) for more details. +[See the Webclient page](../Components/Webclient.md) for more details. ## The Django 'Admin' Page diff --git a/docs/source/Concepts/Zones.md b/docs/source/Concepts/Zones.md index 5f6aca82bb..d368b03fb3 100644 --- a/docs/source/Concepts/Zones.md +++ b/docs/source/Concepts/Zones.md @@ -23,7 +23,7 @@ Many MUD codebases hardcode zones as part of the engine and database. Evennia d distinction due to the fact that rooms themselves are meant to be customized to any level anyway. Below is a suggestion for how to implement zones in Evennia. -All objects in Evennia can hold any number of [Tags](../Components/Tags). Tags are short labels that you attach to +All objects in Evennia can hold any number of [Tags](../Components/Tags.md). 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: @@ -47,7 +47,7 @@ Henceforth you can then easily retrieve only objects with a given tag: The tagging or aliasing systems above don't instill any sort of functional difference between a magical forest room and a normal one - they are just arbitrary ways to mark objects for quick -retrieval later. Any functional differences must be expressed using [Typeclasses](../Components/Typeclasses). +retrieval later. Any functional differences must be expressed using [Typeclasses](../Components/Typeclasses.md). 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 diff --git a/docs/source/Contribs/A-voice-operated-elevator-using-events.md b/docs/source/Contribs/A-voice-operated-elevator-using-events.md index 34c16af188..b5e45a8cda 100644 --- a/docs/source/Contribs/A-voice-operated-elevator-using-events.md +++ b/docs/source/Contribs/A-voice-operated-elevator-using-events.md @@ -1,7 +1,7 @@ # A voice operated elevator using events -- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events) +- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events.md) This tutorial will walk you through the steps to create a voice-operated elevator, using the [in- game Python @@ -97,7 +97,7 @@ things to decorate it a bit. But what we want now is to be able to say "1", "2" or "3" and have the elevator move in that direction. -If you have read [the previous tutorial about adding dialogues in events](./Dialogues-in-events), you +If you have read [the previous tutorial about adding dialogues in events](./Dialogues-in-events.md), you may remember what we need to do. If not, here's a summary: we need to run some code when somebody speaks in the room. So we need to create a callback (the callback will contain our lines of code). We just need to know on which event this should be set. You can enter `call here` to see the @@ -433,4 +433,4 @@ to consider adding the code in the source itself. Another possibility is to cal with the expected behavior, which makes porting code very easy. This side of chained events will be shown in the next tutorial. -- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events) \ No newline at end of file +- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events.md) \ No newline at end of file diff --git a/docs/source/Contribs/Arxcode-installing-help.md b/docs/source/Contribs/Arxcode-installing-help.md index 58eb890b88..a49f01bf67 100644 --- a/docs/source/Contribs/Arxcode-installing-help.md +++ b/docs/source/Contribs/Arxcode-installing-help.md @@ -1,6 +1,6 @@ # Arxcode installing help -## Introduction +## Introduction [Arx - After the Reckoning](https://play.arxmush.org/) is a big and very popular [Evennia](https://www.evennia.com)-based game. Arx is heavily roleplaying-centric, relying on game @@ -10,20 +10,20 @@ Arx on github](https://github.com/Arx-Game/arxcode). This is a treasure-trove fo to pick ideas or even get a starting game to build on. These instructions are based on the Arx-code released as of *Aug 12, 2018*. -If you are not familiar with what Evennia is, you can read -[an introduction here](../Evennia-Introduction). +If you are not familiar with what Evennia is, you can read +[an introduction here](../Evennia-Introduction.md). It's not too hard to run Arx from the sources (of course you'll start with an empty database) but since part of Arx has grown organically, it doesn't follow standard Evennia paradigms everywhere. This page covers one take on installing and setting things up while making your new Arx-based game -better match with the vanilla Evennia install. +better match with the vanilla Evennia install. ## Installing Evennia -Firstly, set aside a folder/directory on your drive for everything to follow. +Firstly, set aside a folder/directory on your drive for everything to follow. -You need to start by installing [Evennia](https://www.evennia.com) by following most of the -[Getting Started Instructions](../Setup/Setup-Quickstart) for your OS. The difference is that you need to `git clone +You need to start by installing [Evennia](https://www.evennia.com) by following most of the +[Getting Started Instructions](../Setup/Setup-Quickstart.md) for your OS. The difference is that you need to `git clone https://github.com/TehomCD/evennia.git` instead of Evennia's repo because Arx uses TehomCD's older Evennia 0.8 [fork](https://github.com/TehomCD/evennia), notably still using Python2. This detail is important if referring to newer Evennia documentation. @@ -31,10 +31,10 @@ important if referring to newer Evennia documentation. If you are new to Evennia it's *highly* recommended that you run through the instructions in full - including initializing and starting a new empty game and connecting to it. That way you can be sure Evennia works correctly as a base line. If you have trouble, make sure to -read the [Troubleshooting instructions](./Getting-Started#troubleshooting) for your +read the [Troubleshooting instructions](../Setup/Extended-Installation.md#troubleshooting) for your operating system. You can also drop into our [forums](https://groups.google.com/forum/#%21forum/evennia), join `#evennia` on `irc.freenode.net` -or chat from the linked [Discord Server](https://discord.gg/NecFePw). +or chat from the linked [Discord Server](https://discord.gg/NecFePw). After installing you should have a `virtualenv` running and you should have the following file structure in your set-aside folder: @@ -49,35 +49,35 @@ mygame/ Here `mygame` is the empty game you created during the Evennia install, with `evennia --init`. Go to that and run `evennia stop` to make sure your empty game is not running. We'll instead let Evenna run Arx, so in principle you could erase `mygame` - but it could also be good to have a clean game -to compare to. +to compare to. ## Installing Arxcode ### Clone the arxcode repo -Cd to the root of your directory and clone the released source code from github: +Cd to the root of your directory and clone the released source code from github: - git clone https://github.com/Arx-Game/arxcode.git myarx + git clone https://github.com/Arx-Game/arxcode.git myarx A new folder `myarx` should appear next to the ones you already had. You could rename this to -something else if you want. +something else if you want. -Cd into `myarx`. If you wonder about the structure of the game dir, you can -[read more about it here](../Howto/Starting/Part1/Gamedir-Overview). +Cd into `myarx`. If you wonder about the structure of the game dir, you can +[read more about it here](../Howto/Starting/Part1/Gamedir-Overview.md). ### Clean up settings Arx has split evennia's normal settings into `base_settings.py` and `production_settings.py`. It also has its own solution for managing 'secret' parts of the settings file. We'll keep most of Arx -way but remove the secret-handling and replace it with the normal Evennia method. +way but remove the secret-handling and replace it with the normal Evennia method. Cd into `myarx/server/conf/` and open the file `settings.py` in a text editor. The top part (within `"""..."""`) is just help text. Wipe everything underneath that and make it look like this instead -(don't forget to save): +(don't forget to save): ``` from base_settings import * - + TELNET_PORTS = [4000] SERVERNAME = "MyArx" GAME_SLOGAN = "The cool game" @@ -97,7 +97,7 @@ the game a name. The slogan changes the sub-text shown under the name of your ga header. You can tweak these to your own liking later. Next, create a new, empty file `secret_settings.py` in the same location as the `settings.py` file. -This can just contain the following: +This can just contain the following: ```python SECRET_KEY = "sefsefiwwj3 jnwidufhjw4545_oifej whewiu hwejfpoiwjrpw09&4er43233fwefwfw" @@ -105,35 +105,35 @@ SECRET_KEY = "sefsefiwwj3 jnwidufhjw4545_oifej whewiu hwejfpoiwjrpw09&4er43233fw ``` Replace the long random string with random ASCII characters of your own. The secret key should not -be shared. +be shared. Next, open `myarx/server/conf/base_settings.py` in your text editor. We want to remove/comment out all mentions of the `decouple` package, which Evennia doesn't use (we use `private_settings.py` to -hide away settings that should not be shared). +hide away settings that should not be shared). Comment out `from decouple import config` by adding a `#` to the start of the line: `# from decouple import config`. Then search for `config(` in the file and comment out all lines where this is used. Many of these are specific to the server environment where the original Arx runs, so is not that -relevant to us. +relevant to us. -### Install Arx dependencies +### Install Arx dependencies Arx has some further dependencies beyond vanilla Evennia. Start by `cd`:ing to the root of your -`myarx` folder. +`myarx` folder. > If you run *Linux* or *Mac*: Edit `myarx/requirements.txt` and comment out the line -> `pypiwin32==219` - it's only needed on Windows and will give an error on other platforms. +> `pypiwin32==219` - it's only needed on Windows and will give an error on other platforms. Make sure your `virtualenv` is active, then run pip install -r requirements.txt -The needed Python packages will be installed for you. +The needed Python packages will be installed for you. ### Adding logs/ folder The Arx repo does not contain the `myarx/server/logs/` folder Evennia expects for storing server -logs. This is simple to add: +logs. This is simple to add: # linux/mac mkdir server/logs @@ -142,7 +142,7 @@ logs. This is simple to add: ### Setting up the database and starting -From the `myarx` folder, run +From the `myarx` folder, run evennia migrate @@ -153,7 +153,7 @@ This creates the database and will step through all database migrations needed. If all goes well Evennia will now start up, running Arx! You can connect to it on `localhost` (or `127.0.0.1` if your platform doesn't alias `localhost`), port `4000` using a Telnet client. Alternatively, you can use your web browser to browse to `http://localhost:4001` to see the game's -website and get to the web client. +website and get to the web client. When you log in you'll get the standard Evennia greeting (since the database is empty), but you can try `help` to see that it's indeed Arx that is running. @@ -164,7 +164,7 @@ The first time you start Evennia after creating the database with the `evennia m it should create a few starting objects for you - your superuser account, which it will prompt you to enter, a starting room (Limbo), and a character object for you. If for some reason this does not occur, you may have to follow the steps below. For the first time Superuser login you may have to -run steps 7-8 and 10 to create and connect to your in-came Character. +run steps 7-8 and 10 to create and connect to your in-came Character. 1. Login to the game website with your Superuser account. 2. Press the `Admin` button to get into the (Django-) Admin Interface. @@ -172,17 +172,17 @@ run steps 7-8 and 10 to create and connect to your in-came Character. 4. Add a new Account named for the new staffer. Use a place holder password and dummy e-mail address. 5. Flag account as `Staff` and apply the `Admin` permission group (This assumes you have already set - up an Admin Group in Django). -6. Add Tags named `player` and `developer`. + up an Admin Group in Django). +6. Add Tags named `player` and `developer`. 7. Log into the game using the web client (or a third-party telnet client) using your superuser - account. Move to where you want the new staffer character to appear. + account. Move to where you want the new staffer character to appear. 8. In the game client, run `@create/drop :typeclasses.characters.Character`, where `` is usually the same name you used for the Staffer account you created in the Admin earlier (if you are creating a Character for your superuser, use your superuser account name). This creates a new in-game Character and places it in your current location. 9. Have the new Admin player log into the game. -10. Have the new Admin puppet the character with `@ic StafferName`. +10. Have the new Admin puppet the character with `@ic StafferName`. 11. Have the new Admin change their password - `@password = `. Now that you have a Character and an Account object, there's a few additional things you may need to @@ -225,14 +225,14 @@ cd Source mkdir Arx cd Arx - Replace the SSH git clone links below with your own github forks. - If you don't plan to change Evennia at all, you can use the + Replace the SSH git clone links below with your own github forks. + If you don't plan to change Evennia at all, you can use the evennia/evennia.git repo instead of a forked one. git clone git@github.com:/evennia.git git clone git@github.com:/arxcode.git - Evennia is a package itself, so we want to install it and all of its + Evennia is a package itself, so we want to install it and all of its prerequisites, after switching to the appropriately-tagged branch for Arxcode. @@ -247,7 +247,7 @@ cd ../arxcode pip install -r requirements.txt The git repo doesn't include the empty log directory and Evennia is unhappy if you - don't have it, so while still in the arxcode directory... + don't have it, so while still in the arxcode directory... mkdir server/logs diff --git a/docs/source/Contribs/Contrib-Overview.md b/docs/source/Contribs/Contrib-Overview.md index 5e63369719..24d4ae9d8d 100644 --- a/docs/source/Contribs/Contrib-Overview.md +++ b/docs/source/Contribs/Contrib-Overview.md @@ -1,6 +1,6 @@ # Contrib modules -Contribs are found in [evennia/contrib/](api:evennia.contrib) and are optional game-specific code-snippets +Contribs are found in [evennia/contrib/](evennia.contrib) and are optional game-specific code-snippets or even full systems you can use for your game. They are contributed by the Evennia community and released under the same license as Evennia itself. Each contrib has its own installation instructions. Bugs are reported to the Evennia [issue tracker](github:issue) as usual. @@ -46,7 +46,7 @@ Contribs modifying locations, movement or helping to creating rooms. Adds an XYZgrid to Evennia, with map-display and pathfinding. Created via map strings and maintained outside of the game via Evennia launch commands. -- [XYZGrid documentation](./XYZGrid) +- [XYZGrid documentation](./XYZGrid.md) ### Extended Room @@ -60,7 +60,7 @@ An expanded Room typeclass with multiple descriptions for time and season as wel Build a game area based on a 2D "graphical" unicode map. Supports asymmetric exits. -- [Static in-game map](./Static-In-Game-Map) +- [Static in-game map](./Static-In-Game-Map.md) ### Simple Door @@ -80,7 +80,7 @@ Custom Exit class that takes different time to pass depending on if you are walk Make infinitely large wilderness areas with dynamically created locations. -- [Dynamic in-game map](./Dynamic-In-Game-Map) +- [Dynamic in-game map](./Dynamic-In-Game-Map.md) ---- @@ -100,9 +100,9 @@ A safe and effective barter-system for any game. Allows safe trading of any good A full, extendable crafting system. -- [Crafting overview](./Crafting) -- [Crafting API documentation](api:evennia.contrib.crafting.crafting) -- [Example of a sword crafting tree](api:evennia.contrib.crafting.example_recipes) +- [Crafting overview](./Crafting.md) +- [Crafting API documentation](evennia.contrib.crafting.crafting) +- [Example of a sword crafting tree](evennia.contrib.crafting.example_recipes) ### Dice @@ -174,15 +174,15 @@ A simple system for creating an EvMenu that presents a player with a highly cust Allow Builders to add Python-scripted events to their objects (OBS-not for untrusted users!) -- [A voice-operated elevator using events](./A-voice-operated-elevator-using-events) -- [Dialogues using events](./Dialogues-in-events) +- [A voice-operated elevator using events](./A-voice-operated-elevator-using-events.md) +- [Dialogues using events](./Dialogues-in-events.md) ### Menu-builder A tool for building using an in-game menu instead of the normal build commands. Meant to be expanded for the needs of your game. -- [Building Menus](./Building-menus) +- [Building Menus](./Building-menus.md) ### Security/Auditing @@ -271,7 +271,7 @@ A folder of basic example objects, commands and scripts. The Evennia single-player sole quest. Made to be analyzed to learn. -- [The tutorial world introduction](../Howto/Starting/Part1/Tutorial-World-Introduction) +- [The tutorial world introduction](../Howto/Starting/Part1/Tutorial-World-Introduction.md) ---- @@ -300,7 +300,7 @@ is maintained by Tehom in its own repository so bug reports should be directed t - [Arxcode repository on github](https://github.com/Arx-Game/arxcode) - [Arxcode issue tracker](https://github.com/Arx-Game/arxcode/issues) -- [Arxcode installation help](./Arxcode-installing-help) - this may not always be fully up-to-date with +- [Arxcode installation help](./Arxcode-installing-help.md) - this may not always be fully up-to-date with latest Evennia. Report your findings! ### Evscaperoom @@ -310,7 +310,7 @@ is maintained by Tehom in its own repository so bug reports should be directed t A full engine for making multiplayer 'escape-rooms' completely in code. This is based on the 2019 MUD Game jam winner *Evscaperoom*. -- [contrib/evscaperoom](api:evennia.contrib.evscaperoom) - game engine to make your own escape rooms. +- [contrib/evscaperoom](evennia.contrib.evscaperoom) - game engine to make your own escape rooms. - [https://demo.evennia.com](https://demo.evennia.com) - a full installation of the original game can be played by entering the *evscaperoom* exit in the first Limbo room. - https://github.com/Griatch/evscaperoom - the original game's source code (warning for spoilers if you @@ -319,17 +319,17 @@ This is based on the 2019 MUD Game jam winner *Evscaperoom*. -```toctree:: - :hidden: +```{toctree} +:hidden: - ./Crafting - ../api/evennia.contrib.crafting.crafting - ../api/evennia.contrib.crafting.example_recipes - ./A-voice-operated-elevator-using-events - ./Dialogues-in-events - ./Dynamic-In-Game-Map - ./Static-In-Game-Map - ../Howto/Starting/Part1/Tutorial-World-Introduction - ./Building-menus +./Crafting +../api/evennia.contrib.crafting.crafting +../api/evennia.contrib.crafting.example_recipes +./A-voice-operated-elevator-using-events +./Dialogues-in-events +./Dynamic-In-Game-Map +./Static-In-Game-Map +../Howto/Starting/Part1/Tutorial-World-Introduction +./Building-menus ``` diff --git a/docs/source/Contribs/Crafting.md b/docs/source/Contribs/Crafting.md index 7b2950e23f..41834de110 100644 --- a/docs/source/Contribs/Crafting.md +++ b/docs/source/Contribs/Crafting.md @@ -1,14 +1,14 @@ # Crafting system contrib _Contrib by Griatch 2020_ -```versionadded:: 1.0 +```{versionadded} 1.0 ``` This contrib implements a full Crafting system that can be expanded and modified to fit your game. -- See the [evennia/contrib/crafting/crafting.py API](api:evennia.contrib.crafting.crafting) for installation +- See the [evennia/contrib/crafting/crafting.py API](evennia.contrib.crafting.crafting) for installation instructrions. -- See the [sword example](api:evennia.contrib.crafting.example_recipes) for an example of how to design +- See the [sword example](evennia.contrib.crafting.example_recipes) for an example of how to design a crafting tree for crafting a sword from base elements. From in-game it uses the new `craft` command: @@ -45,7 +45,7 @@ result = craft(caller, "recipename", *inputs) ``` Here, `caller` is the one doing the crafting and `*inputs` is any combination of consumables and/or tool -Objects. The system will identify which is which by the [Tags](../Components/Tags) on them (see below) +Objects. The system will identify which is which by the [Tags](../Components/Tags.md) on them (see below) The `result` is always a list. ## Adding new recipes @@ -84,7 +84,7 @@ class WoodenPuppetRecipe(CraftingRecipe): ``` -This specifies which tags to look for in the inputs. It defines a [Prototype](../Components/Prototypes) +This specifies which tags to look for in the inputs. It defines a [Prototype](../Components/Prototypes.md) for the recipe to use to spawn the result on the fly (a recipe could spawn more than one result if needed). Instead of specifying the full prototype-dict, you could also just provide a list of `prototype_key`s to existing prototypes you have. @@ -93,7 +93,7 @@ After reloading the server, this recipe would now be available to use. To try it create materials and tools to insert into the recipe. -The recipe analyzes inputs, looking for [Tags](../Components/Tags) with specific tag-categories. +The recipe analyzes inputs, looking for [Tags](../Components/Tags.md) with specific tag-categories. The tag-category used can be set per-recipe using the (`.consumable_tag_category` and `.tool_tag_category` respectively). The defaults are `crafting_material` and `crafting_tool`. For the puppet we need one object with the `wood` tag and another with the `knife` tag: @@ -152,7 +152,7 @@ in `settings.CRAFTING_RECIPE_MODULES`. Even without modifying more than the class properties, there are a lot of options to set on the `CraftingRecipe` class. Easiest is to refer to the -[CraftingRecipe api documentation](evennia.contrib.crafting.crafting.html#evennia.contrib.crafting.crafting.CraftingRecipe). +[CraftingRecipe api documentation](evennia.contrib.crafting.crafting.CraftingRecipe). For example, you can customize the validation-error messages, decide if the ingredients have to be exactly right, if a failure still consumes the ingredients or not, and much more. @@ -211,7 +211,7 @@ if we succed. We would of course make this a lot more immersive and detailed in principle you could customize each recipe just the way you want it, but you could also inherit from a central parent like this to cut down on work. -The [sword recipe example module](api:evennia.contrib.crafting.example_recipes) also shows an example +The [sword recipe example module](evennia.contrib.crafting.example_recipes) also shows an example of a random skill-check being implemented in a parent and then inherited for multiple use. ## Even more customization diff --git a/docs/source/Contribs/Dynamic-In-Game-Map.md b/docs/source/Contribs/Dynamic-In-Game-Map.md index 5ec9d43407..0f249cb37c 100644 --- a/docs/source/Contribs/Dynamic-In-Game-Map.md +++ b/docs/source/Contribs/Dynamic-In-Game-Map.md @@ -4,7 +4,7 @@ ## Introduction An often desired feature in a MUD is to show an in-game map to help navigation. The [Static in-game -map](Static-In-Game-Map) tutorial solves this by creating a *static* map, meaning the map is pre- +map](./Static-In-Game-Map.md) tutorial solves this by creating a *static* map, meaning the map is pre- drawn once and for all - the rooms are then created to match that map. When walking around, parts of the static map is then cut out and displayed next to the room description. @@ -20,9 +20,9 @@ world to be 'logically' impossible with rooms looping to themselves or exits lea side of the map. Exits can also be named anything, from "jumping out the window" to "into the fifth dimension". This tutorial assumes you can only move in the cardinal directions (N, E, S and W). 2. Rooms must be connected and linked together for the map to be generated correctly. Vanilla -Evennia comes with a admin command [@tunnel](../Components/Default-Command-Help#tunnel-cmdtunnel) that allows a +Evennia comes with a admin command [tunnel](evennia.commands.default.building.CmdTunnel) that allows a user to create rooms in the cardinal directions, but additional work is needed to assure that rooms -are connected. For example, if you `@tunnel east` and then immediately do `@tunnel west` you'll find +are connected. For example, if you `tunnel east` and then immediately do `tunnel west` you'll find that you have created two completely stand-alone rooms. So care is needed if you want to create a "logical" layout. In this tutorial we assume you have such a grid of rooms that we can generate the map from. @@ -361,7 +361,7 @@ looping rooms that will show on your in-game map. The above example will display the map above the room description. You could also use an [EvTable](github:evennia.utils.evtable) to place description and map next to each other. Some other -things you can do is to have a [Command](../Components/Commands) that displays with a larger radius, maybe with a +things you can do is to have a [Command](../Components/Commands.md) that displays with a larger radius, maybe with a legend and other features. Below is the whole `map.py` for your reference. You need to update your `Room` typeclass (see above) diff --git a/docs/source/Contribs/Static-In-Game-Map.md b/docs/source/Contribs/Static-In-Game-Map.md index ae480fd436..afa49f12d8 100644 --- a/docs/source/Contribs/Static-In-Game-Map.md +++ b/docs/source/Contribs/Static-In-Game-Map.md @@ -4,8 +4,8 @@ ## Introduction This tutorial describes the creation of an in-game map display based on a pre-drawn map. It also -details how to use the [Batch code processor](../Components/Batch-Code-Processor) for advanced building. There is -also the [Dynamic in-game map tutorial](./Dynamic-In-Game-Map) that works in the opposite direction, +details how to use the [Batch code processor](../Components/Batch-Code-Processor.md) for advanced building. There is +also the [Dynamic in-game map tutorial](./Dynamic-In-Game-Map.md) that works in the opposite direction, by generating a map from an existing grid of rooms. Evennia does not require its rooms to be positioned in a "logical" way. Your exits could be named @@ -41,7 +41,7 @@ map we designed before. ``` We will henceforth assume your game folder is name named `mygame` and that you haven't modified the -default commands. We will also not be using [Colors](../Concepts/TextTags#colored-text) for our map since they +default commands. We will also not be using [Colors](../Concepts/Colors.md) for our map since they don't show in the documentation wiki. ## Planning the Map @@ -83,23 +83,23 @@ planning at this stage can solve many problems before they happen. In this section we will try to create an actual "map" object that an account can pick up and look at. -Evennia offers a range of [default commands](api:evennia.commands.default#modules) for -[creating objects and rooms in-game](../Howto/Starting/Part1/Building-Quickstart). While readily accessible, these commands are made to do very +Evennia offers a range of [default commands](../Components/Default-Commands.md) for +[creating objects and rooms in-game](../Howto/Starting/Part1/Building-Quickstart.md). While readily accessible, these commands are made to do very specific, restricted things and will thus not offer as much flexibility to experiment (for an -advanced exception see [in-line functions](../Concepts/TextTags#new-inlinefuncs)). Additionally, entering long +advanced exception see [the FuncParser](../Components/FuncParser.md)). Additionally, entering long descriptions and properties over and over in the game client can become tedious; especially when testing and you may want to delete and recreate things over and over. -To overcome this, Evennia offers [batch processors](../Components/Batch-Processors) that work as input-files +To overcome this, Evennia offers [batch processors](../Components/Batch-Processors.md) that work as input-files created out-of-game. In this tutorial we'll be using the more powerful of the two available batch -processors, the [Batch Code Processor ](../Components/Batch-Code-Processor), called with the `@batchcode` command. +processors, the [Batch Code Processor ](../Components/Batch-Code-Processor.md), called with the `@batchcode` command. This is a very powerful tool. It allows you to craft Python files to act as blueprints of your entire game world. These files have access to use Evennia's Python API directly. Batchcode allows for easy editing and creation in whatever text editor you prefer, avoiding having to manually build the world line-by-line inside the game. > Important warning: `@batchcode`'s power is only rivaled by the `@py` command. Batchcode is so -powerful it should be reserved only for the [superuser](../Concepts/Building-Permissions). Think carefully +powerful it should be reserved only for the [superuser](../Concepts/Building-Permissions.md). Think carefully before you let others (such as `Developer`- level staff) run `@batchcode` on their own - make sure you are okay with them running *arbitrary Python code* on your server. @@ -412,5 +412,5 @@ easily new game defining features can be added to Evennia. You can easily build from this tutorial by expanding the map and creating more rooms to explore. Why not add more features to your game by trying other tutorials: [Add weather to your world](Weather- -Tutorial), [fill your world with NPC's](../Howto/Tutorial-Aggressive-NPCs) or -[implement a combat system](../Howto/Starting/Part3/Turn-based-Combat-System). +Tutorial), [fill your world with NPC's](../Howto/Tutorial-Aggressive-NPCs.md) or +[implement a combat system](../Howto/Starting/Part3/Turn-based-Combat-System.md). diff --git a/docs/source/Contribs/XYZGrid.md b/docs/source/Contribs/XYZGrid.md index 4fc3975619..72132ce13a 100644 --- a/docs/source/Contribs/XYZGrid.md +++ b/docs/source/Contribs/XYZGrid.md @@ -1,6 +1,6 @@ # XYZGrid contrib -```versionadded:: 1.0 +```{versionadded} 1.0 ``` This optional contrib adds a 'coordinate grid' to Evennia. It allows for @@ -66,7 +66,7 @@ Exits: northeast and east available for use as prototype-parents when spawning the grid. 4. Run `evennia xyzgrid help` for available options. 5. (Optional): By default, the xyzgrid will only spawn module-based - [prototypes](../Components/Prototypes). This is an optimization and usually makes sense + [prototypes](../Components/Prototypes.md). This is an optimization and usually makes sense since the grid is entirely defined outside the game anyway. If you want to also make use of in-game (db-) created prototypes, add `XYZGRID_USE_DB_PROTOTYPES = True` to settings. @@ -79,11 +79,11 @@ The grid contrib consists of multiple components. 1. The `XYMap` - This class parses modules with special _Map strings_ and _Map legends_ into one Python object. It has helpers for pathfinding and visual-range handling. -2. The `XYZGrid` - This is a singleton [Script](../Components/Scripts) that +2. The `XYZGrid` - This is a singleton [Script](../Components/Scripts.md) that stores all `XYMaps` in the game. It is the central point for managing the 'grid' of the game. 3. `XYZRoom` and `XYZExit`are custom typeclasses that use - [Tags](../Components/Tags) + [Tags](../Components/Tags.md) to know which X,Y,Z coordinate they are located at. The `XYZGrid` is abstract until it is used to _spawn_ these database entities into something you can actually interract with in the game. The `XYZRoom` @@ -102,7 +102,7 @@ After installation, do the following from your command line (where the $ evennia xyzgrid init use `evennia xyzgrid help` to see all options) -This will create a new `XYZGrid` [Script](../Components/Scripts) if one didn't already exist. +This will create a new `XYZGrid` [Script](../Components/Scripts.md) if one didn't already exist. The `evennia xyzgrid` is a custom launch option added only for this contrib. The xyzgrid-contrib comes with a full grid example. Let's add it: @@ -120,7 +120,7 @@ about each map with the `show` subcommand: $ evennia xyzgrid show "the small cave" If you want to peek at how the grid's code, open -[evennia/contrib/xyzgrid/example.py](api:evennia.contrib.xyzgrid.example). +[evennia/contrib/xyzgrid/example.py](evennia.contrib.xyzgrid.example). (We'll explain the details in later sections). So far the grid is 'abstract' and has no actual in-game presence. Let's @@ -430,9 +430,9 @@ LEGEND = { The legend is optional, and any symbol not explicitly given in your legend will fall back to its value in the default legend [outlined below](#default-legend). -- [MapNode](api:evennia.contrib.xyzgrid.xymap_legend#evennia.contrib.xyzgrid.xymap_legend.MapNode) +- [MapNode](evennia.contrib.xyzgrid.xymap_legend.MapNode) is the base class for all nodes. -- [MapLink](api:evennia.contrib.xyzgrid.xymap_legend#evennia.contrib.xyzgrid.xymap_legend.MapLink) +- [MapLink](evennia.contrib.xyzgrid.xymap_legend.MapLink) is the base class for all links. As the _Map String_ is parsed, each found symbol is looked up in the legend and @@ -445,7 +445,7 @@ with a full set of map elements that use these properties in various ways (described in the next section). Some useful properties of the -[MapNode](api:evennia.contrib.xyzgrid.xymap_legend#evennia.contrib.xyzgrid.xymap_legend.MapNode) +[MapNode](evennia.contrib.xyzgrid.xymap_legend.MapNode) class (see class doc for hook methods): - `symbol` (str) - The character to parse from the map into this node. By default this @@ -473,7 +473,7 @@ class (see class doc for hook methods): useful for various reasons, mostly map-transitions). Some useful properties of the -[MapLink](api:evennia.contrib.xyzgrid.xymap_legend#evennia.contrib.xyzgrid.xymap_legend.MapLink) +[MapLink](evennia.contrib.xyzgrid.xymap_legend.MapLink) class (see class doc for hook methods): - `symbol` (str) - The character to parse from the map into this node. This must @@ -551,7 +551,7 @@ actually visualized when displaying the map to players in-game. This could have colors etc. All classes are found in `evennia.contrib.xyzgrid.xymap_legend` and their names are included to make it easy to know what to override. -```eval_rst +```{eval-rst} ============= ============== ==== =================== ========================================= symbol display-symbol type class description ============= ============== ==== =================== ========================================= @@ -921,11 +921,11 @@ across the map boundary. ### Prototypes -[Prototypes](../Components/Prototypes) are dicts that describe how to _spawn_ a new instance +[Prototypes](../Components/Prototypes.md) are dicts that describe how to _spawn_ a new instance of an object. Each of the _nodes_ and _links_ above have a default prototype that allows the `evennia xyzgrid spawn` command to convert them to -a [XYZRoom](api:evennia.contrib.xyzgrid.xyzroom#XYZRoom) -or an [XYZExit](api:evennia.contrib.xyzgrid.xyzroom#XYZExit) respectively. +a [XYZRoom](evennia.contrib.xyzgrid.xyzroom.XYZRoom) +or an [XYZExit](evennia.contrib.xyzgrid.xyzroom.XYZRoom) respectively. The default prototypes are found in `evennia.contrib.xyzgrid.prototypes` (added during installation of this contrib), with `prototype_key`s `"xyz_room"` and @@ -1167,7 +1167,7 @@ a location if they know that location's name. Here are some details about ## XYZGrid -The `XYZGrid` is a [Global Script](../Components/Scripts) that holds all `XYMap` objects on +The `XYZGrid` is a [Global Script](../Components/Scripts.md) that holds all `XYMap` objects on the grid. There should be only one XYZGrid created at any time. To access the grid in-code, there are several ways: @@ -1216,17 +1216,17 @@ know how to call find the pathfinder though: - `xymap.get_shortest_path(start_xy, end_xy)` - `xymap.get_visual_range(xy, dist=2, **kwargs)` -See the [XYMap](api:evennia.contrib.xyzgrid.xymap#XYMap) documentation for +See the [XYMap](xymap) documentation for details. ## XYZRoom and XYZExit -These are new custom [Typeclasses](../Components/Typeclasses) located in +These are new custom [Typeclasses](../Components/Typeclasses.md) located in `evennia.contrib.xyzgrid.xyzroom`. They extend the base `DefaultRoom` and `DefaultExit` to be aware of their `X`, `Y` and `Z` coordinates. -```warning:: +```{warning} You should usually **not** create XYZRooms/Exits manually. They are intended to be created/deleted based on the layout of the grid. So to add a new room, add @@ -1253,7 +1253,7 @@ Useful (extra) properties on `XYZRoom`, `XYZExit`: - `xyz_destination` (only for `XYZExits`) - this gives the xyz-coordinate of the exit's destination. -The coordinates are stored as [Tags](../Components/Tags) where both rooms and exits tag +The coordinates are stored as [Tags](../Components/Tags.md) where both rooms and exits tag categories `room_x_coordinate`, `room_y_coordinate` and `room_z_coordinate` while exits use the same in addition to tags for their destination, with tag categories `exit_dest_x_coordinate`, `exit_dest_y_coordinate` and @@ -1293,7 +1293,7 @@ exit = XYZExit.objects.get_xyz_exit(xyz=(0, 12, 'foo'), xyz_destination=(5, 2, ' You can customize the XYZRoom/Exit by having the grid spawn your own subclasses of them. To do this you need to override the prototype used to spawn rooms on the grid. Easiest is to modify the base prototype-parents in settings (see the -[Extending the base prototypes](#extending-the-base-prototypes) section above). +[XYZRoom and XYZExit](#xyzroom-and-xyzexit) section above). ## Working with the grid diff --git a/docs/source/Contributing-Docs.md b/docs/source/Contributing-Docs.md index 6b45bd6ca4..903fe91e2c 100644 --- a/docs/source/Contributing-Docs.md +++ b/docs/source/Contributing-Docs.md @@ -1,23 +1,30 @@ # Contributing to Evennia Docs -```warning:: - WARNING: This system is still WIP and many things are bound to change! +```{warning} +This system is still WIP and many things are bound to change! ``` -Contributing to the docs is is like [contributing to the rest of Evennia][contributing]: Check out the branch of Evennia you want to edit the documentation for. Create your -own work-branch, make your changes to files in `evennia/docs/source/` and make a PR for it! +Contributing to the docs is is like [contributing to the rest of Evennia][contributing]: Check out the branch of Evennia +you want to edit the documentation for. Create your own work-branch, make your changes to files +in `evennia/docs/source/` and make a PR for it! The documentation source files are `*.md` (Markdown) files found in `evennia/docs/source/`. Markdown files are simple text files that can be edited with a normal text editor. They can also -contain raw HTML directives (but that is very rarely needed). They primarly use -the [Markdown][commonmark] syntax. See [the syntax section below](#Editing-syntax) for more help. +contain raw HTML directives (but that is very rarely needed). They use +the [Markdown][commonmark] syntax with [MyST extensions][MyST]. + +```{important} +You do _not_ need to be able to test/build the docs locally to contribute a documentation PR. +We'll resolve any issues when we merge and build documentation. If you still want to build +the docs for yourself, instructions are [at the end of this document](#building-the-docs-locally). +``` ## Source file structure The sources are organized into several rough categories, with only a few administrative documents at the root of `evennia/docs/source/`. The folders are named in singular form since they will -primarily be accessed as link refs (e.g. `Component/Account`) +primarily be accessed as link refs (e.g. `Component/Accounts`) - `source/Components/` are docs describing separate Evennia building blocks, that is, things that you can import and use. This extends and elaborates on what can be found out by reading @@ -42,14 +49,459 @@ primarily be accessed as link refs (e.g. `Component/Account`) Other files and folders: - `source/api/` contains the auto-generated API documentation as `.rst` files. Don't edit these files manually, your changes will be lost. To refer to these files, use `api:` followed by - the Python path, for example `[rpsystem contrib](api:evennia.contrib.rpsystem)`. + the Python path, for example `[rpsystem contrib](evennia.contrib.rpsystem)`. - `source/_templates` and `source/_static` should not be modified unless adding a new doc-page feature or changing the look of the HTML documentation. - `conf.py` holds the Sphinx configuration. It should usually not be modified except to update the Evennia version on a new branch. -## Building the docs locally +# Editing syntax + +The format used for Evennia's docs is [Markdown][commonmark-help] (Commonmark). While markdown +supports a few alternative forms for some of these, we try to stick to the below forms for consistency. + +## Italic/Bold + +We generally use underscores for italics and double-asterisks for bold: + +- `_Italic text_` - _Italic text_ +- `**Bold Text**` - **Bold text** + +## Headings + +We use `#` to indicate sections/headings. The more `#` the more of a sub-heading it is (will get +smaller and smaller font). + +- `# Heading` +- `## SubHeading` +- `### SubSubHeading` +- `#### SubSubSubHeading` + +> Don't use the same heading/subheading name more than once in one page. While Markdown +does not prevent it, it will make it impossible to refer to that heading uniquely. +The Evennia documentation preparser will detect this and give you an error. + +## Lists + +One can create both bullet-point lists and numbered lists: + +``` +- first bulletpoint +- second bulletpoint +- third bulletpoint +``` + +- first bulletpoint +- second bulletpoint +- third bulletpoint + +``` +1. Numbered point one +2. Numbered point two +3. Numbered point three +``` + +1. Numbered point one +2. Numbered point two +3. Numbered point three + +## Blockquotes + +A blockquote will create an indented block. It's useful for emphasis and is +added by starting one or more lines with `>`. For 'notes' you can also use +an explicit [Note](#note). + +``` +> This is an important +> thing to remember. +``` + +> Note: This is an important +> thing to remember. + +## Links + +The link syntax is `[linktext](url_or_ref)` - this gives a clickable link [linktext](#links). + +### Internal links + +Most links will be to other pages of the documentation or to Evennia's API docs. Each document +heading can be referenced. The reference always starts with `#`. The heading-name is always +given in lowercase and ignores any non-letters. Spaces in the heading title are replaced with +a single dash `-`. + +As an example, let's assume the following is the contents of a file `Menu-stuff.md`: + +``` +# Menu items + +Some text... + +## A yes/no? example + +Some more text... +``` + +- From _inside the same file_ you can refer to each heading as + + [menus](#menu-items) + [example](#a-yesno-example) + +- From _another file_, you reference them as as + + [menus](Menu-Stuff.md#menu-items) + [example](Menu-Stuff.md#a-yesno-example) + +> It's fine to not include the `.md` file ending in the reference. The Evennia doc-build process +> will correct for this (and also insert any needed relative paths in the reference). + +### API links + +The documentation contains auto-generated documentation for all of Evennia's source code. You +can direct the reader to the sources by just giving the python-path to the location of the +resource under the `evennia/` repository: + + [DefaultObject](evennia.objects.objects.DefaultObject) + +[DefaultObject](evennia.objects.objects.DefaultObject) <- like this! + +Note that you can't refer to files in the `mygame` folder this way. The game folder is generated +dynamically and is not part of the api docs. Refer to the parent classes in `evennia` where possible. + +### External links + +These are links to resources outside of the documentation. We also provide some convenient shortcuts. + +- `[linkname](https://evennia.com)` - link to an external website. +- `[linkname](github:evennia/objects/objects.py)` - this is a shortcut to point to a location in the + official Evennia repository on Github. Note that you must use `/` and give the full file name. By + default this is code in the `master` branch. +- `[linkname](github:develop/evennia/objects.objects.py` - this points to code in the `develop` branch. +- `[make an issue](github:issue)` - this is a shortcut to the Evennia github issue-creation page. + +> Note that if you want to refer to code, it's usually better to [link to the API](#api-links) as +> described above. + +### Urls/References in one place + +Urls can get long and if you are using the same url/reference in many places it can get a +little cluttered. So you can also put the url as a 'footnote' at the end of your document. +You can then refer to it by putting your reference within square brackets `[ ]`. Here's an example: + +``` +This is a [clickable link][mylink]. This is [another link][1]. + +... + + +[mylink]: http://... +[1]: My-Document.md#this-is-a-long-ref + +``` + +This makes the main text a little shorter. + +## Tables + +A table is done like this: + +```` +| heading1 | heading2 | heading3 | +| --- | --- | --- | +| value1 | value2 | value3 | +| | value 4 | | +| value 5 | value 6 | | +```` + +| heading1 | heading2 | heading3 | +| --- | --- | --- | +| value1 | value2 | value3 | +| | value 4 | | +| value 5 | value 6 | | + +As seen, the Markdown syntax can be pretty sloppy (columns don't need to line up) as long as you +include the heading separators and make sure to add the correct number of `|` on every line. + + +## Verbatim text + +It's common to want to mark something to be displayed verbatim - just as written - without any +Markdown parsing. In running text, this is done using backticks (\`), like \`verbatim text\` becomes +`verbatim text`. + +If you want to put the verbatim text on its own line, you can do so easily by simply indenting +it 4 spaces (add empty lines on each side for readability too): + +``` +This is normal text + + This is verbatim text + +This is normal text +``` + +Another way is to use triple-backticks: + +```` +``` +Everything within these backticks will be verbatim. + +``` +```` + +### Code blocks + +A special 'verbatim' case is code examples - we want them to get code-highlighting for readability. +This is done by using the triple-backticks and specify which language we use: + +```` +```python +from evennia import Command +class CmdEcho(Command): + """ + Usage: echo + """ + key = "echo" + def func(self): + self.caller.msg(self.args.strip()) +``` +```` + +```python +from evennia import Command +class CmdEcho(Command): + """ + Usage: echo + """ + key = "echo" + def func(self): + self.caller.msg(self.args.strip()) +``` + +## MyST directives + +Markdown is easy to read and use. But while it does most of what we need, there are some things it's +not quite as expressive as it needs to be. For this we use extended [MyST][MyST] syntax. This is +on the form + +```` +```{directive} any_options_here + +content + +``` +```` + + +#### Note + +This kind of note may pop more than doing a `> Note: ...`. + +```` +```{note} + +This is some noteworthy content that stretches over more than one line to show how the content indents. +Also the important/warning notes indents like this. + +``` +```` + +```{note} + +This is some noteworthy content that stretches over more than one line to show how the content indents. +Also the important/warning notes indents like this. + +``` + +### Important + +This is for particularly important and visible notes. + +```` +```{important} + This is important because it is! +``` + +```` +```{important} + This is important because it is! +``` + +### Warning + +A warning block is used to draw attention to particularly dangerous things, or features easy to +mess up. + +```` +```{warning} + Be careful about this ... +``` +```` + +```{warning} + Be careful about this ... +``` + +### Version changes and deprecations + +These will show up as one-line warnings that suggest an added, changed or deprecated +feature beginning with particular version. + +```` +```{versionadded} 1.0 +``` +```` + +```{versionadded} 1.0 +``` + +```` +```{versionchanged} 1.0 + How the feature changed with this version. +``` +```` + +```{versionchanged} 1.0 + How the feature changed with this version. +``` + +```` +```{deprecated} 1.0 +``` +```` + +```{deprecated} 1.0 +``` + +### Sidebar + +This will display an informative sidebar that floats to the side of regular content. This is useful +for example to remind the reader of some concept relevant to the text. + +```` +```{sidebar} Things to remember + +- There can be bullet lists +- in here. + +Separate sections with + +an empty line. +``` +```` + +```{sidebar} Things to remember + +- There can be bullet lists +- in here. + +Separate sections with + +an empty line. +``` + +Hint: If wanting to make sure to have the next header appear on a row of its own (rather than +squeezed to the left of the sidebar), one can embed a plain HTML string in the markdown like so: + +```html +
+``` + +
+ +### A more flexible code block + +The regular Markdown Python codeblock is usually enough but for more direct control over the style, one +can also use the `{code-block}` directive that takes a set of additional `:options:`: + +```` +```{code-block} python +:linenos: +:emphasize-lines: 1-2,8 +:caption: An example code block +:name: A full code block example + +from evennia import Command +class CmdEcho(Command): + """ + Usage: echo + """ + key = "echo" + def func(self): + self.caller.msg(self.args.strip()) +``` +```` + +```{code-block} python +:linenos: +:emphasize-lines: 1-2,8 +:caption: An example code block +:name: A full code block example + +from evennia import Command +class CmdEcho(Command): + """ + Usage: echo + """ + key = "echo" + def func(self): + self.caller.msg(self.args.strip()) +``` +Here, `:linenos:` turns on line-numbers and `:emphasize-lines:` allows for emphasizing certain lines +in a different color. The `:caption:` shows an instructive text and `:name:` is used to reference +this +block through the link that will appear (so it should be unique for a given document). + + + +### eval-rst directive + +As a last resort, we can also fall back to writing [ReST][ReST] directives directly: + + +```` +```{eval-rst} + + This will be evaluated as ReST. + All content must be indented. + +``` +```` + +Within a ReST block, one must use Restructured Text syntax, which is not the +same as Markdown. + +- Single backticks around text makes it _italic_. +- Double backticks around text makes it `verbatim`. +- A link is written within back-ticks, with an underscore at the end: + + `python `_ + +[Here is a ReST formatting cheat sheet](https://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html). + +## Code docstrings + +The source code docstrings will be parsed as Markdown. When writing a module docstring, you can use Markdown formatting, +including header levels down to 4th level (`#### SubSubSubHeader`). After the module documentation it's +a good idea to end with four dashes `----`. This will create a visible line between the documentation and the +class/function docs to follow. See for example [the Traits docs](evennia.contrib.traits). + +All non-private classes, methods and functions must have a Google-style docstring, as per the +[Evennia coding style guidelines][github:evennia/CODING_STYLE.md]. This will then be correctly formatted +into pretty api docs. + +## Technical + +Evennia leverages [Sphinx][sphinx] with the [MyST][MyST] extension, which allows us +to write our docs in light-weight Markdown (more specifically [CommonMark][commonmark], like on github) +rather than Sphinx' normal ReST syntax. The `MyST` parser allows for some extra syntax to +make us able to express more complex displays than plain Markdown can. + +For [autodoc-generation][sphinx-autodoc] generation, we use the sphinx-[napoleon][sphinx-napoleon] +extension to understand our friendly Google-style docstrings used in classes and functions etc. + +# Building the docs locally The sources in `evennia/docs/source/` are built into a documentation using the [Sphinx][sphinx] static generator system. To do this locally you need to use a @@ -103,7 +555,7 @@ initialize a new game with a default database (you don't need to have any server running) - It's recommended that you use a virtualenv. Install your cloned version of Evennia into -by pointing to the repo folder (the one containing `/docs`): + by pointing to the repo folder (the one containing `/docs`): ``` pip install -e evennia @@ -112,14 +564,14 @@ by pointing to the repo folder (the one containing `/docs`): - Make sure you are in the parent folder _containing_ your `evennia/` repo (so _two_ levels up from `evennia/docs/`). - Create a new game folder called exactly `gamedir` at the same level as your `evennia` -repo with + repo with ``` evennia --init gamedir ``` - Then `cd` into it and create a new, empty database. You don't need to start the -game or do any further changes after this. + game or do any further changes after this. ``` evennia migrate @@ -177,7 +629,7 @@ specific official Evennia branches will be built, so you can't use this to build your own testing branch. - All local changes must have been committed to git first, since the versioned -docs are built by looking at the git tree. + docs are built by looking at the git tree. - To build for local checking, run (`mv` stands for "multi-version"): ``` @@ -209,494 +661,21 @@ on `github`. So there is no risk of you releasing your local changes accidentall After deployment finishes, the updated live documentation will be available at https://evennia.github.io/evennia/latest/. -# Editing syntax -The format used for Evennia's docs is [Markdown][commonmark-help] (Commonmark). While markdown -supports a -few alternative forms for some of these, we try to stick to the below forms for consistency. -### Italic/Bold - -We generally use underscores for italics and double-asterisks for bold: - -- `_Italic text_` - _Italic text_ -- `**Bold Text**` - **Bold text** - -### Headings - -We use `#` to indicate sections/headings. The more `#` the more of a sub-heading it is (will get -smaller and smaller font). - -- `# Heading` -- `## SubHeading` -- `### SubSubHeading` -- `#### SubSubSubHeading` - -> Don't use the same heading/subheading name more than once in one page. While Markdown -does not prevent it, it will make it impossible to refer to that heading uniquely. -The Evennia documentation preparser will detect this and give you an error. - -### Lists - -One can create both bullet-point lists and numbered lists: - -``` -- first bulletpoint -- second bulletpoint -- third bulletpoint -``` - -- first bulletpoint -- second bulletpoint -- third bulletpoint - -``` -1. Numbered point one -2. Numbered point two -3. Numbered point three -``` - -1. Numbered point one -2. Numbered point two -3. Numbered point three - -### Blockquotes - -A blockquote will create an indented block. It's useful for emphasis and is -added by starting one or more lines with `>`. For 'notes' you can also use -an explicit [Note](#Note). - -``` -> This is an important -> thing to remember. -``` - -> Note: This is an important -> thing to remember. - -### Links - -- `[linktext](url_or_ref)` - gives a clickable link [linktext][linkdemo]. - -The `url_or_ref` can either be a full `http://...` url or an internal _reference_. For example, use -`[my document](My-Document)` to link to the document `evennia/docs/source/My-Document.md`. Avoid -using -full `http://` linking unless really referring to an external resource. - -- `[linktext](ref#heading-name)` - -You can point to sub-sections (headings) in a document by using a single `#` and the name of the -heading, replacing spaces with dashes. So to refer to a heading `## Cool Stuff` inside `My-Document` -would be a link `[cool stuff](My-Document#Cool-Stuff)`. This is why headings must be uniquely named -within on document. - -- `[linktext][linkref]` - refer to a reference defined later in the document. - -Urls can get long and if you are using the same url in many places it can get a little cluttered. So -you can also put the url as a 'footnote' at the end of your document -and refer to it by putting your reference within square brackets `[ ]`. Here's an example: - -``` -This is a [clickable link][mylink]. This is [another link][1]. - -... - - -[mylink]: http://... -[1]: My-Document - -``` - -#### Special references - -The Evennia documentation supports some special reference shortcuts in links: - -##### Github online repository - -- `github:` - a shortcut for the full path to the Evennia repository on github. This must be given -with forward-slashes and include the `.py` file ending. It will refer to the `master` branch by default: - - [link to objects.py](github:evennia/objects/objects.py) - - This will remap to https://github.com/evennia/evennia/blob/master/evennia/objects/objects.py. -- To refer to the `develop` branch, start the url with `develop/`: - - [link to objects.py](github:develop/evennia/objects/objects.py) - -##### API - -- `api:` - references a path in the api documentation. This is specified as a Python-path: - - [link to api for objects.py](api:evennia.objects) - - This will create a link to the auto-generated `evennia/source/api/evennia.objects.rst` document. - - Since api-docs are generated alongside the documentation, this will always be the api docs for - the current version/branch of the docs. - -##### Bug reports/feature request - - -- `github:issue` - links to the github issue selection page, where the user can choose which type of - issue to create. - - If you find a problem, make a [bug report](github:issue)! - - This will generate a link to https://github.com/evennia/evennia/issues/new/choose. - -### Verbatim text - -It's common to want to mark something to be displayed verbatim - just as written - without any -Markdown parsing. In running text, this is done using backticks (\`), like \`verbatim text\` becomes -`verbatim text`. - -If you want to put the verbatim text on its own line, you can do so easily by simply indenting -it 4 spaces (add empty lines on each side for readability too): - -``` -This is normal text - - This is verbatim text - -This is normal text -``` - -Another way is to use triple-backticks: - -```` -``` -Everything within these backticks will be verbatim. - -``` -```` - -### Code blocks - -A special case is code examples - we want them to get code-highlighting for readability. This is -done by using -the triple-backticks and specify which language we use: - -```` -```python - -def a_python_func(x): - return x * x - -``` -```` - -```python - -def a_python_func(x): - return x * x - -``` - -### ReST blocks - -Markdown is easy to read and use. But while it does most of what we need, there are some things it's -not quite as expressive as it needs to be. For this we need to fall back to the [ReST][ReST] markup -language which the documentation system uses under the hood. This is done by specifying `eval_rst` -as the name of the `language` of a literal block: - -```` -```eval_rst - - This will be evaluated as ReST. - All content must be indented. - -``` -```` - -There is also a short-hand form for starting a [ReST directive][ReST-directives] without need for -`eval_rst`: - -```` -```directive:: possible-option - - Content *must* be indented for it to be included in the directive. - - New lines are ignored, empty lines starts a new paragraph. -``` -```` - -Within a ReST block, one must use Restructured Text syntax, which is not the -same as Markdown. - -- Single backticks around text makes it _italic_. -- Double backticks around text makes it `verbatim`. -- A link is written within back-ticks, with an underscore at the end: - - `python `_ - -[Here is a ReST formatting cheat sheet](https://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html). - -Below are examples of ReST-block structures. - -#### Note - -This kind of note may pop more than doing a `> Note: ...`. Contrary to a -[blockquote](#Blockquotes), the end result will not be indented. - -```` -```note:: - - Remember that you have to indent this content for it to be part of the note. - -``` -```` - - -```note:: - - Remember that you have to indent this content for it to be part of the note. - -``` - -#### Important - -This is for particularly important and visible notes. - -```` -```important:: - This is important because it is! -``` - -```` -```important:: - This is important because it is! -``` - -#### Warning - -A warning block is used to draw attention to particularly dangerous things, or features easy to -mess up. - -```` -```warning:: - Be careful about this ... -``` -```` - -```warning:: - Be careful about this ... -``` - -#### Version changes and deprecations - -These will show up as one-line warnings that suggest an added, changed or deprecated -feature beginning with particular version. - -```` -```versionadded:: 1.0 -``` -```` - -```versionadded:: 1.0 -``` - -```` -```versionchanged:: 1.0 - How the feature changed with this version. -``` -```` - -```versionchanged:: 1.0 - How the feature changed with this version. -``` - -```` -```deprecated:: 1.0 -``` -```` - -```deprecated:: 1.0 -``` - -#### Sidebar - -This will display an informative sidebar that floats to the side of regular content. This is useful -for example to remind the reader of some concept relevant to the text. - -```` -```sidebar:: Things to remember - - - There can be bullet lists - - in here. - - Headers: - with indented blocks like this - Will end up: - as full sub-headings in the sidebar. -``` -```` - -```sidebar:: Things to remember - - - There can be bullet lists - - in here. - - Headers: - with indented blocks like this - Will end up: - as full sub-headings in the sidebar. -``` -Remember that for ReST-directives, the content within the triple-backticks _must_ be indented to -some degree or the content will just appear outside of the directive as regular text. - -If wanting to make sure to have the next header appear on a row of its own, one can embed -a plain HTML string in the markdown like so: - -```html -
-``` - -
- -#### Tables - -A table is specified using [ReST table syntax][ReST-tables] (they don't need to be indented): -```` -```eval_rst - -===== ===== ======= -A B A and B -===== ===== ======= -False False False -True False False -False True False -True True True -===== ===== ======= -``` -```` - -```eval_rst - -===== ===== ======= -A B A and B -===== ===== ======= -False False False -True False False -False True False -True True True -===== ===== ======= -``` - -or the more flexible but verbose - -```` -```eval_rst -+------------------------+------------+----------+----------+ -| Header row, column 3 | Header 2 | Header 3 | Header 4 | -| (header rows optional) | | | | -+========================+============+==========+==========+ -| body row 1, column 1 | column 2 | column 3 | column 4 | -+------------------------+------------+----------+----------+ -| body row 2 | ... | ... | | -+------------------------+------------+----------+----------+ -``` -```` - -```eval_rst -+------------------------+------------+----------+----------+ -| Header row, column 3 | Header 2 | Header 3 | Header 4 | -| (header rows optional) | | | | -+========================+============+==========+==========+ -| body row 1, column 1 | column 2 | column 3 | column 4 | -+------------------------+------------+----------+----------+ -| body row 2 | ... | ... | | -+------------------------+------------+----------+----------+ -``` - -#### A more flexible code block - -The regular Markdown Python codeblock is usually enough but for more direct control over the style, one -can also specify the code block explicitly in `ReST` for more flexibility. -It also provides a link to the code block, identified by its name. - - -```` -```code-block:: python - :linenos: - :emphasize-lines: 1-2,8 - :caption: An example code block - :name: A full code block example - - from evennia import Command - class CmdEcho(Command): - """ - Usage: echo - """ - key = "echo" - def func(self): - self.caller.msg(self.args.strip()) -``` -```` - -```code-block:: python - :linenos: - :emphasize-lines: 1-2,8 - :caption: An example code block - :name: A full code block example - - from evennia import Command - class CmdEcho(Command): - """ - Usage: echo - """ - key = "echo" - def func(self): - self.caller.msg(self.args.strip()) -``` -Here, `:linenos:` turns on line-numbers and `:emphasize-lines:` allows for emphasizing certain lines -in a different color. The `:caption:` shows an instructive text and `:name:` is used to reference -this -block through the link that will appear (so it should be unique for a give document). - -> The default markdown syntax will actually generate a code-block ReST instruction like this -> automatically for us behind the scenes. But the automatic generation can't know things like emphasize- -lines or captions since that's not a part of the Markdown specification. - -## Code documentation - -The source code docstrings will be parsed as Markdown. When writing a module docstring, you can use Markdown formatting, -including header levels down to 4th level (`#### SubSubSubHeader`). After the module documentation it's -a good idea to end with four dashes `----`. This will create a visible line between the documentation and the -class/function docs to follow. See for example [the Traits docs](api:evennia.contrib.traits). - -All non-private classes, methods and functions must have a Google-style docstring, as per the -[Evennia coding style guidelines][github:evennia/CODING_STYLE.md]. This will then be correctly formatted -into pretty api docs. - -## Technical - -Evennia leverages [Sphinx][sphinx] with the [recommonmark][recommonmark] extension, which allows us -to write our -docs in light-weight Markdown (more specifically [CommonMark][commonmark], like on github) rather -than ReST. -The recommonmark extension however also allows us to use ReST selectively in the places were it is -more -expressive than the simpler (but much easier) Markdown. - -For [autodoc-generation][sphinx-autodoc] generation, we use the sphinx-[napoleon][sphinx-napoleon] -extension -to understand our friendly Google-style docstrings used in classes and functions etc. - - - -[sphinx](https://www.sphinx-doc.org/en/master/) -[recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) -[commonmark](https://spec.commonmark.org/current/) -[commonmark-help](https://commonmark.org/help/) -[sphinx-autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#module-sphinx.ext.autodoc) -[sphinx-napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html) +[sphinx]: https://www.sphinx-doc.org/en/master/ +[MyST]: https://myst-parser.readthedocs.io/en/latest/syntax/reference.html +[commonmark]: https://spec.commonmark.org/current/ +[commonmark-help]: https://commonmark.org/help/ +[sphinx-autodoc]: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#module-sphinx.ext.autodoc +[sphinx-napoleon]: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html [getting-started]: Setup/Setup-Quickstart [contributing]: ./Contributing -[ReST](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) -[ReST-tables](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#tables) -[ReST-directives](https://www.sphinx-doc.org/en/master/usage/restruturedtext/directives.html) -[Windows-WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10) +[ReST]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html +[ReST-tables]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#tables +[ReST-directives]: https://www.sphinx-doc.org/en/master/usage/restruturedtext/directives.html +[Windows-WSL]: https://docs.microsoft.com/en-us/windows/wsl/install-win10 [linkdemo]: #Links -[retext](https://github.com/retext-project/retext) -[grip](https://github.com/joeyespo/grip) -[pycharm](https://www.jetbrains.com/pycharm/) +[retext]: https://github.com/retext-project/retext +[grip]: https://github.com/joeyespo/grip +[pycharm]: https://www.jetbrains.com/pycharm/ \ No newline at end of file diff --git a/docs/source/Contributing.md b/docs/source/Contributing.md index e79503e40d..3172682971 100644 --- a/docs/source/Contributing.md +++ b/docs/source/Contributing.md @@ -90,9 +90,9 @@ a new `README.md` file within that directory. amount of game-style-specific code. Assume your code will be applied to a very different game than you had in mind when creating it. * To make the licensing situation clear we assume all contributions are released with the same -[license as Evennia](./Licensing). If this is not possible for some reason, talk to us and we'll +[license as Evennia](./Licensing.md). If this is not possible for some reason, talk to us and we'll handle it on a case-by-case basis. -* Your contribution must be covered by [unit tests](Coding/Unit-Testing). Having unit tests will both help +* Your contribution must be covered by [unit tests](Coding/Unit-Testing.md). Having unit tests will both help make your code more stable and make sure small changes does not break it without it being noticed, it will also help us test its functionality and merge it quicker. If your contribution is a single module, you can add your unit tests to `evennia/contribs/tests.py`. If your contribution is bigger diff --git a/docs/source/Evennia-API.md b/docs/source/Evennia-API.md index ab405079a2..4cb829e8df 100644 --- a/docs/source/Evennia-API.md +++ b/docs/source/Evennia-API.md @@ -1,19 +1,19 @@ # API Summary -[evennia](api:evennia) - library root -- [evennia.accounts](api:evennia.accounts) - the out-of-character entities representing players -- [evennia.commands](api:evennia.commands) - handle all inputs. Also includes default commands -- [evennia.comms](api:evennia.comms) - in-game channels and messaging -- [evennia.contrib](api:evennia.contrib) - game-specific tools and code contributed by the community -- [evennia.help](api:evennia.help) - in-game help system -- [evennia.locks](api:evennia.locks) - limiting access to various systems and resources -- [evennia.objects](api:evennia.objects) - all in-game entities, like Rooms, Characters, Exits etc -- [evennia.prototypes](api:evennia.prototypes) - customize entities using dicts -- [evennia.scripts](api:evennia.scripts) - all out-of-character game objects -- [evennia.server](api:evennia.server) - core Server and Portal programs, also network protocols -- [evennia.typeclasses](api:evennia.typeclasses) - core database-python bridge -- [evennia.utils](api:evennia.utils) - lots of useful coding tools and utilities -- [evennia.web](api:evennia.web) - webclient, website and other web resources +[evennia](api/evennia-api.md) - library source tree +- [evennia.accounts](evennia.accounts) - the out-of-character entities representing players +- [evennia.commands](evennia.commands) - handle all inputs. Also includes default commands +- [evennia.comms](evennia.comms) - in-game channels and messaging +- [evennia.contrib](evennia.contrib) - game-specific tools and code contributed by the community +- [evennia.help](evennia.help) - in-game help system +- [evennia.locks](evennia.locks) - limiting access to various systems and resources +- [evennia.objects](evennia.objects) - all in-game entities, like Rooms, Characters, Exits etc +- [evennia.prototypes](evennia.prototypes) - customize entities using dicts +- [evennia.scripts](evennia.scripts) - all out-of-character game objects +- [evennia.server](evennia.server) - core Server and Portal programs, also network protocols +- [evennia.typeclasses](evennia.typeclasses) - core database-python bridge +- [evennia.utils](evennia.utils) - lots of useful coding tools and utilities +- [evennia.web](evennia.web) - webclient, website and other web resources ## Shortcuts @@ -28,71 +28,70 @@ The flat API is defined in `__init__.py` [viewable here](github:evennia/__init__ ### Search functions -- [evennia.search_account](api:evennia.utils.search#evennia.utils.search.search_account) -- [evennia.search_object](api:evennia.utils.search#evennia.utils.search.search_object) -- [evennia.search_object_by_tag](api:evennia.utils.search#evennia.utils.search_object_by_tag) -- [evennia.search_script](api:evennia.utils.search#evennia.utils.search_script) -- [evennia.search_channel](api:evennia.utils.search#evennia.utils.search_channel) -- [evennia.search_message](api:evennia.utils.search#evennia.utils.search_message) -- [evennia.search_help](api:evennia.utils.search#evennia.utils.search.search_help) +- [evennia.search_account](evennia.utils.search.search_account) +- [evennia.search_object](evennia.utils.search.search_object) +- [evennia.search_tag](evennia.utils.search.search_tag) +- [evennia.search_script](evennia.utils.search.search_script) +- [evennia.search_channel](evennia.utils.search.search_channel) +- [evennia.search_message](evennia.utils.search.search_message) +- [evennia.search_help](evennia.utils.search.search_help_entry) ### Create functions -- [evennia.create_account](api:evennia.utils.create#evennia.utils.create.create_account) -- [evennia.create_object](api:evennia.utils.create#evennia.utils.create.create_object) -- [evennia.create_script](api:evennia.utils.create#evennia.utils.create.create_script) -- [evennia.create_channel](api:evennia.utils.create#evennia.utils.create.create_channel) -- [evennia.create_help_entry](api:evennia.utils.create#evennia.utils.create.create_help_entry) -- [evennia.create_message](api:evennia.utils.create#evennia.utils.create.create_message) +- [evennia.create_account](evennia.utils.create.create_account) +- [evennia.create_object](evennia.utils.create.create_object) +- [evennia.create_script](evennia.utils.create.create_script) +- [evennia.create_channel](evennia.utils.create.create_channel) +- [evennia.create_help_entry](evennia.utils.create.create_help_entry) +- [evennia.create_message](evennia.utils.create.create_message) ### Typeclasses -- [evennia.Defaultaccount](api:evennia.accounts.accounts#evennia.accounts.accounts.DefaultAccount) - player account class ([docs](Components/Accounts)) -- [evennia.DefaultGuest](api:evennia.accounts.accounts#evennia.accounts.accounts.DefaultGuest) - base guest account class -- [evennia.DefaultObject](api:evennia.objects.objects#evennia.objects.objects.DefaultObject) - base class for all objects ([docs](Components/Objects)) -- [evennia.DefaultCharacter](api:evennia.objects.objects#evennia.objects.objects.DefaultCharacter) - base class for in-game characters ([docs](Components/Objects#Character)) -- [evennia.DefaultRoom](api:evennia.objects.objects#evennia.objects.objects.DefaultRoom) - base class for rooms ([docs](Components/Objects#Room)) -- [evennia.DefaultExit](api:evennia.objects.objects#evennia.objects.objects.DefaultExit) - base class for exits ([docs](Components/Objects#Exit)) -- [evennia.DefaultScript](api:evennia.scripts.scripts#evennia.scripts.scripts.DefaultScript) - base class for OOC-objects ([docs](Components/Scripts)) -- [evennia.DefaultChannel](api:evennia.comms.comms#evennia.comms.comms.DefaultChannel) - base class for in-game channels ([docs](Components/Channels)) +- [evennia.Defaultaccount](evennia.accounts.accounts.DefaultAccount) - player account class ([docs](Components/Accounts.md)) +- [evennia.DefaultGuest](evennia.accounts.accounts.DefaultGuest) - base guest account class +- [evennia.DefaultObject](evennia.objects.objects.DefaultObject) - base class for all objects ([docs](Components/Objects.md)) +- [evennia.DefaultCharacter](evennia.objects.objects.DefaultCharacter) - base class for in-game characters ([docs](Components/Objects.md#characters)) +- [evennia.DefaultRoom](evennia.objects.objects.DefaultRoom) - base class for rooms ([docs](Components/Objects.md#rooms)) +- [evennia.DefaultExit](evennia.objects.objects.DefaultExit) - base class for exits ([docs](Components/Objects.md#exits)) +- [evennia.DefaultScript](evennia.scripts.scripts.DefaultScript) - base class for OOC-objects ([docs](Components/Scripts.md)) +- [evennia.DefaultChannel](evennia.comms.comms.DefaultChannel) - base class for in-game channels ([docs](Components/Channels.md)) ### Commands -- [evennia.Command](api:evennia.commands.command#evennia.commands.command.Command) - base [Command](Components/Commands) class. See also `evennia.default_cmds.MuxCommand` -- [evennia.CmdSet](api:evennia.commands.cmdset#evennia.commands.cmdset.CmdSet) - base [Cmdset](Components/Command-Sets) class -- [evennia.default_cmds](api:Default-Command-Help) - access all default command classes as properties +- [evennia.Command](evennia.commands.command.Command) - base [Command](Components/Commands.md) class. See also `evennia.default_cmds.MuxCommand` +- [evennia.CmdSet](evennia.commands.cmdset.CmdSet) - base [CmdSet](Components/Command-Sets.md) class +- [evennia.default_cmds](Components/Default-Commands.md) - access all default command classes as properties -- [evennia.syscmdkeys](api:Commands#System-Commands) - access system command keys as properties +- [evennia.syscmdkeys](Components/Commands.md#system-commands) - access system command keys as properties ### Utilities -- [evennia.utils.utils](api:evennia.utils.utils) - mixed useful utilities -- [evennia.gametime](api:evennia.utils.gametime) - server run- and game time ([docs](Components/Coding-Utils#gametime)) -- [evennia.logger](api:evennia.utils.logger) - logging tools -- [evennia.ansi](api:evennia.utils.ansi) - ansi coloring tools -- [evennia.spawn](api:evennia.prototypes.spawner#evennia.prototypes.spawner.Spawn) - spawn/prototype system ([docs](Components/Prototypes)) -- [evennia.lockfuncs](api:evennia.locks.lockfuncs) - default lock functions for access control ([docs](Components/Locks)) -- [evennia.EvMenu](api:evennia.utils.evmenu#evennia.utils.evmenu.EvMenu) - menu system ([docs](Components/EvMenu)) -- [evennia.EvTable](api:evennia.utils.evtable#evennia.utils.evtable.EvTable) - text table creater -- [evennia.EvForm](api:evennia.utils.evform#evennia.utils.evform.EvForm) - text form creator +- [evennia.utils.utils](evennia.utils.utils) - mixed useful utilities +- [evennia.gametime](evennia.utils.gametime.TimeScript) - server run- and game time ([docs](Components/Coding-Utils.md#game-time)) +- [evennia.logger](evennia.utils.logger) - logging tools +- [evennia.ansi](evennia.utils.ansi) - ansi coloring tools +- [evennia.spawn](evennia.prototypes.spawner.spawn) - spawn/prototype system ([docs](Components/Prototypes.md)) +- [evennia.lockfuncs](evennia.locks.lockfuncs) - default lock functions for access control ([docs](Components/Locks.md)) +- [evennia.EvMenu](evennia.utils.evmenu.EvMenu) - menu system ([docs](Components/EvMenu.md)) +- [evennia.EvTable](evennia.utils.evtable.EvTable) - text table creater +- [evennia.EvForm](evennia.utils.evform.EvForm) - text form creator - Evennia.EvMore - text paginator -- [evennia.EvEditor](api:evennia.utils.eveditor#evennia.utils.eveditor.EvEditor) - in game text line editor ([docs](Components/EvEditor)) -- [evennia.utils.funcparser.Funcparser](api:evennia.utils.funcparser) - inline parsing of functions ([docs](Components/FuncParser)) +- [evennia.EvEditor](evennia.utils.eveditor.EvEditor) - in game text line editor ([docs](Components/EvEditor.md)) +- [evennia.utils.funcparser.Funcparser](evennia.utils.funcparser.FuncParser) - inline parsing of functions ([docs](Components/FuncParser.md)) ### Global singleton handlers -- [evennia.TICKER_HANDLER](api:evennia.scripts.tickerhandler) - allow objects subscribe to tickers ([docs](Components/TickerHandler)) -- [evennia.MONITOR_HANDLER](api:evennia.scripts.monitorhandler) - monitor changes ([docs](Components/MonitorHandler)) -- [evennia.CHANNEL_HANDLER](api:evennia.comms.channelhandler) - maintains channels -- [evennia.SESSION_HANDLER](api:evennia.server.serverhandler) - manages all sessionsmain session handler +- [evennia.TICKER_HANDLER](evennia.scripts.tickerhandler.TickerHandler) - allow objects subscribe to tickers ([docs](Components/TickerHandler.md)) +- [evennia.MONITOR_HANDLER](evennia.scripts.monitorhandler.MonitorHandler) - monitor changes ([docs](Components/MonitorHandler.md)) +- [evennia.SESSION_HANDLER](evennia.server.sessionhandler.SessionHandler) - manages all sessionsmain session handler ### Database core models (for more advanced lookups) -- [evennia.ObjectDB](api:evennia.objects.models#evennia.objects.models.ObjectDB) -- [evennia.accountDB](api:evennia.accounts.models#evennia.accounts.models.AccountDB) -- [evennia.ScriptDB](api:evennia.scripts.models#evennia.scripts.models.ScriptDB) -- [evennia.ChannelDB](api:evennia.channels.models#evennia.channels.models.ChannelDB) -- [evennia.Msg](api:evennia.comms.models#evennia.comms.models.Msg) +- [evennia.ObjectDB](evennia.objects.models.ObjectDB) +- [evennia.accountDB](evennia.accounts.models.AccountDB) +- [evennia.ScriptDB](evennia.scripts.models.ScriptDB) +- [evennia.ChannelDB](evennia.comms.models.ChannelDB) +- [evennia.Msg](evennia.comms.models.Msg) - evennia.managers - contains shortcuts to all database managers ### Contributions diff --git a/docs/source/Evennia-Introduction.md b/docs/source/Evennia-Introduction.md index fb80e19c79..7ecceb7f5d 100644 --- a/docs/source/Evennia-Introduction.md +++ b/docs/source/Evennia-Introduction.md @@ -26,7 +26,7 @@ Evennia is *fully persistent*, that means things you drop on the ground somewher there a dozen server reboots later. Through Django we support a large variety of different database systems (a database is created for you automatically if you use the defaults). -We also include a growing list of *optional* [contribs](Contribs/Contrib-Overview) you can use for your game +We also include a growing list of *optional* [contribs](Contribs/Contrib-Overview.md) you can use for your game would you want something to build from. Using the full power of Python throughout the server offers some distinct advantages. All your @@ -38,7 +38,7 @@ implementations indeed. Out of the box, Evennia gives you a 'talker'-type of game; you can walk around, chat, build rooms and objects, do basic roleplaying and administration. The server ships with a default set of player commands that are similar to the MUX command set. We *do not* aim specifically to be a MUX server, but we had to pick some -default to go with (see [this](Concepts/Soft-Code) for more about our original motivations). It's easy to +default to go with (see [this](Concepts/Soft-Code.md) for more about our original motivations). It's easy to remove or add commands, or to have the command syntax mimic other systems, like Diku, LP, MOO and so on. Or why not create a new and better command system of your own design. @@ -49,11 +49,11 @@ connect to the demo via your telnet client you can do so at `demo.evennia.com`, Once you installed Evennia yourself it comes with its own tutorial - this shows off some of the possibilities _and_ gives you a small single-player quest to play. The tutorial takes only one -single in-game command to install as explained [here](Howto/Starting/Part1/Tutorial-World-Introduction). +single in-game command to install as explained [here](Howto/Starting/Part1/Tutorial-World-Introduction.md). ## What you need to know to work with Evennia -Assuming you have Evennia working (see the [quick start instructions](Setup/Setup-Quickstart)) and have +Assuming you have Evennia working (see the [quick start instructions](Setup/Setup-Quickstart.md)) and have gotten as far as to start the server and connect to it with the client of your choice, here's what you need to know depending on your skills and needs. @@ -71,11 +71,11 @@ Evennia's source code is extensively documented and is [viewable online](https://github.com/evennia/evennia). We also have a comprehensive [online manual](https://evennia.com/docs) with lots of examples. But while Python is considered a very easy programming language to get into, you do have a learning curve to climb if -you are new to programming. Evennia's [Starting-tutorial](Howto/Starting/Part1/Starting-Part1) has a [basic introduction -to Python](Howto/Starting/Part1/Python-basic-introduction) but you should probably also sit down +you are new to programming. Evennia's [Starting-tutorial](Howto/Starting/Part1/Starting-Part1.md) has a [basic introduction +to Python](Howto/Starting/Part1/Python-basic-introduction.md) but you should probably also sit down with a full Python beginner's tutorial at some point (there are plenty of them on the web if you look around). See also our [link -page](Links#wiki-litterature) for some reading suggestions. To efficiently code your dream game in +page](./Links.md) for some reading suggestions. To efficiently code your dream game in Evennia you don't need to be a Python guru, but you do need to be able to read example code containing at least these basic Python features: @@ -92,8 +92,8 @@ programming](https://www.tutorialspoint.com/python/python_classes_objects.htm), [Classes](https://docs.python.org/tutorial/classes.html), their methods and properties Obviously, the more things you feel comfortable with, the easier time you'll have to find your way. -With just basic knowledge you should be able to define your own [Commands](Components/Commands), create custom -[Objects](Components/Objects) as well as make your world come alive with basic [Scripts](Components/Scripts). You can +With just basic knowledge you should be able to define your own [Commands](Components/Commands.md), create custom +[Objects](Components/Objects.md) as well as make your world come alive with basic [Scripts](Components/Scripts.md). You can definitely build a whole advanced and customized game from extending Evennia's examples only. ### I know my Python stuff and I am willing to use it! @@ -110,8 +110,8 @@ presence (a website and a mud web client) to play around with ... ### Where to from here? -From here you can continue browsing the [online documentation]([online documentation](index:Evennia-documentation)) to -find more info about Evennia. Or you can jump into the [Tutorials](Howto/Howto-Overview) and get your hands +From here you can continue browsing the [online documentation](./index.md) to +find more info about Evennia. Or you can jump into the [Tutorials](Howto/Howto-Overview.md) and get your hands dirty with code right away. You can also read the lead developer's [dev blog](https://evennia.blogspot.com/) for many tidbits and snippets about Evennia's development and structure. @@ -124,9 +124,9 @@ chat](https://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE on IRC. This allows you to chat directly with other developers new and old as well as with the devs of Evennia itself. This chat is logged (you can find links on https://www.evennia.com) and can also be searched from the same place for discussion topics you are interested in. -2. Read the [Game Planning](Howto/Starting/Part2/Game-Planning) wiki page. It gives some ideas for your work flow and the +2. Read the [Game Planning](Howto/Starting/Part2/Game-Planning.md) wiki page. It gives some ideas for your work flow and the state of mind you should aim for - including cutting down the scope of your game for its first release. -3. Do the [Tutorial for basic MUSH-like game](Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game) carefully from +3. Do the [Tutorial for basic MUSH-like game](Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game.md) carefully from beginning to end and try to understand what does what. Even if you are not interested in a MUSH for your own game, you will end up with a small (very small) game that you can build or learn from. diff --git a/docs/source/Glossary.md b/docs/source/Glossary.md index 7039f75c18..cfdfaf4ff6 100644 --- a/docs/source/Glossary.md +++ b/docs/source/Glossary.md @@ -1,105 +1,106 @@ # Glossary -This explains common recurring terms used in the Evennia docs. It will be expanded as needed. +This explains common recurring terms used in the Evennia docs. It will be expanded as needed. -- _[account](./Glossary#account)_ - the player's account on the game -- _[admin-site](./Glossary#admin-site)_ - the Django web page for manipulating the database -- _[attribute](./Glossary#attribute)_ - persistent, custom data stored on typeclasses -- _[channel](./Glossary#channel)_ - game communication channels -- _[character](./Glossary#character)_ - the player's avatar in the game, controlled from -_[account](./Glossary#account)_ -- _[core](./Glossary#core)_ - a term used for the code distributed with Evennia proper -- _[django](./Glossary#django)_ - web framework Evennia uses for database access and web integration -- _[field](./Glossary#field)_ - a _[typeclass](./Glossary#typeclass)_ property representing a database +- _[account](./Glossary.md#account)_ - the player's account on the game +- _[admin-site](./Glossary.md#admin-site)_ - the Django web page for manipulating the database +- _[attribute](./Glossary.md#attribute)_ - persistent, custom data stored on typeclasses +- _[channel](./Glossary.md#channel)_ - game communication channels +- _[character](./Glossary.md#character)_ - the player's avatar in the game, controlled from +_[account](./Glossary.md#account)_ +- _[contrib](./Glossary.md#contrib)_ - a term used for optional code contributed by the community. +- _[core](./Glossary.md#core)_ - a term used for the code distributed with Evennia proper +- _[django](./Glossary.md#django)_ - web framework Evennia uses for database access and web integration +- _[field](./Glossary.md#field)_ - a _[typeclass](./Glossary.md#typeclass)_ property representing a database column -- _[git](./Glossary#git)_ - the version-control system we use -- _[github](./Glossary#github)_ - the online hosting of our source code -- _[migrate](./Glossary#migrate)_ - updating the database schema +- _[git](./Glossary.md#git)_ - the version-control system we use +- _[github](./Glossary.md#github)_ - the online hosting of our source code +- _[migrate](./Glossary.md#migrate)_ - updating the database schema - _[multisession mode`](#multisession-mode)_ - a setting defining how users connect to Evennia -- _[object](./Glossary#object)_ - Python instance, general term or in-game -_[typeclass](./Glossary#typeclass)_ -- _[pip](./Glossary#pip)_ - the Python installer +- _[object](./Glossary.md#object)_ - Python instance, general term or in-game +_[typeclass](./Glossary.md#typeclass)_ +- _[pip](./Glossary.md#pip)_ - the Python installer - _player_ - the human connecting to the game with their client -- _[puppet](./Glossary#puppet)_ - when an [account](./Glossary#account) controls an in-game -[object](./Glossary#object) -- _[property](./Glossary#property)_ - a python property -- _evenv_ - see _[virtualenv](./Glossary#virtualenv)_ -- _[repository](./Glossary#repository)_ - a store of source code + source history -- _[script](./Glossary#script)_ - a building block for custom storage, systems and time-keepint -- _[session](./Glossary#session)_ - represents one client connection -- _[ticker](./Glossary#ticker)_ - Allows to run events on a steady 'tick' -- _[twisted](./Glossary#twisted)_ - networking engine responsible for Evennia's event loop and +- _[puppet](./Glossary.md#puppet)_ - when an [account](./Glossary.md#account) controls an in-game +[object](./Glossary.md#object) +- _[property](./Glossary.md#property)_ - a python property +- _evenv_ - see _[virtualenv](./Glossary.md#virtualenv)_ +- _[repository](./Glossary.md#repository)_ - a store of source code + source history +- _[script](./Glossary.md#script)_ - a building block for custom storage, systems and time-keepint +- _[session](./Glossary.md#session)_ - represents one client connection +- _[ticker](./Glossary.md#ticker)_ - Allows to run events on a steady 'tick' +- _[twisted](./Glossary.md#twisted)_ - networking engine responsible for Evennia's event loop and communications -- _[typeclass](./Glossary#typeclass)_ - Evennia's database-connected Python class -- _upstream_ - see _[github](./Glossary#github)_ -- _[virtualenv](./Glossary#virtualenv)_ - a Python program and way to make an isolated Python install +- _[typeclass](./Glossary.md#typeclass)_ - Evennia's database-connected Python class +- _upstream_ - see _[github](./Glossary.md#github)_ +- _[virtualenv](./Glossary.md#virtualenv)_ - a Python program and way to make an isolated Python install --- -### _account_ +## _account_ -The term 'account' refers to the [player's](./Glossary#player) unique account on the game. It is -represented by the `Account` [typeclass](./Glossary#typeclass) and holds things like email, password, +The term 'account' refers to the [player's](./Glossary.md#account) unique account on the game. It is +represented by the `Account` [typeclass](./Glossary.md#typeclass) and holds things like email, password, configuration etc. When a player connects to the game, they connect to their account. The account has *no* representation in the game world. Through their Account they can instead choose to -[puppet](./Glossary#puppet) one (or more, depending on game mode) [Characters](./Glossary#character) in +[puppet](./Glossary.md#puppet) one (or more, depending on game mode) [Characters](./Glossary.md#character) in the game. -In the default [multisession mode](Components/Sessions#multisession-mode) of Evennia, you immediately start +In the default [multisession mode](Components/Sessions.md#multisession-mode) of Evennia, you immediately start puppeting a Character with the same name as your Account when you log in - mimicking how older servers used to work. -### _admin-site_ +## _admin-site_ -This usually refers to [Django's](./Glossary#django) *Admin site* or database-administration web page +This usually refers to [Django's](./Glossary.md#django) *Admin site* or database-administration web page ([link to Django docs](https://docs.djangoproject.com/en/2.1/ref/contrib/admin/)). The admin site is an automatically generated web interface to the database (it can be customized extensively). It's reachable from the `admin` link on the default Evennia website you get with your server. -### _attribute_ +## _attribute_ -The term _Attribute_ should not be confused with ([properties](./Glossary#property) or -[fields](./Glossary#field). The `Attribute` represents arbitrary pieces of data that can be attached -to any [typeclassed](./Glossary#typeclass) entity in Evennia. Attributes allows storing new persistent -data on typeclasses without changing their underlying database schemas. -[Read more about Attributes here](Components/Attributes). +The term _Attribute_ should not be confused with ([properties](./Glossary.md#property) or +[fields](./Glossary.md#field). The `Attribute` represents arbitrary pieces of data that can be attached +to any [typeclassed](./Glossary.md#typeclass) entity in Evennia. Attributes allows storing new persistent +data on typeclasses without changing their underlying database schemas. +[Read more about Attributes here](Components/Attributes.md). -### _channel_ +## _channel_ A _Channel_ refers to an in-game communication channel. It's an entity that people subscribe to and which re-distributes messages between all subscribers. Such subscribers default to being -[Accounts](./Glossary#account), for out-of-game communication but could also be [Objects (usually -Characters)](Glossary#character) if one wanted to adopt Channels for things like in-game walkie- +[Accounts](./Glossary.md#account), for out-of-game communication but could also be [Objects (usually +Characters)](./Glossary.md#character) if one wanted to adopt Channels for things like in-game walkie- talkies or phone systems. It is represented by the `Channel` typeclass. [You can read more about the -comm system here](Communications#channels). +comm system here](Components/Channels.md). -### _character_ +## _character_ -The _Character_ is the term we use for the default avatar being [puppeted](./Glossary#puppet) by the -[account](./Glossary#account) in the game world. It is represented by the `Character` typeclass (which -is a child of [Object](./Glossary#object)). Many developers use children of this class to represent -monsters and other NPCs. You can [read more about it here](Components/Objects#subclasses-of-object). +The _Character_ is the term we use for the default avatar being [puppeted](./Glossary.md#puppet) by the +[account](./Glossary.md#account) in the game world. It is represented by the `Character` typeclass (which +is a child of [Object](./Glossary.md#object)). Many developers use children of this class to represent +monsters and other NPCs. You can [read more about it here](Components/Objects.md#subclasses-of-object). -### _django_ +## _django_ [Django](https://www.djangoproject.com/) is a professional and very popular Python web framework, similar to Rails for the Ruby language. It is one of Evennia's central library dependencies (the -other one is [Twisted](./Glossary#twisted)). Evennia uses Django for two main things - to map all +other one is [Twisted](./Glossary.md#twisted)). Evennia uses Django for two main things - to map all database operations to Python and for structuring our web site. - + Through Django, we can work with any supported database (SQlite3, Postgres, MySQL ...) using generic Python instead of database-specific SQL: A database table is represented in Django as a Python class (called a *model*). An Python instance of such a class represents a row in that table. There is usually no need to know the details of Django's database handling in order to use Evennia - it will handle most of the complexity for you under the hood using what we call -[typeclasses](./Glossary#typeclass). But should you need the power of Django you can always get it. +[typeclasses](./Glossary.md#typeclass). But should you need the power of Django you can always get it. Most commonly people want to use "raw" Django when doing more advanced/custom database queries than -offered by Evennia's [default search functions](Howto/Starting/Part1/Searching-Things). One will then need +offered by Evennia's [default search functions](Howto/Starting/Part1/Searching-Things.md). One will then need to read about Django's _querysets_. Querysets are Python method calls on a special form that lets you build complex queries. They get converted into optimized SQL queries under the hood, suitable for your current database. [Here is our tutorial/explanation of Django queries](Tutorial-Searching- @@ -115,27 +116,32 @@ when a user goes that URL in their browser, enters data into a form etc. The ret to show. Django also offers templating with features such as being able to add special markers in HTML where it will insert the values of Python variables on the fly (like showing the current player count on the web page). [Here is one of our tutorials on wiring up such a web page](Add-a-simple- -new-web-page). Django also comes with the [admin site](./Glossary#admin-site), which automatically +new-web-page). Django also comes with the [admin site](./Glossary.md#admin-site), which automatically maps the database into a form accessible from a web browser. -### _core_ +## _core_ This term is sometimes used to represent the main Evennia library code suite, *excluding* its -[contrib](./Glossary#contrib) directory. It can sometimes come up in code reviews, such as +[contribs](./Glossary.md#contrib) directory. It can sometimes come up in code reviews, such as > Evennia is game-agnostic but this feature is for a particular game genre. So it does not belong in core. Better make it a contrib. + +## _contrib_ -### _field_ +Game-specific code and examples are distributed in evennia's [contribs/](Contribs/Contrib-Overview.md) folder. +This is game-specific, optional code created by the Evennia community. -A _field_ or _database field_ in Evennia refers to a [property](./Glossary#property) on a -[typeclass](./Glossary#typeclass) directly linked to an underlying database column. Only a few fixed +## _field_ + +A _field_ or _database field_ in Evennia refers to a [property](./Glossary.md#property) on a +[typeclass](./Glossary.md#typeclass) directly linked to an underlying database column. Only a few fixed properties per typeclass are database fields but they are often tied to the core functionality of -that base typeclass (for example [Objects](./Glossary#object) store its location as a field). In all -other cases, [attributes](./Glossary#attribute) are used to add new persistent data to the typeclass. -[Read more about typeclass properties here](Components/Typeclasses#about-typeclass-properties). +that base typeclass (for example [Objects](./Glossary.md#object) store its location as a field). In all +other cases, [attributes](./Glossary.md#attribute) are used to add new persistent data to the typeclass. +[Read more about typeclass properties here](Components/Typeclasses.md#about-typeclass-properties). -### _git_ +## _git_ [Git](https://git-scm.com/) is a [version control](https://en.wikipedia.org/wiki/Version_control) tool. It allows us to track the development of the Evennia code by dividing it into units called @@ -143,12 +149,12 @@ tool. It allows us to track the development of the Evennia code by dividing it i come back to it later if later changes caused problems. By tracking commits we know what 'version' of the code we are currently using. -Evennia's source code + its source history is jointly called a [repository](./Glossary#repository). -This is centrally stored at our online home on [GitHub](./Glossary#github). Everyone using or +Evennia's source code + its source history is jointly called a [repository](./Glossary.md#repository). +This is centrally stored at our online home on [GitHub](./Glossary.md#github). Everyone using or developing Evennia makes a 'clone' of this repository to their own computer - everyone automatically gets everything that is online, including all the code history. -> Don't confuse Git and [GitHub](./Glossary#github). The former is the version control system. The +> Don't confuse Git and [GitHub](./Glossary.md#github). The former is the version control system. The latter is a website (run by a company) that allows you to upload source code controlled by Git for others to see (among other things). @@ -161,59 +167,59 @@ Developers using Evennia often uses Git on their own games in the same way - to and to help collaboration with team mates. This is done completely independently of Evennia's Git usage. -Common usage (for non-Evennia developers): +Common usage (for non-Evennia developers): - `git clone ` - clone an online repository to your computer. This is what you do when you 'download' Evennia. You only need to do this once. - `git pull` (inside local copy of repository) - sync your local repository with what is online. -> Full usage of Git is way beyond the scope of this glossary. See -[Tutorial - version control](Coding/Version-Control) for more info and links to the Git documentation. +> Full usage of Git is way beyond the scope of this glossary. See +[Tutorial - version control](Coding/Version-Control.md) for more info and links to the Git documentation. -### _migrate_ +## _migrate_ This term is used for upgrading the database structure (it's _schema_ )to a new version. Most often -this is due to Evennia's [upstream](./Glossary#github) schema changing. When that happens you need to -migrate that schema to the new version as well. Once you have used [git](./Glossary#git) to pull the +this is due to Evennia's [upstream](./Glossary.md#github) schema changing. When that happens you need to +migrate that schema to the new version as well. Once you have used [git](./Glossary.md#git) to pull the latest changes, just `cd` into your game dir and run - evennia migrate + evennia migrate -That should be it (see [virtualenv](./Glossary#virtualenv) if you get a warning that the `evennia` -command is not available). See also [Updating your game](Coding/Updating-Your-Game) for more details. +That should be it (see [virtualenv](./Glossary.md#virtualenv) if you get a warning that the `evennia` +command is not available). See also [Updating your game](Coding/Updating-Your-Game.md) for more details. > Technically, migrations are shipped as little Python snippets of code that explains which database actions must be taken to upgrade from one version of the schema to the next. When you run the command above, those snippets are run in sequence. -### _multisession mode_ +## _multisession mode_ This term refers to the `MULTISESSION_MODE` setting, which has a value of 0 to 3. The mode alters how players can connect to the game, such as how many Sessions a player can start with one account and how many Characters they can control at the same time. It is [described in detail -here](Sessions#multisession-mode). +here](Components/Sessions.md#multisession-mode). -### _github_ +## _github_ [Github](https://github.com/evennia) is where Evennia's source code and documentation is hosted. -This online [repository](./Glossary#repository) of code we also sometimes refer to as _upstream_. +This online [repository](./Glossary.md#repository) of code we also sometimes refer to as _upstream_. GitHub is a business, offering free hosting to Open-source projects like Evennia. Despite the -similarity in name, don't confuse GitHub the website with [Git](./Glossary#git), the versioning -system. Github hosts Git [repositories](./Glossary#repository) online and helps with collaboration and +similarity in name, don't confuse GitHub the website with [Git](./Glossary.md#git), the versioning +system. Github hosts Git [repositories](./Glossary.md#repository) online and helps with collaboration and infrastructure. Git itself is a separate project. -### _object_ +## _object_ In general Python (and other [object-oriented languages](https://en.wikipedia.org/wiki/Object- oriented_programming)), an `object` is what we call the instance of a *class*. But one of Evennia's -core [typeclasses](./Glossary#typeclasss) is also called "Object". To separate these in the docs we +core [typeclasses](./Glossary.md#typeclass) is also called "Object". To separate these in the docs we try to use `object` to refer to the general term and capitalized `Object` when we refer to the typeclass. The `Object` is a typeclass that represents all *in-game* entities, including -[Characters](./Glossary#character), rooms, trees, weapons etc. [Read more about Objects here](Components/Objects). +[Characters](./Glossary.md#character), rooms, trees, weapons etc. [Read more about Objects here](Components/Objects.md). -### _pip_ +## _pip_ _[pip](https://pypi.org/project/pip/)_ comes with Python and is the main tool for installing third- party Python packages from the web. Once a python package is installed you can do `import @@ -232,94 +238,99 @@ means that if the code in `` changes, the installed Python package is im If not using `-e`, one would need to run `pip install --upgrade ` every time to make the changes available when you import this package into your code. Evennia is installed this way. -For development, `pip` is usually used together with a [virtualenv](./Glossary#virtualenv) to install +For development, `pip` is usually used together with a [virtualenv](./Glossary.md#virtualenv) to install all packages and dependencies needed for a project in one, isolated location on the hard drive. -### _puppet_ +## _puppet_ -An [account](./Glossary#account) can take control and "play as" any [Object](./Glossary#object). When +An [account](./Glossary.md#account) can take control and "play as" any [Object](./Glossary.md#object). When doing so, we call this _puppeting_, (like [puppeteering](https://en.wikipedia.org/wiki/Puppeteer)). -Normally the entity being puppeted is of the [Character](./Glossary#character) subclass but it does +Normally the entity being puppeted is of the [Character](./Glossary.md#character) subclass but it does not have to be. -### _property_ +## _property_ A _property_ is a general term used for properties on any Python object. The term also sometimes refers to the `property` built-in function of Python ([read more here](https://www.python- course.eu/python3_properties.php)). Note the distinction between properties, -[fields](./Glossary#field) and [Attributes](./Glossary#attribute). +[fields](./Glossary.md#field) and [Attributes](./Glossary.md#attribute). -### _repository_ +## _repository_ -A _repository_ is a version control/[git](./Glossary#git) term. It represents a folder containing +A _repository_ is a version control/[git](./Glossary.md#git) term. It represents a folder containing source code plus its versioning history. > In Git's case, that history is stored in a hidden folder `.git`. If you ever feel the need to look into this folder you probably already know enough Git to know why. The `evennia` folder you download from us with `git clone` is a repository. The code on -[GitHub](./Glossary#github) is often referred to as the 'online repository' (or the _upstream_ +[GitHub](./Glossary.md#github) is often referred to as the 'online repository' (or the _upstream_ repository). If you put your game dir under version control, that of course becomes a repository as well. -### _script_ +## _script_ -When we refer to _Scripts_, we generally refer to the `Script` [typeclass](Components/Typeclasses). Scripts are -the mavericks of Evennia - they are like [Objects](./Glossary#object) but without any in-game +When we refer to _Scripts_, we generally refer to the `Script` [typeclass](Components/Typeclasses.md). Scripts are +the mavericks of Evennia - they are like [Objects](./Glossary.md#object) but without any in-game existence. They are useful as custom places to store data but also as building blocks in persistent game systems. Since the can be initialized with timing capabilities they can also be used for long- -time persistent time keeping (for fast updates other types of timers may be better though). -[Read more about Scripts here](Components/Scripts) +time persistent time keeping (for fast updates other types of timers may be better though). +[Read more about Scripts here](Components/Scripts.md) -### _session_ +## _session_ -A [Session](Components/Sessions) is a Python object representing a single client connection to the server. A +A [Session](Components/Sessions.md) is a Python object representing a single client connection to the server. A given human player could connect to the game from different clients and each would get a Session (even if you did not allow them to actually log in and get access to an -[account](./Glossary#account)). +[account](./Glossary.md#account)). -Sessions are _not_ [typeclassed](./Glossary#typeclass) and has no database persistence. But since they +Sessions are _not_ [typeclassed](./Glossary.md#typeclass) and has no database persistence. But since they always exist (also when not logged in), they share some common functionality with typeclasses that can be useful for certain game states. -### _ticker_ +## _tag_ -The [Ticker handler](Components/TickerHandler) runs Evennia's optional 'ticker' system. In other engines, such +A [Tag](Components/Tags.md) is used to group and categorize other database entitiess together in an efficient way +so they can be efficiently searched later. + +## _ticker_ + +The [Ticker handler](Components/TickerHandler.md) runs Evennia's optional 'ticker' system. In other engines, such as [DIKU](https://en.wikipedia.org/wiki/DikuMUD), all game events are processed only at specific intervals called 'ticks'. Evennia has no such technical limitation (events are processed whenever needed) but using a fixed tick can still be useful for certain types of game systems, like combat. Ticker Handler allows you to emulate any number of tick rates (not just one) and subscribe actions to be called when those ticks come around. -### _typeclass_ +## _typeclass_ -The [typeclass](Components/Typeclasses) is an Evennia-specific term. A typeclass allows developers to work with +The [typeclass](Components/Typeclasses.md) is an Evennia-specific term. A typeclass allows developers to work with database-persistent objects as if they were normal Python objects. It makes use of specific -[Django](./Glossary#django) features to link a Python class to a database table. Sometimes we refer to +[Django](./Glossary.md#django) features to link a Python class to a database table. Sometimes we refer to such code entities as _being typeclassed_. -Evennia's main typeclasses are [Account](./Glossary#account), [Object](./Glossary#object), -[Script](./Glossary#script) and [Channel](./Glossary#channel). Children of the base class (such as -[Character](./Glossary#character)) will use the same database table as the parent, but can have vastly -different Python capabilities (and persistent features through [Attributes](./Glossary#attributes) and -[Tags](./Glossary#tags). A typeclass can be coded and treated pretty much like any other Python class +Evennia's main typeclasses are [Account](./Glossary.md#account), [Object](./Glossary.md#object), +[Script](./Glossary.md#script) and [Channel](./Glossary.md#channel). Children of the base class (such as +[Character](./Glossary.md#character)) will use the same database table as the parent, but can have vastly +different Python capabilities (and persistent features through [Attributes](./Glossary.md#attribute) and +[Tags](./Glossary.md#tag). A typeclass can be coded and treated pretty much like any other Python class except it must inherit (at any distance) from one of the base typeclasses. Also, creating a new instance of a typeclass will add a new row to the database table to which it is linked. -The [core](./Glossary#core) typeclasses in the Evennia library are all named `DefaultAccount`, +The [core](./Glossary.md#core) typeclasses in the Evennia library are all named `DefaultAccount`, `DefaultObject` etc. When you initialize your [game dir] you automatically get empty children of these, called `Account`, `Object` etc that you can start working with. -### _twisted_ +## _twisted_ [Twisted](https://twistedmatrix.com/trac/) is a heavy-duty asynchronous networking engine. It is one -of Evennia's two major library dependencies (the other one is [Django](./Glossary#django)). Twisted is +of Evennia's two major library dependencies (the other one is [Django](./Glossary.md#django)). Twisted is what "runs" Evennia - it handles Evennia's event loop. Twisted also has the building blocks we need to construct network protocols and communicate with the outside world; such as our MUD-custom version of Telnet, Telnet+SSL, SSH, webclient-websockets etc. Twisted also runs our integrated web server, serving the Django-based website for your game. -### _virtualenv_ +## _virtualenv_ The standard [virtualenv](https://virtualenv.pypa.io/en/stable/) program comes with Python. It is used to isolate all Python packages needed by a given Python project into one folder (we call that @@ -328,18 +339,18 @@ referred to as "a virtualenv". If you ever try to run the `evennia` program and something like "the command 'evennia' is not available" - it's probably because your virtualenv is not 'active' yet (see below). -Usage: +Usage: - `virtualenv ` - initialize a new virtualenv `` in a new folder `` in the current location. Called `evenv` in these docs. - `virtualenv -p path/to/alternate/python_executable ` - create a virtualenv using another Python version than default. - `source /bin/activate`(linux/mac) - activate the virtualenv in ``. -- `\Scripts\activate` (windows) +- `\Scripts\activate` (windows) - `deactivate` - turn off the currently activated virtualenv. A virtualenv is 'activated' only for the console/terminal it was started in, but it's safe to activate the same virtualenv many times in different windows if you want. Once activated, all Python -packages now installed with [pip](./Glossary#pip) will install to `evenv` rather than to a global +packages now installed with [pip](./Glossary.md#pip) will install to `evenv` rather than to a global location like `/usr/local/bin` or `C:\Program Files`. > Note that if you have root/admin access you *could* install Evennia globally just fine, without @@ -355,11 +366,11 @@ your computer, you'll need to install it again in your virtualenv. care less if your virtualenv is active or not. So you could use `git` without the virtualenv being active, for example. -When your virtualenv is active you should see your console/terminal prompt change to +When your virtualenv is active you should see your console/terminal prompt change to (evenv) ... -... or whatever name you gave the virtualenv when you initialized it. +... or whatever name you gave the virtualenv when you initialized it. > We sometimes say that we are "in" the virtualenv when it's active. But just to be clear - you never have to actually `cd` into the `evenv` folder. You can activate it from anywhere and will diff --git a/docs/source/How-To-Get-And-Give-Help.md b/docs/source/How-To-Get-And-Give-Help.md index 6763818594..2bb50dc832 100644 --- a/docs/source/How-To-Get-And-Give-Help.md +++ b/docs/source/How-To-Get-And-Give-Help.md @@ -1,7 +1,7 @@ # How To Get And Give Help -### How to *get* Help +## How to *get* Help If you cannot find what you are looking for in the documentation, here's what to do: @@ -21,7 +21,7 @@ have busy personal lives. So you might have to hang around for a while - you'll eventually! -### How to *give* Help +## How to *give* Help Evennia is open-source and non-commercial. It relies on the time donated by its users and developers in order to progress. @@ -29,21 +29,21 @@ Evennia is open-source and non-commercial. It relies on the time donated by its - Take part in the Evennia community! Join the [chat][chat] or [forum][group]. - Report problems you find or features you'd like to our [issue tracker](github:issue). -```important:: +```{important} Just the simple act of us know you are out there using Evennia helps a lot! ``` If you'd like to help develop Evennia more hands-on, here are some ways to get going: -- Look through this [online documentation](./index#Evennia-documentation) and see if you can help improve or expand the -documentation (even small things like fixing typos!). [See here](./Contributing-Docs) on how you +- Look through this [online documentation](./index.md#evennia-documentation) and see if you can help improve or expand the +documentation (even small things like fixing typos!). [See here](./Contributing-Docs.md) on how you contribute to the docs. - Send a message to our [discussion group][group] and/or our [IRC chat][chat] asking about what needs doing, along with what your interests and skills are. - Take a look at our [issue tracker][issues] and see if there's something you feel like taking on. [here are bugs][issues-master] that need fixes. At any given time there may also be some [bounties][issues-bounties] open. -- Check out the [Contributing](./Contributing) page on how to practically contribute with code using +- Check out the [Contributing](./Contributing.md) page on how to practically contribute with code using github. ... And finally, if you want to help motivate and support development you can also drop some coins diff --git a/docs/source/Howto/Add-a-wiki-on-your-website.md b/docs/source/Howto/Add-a-wiki-on-your-website.md index 4038187085..b9d7c75169 100644 --- a/docs/source/Howto/Add-a-wiki-on-your-website.md +++ b/docs/source/Howto/Add-a-wiki-on-your-website.md @@ -2,7 +2,7 @@ **Before doing this tutorial you will probably want to read the intro in -[Basic Web tutorial](Starting/Part5/Web-Tutorial).** Reading the three first parts of the +[Basic Web tutorial](Starting/Part5/Web-Tutorial.md).** Reading the three first parts of the [Django tutorial](https://docs.djangoproject.com/en/1.9/intro/tutorial01/) might help as well. This tutorial will provide a step-by-step process to installing a wiki on your website. diff --git a/docs/source/Howto/Building-a-mech-tutorial.md b/docs/source/Howto/Building-a-mech-tutorial.md index fe59859888..edce1cb379 100644 --- a/docs/source/Howto/Building-a-mech-tutorial.md +++ b/docs/source/Howto/Building-a-mech-tutorial.md @@ -28,9 +28,9 @@ Before we continue, let’s make a brief detour. Evennia is very flexible about more flexible about using and adding commands to those objects. Here are some ground rules well worth remembering for the remainder of this article: -- The [Account](../Components/Accounts) represents the real person logging in and has no game-world existence. -- Any [Object](../Components/Objects) can be puppeted by an Account (with proper permissions). -- [Characters](../Components/Objects#characters), [Rooms](../Components/Objects#rooms), and [Exits](../Components/Objects#exits) are just +- The [Account](../Components/Accounts.md) represents the real person logging in and has no game-world existence. +- Any [Object](../Components/Objects.md) can be puppeted by an Account (with proper permissions). +- [Characters](../Components/Objects.md#characters), [Rooms](../Components/Objects.md#rooms), and [Exits](../Components/Objects.md#exits) are just children of normal Objects. - Any Object can be inside another (except if it creates a loop). - Any Object can store custom sets of commands on it. Those commands can: @@ -121,7 +121,7 @@ about the missiles being fired and has different `key` and `aliases`. We leave that up to you to create as an exercise. You could have it print "WOOSH! The mech launches missiles against !", for example. -Now we shove our commands into a command set. A [Command Set](../Components/Command-Sets) (CmdSet) is a container +Now we shove our commands into a command set. A [Command Set](../Components/Command-Sets.md) (CmdSet) is a container holding any number of commands. The command set is what we will store on the mech. ```python @@ -174,7 +174,7 @@ This is great for testing. The way we added it, the MechCmdSet will even go away server. Now we want to make the mech an actual object “type” so we can create mechs without those extra steps. For this we need to create a new Typeclass. -A [Typeclass](../Components/Typeclasses) is a near-normal Python class that stores its existence to the database +A [Typeclass](../Components/Typeclasses.md) is a near-normal Python class that stores its existence to the database behind the scenes. A Typeclass is created in a normal Python source file: ```python diff --git a/docs/source/Howto/Coding-FAQ.md b/docs/source/Howto/Coding-FAQ.md index aa7800e458..f3ef01a66a 100644 --- a/docs/source/Howto/Coding-FAQ.md +++ b/docs/source/Howto/Coding-FAQ.md @@ -7,28 +7,28 @@ exists before answering - maybe you can clarify that answer rather than to make ## Table of Contents -- [Removing default commands](./Coding-FAQ#removing-default-commands) -- [Preventing character from moving based on a condition](./Coding-FAQ#preventing-character-from- +- [Removing default commands](./Coding-FAQ.md#removing-default-commands) +- [Preventing character from moving based on a condition](./Coding-FAQ.md#preventing-character-from- moving-based-on-a-condition) -- [Reference initiating object in an EvMenu command](./Coding-FAQ#reference-initiating-object-in-an- +- [Reference initiating object in an EvMenu command](./Coding-FAQ.md#reference-initiating-object-in-an- evmenu-command) -- [Adding color to default Evennia Channels](./Coding-FAQ#adding-color-to-default-evennia-channels) -- [Selectively turn off commands in a room](./Coding-FAQ#selectively-turn-off-commands-in-a-room) -- [Select Command based on a condition](./Coding-FAQ#select-command-based-on-a-condition) -- [Automatically updating code when reloading](./Coding-FAQ#automatically-updating-code-when- +- [Adding color to default Evennia Channels](./Coding-FAQ.md#adding-color-to-default-evennia-channels) +- [Selectively turn off commands in a room](./Coding-FAQ.md#selectively-turn-off-commands-in-a-room) +- [Select Command based on a condition](./Coding-FAQ.md#select-command-based-on-a-condition) +- [Automatically updating code when reloading](./Coding-FAQ.md#automatically-updating-code-when- reloading) -- [Changing all exit messages](./Coding-FAQ#changing-all-exit-messages) -- [Add parsing with the "to" delimiter](./Coding-FAQ#add-parsing-with-the-to-delimiter) -- [Store last used session IP address](./Coding-FAQ#store-last-used-session-ip-address) -- [Use wide characters with EvTable](./Coding-FAQ#non-latin-characters-in-evtable) +- [Changing all exit messages](./Coding-FAQ.md#changing-all-exit-messages) +- [Add parsing with the "to" delimiter](./Coding-FAQ.md#add-parsing-with-the-to-delimiter) +- [Store last used session IP address](./Coding-FAQ.md#store-last-used-session-ip-address) +- [Use wide characters with EvTable](./Coding-FAQ.md#non-latin-characters-in-evtable) ## Removing default commands -**Q:** How does one *remove* (not replace) e.g. the default `get` [Command](../Components/Commands) from the -Character [Command Set](../Components/Command-Sets)? +**Q:** How does one *remove* (not replace) e.g. the default `get` [Command](../Components/Commands.md) from the +Character [Command Set](../Components/Command-Sets.md)? **A:** Go to `mygame/commands/default_cmdsets.py`. Find the `CharacterCmdSet` class. It has one method named `at_cmdset_creation`. At the end of that method, add the following line: -`self.remove(default_cmds.CmdGet())`. See the [Adding Commands Tutorial](Starting/Part1/Adding-Commands) +`self.remove(default_cmds.CmdGet())`. See the [Adding Commands Tutorial](Starting/Part1/Adding-Commands.md) for more info. ## Preventing character from moving based on a condition @@ -36,7 +36,7 @@ for more info. combat, immobilized, etc.) **A:** The `at_before_move` hook is called by Evennia just before performing any move. If it returns -`False`, the move is aborted. Let's say we want to check for an [Attribute](../Components/Attributes) `cantmove`. +`False`, the move is aborted. Let's say we want to check for an [Attribute](../Components/Attributes.md) `cantmove`. Add the following code to the `Character` class: ```python @@ -52,7 +52,7 @@ def at_before_move(self, destination): **Q:** An object has a Command on it starts up an EvMenu instance. How do I capture a reference to that object for use in the menu? -**A:** When an [EvMenu](../Components/EvMenu) is started, the menu object is stored as `caller.ndb._menutree`. +**A:** When an [EvMenu](../Components/EvMenu.md) is started, the menu object is stored as `caller.ndb._menutree`. This is a good place to store menu-specific things since it will clean itself up when the menu closes. When initiating the menu, any additional keywords you give will be available for you as properties on this menu object: @@ -100,7 +100,7 @@ CHANNEL_COLORS`. **Q:** I want certain commands to turn off in a given room. They should still work normally for staff. -**A:** This is done using a custom cmdset on a room [locked with the 'call' lock type](../Components/Locks). Only +**A:** This is done using a custom cmdset on a room [locked with the 'call' lock type](../Components/Locks.md). Only if this lock is passed will the commands on the room be made available to an object inside it. Here is an example of a room where certain commands are disabled for non-staff: @@ -141,7 +141,7 @@ superusers). command to only be available on a full moon, from midnight to three in-game time. **A:** This is easiest accomplished by putting the "werewolf" command on the Character as normal, -but to [lock](../Components/Locks) it with the "cmd" type lock. Only if the "cmd" lock type is passed will the +but to [lock](../Components/Locks.md) it with the "cmd" type lock. Only if the "cmd" lock type is passed will the command be available. ```python @@ -156,8 +156,8 @@ class CmdWerewolf(Command): def func(self): # ... ``` -Add this to the [default cmdset as usual](Starting/Part1/Adding-Commands). The `is_full_moon` [lock -function](Locks#lock-functions) does not yet exist. We must create that: +Add this to the [default cmdset as usual](Starting/Part1/Adding-Commands.md). The `is_full_moon` [lock +function](../Components/Locks.md#lock-functions) does not yet exist. We must create that: ```python # in mygame/server/conf/lockfuncs.py diff --git a/docs/source/Howto/Command-Cooldown.md b/docs/source/Howto/Command-Cooldown.md index 030b26e5cd..6310acaa9a 100644 --- a/docs/source/Howto/Command-Cooldown.md +++ b/docs/source/Howto/Command-Cooldown.md @@ -9,7 +9,7 @@ a while. Such effects are called *cooldowns*. This page exemplifies a very resource-efficient way to do cooldowns. A more 'active' way is to use asynchronous delays as in the [command duration -tutorial](Command-Duration#Blocking-Commands), the two might be useful to +tutorial](./Command-Duration.md#blocking-commands), the two might be useful to combine if you want to echo some message to the user after the cooldown ends. ## Non-persistent cooldown @@ -88,7 +88,7 @@ database, you need to use the caster for the storage. self.caller.db.firestorm_lastcast = now ``` -Since we are storing as an [Attribute](../Components/Attributes), we need to identify the +Since we are storing as an [Attribute](../Components/Attributes.md), 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 diff --git a/docs/source/Howto/Command-Duration.md b/docs/source/Howto/Command-Duration.md index c1bedcb4dc..a69f669103 100644 --- a/docs/source/Howto/Command-Duration.md +++ b/docs/source/Howto/Command-Duration.md @@ -2,7 +2,7 @@ Before reading this tutorial, if you haven't done so already, you might want to -read [the documentation on commands](../Components/Commands) to get a basic understanding of +read [the documentation on commands](../Components/Commands.md) to get a basic understanding of how commands work in Evennia. In some types of games a command should not start and finish immediately. @@ -40,7 +40,7 @@ class CmdTest(Command): > Important: The `yield` functionality will *only* work in the `func` method of > Commands. It only works because Evennia has especially > catered for it in Commands. If you want the same functionality elsewhere you -> must use the [interactive decorator](../Concepts/Async-Process#The-@interactive-decorator). +> must use the [interactive decorator](../Concepts/Async-Process.md#the-interactive-decorator). The important line is the `yield 10`. It tells Evennia to "pause" the command and to wait for 10 seconds to execute the rest. If you add this command and @@ -187,7 +187,7 @@ start crafting a shield at the same time, or if you just did a huge power-swing should not be able to do it again immediately. The simplest way of implementing blocking is to use the technique covered in the [Command -Cooldown](Command-Cooldown) tutorial. In that tutorial we implemented cooldowns by having the +Cooldown](./Command-Cooldown.md) tutorial. In that tutorial we implemented cooldowns by having the Command store the current time. Next time the Command was called, we compared the current time to the stored time to determine if enough time had passed for a renewed use. This is a *very* efficient, reliable and passive solution. The drawback is that there is nothing to tell the Player diff --git a/docs/source/Howto/Command-Prompt.md b/docs/source/Howto/Command-Prompt.md index 3a7e1dd21b..217a3635ea 100644 --- a/docs/source/Howto/Command-Prompt.md +++ b/docs/source/Howto/Command-Prompt.md @@ -21,7 +21,7 @@ You can combine the sending of normal text with the sending (updating of the pro self.msg("This is a text", prompt="This is a prompt") ``` -You can update the prompt on demand, this is normally done using [OOB](../Concepts/OOB)-tracking of the relevant +You can update the prompt on demand, this is normally done using [OOB](../Concepts/OOB.md)-tracking of the relevant Attributes (like the character's health). You could also make sure that attacking commands update the prompt when they cause a change in health, for example. diff --git a/docs/source/Howto/Coordinates.md b/docs/source/Howto/Coordinates.md index 142c8ef013..5825a1a3fd 100644 --- a/docs/source/Howto/Coordinates.md +++ b/docs/source/Howto/Coordinates.md @@ -23,7 +23,7 @@ instance. ## Coordinates as tags The first concept might be the most surprising at first glance: we will create coordinates as -[tags](../Components/Tags). +[tags](../Components/Tags.md). > Why not attributes, wouldn't that be easier? diff --git a/docs/source/Howto/Default-Exit-Errors.md b/docs/source/Howto/Default-Exit-Errors.md index 85310894ec..81ddf7b6b6 100644 --- a/docs/source/Howto/Default-Exit-Errors.md +++ b/docs/source/Howto/Default-Exit-Errors.md @@ -2,8 +2,8 @@ Evennia allows for exits to have any name. The command "kitchen" is a valid exit name as well as -"jump out the window" or "north". An exit actually consists of two parts: an [Exit Object](../Components/Objects) -and an [Exit Command](../Components/Commands) stored on said exit object. The command has the same key and aliases +"jump out the window" or "north". An exit actually consists of two parts: an [Exit Object](../Components/Objects.md) +and an [Exit Command](../Components/Commands.md) stored on said exit object. The command has the same key and aliases as the object, which is why you can see the exit in the room and just write its name to traverse it. If you try to enter the name of a non-existing exit, it is thus the same as trying a non-exising @@ -24,7 +24,7 @@ error message just told us that we couldn't go there. ## Adding default error commands -To solve this you need to be aware of how to [write and add new commands](Starting/Part1/Adding-Commands). +To solve this you need to be aware of how to [write and add new commands](Starting/Part1/Adding-Commands.md). What you need to do is to create new commands for all directions you want to support in your game. In this example all we'll do is echo an error message, but you could certainly consider more advanced uses. You add these commands to the default command set. Here is an example of such a set @@ -90,7 +90,7 @@ commands: You cannot move east. Further expansions by the exit system (including manipulating the way the Exit command itself is -created) can be done by modifying the [Exit typeclass](../Components/Typeclasses) directly. +created) can be done by modifying the [Exit typeclass](../Components/Typeclasses.md) directly. ## Additional Comments @@ -109,7 +109,7 @@ So why didn't we create a single error command above? Something like this: The anwer is that this would *not* work and understanding why is important in order to not be confused when working with commands and command sets. -The reason it doesn't work is because Evennia's [command system](../Components/Commands) compares commands *both* +The reason it doesn't work is because Evennia's [command system](../Components/Commands.md) compares commands *both* by `key` and by `aliases`. If *either* of those match, the two commands are considered *identical* as far as cmdset merging system is concerned. diff --git a/docs/source/Howto/Evennia-for-Diku-Users.md b/docs/source/Howto/Evennia-for-Diku-Users.md index da4599e3e2..3866448c07 100644 --- a/docs/source/Howto/Evennia-for-Diku-Users.md +++ b/docs/source/Howto/Evennia-for-Diku-Users.md @@ -14,7 +14,7 @@ all that important for a text-based game. The main advantages of Python are an e development cycle and easy ways to create game systems. Doing the same with C can take many times more code and be harder to make stable and maintainable. -### Core Differences +## Core Differences - As mentioned, the main difference between Evennia and a Diku-derived codebase is that Evennia is written purely in Python. Since Python is an interpreted language there is no compile stage. It is @@ -28,7 +28,7 @@ while writing to a flatfile it may become corrupt and the data lost. A proper da not susceptible to this - at no point is the data in a state where it cannot be recovered. Databases are also highly optimized for querying large data sets efficiently. -### Some Familiar Things +## Some Familiar Things Diku expresses the character object referenced normally by: @@ -63,7 +63,7 @@ class CmdMyCmd(Command): """ This is a Command Evennia Object """ - + [...] def func(self): @@ -136,7 +136,7 @@ Puff~ Puff the Fractal Dragon is here, contemplating a higher reality. ~ Is that some type of differential curve involving some strange, and unknown -calculus that she seems to be made out of? +calculus that she seems to be made out of? ~ 516106 0 0 0 2128 0 0 0 1000 E 34 9 -10 6d6+340 5d5+5 @@ -145,7 +145,7 @@ calculus that she seems to be made out of? BareHandAttack: 12 E T 95 -``` +``` Each line represents something that the MUD reads in and does something with it. This isn't easy to read, but let's see if we can emulate this as a dictionary to be stored on a database script created in Evennia. diff --git a/docs/source/Howto/Evennia-for-MUSH-Users.md b/docs/source/Howto/Evennia-for-MUSH-Users.md index a9130275a2..e5dd840db1 100644 --- a/docs/source/Howto/Evennia-for-MUSH-Users.md +++ b/docs/source/Howto/Evennia-for-MUSH-Users.md @@ -38,7 +38,7 @@ to use. So the *Player* usually operates by making use of the tools prepared for For a *Player*, collaborating on a game need not be too different between MUSH and Evennia. The building and description of the game world can still happen mostly in-game using build commands, -using text tags and [inline functions](../Concepts/TextTags#inline-functions) to prettify and customize the +using text tags and [inline functions](../Components/FuncParser.md) to prettify and customize the experience. Evennia offers external ways to build a world but those are optional. There is also nothing *in principle* stopping a Developer from offering a softcode-like language to Players if that is deemed necessary. @@ -88,7 +88,7 @@ based inheritance of MUSH. There are other differences for sure, but that should give some feel for things. Enough with the theory. Let's get down to more practical matters next. To install, see the -[Getting Started instructions](../Setup/Setup-Quickstart). +[Getting Started instructions](../Setup/Setup-Quickstart.md). ## A first step making things more familiar @@ -203,7 +203,7 @@ developer changing the underlying Python code. ## Next steps If you are a *Developer* and are interested in making a more MUSH-like Evennia game, a good start is -to look into the Evennia [Tutorial for a first MUSH-like game](Starting/Part3/Tutorial-for-basic-MUSH-like-game). +to look into the Evennia [Tutorial for a first MUSH-like game](Starting/Part3/Tutorial-for-basic-MUSH-like-game.md). That steps through building a simple little game from scratch and helps to acquaint you with the various corners of Evennia. There is also the [Tutorial for running roleplaying sessions](Evennia- for-roleplaying-sessions) that can be of interest. @@ -211,8 +211,8 @@ for-roleplaying-sessions) that can be of interest. An important aspect of making things more familiar for *Players* is adding new and tweaking existing commands. How this is done is covered by the [Tutorial on adding new commands](Adding-Command- Tutorial). You may also find it useful to shop through the `evennia/contrib/` folder. The -[Tutorial world](Starting/Part1/Tutorial-World-Introduction) is a small single-player quest you can try (it’s not very MUSH- -like but it does show many Evennia concepts in action). Beyond that there are [many more tutorials](./Howto-Overview) +[Tutorial world](Starting/Part1/Tutorial-World-Introduction.md) is a small single-player quest you can try (it’s not very MUSH- +like but it does show many Evennia concepts in action). Beyond that there are [many more tutorials](./Howto-Overview.md) to try out. If you feel you want a more visual overview you can also look at [Evennia in pictures](https://evennia.blogspot.se/2016/05/evennia-in-pictures.html). diff --git a/docs/source/Howto/Evennia-for-roleplaying-sessions.md b/docs/source/Howto/Evennia-for-roleplaying-sessions.md index 1d4cf22ac3..59dbc1ccf4 100644 --- a/docs/source/Howto/Evennia-for-roleplaying-sessions.md +++ b/docs/source/Howto/Evennia-for-roleplaying-sessions.md @@ -26,12 +26,12 @@ defaults for our particular use-case. Below we will flesh out these components f ## Starting out -We will assume you start from scratch. You need Evennia installed, as per the [Setup Quickstart](../Setup/Setup-Quickstart) +We will assume you start from scratch. You need Evennia installed, as per the [Setup Quickstart](../Setup/Setup-Quickstart.md) instructions. Initialize a new game directory with `evennia init `. In this tutorial we assume your game dir is simply named `mygame`. You can use the default database and keep all other settings to default for now. Familiarize yourself with the `mygame` folder before continuing. You might want to browse the -[First Steps Coding](Starting/Part1/Starting-Part1) tutorial, just to see roughly where things are modified. +[First Steps Coding](Starting/Part1/Starting-Part1.md) tutorial, just to see roughly where things are modified. ## The Game Master role @@ -44,7 +44,7 @@ to show your renewed GM status to the other accounts. ### The permission hierarchy -Evennia has the following [permission hierarchy](../Concepts/Building-Permissions#assigning-permissions) out of +Evennia has the following [permission hierarchy](../Concepts/Building-Permissions.md#assigning-permissions) out of the box: *Players, Helpers, Builders, Admins* and finally *Developers*. We could change these but then we'd need to update our Default commands to use the changes. We want to keep this simple, so instead we map our different roles on top of this permission ladder. @@ -60,7 +60,7 @@ everyone. 5. `Developers`-level permission are the server administrators, the ones with the ability to restart/shutdown the server as well as changing the permission levels. -> The [superuser](../Concepts/Building-Permissions#the-super-user) is not part of the hierarchy and actually +> The [superuser](../Concepts/Building-Permissions.md#the-super-user) is not part of the hierarchy and actually completely bypasses it. We'll assume server admin(s) will "just" be Developers. ### How to grant permissions @@ -102,7 +102,7 @@ its name will have the string`(GM)` added to the end. #### Character modification Let's first start by customizing the Character. We recommend you browse the beginning of the -[Account](../Components/Accounts) page to make sure you know how Evennia differentiates between the OOC "Account +[Account](../Components/Accounts.md) page to make sure you know how Evennia differentiates between the OOC "Account objects" (not to be confused with the `Accounts` permission, which is just a string specifying your access) and the IC "Character objects". @@ -141,7 +141,7 @@ Above, we change how the Character's name is displayed: If the account controlli a GM, we attach the string `(GM)` to the Character's name so everyone can tell who's the boss. If we ourselves are Developers or GM's we will see database ids attached to Characters names, which can help if doing database searches against Characters of exactly the same name. We base the "gm- -ingness" on having an flag (an [Attribute](../Components/Attributes)) named `is_gm`. We'll make sure new GM's +ingness" on having an flag (an [Attribute](../Components/Attributes.md)) named `is_gm`. We'll make sure new GM's actually get this flag below. > **Extra exercise:** This will only show the `(GM)` text on *Characters* puppeted by a GM account, @@ -151,7 +151,7 @@ that is, it will show only to those in the same location. If we wanted it to als #### New @gm/@ungm command -We will describe in some detail how to create and add an Evennia [command](../Components/Commands) here with the +We will describe in some detail how to create and add an Evennia [command](../Components/Commands.md) here with the hope that we don't need to be as detailed when adding commands in the future. We will build on Evennia's default "mux-like" commands here. @@ -266,7 +266,7 @@ We will here show two examples using the *EvTable* and *EvForm* utilities.Later Commands to edit and display the output from those utilities. > Note that due to the limitations of the wiki, no color is used in any of the examples. See -> [the text tag documentation](../Concepts/TextTags) for how to add color to the tables and forms. +> [the text tag documentation](../Concepts/TextTags.md) for how to add color to the tables and forms. #### Making a sheet with EvTable @@ -686,7 +686,7 @@ implemented. ## Rooms Evennia comes with rooms out of the box, so no extra work needed. A GM will automatically have all -needed building commands available. A fuller go-through is found in the [Building tutorial](Starting/Part1/Building-Quickstart). +needed building commands available. A fuller go-through is found in the [Building tutorial](Starting/Part1/Building-Quickstart.md). Here are some useful highlights: * `@dig roomname;alias = exit_there;alias, exit_back;alias` - this is the basic command for digging @@ -704,7 +704,7 @@ access after the fact. ## Channels -Evennia comes with [Channels](../Components/Communications#Channels) in-built and they are described fully in the +Evennia comes with [Channels](../Components/Channels.md) in-built and they are described fully in the documentation. For brevity, here are the relevant commands for normal use: * `@ccreate new_channel;alias;alias = short description` - Creates a new channel. diff --git a/docs/source/Howto/Gametime-Tutorial.md b/docs/source/Howto/Gametime-Tutorial.md index 670a5de186..274b7c09c5 100644 --- a/docs/source/Howto/Gametime-Tutorial.md +++ b/docs/source/Howto/Gametime-Tutorial.md @@ -7,7 +7,7 @@ names for its time units or might even use a completely custom calendar. You don game time system at all. But if you do, Evennia offers basic tools to handle these various situations. This tutorial will walk you through these features. -### A game time with a standard calendar +## A game time with a standard calendar Many games let their in-game time run faster or slower than real time, but still use our normal real-world calendar. This is common both for games set in present day as well as for games in @@ -21,7 +21,7 @@ automatically handled by the system. Evennia's game time features assume a standard calendar (see the relevant section below for a custom calendar). -#### Setting up game time for a standard calendar +### Setting up game time for a standard calendar All is done through the settings. Here are the settings you should use if you want a game time with a standard calendar: @@ -91,14 +91,14 @@ The line that is most relevant here is the game time epoch. You see it shown at this point forward, the game time keeps increasing. If you keep typing `@time`, you'll see the game time updated correctly... and going (by default) twice as fast as the real time. -#### Time-related events +### Time-related events The `gametime` utility also has a way to schedule game-related events, taking into account your game time, and assuming a standard calendar (see below for the same feature with a custom calendar). For instance, it can be used to have a specific message every (in-game) day at 6:00 AM showing how the sun rises. -The function `schedule()` should be used here. It will create a [script](../Components/Scripts) with some +The function `schedule()` should be used here. It will create a [script](../Components/Scripts.md) with some additional features to make sure the script is always executed when the game time matches the given parameters. @@ -110,12 +110,12 @@ repeatedly. - Additional keyword arguments `sec`, `min`, `hour`, `day`, `month` and `year` to describe the time to schedule. If the parameter isn't given, it assumes the current time value of this specific unit. -Here is a short example for making the sun rise every day: +Here is a short example for making the sun rise every day: ```python # in a file ingame_time.py in mygame/world/ -from evennia.utils import gametime +from evennia.utils import gametime from typeclasses.rooms import Room def at_sunrise(): @@ -166,7 +166,7 @@ days. Evennia handles custom calendars through an optional *contrib* module, called `custom_gametime`. Contrary to the normal `gametime` module described above it is not active by default. -#### Setting up the custom calendar +### Setting up the custom calendar In our first example of the Shire calendar, used by hobbits in books by Tolkien, we don't really need the notion of weeks... but we need the notion of months having 30 days, not 28. @@ -194,7 +194,7 @@ configuration: instead, we skip from days to months directly. In order for this setting to work properly, remember all units have to be multiples of the previous units. If you create "day", it needs to be multiple of hours, for instance. -So for our example, our settings may look like this: +So for our example, our settings may look like this: ```python # in a file settings.py in mygame/server/conf @@ -263,7 +263,7 @@ Don't forget to add it in your CharacterCmdSet to see this command: ```python # in mygame/commands/default_cmdset.py -from commands.gametime import CmdTime # <-- Add +from commands.gametime import CmdTime # <-- Add # ... @@ -280,7 +280,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet): Populates the cmdset """ super().at_cmdset_creation() - # ... + # ... self.add(CmdTime()) # <- Add ``` @@ -293,9 +293,9 @@ it, you might see something like: You could display it a bit more prettily with names for months and perhaps even days, if you want. And if "months" are called "moons" in your game, this is where you'd add that. -#### Time-related events in custom gametime +## Time-related events in custom gametime The `custom_gametime` module also has a way to schedule game-related events, taking into account your game time (and your custom calendar). It can be used to have a specific message every day at 6:00 AM, to show the sun rises, for instance. The `custom_gametime.schedule` function works in the -same way as described for the default one above. \ No newline at end of file +same way as described for the default one above. diff --git a/docs/source/Howto/Howto-Overview.md b/docs/source/Howto/Howto-Overview.md index 6c404f7fba..3d07ddbe6e 100644 --- a/docs/source/Howto/Howto-Overview.md +++ b/docs/source/Howto/Howto-Overview.md @@ -3,7 +3,7 @@ The documents in this section aims to teach how to use Evennia in a tutorial or a step-by-step way. They often give hints on about solving a problem or implementing a particular feature or concept. They will often refer to the -[components](../Components/Components-Overview) or [concepts](../Concepts/Concepts-Overview) +[components](../Components/Components-Overview.md) or [concepts](../Concepts/Concepts-Overview.md) docs for those that want to dive deeper. ## The Starting Tutorial @@ -14,92 +14,92 @@ in mind for your own game, this will give you a good start. ### Part 1: What we have -1. [Introduction & Overview](Starting/Part1/Starting-Part1) -1. [Building stuff](Starting/Part1/Building-Quickstart) -1. [The Tutorial World](Starting/Part1/Tutorial-World-Introduction) -1. [Python basics](Starting/Part1/Python-basic-introduction) -1. [Game dir overview](Starting/Part1/Gamedir-Overview) -1. [Python classes and objects](Starting/Part1/Python-classes-and-objects) -1. [Accessing the Evennia library](Starting/Part1/Evennia-Library-Overview) -1. [Typeclasses - Persistent objects](Starting/Part1/Learning-Typeclasses) -1. [Making our first own commands](Starting/Part1/Adding-Commands) -1. [Parsing and replacing default Commands](Starting/Part1/More-on-Commands) -1. [Creating things](Starting/Part1/Creating-Things) -1. [Searching for things](Starting/Part1/Searching-Things) -1. [Advanced searching with Django queries](Starting/Part1/Django-queries) +1. [Introduction & Overview](Starting/Part1/Starting-Part1.md) +1. [Building stuff](Starting/Part1/Building-Quickstart.md) +1. [The Tutorial World](Starting/Part1/Tutorial-World-Introduction.md) +1. [Python basics](Starting/Part1/Python-basic-introduction.md) +1. [Game dir overview](Starting/Part1/Gamedir-Overview.md) +1. [Python classes and objects](Starting/Part1/Python-classes-and-objects.md) +1. [Accessing the Evennia library](Starting/Part1/Evennia-Library-Overview.md) +1. [Typeclasses - Persistent objects](Starting/Part1/Learning-Typeclasses.md) +1. [Making our first own commands](Starting/Part1/Adding-Commands.md) +1. [Parsing and replacing default Commands](Starting/Part1/More-on-Commands.md) +1. [Creating things](Starting/Part1/Creating-Things.md) +1. [Searching for things](Starting/Part1/Searching-Things.md) +1. [Advanced searching with Django queries](Starting/Part1/Django-queries.md) ### Part 2: What we want -1. [Introduction & Overview](Starting/Part2/Starting-Part2) -1. [On planning a game](Starting/Part2/Game-Planning) -1. [Planning to use some useful Contribs](Starting/Part2/Planning-Some-Useful-Contribs) +1. [Introduction & Overview](Starting/Part2/Starting-Part2.md) +1. [On planning a game](Starting/Part2/Game-Planning.md) +1. [Planning to use some useful Contribs](Starting/Part2/Planning-Some-Useful-Contribs.md) ### Part3: How we get there -1. [Introduction & Overview](Starting/Part3/Starting-Part3) -1. [Making a custom Character](Starting/Part3/Implementing-a-game-rule-system) -1. [Character generation](../Unimplemented) -1. [Resolving skills and challenges](../Unimplemented) -1. [NPCs and mobiles](./Coordinates) -1. [Quests and Zones](../Unimplemented) -1. [A Combat system](../Unimplemented) +1. [Introduction & Overview](Starting/Part3/Starting-Part3.md) +1. [Making a custom Character](Starting/Part3/Implementing-a-game-rule-system.md) +1. [Character generation](../Unimplemented.md) +1. [Resolving skills and challenges](../Unimplemented.md) +1. [NPCs and mobiles](./Coordinates.md) +1. [Quests and Zones](../Unimplemented.md) +1. [A Combat system](../Unimplemented.md) ### Part 4: Using what we created -1. [Introduction & Overview](Starting/Part4/Starting-Part4) -1. [Building the tech demo](../Unimplemented) -1. [Creating a game world](../Unimplemented) +1. [Introduction & Overview](Starting/Part4/Starting-Part4.md) +1. [Building the tech demo](../Unimplemented.md) +1. [Creating a game world](../Unimplemented.md) ### Part 5: Showing the world -1. [Introduction & Overview](Starting/Part5/Starting-Part5) -1. [Add a web page](Starting/Part5/Add-a-simple-new-web-page) -1. [More on adding web features](Starting/Part5/Web-Tutorial) -1. [Taking your game online](../Unimplemented) -1. [Next steps](../Unimplemented) +1. [Introduction & Overview](Starting/Part5/Starting-Part5.md) +1. [Add a web page](Starting/Part5/Add-a-simple-new-web-page.md) +1. [More on adding web features](Starting/Part5/Web-Tutorial.md) +1. [Taking your game online](../Unimplemented.md) +1. [Next steps](../Unimplemented.md) ## FAQs -- [Coding FAQ](./Coding-FAQ) +- [Coding FAQ](./Coding-FAQ.md) ## Howto's -- [Giving Exits a default error](./Default-Exit-Errors) -- [Add a command prompt](./Command-Prompt) -- [Don't allow spamming commands](./Command-Cooldown) -- [Commands that take time](./Command-Duration) -- [Configuring color](./Manually-Configuring-Color) -- [Tweet game stats](./Tutorial-Tweeting-Game-Stats) +- [Giving Exits a default error](./Default-Exit-Errors.md) +- [Add a command prompt](./Command-Prompt.md) +- [Don't allow spamming commands](./Command-Cooldown.md) +- [Commands that take time](./Command-Duration.md) +- [Configuring color](./Manually-Configuring-Color.md) +- [Tweet game stats](./Tutorial-Tweeting-Game-Stats.md) ## Mobs and NPCs -- [NPCs that listen to you](./Tutorial-NPCs-listening) -- [Mobs that attack you](./Tutorial-Aggressive-NPCs) -- [Shopkeepers](./NPC-shop-Tutorial) +- [NPCs that listen to you](./Tutorial-NPCs-listening.md) +- [Mobs that attack you](./Tutorial-Aggressive-NPCs.md) +- [Shopkeepers](./NPC-shop-Tutorial.md) ## Vehicles -- [Building a mech](./Building-a-mech-tutorial) -- [Building a train](./Tutorial-Vehicles) +- [Building a mech](./Building-a-mech-tutorial.md) +- [Building a train](./Tutorial-Vehicles.md) ## Systems -- [Understanding In-game time](./Gametime-Tutorial) -- [Understanding the Help system](./Help-System-Tutorial) -- [Adding mass to objects](./Mass-and-weight-for-objects) -- [Add weather](./Weather-Tutorial) +- [Understanding In-game time](./Gametime-Tutorial.md) +- [Understanding the Help system](./Help-System-Tutorial.md) +- [Adding mass to objects](./Mass-and-weight-for-objects.md) +- [Add weather](./Weather-Tutorial.md) ## Web-related tutorials -- [Add a wiki](./Add-a-wiki-on-your-website) -- [A web-based character generation](./Web-Character-Generation) -- [View Character on website](./Web-Character-View-Tutorial) +- [Add a wiki](./Add-a-wiki-on-your-website.md) +- [A web-based character generation](./Web-Character-Generation.md) +- [View Character on website](./Web-Character-View-Tutorial.md) ## Deep-dives -- [Parsing command inputs](./Parsing-commands-tutorial) -- [Understanding color-tags](./Understanding-Color-Tags) -- [Play paper&pen RPGs online with Evennia](./Evennia-for-roleplaying-sessions) -- [Evennia for Diku Users](./Evennia-for-Diku-Users) -- [Evennia for MUSH-Users](./Evennia-for-MUSH-Users) +- [Parsing command inputs](./Parsing-commands-tutorial.md) +- [Understanding color-tags](./Understanding-Color-Tags.md) +- [Play paper&pen RPGs online with Evennia](./Evennia-for-roleplaying-sessions.md) +- [Evennia for Diku Users](./Evennia-for-Diku-Users.md) +- [Evennia for MUSH-Users](./Evennia-for-MUSH-Users.md) diff --git a/docs/source/Howto/Manually-Configuring-Color.md b/docs/source/Howto/Manually-Configuring-Color.md index 276aae5bf9..392c233d2e 100644 --- a/docs/source/Howto/Manually-Configuring-Color.md +++ b/docs/source/Howto/Manually-Configuring-Color.md @@ -5,7 +5,7 @@ This is a small tutorial for customizing your character objects, using the examp turn on and off ANSI color parsing as an example. `@options NOCOLOR=True` will now do what this tutorial shows, but the tutorial subject can be applied to other toggles you may want, as well. -In the Building guide's [Colors](../Concepts/TextTags#coloured-text) page you can learn how to add color to your +In the Building guide's [Colors](../Concepts/Colors.md) page you can learn how to add color to your game by using special markup. Colors enhance the gaming experience, but not all users want color. Examples would be users working from clients that don't support color, or people with various seeing disabilities that rely on screen readers to play your game. Also, whereas Evennia normally @@ -26,7 +26,7 @@ configuration system for your characters. This is the basic sequence: Create a new module in `mygame/typeclasses` named, for example, `mycharacter.py`. Alternatively you can simply add a new class to 'mygamegame/typeclasses/characters.py'. -In your new module(or characters.py), create a new [Typeclass](../Components/Typeclasses) inheriting from +In your new module(or characters.py), create a new [Typeclass](../Components/Typeclasses.md) inheriting from `evennia.DefaultCharacter`. We will also import `evennia.utils.ansi`, which we will use later. ```python @@ -39,7 +39,7 @@ In your new module(or characters.py), create a new [Typeclass](../Components/Typ self.db.config_color = True ``` -Above we set a simple config value as an [Attribute](../Components/Attributes). +Above we set a simple config value as an [Attribute](../Components/Attributes.md). Let's make sure that new characters are created of this type. Edit your `mygame/server/conf/settings.py` file and add/change `BASE_CHARACTER_TYPECLASS` to point to your new @@ -158,7 +158,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet): ## More colors -Apart from ANSI colors, Evennia also supports **Xterm256** colors (See [Colors](../Concepts/TextTags#colored- +Apart from ANSI colors, Evennia also supports **Xterm256** colors (See [Colors](../Concepts/TextTags.md#colored- text)). The `msg()` method supports the `xterm256` keyword for manually activating/deactiving xterm256. It should be easy to expand the above example to allow players to customize xterm256 regardless of if Evennia thinks their client supports it or not. diff --git a/docs/source/Howto/Mass-and-weight-for-objects.md b/docs/source/Howto/Mass-and-weight-for-objects.md index fc4b028962..b4463bfd08 100644 --- a/docs/source/Howto/Mass-and-weight-for-objects.md +++ b/docs/source/Howto/Mass-and-weight-for-objects.md @@ -10,7 +10,7 @@ determine a character's burden weight for travel speed... The total mass of an contribute to the force of a weapon swing, or a speeding meteor to give it a potential striking force. -#### Objects +## Objects Now that we have reasons for keeping track of object mass, let's look at the default object class inside your mygame/typeclasses/objects.py and see how easy it is to total up mass from an object and @@ -36,7 +36,7 @@ default for Heavy types to something much larger than 1 gram or whatever unit yo non-default mass would be stored on the `mass` [[Attributes]] of the objects. -#### Characters and rooms +## Characters and rooms You can add a `get_mass` definition to characters and rooms, also. @@ -57,7 +57,7 @@ else: pass # Danger! Alarm sounds, cable snaps, elevator stops... ``` -#### Inventory +## Inventory Example of listing mass of items in your inventory: ```python @@ -95,4 +95,4 @@ class CmdInventory(MuxCommand): string = f"|wYou are carrying:\n{table}" self.caller.msg(string) -``` \ No newline at end of file +``` diff --git a/docs/source/Howto/NPC-shop-Tutorial.md b/docs/source/Howto/NPC-shop-Tutorial.md index e30c6a4573..db37508f95 100644 --- a/docs/source/Howto/NPC-shop-Tutorial.md +++ b/docs/source/Howto/NPC-shop-Tutorial.md @@ -1,6 +1,6 @@ # NPC shop Tutorial -This tutorial will describe how to make an NPC-run shop. We will make use of the [EvMenu](../Components/EvMenu) +This tutorial will describe how to make an NPC-run shop. We will make use of the [EvMenu](../Components/EvMenu.md) system to present shoppers with a menu where they can buy things from the store's stock. Our shop extends over two rooms - a "front" room open to the shop's customers and a locked "store @@ -19,13 +19,13 @@ compare it to the `gold` Attribute of the customer. If enough gold is available, deducted and the goods transferred from the store room to the inventory of the customer. - We will lock the store room so that only people with the right key can get in there. -### The shop menu +## The shop menu We want to show a menu to the customer where they can list, examine and buy items in the store. This menu should change depending on what is currently for sale. Evennia's *EvMenu* utility will manage -the menu for us. It's a good idea to [read up on EvMenu](../Components/EvMenu) if you are not familiar with it. +the menu for us. It's a good idea to [read up on EvMenu](../Components/EvMenu.md) if you are not familiar with it. -#### Designing the menu +### Designing the menu The shopping menu's design is straightforward. First we want the main screen. You get this when you enter a shop and use the `browse` or `buy` command: @@ -64,7 +64,7 @@ You cannot afford 5 gold for A rusty sword! ``` After this you should be back to the top level of the shopping menu again and can continue browsing. -#### Coding the menu +### Coding the menu EvMenu defines the *nodes* (each menu screen with options) as normal Python functions. Each node must be able to change on the fly depending on what items are currently for sale. EvMenu will @@ -164,10 +164,10 @@ need to return anything. In `buy_ware_result` we determine if the customer can a give proper return messages. This is also where we actually move the bought item into the inventory of the customer. -#### The command to start the menu +### The command to start the menu We could *in principle* launch the shopping menu the moment a customer steps into our shop room, but -this would probably be considered pretty annoying. It's better to create a [Command](../Components/Commands) for +this would probably be considered pretty annoying. It's better to create a [Command](../Components/Commands.md) for customers to explicitly wanting to shop around. ```python @@ -200,7 +200,7 @@ class CmdBuy(Command): This will launch the menu. The `EvMenu` instance is initialized with the path to this very module - since the only global functions available in this module are our menu nodes, this will work fine (you could also have put those in a separate module). We now just need to put this command in a -[CmdSet](../Components/Command-Sets) so we can add it correctly to the game: +[CmdSet](../Components/Command-Sets.md) so we can add it correctly to the game: ```python from evennia import CmdSet @@ -210,7 +210,7 @@ class ShopCmdSet(CmdSet): self.add(CmdBuy()) ``` -### Building the shop +## Building the shop There are really only two things that separate our shop from any other Room: @@ -219,7 +219,7 @@ There are really only two things that separate our shop from any other Room: the shop. For testing we could easily add these features manually to a room using `@py` or other admin -commands. Just to show how it can be done we'll instead make a custom [Typeclass](../Components/Typeclasses) for +commands. Just to show how it can be done we'll instead make a custom [Typeclass](../Components/Typeclasses.md) for the shop room and make a small command that builders can use to build both the shop and the storeroom at once. @@ -300,7 +300,7 @@ default-cmdset) before you can use it. Once having created the shop you can now `@open` a new exit to it. You could also easily expand the above command to automatically create exits to and from the new shop from your current location. -To avoid customers walking in and stealing everything, we create a [Lock](../Components/Locks) on the storage +To avoid customers walking in and stealing everything, we create a [Lock](../Components/Locks.md) on the storage door. It's a simple lock that requires the one entering to carry an object named `-storekey`. We even create such a key object and drop it in the shop for the new shop keeper to pick up. @@ -312,7 +312,7 @@ you need to come up with a more robust lock-key solution. You could add better default descriptions as part of the `@buildshop` command or leave descriptions this up to the Builder. -### The shop is open for business! +## The shop is open for business! We now have a functioning shop and an easy way for Builders to create it. All you need now is to `@open` a new exit from the rest of the game into the shop and put some sell-able items in the store @@ -328,7 +328,7 @@ would then be gone and the counter be wrong - the shop would pass us the next it Fixing these issues are left as an exercise. -If you want to keep the shop fully NPC-run you could add a [Script](../Components/Scripts) to restock the shop's +If you want to keep the shop fully NPC-run you could add a [Script](../Components/Scripts.md) to restock the shop's store room regularly. This shop example could also easily be owned by a human Player (run for them by a hired NPC) - the shop owner would get the key to the store room and be responsible for keeping it well stocked. diff --git a/docs/source/Howto/Parsing-commands-tutorial.md b/docs/source/Howto/Parsing-commands-tutorial.md index 4c5c4e79f2..33545b9849 100644 --- a/docs/source/Howto/Parsing-commands-tutorial.md +++ b/docs/source/Howto/Parsing-commands-tutorial.md @@ -2,7 +2,7 @@ This tutorial will elaborate on the many ways one can parse command arguments. The first step after -[adding a command](Starting/Part1/Adding-Commands) usually is to parse its arguments. There are lots of +[adding a command](Starting/Part1/Adding-Commands.md) usually is to parse its arguments. There are lots of ways to do it, but some are indeed better than others and this tutorial will try to present them. If you're a Python beginner, this tutorial might help you a lot. If you're already familiar with @@ -652,7 +652,7 @@ about... what is this `"book"`? To get an object from a string, we perform an Evennia search. Evennia provides a `search` method on all typeclassed objects (you will most likely use the one on characters or accounts). This method -supports a very wide array of arguments and has [its own tutorial](Starting/Part1/Searching-Things). +supports a very wide array of arguments and has [its own tutorial](Starting/Part1/Searching-Things.md). Some examples of useful cases follow: ### Local searches diff --git a/docs/source/Howto/Starting/Part1/Adding-Commands.md b/docs/source/Howto/Starting/Part1/Adding-Commands.md index 27e5b741bc..1701208210 100644 --- a/docs/source/Howto/Starting/Part1/Adding-Commands.md +++ b/docs/source/Howto/Starting/Part1/Adding-Commands.md @@ -7,7 +7,7 @@ A Command is something that handles the input from a user and causes a result to An example is `look`, which examines your current location and tells how it looks like and what is in it. -```sidebar:: Commands are not typeclassed +```{sidebar} Commands are not typeclassed If you just came from the previous lesson, you might want to know that Commands and CommandSets are not `typeclassed`. That is, instances of them are not saved to the @@ -181,7 +181,7 @@ class CmdEcho(Command): First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also automatically become the in-game help entry! Next we add the `func` method. It has one active line where it makes use of some of those variables we found the Command offers to us. If you did the -[basic Python tutorial](./Python-basic-introduction), you will recognize `.msg` - this will send a message +[basic Python tutorial](./Python-basic-introduction.md), you will recognize `.msg` - this will send a message to the object it is attached to us - in this case `self.caller`, that is, us. We grab `self.args` and includes that in the message. @@ -306,7 +306,7 @@ A lot of things to dissect here: `self.args.strip()` over and over, we store the stripped version in a _local variable_ `args`. Note that we don't modify `self.args` by doing this, `self.args` will still have the whitespace and is not the same as `args` in this example. -```sidebar:: if-statements +```{sidebar} if-statements The full form of the if statement is @@ -354,7 +354,7 @@ class MyCmdSet(CmdSet): ``` -```sidebar:: Errors in your code +```{sidebar} Errors in your code With longer code snippets to try, it gets more and more likely you'll make an error and get a `traceback` when you reload. This will either appear diff --git a/docs/source/Howto/Starting/Part1/Building-Quickstart.md b/docs/source/Howto/Starting/Part1/Building-Quickstart.md index 5c57c700dd..51da3dd88f 100644 --- a/docs/source/Howto/Starting/Part1/Building-Quickstart.md +++ b/docs/source/Howto/Starting/Part1/Building-Quickstart.md @@ -1,17 +1,17 @@ # Using the game and building stuff -In this lesson we will test out what we can do in-game out-of-the-box. Evennia ships with -[around 90 default commands](api:evennia.commands.default#modules), and while you can override those as you please, +In this lesson we will test out what we can do in-game out-of-the-box. Evennia ships with +[around 90 default commands](../../../Components/Default-Commands.md), and while you can override those as you please, they can be quite useful. -Connect and log into your new game and you will end up in the "Limbo" location. This +Connect and log into your new game and you will end up in the "Limbo" location. This is the only room in the game at this point. Let's explore the commands a little. -The default commands has syntax [similar to MUX](../../../Concepts/Using-MUX-as-a-Standard): +The default commands has syntax [similar to MUX](../../../Concepts/Using-MUX-as-a-Standard.md): command[/switch/switch...] [arguments ...] -An example would be +An example would be create/drop box @@ -21,32 +21,32 @@ or more inputs to the commands. It's common to use an equal sign (`=`) when assi an object. > Are you used to commands starting with @, like @create? That will work too. Evennia simply ignores -> the preceeding @. +> the preceeding @. ## Getting help - help - -Will give you a list of all commands available to you. Use + help + +Will give you a list of all commands available to you. Use help - -to see the in-game help for that command. + +to see the in-game help for that command. ## Looking around -The most common comman is +The most common comman is look - -This will show you the description of the current location. `l` is an alias. + +This will show you the description of the current location. `l` is an alias. When targeting objects in commands you have two special labels you can use, `here` for the current -room or `me`/`self` to point back to yourself. So +room or `me`/`self` to point back to yourself. So look me -will give you your own description. `look here` is, in this case, the same as plain `look`. +will give you your own description. `look here` is, in this case, the same as plain `look`. ## Stepping Down From Godhood @@ -81,9 +81,9 @@ This created a new 'box' (of the default object type) in your inventory. Use the name box = very large box;box;very;crate -```warning:: MUD clients and semi-colon +```{warning} MUD clients and semi-colon - Some traditional MUD clients use the semi-colon `;` to separate client inputs. If so, + Some traditional MUD clients use the semi-colon `;` to separate client inputs. If so, the above line will give an error. You need to change your client to use another command-separator or to put it in 'verbatim' mode. If you still have trouble, use the Evennia web client instead. @@ -99,8 +99,8 @@ used the `alias` command. We are currently carrying the box. Let's drop it (there is also a short cut to create and drop in one go by using the `/drop` switch, for example `create/drop box`). - - drop box + + drop box Hey presto - there it is on the ground, in all its normality. @@ -109,7 +109,7 @@ Hey presto - there it is on the ground, in all its normality. This will show some technical details about the box object. For now we will ignore what this information means. -Try to `look` at the box to see the (default) description. +Try to `look` at the box to see the (default) description. look box You see nothing special. @@ -125,20 +125,20 @@ dropped in the room, then try this: lock box = get:false() -Locks represent a rather [big topic](../../../Components/Locks), but for now that will do what we want. This will lock +Locks represent a rather [big topic](../../../Components/Locks.md), 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 thís default error message looks dull? The `get` command looks for an [Attribute](../../../Components/Attributes) +Think thís default error message looks dull? The `get` command looks for an [Attribute](../../../Components/Attributes.md) named `get_err_msg` for returning a nicer error message (we just happen to know this, you would need to peek into the [code](https://github.com/evennia/evennia/blob/master/evennia/commands/default/general.py#L235) 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. + 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. To see what this message string is in the future, you can use 'examine.' @@ -149,12 +149,12 @@ Examine will return the value of attributes, including color codes. `examine her the raw description of your current room (including color codes), so that you can copy-and-paste to set its description to something else. -You create new Commands (or modify existing ones) in Python outside the game. We will get to that -later, in the [Commands tutorial](./Adding-Commands). +You create new Commands (or modify existing ones) in Python outside the game. We will get to that +later, in the [Commands tutorial](./Adding-Commands.md). ## Get a Personality -[Scripts](../../../Components/Scripts) are powerful out-of-character objects useful for many "under the hood" things. +[Scripts](../../../Components/Scripts.md) are powerful out-of-character objects useful for many "under the hood" things. One of their optional abilities is to do things on a timer. To try out a first script, let's put one on ourselves. There is an example script in `evennia/contrib/tutorial_examples/bodyfunctions.py` that is called `BodyFunctions`. To add this to us we will use the `script` command: @@ -162,16 +162,16 @@ that is called `BodyFunctions`. To add this to us we will use the `script` comma script self = tutorial_examples.bodyfunctions.BodyFunctions This string will tell Evennia to dig up the Python code at the place we indicate. It already knows -to look in the `contrib/` folder, so we don't have to give the full path. +to look in the `contrib/` folder, so we don't have to give the full path. -> Note also how we use `.` instead of `/` (or `\` on Windows). This is a so-called "Python path". In a Python-path, +> Note also how we use `.` instead of `/` (or `\` on Windows). This is a so-called "Python path". In a Python-path, > you separate the parts of the path with `.` and skip the `.py` file-ending. Importantly, it also allows you to point to -Python code _inside_ files, like the `BodyFunctions` class inside `bodyfunctions.py` (we'll get to classes later). -These "Python-paths" are used extensively throughout Evennia. +Python code _inside_ files, like the `BodyFunctions` class inside `bodyfunctions.py` (we'll get to classes later). +These "Python-paths" are used extensively throughout Evennia. Wait a while and you will notice yourself starting making random observations ... - script self + 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 @@ -183,14 +183,14 @@ When you are tired of your character's "insights", kill the script with script/stop self = tutorial_examples.bodyfunctions.BodyFunctions You create your own scripts in Python, outside the game; the path you give to `script` is literally -the Python path to your script file. The [Scripts](../../../Components/Scripts) page explains more details. +the Python path to your script file. The [Scripts](../../../Components/Scripts.md) page explains more details. ## Pushing Your Buttons If we get back to the box we made, there is only so much fun you can have 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](../../../Components/Typeclasses), [Scripts](../../../Components/Scripts) -and object-based [Commands](../../../Components/Commands), you could expand it and other items to be as unique, complex +the wiser. However, with the combined use of custom [Typeclasses](../../../Components/Typeclasses.md), [Scripts](../../../Components/Scripts.md) +and object-based [Commands](../../../Components/Commands.md), 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 @@ -206,18 +206,18 @@ The same way we did with the Script Earler, we specify a "Python-path" to the Py to use for creating the object. 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 [Typeclass](../../../Components/Typeclasses) and [Commands](../../../Components/Commands) controlling it are -inside [evennia/contrib/tutorial_examples](api:evennia.contrib.tutorial_examples) +that the [Typeclass](../../../Components/Typeclasses.md) and [Commands](../../../Components/Commands.md) controlling it are +inside [evennia/contrib/tutorial_examples](../../../api/evennia.contrib.tutorial_examples.md) -If you wait for a while (make sure you dropped it!) the button will blink invitingly. +If you wait for a while (make sure you dropped it!) the button will blink invitingly. -Why don't you try to push it ...? +Why don't you try to push it ...? -Surely a big red button is meant to be pushed. +Surely a big red button is meant to be pushed. You know you want to. -```warning:: Don't press the invitingly blinking red button. +```{warning} Don't press the invitingly blinking red button. ``` ## Making Yourself a House @@ -242,14 +242,14 @@ also up/down and in/out). It's called `tunnel`: 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: +You can create new exits from where you are, using the `open` command: open north;n = house This opens an exit `north` (with an alias `n`) 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. +want to link to. Follow the north exit to your 'house' or `teleport` to it: @@ -274,7 +274,7 @@ _large box_ to our house. very large box is leaving Limbo, heading for house. Teleported very large box -> house. -We can still find the box by using find: +We can still find the box by using find: find box One Match(#1-#8): @@ -291,15 +291,15 @@ We are getting tired of the box. Let's destroy it. destroy box -It will ask you for confirmation. Once you give it, the box will be gone. +It will ask you for confirmation. Once you give it, the box will be gone. You can destroy many objects in one go by giving a comma-separated list of objects (or a range of #dbrefs, if they are not in the same location) to the command. ## Adding a Help Entry -The Command-help is something you modify in Python code. We'll get to that when we get to how to -add Commands. But you can also add regular help entries, for example to explain something about +The Command-help is something you modify in Python code. We'll get to that when we get to how to +add Commands. But you can also add regular help entries, for example to explain something about the history of your game world: sethelp/add History = At the dawn of time ... @@ -308,5 +308,5 @@ You will now find your new `History` entry in the `help` list and read your help ## Adding a World -After this brief introduction to building and using in-game commands you may be ready to see a more fleshed-out +After this brief introduction to building and using in-game commands you may be ready to see a more fleshed-out example. Evennia comes with a tutorial world for you to explore. We will try that out in the next section. diff --git a/docs/source/Howto/Starting/Part1/Creating-Things.md b/docs/source/Howto/Starting/Part1/Creating-Things.md index 163d54049f..8e55296e8f 100644 --- a/docs/source/Howto/Starting/Part1/Creating-Things.md +++ b/docs/source/Howto/Starting/Part1/Creating-Things.md @@ -20,7 +20,7 @@ Given the path to a Typeclass, there are three ways to create an instance of it: This is the recommended way if you are trying to create things in Python. The first argument can either be the class _or_ the python-path to the typeclass, like `"path.to.SomeTypeClass"`. It can also be `None` in which case the Evennia default will be used. While all the creation methods - are available on `evennia`, they are actually implemented in [evennia/utils/create.py](api:evennia.utils.create). + are available on `evennia`, they are actually implemented in [evennia/utils/create.py](../../../api/evennia.utils.create.md). - Finally, you can create objects using an in-game command, such as create/drop obj:path.to.SomeTypeClass diff --git a/docs/source/Howto/Starting/Part1/Django-queries.md b/docs/source/Howto/Starting/Part1/Django-queries.md index e5003df9c7..9d5586496a 100644 --- a/docs/source/Howto/Starting/Part1/Django-queries.md +++ b/docs/source/Howto/Starting/Part1/Django-queries.md @@ -1,88 +1,88 @@ # Django Database queries -```important:: More advanced lesson! - - Learning about Django's queryset language is very useful once you start doing more advanced things - in Evennia. But it's not strictly needed out the box and can be a little overwhelming for a first - reading. So if you are new to Python and Evennia, feel free to just skim this lesson and refer +```{important} More advanced lesson! + + Learning about Django's queryset language is very useful once you start doing more advanced things + in Evennia. But it's not strictly needed out the box and can be a little overwhelming for a first + reading. So if you are new to Python and Evennia, feel free to just skim this lesson and refer back to it later when you've gained more experience. ``` -The search functions and methods we used in the previous lesson are enough for most cases. -But sometimes you need to be more specific: +The search functions and methods we used in the previous lesson are enough for most cases. +But sometimes you need to be more specific: - You want to find all `Characters` ... -- ... who are in Rooms tagged as `moonlit` ... +- ... who are in Rooms tagged as `moonlit` ... - ... _and_ who has the Attribute `lycantrophy` with a level higher than 2 ... -- ... because they'll should immediately transform to werewolves! +- ... because they'll should immediately transform to werewolves! -In principle you could achieve this with the existing search functions combined with a lot of loops -and if statements. But for something non-standard like this, querying the database directly will be +In principle you could achieve this with the existing search functions combined with a lot of loops +and if statements. But for something non-standard like this, querying the database directly will be much more efficient. Evennia uses [Django](https://www.djangoproject.com/) to handle its connection to the database. -A [django queryset](https://docs.djangoproject.com/en/3.0/ref/models/querysets/) represents -a database query. One can add querysets together to build ever-more complicated queries. Only when -you are trying to use the results of the queryset will it actually call the database. +A [django queryset](https://docs.djangoproject.com/en/3.0/ref/models/querysets/) represents +a database query. One can add querysets together to build ever-more complicated queries. Only when +you are trying to use the results of the queryset will it actually call the database. -The normal way to build a queryset is to define what class of entity you want to search by getting its -`.objects` resource, and then call various methods on that. We've seen this one before: +The normal way to build a queryset is to define what class of entity you want to search by getting its +`.objects` resource, and then call various methods on that. We've seen this one before: all_weapons = Weapon.objects.all() - -This is now a queryset representing all instances of `Weapon`. If `Weapon` had a subclass `Cannon` and we + +This is now a queryset representing all instances of `Weapon`. If `Weapon` had a subclass `Cannon` and we only wanted the cannons, we would do all_cannons = Cannon.objects.all() -Note that `Weapon` and `Cannon` are different typeclasses. You won't find any `Cannon` instances in -the `all_weapon` result above, confusing as that may sound. To get instances of a Typeclass _and_ the +Note that `Weapon` and `Cannon` are different typeclasses. You won't find any `Cannon` instances in +the `all_weapon` result above, confusing as that may sound. To get instances of a Typeclass _and_ the instances of all its children classes you need to use `_family`: -```sidebar:: _family +```{sidebar} _family - The all_family, filter_family etc is an Evennia-specific + The all_family, filter_family etc is an Evennia-specific thing. It's not part of regular Django. ``` really_all_weapons = Weapon.objects.all_family() - -This result now contains both `Weapon` and `Cannon` instances. -To limit your search by other criteria than the Typeclass you need to use `.filter` -(or `.filter_family`) instead: +This result now contains both `Weapon` and `Cannon` instances. + +To limit your search by other criteria than the Typeclass you need to use `.filter` +(or `.filter_family`) instead: roses = Flower.objects.filter(db_key="rose") - -This is a queryset representing all objects having a `db_key` equal to `"rose"`. + +This is a queryset representing all objects having a `db_key` equal to `"rose"`. Since this is a queryset you can keep adding to it; this will act as an `AND` condition. local_roses = roses.filter(db_location=myroom) - -We could also have written this in one statement: + +We could also have written this in one statement: local_roses = Flower.objects.filter(db_key="rose", db_location=myroom) - + We can also `.exclude` something from results local_non_red_roses = local_roses.exclude(db_key="red_rose") - -Only until we actually try to examine the result will the database be called. Here it's called when we -try to loop over the queryset: + +Only until we actually try to examine the result will the database be called. Here it's called when we +try to loop over the queryset: for rose in local_non_red_roses: print(rose) - -From now on, the queryset is _evaluated_ and we can't keep adding more queries to it - we'd need to + +From now on, the queryset is _evaluated_ and we can't keep adding more queries to it - we'd need to create a new queryset if we wanted to find some other result. Other ways to evaluate the queryset is to print it, convert it to a list with `list()` and otherwise try to access its results. - + Note how we use `db_key` and `db_location`. This is the actual names of these database fields. By convention Evennia uses `db_` in front of every database field. When you use the normal Evennia search helpers and objects -you can skip the `db_` but here we are calling the database directly and need to use the 'real' names. +you can skip the `db_` but here we are calling the database directly and need to use the 'real' names. -Here are the most commonly used methods to use with the `objects` managers: +Here are the most commonly used methods to use with the `objects` managers: - `filter` - query for a listing of objects based on search criteria. Gives empty queryset if none were found. @@ -91,71 +91,71 @@ found. - `all` - get all instances of the particular type. - `filter_family` - like `filter`, but search all sub classes as well. - `get_family` - like `get`, but search all sub classes as well. -- `all_family` - like `all`, but return entities of all subclasses as well. +- `all_family` - like `all`, but return entities of all subclasses as well. -> All of Evennia search functions use querysets under the hood. The `evennia.search_*` functions actually +> All of Evennia search functions use querysets under the hood. The `evennia.search_*` functions actually > return querysets, which means you could in principle keep adding queries to their results as well. -### Queryset field lookups +## Queryset field lookups -Above we found roses with exactly the `db_key` `"rose"`. This is an _exact_ match that is _case sensitive_, -so it would not find `"Rose"`. +Above we found roses with exactly the `db_key` `"rose"`. This is an _exact_ match that is _case sensitive_, +so it would not find `"Rose"`. # this is case-sensitive and the same as = roses = Flower.objects.filter(db_key__exact="rose" - + # the i means it's case-insensitive roses = Flower.objects.filter(db_key__iexact="rose") - -The Django field query language uses `__` in the same way as Python uses `.` to access resources. This -is because `.` is not allowed in a function keyword. + +The Django field query language uses `__` in the same way as Python uses `.` to access resources. This +is because `.` is not allowed in a function keyword. roses = Flower.objects.filter(db_key__icontains="rose") - -This will find all flowers whose name contains the string `"rose"`, like `"roses"`, `"wild rose"` etc. The -`i` in the beginning makes the search case-insensitive. Other useful variations to use -are `__istartswith` and `__iendswith`. You can also use `__gt`, `__ge` for "greater-than"/"greater-or-equal-than" + +This will find all flowers whose name contains the string `"rose"`, like `"roses"`, `"wild rose"` etc. The +`i` in the beginning makes the search case-insensitive. Other useful variations to use +are `__istartswith` and `__iendswith`. You can also use `__gt`, `__ge` for "greater-than"/"greater-or-equal-than" comparisons (same for `__lt` and `__le`). There is also `__in`: swords = Weapons.objects.filter(db_key__in=("rapier", "two-hander", "shortsword")) - + One also uses `__` to access foreign objects like Tags. Let's for example assume this is how we identify mages: char.tags.add("mage", category="profession") -Now, in this case we have an Evennia helper to do this search: +Now, in this case we have an Evennia helper to do this search: mages = evennia.search_tags("mage", category="profession") But this will find all Objects with this tag+category. Maybe you are only looking for Vampire mages: sparkly_mages = Vampire.objects.filter(db_tags__db_key="mage", db_tags__db_category="profession") - -This looks at the `db_tags` field on the `Vampire` and filters on the values of each tag's + +This looks at the `db_tags` field on the `Vampire` and filters on the values of each tag's `db_key` and `db_category` together. - -For more field lookups, see the + +For more field lookups, see the [django docs](https://docs.djangoproject.com/en/3.0/ref/models/querysets/#field-lookups) on the subject. -### Get that werewolf ... +## Get that werewolf ... -Let's see if we can make a query for the werewolves in the moonlight we mentioned at the beginning -of this section. +Let's see if we can make a query for the werewolves in the moonlight we mentioned at the beginning +of this section. -Firstly, we make ourselves and our current location match the criteria, so we can test: +Firstly, we make ourselves and our current location match the criteria, so we can test: > py here.tags.add("moonlit") > py me.db.lycantrophy = 3 - -This is an example of a more complex query. We'll consider it an example of what is + +This is an example of a more complex query. We'll consider it an example of what is possible. -```sidebar:: Line breaks +```{sidebar} Line breaks - Note the way of writing this code. It would have been very hard to read if we just wrote it in + Note the way of writing this code. It would have been very hard to read if we just wrote it in one long line. But since we wrapped it in `(...)` we can spread it out over multiple lines - without worrying about line breaks! + without worrying about line breaks! ``` ```python @@ -172,30 +172,30 @@ will_transform = ( - **Line 3** - We want to find `Character`s, so we access `.objects` on the `Character` typeclass. - **Line 4** - We start to filter ... -- **Line 5** +- **Line 5** - ... by accessing the `db_location` field (usually this is a Room) - ... and on that location, we get the value of `db_tags` (this is a _many-to-many_ database field - that we can treat like an object for this purpose; it references all Tags on the location) + that we can treat like an object for this purpose; it references all Tags on the location) - ... and from those `Tags`, we looking for `Tags` whose `db_key` is "monlit" (non-case sensitive). - **Line 6** - ... We also want only Characters with `Attributes` whose `db_key` is exactly `"lycantrophy"` -- **Line 7** - ... at the same time as the `Attribute`'s `db_value` is greater-than 2. - -Running this query makes our newly lycantrrophic Character appear in `will_transform`. Success! +- **Line 7** - ... at the same time as the `Attribute`'s `db_value` is greater-than 2. -> Don't confuse database fields with [Attributes](../../../Components/Attributes) you set via `obj.db.attr = 'foo'` or +Running this query makes our newly lycantrrophic Character appear in `will_transform`. Success! + +> Don't confuse database fields with [Attributes](../../../Components/Attributes.md) you set via `obj.db.attr = 'foo'` or `obj.attributes.add()`. Attributes are custom database entities *linked* to an object. They are not -separate fields *on* that object like `db_key` or `db_location` are. +separate fields *on* that object like `db_key` or `db_location` are. -### Complex queries +## Complex queries All examples so far used `AND` relations. The arguments to `.filter` are added together with `AND` ("we want tag room to be "monlit" _and_ lycantrhopy be > 2"). -For queries using `OR` and `NOT` we need Django's -[Q object](https://docs.djangoproject.com/en/1.11/topics/db/queries/#complex-lookups-with-q-objects). It is -imported from Django directly: +For queries using `OR` and `NOT` we need Django's +[Q object](https://docs.djangoproject.com/en/1.11/topics/db/queries/#complex-lookups-with-q-objects). It is +imported from Django directly: - from django.db.models import Q + from django.db.models import Q The `Q` is an object that is created with the same arguments as `.filter`, for example @@ -205,28 +205,28 @@ You can then use this `Q` instance as argument in a `filter`: q1 = Q(db_key="foo") Character.objects.filter(q1) - -The useful thing about `Q` is that these objects can be chained together with special symbols (bit operators): -`|` for `OR` and `&` for `AND`. A tilde `~` in front negates the expression inside the `Q` and thus -works like `NOT`. + +The useful thing about `Q` is that these objects can be chained together with special symbols (bit operators): +`|` for `OR` and `&` for `AND`. A tilde `~` in front negates the expression inside the `Q` and thus +works like `NOT`. q1 = Q(db_key="Dalton") q2 = Q(db_location=prison) Character.objects.filter(q1 | ~q2) - + Would get all Characters that are either named "Dalton" _or_ which is _not_ in prison. The result is a mix -of Daltons and non-prisoners. +of Daltons and non-prisoners. Let us expand our original werewolf query. Not only do we want to find all Characters in a moonlit room -with a certain level of `lycanthrophy`. Now we also want the full moon to immediately transform people who were +with a certain level of `lycanthrophy`. Now we also want the full moon to immediately transform people who were recently bitten, even if their `lycantrophy` level is not yet high enough (more dramatic this way!). Let's say there is a Tag "recently_bitten" that controls this. -This is how we'd change our query: +This is how we'd change our query: ```python -from django.db.models import Q +from django.db.models import Q will_transform = ( Character.objects @@ -244,7 +244,7 @@ will_transform = ( That's quite compact. It may be easier to see what's going on if written this way: ```python -from django.db.models import Q +from django.db.models import Q q_moonlit = Q(db_location__db_tags__db_key__iexact="moonlit") q_lycantropic = Q(db_attributes__db_key="lycantrophy", db_attributes__db_value__gt=2) @@ -257,7 +257,7 @@ will_transform = ( ) ``` -```sidebar:: SQL +```{sidebar} SQL These Python structures are internally converted to SQL, the native language of the database. If you are familiar with SQL, these are many-to-many tables joined with `LEFT OUTER JOIN`, @@ -266,31 +266,31 @@ will_transform = ( ``` This reads as "Find all Characters in a moonlit room that either has the Attribute `lycantrophy` higher -than two _or_ which has the Tag `recently_bitten`". With an OR-query like this it's possible to find the -same Character via different paths, so we add `.distinct()` at the end. This makes sure that there is only +than two _or_ which has the Tag `recently_bitten`". With an OR-query like this it's possible to find the +same Character via different paths, so we add `.distinct()` at the end. This makes sure that there is only one instance of each Character in the result. -### Annotations +## Annotations What if we wanted to filter on some condition that isn't represented easily by a field on the object? Maybe we want to find rooms only containing five or more objects? -We *could* do it like this (don't actually do it this way!): +We *could* do it like this (don't actually do it this way!): ```python from typeclasses.rooms import Room - all_rooms = Rooms.objects.all() + all_rooms = Rooms.objects.all() rooms_with_five_objects = [] - for room in all_rooms: + for room in all_rooms: if len(room.contents) >= 5: rooms_with_five_objects.append(room) ``` -Above we get all rooms and then use `list.append()` to keep adding the right rooms -to an ever-growing list. This is _not_ a good idea, once your database grows this will -be unnecessarily computing-intensive. The database is much more suitable for this. +Above we get all rooms and then use `list.append()` to keep adding the right rooms +to an ever-growing list. This is _not_ a good idea, once your database grows this will +be unnecessarily computing-intensive. The database is much more suitable for this. _Annotations_ allow you to set a 'variable' inside the query that you can then access from other parts of the query. Let's do the same example as before directly in the database: @@ -307,10 +307,10 @@ rooms = ( ) ``` -`Count` is a Django class for counting the number of things in the database. +`Count` is a Django class for counting the number of things in the database. Here we first create an annotation `num_objects` of type `Count`. It creates an in-database function -that will count the number of results inside the database. +that will count the number of results inside the database. > Note the use of `location_set` in that `Count`. The `*_set` is a back-reference automatically created by Django. In this case it allows you to find all objects that *has the current object as location*. @@ -319,13 +319,13 @@ Next we filter on this annotation, using the name `num_objects` as something we use `num_objects__gte=5` which means that `num_objects` should be greater than 5. This is a little harder to get one's head around but much more efficient than lopping over all objects in Python. -### F-objects +## F-objects What if we wanted to compare two dynamic parameters against one another in a query? For example, what if -instead of having 5 or more objects, we only wanted objects that had a bigger inventory than they had -tags (silly example, but ...)? This can be with Django's +instead of having 5 or more objects, we only wanted objects that had a bigger inventory than they had +tags (silly example, but ...)? This can be with Django's [F objects](https://docs.djangoproject.com/en/1.11/ref/models/expressions/#f-expressions). -So-called F expressions allow you to do a query that looks at a value of each object in the database. +So-called F expressions allow you to do a query that looks at a value of each object in the database. ```python from django.db.models import Count, F @@ -334,24 +334,24 @@ from typeclasses.rooms import Room result = ( Room.objects .annotate( - num_objects=Count('locations_set'), + num_objects=Count('locations_set'), num_tags=Count('db_tags')) .filter(num_objects__gt=F('num_tags')) ) ``` -Here we used `.annotate` to create two in-query 'variables' `num_objects` and `num_tags`. We then +Here we used `.annotate` to create two in-query 'variables' `num_objects` and `num_tags`. We then directly use these results in the filter. Using `F()` allows for also the right-hand-side of the filter condition to be calculated on the fly, completely within the database. -### Grouping and returning only certain properties +## Grouping and returning only certain properties Suppose you used tags to mark someone belonging to an organization. Now you want to make a list and -need to get the membership count of every organization all at once. +need to get the membership count of every organization all at once. -The `.annotate`, `.values_list`, and `.order_by` queryset methods are useful for this. Normally when -you run a `.filter`, what you get back is a bunch of full typeclass instances, like roses or swords. -Using `.values_list` you can instead choose to only get back certain properties on objects. +The `.annotate`, `.values_list`, and `.order_by` queryset methods are useful for this. Normally when +you run a `.filter`, what you get back is a bunch of full typeclass instances, like roses or swords. +Using `.values_list` you can instead choose to only get back certain properties on objects. The `.order_by` method finally allows for sorting the results according to some criterion: @@ -372,7 +372,7 @@ Here we fetch all Characters who ... - ... along the way we count how many different Characters (each `id` is unique) we find for each organization and store it in a 'variable' `tagcount` using `.annotate` and `Count` - ... we use this count to sort the result in descending order of `tagcount` (descending because there is a minus sign, - default is increasing order but we want the most popular organization to be first). + default is increasing order but we want the most popular organization to be first). - ... and finally we make sure to only return exactly the properties we want, namely the name of the organization tag and how many matches we found for that organization. @@ -380,18 +380,18 @@ The result queryset will be a list of tuples ordered in descending order by the in a format like the following: ``` [ - ('Griatch's poets society', 3872), - ("Chainsol's Ainneve Testers", 2076), + ('Griatch's poets society', 3872), + ("Chainsol's Ainneve Testers", 2076), ("Blaufeuer's Whitespace Fixers", 1903), ("Volund's Bikeshed Design Crew", 1764), ("Tehom's Glorious Misanthropes", 1763) ] ``` -## Conclusions +## Conclusions -We have covered a lot of ground in this lesson and covered several more complex topics. Knowing how to -query using Django is a powerful skill to have. +We have covered a lot of ground in this lesson and covered several more complex topics. Knowing how to +query using Django is a powerful skill to have. This concludes the first part of the Evennia starting tutorial - "What we have". Now we have a good foundation to understand how to plan what our tutorial game will be about. diff --git a/docs/source/Howto/Starting/Part1/Evennia-Library-Overview.md b/docs/source/Howto/Starting/Part1/Evennia-Library-Overview.md index 795561c73d..70c66ce882 100644 --- a/docs/source/Howto/Starting/Part1/Evennia-Library-Overview.md +++ b/docs/source/Howto/Starting/Part1/Evennia-Library-Overview.md @@ -1,126 +1,123 @@ # Overview of the Evennia library -```sidebar:: API +```{sidebar} API API stands for `Application Programming Interface`, a description for how to access the resources of a program or library. ``` -A good place to start exploring Evennia is the [Evenia-API frontpage](../../../Evennia-API). -This page sums up the main components of Evennia with a short description of each. Try clicking through +A good place to start exploring Evennia is the [Evenia-API frontpage](../../../Evennia-API.md). +This page sums up the main components of Evennia with a short description of each. Try clicking through to a few entries - once you get deep enough you'll see full descriptions -of each component along with their documentation. You can also click `[source]` to see the full Python source -for each thing. +of each component along with their documentation. You can also click `[source]` to see the full Python source +for each thing. You can also browse [the evennia repository on github](https://github.com/evennia/evennia). This is exactly -what you can download from us. The github repo is also searchable. - -Finally, you can clone the evennia repo to your own computer and read the sources locally. This is necessary -if you want to help with Evennia's development itself. See the - [extended install instructions](../../../Setup/Extended-Installation) if you want to do this. - -### Where is it? - -If Evennia is installed, you can import from it simply with +what you can download from us. The github repo is also searchable. + +Finally, you can clone the evennia repo to your own computer and read the sources locally. This is necessary +if you want to help with Evennia's development itself. See the + [extended install instructions](../../../Setup/Extended-Installation.md) if you want to do this. + +## Where is it? + +If Evennia is installed, you can import from it simply with import evennia from evennia import some_module - from evennia.some_module.other_module import SomeClass - -and so on. - + from evennia.some_module.other_module import SomeClass + +and so on. + If you installed Evennia with `pip install`, the library folder will be installed deep inside your Python -installation. If you cloned the repo there will be a folder `evennia` on your hard drive there. +installation. If you cloned the repo there will be a folder `evennia` on your hard drive there. If you cloned the repo or read the code on `github` you'll find this being the outermost structure: - evennia/ - bin/ + evennia/ + bin/ CHANGELOG.md ... ... docs/ - evennia/ + evennia/ -This outer layer is for Evennia's installation and package distribution. That internal folder `evennia/evennia/` is +This outer layer is for Evennia's installation and package distribution. That internal folder `evennia/evennia/` is the _actual_ library, the thing covered by the API auto-docs and what you get when you do `import evennia`. -> The `evennia/docs/` folder contains the sources for this documentation. See -> [contributing to the docs](../../../Contributing-Docs) if you want to learn more about how this works. +> The `evennia/docs/` folder contains the sources for this documentation. See +> [contributing to the docs](../../../Contributing-Docs.md) if you want to learn more about how this works. This the the structure of the Evennia library: - evennia - - [`__init__.py`](../../../Evennia-API#shortcuts) - The "flat API" of Evennia resides here. - - [`settings_default.py`](../../../Components/Server-Conf#Settings-file) - Root settings of Evennia. Copy settings + - [`__init__.py`](../../../Evennia-API.md#shortcuts) - The "flat API" of Evennia resides here. + - [`settings_default.py`](../../../Setup/Server-Conf.md#settings-file) - Root settings of Evennia. Copy settings from here to `mygame/server/settings.py` file. - - [`commands/`](../../../Components/Commands) - The command parser and handler. - - `default/` - The [default commands](api:evennia.commands.default#modules) and cmdsets. - - [`comms/`](../../../Components/Communications) - Systems for communicating in-game. + - [`commands/`](../../../Components/Commands.md) - The command parser and handler. + - `default/` - The [default commands](../../../Components/Default-Commands.md) and cmdsets. + - [`comms/`](../../../Components/Communications.md) - Systems for communicating in-game. - `contrib/` - Optional plugins too game-specific for core Evennia. - - `game_template/` - Copied to become the "game directory" when using `evennia --init`. - - [`help/`](../../../Components/Help-System) - Handles the storage and creation of help entries. - - `locale/` - Language files ([i18n](../../../Concepts/Internationalization)). - - [`locks/`](../../../Components/Locks) - Lock system for restricting access to in-game entities. - - [`objects/`](../../../Components/Objects) - In-game entities (all types of items and Characters). - - [`prototypes/`](../../../Components/Prototypes) - Object Prototype/spawning system and OLC menu - - [`accounts/`](../../../Components/Accounts) - Out-of-game Session-controlled entities (accounts, bots etc) - - [`scripts/`](../../../Components/Scripts) - Out-of-game entities equivalence to Objects, also with timer support. - - [`server/`](../../../Components/Portal-And-Server) - Core server code and Session handling. + - `game_template/` - Copied to become the "game directory" when using `evennia --init`. + - [`help/`](../../../Components/Help-System.md) - Handles the storage and creation of help entries. + - `locale/` - Language files ([i18n](../../../Concepts/Internationalization.md)). + - [`locks/`](../../../Components/Locks.md) - Lock system for restricting access to in-game entities. + - [`objects/`](../../../Components/Objects.md) - In-game entities (all types of items and Characters). + - [`prototypes/`](../../../Components/Prototypes.md) - Object Prototype/spawning system and OLC menu + - [`accounts/`](../../../Components/Accounts.md) - Out-of-game Session-controlled entities (accounts, bots etc) + - [`scripts/`](../../../Components/Scripts.md) - Out-of-game entities equivalence to Objects, also with timer support. + - [`server/`](../../../Components/Portal-And-Server.md) - Core server code and Session handling. - `portal/` - Portal proxy and connection protocols. - - [`typeclasses/`](../../../Components/Typeclasses) - Abstract classes for the typeclass storage and database system. - - [`utils/`](../../../Components/Coding-Utils) - Various miscellaneous useful coding resources. - - [`web/`](../../../Concepts/Web-Features) - Web resources and webserver. Partly copied into game directory on initialization. + - [`typeclasses/`](../../../Components/Typeclasses.md) - Abstract classes for the typeclass storage and database system. + - [`utils/`](../../../Components/Coding-Utils.md) - Various miscellaneous useful coding resources. + - [`web/`](../../../Concepts/Web-Features.md) - Web resources and webserver. Partly copied into game directory on initialization. -```sidebar:: __init__.py +```{sidebar} __init__.py The `__init__.py` file is a special Python filename used to represent a Python 'package'. When you import `evennia` on its own, you import this file. When you do `evennia.foo` Python will - first look for a property `.foo` in `__init__.py` and then for a module or folder of that name - in the same location. + first look for a property `.foo` in `__init__.py` and then for a module or folder of that name + in the same location. ``` -While all the actual Evennia code is found in the various folders, the `__init__.py` represents the entire +While all the actual Evennia code is found in the various folders, the `__init__.py` represents the entire package `evennia`. It contains "shortcuts" to code that is actually located elsewhere. Most of these shortcuts -are listed if you [scroll down a bit](../../../Evennia-API) on the Evennia-API page. +are listed if you [scroll down a bit](../../../Evennia-API.md) on the Evennia-API page. ## An example of exploring the library In the previous lesson we took a brief look at `mygame/typeclasses/objects` as an example of a Python module. Let's -open it again. Inside is the `Object` class, which inherits from `DefaultObject`. +open it again. Inside is the `Object` class, which inherits from `DefaultObject`. Near the top of the module is this line: - + from evennia import DefaultObject -We want to figure out just what this DefaultObject offers. Since this is imported directly from `evennia`, we -are actually importing from `evennia/__init__.py`. +We want to figure out just what this DefaultObject offers. Since this is imported directly from `evennia`, we +are actually importing from `evennia/__init__.py`. -[Look at Line 189](evennia/__init__.py#L189) of `evennia/__init__.py` and you'll find this line: +[Look at Line 159](github:evennia/__init__.py#159) of `evennia/__init__.py` and you'll find this line: - from .objects.objects import DefaultObject + from .objects.objects import DefaultObject -```sidebar:: Relative and absolute imports +```{sidebar} Relative and absolute imports - The first full-stop in `from .objects.objects ...` means that + The first full-stop in `from .objects.objects ...` means that we are importing from the current location. This is called a `relative import`. By comparison, `from evennia.objects.objects` is an `absolute import`. In this particular - case, the two would give the same result. + case, the two would give the same result. ``` -> You can also look at [the right section of the API frontpage](../../../Evennia-API#typeclasses) and click through +> You can also look at [the right section of the API frontpage](../../../Evennia-API.md#typeclasses) and click through > to the code that way. -The fact that `DefaultObject` is imported into `__init__.py` here is what makes it possible to also import +The fact that `DefaultObject` is imported into `__init__.py` here is what makes it possible to also import it as `from evennia import DefaultObject` even though the code for the class is not actually here. -So to find the code for `DefaultObject` we need to look in `evennia/objects/objects.py`. Here's how -to look it up in the docs: - -1. Open the [API frontpage](../../../Evennia-API) -2. Locate the link to [evennia.objects](api:evennia.objects) and click on it. -3. Click through to [evennia.objects.objects](api:evennia.objects.objects). -4. You are now in the python module. Scroll down (or search in your web browser) to find the `DefaultObject` class. -5. You can now read what this does and what methods are on it. If you want to see the full source, click the - \[[source](src:evennia.objects.objects#DefaultObject)\] link. - +So to find the code for `DefaultObject` we need to look in `evennia/objects/objects.py`. Here's how +to look it up in the docs: +1. Open the [API frontpage](../../../Evennia-API.md) +2. Locate the link to [evennia.objects.objects](evennia.objects.objects) and click on it. +3 You are now in the python module. Scroll down (or search in your web browser) to find the `DefaultObject` class. +4 You can now read what this does and what methods are on it. If you want to see the full source, click the + \[source\] link next to it. diff --git a/docs/source/Howto/Starting/Part1/Gamedir-Overview.md b/docs/source/Howto/Starting/Part1/Gamedir-Overview.md index c18616d2f4..5c55ef9029 100644 --- a/docs/source/Howto/Starting/Part1/Gamedir-Overview.md +++ b/docs/source/Howto/Starting/Part1/Gamedir-Overview.md @@ -15,7 +15,7 @@ Like everywhere in the docs we'll assume it's called `mygame`. You may have noticed when we were building things in-game that we would often refer to code through "python paths", such as -```sidebar:: Python-paths +```{sidebar} Python-paths A 'python path' uses '.' instead of '/' or '`\\`' and skips the `.py` ending of files. It can also point to @@ -57,10 +57,10 @@ and how you point to it correctly. ## commands/ -The `commands/` folder holds Python modules related to creating and extending the [Commands](../../../Components/Commands) +The `commands/` folder holds Python modules related to creating and extending the [Commands](../../../Components/Commands.md) of Evennia. These manifest in game like the server understanding input like `look` or `dig`. -```sidebar:: Classes +```{sidebar} Classes A `class` is template for creating object-instances of a particular type in Python. We will explain classes in more detail in the next @@ -149,28 +149,28 @@ knows where they are and will read them to configure itself at startup. ### typeclasses/ -The [Typeclasses](../../../Components/Typeclasses) of Evennia are Evennia-specific Python classes whose instances save themselves +The [Typeclasses](../../../Components/Typeclasses.md) of Evennia are Evennia-specific Python classes whose instances save themselves to the database. This allows a Character to remain in the same place and your updated strength stat to still be the same after a server reboot. - [accounts.py](github:evennia/game_template/typeclasses/accounts.py) (Python-path: `typeclasses.accounts`) - An - [Account](../../../Components/Accounts) represents the player connecting to the game. It holds information like email, + [Account](../../../Components/Accounts.md) represents the player connecting to the game. It holds information like email, password and other out-of-character details. - [channels.py](github:evennia/game_template/typeclasses/channels.py) (Python-path: `typeclasses.channels`) - - [Channels](../../../Components/Channels) are used to manage in-game communication between players. + [Channels](../../../Components/Channels.md) are used to manage in-game communication between players. - [objects.py](github:evennia/game_template/typeclasses/objects.py) (Python-path: `typeclasses.objects`) - - [Objects](../../../Components/Objects) represent all things having a location within the game world. + [Objects](../../../Components/Objects.md) represent all things having a location within the game world. - [characters.py](github:evennia/game_template/typeclasses/characters.py) (Python-path: `typeclasses.characters`) - - The [Character](../../../Components/Objects#Characers) is a subclass of Objects, controlled by Accounts - they are the player's + The [Character](../../../Components/Objects.md#characters) is a subclass of Objects, controlled by Accounts - they are the player's avatars in the game world. - [rooms.py](github:evennia/game_template/typeclasses/rooms.py) (Python-path: `typeclasses.rooms`) - A - [Room](../../../Components/Objects#Room) is also a subclass of Object; describing discrete locations. While the traditional + [Room](../../../Components/Objects.md#rooms) is also a subclass of Object; describing discrete locations. While the traditional term is 'room', such a location can be anything and on any scale that fits your game, from a forest glade, an entire planet or an actual dungeon room. - [exits.py](github:evennia/game_template/typeclasses/exits.py) (Python-path: `typeclasses.exits`) - - [Exits](../../../Components/Objects#Exit) is another subclass of Object. Exits link one Room to another. + [Exits](../../../Components/Objects.md#exits) is another subclass of Object. Exits link one Room to another. - [scripts.py](github:evennia/game_template/typeclasses/scripts.py) (Python-path: `typeclasses.scripts`) - - [Scripts](../../../Components/Scripts) are 'out-of-character' objects. They have no location in-game and can serve as basis for + [Scripts](../../../Components/Scripts.md) are 'out-of-character' objects. They have no location in-game and can serve as basis for anything that needs database persistence, such as combat, weather, or economic systems. They also have the ability to execute code repeatedly, on a timer. @@ -200,8 +200,8 @@ people change and re-structure this in various ways to better fit their ideas. - [batch_cmds.ev](github:evennia/game_template/world/batch_cmds.ev) - This is an `.ev` file, which is essentially just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The - [Tutorial World](./Tutorial-World-Introduction) was built with such a batch-file. -- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes) is a way + [Tutorial World](./Tutorial-World-Introduction.md) was built with such a batch-file. +- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes.md) is a way to easily vary objects without changing their base typeclass. For example, one could use prototypes to tell that Two goblins, while both of the class 'Goblin' (so they follow the same code logic), should have different equipment, stats and looks. diff --git a/docs/source/Howto/Starting/Part1/Learning-Typeclasses.md b/docs/source/Howto/Starting/Part1/Learning-Typeclasses.md index a483f50f98..ef2320010f 100644 --- a/docs/source/Howto/Starting/Part1/Learning-Typeclasses.md +++ b/docs/source/Howto/Starting/Part1/Learning-Typeclasses.md @@ -2,7 +2,7 @@ Now that we have learned a little about how to find things in the Evennia library, let's use it. -In the [Python classes and objects](./Python-classes-and-objects) lesson we created the dragons Fluffy, Cuddly +In the [Python classes and objects](./Python-classes-and-objects.md) lesson we created the dragons Fluffy, Cuddly and Smaug and made them fly and breathe fire. So far our dragons are short-lived - whenever we `restart` the server or `quit()` out of python mode they are gone. @@ -65,7 +65,7 @@ If we knew what kind of methods and resources were available on `DefaultObject` change the way it works! > Hint: We will get back to this, but to learn what resources an Evennia parent like `DefaultObject` offers, -> easiest is to peek at its [API documentation](api:evennia.objects.objects#DefaultObject). The docstring for +> easiest is to peek at its [API documentation](evennia.objects.objects.DefaultObject). The docstring for > the `Object` class can also help. One thing that Evennia classes offers and which you don't get with vanilla Python classes is _persistence_. As @@ -110,7 +110,7 @@ from `DefaultObject`, just from further away! First reload the server as usual. We will need to create the dragon a little differently this time: -```sidebar:: Keyword arguments +```{sidebar} Keyword arguments Keyword arguments (like `db_key="Smaug"`) is a way to name the input arguments to a function or method. They make @@ -251,7 +251,7 @@ You are specifying exactly which typeclass you want to use to build the Giantess desc = You see nothing special. ------------------------------------------------------------------------------- -We used the `examine` command briefly in the [lesson about building in-game](./Building-Quickstart). Now these lines +We used the `examine` command briefly in the [lesson about building in-game](./Building-Quickstart.md). Now these lines may be more useful to us: - **Name/key** - The name of this thing. The value `(#14)` is probably different for you. This is the unique 'primary key' or _dbref_ for this entity in the database. @@ -294,7 +294,7 @@ But the reason Evennia knows to fall back to this class is not hard-coded - it's in [evennia/settings_default.py](https://github.com/evennia/evennia/blob/master/evennia/settings_default.py#L465), with the name `BASE_OBJECT_TYPECLASS`, which is set to `typeclasses.objects.Object`. -```sidebar:: Changing things +```{sidebar} Changing things While it's tempting to change folders around to your liking, this can make it harder to follow tutorials and may confuse if @@ -357,7 +357,7 @@ You got a lot longer output this time. You have a lot more going on than a simpl - **Session id(s)**: This identifies the _Session_ (that is, the individual connection to a player's game client). - **Account** shows, well the `Account` object associated with this Character and Session. - **Stored/Merged Cmdsets** and **Commands available** is related to which _Commands_ are stored on you. We will - get to them in the [next lesson](./Adding-Commands). For now it's enough to know these consitute all the + get to them in the [next lesson](./Adding-Commands.md). For now it's enough to know these consitute all the commands available to you at a given moment. - **Non-Persistent attributes** are Attributes that are only stored temporarily and will go away on next reload. @@ -391,7 +391,7 @@ class Character(DefaultCharacter): > py self.get_stats() (10, 12, 15) -```sidebar:: Tuples and lists +```{sidebar} Tuples and lists - A `list` is written `[a, b, c, d, ...]`. It can be modified after creation. - A `tuple` is written `(a, b, c, ...)`. It cannot be modified once created. @@ -451,7 +451,7 @@ class Character(DefaultCharacter): return self.db.str, self.db.dex, self.db.int ``` -```sidebar:: Spaces in Attribute name? +```{sidebar} Spaces in Attribute name? What if you want spaces in your Attribute name? Or you want to assign the name of the Attribute on-the fly? Then you can use `.attributes.add(name, value)` instead, @@ -506,7 +506,7 @@ in more detail. For now, let's give every new character some random stats to sta We want those stats to be set only once, when the object is first created. For the Character, this method is called `at_object_creation`. -```sidebar:: __init__ vs at_object_creation +```{sidebar} __init__ vs at_object_creation For the `Monster` class we used `__init__` to set up the class. We can't use this for a typeclass because it will be called more than once, at the very least after @@ -583,7 +583,7 @@ this is done (still in python multi-line mode): > for char in Character.objects.all() > char.at_object_creation() -```sidebar:: Database queries +```{sidebar} Database queries `Character.objects.all()` is an example of a database query expressed in Python. This will be converted into a database query under the hood. This syntax is part of diff --git a/docs/source/Howto/Starting/Part1/More-on-Commands.md b/docs/source/Howto/Starting/Part1/More-on-Commands.md index a730bc5d06..00911c05ba 100644 --- a/docs/source/Howto/Starting/Part1/More-on-Commands.md +++ b/docs/source/Howto/Starting/Part1/More-on-Commands.md @@ -75,7 +75,7 @@ The `parse` method is called before `func` and has access to all the same on-com your parsing - if you wanted some other Command to also understand input on the form ` with ` you'd inherit from this class and just implement the `func` needed for that command without implementing `parse` anew. -```sidebar:: Tuples and Lists +```{sidebar} Tuples and Lists - A `list` is written as `[a, b, c, d, ...]`. You can add and grow/shrink a list after it was first created. - A `tuple` is written as `(a, b, c, d, ...)`. A tuple cannot be modified once it is created. @@ -143,8 +143,8 @@ change (no code changed, only stuff in the database). ## Adding a Command to an object The commands of a cmdset attached to an object with `obj.cmdset.add()` will by default be made available to that object -but _also to those in the same location as that object_. If you did the [Building introduction](./Building-Quickstart) -you've seen an example of this with the "Red Button" object. The [Tutorial world](./Tutorial-World-Introduction) +but _also to those in the same location as that object_. If you did the [Building introduction](./Building-Quickstart.md) +you've seen an example of this with the "Red Button" object. The [Tutorial world](./Tutorial-World-Introduction.md) also has many examples of objects with commands on them. To show how this could work, let's put our 'hit' Command on our simple `sword` object from the previous section. @@ -161,7 +161,7 @@ Let's try to swing it! hit-1 (sword #11) hit-2 -```sidebar:: Multi-matches +```{sidebar} Multi-matches Some game engines will just pick the first hit when finding more than one. Evennia will always give you a choice. The reason for this is that Evennia @@ -206,7 +206,7 @@ Let's get a little ahead of ourselves and make it so you have to _hold_ the swor be available. This involves a _Lock_. We've cover locks in more detail later, just know that they are useful for limiting the kind of things you can do with an object, including limiting just when you can call commands on it. -```sidebar:: Locks +```{sidebar} Locks Evennia Locks are defined as a mini-language defined in `lockstrings`. The lockstring is on a form `:`, where `situation` determines when this @@ -221,7 +221,7 @@ this object if you are _holding_ the object (that is, it's in your inventory). For locks to work, you cannot be _superuser_, since the superuser passes all locks. You need to `quell` yourself first: -```sidebar:: quell/unquell +```{sidebar} quell/unquell Quelling allows you as a developer to take on the role of players with less priveleges. This is useful for testing and debugging, in particular since a @@ -320,7 +320,7 @@ class SessionCmdSet(default_cmds.SessionCmdSet): # ``` -```sidebar:: super() +```{sidebar} super() The `super()` function refers to the parent of the current class and is commonly used to call same-named methods on the parent. @@ -474,7 +474,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet): self.add(mycommands.MyCmdGet) # ... ``` -```sidebar:: Another way +```{sidebar} Another way Instead of adding `MyCmdGet` explicitly in default_cmdset.py, you could also add it to `mycommands.MyCmdSet` and let it be diff --git a/docs/source/Howto/Starting/Part1/Python-basic-introduction.md b/docs/source/Howto/Starting/Part1/Python-basic-introduction.md index aa0be7d184..f2718cd252 100644 --- a/docs/source/Howto/Starting/Part1/Python-basic-introduction.md +++ b/docs/source/Howto/Starting/Part1/Python-basic-introduction.md @@ -5,7 +5,7 @@ which is a mature and professional programming language that is very fast to wor That said, even though Python is widely considered easy to learn, we can only cover the most immediately important aspects of Python in this series of starting tutorials. Hopefully we can get you started -but then you'll need to continue learning from there. See our [link section](../../../Links) for finding +but then you'll need to continue learning from there. See our [link section](../../../Links.md) for finding more reference material and dedicated Python tutorials. > While this will be quite basic if you are an experienced developer, you may want to at least @@ -17,7 +17,7 @@ superuser powers back: unquell -### Evennia Hello world +## Evennia Hello world The `py` Command (or `!`, which is an alias) allows you as a superuser to execute raw Python from in- game. This is useful for quick testing. From the game's input line, enter the following: @@ -25,7 +25,7 @@ game. This is useful for quick testing. From the game's input line, enter the fo > py print("Hello World!") -```sidebar:: Command input +```{sidebar} Command input The line with `>` indicates input to enter in-game, while the lines below are the expected return from that input. @@ -43,7 +43,7 @@ Python accepts both. A third variant is triple-quotes (`"""..."""` or `'''...''' lines and are common for larger text-blocks. The way we use the `py` command right now only supports single-line input however. -### Making some text 'graphics' +## Making some text 'graphics' When making a text-game you will, unsurprisingly, be working a lot with text. Even if you have the occational button or even graphical element, the normal process is for the user to input commands as @@ -72,7 +72,8 @@ is to use the `.format` _method_ of the string: > py print("This is a {} idea!".format("good")) This is a good idea! -```sidebar:: Functions and Methods +```{eval-rst} +.. sidebar:: Functions and Methods Function: Something that performs and action when you `call` it with zero or more `arguments`. A function @@ -111,7 +112,7 @@ To separate two Python instructions on the same line, you use the semi-colon, `; > py a = "awesome sauce" ; print("This is {}!".format(a)) This is awesome sauce! -```warning:: MUD clients and semi-colon +```{warning} MUD clients and semi-colon Some MUD clients use the semi-colon `;` to split client-inputs into separate sends. If so, the above will give an error. Most clients allow you to @@ -169,7 +170,7 @@ gives the normal text color. You can also use RGB (Red-Green-Blue) values from 0 Use the commands `color ansi` or `color xterm` to see which colors are available. Experiment! -### Importing code from other modules +## Importing code from other modules As we saw in the previous sections, we used `.format` to format strings and `me.msg` to access the `msg` method on `me`. This use of the full-stop character is used to access all sorts of resources, @@ -191,7 +192,7 @@ For now, only add one line to `test.py`: print("Hello World!") ``` -```sidebar:: Python module +```{sidebar} Python module This is a text file with the `.py` file ending. A module contains Python source code and from within Python one can @@ -306,7 +307,7 @@ print our text. We can now redo this as many times as we want without having to > py import world.test ; world.test.hello_world() Hello world! -### Sending text to others +## Sending text to others The `print` command is a standard Python structure. We can use that here in the `py` command since we can se the output. It's great for debugging and quick testing. But if you need to send a text @@ -332,7 +333,7 @@ For now, `print` and `me.msg` behaves the same, just remember that `print` is ma debugging and `.msg()` will be more useful for you in the future. -### Parsing Python errors +## Parsing Python errors Let's try this new text-sending in the function we just created. Go back to your `test.py` file and Replace the function with this instead: @@ -355,7 +356,7 @@ File "./world/test.py", line 2, in hello_world NameError: name 'me' is not defined ``` -```sidebar:: Errors in the logs +```{sidebar} Errors in the logs In regular use, tracebacks will often appear in the log rather than in the game. Use `evennia --log` to view the log in the terminal. Make @@ -386,7 +387,7 @@ reserved word (as mentioned, it's just something Evennia came up with for conven command). As far as the module is concerned `me` is an unfamiliar name, appearing out of nowhere. Hence the `NameError`. -### Passing arguments to functions +## Passing arguments to functions We know that `me` exists at the point when we run the `py` command, because we can do `py me.msg("Hello World!")` with no problem. So let's _pass_ that me along to the function so it knows what it should be. @@ -419,7 +420,7 @@ suitable targets. >and the concept of _Leap before you Look_. -### Finding others to send to +## Finding others to send to Let's wrap up this first Python `py` crash-course by finding someone else to send to. @@ -431,7 +432,7 @@ On the game command-line, let's create a mirror: > create/drop mirror:contrib.tutorial_examples.mirror.TutorialMirror -```sidebar:: Creating objects +```{sidebar} Creating objects The `create` command was first used to create boxes in the `Building Stuff `_ tutorial. Note how it @@ -466,7 +467,7 @@ Make sure you are in the same location as the mirror and try: `me.search("name")` will, by default, search and _return_ an object with the given name found in _the same location_ as the `me` object is. If it can't find anything you'll see an error. -```sidebar:: Function returns +```{sidebar} Function returns Whereas a function like `print` only prints its arguments, it's very common for functions/methods to `return` a result of some kind. Think of the function @@ -490,7 +491,7 @@ The mirror is useful for testing because its `.msg` method just echoes whatever would be to talk to a player character, in which case the text you sent would have appeared in their game client. -### Multi-line py +## Multi-line py So far we have use `py` in single-line mode, using `;` to separate multiple inputs. This is very convenient when you want to do some quick testing. But you can also start a full multi-line Python interactive interpreter @@ -524,7 +525,7 @@ the `>>>`). For brevity in this tutorual we'll turn the echo off. First exit `py [GCC 8.2.0] on Linux [py mode - quit() to exit] -```sidebar:: interactive py +```{sidebar} interactive py - Start with `py`. - Use `py/noecho` if you don't want your input to be echoed for every line. @@ -602,7 +603,7 @@ get at the first of them (counting starts from 0). Use `Ctrl-D` (`Cmd-D` on Mac) or `quit()` to exit the Python console. -### ipython +## ipython The default Python shell is quite limited and ugly. It's *highly* recommended to install `ipython` instead. This is a much nicer, third-party Python interpreter with colors and many usability improvements. @@ -614,8 +615,7 @@ If `ipython` is installed, `evennia shell` will use it automatically. evennia shell ... IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help - In [1]: -You now have Tab-completion: + In [1]: You now have Tab-completion: > import evennia > evennia. @@ -631,7 +631,7 @@ want to see the entire source code. As for the normal python interpreter, use `Ctrl-D`/`Cmd-D` or `quit()` to exit ipython. -```important:: Persistent code +```{important} Persistent code Common for both `py` and `python`/`ipython` is that the code you write is not persistent - it will be gone after you shut down the interpreter (but ipython will remember your input history). For making long-lasting @@ -639,7 +639,7 @@ As for the normal python interpreter, use `Ctrl-D`/`Cmd-D` or `quit()` to exit i ``` -## Conclusions +# Conclusions This covers quite a lot of basic Python usage. We printed and formatted strings, defined our own first function, fixed an error and even searched and talked to a mirror! Being able to access diff --git a/docs/source/Howto/Starting/Part1/Python-classes-and-objects.md b/docs/source/Howto/Starting/Part1/Python-classes-and-objects.md index 5388d11169..8803d6fc8c 100644 --- a/docs/source/Howto/Starting/Part1/Python-classes-and-objects.md +++ b/docs/source/Howto/Starting/Part1/Python-classes-and-objects.md @@ -5,13 +5,13 @@ We have also taken a look at what our game dir looks and what is where. Now we'l ## Importing things -No one writes something as big as an online game in one single huge file. Instead one breaks up the -code into separate files (modules). Each module is dedicated to different purposes. Not only does -it make things cleaner, organized and easier to understand. It also makes it easier to re-use code - -you just import the resources you need and know you only get just what you requested. This makes +No one writes something as big as an online game in one single huge file. Instead one breaks up the +code into separate files (modules). Each module is dedicated to different purposes. Not only does +it make things cleaner, organized and easier to understand. It also makes it easier to re-use code - +you just import the resources you need and know you only get just what you requested. This makes it much easier to find errors and to know what code is good and which has issues. -> Evennia itself uses your code in the same way - you just tell it where a particular type of code is, +> Evennia itself uses your code in the same way - you just tell it where a particular type of code is, and it will import and use it (often instead of its defaults). We have already successfully imported things, for example: @@ -19,11 +19,11 @@ We have already successfully imported things, for example: > py import world.test ; world.test.hello_world(me) Hello World! -In this example, on your hard drive, the files looks like this: +In this example, on your hard drive, the files looks like this: ``` mygame/ - world/ + world/ test.py <- inside this file is a function hello_world ``` @@ -35,71 +35,73 @@ def hello_world(who): who.msg("Hello World!") ``` -```sidebar:: Remember: +```{eval-rst} - - Indentation matters in Python +.. sidebar:: Remember: + + - Indentation matters in Python - So does capitalization - Use 4 `spaces` to indent, not tabs - Empty lines are fine - Anything on a line after a `#` is a `comment`, ignored by Python ``` -The _python_path_ describes the relation between Python resources, both between and inside -Python _modules_ (that is, files ending with .py). A python-path separates each part of the -path `.` and always skips the `.py` file endings. Also, Evennia already knows to start looking +The _python_path_ describes the relation between Python resources, both between and inside +Python _modules_ (that is, files ending with .py). A python-path separates each part of the +path `.` and always skips the `.py` file endings. Also, Evennia already knows to start looking for python resources inside `mygame/` so this should never be specified. Hence - import world.test + import world.test The `import` Python instruction loads `world.test` so you have it available. You can now go "into" this module to get to the function you want: - + world.test.hello_world(me) Using `import` like this means that you have to specify the full `world.test` every time you want -to get to your function. Here's a more powerful form of import: +to get to your function. Here's a more powerful form of import: from world.test import hello_world -The `from ... import ...` is very, very common as long as you want to get something with a longer +The `from ... import ...` is very, very common as long as you want to get something with a longer python path. It imports `hello_world` directly, so you can use it right away! > py from world.test import hello_world ; hello_world(me) Hello World! - + Let's say your `test.py` module had a bunch of interesting functions. You could then import them -all one by one: +all one by one: from world.test import hello_world, my_func, awesome_func - -If there were _a lot_ of functions, you could instead just import `test` and get the function + +If there were _a lot_ of functions, you could instead just import `test` and get the function from there when you need (without having to give the full `world.test` every time): > from world import test ; test.hello_world(me - Hello World! - -You can also _rename_ stuff you import. Say for example that the module you import to already + Hello World! + +You can also _rename_ stuff you import. Say for example that the module you import to already has a function `hello_world` but we also want to use the one from `world/test.py`: from world.test import hello_world as test_hello_world - -The form `from ... import ... as ...` renames the import. + +The form `from ... import ... as ...` renames the import. > from world.test import hello_world as hw ; hw(me) Hello World! - -> Avoid renaming unless it's to avoid a name-collistion like above - you want to make things as -> easy to read as possible, and renaming adds another layer of potential confusion. - -In [the basic intro to Python](./Python-basic-introduction) we learned how to open the in-game -multi-line interpreter. - > py +> Avoid renaming unless it's to avoid a name-collistion like above - you want to make things as +> easy to read as possible, and renaming adds another layer of potential confusion. + +In [the basic intro to Python](./Python-basic-introduction.md) we learned how to open the in-game +multi-line interpreter. + + > py Evennia Interactive Python mode Python 3.7.1 (default, Oct 22 2018, 11:21:55) [GCC 8.2.0] on Linux - [py mode - quit() to exit] - + [py mode - quit() to exit] + You now only need to import once to use the imported function over and over. > from world.test import hello_world @@ -112,14 +114,14 @@ You now only need to import once to use the imported function over and over. > quit() Closing the Python console. -The same goes when writing code in a module - in most Python modules you will see a bunch of +The same goes when writing code in a module - in most Python modules you will see a bunch of imports at the top, resources that are then used by all code in that module. -## On classes and objects +## On classes and objects Now that we know about imports, let look at a real Evennia module and try to understand it. -Open `mygame/typeclasses/objects.py` in your text editor of choice. +Open `mygame/typeclasses/objects.py` in your text editor of choice. ```python """ @@ -134,30 +136,30 @@ class Object(DefaultObject): pass ``` -```sidebar:: Docstrings vs Comments +```{sidebar} Docstrings vs Comments - A docstring is not the same as a comment (created by `#`). A - docstring is not ignored by Python but is an integral part of the thing + A docstring is not the same as a comment (created by `#`). A + docstring is not ignored by Python but is an integral part of the thing it is documenting (the module and the class in this case). ``` -The real file is much longer but we can ignore the multi-line strings (`""" ... """`). These serve -as documentation-strings, or _docstrings_ for the module (at the top) and the `class` below. +The real file is much longer but we can ignore the multi-line strings (`""" ... """`). These serve +as documentation-strings, or _docstrings_ for the module (at the top) and the `class` below. Below the module doc string we have the import. In this case we are importing a resource from the core `evennia` library itself. We will dive into this later, for now we just treat this -as a black box. +as a black box. Next we have a `class` named `Object`, which _inherits_ from `DefaultObject`. This class doesn't actually do anything on its own, its only code (except the docstring) is `pass` which means, -well, to pass and don't do anything. +well, to pass and don't do anything. -We will get back to this module in the [next lesson](./Learning-Typeclasses). First we need to do a -little detour to understand what a 'class', an 'object' or 'instance' is. These are fundamental -things to understand before you can use Evennia efficiently. -```sidebar:: OOP +We will get back to this module in the [next lesson](./Learning-Typeclasses.md). First we need to do a +little detour to understand what a 'class', an 'object' or 'instance' is. These are fundamental +things to understand before you can use Evennia efficiently. +```{sidebar} OOP - Classes, objects, instances and inheritance are fundamental to Python. This and some - other concepts are often clumped together under the term Object-Oriented-Programming (OOP). + Classes, objects, instances and inheritance are fundamental to Python. This and some + other concepts are often clumped together under the term Object-Oriented-Programming (OOP). ``` ### Classes and instances @@ -179,57 +181,58 @@ class Monster: ``` -Above we have defined a `Monster` class with one variable `key` (that is, the name) and one -_method_ on it. A method is like a function except it sits "on" the class. It also always has -at least one argument (almost always written as `self` although you could in principle use +Above we have defined a `Monster` class with one variable `key` (that is, the name) and one +_method_ on it. A method is like a function except it sits "on" the class. It also always has +at least one argument (almost always written as `self` although you could in principle use another name), which is a reference back to itself. So when we print `self.key` we are referring back to the `key` on the class. -```sidebar:: Terms +```{eval-rst} +.. sidebar:: Terms - A `class` is a code template describing a 'type' of something - - An `object` is an `instance` of a `class`. Like using a mold to cast tin soldiers, one class can be `instantiated` into any number of object-instances. + - An `object` is an `instance` of a `class`. Like using a mold to cast tin soldiers, one class can be `instantiated` into any number of object-instances. ``` A class is just a template. Before it can be used, we must create an _instance_ of the class. If -`Monster` is a class, then an instance is Fluffy, the individual red dragon. You instantiate -by _calling_ the class, much like you would a function: +`Monster` is a class, then an instance is Fluffy, the individual red dragon. You instantiate +by _calling_ the class, much like you would a function: fluffy = Monster() - + Let's try it in-game (we use multi-line mode, it's easier) - > py + > py > from typeclasses.monsters import Monster > fluffy = Monster() > fluffy.move_around() Monster is moving! -We created an _instance_ of `Monster`, which we stored in the variable `fluffy`. We then -called the `move_around` method on fluffy to get the printout. +We created an _instance_ of `Monster`, which we stored in the variable `fluffy`. We then +called the `move_around` method on fluffy to get the printout. -> Note how we _didn't_ call the method as `fluffy.move_around(self)`. While the `self` has to be -> there when defining the method, we _never_ add it explicitly when we call the method (Python -> will add the correct `self` for us automatically behind the scenes). +> Note how we _didn't_ call the method as `fluffy.move_around(self)`. While the `self` has to be +> there when defining the method, we _never_ add it explicitly when we call the method (Python +> will add the correct `self` for us automatically behind the scenes). Let's create the sibling of Fluffy, Cuddly: > cuddly = Monster() > cuddly.move_around() - Monster is moving! + Monster is moving! -We now have two dragons and they'll hang around until with call `quit()` to exit this Python -instance. We can have them move as many times as we want. But no matter how many dragons we +We now have two dragons and they'll hang around until with call `quit()` to exit this Python +instance. We can have them move as many times as we want. But no matter how many dragons we create, they will all show the same printout since `key` is always fixed as "Monster". -Let's make the class a little more flexible: +Let's make the class a little more flexible: ```python class Monster: - + def __init__(self, key): - self.key = key + self.key = key def move_around(self): print(f"{self.key} is moving!") @@ -237,7 +240,7 @@ class Monster: ``` The `__init__` is a special method that Python recognizes. If given, this handles extra arguments -when you instantiate a new Monster. We have it add an argument `key` that we store on `self`. +when you instantiate a new Monster. We have it add an argument `key` that we store on `self`. Now, for Evennia to see this code change, we need to reload the server. You can either do it this way: @@ -245,13 +248,13 @@ way: > quit() Python Console is closing. > reload - -Or you can use a separate terminal and restart from outside the game: -```sidebar:: On reloading + +Or you can use a separate terminal and restart from outside the game: +```{sidebar} On reloading Reloading with the python mode gets a little annoying since you need to redo everything - after every reload. Just keep in mind that during regular development you will not be - working this way. The in-game python mode is practical for quick fixes and experiments like + after every reload. Just keep in mind that during regular development you will not be + working this way. The in-game python mode is practical for quick fixes and experiments like this, but actual code is normally written externally, in python modules. ``` @@ -259,50 +262,50 @@ Or you can use a separate terminal and restart from outside the game: Either way you'll need to go into `py` again: - > py + > py > from typeclasses.monsters import Monster fluffy = Monster("Fluffy") fluffy.move_around() - Fluffy is moving! + Fluffy is moving! -Now we passed `"Fluffy"` as an argument to the class. This went into `__init__` and set `self.key`, which we +Now we passed `"Fluffy"` as an argument to the class. This went into `__init__` and set `self.key`, which we later used to print with the right name! Again, note that we didn't include `self` when calling. -### What's so good about objects? +### What's so good about objects? -So far all we've seen a class do is to behave our first `hello_world` function but more complex. We +So far all we've seen a class do is to behave our first `hello_world` function but more complex. We could just have made a function: ```python def monster_move_around(key): - print(f"{key} is moving!") + print(f"{key} is moving!") ``` -The difference between the function and an instance of a class (the object), is that the +The difference between the function and an instance of a class (the object), is that the object retains _state_. Once you called the function it forgets everything about what you called -it with last time. The object, on the other hand, remembers changes: +it with last time. The object, on the other hand, remembers changes: > fluffy.key = "Cuddly" > fluffy.move_around() - Cuddly is moving! - -The `fluffy` object's `key` was changed to "Cuddly" for as long as it's around. This makes objects -extremely useful for representing and remembering collections of data - some of which can be other -objects in turn: + Cuddly is moving! -- A player character with all its stats +The `fluffy` object's `key` was changed to "Cuddly" for as long as it's around. This makes objects +extremely useful for representing and remembering collections of data - some of which can be other +objects in turn: + +- A player character with all its stats - A monster with HP - A chest with a number of gold coins in it - A room with other objects inside it - The current policy positions of a political party - A rule with methods for resolving challenges or roll dice - A multi-dimenstional data-point for a complex economic simulation -- And so much more! +- And so much more! ### Classes can have children -Classes can _inherit_ from each other. A "child" class will inherit everything from its "parent" class. But if -the child adds something with the same name as its parent, it will _override_ whatever it got from its parent. +Classes can _inherit_ from each other. A "child" class will inherit everything from its "parent" class. But if +the child adds something with the same name as its parent, it will _override_ whatever it got from its parent. Let's expand `mygame/typeclasses/monsters.py` with another class: @@ -312,9 +315,9 @@ class Monster: """ This is a base class for Monster. """ - + def __init__(self, key): - self.key = key + self.key = key def move_around(self): print(f"{self.key} is moving!") @@ -329,7 +332,7 @@ class Dragon(Monster): print(f"{self.key} flies through the air high above!") def firebreath(self): - """ + """ Let our dragon breathe fire. """ print(f"{self.key} breathes fire!") @@ -339,10 +342,10 @@ class Dragon(Monster): We added some docstrings for clarity. It's always a good idea to add doc strings; you can do so also for methods, as exemplified for the new `firebreath` method. -We created the new class `Dragon` but we also specified that `Monster` is the _parent_ of `Dragon` but adding -the parent in parenthesis. `class Classname(Parent)` is the way to do this. +We created the new class `Dragon` but we also specified that `Monster` is the _parent_ of `Dragon` but adding +the parent in parenthesis. `class Classname(Parent)` is the way to do this. -```sidebar:: Multi-inheritance +```{sidebar} Multi-inheritance It's possible to add more comma-separated parents to a class. You should usually avoid this until you `really` know what you are doing. A single parent will be enough for almost @@ -352,61 +355,61 @@ the parent in parenthesis. `class Classname(Parent)` is the way to do this. Let's try out our new class. First `reload` the server and the do - > py - > from typeclasses.monsters import Dragon + > py + > from typeclasses.monsters import Dragon > smaug = Dragon("Smaug") > smaug.move_around() Smaug flies through the air high above! > smaug.firebreath() - Smaug breathes fire! - -Because we didn't implement `__init__` in `Dragon`, we got the one from `Monster` instead. But since we -implemented our own `move_around` in `Dragon`, it _overrides_ the one in `Monster`. And `firebreath` is only + Smaug breathes fire! + +Because we didn't implement `__init__` in `Dragon`, we got the one from `Monster` instead. But since we +implemented our own `move_around` in `Dragon`, it _overrides_ the one in `Monster`. And `firebreath` is only available for `Dragon`s of course. Having that on `Monster` would not have made much sense, since not every monster -can breathe fire. +can breathe fire. One can also force a class to use resources from the parent even if you are overriding some of it. This is done with the `super()` method. Modify your `Dragon` class as follows: ```python -# ... +# ... class Dragon(Monster): def move_around(self): super().move_around() print("The world trembles.") - + # ... ``` -> Keep `Monster` and the `firebreath` method, `# ...` indicates the rest of the code is untouched. +> Keep `Monster` and the `firebreath` method, `# ...` indicates the rest of the code is untouched. > -The `super().move_around()` line means that we are calling `move_around()` on the parent of the class. So in this -case, we will call `Monster.move_around` first, before doing our own thing. +The `super().move_around()` line means that we are calling `move_around()` on the parent of the class. So in this +case, we will call `Monster.move_around` first, before doing our own thing. -Now `reload` the server and then: +Now `reload` the server and then: - > py - > from typeclasses.monsters import Dragon + > py + > from typeclasses.monsters import Dragon > smaug = Dragon("Smaug") > smaug.move_around() Smaug is moving! The world trembles. -We can see that `Monster.move_around()` is calls first and prints "Smaug is moving!", followed by the extra bit +We can see that `Monster.move_around()` is calls first and prints "Smaug is moving!", followed by the extra bit about the trembling world we added in the `Dragon` class. Inheritance is very powerful because it allows you to organize and re-use code while only adding the special things -you want to change. Evennia uses this concept a lot. +you want to change. Evennia uses this concept a lot. ## Summary -We have created our first dragons from classes. We have learned a little about how you _instantiate_ a class +We have created our first dragons from classes. We have learned a little about how you _instantiate_ a class into an _object_. We have seen some examples of _inheritance_ and we tested to _override_ a method in the parent with one in the child class. We also used `super()` to good effect. -We have used pretty much raw Python so far. In the coming lessons we'll start to look at the extra bits that Evennia +We have used pretty much raw Python so far. In the coming lessons we'll start to look at the extra bits that Evennia provides. But first we need to learn just where to find everything. diff --git a/docs/source/Howto/Starting/Part1/Searching-Things.md b/docs/source/Howto/Starting/Part1/Searching-Things.md index 08e6363711..1b6b01ecf3 100644 --- a/docs/source/Howto/Starting/Part1/Searching-Things.md +++ b/docs/source/Howto/Starting/Part1/Searching-Things.md @@ -1,30 +1,30 @@ # Searching for things -We have gone through how to create the various entities in Evennia. But creating something is of little use -if we cannot find and use it afterwards. +We have gone through how to create the various entities in Evennia. But creating something is of little use +if we cannot find and use it afterwards. ## Main search functions -The base tools are the `evennia.search_*` functions, such as `evennia.search_object`. +The base tools are the `evennia.search_*` functions, such as `evennia.search_object`. rose = evennia.search_object(key="rose") acct = evennia.search_account(key="MyAccountName", email="foo@bar.com") -```sidebar:: Querysets +```{sidebar} Querysets - What is returned from the main search functions is actually a `queryset`. They can be + What is returned from the main search functions is actually a `queryset`. They can be treated like lists except that they can't modified in-place. We'll discuss querysets in the `next lesson` `_. ``` Strings are always case-insensitive, so searching for `"rose"`, `"Rose"` or `"rOsE"` give the same results. -It's important to remember that what is returned from these search methods is a _listing_ of 0, one or more -elements - all the matches to your search. To get the first match: +It's important to remember that what is returned from these search methods is a _listing_ of 0, one or more +elements - all the matches to your search. To get the first match: - rose = rose[0] + rose = rose[0] -Often you really want all matches to the search parameters you specify. In other situations, having zero or -more than one match is a sign of a problem and you need to handle this case yourself. +Often you really want all matches to the search parameters you specify. In other situations, having zero or +more than one match is a sign of a problem and you need to handle this case yourself. the_one_ring = evennia.search_object(key="The one Ring") if not the_one_ring: @@ -35,16 +35,16 @@ more than one match is a sign of a problem and you need to handle this case your # ok - exactly one ring found the_one_ring = the_one_ring[0] -There are equivalent search functions for all the main resources. You can find a listing of them -[in the Search functions section](../../../Evennia-API) of the API frontpage. +There are equivalent search functions for all the main resources. You can find a listing of them +[in the Search functions section](../../../Evennia-API.md) of the API frontpage. ## Searching using Object.search -On the `DefaultObject` is a `.search` method which we have already tried out when we made Commands. For -this to be used you must already have an object available: +On the `DefaultObject` is a `.search` method which we have already tried out when we made Commands. For +this to be used you must already have an object available: rose = obj.search("rose") - + The `.search` method wraps `evennia.search_object` and handles its output in various ways. - By default it will always search for objects among those in `obj.location.contents` and `obj.contents` (that is, @@ -52,7 +52,7 @@ things in obj's inventory or in the same room). - It will always return exactly one match. If it found zero or more than one match, the return is `None`. - On a no-match or multimatch, `.search` will automatically send an error message to `obj`. -So this method handles error messaging for you. A very common way to use it is in commands: +So this method handles error messaging for you. A very common way to use it is in commands: ```python from evennia import Command @@ -68,21 +68,21 @@ class MyCommand(Command): return ``` -Remember, `self.caller` is the one calling the command. This is usually a Character, which -inherits from `DefaultObject`! This (rather stupid) Command searches for an object named "foo" in -the same location. If it can't find it, `foo` will be `None`. The error has already been reported -to `self.caller` so we just abort with `return`. +Remember, `self.caller` is the one calling the command. This is usually a Character, which +inherits from `DefaultObject`! This (rather stupid) Command searches for an object named "foo" in +the same location. If it can't find it, `foo` will be `None`. The error has already been reported +to `self.caller` so we just abort with `return`. -You can use `.search` to find anything, not just stuff in the same room: +You can use `.search` to find anything, not just stuff in the same room: volcano = self.caller.search("Volcano", global=True) -If you only want to search for a specific list of things, you can do so too: +If you only want to search for a specific list of things, you can do so too: stone = self.caller.search("MyStone", candidates=[obj1, obj2, obj3, obj4]) - + This will only return a match if MyStone is one of the four provided candidate objects. This is quite powerful, -here's how you'd find something only in your inventory: +here's how you'd find something only in your inventory: potion = self.caller.search("Healing potion", candidates=self.caller.contents) @@ -90,25 +90,25 @@ You can also turn off the automatic error handling: swords = self.caller.search("Sword", quiet=True) -With `quiet=True` the user will not be notified on zero or multi-match errors. Instead you are expected to handle this -yourself and what you get back is now a list of zero, one or more matches! +With `quiet=True` the user will not be notified on zero or multi-match errors. Instead you are expected to handle this +yourself and what you get back is now a list of zero, one or more matches! ## What can be searched for These are the main database entities one can search for: -- [Objects](../../../Components/Objects) -- [Accounts](../../../Components/Accounts) -- [Scripts](../../../Components/Scripts), -- [Channels](../../../Components/Communications#channels), -- [Messages](Communication#Msg) -- [Help Entries](../../../Components/Help-System). +- [Objects](../../../Components/Objects.md) +- [Accounts](../../../Components/Accounts.md) +- [Scripts](../../../Components/Scripts.md), +- [Channels](../../../Components/Channels.md), +- [Messages](../../../Components/Msg.md) +- [Help Entries](../../../Components/Help-System.md). Most of the time you'll likely spend your time searching for Objects and the occasional Accounts. -So to find an entity, what can be searched for? +So to find an entity, what can be searched for? -### Search by key +### Search by key The `key` is the name of the entity. Searching for this is always case-insensitive. @@ -118,29 +118,29 @@ Objects and Accounts can have any number of aliases. When searching for `key` th you can't easily search only for aliases. rose.aliases.add("flower") - -If the above `rose` has a `key` `"Rose"`, it can now also be found by searching for `flower`. In-game + +If the above `rose` has a `key` `"Rose"`, it can now also be found by searching for `flower`. In-game you can assign new aliases to things with the `alias` command. ### Search by location - -Only Objects (things inheriting from `evennia.DefaultObject`) has a location. This is usually a room. + +Only Objects (things inheriting from `evennia.DefaultObject`) has a location. This is usually a room. The `Object.search` method will automatically limit it search by location, but it also works for the -general search function. If we assume `room` is a particular Room instance, +general search function. If we assume `room` is a particular Room instance, - chest = evennia.search_object("Treasure chest", location=room) + chest = evennia.search_object("Treasure chest", location=room) -### Search by Tags +### Search by Tags -Think of a [Tag](../../../Components/Tags) as the label the airport puts on your luggage when flying. -Everyone going on the same plane gets a tag grouping them together so the airport can know what should +Think of a [Tag](../../../Components/Tags.md) as the label the airport puts on your luggage when flying. +Everyone going on the same plane gets a tag grouping them together so the airport can know what should go to which plane. Entities in Evennia can be grouped in the same way. Any number of tags can be attached -to each object. +to each object. rose.tags.add("flowers") daffodil.tags.add("flowers") tulip.tags.add("flowers") - + You can now find all flowers using the `search_tag` function: all_flowers = evennia.search_tag("flowers") @@ -150,100 +150,100 @@ Tags can also have categories. By default this category is `None` which is also silmarillion.tags.add("fantasy", category="books") ice_and_fire.tags.add("fantasy", category="books") mona_lisa_overdrive.tags.add("cyberpunk", category="books") - -Note that if you specify the tag you _must_ also include its category, otherwise that category + +Note that if you specify the tag you _must_ also include its category, otherwise that category will be `None` and find no matches. - all_fantasy_books = evennia.search_tag("fantasy") # no matches! - all_fantasy_books = evennia.search_tag("fantasy", category="books") - + all_fantasy_books = evennia.search_tag("fantasy") # no matches! + all_fantasy_books = evennia.search_tag("fantasy", category="books") + Only the second line above returns the two fantasy books. If we specify a category however, -we can get all tagged entities within that category: +we can get all tagged entities within that category: all_books = evennia.search_tag(category="books") - -This gets all three books. - + +This gets all three books. + ### Search by Attribute -We can also search by the [Attributes](../../../Components/Attributes) associated with entities. +We can also search by the [Attributes](../../../Components/Attributes.md) associated with entities. -For example, let's give our rose thorns: +For example, let's give our rose thorns: rose.db.has_thorns = True wines.db.has_thorns = True - daffodil.db.has_thorns = False - -Now we can find things attribute and the value we want it to have: - + daffodil.db.has_thorns = False + +Now we can find things attribute and the value we want it to have: + is_ouch = evennia.search_object_attribute("has_thorns", True) -This returns the rose and the wines. +This returns the rose and the wines. > Searching by Attribute can be very practical. But if you plan to do a search very often, searching -> by-tag is generally faster. +> by-tag is generally faster. ### Search by Typeclass Sometimes it's useful to find all objects of a specific Typeclass. All of Evennia's search tools support this. - all_roses = evennia.search_object(typeclass="typeclasses.flowers.Rose") + all_roses = evennia.search_object(typeclass="typeclasses.flowers.Rose") If you have the `Rose` class already imported you can also pass it directly: all_roses = evennia.search_object(typeclass=Rose) - + You can also search using the typeclass itself: all_roses = Rose.objects.all() - -This last way of searching is a simple form of a Django _query_. This is a way to express SQL queries using -Python. We'll cover this some more as an [Extra-credits](#Extra-Credits) section at the end of this lesson. - -### Search by dbref -The database id or `#dbref` is unique and never-reused within each database table. In search methods you can -replace the search for `key` with the dbref to search for. This must be written as a string `#dbref`: +This last way of searching is a simple form of a Django _query_. This is a way to express SQL queries using +Python. + +### Search by dbref + +The database id or `#dbref` is unique and never-reused within each database table. In search methods you can +replace the search for `key` with the dbref to search for. This must be written as a string `#dbref`: the_answer = self.caller.search("#42") - eightball = evennia.search_object("#8") + eightball = evennia.search_object("#8") -Since `#dbref` is always unique, this search is always global. +Since `#dbref` is always unique, this search is always global. -```warning:: Relying on #dbrefs +```{warning} Relying on #dbrefs - You may be used to using #dbrefs a lot from other codebases. It is however considered + You may be used to using #dbrefs a lot from other codebases. It is however considered `bad practice` in Evennia to rely on hard-coded #dbrefs. It makes your code hard to maintain - and tied to the exact layout of the database. In 99% of cases you should pass the actual objects - around and search by key/tags/attribute instead. + and tied to the exact layout of the database. In 99% of cases you should pass the actual objects + around and search by key/tags/attribute instead. ``` ## Finding objects relative each other Let's consider a `chest` with a `coin` inside it. The chests stand in a room `dungeon`. In the dungeon is also -a `door`. This is an exit leading outside. +a `door`. This is an exit leading outside. - `coin.location` is `chest`. - `chest.location` is `dungeon`. - `door.location` is `dungeon`. -- `room.location` is `None` since it's not inside something else. +- `room.location` is `None` since it's not inside something else. -One can use this to find what is inside what. For example, `coin.location.location` is the `room`. +One can use this to find what is inside what. For example, `coin.location.location` is the `room`. We can also find what is inside each object. This is a list of things. - `room.contents` is `[chest, door]` - `chest.contents` is `[coin]` - `coin.contents` is `[]`, the empty list since there's nothing 'inside' the coin. -- `door.contents` is `[]` too. +- `door.contents` is `[]` too. -A convenient helper is `.contents_get` - this allows to restrict what is returned: +A convenient helper is `.contents_get` - this allows to restrict what is returned: - `room.contents_get(exclude=chest)` - this returns everything in the room except the chest (maybe it's hidden?) -There is a special property for finding exits: +There is a special property for finding exits: -- `room.exits` is `[door]` +- `room.exits` is `[door]` - `coin.exits` is `[]` (same for all the other objects) There is a property `.destination` which is only used by exits: @@ -251,11 +251,11 @@ There is a property `.destination` which is only used by exits: - `door.destination` is `outside` (or wherever the door leads) - `room.destination` is `None` (same for all the other non-exit objects) -## Summary +## Summary Knowing how to find things is important and the tools from this section will serve you well. For most of your needs these tools will be all you need ... -... but not always. In the next lesson we will dive further into more complex searching when we look at +... but not always. In the next lesson we will dive further into more complex searching when we look at Django queries and querysets in earnest. diff --git a/docs/source/Howto/Starting/Part1/Starting-Part1.md b/docs/source/Howto/Starting/Part1/Starting-Part1.md index a4787f538c..dbe6881f37 100644 --- a/docs/source/Howto/Starting/Part1/Starting-Part1.md +++ b/docs/source/Howto/Starting/Part1/Starting-Part1.md @@ -1,49 +1,51 @@ # Starting Tutorial (Part 1) -```sidebar:: Tutorial Parts +```{eval-rst} +.. sidebar:: Tutorial Parts + + **Part 1: What we have** + A tour of Evennia and how to use the tools, including an introduction to Python. + Part 2: `What we want <../Part2/Starting-Part2.html>`_ + Planning our tutorial game and what to think about when planning your own in the future. + Part 3: `How we get there <../Part3/Starting-Part3.html>`_ + Getting down to the meat of extending Evennia to make our game + Part 4: `Using what we created <../Part4/Starting-Part4.html>`_ + Building a tech-demo and world content to go with our code + Part 5: `Showing the world <../Part5/Starting-Part5.html>`_ + Taking our new game online and let players try it out - **Part 1: What we have** - A tour of Evennia and how to use the tools, including an introduction to Python. - Part 2: `What we want <../Part2/Starting-Part2.html>`_ - Planning our tutorial game and what to think about when planning your own in the future. - Part 3: `How we get there <../Part3/Starting-Part3.html>`_ - Getting down to the meat of extending Evennia to make our game - Part 4: `Using what we created <../Part4/Starting-Part4.html>`_ - Building a tech-demo and world content to go with our code - Part 5: `Showing the world <../Part5/Starting-Part5.html>`_ - Taking our new game online and let players try it out ``` Welcome to Evennia! This multi-part Tutorial will help you get off the ground. It consists -of five parts, each with several lessons. You can pick what seems interesting, but if you -follow through to the end you will have created a little online game of your own to play -and share with others! +of five parts, each with several lessons. You can pick what seems interesting, but if you +follow through to the end you will have created a little online game of your own to play +and share with others! ## Lessons of Part 1 - "What we have" 1. Introduction (you are here) -1. [Building stuff](./Building-Quickstart) -1. [The Tutorial World](./Tutorial-World-Introduction) -1. [Python basics](./Python-basic-introduction) -1. [Game dir overview](./Gamedir-Overview) -1. [Python classes and objects](./Python-classes-and-objects) -1. [Accessing the Evennia library](./Evennia-Library-Overview) -1. [Typeclasses and Persistent objects](./Learning-Typeclasses) -1. [Making first own Commands](./Adding-Commands) -1. [Parsing and replacing default Commands](./More-on-Commands) -1. [Creating things](./Creating-Things) -1. [Searching for things](./Searching-Things) -1. [Advanced searching with Django queries](./Django-queries) +1. [Building stuff](./Building-Quickstart.md) +1. [The Tutorial World](./Tutorial-World-Introduction.md) +1. [Python basics](./Python-basic-introduction.md) +1. [Game dir overview](./Gamedir-Overview.md) +1. [Python classes and objects](./Python-classes-and-objects.md) +1. [Accessing the Evennia library](./Evennia-Library-Overview.md) +1. [Typeclasses and Persistent objects](./Learning-Typeclasses.md) +1. [Making first own Commands](./Adding-Commands.md) +1. [Parsing and replacing default Commands](./More-on-Commands.md) +1. [Creating things](./Creating-Things.md) +1. [Searching for things](./Searching-Things.md) +1. [Advanced searching with Django queries](./Django-queries.md) In this first part we'll focus on what we get out of the box in Evennia - we'll get used to the tools, -and how to find things we are looking for. We will also dive into some of things you'll +and how to find things we are looking for. We will also dive into some of things you'll need to know to fully utilize the system, including giving you a brief rundown of Python concepts. If you are -an experienced Python programmer, some sections may feel a bit basic, but you will at least not have seen -these concepts in the context of Evennia before. +an experienced Python programmer, some sections may feel a bit basic, but you will at least not have seen +these concepts in the context of Evennia before. -## Things you will need +## Things you will need -### A Command line +### A Command line First of all, you need to know how to find your Terminal/Console in your OS. The Evennia server can be controlled from in-game, but you _will_ need to use the command-line to get anywhere. Here are some starters: @@ -55,75 +57,75 @@ from in-game, but you _will_ need to use the command-line to get anywhere. Here ### A MUD client -You might already have a MUD-client you prefer. Check out the [grid of supported clients](../../../Setup/Client-Support-Grid) for aid. -If telnet's not your thing, you can also just use Evennia's web client in your browser. +You might already have a MUD-client you prefer. Check out the [grid of supported clients](../../../Setup/Client-Support-Grid.md) for aid. +If telnet's not your thing, you can also just use Evennia's web client in your browser. > In this documentation we often use 'MUD' and 'MU' or 'MU*' interchangeably - as labels to represent all the historically different forms of text-based multiplayer game-styles, + as labels to represent all the historically different forms of text-based multiplayer game-styles, like MUD, MUX, MUSH, MUCK, MOO and others. Evennia can be used to create all those game-styles and more. ### An Editor You need a text-editor to edit Python source files. Most everything that can edit and output raw -text works (so not Word). +text works (so not Word). -- [Here's a blog post summing up some of the alternatives](https://www.elegantthemes.com/blog/resources/best-code-editors) - these -things don't change much from year to year. Popular choices for Python are PyCharm, VSCode, Atom, Sublime Text and Notepad++. +- [Here's a blog post summing up some of the alternatives](https://www.elegantthemes.com/blog/resources/best-code-editors) - these +things don't change much from year to year. Popular choices for Python are PyCharm, VSCode, Atom, Sublime Text and Notepad++. Evennia is to a very large degree coded in VIM, but that's not suitable for beginners. - + > Hint: When setting up your editor, make sure that pressing TAB inserts _4 spaces_ rather than a Tab-character. Since > Python is whitespace-aware, this will make your life a lot easier. ### Set up a game dir for the tutorial -Next you should make sure you have [installed Evennia](../../../Setup/Setup-Quickstart). If you followed the instructions -you will already have created a game-dir. You could use that for this tutorial or you may want to do the +Next you should make sure you have [installed Evennia](../../../Setup/Setup-Quickstart.md). If you followed the instructions +you will already have created a game-dir. You could use that for this tutorial or you may want to do the tutorial in its own, isolated game dir; it's up to you. -- If you want a new gamedir for the tutorial game and already have Evennia running with another gamedir, +- If you want a new gamedir for the tutorial game and already have Evennia running with another gamedir, first enter that gamedir and run - evennia stop - -> If you want to run two parallel servers, that'd be fine too, but one would have to use + evennia stop + +> If you want to run two parallel servers, that'd be fine too, but one would have to use > different ports from the defaults, or there'd be a clash. We will go into changing settings later. - Now go to where you want to create your tutorial-game. We will always refer to it as `mygame` so it may be convenient if you do too: - + evennia --init mygame - cd mygame - evennia migrate + cd mygame + evennia migrate evennia start --log - - Add your superuser name and password at the prompt (email is optional). Make sure you can + + Add your superuser name and password at the prompt (email is optional). Make sure you can go to `localhost:4000` in your MUD client or to [http://localhost:4001](http://localhost:4001) in your web browser (Mac users: Try `127.0.0.1` instead of `localhost` if you have trouble). - + The above `--log` flag will have Evennia output all its logs to the terminal. This will block the terminal from other input. To leave the log-view, press `Ctrl-C` (`Cmd-C` on Mac). To see - the log again just run - + the log again just run + evennia --log - You should now be good to go! - - - ```toctree:: - :hidden: - - Building-Quickstart - Tutorial-World-Introduction - Python-basic-introduction - Gamedir-Overview - Python-classes-and-objects - Evennia-Library-Overview - Learning-Typeclasses - Adding-Commands - More-on-Commands - Creating-Things - Searching-Things - Django-queries - ../Part2/Starting-Part2 + You should now be good to go! -``` \ No newline at end of file + +```{toctree} +:hidden: + +Building-Quickstart +Tutorial-World-Introduction +Python-basic-introduction +Gamedir-Overview +Python-classes-and-objects +Evennia-Library-Overview +Learning-Typeclasses +Adding-Commands +More-on-Commands +Creating-Things +Searching-Things +Django-queries +../Part2/Starting-Part2 + +``` diff --git a/docs/source/Howto/Starting/Part1/Tutorial-World-Introduction.md b/docs/source/Howto/Starting/Part1/Tutorial-World-Introduction.md index 34c8ce2df6..d406766bd5 100644 --- a/docs/source/Howto/Starting/Part1/Tutorial-World-Introduction.md +++ b/docs/source/Howto/Starting/Part1/Tutorial-World-Introduction.md @@ -1,26 +1,26 @@ -# The Tutorial World +# The Tutorial World -The *Tutorial World* is a small and functioning MUD-style game world shipped with Evennia. +The *Tutorial World* is a small and functioning MUD-style game world shipped with Evennia. It's a small showcase of what is possible. It can also be useful for those who have an easier -time learning by deconstructing existing code. +time learning by deconstructing existing code. -Stand in the Limbo room and install it with +Stand in the Limbo room and install it with batchcommand tutorial_world.build - + What this does is to run the build script [evennia/contrib/tutorial_world/build.ev](github:evennia/contrib/tutorial_world/build.ev). -This is pretty much just a list of build-commands executed in sequence by the `batchcommand` command. +This is pretty much just a list of build-commands executed in sequence by the `batchcommand` command. Wait for the building to complete and don't run it twice. A new exit should have appeared named _Tutorial_. - -The game consists of a single-player quest and has some 20 rooms that you can explore as you seek + +The game consists of a single-player quest and has some 20 rooms that you can explore as you seek to discover the whereabouts of a mythical weapon. Make sure you don't play as superuser: quell - -Enter the new exit by writing `tutorial`. Enjoy! If you succeed you will eventually + +Enter the new exit by writing `tutorial`. Enjoy! If you succeed you will eventually end up back in Limbo. - + ## Gameplay ![the castle off the moor](https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/22916c25-6299-453d-a221-446ec839f567/da2pmzu-46d63c6d-9cdc-41dd-87d6-1106db5a5e1a.jpg/v1/fill/w_600,h_849,q_75,strp/the_castle_off_the_moor_by_griatch_art_da2pmzu-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3siaGVpZ2h0IjoiPD04NDkiLCJwYXRoIjoiXC9mXC8yMjkxNmMyNS02Mjk5LTQ1M2QtYTIyMS00NDZlYzgzOWY1NjdcL2RhMnBtenUtNDZkNjNjNmQtOWNkYy00MWRkLTg3ZDYtMTEwNmRiNWE1ZTFhLmpwZyIsIndpZHRoIjoiPD02MDAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.omuS3D1RmFiZCy9OSXiIita-HxVGrBok3_7asq0rflw) @@ -39,7 +39,7 @@ face you stand where the moor meets the sea along a high, rocky coast ...* - Look at everything. While a demo, this is not necessarily trivial, depending on your experience with text-based adventure games. Just remember that everything can be solved or bypassed. - Some things cannot be damaged by mortal weapons. In that case it's OK to run away. Expect - to be chased though. + to be chased though. - 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 game. @@ -49,14 +49,14 @@ which commands are available at any given time. - *defend* will lower the chance to taking damage on your enemy's next attack. - Being defeated is a part of the experience. You can't actually die, but getting knocked out means being left in the dark ... - + ## Once you are done (or had enough) -Afterwards you'll either have conquered the old ruin and returned in glory and triumph ... or +Afterwards you'll either have conquered the old ruin and returned in glory and triumph ... or you returned limping and whimpering from the challenge through `telport limbo`. Either way you should now be back in Limbo, able to reflect on the experience. -Some features exemplified by the tutorial world: +Some features exemplified by the tutorial world: - Rooms with custom ability to show details (like looking at the wall in the dark room) - Hidden or impassable exits until you fulfilled some criterion @@ -72,14 +72,14 @@ Some features exemplified by the tutorial world: - Object spawning (the weapons in the barrel and the final weapoon is actually randomized) - Teleporter trap rooms (if you fail the obelisk puzzle) -```sidebar:: Extra Credit +```{sidebar} Extra Credit - If you have previous programming experience (or after you have gone - through this Starter tutorial) it may be instructive to dig a little deeper into the Tutorial-world - code to learn how it achieves what it does. The code is heavily documented. + If you have previous programming experience (or after you have gone + through this Starter tutorial) it may be instructive to dig a little deeper into the Tutorial-world + code to learn how it achieves what it does. The code is heavily documented. You can find all the code in `evennia/contrib/tutorial_world <../../api/evennia.contrib.tutorial_world.html>`_, the build-script is `here `_. - + When reading and learning from the code, however, keep in mind that *Tutorial World* was created with a very specific goal in mind: to install easily and to not permanently modify the rest of the server. It therefore @@ -87,7 +87,7 @@ Some features exemplified by the tutorial world: you will usually need to worry about when making your own game. ``` -Quite a lot of stuff crammed in such a small area! +Quite a lot of stuff crammed in such a small area! ## Uninstall the tutorial world diff --git a/docs/source/Howto/Starting/Part2/Game-Planning.md b/docs/source/Howto/Starting/Part2/Game-Planning.md index 170e376b7c..c9b9a752f5 100644 --- a/docs/source/Howto/Starting/Part2/Game-Planning.md +++ b/docs/source/Howto/Starting/Part2/Game-Planning.md @@ -1,55 +1,55 @@ # On Planning a Game -Last lesson we asked ourselves some questions about our motivation. In this one we'll present -some more technical questions to consider. In the next lesson we'll answer them for the sake of +Last lesson we asked ourselves some questions about our motivation. In this one we'll present +some more technical questions to consider. In the next lesson we'll answer them for the sake of our tutorial game. -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. +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. -```important:: +```{important} - Your first all overshadowing goal is to beat the odds and get **something** out the door! - Even if it's a scaled-down version of your dream game, lacking many "must-have" features! + Your first all overshadowing goal is to beat the odds and get **something** out the door! + Even if it's a scaled-down version of your dream game, lacking many "must-have" features! ``` Remember: *99.99999% of all great game ideas never lead to a game*. Especially not to an online -game that people can actually play and enjoy. It's better to get your game out there and expand on it +game that people can actually play and enjoy. It's better to get your game out there and expand on it later than to code in isolation until you burn out, lose interest or your hard drive crashes. -- Keep the scope of your initial release down. Way down. +- Keep the scope of your initial release down. Way down. - Start small, with an eye towards expansions later, after first release. -- If the suggestions here seems boring or a chore to you, do it your way instead. Everyone's different. -- Keep having _fun_. You must keep your motivation up, whichever way works for _you_. +- If the suggestions here seems boring or a chore to you, do it your way instead. Everyone's different. +- Keep having _fun_. You must keep your motivation up, whichever way works for _you_. -## The steps +## The steps Here are the rough steps towards your goal. -1. Planning +1. Planning 2. Coding + Gradually building a tech-demo 3. Building the actual game world 4. Release 5. Celebrate -## Planning +## Planning -You need to have at least a rough idea about what you want to create. Some like a lot of planning, others -do it more seat-of-the-pants style. Regardless, while _some_ planning is always good to do, it's common -to have your plans change on you as you create your code prototypes. So don't get _too_ bogged down in +You need to have at least a rough idea about what you want to create. Some like a lot of planning, others +do it more seat-of-the-pants style. Regardless, while _some_ planning is always good to do, it's common +to have your plans change on you as you create your code prototypes. So don't get _too_ bogged down in the details out of the gate. -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. Such things are very important. But -unfortunately, they are not enough to make your game. You need to figure out how to accomplish your ideas in +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. Such things are very important. But +unfortunately, they are not enough to make your game. You need to figure out how to accomplish your ideas in Evennia. Below are some questions to get you going. In the next lesson we will try to answer them for our particular tutorial game. There are of course many more questions you could be asking yourself. -### Administration +### Administration - Should your game rules be enforced by coded systems or by human game masters? - What is the staff hierarchy in your game? Is vanilla Evennia roles enough or do you need something else? @@ -57,21 +57,21 @@ tutorial game. There are of course many more questions you could be asking yours ### Building -- How will the world be built? Traditionally (from in-game with build-commands) or externally (by batchcmds/code - or directly with custom code)? +- How will the world be built? Traditionally (from in-game with build-commands) or externally (by batchcmds/code + or directly with custom code)? - Can only privileged Builders create things or should regular players also have limited build-capability? ### Systems - Do you base your game off an existing RPG system or make up your own? -- What are the game mechanics? How do you decide if an action succeeds or fails? +- What are the game mechanics? How do you decide if an action succeeds or fails? - Does the flow of time matter in your game - does night and day change? What about seasons? -- Do you want changing, global weather or should weather just be set manually in roleplay? +- Do you want changing, global weather or should weather just be set manually in roleplay? - Do you want a coded world-economy or just a simple barter system? Or no formal economy at all? -- Do you have concepts like reputation and influence? -- Will your characters be known by their name or only by their physical appearance? +- Do you have concepts like reputation and influence? +- Will your characters be known by their name or only by their physical appearance? -### Rooms +### Rooms - Is a simple room description enough or should the description be able to change (such as with time, by light conditions, weather or season)? @@ -91,60 +91,60 @@ created on demand? - Can you fight with a chair or a flower or must you use a specific 'weapon' kind of thing? - Will characters be able to craft new objects? - Should mobs/NPCs have some sort of AI? -- Are NPCs and mobs different entities? How do they differ? -- Should there be NPCs giving quests? If so, how do you track Quest status? +- Are NPCs and mobs different entities? How do they differ? +- Should there be NPCs giving quests? If so, how do you track Quest status? ### Characters - Can players have more than one Character active at a time or are they allowed to multi-play? -- How does the character-generation work? Walk from room-to-room? A menu? +- How does the character-generation work? Walk from room-to-room? A menu? - How do you implement different "classes" or "races"? Are they separate types of objects or do you simply load different stats on a basic object depending on what the Player wants? - If a Character can hide in a room, what skill will decide if they are detected? - What does the skill tree look like? Can a Character gain experience to improve? By killing enemies? Solving quests? By roleplaying? - May player-characters attack each other (PvP)? -- What are the penalties of defeat? Permanent death? Quick respawn? Time in prison? +- What are the penalties of defeat? Permanent death? Quick respawn? Time in prison? 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 *only* on them for your first release. Make a list. Keep future expansions in mind but limit yourself. -## Coding and Tech demo +## Coding and Tech demo -This is the actual work of creating the "game" part of your game. As you code and test systems you should -build a little "tech demo" along the way. +This is the actual work of creating the "game" part of your game. As you code and test systems you should +build a little "tech demo" along the way. -```sidebar:: Tech demo +```{sidebar} Tech demo With "tech demo" we mean a small example of your code in-action: A room with a mob, - a way to jump into and test character-creation etc. The tech demo need not be pretty, it's + a way to jump into and test character-creation etc. The tech demo need not be pretty, it's there to test functionality. It's not the beginning of your game world (unless you find that to be more fun). ``` -Try to avoid going wild with building a huge game world before you have a tech-demo showing off all parts +Try to avoid going wild with building a huge game world before you have a tech-demo showing off all parts you expect to have in the first version of your game. Otherwise you run the risk of having to redo it all -again. +again. -Evennia tries hard to make the coding easier for you, but there is no way around the fact that if you want -anything but a basic chat room you *will* have to bite the bullet and code your game (or find a coder willing +Evennia tries hard to make the coding easier for you, but there is no way around the fact that if you want +anything but a basic chat room 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 and components of Evennia. It's recommended you look over the rest of this Beginner Tutorial to learn -what tools you have available. +what tools you have available. 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. -A good idea is to host your code online using _version control_. Github.com offers free Private repos +A good idea is to host your code online using _version control_. Github.com offers free Private repos these days if you don't want the world to learn your secrets. Not only version control make it easy for your team to collaborate, it also means -your work is backed up at all times. The page on [Version Control](../../../Coding/Version-Control) +your work is backed up at all times. The page on [Version Control](../../../Coding/Version-Control.md) will help you to setting up a sane developer environment with proper version control. ## World Building @@ -154,17 +154,17 @@ populating the database with a larger, thematic world. Too many would-be develop stage too soon (skipping the **Coding** or even **Planning** stages). What if the rooms you build now doesn't include all the nice weather messages the code grows to support? Or the way you store data changes under the hood? Your building work would at best require some rework and at worst you -would have to redo the whole thing. You could be in for a *lot* of unnecessary work if you build stuff +would have to redo the whole thing. You could be 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 before starting to build, the "game" bit (**Coding** + **Testing**) should be more or less **complete**, *at least to the level of your initial release*. -Make sure it is clear to yourself and your eventual builders just which parts of the world you want -for your initial release. Establish for everyone which style, quality and level of detail you expect. +Make sure it is clear to yourself and your eventual builders just which parts of the world you want +for your initial release. Establish for everyone which style, quality and level of detail you expect. -Your goal should *not* be to complete your entire world in one go. You want just enough to make the -game's "feel" come across. You want a minimal but functioning world where the intended game play can +Your goal should *not* be to complete your entire world in one go. You want just enough to make the +game's "feel" come across. You want a minimal but functioning world where the intended game play can be tested and roughly balanced. You can always add new areas later. During building you get free and extensive testing of whatever custom build commands and systems you @@ -176,18 +176,18 @@ to this feedback. ## 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! +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 +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). +feedback and bug reports (there *will* be bugs, there is no way around it). -Follow the quick instructions for [Online Setup](../../../Setup/Online-Setup) to make your -game visible online. +Follow the quick instructions for [Online Setup](../../../Setup/Online-Setup.md) to make your +game visible online. -If you hadn't already, make sure to put up your game on the -[Evennia game index](http://games.evennia.com/) so people know it's in the works (actually, even +If you hadn't already, make sure to put up your game on the +[Evennia game index](http://games.evennia.com/) so people know it's in the works (actually, even pre-alpha games are allowed in the index so don't be shy)! ## Beta Release/Perpetual Beta @@ -198,12 +198,12 @@ Once things stabilize in Alpha you can move to *Beta* and let more people in. Ma features get implemented or Players come with suggestions. As the game designer it is now up to you to gradually perfect your vision. -## Congratulate yourself! +## Congratulate yourself! You are worthy of a celebration since at this point you have joined the small, exclusive crowd who have made their dream game a reality! ## Planning our tutorial game -In the next lesson we'll make use of these general points and try to plan out our tutorial game. +In the next lesson we'll make use of these general points and try to plan out our tutorial game. diff --git a/docs/source/Howto/Starting/Part2/Planning-Some-Useful-Contribs.md b/docs/source/Howto/Starting/Part2/Planning-Some-Useful-Contribs.md index 907e221c0a..8dce4f18a9 100644 --- a/docs/source/Howto/Starting/Part2/Planning-Some-Useful-Contribs.md +++ b/docs/source/Howto/Starting/Part2/Planning-Some-Useful-Contribs.md @@ -8,7 +8,7 @@ That said, Evennia _does_ offer some more game-opinionated _optional_ stuff. The and is an ever-growing treasure trove of code snippets, concepts and even full systems you can pick and choose from to use, tweak or take inspiration from when you make your game. -The [Contrib overview](../../../Contribs/Contrib-Overview) page gives the full list of the current roster of contributions. On +The [Contrib overview](../../../Contribs/Contrib-Overview.md) page gives the full list of the current roster of contributions. On this page we will review a few contribs we will make use of for our game. We will do the actual installation of them when we start coding in the next part of this tutorial series. While we will introduce them here, you are wise to read their doc-strings yourself for the details. @@ -26,7 +26,7 @@ This is the things we know we need: ## Barter contrib -[source](api:evennia.contrib.barter) +[source](../../../api/evennia.contrib.barter.md) Reviewing this contrib suggests that it allows for safe trading between two parties. The basic principle is that the parties puts up the stuff they want to sell and the system will guarantee that these systems are @@ -57,7 +57,7 @@ things than boring gold coin. ## Character generation contrib -[source](api:evennia.contrib.chargen) +[source](../../../api/evennia.contrib.chargen.md) This contrib is an example module for creating characters. Since we will be using `MULTISESSION_MODE=3` we will get a selection screen like this automatically. We also plan to use a proper menu to build our character, so @@ -65,7 +65,7 @@ we will _not_ be using this contrib. ## Clothing contrib -[source](api:evennia.contrib.clothing) +[source](../../../api/evennia.contrib.clothing.md) This contrib provides a full system primarily aimed at wearing clothes, but it could also work for armor. You wear an object in a particular location and this will then be reflected in your character's description. You can @@ -80,7 +80,7 @@ for things like armor. It's a good contrib to build from though, so that's what ## Dice contrib -[source](api:evennia.contrib.dice) +[source](../../../api/evennia.contrib.dice.md) The dice contrib presents a general dice roller to use in game. @@ -102,7 +102,7 @@ or play a game, we will not need it for the core of our game. ## Extended room contrib -[source](api:evennia.contrib.extended_room) +[source](../../../api/evennia.contrib.extended_room.md) This is a custom Room typeclass that changes its description based on time of day and season. @@ -122,7 +122,7 @@ game, why not! ## RP-System contrib -[source](api:evennia.contrib.rpsystem) +[source](../../../api/evennia.contrib.rpsystem.md) This contrib adds a full roleplaying subsystem to your game. It gives every character a "short-description" (sdesc) that is what people will see when first meeting them. Let's say Tom has an sdesc "A tall man" and @@ -159,20 +159,20 @@ You can also wear a mask to hide your identity; your sdesc will then be changed like `a person with a mask`. The RPSystem gives a lot of roleplaying power out of the box, so we will add it. There is also a separate -[rplanguage](api:evennia.contrib.rplanguage) module that integrates with the spoken words in your emotes and garbles them if you don't understand +[rplanguage](../../../api/evennia.contrib.rplanguage.md) module that integrates with the spoken words in your emotes and garbles them if you don't understand the language spoken. In order to restrict the scope we will not include languages for the tutorial game. ## Talking NPC contrib -[source](api:evennia.contrib.talking_npc) +[source](../../../api/evennia.contrib.talking_npc.md) This exemplifies an NPC with a menu-driven dialogue tree. We will not use this contrib explicitly, but it's good as inspiration for how we'll do quest-givers later. ## Traits contrib -[source](api:evennia.contrib.traits) +[source](../../../api/evennia.contrib.traits.md) An issue with dealing with roleplaying attributes like strength, dexterity, or skills like hunting, sword etc is how to keep track of the values in the moment. Your strength may temporarily be buffed by a strength-potion. @@ -226,7 +226,7 @@ Traits will be very practical to use for our character sheets. ## Turnbattle contrib -[source](api:evennia.contrib.turnbattle) +[source](../../../api/evennia.contrib.turnbattle.md) This contrib consists of several implementations of a turn-based combat system, divivided into complexity: diff --git a/docs/source/Howto/Starting/Part2/Planning-The-Tutorial-Game.md b/docs/source/Howto/Starting/Part2/Planning-The-Tutorial-Game.md index 03c598cf05..b68200cf5c 100644 --- a/docs/source/Howto/Starting/Part2/Planning-The-Tutorial-Game.md +++ b/docs/source/Howto/Starting/Part2/Planning-The-Tutorial-Game.md @@ -1,53 +1,53 @@ # Planning our tutorial game Using the general plan from last lesson we'll now establish what kind of game we want to create for this tutorial. -Remembering that we need to keep the scope down, let's establish some parameters. -Note that for your own -game you don't _need_ to agree/adopt any of these. Many game-types need more or much less than this. +Remembering that we need to keep the scope down, let's establish some parameters. +Note that for your own +game you don't _need_ to agree/adopt any of these. Many game-types need more or much less than this. But this makes for good, instructive examples. -- To have something to refer to rather than just saying "our tutorial game" over and over, we'll +- To have something to refer to rather than just saying "our tutorial game" over and over, we'll name it ... _EvAdventure_. -- We want EvAdventure be a small game we can play ourselves for fun, but which could in principle be expanded +- We want EvAdventure be a small game we can play ourselves for fun, but which could in principle be expanded to something more later. - Let's go with a fantasy theme, it's well understood. -- We'll use some existing, simple RPG system. -- We want to be able to create and customize a character of our own. -- We want the tools to roleplay with other players. +- We'll use some existing, simple RPG system. +- We want to be able to create and customize a character of our own. +- We want the tools to roleplay with other players. - We don't want to have to rely on a Game master to resolve things, but will rely on code for skill resolution and combat. -- We want monsters to fight and NPCs we can talk to. So some sort of AI. -- We want to be able to buy and sell stuff, both with NPCs and other players. +- We want monsters to fight and NPCs we can talk to. So some sort of AI. +- We want to be able to buy and sell stuff, both with NPCs and other players. - We want some sort of crafting system. -- We want some sort of quest system. +- We want some sort of quest system. -Let's answer the questions from the previous lesson and discuss some of the possibilities. +Let's answer the questions from the previous lesson and discuss some of the possibilities. -### Administration +## Administration -#### Should your game rules be enforced by coded systems by human game masters? +### Should your game rules be enforced by coded systems by human game masters? -Generally, the more work you expect human staffers/GMs to do, the less your code needs to work. To -support GMs you'd need to design commands to support GM-specific actions and the type of game-mastering -you want them to do. You may need to expand communication channels so you can easily +Generally, the more work you expect human staffers/GMs to do, the less your code needs to work. To +support GMs you'd need to design commands to support GM-specific actions and the type of game-mastering +you want them to do. You may need to expand communication channels so you can easily talk to groups people in private and split off gaming groups from each other. RPG rules could be as simple as the GM sitting with the rule books and using a dice-roller for visibility. -GM:ing is work-intensive however, and even the most skilled and enthusiastic GM can't be awake all hours +GM:ing is work-intensive however, and even the most skilled and enthusiastic GM can't be awake all hours of the day to serve an international player base. The computer never needs sleep, so having the ability for players to "self-serve" their RP itch when no GMs are around is a good idea even for the most GM-heavy games. On the other side of the spectrum are games with no GMs at all; all gameplay are driven either by the computer -or by the interactions between players. Such games still need an active staff, but nowhere as much active +or by the interactions between players. Such games still need an active staff, but nowhere as much active involvement. Allowing for solo-play with the computer also allows players to have fun when the number of active -players is low. +players is low. -We want EvAdventure to work entirely without depending on human GMs. That said, there'd be nothing -stopping a GM from stepping in and run an adventure for some players should they want to. +We want EvAdventure to work entirely without depending on human GMs. That said, there'd be nothing +stopping a GM from stepping in and run an adventure for some players should they want to. -#### What is the staff hierarchy in your game? Is vanilla Evennia roles enough or do you need something else? +### What is the staff hierarchy in your game? Is vanilla Evennia roles enough or do you need something else? -The default hierarchy is +The default hierarchy is - `Player` - regular players - `Player Helper` - can create/edit help entries @@ -58,368 +58,368 @@ The default hierarchy is There is also the _superuser_, the "owner" of the game you create when you first set up your database. This user goes outside the regular hierarchy and should usually only. -We are okay with keeping this structure for our game. +We are okay with keeping this structure for our game. -#### Should players be able to post out-of-characters on channels and via other means like bulletin-boards? - -Evennia's _Channels_ are by default only available between _Accounts_. That is, for players to communicate with each +### Should players be able to post out-of-characters on channels and via other means like bulletin-boards? + +Evennia's _Channels_ are by default only available between _Accounts_. That is, for players to communicate with each other. By default, the `public` channel is created for general discourse. Channels are logged to a file and when you are coming back to the game you can view the history of a channel -in case you missed something. +in case you missed something. > public Hello world! - [Public] MyName: Hello world! + [Public] MyName: Hello world! But Channels can also be set up to work between Characters instead of Accounts. This would mean the channels -would have an in-game meaning: +would have an in-game meaning: -- Members of a guild could be linked telepathically. +- Members of a guild could be linked telepathically. - Survivors of the apocalypse can communicate over walkie-talkies. -- Radio stations you can tune into or have to discover. +- Radio stations you can tune into or have to discover. _Bulletin boards_ are a sort of in-game forum where posts are made publicly or privately. Contrary to a channel, the messages are usually stored and are grouped into topics with replies. Evennia has no default bulletin-board -system. +system. -In EvAdventure we will just use the default inter-account channels. We will also not be implementing any -bulletin boards. +In EvAdventure we will just use the default inter-account channels. We will also not be implementing any +bulletin boards. -### Building +## Building -#### How will the world be built? - -There are two main ways to handle this: +### How will the world be built? + +There are two main ways to handle this: - Traditionally, from in-game with build-commands: This means builders creating content in their game - client. This has the advantage of not requiring Python skills nor server access. This can often be a quite - intuitive way to build since you are sort-of walking around in your creation as you build it. However, the - developer (you) must make sure to provide build-commands that are flexible enough for builders to be able to - create the content you want for your game. -- Externally (by batchcmds): Evennia's `batchcmd` takes a text file with Evennia Commands and executes them - in sequence. This allows the build process to be repeated and applied quickly to a new database during development. + client. This has the advantage of not requiring Python skills nor server access. This can often be a quite + intuitive way to build since you are sort-of walking around in your creation as you build it. However, the + developer (you) must make sure to provide build-commands that are flexible enough for builders to be able to + create the content you want for your game. +- Externally (by batchcmds): Evennia's `batchcmd` takes a text file with Evennia Commands and executes them + in sequence. This allows the build process to be repeated and applied quickly to a new database during development. It also allows builders to use proper text-editing tools rather than writing things line-by-line in their clients. - The drawback is that for their changes to go live they either need server access or they need to send their - batchcode to the game administrator so they can apply the changes. Or use version control. -- Externally (with batchcode or custom code): This is the "professional game development" approach. This gives the - builders maximum power by creating the content in Python using Evennia primitives. The `batchcode` processor - allows Evennia to apply and re-apply build-scripts that are raw Python modules. Again, this would require the + The drawback is that for their changes to go live they either need server access or they need to send their + batchcode to the game administrator so they can apply the changes. Or use version control. +- Externally (with batchcode or custom code): This is the "professional game development" approach. This gives the + builders maximum power by creating the content in Python using Evennia primitives. The `batchcode` processor + allows Evennia to apply and re-apply build-scripts that are raw Python modules. Again, this would require the builder to have server access or to use version control to share their work with the rest of the development team. -In this tutorial, we will show examples of all these ways, but since we don't have a team of builders we'll -build the brunt of things using Evennia's Batchcode system. +In this tutorial, we will show examples of all these ways, but since we don't have a team of builders we'll +build the brunt of things using Evennia's Batchcode system. -#### Can only privileged Builders create things or should regular players also have limited build-capability? +### Can only privileged Builders create things or should regular players also have limited build-capability? In some game styles, players have the ability to create objects and even script them. While giving regular users -the ability to create objects with in-built commands is easy and safe, actual code-creation (aka _softcode_ ) is -not something Evennia supports natively. Regular, untrusted users should never be allowed to execute raw Python -code (such as what you can do with the `py` command). You can -[read more about Evennia's stance on softcode here](../../../Concepts/Soft-Code). If you want users to do limited scripting, -it's suggested that this is accomplished by adding more powerful build-commands for them to use. +the ability to create objects with in-built commands is easy and safe, actual code-creation (aka _softcode_ ) is +not something Evennia supports natively. Regular, untrusted users should never be allowed to execute raw Python +code (such as what you can do with the `py` command). You can +[read more about Evennia's stance on softcode here](../../../Concepts/Soft-Code.md). If you want users to do limited scripting, +it's suggested that this is accomplished by adding more powerful build-commands for them to use. -For our tutorial-game, we will only allow privileged builders to modify the world. The exception is crafting, +For our tutorial-game, we will only allow privileged builders to modify the world. The exception is crafting, which we will limit to repairing broken items by combining them with other repair-related items. -### Systems +## Systems -#### Do you base your game off an existing RPG system or make up your own? +### Do you base your game off an existing RPG system or make up your own? -We will make use of [Open Adventure](http://www.geekguild.com/openadventure/), a simple 'old school' RPG-system -that is available for free under the Creative Commons license. We'll only use a subset of the rules from +We will make use of [Open Adventure](http://www.geekguild.com/openadventure/), a simple 'old school' RPG-system +that is available for free under the Creative Commons license. We'll only use a subset of the rules from the blue "basic" book. For the sake of keeping down the length of this tutorial we will limit what features -we will include: +we will include: - Only two 'archetypes' (classes) - Arcanist (wizard) and Warrior, these are examples of two different play styles. - Two races only (dwarves and elves), to show off how to implement races and race bonuses. -- No extra features of the races/archetypes such as foci and special feats. While these are good for fleshing +- No extra features of the races/archetypes such as foci and special feats. While these are good for fleshing out a character, these will work the same as other bonuses and are thus not that instructive. -- We will add only a small number of items/weapons from the Open Adventure rulebook to show how it's done. +- We will add only a small number of items/weapons from the Open Adventure rulebook to show how it's done. -#### What are the game mechanics? How do you decide if an action succeeds or fails? +### What are the game mechanics? How do you decide if an action succeeds or fails? -Open Adventure's conflict resolution is based on adding a trait (such as Strength) with a random number in -order to beat a target. We will emulate this in code. +Open Adventure's conflict resolution is based on adding a trait (such as Strength) with a random number in +order to beat a target. We will emulate this in code. -Having a "skill" means getting a bonus to that roll for a more narrow action. +Having a "skill" means getting a bonus to that roll for a more narrow action. Since the computer will need to know exactly what those skills are, we will add them more explicitly than in the rules, but we will only add the minimum to show off the functionality we need. -#### Does the flow of time matter in your game - does night and day change? What about seasons? +### Does the flow of time matter in your game - does night and day change? What about seasons? -Most commonly, game-time runs faster than real-world time. There are -a few advantages with this: +Most commonly, game-time runs faster than real-world time. There are +a few advantages with this: -- Unlike in a single-player game, you can't fast-forward time in a multiplayer game if you are waiting for - something, like NPC shops opening. +- Unlike in a single-player game, you can't fast-forward time in a multiplayer game if you are waiting for + something, like NPC shops opening. - Healing and other things that we know takes time will go faster while still being reasonably 'realistic'. The main drawback is for games with slower roleplay pace. While you are having a thoughtful roleplaying scene -over dinner, the game world reports that two days have passed. Having a slower game time than real-time is -a less common, but possible solution for such games. +over dinner, the game world reports that two days have passed. Having a slower game time than real-time is +a less common, but possible solution for such games. -It is however _not_ recommended to let game-time exactly equal the speed of real time. The reason for this -is that people will join your game from all around the world, and they will often only be able to play at -particular times of their day. With a game-time drifting relative real-time, everyone will eventually be -able to experience both day and night in the game. +It is however _not_ recommended to let game-time exactly equal the speed of real time. The reason for this +is that people will join your game from all around the world, and they will often only be able to play at +particular times of their day. With a game-time drifting relative real-time, everyone will eventually be +able to experience both day and night in the game. For this tutorial-game we will go with Evennia's default, which is that the game-time runs two times faster than real time. -#### Do you want changing, global weather or should weather just be set manually in roleplay? +### Do you want changing, global weather or should weather just be set manually in roleplay? -A weather system is a good example of a game-global system that affects a subset of game entities -(outdoor rooms). We will not be doing any advanced weather simulation, but we'll show how to do -random weather changes happening across the game world. +A weather system is a good example of a game-global system that affects a subset of game entities +(outdoor rooms). We will not be doing any advanced weather simulation, but we'll show how to do +random weather changes happening across the game world. -#### Do you want a coded world-economy or just a simple barter system? Or no formal economy at all? +### Do you want a coded world-economy or just a simple barter system? Or no formal economy at all? -We will allow for money and barter/trade between NPCs/Players and Player/Player, but will not care about -inflation. A real economic simulation could do things like modify shop prices based on supply and demand. +We will allow for money and barter/trade between NPCs/Players and Player/Player, but will not care about +inflation. A real economic simulation could do things like modify shop prices based on supply and demand. We will not go down that rabbit hole. -#### Do you have concepts like reputation and influence? - -These are useful things for a more social-interaction heavy game. We will not include them for this -tutorial however. +### Do you have concepts like reputation and influence? -#### Will your characters be known by their name or only by their physical appearance? +These are useful things for a more social-interaction heavy game. We will not include them for this +tutorial however. + +### Will your characters be known by their name or only by their physical appearance? This is a common thing in RP-heavy games. Others will only see you as "The tall woman" until you introduce yourself and they 'recognize' you with a name. Linked to this is the concept of more complex -emoting and posing. +emoting and posing. -Adding such a system from scratch is complex and way beyond the scope of this tutorial. However, -there is an existing Evennia contrib that adds all of this functionality and more, so we will +Adding such a system from scratch is complex and way beyond the scope of this tutorial. However, +there is an existing Evennia contrib that adds all of this functionality and more, so we will include that and explain briefly how it works. -### Rooms +## Rooms -#### Is a simple room description enough or should the description be able to change? +### Is a simple room description enough or should the description be able to change? -Changing room descriptions for day and night, winder and summer is actually quite easy to do, but looks -very impressive. We happen to know there is also a contrib that helps with this, so we'll show how to -include that. +Changing room descriptions for day and night, winder and summer is actually quite easy to do, but looks +very impressive. We happen to know there is also a contrib that helps with this, so we'll show how to +include that. -#### Should the room have different statuses? +### Should the room have different statuses? We will have different weather in outdoor rooms, but this will not have any gameplay effect - bow strings -will not get wet and fireballs will not fizzle if it rains. +will not get wet and fireballs will not fizzle if it rains. -#### Can objects be hidden in the room? Can a person hide in the room? +### Can objects be hidden in the room? Can a person hide in the room? We will not model hiding and stealth. This will be a game of honorable face-to-face conflict. -### Objects +## Objects -#### How numerous are your objects? Do you want large loot-lists or are objects just role playing props? +### How numerous are your objects? Do you want large loot-lists or are objects just role playing props? -Since we are not going for a pure freeform RPG here, we will want objects with properties, like weapons -and potions and such. Monsters should drop loot even though our list of objects will not be huge. +Since we are not going for a pure freeform RPG here, we will want objects with properties, like weapons +and potions and such. Monsters should drop loot even though our list of objects will not be huge. -#### Is each coin a separate object or do you just store a bank account value? +### Is each coin a separate object or do you just store a bank account value? -Since we will use bartering, placing coin objects on one side of the barter makes for a simple way to +Since we will use bartering, placing coin objects on one side of the barter makes for a simple way to handle payments. So we will use coins as-objects. -#### Do multiple similar objects form stacks and how are those stacks handled in that case? +### Do multiple similar objects form stacks and how are those stacks handled in that case? -Since we'll use coins, it's practical to have them and other items stack together. While Evennia does not -do this natively, we will make use of a contrib for this. +Since we'll use coins, it's practical to have them and other items stack together. While Evennia does not +do this natively, we will make use of a contrib for this. -#### Does an object have weight or volume (so you cannot carry an infinite amount of them)? +### Does an object have weight or volume (so you cannot carry an infinite amount of them)? -Limiting carrying weight is one way to stop players from hoarding. It also makes it more important -for players to pick only the equipment they need. Carrying limits can easily come across as -annoying to players though, so one needs to be careful with it. +Limiting carrying weight is one way to stop players from hoarding. It also makes it more important +for players to pick only the equipment they need. Carrying limits can easily come across as +annoying to players though, so one needs to be careful with it. -Open Adventure rules include weight limits, so we will include them. +Open Adventure rules include weight limits, so we will include them. -#### Can objects be broken? Can they be repaired? +### Can objects be broken? Can they be repaired? -Item breakage is very useful for a game economy; breaking weapons adds tactical considerations (if it's not -too common, then it becomes annoying) and repairing things gives work for crafting players. +Item breakage is very useful for a game economy; breaking weapons adds tactical considerations (if it's not +too common, then it becomes annoying) and repairing things gives work for crafting players. -We wanted a crafting system, so this is what we will limit it to - repairing items using some sort -of raw materials. +We wanted a crafting system, so this is what we will limit it to - repairing items using some sort +of raw materials. -#### Can you fight with a chair or a flower or must you use a special 'weapon' kind of thing? +### Can you fight with a chair or a flower or must you use a special 'weapon' kind of thing? -Traditionally, only 'weapons' could be used to fight with. In the past this was a useful -simplification, but with Python classes and inheritance, it's not actually more work to just -let all items in game work as a weapon in a pinch. +Traditionally, only 'weapons' could be used to fight with. In the past this was a useful +simplification, but with Python classes and inheritance, it's not actually more work to just +let all items in game work as a weapon in a pinch. -So for our game we will let a character use any item they want as a weapon. The difference will -be that non-weapon items will do less damage and also break and become unusable much quicker. +So for our game we will let a character use any item they want as a weapon. The difference will +be that non-weapon items will do less damage and also break and become unusable much quicker. -#### Will characters be able to craft new objects? +### Will characters be able to craft new objects? -Crafting is a common feature in multiplayer games. In code it usually means using a skill-check -to combine base ingredients from a fixed recipe in order to create a new item. The classic -example is to combine _leather straps_, a _hilt_, a _pommel_ and a _blade_ to make a new _sword_. -A full-fledged crafting system could require multiple levels of crafting, including having to mine -for ore or cut down trees for wood. +Crafting is a common feature in multiplayer games. In code it usually means using a skill-check +to combine base ingredients from a fixed recipe in order to create a new item. The classic +example is to combine _leather straps_, a _hilt_, a _pommel_ and a _blade_ to make a new _sword_. +A full-fledged crafting system could require multiple levels of crafting, including having to mine +for ore or cut down trees for wood. In our case we will limit our crafting to repairing broken items. To show how it's done, we will require -extra items (a recipe) in order to facilitate the repairs. +extra items (a recipe) in order to facilitate the repairs. -#### Should mobs/NPCs have some sort of AI? +### Should mobs/NPCs have some sort of AI? -A rule of adding Artificial Intelligence is that with today's technology you should not hope to fool +A rule of adding Artificial Intelligence is that with today's technology you should not hope to fool anyone with it anytime soon. Unless you have a side-gig as an AI researcher, users will likely not notice any practical difference between a simple state-machine and you spending a lot of time learning -how to train a neural net. +how to train a neural net. -For this tutorial, we will show how to add a simple state-machine for monsters. NPCs will only be -shop-keepers and quest-gives so they won't need any real AI to speak of. +For this tutorial, we will show how to add a simple state-machine for monsters. NPCs will only be +shop-keepers and quest-gives so they won't need any real AI to speak of. -#### Are NPCs and mobs different entities? How do they differ? +### Are NPCs and mobs different entities? How do they differ? -"Mobs" or "mobiles" are things that move around. This is traditionally monsters you can fight with, but could +"Mobs" or "mobiles" are things that move around. This is traditionally monsters you can fight with, but could also be city guards or the baker going to chat with the neighbor. Back in the day, they were often fundamentally -different these days it's often easier to just make NPCs and mobs essentially the same thing. +different these days it's often easier to just make NPCs and mobs essentially the same thing. In EvAdventure, both Monsters and NPCs will be the same type of thing; A monster could give you a quest -and an NPC might fight you as a mob as well as trade with you. +and an NPC might fight you as a mob as well as trade with you. -#### _Should there be NPCs giving quests? If so, how do you track Quest status? +### _Should there be NPCs giving quests? If so, how do you track Quest status? -We will design a simple quest system to track the status of ongoing quests. +We will design a simple quest system to track the status of ongoing quests. -### Characters +## Characters -#### Can players have more than one Character active at a time or are they allowed to multi-play? +### Can players have more than one Character active at a time or are they allowed to multi-play? -Since Evennia differentiates between `Sessions` (the client-connection to the game), `Accounts` -and `Character`s, it natively supports multi-play. This is controlled by the `MULTISESSION_MODE` -setting, which has a value from `0` (default) to `3`. +Since Evennia differentiates between `Sessions` (the client-connection to the game), `Accounts` +and `Character`s, it natively supports multi-play. This is controlled by the `MULTISESSION_MODE` +setting, which has a value from `0` (default) to `3`. -- `0`- One Character per Account and one Session per Account. This means that if you login to the same +- `0`- One Character per Account and one Session per Account. This means that if you login to the same account from another client you'll be disconnected from the first. When creating a new account, a Character will be auto-created with the same name as your Account. This is default mode and mimics legacy code bases - which had no separation between Account and Character. -- `1` - One Character per Account, multiple Sessions per Account. So you can connect simultaneously from + which had no separation between Account and Character. +- `1` - One Character per Account, multiple Sessions per Account. So you can connect simultaneously from multiple clients and see the same output in all of them. -- `2` - Multiple Characters per Account, one Session per Character. This will not auto-create a same-named - Character for you, instead you get to create/choose between a number of Characters up to a max limit given by +- `2` - Multiple Characters per Account, one Session per Character. This will not auto-create a same-named + Character for you, instead you get to create/choose between a number of Characters up to a max limit given by the `MAX_NR_CHARACTERS` setting (default 1). You can play them all simultaneously if you have multiple clients open, but only one client per Character. - `3` - Multiple Characters per Account, Multiple Sessions per Character. This is like mode 2, except players - can control each Character from multiple clients, seeing the same output from each Character. + can control each Character from multiple clients, seeing the same output from each Character. -We will go with a multi-role game, so we will use `MULTISESSION_MODE=3` for this tutorial. +We will go with a multi-role game, so we will use `MULTISESSION_MODE=3` for this tutorial. -#### How does the character-generation work? +### How does the character-generation work? There are a few common ways to do character generation: -- Rooms. This is the traditional way. Each room's description tells you what command to use to modify +- Rooms. This is the traditional way. Each room's description tells you what command to use to modify your character. When you are done you move to the next room. Only use this if you have another reason for using a room, like having a training dummy to test skills on, for example. -- A Menu. The Evennia _EvMenu_ system allows you to code very flexible in-game menus without needing to walk +- A Menu. The Evennia _EvMenu_ system allows you to code very flexible in-game menus without needing to walk between rooms. You can both have a step-by-step menu (a 'wizard') or allow the user to jump between the - steps as they please. This tends to be a lot easier for newcomers to understand since it doesn't require + steps as they please. This tends to be a lot easier for newcomers to understand since it doesn't require using custom commands they will likely never use again after this. - Questions. A fun way to build a character is to answer a series of questions. This is usually implemented - with a sequential menu. + with a sequential menu. For the tutorial we will use a menu to let the user modify each section of their character sheet in any order -until they are happy. - -#### How do you implement different "classes" or "races"? +until they are happy. -The way classes and races work in most RPGs (as well as in OpenAdventure) is that they act as static 'templates' -that inform which bonuses and special abilities you have. This means that all we need to store on the -Character is _which_ class and _which_ race they have; the actual logic can sit in Python code and just -be looked up when we need it. +### How do you implement different "classes" or "races"? -#### If a Character can hide in a room, what skill will decide if they are detected? +The way classes and races work in most RPGs (as well as in OpenAdventure) is that they act as static 'templates' +that inform which bonuses and special abilities you have. This means that all we need to store on the +Character is _which_ class and _which_ race they have; the actual logic can sit in Python code and just +be looked up when we need it. -Hiding means a few things. +### If a Character can hide in a room, what skill will decide if they are detected? + +Hiding means a few things. - The Character should not appear in the room's description / character list - Others hould not be able to interact with a hidden character. It'd be weird if you could do `attack ` or `look ` if the named character is in hiding. - There must be a way for the person to come out of hiding, and probably for others to search or accidentally find the person (probably based on skill checks). -- The room will also need to be involved, maybe with some modifier as to how easy it is to hide in the room. +- The room will also need to be involved, maybe with some modifier as to how easy it is to hide in the room. -We will _not_ be including a hide-mechanic in EvAdventure though. +We will _not_ be including a hide-mechanic in EvAdventure though. -#### What does the skill tree look like? Can a Character gain experience to improve? By killing enemies? Solving quests? By roleplaying? +### What does the skill tree look like? Can a Character gain experience to improve? By killing enemies? Solving quests? By roleplaying? -Gaining experience points (XP) and improving one's character is a staple of roleplaying games. There are many -ways to implement this: -- Gaining XP from kills is very common; it's easy to let a monster be 'worth' a certain number of XP and it's - easy to tell when you should gain it. +Gaining experience points (XP) and improving one's character is a staple of roleplaying games. There are many +ways to implement this: +- Gaining XP from kills is very common; it's easy to let a monster be 'worth' a certain number of XP and it's + easy to tell when you should gain it. - Gaining XP from quests is the same - each quest is 'worth' XP and you get them when completing the test. - Gaining XP from roleplay is harder to define. Different games have tried a lot of different ways to do this: - - XP from being online - just being online gains you XP. This inflates player numbers but many players may + - XP from being online - just being online gains you XP. This inflates player numbers but many players may just be lurking and not be actually playing the game at any given time. - - XP from roleplaying scenes - you gain XP according to some algorithm analyzing your emotes for 'quality', - how often you post, how long your emotes are etc. + - XP from roleplaying scenes - you gain XP according to some algorithm analyzing your emotes for 'quality', + how often you post, how long your emotes are etc. - XP from actions - you gain XP when doing things, anything. Maybe your XP is even specific to each action, so you gain XP only for running when you run, XP for your axe skill when you fight with an axe etc. - - XP from fails - you only gain XP when failing rolls. - - XP from other players - other players can award you XP for good RP. - -For EvAdventure we will use Open Adventure's rules for XP, which will be driven by kills and quest successes. - -#### May player-characters attack each other (PvP)? + - XP from fails - you only gain XP when failing rolls. + - XP from other players - other players can award you XP for good RP. -Deciding this affects the style of your entire game. PvP makes for exciting gameplay but it opens a whole new -can of worms when it comes to "fairness". Players will usually accept dying to an overpowered NPC dragon. They -will not be as accepting if they perceive another player is perceived as being overpowered. PvP means that you -have to be very careful to balance the game - all characters does not have to be exactly equal but they should -all be viable to play a fun game with. PvP does not only mean combat though. Players can compete in all sorts of ways, including gaining influence in -a political game or gaining market share when selling their crafted merchandise. +For EvAdventure we will use Open Adventure's rules for XP, which will be driven by kills and quest successes. + +### May player-characters attack each other (PvP)? + +Deciding this affects the style of your entire game. PvP makes for exciting gameplay but it opens a whole new +can of worms when it comes to "fairness". Players will usually accept dying to an overpowered NPC dragon. They +will not be as accepting if they perceive another player is perceived as being overpowered. PvP means that you +have to be very careful to balance the game - all characters does not have to be exactly equal but they should +all be viable to play a fun game with. PvP does not only mean combat though. Players can compete in all sorts of ways, including gaining influence in +a political game or gaining market share when selling their crafted merchandise. For the EvAdventure we will support both Player-vs-environment combat and turn-based PvP. We will allow players to barter with each other (so potentially scam others?) but that's the extent of it. We will focus on showing -off techniques and will not focus on making a balanced game. +off techniques and will not focus on making a balanced game. -#### What are the penalties of defeat? Permanent death? Quick respawn? Time in prison? +### What are the penalties of defeat? Permanent death? Quick respawn? Time in prison? This is another big decision that strongly affects the mood and style of your game. -Perma-death means that once your character dies, it's gone and you have to make a new one. +Perma-death means that once your character dies, it's gone and you have to make a new one. -- It allows for true heroism. If you genuinely risk losing your character of two years to fight the dragon, +- It allows for true heroism. If you genuinely risk losing your character of two years to fight the dragon, your triumph is an actual feat. - It limits the old-timer dominance problem. If long-time players dies occationally, it will open things - up for newcomers. -- It lowers inflation, since the hoarded resources of a dead character can be removed. -- It gives capital punishment genuine discouraging power. -- It's realistic. + up for newcomers. +- It lowers inflation, since the hoarded resources of a dead character can be removed. +- It gives capital punishment genuine discouraging power. +- It's realistic. -Perma-death comes with some severe disadvantages however. +Perma-death comes with some severe disadvantages however. -- It's impopular. Many players will just not play a game where they risk losing their beloved character - just like that. +- It's impopular. Many players will just not play a game where they risk losing their beloved character + just like that. - Many players say they like the _idea_ of permadeath except when it could happen to them. - It can limit roleplaying freedom and make people refuse to take any risks. - It may make players even more reluctant to play conflict-driving 'bad guys'. - Game balance is much, much more important when results are "final". This escalates the severity of 'unfairness' a hundred-fold. Things like bugs or exploits can also lead to much more server effects. - + For these reasons, it's very common to do hybrid systems. Some tried variations: -- NPCs cannot kill you, only other players can. +- NPCs cannot kill you, only other players can. - Death is permanent, but it's difficult to actually die - you are much more likely to end up being severely -hurt/incapacitated. +hurt/incapacitated. - You can pre-pay 'insurance' to magically/technologically avoid actually dying. Only if don't have insurance will you die permanently. - Death just means harsh penalties, not actual death. -- When you die you can fight your way back to life from some sort of afterlife. +- When you die you can fight your way back to life from some sort of afterlife. - You'll only die permanently if you as a player explicitly allows it. - + For our tutorial-game we will not be messing with perma-death; instead your defeat will mean you will re-spawn -back at your home location with a fraction of your health. +back at your home location with a fraction of your health. -## Conclusions +## Conclusions -Going through the questions has helped us get a little bit more of a feel for the game we want to do. There are +Going through the questions has helped us get a little bit more of a feel for the game we want to do. There are many other things we could ask ourselves, but if we can cover these points we will be a good way towards a complete, -playable game! +playable game! Before starting to code in earnest a good coder should always do an inventory of all the stuff they _don't_ need -to code themselves. So in the next lesson we will check out what help we have from Evennia's _contribs_. +to code themselves. So in the next lesson we will check out what help we have from Evennia's _contribs_. diff --git a/docs/source/Howto/Starting/Part2/Planning-Where-Do-I-Begin.md b/docs/source/Howto/Starting/Part2/Planning-Where-Do-I-Begin.md index c5af620bc5..23bbdf6b0c 100644 --- a/docs/source/Howto/Starting/Part2/Planning-Where-Do-I-Begin.md +++ b/docs/source/Howto/Starting/Part2/Planning-Where-Do-I-Begin.md @@ -121,7 +121,7 @@ question. And maybe you’ll find that you have a better feeling for the answer Once you are out of the starting tutorial, you'll be off to do your own thing. -- The starting tutorial cannot cover everything. Skim through the [Evennia docs](../../../index). +- The starting tutorial cannot cover everything. Skim through the [Evennia docs](../../../index.md). Even if you don't read everything, it gives you a feeling for what's available should you need to look for something later. Make sure to use the search function. - You can now start by expanding on the tutorial-game we will have created. In the last part there diff --git a/docs/source/Howto/Starting/Part2/Starting-Part2.md b/docs/source/Howto/Starting/Part2/Starting-Part2.md index c56988054f..f31330ef24 100644 --- a/docs/source/Howto/Starting/Part2/Starting-Part2.md +++ b/docs/source/Howto/Starting/Part2/Starting-Part2.md @@ -1,12 +1,13 @@ # Evennia Starting Tutorial (Part 2) -```sidebar:: Tutorial Parts +```{eval-rst} +.. sidebar:: Tutorial Parts Part 1: `What we have <../Part1/Starting-Part1.html>`_ A tour of Evennia and how to use the tools, including an introduction to Python. **Part 2: What we want** Planning our tutorial game and what to think about when planning your own in the future. - Part 3: `How we get there <../Part3/Starting-Part3.html>`_ + Part 3: `How we get there <../Part3/Starting-Part3.html>`_ Getting down to the meat of extending Evennia to make our game Part 4: `Using what we created <../Part4/Starting-Part4.html>`_ Building a tech-demo and world content to go with our code @@ -16,25 +17,25 @@ ## Lessons for Part 2 -In Part two of the Starting tutorial we'll step back and plan out the kind of tutorial +In Part two of the Starting tutorial we'll step back and plan out the kind of tutorial game we want to make. This is a more 'theoretical' part where we won't do any hands-on -programming. +programming. 1. Introduction & Overview (you are here) -1. [Where do I begin](./Planning-Where-Do-I-Begin) -1. [On planning a game](./Game-Planning) -1. [Planning to use some useful Contribs](./Planning-Some-Useful-Contribs) +1. [Where do I begin](./Planning-Where-Do-I-Begin.md) +1. [On planning a game](./Game-Planning.md) +1. [Planning to use some useful Contribs](./Planning-Some-Useful-Contribs.md) In the process we'll go through the common questions of "where to start" and "what to think about" when creating a multiplayer online text game. -```toctree:: - :hidden: +```{toctree} +:hidden: - Planning-Where-Do-I-Begin - Game-Planning - Planning-Some-Useful-Contribs - ../Part3/Starting-Part3 +Planning-Where-Do-I-Begin +Game-Planning +Planning-Some-Useful-Contribs +../Part3/Starting-Part3 ``` diff --git a/docs/source/Howto/Starting/Part3/A-Sittable-Object.md b/docs/source/Howto/Starting/Part3/A-Sittable-Object.md index a51c9b52e4..22f47abfe9 100644 --- a/docs/source/Howto/Starting/Part3/A-Sittable-Object.md +++ b/docs/source/Howto/Starting/Part3/A-Sittable-Object.md @@ -1,32 +1,32 @@ -[prev lesson](../../../Unimplemented) | [next lesson](../../../Unimplemented) +[prev lesson](../../../Unimplemented.md) | [next lesson](../../../Unimplemented.md) -# Making a sittable object +# Making a sittable object -In this lesson we will go through how to make a chair you can sit on. Sounds easy, right? -Well it is. But in the process of making the chair we will need to consider the various ways -to do it depending on how we want our game to work. +In this lesson we will go through how to make a chair you can sit on. Sounds easy, right? +Well it is. But in the process of making the chair we will need to consider the various ways +to do it depending on how we want our game to work. The goals of this lesson are as follows: - + - We want a new 'sittable' object, a Chair in particular". -- We want to be able to use a command to sit in the chair. +- We want to be able to use a command to sit in the chair. - Once we are sitting in the chair it should affect us somehow. To demonstrate this we'll - set a flag "Resting" on the Character sitting in the Chair. + set a flag "Resting" on the Character sitting in the Chair. - When you sit down you should not be able to walk to another room without first standing up. -- A character should be able to stand up and move away from the chair. +- A character should be able to stand up and move away from the chair. There are two main ways to design the commands for sitting and standing up. - You can store the commands on the chair so they are only available when a chair is in the room - You can store the commands on the Character so they are always available and you must always specify which chair to sit on. - + Both of these are very useful to know about, so in this lesson we'll try both. But first -we need to handle some basics. +we need to handle some basics. ## Don't move us when resting -When you are sitting in a chair you can't just walk off without first standing up. +When you are sitting in a chair you can't just walk off without first standing up. This requires a change to our Character typeclass. Open `mygame/typeclasses/characters.py`: ```python @@ -39,7 +39,7 @@ class Character(DefaultCharacter): def at_before_move(self, destination): """ Called by self.move_to when trying to move somewhere. If this returns - False, the move is immediately cancelled. + False, the move is immediately cancelled. """ if self.db.is_resting: self.msg("You can't go anywhere while resting.") @@ -48,15 +48,15 @@ class Character(DefaultCharacter): ``` -When moving somewhere, [character.move_to](api.objects.objects#Object.move_to) is called. This in turn +When moving somewhere, [character.move_to](evennia.objects.objects.DefaultObject.move_to) is called. This in turn will call `character.at_before_move`. Here we look for an Attribute `is_resting` (which we will assign below) -to determine if we are stuck on the chair or not. +to determine if we are stuck on the chair or not. -## Making the Chair itself +## Making the Chair itself -Next we need the Chair itself, or rather a whole family of "things you can sit on" that we will call -_sittables_. We can't just use a default Object since we want a sittable to contain some custom code. We need -a new, custom Typeclass. Create a new module `mygame/typeclasses/sittables.py` with the following content: +Next we need the Chair itself, or rather a whole family of "things you can sit on" that we will call +_sittables_. We can't just use a default Object since we want a sittable to contain some custom code. We need +a new, custom Typeclass. Create a new module `mygame/typeclasses/sittables.py` with the following content: ```python @@ -69,8 +69,8 @@ class Sittable(DefaultObject): def do_sit(self, sitter): """ - Called when trying to sit on/in this object. - + Called when trying to sit on/in this object. + Args: sitter (Object): The one trying to sit down. @@ -78,43 +78,43 @@ class Sittable(DefaultObject): current = self.db.sitter if current: if current == sitter: - sitter.msg("You are already sitting on {self.key}.") + sitter.msg("You are already sitting on {self.key}.") else: sitter.msg(f"You can't sit on {self.key} " f"- {current.key} is already sitting there!") - return + return self.db.sitting = sitter sitter.db.is_resting = True sitter.msg(f"You sit on {self.key}") def do_stand(self, stander): """ - Called when trying to stand from this object. + Called when trying to stand from this object. Args: stander (Object): The one trying to stand up. """ - current = self.db.sitter + current = self.db.sitter if not stander == current: stander.msg(f"You are not sitting on {self.key}.") else: self.db.sitting = None - stander.db.is_resting = False + stander.db.is_resting = False stander.msg(f"You stand up from {self.key}") ``` -Here we have a small Typeclass that handles someone trying to sit on it. It has two methods that we can simply +Here we have a small Typeclass that handles someone trying to sit on it. It has two methods that we can simply call from a Command later. We set the `is_resting` Attribute on the one sitting down. - -One could imagine that one could have the future `sit` command check if someone is already sitting in the + +One could imagine that one could have the future `sit` command check if someone is already sitting in the chair instead. This would work too, but letting the `Sittable` class handle the logic around who can sit on it makes -logical sense. +logical sense. We let the typeclass handle the logic, and also let it do all the return messaging. This makes it easy to churn out a bunch of chairs for people to sit on. But it's not perfect. The `Sittable` class is general. What if you want to make an armchair. You sit "in" an armchair rather than "on" it. We _could_ make a child class of `Sittable` named -`SittableIn` that makes this change, but that feels excessive. Instead we will make it so that Sittables can +`SittableIn` that makes this change, but that feels excessive. Instead we will make it so that Sittables can modify this per-instance: @@ -126,13 +126,13 @@ class Sittable(DefaultObject): def at_object_creation(self): self.db.sitter = None - # do you sit "on" or "in" this object? + # do you sit "on" or "in" this object? self.db.adjective = "on" def do_sit(self, sitter): """ - Called when trying to sit on/in this object. - + Called when trying to sit on/in this object. + Args: sitter (Object): The one trying to sit down. @@ -141,46 +141,46 @@ class Sittable(DefaultObject): current = self.db.sitter if current: if current == sitter: - sitter.msg(f"You are already sitting {adjective} {self.key}.") + sitter.msg(f"You are already sitting {adjective} {self.key}.") else: sitter.msg( f"You can't sit {adjective} {self.key} " f"- {current.key} is already sitting there!") - return + return self.db.sitting = sitter sitter.db.is_resting = True sitter.msg(f"You sit {adjective} {self.key}") def do_stand(self, stander): """ - Called when trying to stand from this object. + Called when trying to stand from this object. Args: stander (Object): The one trying to stand up. """ - current = self.db.sitter + current = self.db.sitter if not stander == current: stander.msg(f"You are not sitting {self.db.adjective} {self.key}.") else: self.db.sitting = None - stander.db.is_resting = False + stander.db.is_resting = False stander.msg(f"You stand up from {self.key}") ``` We added a new Attribute `adjective` which will probably usually be `in` or `on` but could also be `at` if you -want to be able to sit _at a desk_ for example. A regular builder would use it like this: +want to be able to sit _at a desk_ for example. A regular builder would use it like this: > create/drop armchair : sittables.Sittable > set armchair/adjective = in This is probably enough. But all those strings are hard-coded. What if we want some more dramatic flair when you -sit down? +sit down? - You sit down and a whoopie cushion makes a loud fart noise! + You sit down and a whoopie cushion makes a loud fart noise! -For this we need to allow some further customization. Let's let the current strings be defaults that -we can replace. +For this we need to allow some further customization. Let's let the current strings be defaults that +we can replace. ```python @@ -188,13 +188,13 @@ from evennia import DefaultObject class Sittable(DefaultObject): """ - An object one can sit on + An object one can sit on - Customizable Attributes: + Customizable Attributes: adjective: How to sit (on, in, at etc) Return messages (set as Attributes): msg_already_sitting: Already sitting here - format tokens {adjective} and {key} + format tokens {adjective} and {key} msg_other_sitting: Someone else is sitting here. format tokens {adjective}, {key} and {other} msg_sitting_down: Successfully sit down @@ -207,13 +207,13 @@ class Sittable(DefaultObject): """ def at_object_creation(self): self.db.sitter = None - # do you sit "on" or "in" this object? + # do you sit "on" or "in" this object? self.db.adjective = "on" def do_sit(self, sitter): """ - Called when trying to sit on/in this object. - + Called when trying to sit on/in this object. + Args: sitter (Object): The one trying to sit down. @@ -235,7 +235,7 @@ class Sittable(DefaultObject): else: sitter.msg(f"You can't sit {adjective} {self.key} " f"- {current.key} is already sitting there!") - return + return self.db.sitting = sitter sitter.db.is_resting = True if self.db.msg_sitting_down: @@ -245,13 +245,13 @@ class Sittable(DefaultObject): def do_stand(self, stander): """ - Called when trying to stand from this object. + Called when trying to stand from this object. Args: stander (Object): The one trying to stand up. """ - current = self.db.sitter + current = self.db.sitter if not stander == current: if self.db.msg_standing_fail: stander.msg(self.db.msg_standing_fail.format( @@ -260,7 +260,7 @@ class Sittable(DefaultObject): stander.msg(f"You are not sitting {self.db.adjective} {self.key}") else: self.db.sitting = None - stander.db.is_resting = False + stander.db.is_resting = False if self.db.msg_standing_up: stander.msg(self.db.msg_standing_up.format( adjective=self.db.adjective, key=self.key)) @@ -268,55 +268,55 @@ class Sittable(DefaultObject): stander.msg(f"You stand up from {self.key}") ``` -Here we really went all out with flexibility. If you need this much is up to you. -We added a bunch of optional Attributes to hold alternative versions of all the messages. -There are some things to note: +Here we really went all out with flexibility. If you need this much is up to you. +We added a bunch of optional Attributes to hold alternative versions of all the messages. +There are some things to note: -- We don't actually initiate those Attributes in `at_object_creation`. This is a simple -optimization. The assumption is that _most_ chairs will probably not be this customized. -So initiating a bunch of Attributes to, say, empty strings would be a lot of useless database calls. +- We don't actually initiate those Attributes in `at_object_creation`. This is a simple +optimization. The assumption is that _most_ chairs will probably not be this customized. +So initiating a bunch of Attributes to, say, empty strings would be a lot of useless database calls. The drawback is that the available Attributes become less visible when reading the code. So we add a long -describing docstring to the end to explain all you can use. +describing docstring to the end to explain all you can use. - We use `.format` to inject formatting-tokens in the text. The good thing about such formatting -markers is that they are _optional_. They are there if you want them, but Python will not complain -if you don't include some or any of them. Let's see an example: +markers is that they are _optional_. They are there if you want them, but Python will not complain +if you don't include some or any of them. Let's see an example: > reload # if you have new code - > create/drop armchair : sittables.Sittable + > create/drop armchair : sittables.Sittable > set armchair/adjective = in > set armchair/msg_sitting_down = As you sit down {adjective} {key}, life feels easier. > set armchair/msg_standing_up = You stand up from {key}. Life resumes. - -The `{key}` and `{adjective}` are examples of optional formatting markers. Whenever the message is -returned, the format-tokens within will be replaced with `armchair` and `in` respectively. Should we + +The `{key}` and `{adjective}` are examples of optional formatting markers. Whenever the message is +returned, the format-tokens within will be replaced with `armchair` and `in` respectively. Should we rename the chair later, this will show in the messages automatically (since `{key}` will change). We have no Command to use this chair yet. But we can try it out with `py`: > py self.search("armchair").do_sit(self) - As you sit down in armchair, life feels easier. - > self.db.resting + As you sit down in armchair, life feels easier. + > self.db.resting True > py self.search("armchair").do_stand(self) - You stand up from armchair. Life resumes - > self.db.resting - False - -If you follow along and get a result like this, all seems to be working well! + You stand up from armchair. Life resumes + > self.db.resting + False + +If you follow along and get a result like this, all seems to be working well! ## Command variant 1: Commands on the chair This way to implement `sit` and `stand` puts new cmdsets on the Sittable itself. -As we've learned before, commands on objects are made available to others in the room. -This makes the command easy but instead adds some complexity in the management of the CmdSet. +As we've learned before, commands on objects are made available to others in the room. +This makes the command easy but instead adds some complexity in the management of the CmdSet. -This is how it will look if `armchair` is in the room: +This is how it will look if `armchair` is in the room: - > sit - As you sit down in armchair, life feels easier. + > sit + As you sit down in armchair, life feels easier. What happens if there are sittables `sofa` and `barstool` also in the room? Evennia will automatically -handle this for us and allow us to specify which one we want: +handle this for us and allow us to specify which one we want: > sit More than one match for 'sit' (please narrow target): @@ -325,24 +325,24 @@ handle this for us and allow us to specify which one we want: sit-3 (barstool) > sit-1 As you sit down in armchair, life feels easier. - + To keep things separate we'll make a new module `mygame/commands/sittables.py`: - -```sidebar:: Separate Commands and Typeclasses? + +```{sidebar} Separate Commands and Typeclasses? You can organize these things as you like. If you wanted you could put the sit-command + cmdset - together with the `Sittable` typeclass in `mygame/typeclasses/sittables.py`. That has the advantage of - keeping everything related to sitting in one place. But there is also some organizational merit to - keeping all Commands in one place as we do here. + together with the `Sittable` typeclass in `mygame/typeclasses/sittables.py`. That has the advantage of + keeping everything related to sitting in one place. But there is also some organizational merit to + keeping all Commands in one place as we do here. ``` ```python from evennia import Command, CmdSet -class CmdSit(Command): +class CmdSit(Command): """ - Sit down. + Sit down. """ key = "sit" @@ -366,65 +366,65 @@ class CmdSetSit(CmdSet): ``` -As seen, the commands are nearly trivial. `self.obj` is the object to which we added the cmdset with this -Command (so for example a chair). We just call the `do_sit/stand` on that object and the `Sittable` will +As seen, the commands are nearly trivial. `self.obj` is the object to which we added the cmdset with this +Command (so for example a chair). We just call the `do_sit/stand` on that object and the `Sittable` will do the rest. Why that `priority = 1` on `CmdSetSit`? This makes same-named Commands from this cmdset merge with a bit higher -priority than Commands from the Character-cmdset. Why this is a good idea will become clear shortly. - +priority than Commands from the Character-cmdset. Why this is a good idea will become clear shortly. + We also need to make a change to our `Sittable` typeclass. Open `mygame/typeclasses/sittables.py`: - + ```python from evennia import DefaultObject -from commands.sittables import CmdSetSit # <- new +from commands.sittables import CmdSetSit # <- new -class Sittable(DefaultObject): +class Sittable(DefaultObject): """ (docstring) - """ + """ def at_object_creation(self): self.db.sitter = None - # do you sit "on" or "in" this object? + # do you sit "on" or "in" this object? self.db.adjective = "on" self.cmdset.add_default(CmdSetSit) # <- new -``` +``` -Any _new_ Sittables will now have your `sit` Command. Your existing `armchair` will not, -since `at_object_creation` will not re-run for already existing objects. We can update it manually: +Any _new_ Sittables will now have your `sit` Command. Your existing `armchair` will not, +since `at_object_creation` will not re-run for already existing objects. We can update it manually: + + > reload + > update armchair - > reload - > update armchair - We could also update all existing sittables (all on one line): - > py from typeclasses.sittables import Sittable ; + > py from typeclasses.sittables import Sittable ; [sittable.at_object_creation() for sittable in Sittable.objects.all()] - -> The above shows an example of a _list comprehension_. Think of it as an efficient way to construct a new list -all in one line. You can read more about list comprehensions + +> The above shows an example of a _list comprehension_. Think of it as an efficient way to construct a new list +all in one line. You can read more about list comprehensions [here in the Python docs](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions). - + We should now be able to use `sit` while in the room with the armchair. - > sit + > sit As you sit down in armchair, life feels easier. - > stand + > stand You stand up from armchair. -One issue with placing the `sit` (or `stand`) Command "on" the chair is that it will not be available when in a -room without a Sittable object: +One issue with placing the `sit` (or `stand`) Command "on" the chair is that it will not be available when in a +room without a Sittable object: - > sit + > sit Command 'sit' is not available. ... - -This is practical but not so good-looking; it makes it harder for the user to know a `sit` action is at all -possible. Here is a trick for fixing this. Let's add _another_ Command to the bottom + +This is practical but not so good-looking; it makes it harder for the user to know a `sit` action is at all +possible. Here is a trick for fixing this. Let's add _another_ Command to the bottom of `mygame/commands/sittables.py`: ```python -# ... +# ... class CmdNoSitStand(Command): """ @@ -441,15 +441,15 @@ class CmdNoSitStand(Command): ``` -Here we have a Command that is actually two - it will answer to both `sit` and `stand` since we -added `stand` to its `aliases`. In the command we look at `self.cmdname`, which is the string -_actually used_ to call this command. We use this to return different messages. +Here we have a Command that is actually two - it will answer to both `sit` and `stand` since we +added `stand` to its `aliases`. In the command we look at `self.cmdname`, which is the string +_actually used_ to call this command. We use this to return different messages. -We don't need a separate CmdSet for this, instead we will add this +We don't need a separate CmdSet for this, instead we will add this to the default Character cmdset. Open `mygame/commands/default_cmdsets.py`: ```python -# ... +# ... from commands import sittables class CharacterCmdSet(CmdSet): @@ -462,36 +462,36 @@ class CharacterCmdSet(CmdSet): ``` -To test we'll build a new location without any comfy armchairs and go there: +To test we'll build a new location without any comfy armchairs and go there: - > reload - > tunnel n = kitchen - north - > sit + > reload + > tunnel n = kitchen + north + > sit You have nothing to sit on. - > south - sit + > south + sit As you sit down in armchair, life feels easier. - -We now have a fully functioning `sit` action that is contained with the chair itself. When no chair is around, a -default error message is shown. -How does this work? There are two cmdsets at play, both of which have a `sit` Command. As you may remember we -set the chair's cmdset to `priority = 1`. This is where that matters. The default Character cmdset has a +We now have a fully functioning `sit` action that is contained with the chair itself. When no chair is around, a +default error message is shown. + +How does this work? There are two cmdsets at play, both of which have a `sit` Command. As you may remember we +set the chair's cmdset to `priority = 1`. This is where that matters. The default Character cmdset has a priority of 0. This means that whenever we enter a room with a Sittable thing, the `sit` command -from _its_ cmdset will take _precedence_ over the Character cmdset's version. So we are actually picking +from _its_ cmdset will take _precedence_ over the Character cmdset's version. So we are actually picking _different_ `sit` commands depending on circumstance! The user will never be the wiser. - -So this handles `sit`. What about `stand`? That will work just fine: + +So this handles `sit`. What about `stand`? That will work just fine: > stand - You stand up from armchair. + You stand up from armchair. > north - > stand - You are not sitting down. - -We have one remaining problem with `stand` though - what happens when you are sitting down and try to -`stand` in a room with more than one chair: + > stand + You are not sitting down. + +We have one remaining problem with `stand` though - what happens when you are sitting down and try to +`stand` in a room with more than one chair: > stand More than one match for 'stand' (please narrow target): @@ -499,12 +499,12 @@ We have one remaining problem with `stand` though - what happens when you are si stand-2 (sofa) stand-3 (barstool) -Since all the sittables have the `stand` Command on them, you'll get a multi-match error. This _works_ ... but +Since all the sittables have the `stand` Command on them, you'll get a multi-match error. This _works_ ... but you could pick _any_ of those sittables to "stand up from". That's really weird and non-intuitive. With `sit` it -was okay to get a choice - Evennia can't know which chair we intended to sit on. But we know which chair we -sit on so we should only get _its_ `stand` command. +was okay to get a choice - Evennia can't know which chair we intended to sit on. But we know which chair we +sit on so we should only get _its_ `stand` command. -We will fix this with a `lock` and a custom `lock function`. We want a lock on the `stand` Command that only +We will fix this with a `lock` and a custom `lock function`. We want a lock on the `stand` Command that only makes it available when the caller is actually sitting on the chair the `stand` command is on. First let's add the lock so we see what we want. Open `mygame/commands/sittables.py`: @@ -518,37 +518,37 @@ class CmdStand(Command): """ key = "stand" lock = "cmd:sitsonthis()" # < this is new - + def func(self): self.obj.do_stand(self.caller) # ... ``` -We define a [Lock](../../../Components/Locks) on the command. The `cmd:` is in what situation Evennia will check -the lock. The `cmd` means that it will check the lock when determining if a user has access to this command or not. -What will be checked is the `sitsonthis` _lock function_ which doesn't exist yet. +We define a [Lock](../../../Components/Locks.md) on the command. The `cmd:` is in what situation Evennia will check +the lock. The `cmd` means that it will check the lock when determining if a user has access to this command or not. +What will be checked is the `sitsonthis` _lock function_ which doesn't exist yet. -Open `mygame/server/conf/lockfuncs.py` to add it! +Open `mygame/server/conf/lockfuncs.py` to add it! ```python """ (module lockstring) """ -# ... +# ... def sitsonthis(accessing_obj, accessed_obj, *args, **kwargs): """ - True if accessing_obj is sitting on/in the accessed_obj. + True if accessing_obj is sitting on/in the accessed_obj. """ return accessed_obj.db.sitting == accessing_obj -# ... +# ... ``` Evennia knows that all functions in `mygame/server/conf/lockfuncs` should be possible to use in a lock definition. -The arguments are required and Evennia will pass all relevant objects to them: +The arguments are required and Evennia will pass all relevant objects to them: -```sidebar:: Lockfuncs +```{sidebar} Lockfuncs Evennia provides a large number of default lockfuncs, such as checking permission-levels, if you are carrying or are inside the accessed object etc. There is no concept of 'sitting' @@ -556,53 +556,53 @@ The arguments are required and Evennia will pass all relevant objects to them: ``` -- `accessing_obj` is the one trying to access the lock. So us, in this case. +- `accessing_obj` is the one trying to access the lock. So us, in this case. - `accessed_obj` is the entity we are trying to gain a particular type of access to. So the chair. -- `args` is a tuple holding any arguments passed to the lockfunc. Since we use `sitsondthis()` this will +- `args` is a tuple holding any arguments passed to the lockfunc. Since we use `sitsondthis()` this will be empty (and if we add anything, it will be ignored). - `kwargs` is a tuple of keyword arguments passed to the lockfuncs. This will be empty as well in our example. -If you are superuser, it's important that you `quell` yourself before trying this out. This is because the superuser +If you are superuser, it's important that you `quell` yourself before trying this out. This is because the superuser bypasses all locks - it can never get locked out, but it means it will also not see the effects of a lock like this. - > reload - > quell - > stand - You stand up from armchair - -None of the other sittables' `stand` commands passed the lock and only the one we are actually sitting on did. + > reload + > quell + > stand + You stand up from armchair + +None of the other sittables' `stand` commands passed the lock and only the one we are actually sitting on did. Adding a Command to the chair object like this is powerful and a good technique to know. It does come with some -caveats though that one needs to keep in mind. +caveats though that one needs to keep in mind. We'll now try another way to add the `sit/stand` commands. -## Command variant 2: Command on Character +## Command variant 2: Command on Character -Before we start with this, delete the chairs you've created (`del armchair` etc) and then do the following -changes: +Before we start with this, delete the chairs you've created (`del armchair` etc) and then do the following +changes: - In `mygame/typeclasses/sittables.py`, comment out the line `self.cmdset.add_default(CmdSetSit)`. -- In `mygame/commands/default_cmdsets.py`, comment out the line `self.add(sittables.CmdNoSitStand)`. +- In `mygame/commands/default_cmdsets.py`, comment out the line `self.add(sittables.CmdNoSitStand)`. -This disables the on-object command solution so we can try an alternative. Make sure to `reload` so the -changes are known to Evennia. +This disables the on-object command solution so we can try an alternative. Make sure to `reload` so the +changes are known to Evennia. In this variation we will put the `sit` and `stand` commands on the `Character` instead of on the chair. This -makes some things easier, but makes the Commands themselves more complex because they will not know which -chair to sit on. We can't just do `sit` anymore. This is how it will work. +makes some things easier, but makes the Commands themselves more complex because they will not know which +chair to sit on. We can't just do `sit` anymore. This is how it will work. - > sit + > sit You sit on chair. - > stand + > stand You stand up from chair. - -Open `mygame/commands.sittables.py` again. We'll add a new sit-command. We name the class `CmdSit2` since -we already have `CmdSit` from the previous example. We put everything at the end of the module to -keep it separate. + +Open `mygame/commands.sittables.py` again. We'll add a new sit-command. We name the class `CmdSit2` since +we already have `CmdSit` from the previous example. We put everything at the end of the module to +keep it separate. ```python -from evennia import Command, CmdSet +from evennia import Command, CmdSet from evennia import InterruptCommand # <- this is new class CmdSit(Command): @@ -610,18 +610,18 @@ class CmdSit(Command): # ... -# new from here +# new from here class CmdSit2(Command): """ Sit down. - Usage: + Usage: sit - - """ + + """ key = "sit" - + def parse(self): self.args = self.args.strip() if not self.args: @@ -641,7 +641,7 @@ class CmdSit2(Command): ``` -With this Command-variation we need to search for the sittable. A series of methods on the Command +With this Command-variation we need to search for the sittable. A series of methods on the Command are run in sequence: 1. `Command.at_pre_command` - this is not used by default @@ -649,77 +649,77 @@ are run in sequence: 3. `Command.func` - this should implement the actual Command functionality 4. `Command.at_post_func` - this is not used by default -So if we just `return` in `.parse`, `.func` will still run, which is not what we want. To immediately +So if we just `return` in `.parse`, `.func` will still run, which is not what we want. To immediately abort this sequence we need to `raise InterruptCommand`. -```sidebar:: Raising exceptions +```{sidebar} Raising exceptions - Raising an exception allows for immediately interrupting the current program flow. Python - automatically raises error-exceptions when detecting problems with the code. It will be + Raising an exception allows for immediately interrupting the current program flow. Python + automatically raises error-exceptions when detecting problems with the code. It will be raised up through the sequence of called code (the 'stack') until it's either `caught` with a `try ... except` or reaches the outermost scope where it'll be logged or displayed. ``` -`InterruptCommand` is an _exception_ that the Command-system catches with the understanding that we want -to do a clean abort. In the `.parse` method we strip any whitespaces from the argument and -sure there actuall _is_ an argument. We abort immediately if there isn't. +`InterruptCommand` is an _exception_ that the Command-system catches with the understanding that we want +to do a clean abort. In the `.parse` method we strip any whitespaces from the argument and +sure there actuall _is_ an argument. We abort immediately if there isn't. We we get to `.func` at all, we know that we have an argument. We search for this and abort if we there was -a problem finding the target. +a problem finding the target. > We could have done `raise InterruptCommand` in `.func` as well, but `return` is a little shorter to write > and there is no harm done if `at_post_func` runs since it's empty. -Next we call the found sittable's `do_sit` method. Note that we wrap this call like this: +Next we call the found sittable's `do_sit` method. Note that we wrap this call like this: ```python try: - # code + # code except AttributeError: # stuff to do if AttributeError exception was raised ``` -The reason is that `caller.search` has no idea we are looking for a Sittable. The user could have tried +The reason is that `caller.search` has no idea we are looking for a Sittable. The user could have tried `sit wall` or `sit sword`. These don't have a `do_sit` method _but we call it anyway and handle the error_. This is a very "Pythonic" thing to do. The concept is often called "leap before you look" or "it's easier to ask for forgiveness than for permission". If `sittable.do_sit` does not exist, Python will raise an `AttributeError`. -We catch this with `try ... except AttributeError` and convert it to a proper error message. +We catch this with `try ... except AttributeError` and convert it to a proper error message. While it's useful to learn about `try ... except`, there is also a way to leverage Evennia to do this without `try ... except`: ```python - # ... + # ... def func(self): # self.search handles all error messages etc. sittable = self.caller.search( - self.args, + self.args, typeclass="typeclasses.sittables.Sittable") if not sittable: return sittable.do_sit(self.caller) ``` -```sidebar:: Continuing across multiple lines +```{sidebar} Continuing across multiple lines Note how the `.search()` method's arguments are spread out over multiple - lines. This works for all lists, tuples and other listings and is + lines. This works for all lists, tuples and other listings and is a good way to avoid very long and hard-to-read lines. ``` -The `caller.search` method has an keyword argument `typeclass` that can take either a python-path to a +The `caller.search` method has an keyword argument `typeclass` that can take either a python-path to a typeclass, the typeclass itself, or a list of either to widen the allowed options. In this case we know for sure that the `sittable` we get is actually a `Sittable` class and we can call `sittable.do_sit` without -needing to worry about catching errors. +needing to worry about catching errors. Let's do the `stand` command while we are at it. Again, since the Command is external to the chair we don't -know which object we are sitting in and have to search for it. +know which object we are sitting in and have to search for it. ```python @@ -727,43 +727,43 @@ class CmdStand2(Command): """ Stand up. - Usage: + Usage: stand - - """ + + """ key = "stand" - + def func(self): - caller = self.caller + caller = self.caller # find the thing we are sitting on/in, by finding the object - # in the current location that as an Attribute "sitter" set + # in the current location that as an Attribute "sitter" set # to the caller sittable = caller.search( - caller, + caller, candidates=caller.location.contents, - attribute_name="sitter", + attribute_name="sitter", typeclass="typeclasses.sittables.Sittable") # if this is None, the error was already reported to user if not sittable: - return + return sittable.do_stand(caller) - + ``` -This forced us to to use the full power of the `caller.search` method. If we wanted to search for something -more complex we would likely need to break out a [Django query](../Part1/Django-queries) to do it. The key here is that -we know that the object we are looking for is a `Sittable` and that it must have an Attribute named `sitter` -which should be set to us, the one sitting on/in the thing. Once we have that we just call `.do_stand` on it -and let the Typeclass handle the rest. +This forced us to to use the full power of the `caller.search` method. If we wanted to search for something +more complex we would likely need to break out a [Django query](../Part1/Django-queries.md) to do it. The key here is that +we know that the object we are looking for is a `Sittable` and that it must have an Attribute named `sitter` +which should be set to us, the one sitting on/in the thing. Once we have that we just call `.do_stand` on it +and let the Typeclass handle the rest. All that is left now is to make this available to us. This type of Command should be available to us all the time so we can put it in the default Cmdset` on the Character. Open `mygame/default_cmdsets.py` ```python -# ... +# ... from commands import sittables class CharacterCmdSet(CmdSet): @@ -777,26 +777,26 @@ class CharacterCmdSet(CmdSet): ``` -Now let's try it out: +Now let's try it out: - > reload + > reload > create/drop sofa : sittables.Sittable > sit sofa You sit down on sofa. - > stand + > stand You stand up from sofa. ## Conclusions -In this lesson we accomplished quite a bit: +In this lesson we accomplished quite a bit: - We modified our `Character` class to avoid moving when sitting down. - We made a new `Sittable` typeclass -- We tried two ways to allow a user to interact with sittables using `sit` and `stand` commands. +- We tried two ways to allow a user to interact with sittables using `sit` and `stand` commands. -Eagle-eyed readers will notice that the `stand` command sitting "on" the chair (variant 1) would work just fine -together with the `sit` command sitting "on" the Character (variant 2). There is nothing stopping you from -mixing them, or even try a third solution that better fits what you have in mind. +Eagle-eyed readers will notice that the `stand` command sitting "on" the chair (variant 1) would work just fine +together with the `sit` command sitting "on" the Character (variant 2). There is nothing stopping you from +mixing them, or even try a third solution that better fits what you have in mind. -[prev lesson](../../../Unimplemented) | [next lesson](../../../Unimplemented) \ No newline at end of file +[prev lesson](../../../Unimplemented.md) | [next lesson](../../../Unimplemented.md) diff --git a/docs/source/Howto/Starting/Part3/Implementing-a-game-rule-system.md b/docs/source/Howto/Starting/Part3/Implementing-a-game-rule-system.md index 4b8e50844f..85e752d974 100644 --- a/docs/source/Howto/Starting/Part3/Implementing-a-game-rule-system.md +++ b/docs/source/Howto/Starting/Part3/Implementing-a-game-rule-system.md @@ -45,12 +45,12 @@ makes it easier to change and update things in one place later. values for Health, a list of skills etc, store those things on the Character - don't store how to roll or change them. - Next is to determine just how you want to store things on your Objects and Characters. You can -choose to either store things as individual [Attributes](../../../Components/Attributes), like `character.db.STR=34` and +choose to either store things as individual [Attributes](../../../Components/Attributes.md), like `character.db.STR=34` and `character.db.Hunting_skill=20`. But you could also use some custom storage method, like a dictionary `character.db.skills = {"Hunting":34, "Fishing":20, ...}`. A much more fancy solution is to look at the Ainneve [Trait handler](https://github.com/evennia/ainneve/blob/master/world/traits.py). Finally you could even go -with a [custom django model](../../../Concepts/New-Models). Which is the better depends on your game and the +with a [custom django model](../../../Concepts/New-Models.md). Which is the better depends on your game and the complexity of your system. - Make a clear [API](https://en.wikipedia.org/wiki/Application_programming_interface) into your rules. That is, make methods/functions that you feed with, say, your Character and which skill you diff --git a/docs/source/Howto/Starting/Part3/Starting-Part3.md b/docs/source/Howto/Starting/Part3/Starting-Part3.md index cda32b590d..a92c601603 100644 --- a/docs/source/Howto/Starting/Part3/Starting-Part3.md +++ b/docs/source/Howto/Starting/Part3/Starting-Part3.md @@ -1,6 +1,8 @@ # Evennia Starting Tutorial (Part 3) -```sidebar:: Tutorial Parts +```{eval-rst} + +sidebar:: Tutorial Parts Part 1: `What we have <../Part1/Starting-Part1.html>`_ A tour of Evennia and how to use the tools, including an introduction to Python. @@ -13,33 +15,33 @@ Part 5: `Showing the world <../Part5/Starting-Part5.html>`_ Taking our new game online and let players try it out ``` -In part three of the Evennia Starting tutorial we will go through the creation of several key parts -of our tutorial game _EvAdventure_. As we go, we will test each part and create a simple "tech demo" to -show off all the moving parts. +In part three of the Evennia Starting tutorial we will go through the creation of several key parts +of our tutorial game _EvAdventure_. As we go, we will test each part and create a simple "tech demo" to +show off all the moving parts. 1. Introduction & Overview (you are here) -1. [Changing settings](../../../Unimplemented) -1. [Applying contribs](../../../Unimplemented) -1. [Creating a rule module](../../../Unimplemented) -1. [Tweaking the base Typeclasses](../../../Unimplemented) -1. [Character creation menu](../../../Unimplemented) -1. [Wearing armor and wielding weapons](../../../Unimplemented) -1. [Two types of combat](../../../Unimplemented) -1. [Monsters and AI](../../../Unimplemented) -1. [Questing and rewards](../../../Unimplemented) -1. [Overview of Tech demo](../../../Unimplemented) +1. [Changing settings](../../../Unimplemented.md) +1. [Applying contribs](../../../Unimplemented.md) +1. [Creating a rule module](../../../Unimplemented.md) +1. [Tweaking the base Typeclasses](../../../Unimplemented.md) +1. [Character creation menu](../../../Unimplemented.md) +1. [Wearing armor and wielding weapons](../../../Unimplemented.md) +1. [Two types of combat](../../../Unimplemented.md) +1. [Monsters and AI](../../../Unimplemented.md) +1. [Questing and rewards](../../../Unimplemented.md) +1. [Overview of Tech demo](../../../Unimplemented.md) If you followed the previous parts of this tutorial you will have some notions about Python and where to find -and make use of things in Evennia. We also have a good idea of the type of game we want. -Even if this is not the game-style you are interested in, following along will give you a lot of experience -with using Evennia. This be of much use when doing your own thing later. +and make use of things in Evennia. We also have a good idea of the type of game we want. +Even if this is not the game-style you are interested in, following along will give you a lot of experience +with using Evennia. This be of much use when doing your own thing later. _TODO_ -```toctree:: - :hidden: +```{toctree} +:hidden: - ../../../Unimplemented +../../../Unimplemented -``` \ No newline at end of file +``` diff --git a/docs/source/Howto/Starting/Part3/Turn-based-Combat-System.md b/docs/source/Howto/Starting/Part3/Turn-based-Combat-System.md index 1b8900cef1..b00459a784 100644 --- a/docs/source/Howto/Starting/Part3/Turn-based-Combat-System.md +++ b/docs/source/Howto/Starting/Part3/Turn-based-Combat-System.md @@ -31,8 +31,8 @@ allows for emoting as part of combat which is an advantage for roleplay-heavy ga To implement a freeform combat system all you need is a dice roller and a roleplaying rulebook. See [contrib/dice.py](https://github.com/evennia/evennia/blob/master/evennia/contrib/dice.py) for an example dice roller. To implement at twitch-based system you basically need a few combat -[commands](../../../Components/Commands), possibly ones with a [cooldown](../../Command-Cooldown). You also need a [game rule -module](Implementing-a-game-rule-system) that makes use of it. We will focus on the turn-based +[commands](../../../Components/Commands.md), possibly ones with a [cooldown](../../Command-Cooldown.md). You also need a [game rule +module](./Implementing-a-game-rule-system.md) that makes use of it. We will focus on the turn-based variety here. ## Tutorial overview @@ -61,22 +61,22 @@ reported. A new turn then begins. For creating the combat system we will need the following components: -- A combat handler. This is the main mechanic of the system. This is a [Script](../../../Components/Scripts) object +- A combat handler. This is the main mechanic of the system. This is a [Script](../../../Components/Scripts.md) object created for each combat. It is not assigned to a specific object but is shared by the combating characters and handles all the combat information. Since Scripts are database entities it also means that the combat will not be affected by a server reload. -- A combat [command set](../../../Components/Command-Sets) with the relevant commands needed for combat, such as the +- A combat [command set](../../../Components/Command-Sets.md) with the relevant commands needed for combat, such as the various attack/defend options and the `flee/disengage` command to leave the combat mode. - A rule resolution system. The basics of making such a module is described in the [rule system -tutorial](Implementing-a-game-rule-system). We will only sketch such a module here for our end-turn +tutorial](./Implementing-a-game-rule-system.md). We will only sketch such a module here for our end-turn combat resolution. -- An `attack` [command](../../../Components/Commands) for initiating the combat mode. This is added to the default +- An `attack` [command](../../../Components/Commands.md) for initiating the combat mode. This is added to the default command set. It will create the combat handler and add the character(s) to it. It will also assign the combat command set to the characters. ## The combat handler -The _combat handler_ is implemented as a stand-alone [Script](../../../Components/Scripts). This Script is created when +The _combat handler_ is implemented as a stand-alone [Script](../../../Components/Scripts.md). This Script is created when the first Character decides to attack another and is deleted when no one is fighting any more. Each handler represents one instance of combat and one combat only. Each instance of combat can hold any number of characters but each character can only be part of one combat at a time (a player would @@ -89,7 +89,7 @@ don't use this very much here this might allow the combat commands on the charac update the combat handler state directly. _Note: Another way to implement a combat handler would be to use a normal Python object and handle -time-keeping with the [TickerHandler](../../../Components/TickerHandler). This would require either adding custom hook +time-keeping with the [TickerHandler](../../../Components/TickerHandler.md). This would require either adding custom hook methods on the character or to implement a custom child of the TickerHandler class to track turns. Whereas the TickerHandler is easy to use, a Script offers more power in this case._ @@ -507,7 +507,7 @@ class CmdAttack(Command): ``` The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g. -the [Adding Command Tutorial](../Part1/Adding-Commands) if you are unsure about how to do this. +the [Adding Command Tutorial](../Part1/Adding-Commands.md) if you are unsure about how to do this. ## Expanding the example diff --git a/docs/source/Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game.md b/docs/source/Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game.md index 20991fc920..b9c345f88c 100644 --- a/docs/source/Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game.md +++ b/docs/source/Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game.md @@ -7,7 +7,7 @@ focused on free form storytelling. Even if you are not interested in MUSH:es, th first game-type to try since it's not so code heavy. You will be able to use the same principles for building other types of games. -The tutorial starts from scratch. If you did the [First Steps Coding](../Part1/Starting-Part1) tutorial +The tutorial starts from scratch. If you did the [First Steps Coding](../Part1/Starting-Part1.md) tutorial already you should have some ideas about how to do some of the steps already. The following are the (very simplistic and cut-down) features we will implement (this was taken from @@ -61,7 +61,7 @@ class Character(DefaultCharacter): self.db.combat_score = 1 ``` -We defined two new [Attributes](../../../Components/Attributes) `power` and `combat_score` and set them to default +We defined two new [Attributes](../../../Components/Attributes.md) `power` and `combat_score` and set them to default values. Make sure to `@reload` the server if you had it already running (you need to reload every time you update your python code, don't worry, no accounts will be disconnected by the reload). @@ -94,8 +94,8 @@ check it. Using this method however will make it easy to add more functionality What we need are the following: -- One character generation [Command](../../../Components/Commands) to set the "Power" on the `Character`. -- A chargen [CmdSet](../../../Components/Command-Sets) to hold this command. Lets call it `ChargenCmdset`. +- One character generation [Command](../../../Components/Commands.md) to set the "Power" on the `Character`. +- A chargen [CmdSet](../../../Components/Command-Sets.md) to hold this command. Lets call it `ChargenCmdset`. - A custom `ChargenRoom` type that makes this set of commands available to players in such rooms. - One such room to test things in. @@ -104,7 +104,7 @@ What we need are the following: For this tutorial we will add all our new commands to `mygame/commands/command.py` but you could split your commands into multiple module if you prefered. -For this tutorial character generation will only consist of one [Command](../../../Components/Commands) to set the +For this tutorial character generation will only consist of one [Command](../../../Components/Commands.md) to set the Character s "power" stat. It will be called on the following MUSH-like form: +setpower 4 @@ -156,7 +156,7 @@ This is a pretty straightforward command. We do some error checking, then set th We use a `help_category` of "mush" for all our commands, just so they are easy to find and separate in the help list. -Save the file. We will now add it to a new [CmdSet](../../../Components/Command-Sets) so it can be accessed (in a full +Save the file. We will now add it to a new [CmdSet](../../../Components/Command-Sets.md) so it can be accessed (in a full chargen system you would of course have more than one command here). Open `mygame/commands/default_cmdsets.py` and import your `command.py` module at the top. We also @@ -210,7 +210,7 @@ class ChargenRoom(Room): ``` Note how new rooms created with this typeclass will always start with `ChargenCmdset` on themselves. Don't forget the `persistent=True` keyword or you will lose the cmdset after a server reload. For -more information about [Command Sets](../../../Components/Command-Sets) and [Commands](../../../Components/Commands), see the respective +more information about [Command Sets](../../../Components/Command-Sets.md) and [Commands](../../../Components/Commands.md), see the respective links. ### Testing chargen @@ -242,7 +242,7 @@ between fixes. Don't continue until the creation seems to have worked okay. This should bring you to the chargen room. Being in there you should now have the `+setpower` command available, so test it out. When you leave (via the `finish` exit), the command will go away and trying `+setpower` should now give you a command-not-found error. Use `ex me` (as a privileged -user) to check so the `Power` [Attribute](../../../Components/Attributes) has been set correctly. +user) to check so the `Power` [Attribute](../../../Components/Attributes.md) has been set correctly. If things are not working, make sure your typeclasses and commands are free of bugs and that you have entered the paths to the various command sets and commands correctly. Check the logs or command @@ -397,7 +397,7 @@ There are a few ways to define the NPC class. We could in theory create a custom and put a custom NPC-specific cmdset on all NPCs. This cmdset could hold all manipulation commands. Since we expect NPC manipulation to be a common occurrence among the user base however, we will instead put all relevant NPC commands in the default command set and limit eventual access with -[Permissions and Locks](../../../Components/Locks#Permissions). +[Permissions and Locks](../../../Components/Permissions.md). ### Creating an NPC with +createNPC @@ -454,13 +454,13 @@ class CmdCreateNPC(Command): ), exclude=caller) ``` Here we define a `+createnpc` (`+createNPC` works too) that is callable by everyone *not* having the -`nonpcs` "[permission](../../../Components/Locks#Permissions)" (in Evennia, a "permission" can just as well be used to +`nonpcs` "[permission](../../../Components/Permissions.md)" (in Evennia, a "permission" can just as well be used to block access, it depends on the lock we define). We create the NPC object in the caller's current location, using our custom `Character` typeclass to do so. We set an extra lock condition on the NPC, which we will use to check who may edit the NPC later -- we allow the creator to do so, and anyone with the Builders permission (or higher). See -[Locks](../../../Components/Locks) for more information about the lock system. +[Locks](../../../Components/Locks.md) for more information about the lock system. Note that we just give the object default permissions (by not specifying the `permissions` keyword to the `create_object()` call). In some games one might want to give the NPC the same permissions @@ -475,7 +475,7 @@ Since we re-used our custom character typeclass, our new NPC already has a *Powe defaults to 1. How do we change this? There are a few ways we can do this. The easiest is to remember that the `power` attribute is just a -simple [Attribute](../../../Components/Attributes) stored on the NPC object. So as a Builder or Admin we could set this +simple [Attribute](../../../Components/Attributes.md) stored on the NPC object. So as a Builder or Admin we could set this right away with the default `@set` command: @set mynpc/power = 6 @@ -660,6 +660,6 @@ The simple "Power" game mechanic should be easily expandable to something more f useful, same is true for the combat score principle. The `+attack` could be made to target a specific player (or npc) and automatically compare their relevant attributes to determine a result. -To continue from here, you can take a look at the [Tutorial World](../Part1/Tutorial-World-Introduction). For -more specific ideas, see the [other tutorials and hints](../../Howto-Overview) as well -as the [Evennia Component overview](../../../Components/Components-Overview). +To continue from here, you can take a look at the [Tutorial World](../Part1/Tutorial-World-Introduction.md). For +more specific ideas, see the [other tutorials and hints](../../Howto-Overview.md) as well +as the [Evennia Component overview](../../../Components/Components-Overview.md). diff --git a/docs/source/Howto/Starting/Part4/Starting-Part4.md b/docs/source/Howto/Starting/Part4/Starting-Part4.md index 00e0856e3a..0a105a09ed 100644 --- a/docs/source/Howto/Starting/Part4/Starting-Part4.md +++ b/docs/source/Howto/Starting/Part4/Starting-Part4.md @@ -1,23 +1,24 @@ # Evennia Starting Tutorial (Part 4) -```sidebar:: Tutorial Parts +```{eval-rst} +sidebar:: Tutorial Parts Part 1: `What we have <../Part1/Starting-Part1.html>`_ A tour of Evennia and how to use the tools, including an introduction to Python. Part 2: `What we want <../Part2/Starting-Part2.html>`_ Planning our tutorial game and what to think about when planning your own in the future. - Part 3: `How we get there <../Part3/Starting-Part3.html>`_ + Part 3: `How we get there <../Part3/Starting-Part3.html>`_ Getting down to the meat of extending Evennia to make our game to make a tech-demo **Part 4: Using what we created** Using the tech-demo and world content to go with our code Part 5: `Showing the world <../Part5/Starting-Part5.html>`_ Taking our new game online and let players try it out -``` +``` -We now have the code underpinnings of everything we need. We have also tested the various components +We now have the code underpinnings of everything we need. We have also tested the various components and has a simple tech-demo to show it all works together. But there is no real coherence to it at this -point - we need to actually make a world. +point - we need to actually make a world. In part four we will expand our tech demo into a more full-fledged (if small) game by use of batchcommand -and batchcode processors. +and batchcode processors. -_TODO_ \ No newline at end of file +_TODO_ diff --git a/docs/source/Howto/Starting/Part5/Add-a-simple-new-web-page.md b/docs/source/Howto/Starting/Part5/Add-a-simple-new-web-page.md index e5ccfaf0d8..8e5030ec60 100644 --- a/docs/source/Howto/Starting/Part5/Add-a-simple-new-web-page.md +++ b/docs/source/Howto/Starting/Part5/Add-a-simple-new-web-page.md @@ -4,14 +4,14 @@ Evennia leverages [Django](https://docs.djangoproject.com) which is a web development framework. Huge professional websites are made in Django and there is extensive documentation (and books) on it . You are encouraged to at least look at the Django basic tutorials. Here we will just give a brief -introduction for how things hang together, to get you started. +introduction for how things hang together, to get you started. We assume you have installed and set up Evennia to run. A webserver and website comes out of the box. You can get to that by entering `http://localhost:4001` in your web browser - you should see a welcome page with some game statistics and a link to the web client. Let us add a new page that you can get to by going to `http://localhost:4001/story`. -### Create the view +## Create the view A django "view" is a normal Python function that django calls to render the HTML page you will see in the web browser. Here we will just have it spit back the raw html, but Django can do all sorts of @@ -32,12 +32,12 @@ def storypage(request): This view takes advantage of a shortcut provided to use by Django, _render_. This shortcut gives the template some information from the request, for instance, the game name, and then renders it. -### The HTML page +## The HTML page We need to find a place where Evennia (and Django) looks for html files (called *templates* in Django parlance). You can specify such places in your settings (see the `TEMPLATES` variable in `default_settings.py` for more info), but here we'll use an existing one. Go to -`mygame/template/overrides/website/` and create a page `story.html` there. +`mygame/template/overrides/website/` and create a page `story.html` there. This is not a HTML tutorial, so we'll go simple: @@ -69,14 +69,14 @@ If you'd rather not take advantage of Evennia's base styles, you can do somethin ``` - -### The URL + +## The URL When you enter the address `http://localhost:4001/story` in your web browser, Django will parse that field to figure out which page you want to go to. You tell it which patterns are relevant in the file [mygame/web/urls.py](https://github.com/evennia/evennia/blob/master/evennia/game_template/web/urls.py). -Open it now. +Open it now. Django looks for the variable `urlpatterns` in this file. You want to add your new pattern to the `custom_patterns` list we have prepared - that is then merged with the default `urlpatterns`. Here's @@ -97,4 +97,4 @@ instance. The first argument to `url` is the pattern of the url we want to find a regular expression if you are familiar with those) and then our view function we want to direct to. -That should be it. Reload Evennia and you should be able to browse to your new story page! \ No newline at end of file +That should be it. Reload Evennia and you should be able to browse to your new story page! diff --git a/docs/source/Howto/Starting/Part5/Starting-Part5.md b/docs/source/Howto/Starting/Part5/Starting-Part5.md index 704f2760dc..4703710859 100644 --- a/docs/source/Howto/Starting/Part5/Starting-Part5.md +++ b/docs/source/Howto/Starting/Part5/Starting-Part5.md @@ -1,12 +1,13 @@ # Evennia Starting Tutorial (part 5) -```sidebar:: Tutorial Parts +```{eval-rst} +.. sidebar:: Tutorial Parts Part 1: `What we have <../Part1/Starting-Part1.html>`_ A tour of Evennia and how to use the tools, including an introduction to Python. Part 2: `What we want <../Part2/Starting-Part2.html>`_ Planning our tutorial game and what to think about when planning your own in the future. - Part 3: `How we get there <../Part3/Starting-Part3.html>`_ + Part 3: `How we get there <../Part3/Starting-Part3.html>`_ Getting down to the meat of extending Evennia to make our game Part 4: `Using what we created <../Part4/Starting-Part4.html>`_ Building a tech-demo and world content to go with our code @@ -15,7 +16,7 @@ ``` You have a working game! In part five we will look at the web-components of Evennia and how to modify them -to fit your game. We will also look at hosting your game and if you feel up to it we'll also go through how -to bring your game online so you can invite your first players. +to fit your game. We will also look at hosting your game and if you feel up to it we'll also go through how +to bring your game online so you can invite your first players. -_TODO_ \ No newline at end of file +_TODO_ diff --git a/docs/source/Howto/Starting/Part5/Web-Tutorial.md b/docs/source/Howto/Starting/Part5/Web-Tutorial.md index ec6ad3b789..34f62b9f08 100644 --- a/docs/source/Howto/Starting/Part5/Web-Tutorial.md +++ b/docs/source/Howto/Starting/Part5/Web-Tutorial.md @@ -5,7 +5,7 @@ Evennia uses the [Django](https://www.djangoproject.com/) web framework as the b database configuration and the website it provides. While a full understanding of Django requires reading the Django documentation, we have provided this tutorial to get you running with the basics and how they pertain to Evennia. This text details getting everything set up. The -[Web-based Character view Tutorial](../../Web-Character-View-Tutorial) gives a more explicit example of making a +[Web-based Character view Tutorial](../../Web-Character-View-Tutorial.md) gives a more explicit example of making a custom web page connected to your game, and you may want to read that after finishing this guide. ## A Basic Overview @@ -25,7 +25,7 @@ like [CSS](https://en.wikipedia.org/wiki/CSS), [Javascript](https://en.wikipedia and Image files (You may note your mygame/web folder does not have a `static` or `template` folder. This is intended and explained further below). Django applications may also have a `models.py` file for storing information in the database. We will not change any models here, take a look at the -[New Models](../../../Concepts/New-Models) page (as well as the [Django docs](https://docs.djangoproject.com/en/1.7/topics/db/models/) on models) if you are interested. +[New Models](../../../Concepts/New-Models.md) page (as well as the [Django docs](https://docs.djangoproject.com/en/1.7/topics/db/models/) on models) if you are interested. There is also a root `urls.py` that determines the URL structure for the entire project. A starter `urls.py` is included in the default game template, and automatically imports all of Evennia's @@ -104,7 +104,7 @@ run any extra commands to see these changes - reloading the web page in your bro To replace the index page's text, we'll need to find the template for it. We'll go into more detail about how to determine which template is used for rendering a page in the -[Web-based Character view Tutorial](../../Web-Character-View-Tutorial). For now, you should know that the template we want to change +[Web-based Character view Tutorial](../../Web-Character-View-Tutorial.md). For now, you should know that the template we want to change is stored in `evennia/web/website/templates/website/index.html`. To replace this template file, you will put your changed template inside the @@ -120,7 +120,7 @@ original file already has all the markup and tags, ready for editing. ## Further reading For further hints on working with the web presence, you could now continue to the -[Web-based Character view Tutorial](../../Web-Character-View-Tutorial) where you learn to make a web page that +[Web-based Character view Tutorial](../../Web-Character-View-Tutorial.md) where you learn to make a web page that displays in-game character stats. You can also look at [Django's own tutorial](https://docs.djangoproject.com/en/1.7/intro/tutorial01/) to get more insight in how Django works and what possibilities exist. \ No newline at end of file diff --git a/docs/source/Howto/Tutorial-Aggressive-NPCs.md b/docs/source/Howto/Tutorial-Aggressive-NPCs.md index a4f224e029..b17e6519e8 100644 --- a/docs/source/Howto/Tutorial-Aggressive-NPCs.md +++ b/docs/source/Howto/Tutorial-Aggressive-NPCs.md @@ -5,17 +5,17 @@ This tutorial shows the implementation of an NPC object that responds to charact location. In this example the NPC has the option to respond aggressively or not, but any actions could be triggered this way. -One could imagine using a [Script](../Components/Scripts) that is constantly checking for newcomers. This would be +One could imagine using a [Script](../Components/Scripts.md) that is constantly checking for newcomers. This would be highly inefficient (most of the time its check would fail). Instead we handle this on-demand by using a couple of existing object hooks to inform the NPC that a Character has entered. It is assumed that you already know how to create custom room and character typeclasses, please see -the [Basic Game tutorial](Starting/Part3/Tutorial-for-basic-MUSH-like-game) if you haven't already done this. +the [Basic Game tutorial](Starting/Part3/Tutorial-for-basic-MUSH-like-game.md) if you haven't already done this. What we will need is the following: - An NPC typeclass that can react when someone enters. -- A custom [Room](../Components/Objects#rooms) typeclass that can tell the NPC that someone entered. +- A custom [Room](../Components/Objects.md#rooms) typeclass that can tell the NPC that someone entered. - We will also tweak our default `Character` typeclass a little. To begin with, we need to create an NPC typeclass. Create a new file inside of your typeclasses diff --git a/docs/source/Howto/Tutorial-NPCs-listening.md b/docs/source/Howto/Tutorial-NPCs-listening.md index 2cefe6d2c9..724427afae 100644 --- a/docs/source/Howto/Tutorial-NPCs-listening.md +++ b/docs/source/Howto/Tutorial-NPCs-listening.md @@ -6,7 +6,7 @@ their location. In this example the NPC parrots what is said, but any actions co this way. It is assumed that you already know how to create custom room and character typeclasses, please see -the [Basic Game tutorial](Starting/Part3/Tutorial-for-basic-MUSH-like-game) if you haven't already done this. +the [Basic Game tutorial](Starting/Part3/Tutorial-for-basic-MUSH-like-game.md) if you haven't already done this. What we will need is simply a new NPC typeclass that can react when someone speaks. diff --git a/docs/source/Howto/Tutorial-Tweeting-Game-Stats.md b/docs/source/Howto/Tutorial-Tweeting-Game-Stats.md index 61e996095e..495b3cba82 100644 --- a/docs/source/Howto/Tutorial-Tweeting-Game-Stats.md +++ b/docs/source/Howto/Tutorial-Tweeting-Game-Stats.md @@ -2,7 +2,7 @@ This tutorial will create a simple script that will send a tweet to your already configured twitter -account. Please see: [How to connect Evennia to Twitter](../Setup/How-to-connect-Evennia-to-Twitter) if you +account. Please see: [How to connect Evennia to Twitter](../Setup/How-to-connect-Evennia-to-Twitter.md) if you haven't already done so. The script could be expanded to cover a variety of statistics you might wish to tweet about @@ -89,7 +89,7 @@ randomly choosing between these outputs. 1. Shows the number of Player Characters, Rooms and Other/Objects 2. Shows the number of prototypes currently in the game and then selects 3 random keys to show -[Scripts Information](../Components/Scripts) will show you how to add it as a Global script, however, for testing +[Scripts Information](../Components/Scripts.md) will show you how to add it as a Global script, however, for testing it may be useful to start/stop it quickly from within the game. Assuming that you create the file as `mygame/typeclasses/tweet_stats.py` it can be started by using the following command diff --git a/docs/source/Howto/Tutorial-Vehicles.md b/docs/source/Howto/Tutorial-Vehicles.md index 6dce8d8fa4..a62aa485f3 100644 --- a/docs/source/Howto/Tutorial-Vehicles.md +++ b/docs/source/Howto/Tutorial-Vehicles.md @@ -50,7 +50,7 @@ and back (assuming we created it in limbo). Using the `@tel`command like shown above is obviously not what we want. `@tel` is an admin command and normal players will thus never be able to enter the train! It is also not really a good idea to -use [Exits](../Components/Objects#exits) to get in and out of the train - Exits are (at least by default) objects +use [Exits](../Components/Objects.md#exits) to get in and out of the train - Exits are (at least by default) objects too. They point to a specific destination. If we put an Exit in this room leading inside the train it would stay here when the train moved away (still leading into the train like a magic portal!). In the same way, if we put an Exit object inside the train, it would always point back to this room, @@ -58,7 +58,7 @@ regardless of where the Train has moved. Now, one *could* define custom Exit typ the train or change their destination in the right way - but this seems to be a pretty cumbersome solution. -What we will do instead is to create some new [commands](../Components/Commands): one for entering the train and +What we will do instead is to create some new [commands](../Components/Commands.md): one for entering the train and another for leaving it again. These will be stored *on the train object* and will thus be made available to whomever is either inside it or in the same room as the train. @@ -122,7 +122,7 @@ documentation. These commands are work in a pretty straightforward way: `CmdEnterTrain` moves the location of the player to inside the train and `CmdLeaveTrain` does the opposite: it moves the player back to the current location of the train (back outside to its current location). We stacked them in a -[cmdset](../Components/Command-Sets) `CmdSetTrain` so they can be used. +[cmdset](../Components/Command-Sets.md) `CmdSetTrain` so they can be used. To make the commands work we need to add this cmdset to our train typeclass: @@ -159,7 +159,7 @@ As seen above, when this hook is called on our train, our new cmdset will be loa If you have played around a bit, you've probably figured out that you can use `leave train` when outside the train and `enter train` when inside. This doesn't make any sense ... so let's go ahead and fix that. We need to tell Evennia that you can not enter the train when you're already inside -or leave the train when you're outside. One solution to this is [locks](../Components/Locks): we will lock down +or leave the train when you're outside. One solution to this is [locks](../Components/Locks.md): we will lock down the commands so that they can only be called if the player is at the correct location. Right now commands defaults to the lock `cmd:all()`. The `cmd` lock type in combination with the @@ -322,7 +322,7 @@ If we wanted full control of the train we could now just add a command to step i when desired. We want the train to move on its own though, without us having to force it by manually calling the `goto_next_room` method. -To do this we will create two [scripts](../Components/Scripts): one script that runs when the train has stopped at +To do this we will create two [scripts](../Components/Scripts.md): one script that runs when the train has stopped at a station and is responsible for starting the train again after a while. The other script will take care of the driving. @@ -416,7 +416,7 @@ enter/exit commands check so the train is not moving before allowing the caller * Have train conductor commands that can override the automatic start/stop. * Allow for in-between stops between the start- and end station * Have a rail road track instead of hard-coding the rooms in the train object. This could for -example be a custom [Exit](../Components/Objects#exits) only traversable by trains. The train will follow the +example be a custom [Exit](../Components/Objects.md#exits) only traversable by trains. The train will follow the track. Some track segments can split to lead to two different rooms and a player can switch the direction to which room it goes. * Create another kind of vehicle! \ No newline at end of file diff --git a/docs/source/Howto/Understanding-Color-Tags.md b/docs/source/Howto/Understanding-Color-Tags.md index 83570e8df4..08552d8ce7 100644 --- a/docs/source/Howto/Understanding-Color-Tags.md +++ b/docs/source/Howto/Understanding-Color-Tags.md @@ -2,10 +2,10 @@ This tutorial aims at dispelling confusions regarding the use of color tags within Evennia. -Correct understanding of this topic requires having read the [TextTags](../Concepts/TextTags) page and learned +Correct understanding of this topic requires having read the [TextTags](../Concepts/TextTags.md) page and learned Evennia's color tags. Here we'll explain by examples the reasons behind the unexpected (or apparently incoherent) behaviors of some color tags, as mentioned _en passant_ in the -[TextTags](../Concepts/TextTags) page. +[TextTags](../Concepts/TextTags.md) page. All you'll need for this tutorial is access to a running instance of Evennia via a color-enabled diff --git a/docs/source/Howto/Weather-Tutorial.md b/docs/source/Howto/Weather-Tutorial.md index fbf59d416d..e426e5dadc 100644 --- a/docs/source/Howto/Weather-Tutorial.md +++ b/docs/source/Howto/Weather-Tutorial.md @@ -12,7 +12,7 @@ individually track the time, they instead subscribe to be called by a global tic keeping. Not only does this centralize and organize much of the code in one place, it also has less computing overhead. -Evennia offers the [TickerHandler](../Components/TickerHandler) specifically for using the subscription model. We +Evennia offers the [TickerHandler](../Components/TickerHandler.md) specifically for using the subscription model. We will use it for our weather system. We will assume you know how to make your own Typeclasses. If not see one of the beginning tutorials. diff --git a/docs/source/Howto/Web-Character-Generation.md b/docs/source/Howto/Web-Character-Generation.md index 122d20965e..e1115cf323 100644 --- a/docs/source/Howto/Web-Character-Generation.md +++ b/docs/source/Howto/Web-Character-Generation.md @@ -24,7 +24,7 @@ needed. ## Pictures -Here are some screenshots of the simple app we will be making. +Here are some screenshots of the simple app we will be making. Index page, with no character application yet done: @@ -82,7 +82,7 @@ and *templates* (how the web page should be structured). Models are created in `mygame/web/chargen/models.py`. -A [Django database model](../Concepts/New-Models) is a Python class that describes the database storage of the +A [Django database model](../Concepts/New-Models.md) is a Python class that describes the database storage of the data you want to manage. Any data you choose to store is stored in the same database as the game and you have access to all the game's objects here. @@ -101,7 +101,7 @@ AccountID from the AccountDB object. > Note: In a full-fledged game, you’d likely want them to be able to select races, skills, attributes and so on. -Our `models.py` file should look something like this: +Our `models.py` file should look something like this: ```python # in mygame/web/chargen/models.py @@ -139,13 +139,13 @@ specific web page. We will use three views and three pages here: `http://yoursite.com/chargen`. * The detail display sheet (manages `detail.html`). A page that passively displays the stats of a given Character. -* Character creation sheet (manages `create.html`). This is the main form with fields to fill in. +* Character creation sheet (manages `create.html`). This is the main form with fields to fill in. ### *Index* view Let’s get started with the index first. -We’ll want characters to be able to see their created characters so let’s +We’ll want characters to be able to see their created characters so let’s ```python # file mygame/web/chargen.views.py @@ -182,7 +182,7 @@ def detail(request, app_id): background = app.background submitted = app.submitted p_id = request.user.id - context = {'name': name, 'background': background, + context = {'name': name, 'background': background, 'p_id': p_id, 'submitted': submitted} return render(request, 'chargen/detail.html', context) ``` @@ -206,7 +206,7 @@ class AppForm(forms.Form): background = forms.CharField(label='Background') ``` -Now we make use of this form in our view. +Now we make use of this form in our view. ```python # file mygame/web/chargen/views.py @@ -230,8 +230,8 @@ def creating(request): submitted = True if 'save' in request.POST: submitted = False - app = CharApp(char_name=name, background=background, - date_applied=applied_date, account_id=user.id, + app = CharApp(char_name=name, background=background, + date_applied=applied_date, account_id=user.id, submitted=submitted) app.save() if submitted: @@ -239,9 +239,9 @@ def creating(request): typeclass = settings.BASE_CHARACTER_TYPECLASS home = ObjectDB.objects.get_id(settings.GUEST_HOME) # turn the permissionhandler to a string - perms = str(user.permissions) + perms = str(user.permissions) # create the character - char = create.create_object(typeclass=typeclass, key=name, + char = create.create_object(typeclass=typeclass, key=name, home=home, permissions=perms) user.db._playable_characters.append(char) # add the right locks for the character so the account can @@ -266,9 +266,9 @@ create_object function to properly process the permissions. Most importantly, the following attributes must be set on the created character object: -* Evennia [permissions](../Components/Locks#permissions) (copied from the `AccountDB`). -* The right `puppet` [locks](../Components/Locks) so the Account can actually play as this Character later. -* The relevant Character [typeclass](../Components/Typeclasses) +* Evennia [permissions](../Components/Permissions.md) (copied from the `AccountDB`). +* The right `puppet` [locks](../Components/Locks.md) so the Account can actually play as this Character later. +* The relevant Character [typeclass](../Components/Typeclasses.md) * Character name (key) * The Character's home room location (`#2` by default) @@ -281,7 +281,7 @@ After all of this, our `views.py` file should look like something like this: ```python # file mygame/web/chargen/views.py - + from django.shortcuts import render from web.chargen.models import CharApp from web.chargen.forms import AppForm @@ -305,7 +305,7 @@ def detail(request, app_id): background = app.background submitted = app.submitted p_id = request.user.id - context = {'name': name, 'background': background, + context = {'name': name, 'background': background, 'p_id': p_id, 'submitted': submitted} return render(request, 'chargen/detail.html', context) @@ -320,8 +320,8 @@ def creating(request): submitted = True if 'save' in request.POST: submitted = False - app = CharApp(char_name=name, background=background, - date_applied=applied_date, account_id=user.id, + app = CharApp(char_name=name, background=background, + date_applied=applied_date, account_id=user.id, submitted=submitted) app.save() if submitted: @@ -329,9 +329,9 @@ def creating(request): typeclass = settings.BASE_CHARACTER_TYPECLASS home = ObjectDB.objects.get_id(settings.GUEST_HOME) # turn the permissionhandler to a string - perms = str(user.permissions) + perms = str(user.permissions) # create the character - char = create.create_object(typeclass=typeclass, key=name, + char = create.create_object(typeclass=typeclass, key=name, home=home, permissions=perms) user.db._playable_characters.append(char) # add the right locks for the character so the account can @@ -507,7 +507,7 @@ up on documentation elsewhere on the web for GET vs. POST. {% endblock %} ``` -### Templates - Checkpoint: +### Templates - Checkpoint: * Create a `index.html`, `detail.html` and `create.html` template in your `mygame/web/chargen/templates/chargen` directory diff --git a/docs/source/Howto/Web-Character-View-Tutorial.md b/docs/source/Howto/Web-Character-View-Tutorial.md index df4a2dd21f..70220e3b21 100644 --- a/docs/source/Howto/Web-Character-View-Tutorial.md +++ b/docs/source/Howto/Web-Character-View-Tutorial.md @@ -44,7 +44,7 @@ wasn't generated for you): # URL patterns for the character app from django.conf.urls import url -from web.character.views import sheet +from web.character.views import sheet urlpatterns = [ url(r'^sheet/(?P\d+)/$', sheet, name="sheet") @@ -222,8 +222,8 @@ As an optional final step, you can also change your character typeclass to have ``` Doing so will give you a 'view on site' button in the top right of the Django Admin Objects changepage that links to your new character sheet, and allow you to get the link to a character's -page by using {{ object.get_absolute_url }} in any template where you have a given object. +page by using `{{ object.get_absolute_url }}` in any template where you have a given object. *Now that you've made a basic page and app with Django, you may want to read the full Django tutorial to get a better idea of what it can do. [You can find Django's tutorial -here](https://docs.djangoproject.com/en/1.8/intro/tutorial01/).* \ No newline at end of file +here](https://docs.djangoproject.com/en/1.8/intro/tutorial01/).* diff --git a/docs/source/Links.md b/docs/source/Links.md index 378cb6d82e..ed9cdb5714 100644 --- a/docs/source/Links.md +++ b/docs/source/Links.md @@ -2,7 +2,7 @@ *A list of resources that may be useful for Evennia users and developers.* -### Official Evennia links +## Official Evennia links - [evennia.com](https://www.evennia.com) - Main Evennia portal page. Links to all corners of Evennia. - [Evennia github page](https://github.com/evennia/evennia) - Download code and read documentation. @@ -21,7 +21,7 @@ offline in html, PDF or epub formats. - [Evennia on PyPi](https://pypi.python.org/pypi/Evennia-MUD-Server/) - [Evennia subreddit](https://www.reddit.com/r/Evennia/) (not much there yet though) -### Third-party Evennia utilities and resources +## Third-party Evennia utilities and resources *For publicly available games running on Evennia, add and find those in the [Evennia game index](http://games.evennia.com) instead!* @@ -29,7 +29,7 @@ index](http://games.evennia.com) instead!* - [Discord Evennia channel](https://discord.gg/NecFePw) - This is a fan-driven Discord channel with a bridge to the official Evennia IRC channel. ---- +--- - [Discord live blog](https://discordapp.com/channels/517176782357528616/517176782781415434) of the _Blackbirds_ Evennia game project. @@ -76,13 +76,13 @@ learning](http://news.mit.edu/2015/learning-language-playing-computer-games-0924 ([PDF](https://people.csail.mit.edu/karthikn/pdfs/mud-play15.pdf)) - MIT research paper using Evennia to train AIs. -### Other useful mud development resources +## Other useful mud development resources - [ROM area reader](https://github.com/ctoth/area_reader) - Parser for converting ROM area files to Python objects. - [Gossip MUD chat network](https://gossip.haus/) -### General MUD forums and discussions +## General MUD forums and discussions - [MUD Coder's Guild](https://mudcoders.com/) - A blog and [associated Slack channel](https://slack.mudcoders.com/) with discussions on MUD development. @@ -122,9 +122,9 @@ Contains a very useful list of things to think about when starting your new MUD. thought-provoking guidelines and things to think about when designing a virtual multiplayer world (Raph is known for *Ultima Online* among other things). -### Literature +## Literature -- Richard Bartle *Designing Virtual Worlds* +- Richard Bartle *Designing Virtual Worlds* ([amazon page](https://www.amazon.com/Designing-Virtual-Worlds-Richard-Bartle/dp/0131018167)) - Essential reading for the design of any persistent game world, written by the co-creator of the original game *MUD*. Published in 2003 but it's still as @@ -148,7 +148,7 @@ Contains a very useful list of things to think about when starting your new MUD. easy to follow also for a modern reader. Required reading if you think of implementing a sane game economic system. -### Frameworks +## Frameworks - [Django's homepage](https://www.djangoproject.com/) - [Documentation](https://docs.djangoproject.com/en) @@ -157,13 +157,13 @@ Contains a very useful list of things to think about when starting your new MUD. - [Documentation](https://twistedmatrix.com/documents/current/core/howto/index.html) - [Code](https://twistedmatrix.com/trac/browser) -### Tools +## Tools - [GIT](https://git-scm.com/) - [Documentation](https://git-scm.com/documentation) -- [Learn GIT in 15 minutes](https://try.github.io/levels/1/challenges/1) (interactive tutorial) - -### Python Info + - [Learn GIT in 15 minutes](https://try.github.io/levels/1/challenges/1) (interactive tutorial) + +## Python Info - [Python Website](https://www.python.org/) - [Documentation](https://www.python.org/doc/) diff --git a/docs/source/Setup/Choosing-An-SQL-Server.md b/docs/source/Setup/Choosing-An-SQL-Server.md index bbc8957789..0dd5fbb5ba 100644 --- a/docs/source/Setup/Choosing-An-SQL-Server.md +++ b/docs/source/Setup/Choosing-An-SQL-Server.md @@ -51,11 +51,11 @@ evennia database is `evennia dbshell`. Linux users should look for the `sqlite3` distro while Mac/Windows should get the [sqlite-tools package from this page](https://sqlite.org/download.html). -To inspect the default Evennia database (once it's been created), go to your game dir and do +To inspect the default Evennia database (once it's been created), go to your game dir and do ```bash sqlite3 server/evennia.db3 - # or + # or evennia dbshell ``` @@ -68,7 +68,7 @@ See [here](https://gist.github.com/vincent178/10889334) for a cheat-sheet of com 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. -### Install and initial setup of PostgreSQL +### Install and initial setup of PostgreSQL First, install the posgresql server. Version `9.6` is tested with Evennia. Packages are readily available for all distributions. You need to also get the `psql` client (this is called `postgresql- @@ -85,16 +85,16 @@ Next, start the postgres client: psql -U postgres --password ``` -```warning:: +```{warning} With the `--password` argument, Postgres should prompt you for a password. If it won't, replace that with `-p yourpassword` instead. Do not use the `-p` argument unless you have to since the resulting command, and your password, will be logged in the shell history. ``` -This will open a console to the postgres service using the psql client. +This will open a console to the postgres service using the psql client. -On the psql command line: +On the psql command line: ```sql CREATE USER evennia WITH PASSWORD 'somepassword'; @@ -107,7 +107,7 @@ ALTER ROLE evennia SET default_transaction_isolation TO 'read committed'; ALTER ROLE evennia SET timezone TO 'UTC'; GRANT ALL PRIVILEGES ON DATABASE evennia TO evennia; --- Other useful commands: +-- Other useful commands: -- \l (list all databases and permissions) -- \q (exit) @@ -123,7 +123,7 @@ again to recreate the database and grant privileges. ### Evennia PostgreSQL configuration -Edit `mygame/server/conf/secret_settings.py and add the following section: +Edit `mygame/server/conf/secret_settings.py and add the following section: ```python # @@ -156,7 +156,7 @@ database. ### Advanced Postgresql Usage (Remote Server) -```warning:: +```{warning} The example below is for a server within a private network that is not open to the Internet. Be sure to understand the details before making any changes to @@ -197,7 +197,7 @@ listen_address = 'localhost' # What IP address(es) to listen on; # defaults to 'localhost'; use '*' for all ``` -```warning:: +```{warning} Misconfiguring the wrong cluster may cause problems with existing clusters. ``` @@ -207,7 +207,7 @@ Also, note the line with `port =` and keep the port number in mind. Set `listen_addresses` to `'*'`. This permits postgresql to accept connections on any interface. -```warning:: +```{warning} Setting `listen_addresses` to `'*'` opens a port on all interfaces. If your server has access to the Internet, ensure your firewall is configured appropriately to limit access to this port as necessary. (You may also list @@ -226,7 +226,7 @@ Add a line with: host all all 0.0.0.0/0 md5 ``` -```warning:: +```{warning} This permits incoming connections from *all* IPs. See the PosgreSQL documentation on how to limit this. ``` @@ -282,7 +282,7 @@ GRANT ALL PRIVILEGES ON evennia.* TO 'evennia'@'localhost'; FLUSH PRIVILEGES; -- use 'exit' to quit client ``` -[Here](https://gist.github.com/hofmannsven/9164408) is a mysql command cheat sheet. +[Here](https://gist.github.com/hofmannsven/9164408) is a mysql command cheat sheet. Above we created a new local user and database (we called both 'evennia' here, you can name them what you prefer). We set the character set to `utf8` to avoid an issue with prefix character length @@ -313,9 +313,9 @@ your settings as below. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'evennia', - 'USER': 'evennia', - 'PASSWORD': 'somepassword', + 'NAME': 'evennia', + 'USER': 'evennia', + 'PASSWORD': 'somepassword', 'HOST': 'localhost', # or an IP Address that your DB is hosted on 'PORT': '', # use default port } diff --git a/docs/source/Setup/Client-Support-Grid.md b/docs/source/Setup/Client-Support-Grid.md index a4dbfb5d50..3389118e5c 100644 --- a/docs/source/Setup/Client-Support-Grid.md +++ b/docs/source/Setup/Client-Support-Grid.md @@ -1,96 +1,73 @@ # Client Support Grid This grid tries to gather info about different MU clients when used with Evennia. -If you want to report a problem, update an entry or add a client, make a +If you want to report a problem, update an entry or add a client, make a new [documentation issue](github:issue) for it. Everyone's encouraged to report their findings. -##### Legend: +## Client Grid + +Legend: - **Name**: The name of the client. Also note if it's OS-specific. - **Version**: Which version or range of client versions were tested. - **Comments**: Any quirks on using this client with Evennia should be added here. -## Client Grid -```eval_rst +| Name | Version tested | Comments | +| --- | --- | --- | +| [Evennia Webclient][1] | 1.0+ | Evennia-specific | +| [tintin++][2] | 2.0+ | No MXP support | +| [tinyfugue][3] | 5.0+ | No UTF-8 support | +| [MUSHclient][4] (Win) | 4.94 | NAWS reports full text area | +| [Zmud][5] (Win) | 7.21 | *UNTESTED* | +| [Cmud][6] (Win) | v3 | *UNTESTED* | +| [Potato][7]_ | 2.0.0b16 | No MXP, MCCP support. Win 32bit does not understand | +| | | "localhost", must use `127.0.0.1`. | +| [Mudlet][8] | 3.4+ | No known issues. Some older versions showed <> as html | +| | | under MXP. | +| [SimpleMU][9] (Win) | full | Discontinued. NAWS reports pixel size. | +| [Atlantis][10] (Mac) | 0.9.9.4 | No known issues. | +| [GMUD][11] | 0.0.1 | Can't handle any telnet handshakes. Not recommended. | +| [BeipMU][12] (Win) | 3.0.255 | No MXP support. Best to enable "MUD prompt handling", disable | +| | | "Handle HTML tags". | +| [MudRammer][13] (IOS) | 1.8.7 | Bad Telnet Protocol compliance: displays spurious characters. | +| [MUDMaster][14] | 1.3.1 | *UNTESTED* | +| [BlowTorch][15] (Andr) | 1.1.3 | Telnet NOP displays as spurious character. | +| [Mukluk][16] (Andr) | 2015.11.20| Telnet NOP displays as spurious character. Has UTF-8/Emoji | +| | | support. | +| [Gnome-MUD][17] (Unix) | 0.11.2 | Telnet handshake errors. First (only) attempt at logging in | +| | | fails. | +| [Spyrit][18] | 0.4 | No MXP, OOB support. | +| [JamochaMUD][19] | 5.2 | Does not support ANSI within MXP text. | +| [DuckClient][20] (Chrome) | 4.2 | No MXP support. Displays Telnet Go-Ahead and | +| | | WILL SUPPRESS-GO-AHEAD as ù character. Also seems to run | +| | | the `version` command on connection, which will not work in | +| | | `MULTISESSION_MODES` above 1. | +| [KildClient][21] | 2.11.1 | No known issues. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Name | Version | Comments | -+============================+===========+================================================================+ -| `Evennia Webclient`_ | 0.9 | Evennia-specific | -+----------------------------+-----------+----------------------------------------------------------------+ -| `tintin++`_ | 2.0+ | No MXP support | -+----------------------------+-----------+----------------------------------------------------------------+ -| tinyfugue_ | 5.0+ | No UTF-8 support | -+----------------------------+-----------+----------------------------------------------------------------+ -| MUSHclient_ (Win) | 4.94 | NAWS reports full text area | -+----------------------------+-----------+----------------------------------------------------------------+ -| Zmud_ (Win) | 7.21 | *UNTESTED* | -+----------------------------+-----------+----------------------------------------------------------------+ -| Cmud_ (Win) | v3 | *UNTESTED* | -+----------------------------+-----------+----------------------------------------------------------------+ -| Potato_ | 2.0.0b16 | No MXP, MCCP support. Win 32bit does not understand | -| | | "localhost", must use `127.0.0.1`. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Mudlet_ | 3.4+ | No known issues. Some older versions showed <> as html | -| | | under MXP. | -+----------------------------+-----------+----------------------------------------------------------------+ -| SimpleMU_ (Win) | full | Discontinued. NAWS reports pixel size. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Atlantis_ (Mac) | 0.9.9.4 | No known issues. | -+----------------------------+-----------+----------------------------------------------------------------+ -| GMUD_ | 0.0.1 | Can't handle any telnet handshakes. Not recommended. | -+----------------------------+-----------+----------------------------------------------------------------+ -| BeipMU_ (Win) | 3.0.255 | No MXP support. Best to enable "MUD prompt handling", disable | -| | | "Handle HTML tags". | -+----------------------------+-----------+----------------------------------------------------------------+ -| MudRammer_ (IOS) | 1.8.7 | Bad Telnet Protocol compliance: displays spurious characters. | -+----------------------------+-----------+----------------------------------------------------------------+ -| MUDMaster_ | 1.3.1 | *UNTESTED* | -+----------------------------+-----------+----------------------------------------------------------------+ -| BlowTorch_ (Andr) | 1.1.3 | Telnet NOP displays as spurious character. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Mukluk_ (Andr) | 2015.11.20| Telnet NOP displays as spurious character. Has UTF-8/Emoji | -| | | support. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Gnome-MUD_ (Unix) | 0.11.2 | Telnet handshake errors. First (only) attempt at logging in | -| | | fails. | -+----------------------------+-----------+----------------------------------------------------------------+ -| Spyrit_ | 0.4 | No MXP, OOB support. | -+----------------------------+-----------+----------------------------------------------------------------+ -| JamochaMUD_ | 5.2 | Does not support ANSI within MXP text. | -+----------------------------+-----------+----------------------------------------------------------------+ -| DuckClient_ (Chrome) | 4.2 | No MXP support. Displays Telnet Go-Ahead and | -| | | WILL SUPPRESS-GO-AHEAD as ù character. Also seems to run | -| | | the `version` command on connection, which will not work in | -| | | `MULTISESSION_MODES` above 1. | -+----------------------------+-----------+----------------------------------------------------------------+ -| KildClient_ | 2.11.1 | No known issues. | -+----------------------------+-----------+----------------------------------------------------------------+ -.. _Evennia Webclient: ../Components/Webclient.html -.. _tintin++: http://tintin.sourceforge.net/ -.. _tinyfugue: http://tinyfugue.sourceforge.net/ -.. _MUSHclient: https://mushclient.com/ -.. _Zmud: http://forums.zuggsoft.com/index.php?page=4&action=file&file_id=65 -.. _Cmud: http://forums.zuggsoft.com/index.php?page=4&action=category&cat_id=11 -.. _Potato: https://www.potatomushclient.com/ -.. _Mudlet: https://www.mudlet.org/ -.. _SimpleMU: https://archive.org/details/tucows_196173_SimpleMU_MU_Client -.. _Atlantis: https://www.riverdark.net/atlantis/ -.. _GMUD: https://sourceforge.net/projects/g-mud/ -.. _BeipMU: http://www.beipmu.com/ -.. _MudRammer: https://itunes.apple.com/us/app/mudrammer-a-modern-mud-client/id597157072 -.. _MUDMaster: https://itunes.apple.com/us/app/mudmaster/id341160033 -.. _BlowTorch: https://bt.happygoatstudios.com/ -.. _Mukluk: https://play.google.com/store/apps/details?id=com.crap.mukluk -.. _Gnome-MUD: https://github.com/GNOME/gnome-mud -.. _Spyrit: https://spyrit.ierne.eu.org/ -.. _JamochaMUD: https://jamochamud.org/ -.. _DuckClient: http://duckclient.com/ -.. _KildClient: https://www.kildclient.org/ +[1]: ../Components/Webclient +[2]: http://tintin.sourceforge.net/ +[3]: http://tinyfugue.sourceforge.net/ +[4]: https://mushclient.com/ +[5]: http://forums.zuggsoft.com/index.php?page=4&action=file&file_id=65 +[6]: http://forums.zuggsoft.com/index.php?page=4&action=category&cat_id=11 +[7]: https://www.potatomushclient.com/ +[8]: https://www.mudlet.org/ +[9]: https://archive.org/details/tucows_196173_SimpleMU_MU_Client +[10]: https://www.riverdark.net/atlantis/ +[11]: https://sourceforge.net/projects/g-mud/ +[12]: http://www.beipmu.com/ +[13]: https://itunes.apple.com/us/app/mudrammer-a-modern-mud-client/id597157072 +[14]: https://itunes.apple.com/us/app/mudmaster/id341160033 +[15]: https://bt.happygoatstudios.com/ +[16]: https://play.google.com/store/apps/details?id=com.crap.mukluk +[17]: https://github.com/GNOME/gnome-mud +[18]: https://spyrit.ierne.eu.org/ +[19]: https://jamochamud.org/ +[20]: http://duckclient.com/ +[21]: https://www.kildclient.org/ -``` ## Workarounds for client issues: ### Issue: Telnet NOP displays as spurious character. @@ -105,5 +82,3 @@ Workaround: * In-game: Use `@option NOPKEEPALIVE=off` for the session, or use the `/save` parameter to disable it for that Evennia account permanently. * Client-side: Set a gag-type trigger on the NOP character to make it invisible to the client. - - diff --git a/docs/source/Setup/Extended-Installation.md b/docs/source/Setup/Extended-Installation.md index 5a01e8d245..c7fabca9b4 100644 --- a/docs/source/Setup/Extended-Installation.md +++ b/docs/source/Setup/Extended-Installation.md @@ -7,15 +7,15 @@ This will help you download, install and start Evennia for the first time. > test out Evennia. Apart from downloading and updating you don't even need an > internet connection until you feel ready to share your game with the world. -- [Quick Start](Getting-Started#quick-start) -- [Requirements](Getting-Started#requirements) -- [Linux Install](Getting-Started#linux-install) -- [Mac Install](Getting-Started#mac-install) -- [Windows Install](Getting-Started#windows-install) -- [Running in Docker](./Running-Evennia-in-Docker) -- [Where to Go Next](Getting-Started#where-to-go-next) -- [Troubleshooting](Getting-Started#troubleshooting) -- [Glossary of terms](../Glossary) +- [Quick Start](#quick-start) +- [Requirements](#requirements) +- [Linux Install](#linux-install) +- [Mac Install](#mac-install) +- [Windows Install](#windows-install) +- [Running in Docker](./Running-Evennia-in-Docker.md) +- [Where to Go Next](#where-to-go-next) +- [Troubleshooting](#troubleshooting) +- [Glossary of terms](../Glossary.md) ## Quick Start @@ -37,7 +37,7 @@ Evennia should now be running and you can connect to it by pointing a web browse `http://localhost:4001` or a MUD telnet client to `localhost:4000` (use `127.0.0.1` if your OS does not recognize `localhost`). -We also release [Docker images](./Running-Evennia-in-Docker) +We also release [Docker images](./Running-Evennia-in-Docker.md) based on `master` and `develop` branches. ## Requirements @@ -68,10 +68,10 @@ Twisted packages ## Linux Install If you run into any issues during the installation and first start, please -check out [Linux Troubleshooting](./Getting-Started#linux-troubleshooting). +check out [Linux Troubleshooting](#linux-troubleshooting). For Debian-derived systems (like Ubuntu, Mint etc), start a terminal and -install the [dependencies](./Getting-Started#requirements): +install the [dependencies](#requirements): ``` sudo apt-get update @@ -104,7 +104,7 @@ contains the source code though, it is not *installed* yet. To isolate the Evennia install and its dependencies from the rest of the system, it is good Python practice to install into a _virtualenv_. If you are unsure about what a virtualenv is and why it's useful, see the [Glossary entry on -virtualenv](Glossary#virtualenv). +virtualenv](../Glossary.md#virtualenv). Run `python -V` to see which version of Python your system defaults to. @@ -142,8 +142,8 @@ folders) and run pip install -e evennia ``` -For more info about `pip`, see the [Glossary entry on pip](../Glossary#pip). If -install failed with any issues, see [Linux Troubleshooting](Getting-Started#linux-troubleshooting). +For more info about `pip`, see the [Glossary entry on pip](../Glossary.md#pip). If +install failed with any issues, see [Linux Troubleshooting](#linux-troubleshooting). Next we'll start our new game, here called "mygame". This will create yet another new folder where you will be creating your new game: @@ -160,8 +160,8 @@ Your final folder structure should look like this: mygame/ ``` -You can [configure Evennia](../Components/Server-Conf#settings-file) extensively, for example -to use a [different database](./Choosing-An-SQL-Server). For now we'll just stick +You can [configure Evennia](./Server-Conf.md#settings-file) extensively, for example +to use a [different database](./Choosing-An-SQL-Server.md). For now we'll just stick to the defaults though. ``` @@ -175,7 +175,7 @@ evennia start # (create a superuser when asked. Email is optional.) Your game should now be running! Open a web browser at `http://localhost:4001` or point a telnet client to `localhost:4000` and log in with the user you -created. Check out [where to go next](./Getting-Started#where-to-go-next). +created. Check out [where to go next](#where-to-go-next). ## Mac Install @@ -184,7 +184,7 @@ The Evennia server is a terminal program. Open the terminal e.g. from *Applications->Utilities->Terminal*. [Here is an introduction to the Mac terminal](https://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line) if you are unsure how it works. If you run into any issues during the -installation, please check out [Mac Troubleshooting](./Getting-Started#mac-troubleshooting). +installation, please check out [Mac Troubleshooting](#mac-troubleshooting). * Python should already be installed but you must make sure it's a high enough version. ([This](https://docs.python-guide.org/en/latest/starting/install/osx/) discusses @@ -215,7 +215,7 @@ A new folder `evennia` will appear containing the Evennia library. This only contains the source code though, it is not *installed* yet. To isolate the Evennia install and its dependencies from the rest of the system, it is good Python practice to install into a _virtualenv_. If you are unsure about what a -virtualenv is and why it's useful, see the [Glossary entry on virtualenv](../Glossary#virtualenv). +virtualenv is and why it's useful, see the [Glossary entry on virtualenv](../Glossary.md#virtualenv). Run `python -V` to check which Python your system defaults to. @@ -253,8 +253,8 @@ pip install --upgrade setuptools # Ditto concerning Mac issues. pip install -e evennia ``` -For more info about `pip`, see the [Glossary entry on pip](../Glossary#pip). If -install failed with any issues, see [Mac Troubleshooting](Getting-Started#mac-troubleshooting). +For more info about `pip`, see the [Glossary entry on pip](../Glossary.md#pip). If +install failed with any issues, see [Mac Troubleshooting](#mac-troubleshooting). Next we'll start our new game. We'll call it "mygame" here. This creates a new folder where you will be creating your new game: @@ -272,8 +272,8 @@ Your final folder structure should look like this: mygame/ ``` -You can [configure Evennia](../Components/Server-Conf#settings-file) extensively, for example -to use a [different database](./Choosing-An-SQL-Server). We'll go with the +You can [configure Evennia](./Server-Conf.md#settings-file) extensively, for example +to use a [different database](./Choosing-An-SQL-Server.md). We'll go with the defaults here. ``` @@ -287,13 +287,13 @@ evennia start # (create a superuser when asked. Email is optional.) Your game should now be running! Open a web browser at `http://localhost:4001` or point a telnet client to `localhost:4000` and log in with the user you -created. Check out [where to go next](./Getting-Started#where-to-go-next). +created. Check out [where to go next](#where-to-go-next). ## Windows Install If you run into any issues during the installation, please check out -[Windows Troubleshooting](./Getting-Started#windows-troubleshooting). +[Windows Troubleshooting](#windows-troubleshooting). > If you are running Windows10, consider using the Windows Subsystem for Linux > ([WSL](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux)) instead. @@ -348,7 +348,7 @@ A new folder `evennia` will appear containing the Evennia library. This only contains the source code though, it is not *installed* yet. To isolate the Evennia install and its dependencies from the rest of the system, it is good Python practice to install into a _virtualenv_. If you are unsure about what a -virtualenv is and why it's useful, see the [Glossary entry on virtualenv](../Glossary#virtualenv). +virtualenv is and why it's useful, see the [Glossary entry on virtualenv](../Glossary.md#virtualenv). In your console, try `python -V` to see which version of Python your system defaults to. @@ -393,8 +393,8 @@ folders when you use the `dir` command) and run ``` pip install -e evennia ``` -For more info about `pip`, see the [Glossary entry on pip](../Glossary#pip). If -the install failed with any issues, see [Windows Troubleshooting](Getting-Started#windows- +For more info about `pip`, see the [Glossary entry on pip](../Glossary.md#pip). If +the install failed with any issues, see [Windows Troubleshooting](#windows- troubleshooting). Next we'll start our new game, we'll call it "mygame" here. This creates a new folder where you will be @@ -413,8 +413,8 @@ path\to\muddev mygame\ ``` -You can [configure Evennia](../Components/Server-Conf#settings-file) extensively, for example -to use a [different database](./Choosing-An-SQL-Server). We'll go with the +You can [configure Evennia](./Server-Conf.md#settings-file) extensively, for example +to use a [different database](./Choosing-An-SQL-Server.md). We'll go with the defaults here. ``` @@ -428,7 +428,7 @@ evennia start # (create a superuser when asked. Email is optional.) Your game should now be running! Open a web browser at `http://localhost:4001` or point a telnet client to `localhost:4000` and log in with the user you -created. Check out [where to go next](./Getting-Started#where-to-go-next). +created. Check out [where to go next](#where-to-go-next). ## Non-interactive setup @@ -453,7 +453,7 @@ logged in, stand in the `Limbo` room and run @batchcommand tutorial_world.build -to build [Evennia's tutorial world](../Howto/Starting/Part1/Tutorial-World-Introduction) - it's a small solo quest to +to build [Evennia's tutorial world](../Howto/Starting/Part1/Tutorial-World-Introduction.md) - it's a small solo quest to explore. Only run the instructed `@batchcommand` once. You'll get a lot of text scrolling by as the tutorial is built. Once done, the `tutorial` exit will have appeared out of Limbo - just write `tutorial` to enter it. @@ -461,10 +461,10 @@ tutorial is built. Once done, the `tutorial` exit will have appeared out of Limb Once you get back to `Limbo` from the tutorial (if you get stuck in the tutorial quest you can do `@tel #2` to jump to Limbo), a good idea is to learn how to [start, stop and reload](Start-Stop- Reload) the Evennia server. You may also want to familiarize yourself with some -[commonly used terms in our Glossary](../Glossary). After that, why not experiment with -[creating some new items and build some new rooms](../Howto/Starting/Part1/Building-Quickstart) out from Limbo. +[commonly used terms in our Glossary](../Glossary.md). After that, why not experiment with +[creating some new items and build some new rooms](../Howto/Starting/Part1/Building-Quickstart.md) out from Limbo. -From here on, you could move on to do one of our [introductory tutorials](../Howto/Howto-Overview) or simply dive +From here on, you could move on to do one of our [introductory tutorials](../Howto/Howto-Overview.md) or simply dive headlong into Evennia's comprehensive [manual](https://github.com/evennia/evennia/wiki). While Evennia has no major game systems out of the box, we do supply a range of optional *contribs* that you can use or borrow from. They range from dice rolling and alternative color schemes to barter and @@ -478,7 +478,7 @@ forums](https://groups.google.com/forum/#%21forum/evennia). You can also join th Server](https://discord.gg/NecFePw). Finally, if you are itching to help out or support Evennia (awesome!) have an -issue to report or a feature to request, [see here](../How-To-Get-And-Give-Help). +issue to report or a feature to request, [see here](../How-To-Get-And-Give-Help.md). Enjoy your stay! diff --git a/docs/source/Setup/HAProxy-Config.md b/docs/source/Setup/HAProxy-Config.md index 8e6f11e1d5..48c466ad8b 100644 --- a/docs/source/Setup/HAProxy-Config.md +++ b/docs/source/Setup/HAProxy-Config.md @@ -1,4 +1,4 @@ -## Making Evennia, HTTPS and WSS (Secure Websockets) play nicely together +# Making Evennia, HTTPS and WSS (Secure Websockets) play nicely together A modern public-facing website should these days be served via encrypted connections. So `https:` rather than `http:` for the website and diff --git a/docs/source/Setup/How-to-connect-Evennia-to-Twitter.md b/docs/source/Setup/How-to-connect-Evennia-to-Twitter.md index d08c18b267..2c278a8068 100644 --- a/docs/source/Setup/How-to-connect-Evennia-to-Twitter.md +++ b/docs/source/Setup/How-to-connect-Evennia-to-Twitter.md @@ -29,8 +29,8 @@ pip install python-twitter ## A basic tweet command Evennia doesn't have a `tweet` command out of the box so you need to write your own little -[Command](../Components/Commands) in order to tweet. If you are unsure about how commands work and how to add -them, it can be an idea to go through the [Adding a Command Tutorial](../Howto/Starting/Part1/Adding-Commands) +[Command](../Components/Commands.md) in order to tweet. If you are unsure about how commands work and how to add +them, it can be an idea to go through the [Adding a Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) before continuing. You can create the command in a separate command module (something like `mygame/commands/tweet.py`) @@ -89,7 +89,7 @@ Be sure to substitute your own actual API/Access keys and secrets in the appropr We default to limiting tweet access to players with `Developers`-level access *or* to those players that have the permission "tweet" (allow individual characters to tweet with `@perm/player playername -= tweet`). You may change the [lock](../Components/Locks) as you feel is appropriate. Change the overall += tweet`). You may change the [lock](../Components/Locks.md) as you feel is appropriate. Change the overall permission to `Players` if you want everyone to be able to tweet. Now add this command to your default command set (e.g in `mygame/commands/defalt_cmdsets.py`") and @@ -106,5 +106,5 @@ This shows only a basic tweet setup, other things to do could be: * Echo your tweets to an in-game channel Rather than using an explicit command you can set up a Script to send automatic tweets, for example -to post updated game stats. See the [Tweeting Game Stats tutorial](../Howto/Tutorial-Tweeting-Game-Stats) for +to post updated game stats. See the [Tweeting Game Stats tutorial](../Howto/Tutorial-Tweeting-Game-Stats.md) for help. \ No newline at end of file diff --git a/docs/source/Setup/IRC.md b/docs/source/Setup/IRC.md index a3d2a23e07..b82939a34d 100644 --- a/docs/source/Setup/IRC.md +++ b/docs/source/Setup/IRC.md @@ -7,7 +7,7 @@ Discord](https://discord.gg/NecFePw), which is mirrored to IRC._ [IRC (Internet Relay Chat)](https://en.wikipedia.org/wiki/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](../Components/Communications) to an IRC channel you can communicate also with people not on +Evennia's [Channels](../Components/Communications.md) to an IRC channel you can communicate also with people not on an mud themselves. You can also use IRC if you are only running your Evennia MUD locally on your computer (your game doesn't need to be open to the public)! All you need is an internet connection. For IRC operation you also need [twisted.words](https://twistedmatrix.com/trac/wiki/TwistedWords). diff --git a/docs/source/Setup/Installing-on-Android.md b/docs/source/Setup/Installing-on-Android.md index b686110e64..f7ba8b04ea 100644 --- a/docs/source/Setup/Installing-on-Android.md +++ b/docs/source/Setup/Installing-on-Android.md @@ -75,20 +75,20 @@ export CFLAGS="-I/data/data/com.termux/files/usr/include/" Install the latest Evennia in a way that lets you edit the source ``` -(evenv) $ pip install --upgrade -e 'git+https://github.com/evennia/evennia#egg=evennia' +(evenv) $ pip install --upgrade -e 'git+https://github.com/evennia/evennia#egg=evennia' ``` This step will possibly take quite a while - we are downloading Evennia and are then installing it, building all of the requirements for Evennia to run. If you run into trouble on this step, please -see [Troubleshooting](./Installing-on-Android#troubleshooting). +see [Troubleshooting](./Installing-on-Android.md#troubleshooting). You can go to the dir where Evennia is installed with `cd $VIRTUAL_ENV/src/evennia`. `git grep (something)` can be handy, as can `git diff` ### Final steps -At this point, Evennia is installed on your phone! You can now continue with the original -[Setup Quickstart](./Setup-Quickstart) instruction, we repeat them here for clarity. +At this point, Evennia is installed on your phone! You can now continue with the original +[Setup Quickstart](./Setup-Quickstart.md) instruction, we repeat them here for clarity. To start a new game: @@ -120,7 +120,7 @@ $ cd ~ && source evenv/bin/activate (evenv) $ evennia start ``` -You may wish to look at the [Linux Instructions](./Getting-Started#linux-install) for more. +You may wish to look at the [Linux Instructions](./Extended-Installation.md#linux-install) for more. ## Caveats @@ -140,4 +140,4 @@ Some steps to try anyway: * Make sure you're in the right directory. `cd ~/mygame * Make sure you've sourced your virtualenv. type `cd && source evenv/bin/activate` * See if a shell will start: `cd ~/mygame ; evennia shell` -* Look at the log files in ~/mygame/server/logs/ \ No newline at end of file +* Look at the log files in ~/mygame/server/logs/ diff --git a/docs/source/Setup/Online-Setup.md b/docs/source/Setup/Online-Setup.md index e9aaabe881..7d3951743a 100644 --- a/docs/source/Setup/Online-Setup.md +++ b/docs/source/Setup/Online-Setup.md @@ -66,7 +66,7 @@ web services you are running through this router though. You can connect Evennia to the Internet without any changes to your settings. The default settings are easy to use but are not necessarily the safest. You can customize your online presence in your -[settings file](../Components/Server-Conf#settings-file). To have Evennia recognize changed port settings you have +[settings file](./Server-Conf.md#settings-file). To have Evennia recognize changed port settings you have to do a full `evennia reboot` to also restart the Portal and not just the Server component. Below is an example of a simple set of settings, mostly using the defaults. Evennia will require @@ -179,7 +179,7 @@ AMP_PORT = 4006 ``` The `AMP_PORT` is required to work, since this is the internal port linking Evennia's -[Server and Portal](../Components/Portal-And-Server) components together. The other ports are encrypted ports that may be +[Server and Portal](../Components/Portal-And-Server.md) components together. The other ports are encrypted ports that may be useful for custom protocols but are otherwise not used. ### Lockdown mode @@ -202,7 +202,7 @@ To register, stand in your game dir, run evennia connections -and follow the instructions. See the [Game index page](./Evennia-Game-Index) for more details. +and follow the instructions. See the [Game index page](./Evennia-Game-Index.md) for more details. ## SSL @@ -249,8 +249,8 @@ also be based on your hosting choice. In a controlled/cPanel environment, you wi to use DNS verification. ## Relevant SSL Proxy Setup Information -- [Apache webserver configuration](./Apache-Config) (optional) -- [HAProxy Config](./HAProxy-Config) +- [Apache webserver configuration](./Apache-Config.md) (optional) +- [HAProxy Config](./HAProxy-Config.md) ## Hosting locally or remotely? @@ -283,7 +283,7 @@ main internet connection terminated as a consequence. #### Setting up your own machine as a server -[The first section](./Online-Setup#connecting-from-the-outside) of this page describes how to do this +[The first section](./Online-Setup.md#connecting-from-the-outside) of this page describes how to do this and allow users to connect to the IP address of your machine/router. A complication with using a specific IP address like this is that your home IP might not remain the @@ -344,7 +344,7 @@ game stays online. Many services guarantee a certain level of up-time and also d for you. Make sure to check, some offer lower rates in exchange for you yourself being fully responsible for your data/backups. - Usually offers a fixed domain name, so no need to mess with IP addresses. -- May have the ability to easily deploy [docker](./Running-Evennia-in-Docker) versions of evennia +- May have the ability to easily deploy [docker](./Running-Evennia-in-Docker.md) versions of evennia and/or your game. **Disadvantages** @@ -362,7 +362,7 @@ Docker) to deploy your game to the remote server; it will likely ease installati Docker images may be a little confusing if you are completely new to them though. If not using docker, and assuming you know how to connect to your account over ssh/PuTTy, you should -be able to follow the [Setup Quickstart](./Setup-Quickstart) instructions normally. You only need Python +be able to follow the [Setup Quickstart](./Setup-Quickstart.md) instructions normally. You only need Python and GIT pre-installed; these should both be available on any servers (if not you should be able to easily ask for them to be installed). On a VPS or Cloud service you can install them yourself as needed. @@ -382,40 +382,31 @@ region. You may find useful offers for "low cost" VPS hosting on [Low End Box][7 There are all sorts of services available. Below are some international suggestions offered by Evennia users: -Hosting name | Type | Lowest price | Comments -:--------------:|:-------:--------------- -[silvren.com][1] | Shell account | Free for MU* | Private hobby provider so don't assume backups -or expect immediate support. To ask for an account, connect with a MUD client to iweb.localecho.net, -port 4201 and ask for "Jarin". -[Digital Ocean][2] | VPS | $5/month | You can get a $50 credit if you use the referral link -https://m.do.co/c/8f64fec2670c - if you do, once you've had it long enough to have paid $25 we will -get that as a referral bonus to help Evennia development. -[Amazon Web services][3] | Cloud | ~$5/month / on-demand | Free Tier first 12 months. Regions -available around the globe. -[Amazon Lightsail][9] | Cloud | $5/month | Free first month. AWS's new "fixed cost" offering. -[Genesis MUD hosting][4] | Shell account | $8/month | Dedicated MUD host with very limited memory -offerings. As for 2017, runs a 13 years old Python version (2.4) so you'd need to either convince -them to update or compile yourself. Note that Evennia needs *at least* the "Deluxe" package (50MB -RAM) and probably *a lot* higher for a production game. This host is *not* recommended for Evennia. -[Host1Plus][5] | VPS & Cloud | $4/month | $4-$8/month depending on length of sign-up period. -[Scaleway][6] | Cloud | €3/month / on-demand | EU based (Paris, Amsterdam). Smallest option -provides 2GB RAM. -[Prgmr][10] | VPS | $5/month | 1 month free with a year prepay. You likely want some experience with -servers with this option as they don't have a lot of support. -[Linode][11] | Cloud | $5/month / on-demand | Multiple regions. Smallest option provides 1GB RAM -*Please help us expand this list.* +| Hosting name | Type | Lowest price | Comments | +|---|---| ---| --- | +| [silvren.com][1] | Shell account | Free for MU* | Private hobby provider so don't assume backups or expect immediate support. To ask for an account,connect with a MUD client to iweb.localecho.net, port 4201 and ask for "Jarin". | +| [Digital Ocean][2] | VPS | $5/month | You can get a $50 credit if you use the referral link https://m.do.co/c/8f64fec2670c - if you do, once you've had it long enough to have paid $25 we will get that as a referral bonus to help Evennia development.| +| [Amazon Web services][3] | Cloud | ~$5/month / on-demand | Free Tier first 12 months. Regions available around the globe.| +| [Amazon Lightsail][9] | Cloud | $5/month | Free first month. AWS's new "fixed cost" offering.| +| [Genesis MUD hosting][4] | Shell account | $8/month | Dedicated MUD host with very limited memory offerings. As for 2017, runs a 13 years old Python version (2.4) so you'd need to either convince them to update or compile yourself. Note that Evennia needs *at least* the "Deluxe" package (50MB RAM) and probably *a lot* higher for a production game. This host is *not* recommended for Evennia.| +| [Host1Plus][5] | VPS & Cloud | $4/month | $4-$8/month depending on length of sign-up period. +| [Scaleway][6] | Cloud | €3/month / on-demand | EU based (Paris, Amsterdam). Smallest option provides 2GB RAM. | +| [Prgmr][10] | VPS | $5/month | 1 month free with a year prepay. You likely want some experience with servers with this option as they don't have a lot of support.| +| [Linode][11] | Cloud | $5/month / on-demand | Multiple regions. Smallest option provides 1GB RAM| + +*Please help us expand this list.* [1]: https://silvren.com -[2](https://www.digitalocean.com/pricing) -[3](https://aws.amazon.com/pricing/) -[4](https://www.genesismuds.com/) -[5](https://www.host1plus.com/) -[6](https://www.scaleway.com/) -[7](https://lowendbox.com/) -[8](https://www.lowendtalk.com) -[9](https://amazonlightsail.com) -[10](https://prgmr.com/) -[11](https://www.linode.com/) +[2]: https://www.digitalocean.com/pricing +[3]: https://aws.amazon.com/pricing/ +[4]: https://www.genesismuds.com/ +[5]: https://www.host1plus.com/ +[6]: https://www.scaleway.com/ +[7]: https://lowendbox.com/ +[8]: https://www.lowendtalk.com +[9]: https://amazonlightsail.com +[10]: https://prgmr.com/ +[11]: https://www.linode.com/ ## Cloud9 diff --git a/docs/source/Setup/RSS.md b/docs/source/Setup/RSS.md index 8857d7db3f..08b2f1cab2 100644 --- a/docs/source/Setup/RSS.md +++ b/docs/source/Setup/RSS.md @@ -44,4 +44,4 @@ switch: @rss2chan/delete rss = https://github.com/evennia/evennia/commits/master.atom You can connect any number of RSS feeds to a channel this way. You could also connect them to the -same channels as [IRC](./IRC) to have the feed echo to external chat channels as well. +same channels as [IRC](./IRC.md) to have the feed echo to external chat channels as well. diff --git a/docs/source/Setup/Running-Evennia-in-Docker.md b/docs/source/Setup/Running-Evennia-in-Docker.md index 816e4e737c..31d45cb0e8 100644 --- a/docs/source/Setup/Running-Evennia-in-Docker.md +++ b/docs/source/Setup/Running-Evennia-in-Docker.md @@ -34,7 +34,7 @@ evennia|docker /usr/src/game $ This is a normal shell prompt. We are in the `/usr/src/game` location inside the docker container. If you had anything in the folder you started from, you should see it here (with `ls`) since we mounted the current directory to `usr/src/game` (with `-v` above). You have the `evennia` command -available and can now proceed to create a new game as per the [Setup Quickstart](./Setup-Quickstart) +available and can now proceed to create a new game as per the [Setup Quickstart](./Setup-Quickstart.md) instructions (you can skip the virtualenv and install 'globally' in the container though). You can run Evennia from inside this container if you want to, it's like you are root in a little diff --git a/docs/source/Setup/Security.md b/docs/source/Setup/Security.md index 67ceef8b5f..10236956d6 100644 --- a/docs/source/Setup/Security.md +++ b/docs/source/Setup/Security.md @@ -16,7 +16,7 @@ fact. As a developer about to expose a web application to the threat landscape of the modern internet, here are a few tips to consider to increase the security of your Evennia install. -### Know your logs +## Know your logs In case of emergency, check your logs! By default they are located in the `server/logs/` folder. Here are some of the more important ones and why you should care: @@ -32,7 +32,7 @@ objects, and more. If your game fails to start or crashes and you can't tell why place you should look for answers. Security-related events are prefixed with an `[SS]` so when there's a problem you might want to pay special attention to those. -### Disable development/debugging options +## Disable development/debugging options There are a few Evennia/Django options that are set when you first create your game to make it more obvious to you where problems arise. These options should be disabled before you push your game into production-- leaving them on can expose variables or code someone with malicious intent can easily @@ -49,7 +49,7 @@ as-is. # Note the leading period-- it is not a typo! ALLOWED_HOSTS = ['.example.com'] -### Handle user-uploaded images with care +## Handle user-uploaded images with care If you decide to allow users to upload their own images to be served from your site, special care must be taken. Django will read the file headers to confirm it's an image (as opposed to a document or zip archive), but [code can be injected into an image @@ -70,7 +70,7 @@ resources in bulk). bothered with additional infrastructure, then simply reprocess user images upon receipt using an image library. Convert them to a different format, for example. *Destroy the originals!* -### Disable the web interface +## Disable the web interface The web interface allows visitors to see an informational page as well as log into a browser-based telnet client with which to access Evennia. It also provides authentication endpoints against which an attacker can attempt to validate stolen lists of credentials to see which ones might be shared by @@ -85,7 +85,7 @@ In `server/conf/settings.py`: # Disable the website altogether WEBSERVER_ENABLED = False -### Change your ssh port +## Change your ssh port Automated attacks will often target port 22 seeing as how it's the standard port for SSH traffic. Also, many public wifi hotspots block ssh traffic over port 22 so you might not be able to access your @@ -104,9 +104,9 @@ Save, close, then run the following command: sudo service ssh restart -### Set up a firewall +## Set up a firewall Ubuntu users can make use of the simple ufw utility. Anybody else can use iptables. - + # Install ufw (if not already) sudo apt-get install ufw @@ -130,8 +130,8 @@ Finally: Now the only ports open will be your administrative ssh port (whichever you chose), and Evennia on 4000-4001. -### Use an external webserver -Though not officially supported, there are some benefits to [deploying a webserver](./Apache-Config) +## Use an external webserver +Though not officially supported, there are some benefits to [deploying a webserver](./Apache-Config.md) to handle/proxy traffic to your Evennia instance. For example, Evennia's game engine and webservice are tightly integrated. If you bring your game @@ -149,4 +149,4 @@ Many of the popular webservers also let you plug in additional modules (like (and block!) malicious users or requests before they even touch your game or site. There are also automated solutions for installing and configuring TLS (via [Certbot/Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt)) to secure your website against hotspot and -ISP snooping. \ No newline at end of file +ISP snooping. diff --git a/docs/source/Components/Server-Conf.md b/docs/source/Setup/Server-Conf.md similarity index 95% rename from docs/source/Components/Server-Conf.md rename to docs/source/Setup/Server-Conf.md index f18f118b87..88b717eab4 100644 --- a/docs/source/Components/Server-Conf.md +++ b/docs/source/Setup/Server-Conf.md @@ -8,7 +8,7 @@ ways to customize the server and expand it with your own plugins. The "Settings" file referenced throughout the documentation is the file `mygame/server/conf/settings.py`. This is automatically created on the first run of `evennia --init` -(see the [Setup Quickstart](../Setup/Setup-Quickstart) page). +(see the [Setup Quickstart](./Setup-Quickstart.md) page). Your new `settings.py` is relatively bare out of the box. Evennia's core settings file is actually [evennia/settings_default.py](https://github.com/evennia/evennia/blob/master/evennia/settings_default.py) @@ -66,15 +66,15 @@ 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 an Account first connects. If more than one string variable is present in the module a random one will be picked. -- `inlinefuncs.py` - this is where you can define custom [Inline functions](../Concepts/TextTags#inlinefuncs). -- `inputfuncs.py` - this is where you define custom [Input functions](./Inputfuncs) to handle data +- `inlinefuncs.py` - this is where you can define custom [FuncParser functions](../Components/FuncParser.md). +- `inputfuncs.py` - this is where you define custom [Input functions](../Components/Inputfuncs.md) to handle data from the client. - `lockfuncs.py` - this is one of many possible modules to hold your own "safe" *lock functions* to -make available to Evennia's [Locks](./Locks). +make available to Evennia's [Locks](../Components/Locks.md). - `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 accounts and online status. -- `oobfuncs.py` - in here you can define custom [OOB functions](../Concepts/OOB). +- `oobfuncs.py` - in here you can define custom [OOB functions](../Concepts/OOB.md). - `portal_services_plugin.py` - this allows for adding your own custom services/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 diff --git a/docs/source/Setup/Setup-Overview.md b/docs/source/Setup/Setup-Overview.md index 3e00833974..6c49ae743d 100644 --- a/docs/source/Setup/Setup-Overview.md +++ b/docs/source/Setup/Setup-Overview.md @@ -4,32 +4,32 @@ This documentation covers how to setup and maintain the server, from first insta ## Installation & running -- [Installation & Setup quick-start](./Setup-Quickstart) - one page to quickly get you going -- [Extended Install instructions](./Extended-Installation) - if you have trouble or want to contribute to Evennia itself -- [Running through Docker](./Running-Evennia-in-Docker) - alternative install method, useful for quick deployment on remote servers -- [Installing Evennia on Android](./Installing-on-Android) - for those craving a mobile life -- [Controlling the server](./Start-Stop-Reload) - an extended view on how to start/stop/update the server +- [Installation & Setup quick-start](./Setup-Quickstart.md) - one page to quickly get you going +- [Extended Install instructions](./Extended-Installation.md) - if you have trouble or want to contribute to Evennia itself +- [Running through Docker](./Running-Evennia-in-Docker.md) - alternative install method, useful for quick deployment on remote servers +- [Installing Evennia on Android](./Installing-on-Android.md) - for those craving a mobile life +- [Controlling the server](./Start-Stop-Reload.md) - an extended view on how to start/stop/update the server ## Installing custom game dirs -- [Installing Arxcode](../Contribs/Arxcode-installing-help) - a custom gamedir based on the popular Evennia game [Arx](https://play.arxgame.org/) +- [Installing Arxcode](../Contribs/Arxcode-installing-help.md) - a custom gamedir based on the popular Evennia game [Arx](https://play.arxgame.org/) ## Configuring -- [The settings file](./Settings-File) - how and where to change the main settings of the server -- [Change database engine](./Choosing-An-SQL-Server) - if you want to use something other than SQLite3 -- [Evennia game index](./Evennia-Game-Index) - register your upcoming game with the index to start the hype going +- [The settings file](./Settings-File.md) - how and where to change the main settings of the server +- [Change database engine](./Choosing-An-SQL-Server.md) - if you want to use something other than SQLite3 +- [Evennia game index](./Evennia-Game-Index.md) - register your upcoming game with the index to start the hype going -- [Chat on IRC](./IRC) - how to link your game's channels to an external [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) channel -- [Chat on Grapevine](./Grapevine) - how to link your game's channels the [Grapevine](https://grapevine.haus/) mud network/chat -- [Messages to RSS](./RSS) - have your game notify people through RSS -- [Messages to Twitter](./How-to-connect-Evennia-to-Twitter) - have Evennia send messages to [Twitter](https://twitter.com/) (requires some coding) +- [Chat on IRC](./IRC.md) - how to link your game's channels to an external [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) channel +- [Chat on Grapevine](./Grapevine.md) - how to link your game's channels the [Grapevine](https://grapevine.haus/) mud network/chat +- [Messages to RSS](./RSS.md) - have your game notify people through RSS +- [Messages to Twitter](./How-to-connect-Evennia-to-Twitter.md) - have Evennia send messages to [Twitter](https://twitter.com/) (requires some coding) ## Going public -- [Notes about security](./Security) - some things to think about to stay safe(r) - - [Using HAProxy](./HAProxy-Config) - putting a proxy in front of the game server for security - - [Using Apache as a webserver](./Apache-Config) - use Apache instead of Evennia's webserver (limited support) -- [Taking your server online](./Online-Setup) - decide on where to host and configure your game for production -- [Client support grid](./Client-Support-Grid) - clients known to work (or not) with Evennia +- [Notes about security](./Security.md) - some things to think about to stay safe(r) + - [Using HAProxy](./HAProxy-Config.md) - putting a proxy in front of the game server for security + - [Using Apache as a webserver](./Apache-Config.md) - use Apache instead of Evennia's webserver (limited support) +- [Taking your server online](./Online-Setup.md) - decide on where to host and configure your game for production +- [Client support grid](./Client-Support-Grid.md) - clients known to work (or not) with Evennia diff --git a/docs/source/Setup/Setup-Quickstart.md b/docs/source/Setup/Setup-Quickstart.md index e3dea0103f..b64350b72b 100644 --- a/docs/source/Setup/Setup-Quickstart.md +++ b/docs/source/Setup/Setup-Quickstart.md @@ -7,11 +7,11 @@ in complete isolation if you want, without needing any access to the internet. ## Installation Evennia supports Python 3.7 to 3.9. As with most Python packages, using a -[virtualenv](../Glossary#virtualenv) is recommended in order to keep your +[virtualenv](../Glossary.md#virtualenv) is recommended in order to keep your installation independent from the system libraries. It's _not_ recommended to install Evennia as superuser. -```warning:: +```{warning} This is not yet available. Switch to the 0.9.5 version of these docs to install Evennia. ``` @@ -22,8 +22,8 @@ Make sure the `evennia` command works. Use `evennia -h` for usage help (or read If you are having trouble, want to install in some other way (like with Docker) or want to contribute to Evennia itself, check out the [Extended Installation -instructions](./Extended-Installation). It also has a [troubleshooting -section](./Extended-Installation#Troubleshooting) for different operating +instructions](./Extended-Installation.md). It also has a [troubleshooting +section](./Extended-Installation.md#troubleshooting) for different operating systems. @@ -96,4 +96,4 @@ Full stop of the server (will need to use `start` to activate it again): ## The Next step -Why not head into the [Starting Tutorial](../Howto/Starting/Part1/Starting-Part1) to learn how to start making your new game! +Why not head into the [Starting Tutorial](../Howto/Starting/Part1/Starting-Part1.md) to learn how to start making your new game! diff --git a/docs/source/Setup/Start-Stop-Reload.md b/docs/source/Setup/Start-Stop-Reload.md index a482b39ff6..32fc11189d 100644 --- a/docs/source/Setup/Start-Stop-Reload.md +++ b/docs/source/Setup/Start-Stop-Reload.md @@ -3,10 +3,10 @@ You control Evennia from your game folder (we refer to it as `mygame/` here), using the `evennia` program. If the `evennia` program is not available on the command line you must first install -Evennia as described in the [Setup Quickstart](./Setup-Quickstart) page. +Evennia as described in the [Setup Quickstart](./Setup-Quickstart.md) page. > Hint: If you ever try the `evennia` command and get an error complaining that the command is not -available, make sure your [virtualenv](../Glossary#virtualenv) is active. +available, make sure your [virtualenv](../Glossary.md#virtualenv) is active. Below are described the various management options. Run @@ -20,7 +20,7 @@ to give you a menu with options. ## Starting Evennia -Evennia consists of two components, the Evennia [Server and Portal](../Components/Portal-And-Server). Briefly, +Evennia consists of two components, the Evennia [Server and Portal](../Components/Portal-And-Server.md). Briefly, the *Server* is what is running the mud. It handles all game-specific things but doesn'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 @@ -67,7 +67,7 @@ reboots. Since they are connected to the *Portal*, their connections are not los Reloading is as close to a "warm reboot" you can get. It reinitializes all code of Evennia, but -doesn't kill "persistent" [Scripts](../Components/Scripts). It also calls `at_server_reload()` hooks on all +doesn't kill "persistent" [Scripts](../Components/Scripts.md). It also calls `at_server_reload()` hooks on all objects so you can save eventual temporary properties you want. diff --git a/docs/source/Unimplemented.md b/docs/source/Unimplemented.md index 99be5ebf38..db86cea677 100644 --- a/docs/source/Unimplemented.md +++ b/docs/source/Unimplemented.md @@ -2,4 +2,4 @@ _Sorry, but this page has not been written yet._ -Go back or return to the [front page](./index#Evennia-documentation). \ No newline at end of file +Go back or return to the [front page](./index.md). diff --git a/docs/source/_static/basic.css b/docs/source/_static/basic.css index d0fa172aba..463e739b7b 100644 --- a/docs/source/_static/basic.css +++ b/docs/source/_static/basic.css @@ -313,7 +313,7 @@ img.align-default, .figure.align-default { /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #787878; padding: 5px 7px 7px 15px; diff --git a/docs/source/_static/nature.css b/docs/source/_static/nature.css index f0cad24e91..f4e8cde0d3 100644 --- a/docs/source/_static/nature.css +++ b/docs/source/_static/nature.css @@ -220,6 +220,10 @@ div.admonition p.admonition-title + p { display: inline; } +p.admonition-title { + margin-right: 0.2em; +} + div.highlight { background-color: #f1f1ef; } @@ -228,6 +232,8 @@ div.note { background-color: #eee; border: 1px solid #ccc; font-style: italic; + text-indent: -2.9em; + padding-left: 3.5em; } div.seealso { @@ -243,6 +249,13 @@ div.warning { background-color: #ffe4e4; border: 1px solid #f66; font-style: italic; + text-indent: -4.6em; + padding-left: 5.2em; +} + +div.important { + text-indent: -5.5em; + padding-left: 6.1em; } p.admonition-title { @@ -283,12 +296,6 @@ dd.field-odd > ul.simple > li > ul > li > dl.simple { background-color: #e1e8e2; } -.admonition.important { - background-color: #fbf7c3; - border: 1px solid #c8c59b; - font-style: italic; -} - pre { padding: 10px; background-color: #e3e3e3; diff --git a/docs/source/api/evennia-api.rst b/docs/source/api/evennia-api.md similarity index 76% rename from docs/source/api/evennia-api.rst rename to docs/source/api/evennia-api.md index 27caffe4e4..ea63f3336c 100644 --- a/docs/source/api/evennia-api.rst +++ b/docs/source/api/evennia-api.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia ======= @@ -5,3 +6,5 @@ evennia :maxdepth: 6 evennia + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.accounts.accounts.rst b/docs/source/api/evennia.accounts.accounts.md similarity index 89% rename from docs/source/api/evennia.accounts.accounts.rst rename to docs/source/api/evennia.accounts.accounts.md index 5e256eb18b..6d01608a5d 100644 --- a/docs/source/api/evennia.accounts.accounts.rst +++ b/docs/source/api/evennia.accounts.accounts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.accounts.accounts ================================ @@ -5,3 +6,5 @@ evennia.accounts.accounts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.accounts.bots.rst b/docs/source/api/evennia.accounts.bots.md similarity index 88% rename from docs/source/api/evennia.accounts.bots.rst rename to docs/source/api/evennia.accounts.bots.md index 713986b696..bb1288c6eb 100644 --- a/docs/source/api/evennia.accounts.bots.rst +++ b/docs/source/api/evennia.accounts.bots.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.accounts.bots ============================ @@ -5,3 +6,5 @@ evennia.accounts.bots :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.accounts.manager.rst b/docs/source/api/evennia.accounts.manager.md similarity index 89% rename from docs/source/api/evennia.accounts.manager.rst rename to docs/source/api/evennia.accounts.manager.md index 0d3929ffeb..5769f087e1 100644 --- a/docs/source/api/evennia.accounts.manager.rst +++ b/docs/source/api/evennia.accounts.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.accounts.manager =============================== @@ -5,3 +6,5 @@ evennia.accounts.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.accounts.rst b/docs/source/api/evennia.accounts.md similarity index 93% rename from docs/source/api/evennia.accounts.rst rename to docs/source/api/evennia.accounts.md index c543b6a2a1..ccdd9427c5 100644 --- a/docs/source/api/evennia.accounts.rst +++ b/docs/source/api/evennia.accounts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.accounts ======================== @@ -15,3 +16,5 @@ evennia.accounts evennia.accounts.bots evennia.accounts.manager evennia.accounts.models + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.accounts.models.rst b/docs/source/api/evennia.accounts.models.md similarity index 89% rename from docs/source/api/evennia.accounts.models.rst rename to docs/source/api/evennia.accounts.models.md index 2a87b70eca..186fa02244 100644 --- a/docs/source/api/evennia.accounts.models.rst +++ b/docs/source/api/evennia.accounts.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.accounts.models ============================== @@ -5,3 +6,5 @@ evennia.accounts.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.cmdhandler.rst b/docs/source/api/evennia.commands.cmdhandler.md similarity index 90% rename from docs/source/api/evennia.commands.cmdhandler.rst rename to docs/source/api/evennia.commands.cmdhandler.md index 8c13d3afe0..b0bbb99df2 100644 --- a/docs/source/api/evennia.commands.cmdhandler.rst +++ b/docs/source/api/evennia.commands.cmdhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.cmdhandler ================================== @@ -5,3 +6,5 @@ evennia.commands.cmdhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.cmdparser.rst b/docs/source/api/evennia.commands.cmdparser.md similarity index 89% rename from docs/source/api/evennia.commands.cmdparser.rst rename to docs/source/api/evennia.commands.cmdparser.md index 0ae78c86cd..5cdbdf1194 100644 --- a/docs/source/api/evennia.commands.cmdparser.rst +++ b/docs/source/api/evennia.commands.cmdparser.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.cmdparser ================================= @@ -5,3 +6,5 @@ evennia.commands.cmdparser :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.cmdset.rst b/docs/source/api/evennia.commands.cmdset.md similarity index 89% rename from docs/source/api/evennia.commands.cmdset.rst rename to docs/source/api/evennia.commands.cmdset.md index bdaa62aa52..5b5da1bfbf 100644 --- a/docs/source/api/evennia.commands.cmdset.rst +++ b/docs/source/api/evennia.commands.cmdset.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.cmdset ============================== @@ -5,3 +6,5 @@ evennia.commands.cmdset :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.cmdsethandler.rst b/docs/source/api/evennia.commands.cmdsethandler.md similarity index 90% rename from docs/source/api/evennia.commands.cmdsethandler.rst rename to docs/source/api/evennia.commands.cmdsethandler.md index 8c470882a8..55ce0d287e 100644 --- a/docs/source/api/evennia.commands.cmdsethandler.rst +++ b/docs/source/api/evennia.commands.cmdsethandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.cmdsethandler ===================================== @@ -5,3 +6,5 @@ evennia.commands.cmdsethandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.command.rst b/docs/source/api/evennia.commands.command.md similarity index 89% rename from docs/source/api/evennia.commands.command.rst rename to docs/source/api/evennia.commands.command.md index dc54d5b0b3..04c5d2b169 100644 --- a/docs/source/api/evennia.commands.command.rst +++ b/docs/source/api/evennia.commands.command.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.command =============================== @@ -5,3 +6,5 @@ evennia.commands.command :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.account.rst b/docs/source/api/evennia.commands.default.account.md similarity index 90% rename from docs/source/api/evennia.commands.default.account.rst rename to docs/source/api/evennia.commands.default.account.md index 60b90c7342..9504dca8cf 100644 --- a/docs/source/api/evennia.commands.default.account.rst +++ b/docs/source/api/evennia.commands.default.account.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.account ======================================= @@ -5,3 +6,5 @@ evennia.commands.default.account :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.admin.rst b/docs/source/api/evennia.commands.default.admin.md similarity index 90% rename from docs/source/api/evennia.commands.default.admin.rst rename to docs/source/api/evennia.commands.default.admin.md index 83dd6b5d15..7b756a1d75 100644 --- a/docs/source/api/evennia.commands.default.admin.rst +++ b/docs/source/api/evennia.commands.default.admin.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.admin ===================================== @@ -5,3 +6,5 @@ evennia.commands.default.admin :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.batchprocess.rst b/docs/source/api/evennia.commands.default.batchprocess.md similarity index 91% rename from docs/source/api/evennia.commands.default.batchprocess.rst rename to docs/source/api/evennia.commands.default.batchprocess.md index 3b14019baa..30fd693bc1 100644 --- a/docs/source/api/evennia.commands.default.batchprocess.rst +++ b/docs/source/api/evennia.commands.default.batchprocess.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.batchprocess ============================================ @@ -5,3 +6,5 @@ evennia.commands.default.batchprocess :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.building.rst b/docs/source/api/evennia.commands.default.building.md similarity index 90% rename from docs/source/api/evennia.commands.default.building.rst rename to docs/source/api/evennia.commands.default.building.md index 2b34708766..e8de25927c 100644 --- a/docs/source/api/evennia.commands.default.building.rst +++ b/docs/source/api/evennia.commands.default.building.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.building ======================================== @@ -5,3 +6,5 @@ evennia.commands.default.building :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.cmdset_account.rst b/docs/source/api/evennia.commands.default.cmdset_account.md similarity index 91% rename from docs/source/api/evennia.commands.default.cmdset_account.rst rename to docs/source/api/evennia.commands.default.cmdset_account.md index 9d1c96533e..db0b9a045e 100644 --- a/docs/source/api/evennia.commands.default.cmdset_account.rst +++ b/docs/source/api/evennia.commands.default.cmdset_account.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.cmdset\_account =============================================== @@ -5,3 +6,5 @@ evennia.commands.default.cmdset\_account :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.cmdset_character.rst b/docs/source/api/evennia.commands.default.cmdset_character.md similarity index 92% rename from docs/source/api/evennia.commands.default.cmdset_character.rst rename to docs/source/api/evennia.commands.default.cmdset_character.md index c859957275..c96181d181 100644 --- a/docs/source/api/evennia.commands.default.cmdset_character.rst +++ b/docs/source/api/evennia.commands.default.cmdset_character.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.cmdset\_character ================================================= @@ -5,3 +6,5 @@ evennia.commands.default.cmdset\_character :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.cmdset_session.rst b/docs/source/api/evennia.commands.default.cmdset_session.md similarity index 91% rename from docs/source/api/evennia.commands.default.cmdset_session.rst rename to docs/source/api/evennia.commands.default.cmdset_session.md index a6324f096f..6e707db175 100644 --- a/docs/source/api/evennia.commands.default.cmdset_session.rst +++ b/docs/source/api/evennia.commands.default.cmdset_session.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.cmdset\_session =============================================== @@ -5,3 +6,5 @@ evennia.commands.default.cmdset\_session :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.cmdset_unloggedin.rst b/docs/source/api/evennia.commands.default.cmdset_unloggedin.md similarity index 92% rename from docs/source/api/evennia.commands.default.cmdset_unloggedin.rst rename to docs/source/api/evennia.commands.default.cmdset_unloggedin.md index e15cbaf882..0781385547 100644 --- a/docs/source/api/evennia.commands.default.cmdset_unloggedin.rst +++ b/docs/source/api/evennia.commands.default.cmdset_unloggedin.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.cmdset\_unloggedin ================================================== @@ -5,3 +6,5 @@ evennia.commands.default.cmdset\_unloggedin :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.comms.rst b/docs/source/api/evennia.commands.default.comms.md similarity index 90% rename from docs/source/api/evennia.commands.default.comms.rst rename to docs/source/api/evennia.commands.default.comms.md index 7840a59c33..0a0878c514 100644 --- a/docs/source/api/evennia.commands.default.comms.rst +++ b/docs/source/api/evennia.commands.default.comms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.comms ===================================== @@ -5,3 +6,5 @@ evennia.commands.default.comms :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.general.rst b/docs/source/api/evennia.commands.default.general.md similarity index 90% rename from docs/source/api/evennia.commands.default.general.rst rename to docs/source/api/evennia.commands.default.general.md index 6398464063..7c6045028e 100644 --- a/docs/source/api/evennia.commands.default.general.rst +++ b/docs/source/api/evennia.commands.default.general.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.general ======================================= @@ -5,3 +6,5 @@ evennia.commands.default.general :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.help.rst b/docs/source/api/evennia.commands.default.help.md similarity index 90% rename from docs/source/api/evennia.commands.default.help.rst rename to docs/source/api/evennia.commands.default.help.md index 61e2009ef8..46975ce296 100644 --- a/docs/source/api/evennia.commands.default.help.rst +++ b/docs/source/api/evennia.commands.default.help.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.help ==================================== @@ -5,3 +6,5 @@ evennia.commands.default.help :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.rst b/docs/source/api/evennia.commands.default.md similarity index 97% rename from docs/source/api/evennia.commands.default.rst rename to docs/source/api/evennia.commands.default.md index 0ed91c7571..afac41c901 100644 --- a/docs/source/api/evennia.commands.default.rst +++ b/docs/source/api/evennia.commands.default.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default ================================ @@ -27,3 +28,5 @@ evennia.commands.default evennia.commands.default.system evennia.commands.default.tests evennia.commands.default.unloggedin + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.muxcommand.rst b/docs/source/api/evennia.commands.default.muxcommand.md similarity index 91% rename from docs/source/api/evennia.commands.default.muxcommand.rst rename to docs/source/api/evennia.commands.default.muxcommand.md index f47330d5cf..6b58cb6a4c 100644 --- a/docs/source/api/evennia.commands.default.muxcommand.rst +++ b/docs/source/api/evennia.commands.default.muxcommand.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.muxcommand ========================================== @@ -5,3 +6,5 @@ evennia.commands.default.muxcommand :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.syscommands.rst b/docs/source/api/evennia.commands.default.syscommands.md similarity index 91% rename from docs/source/api/evennia.commands.default.syscommands.rst rename to docs/source/api/evennia.commands.default.syscommands.md index 630b2c79c9..c6eb24d4cd 100644 --- a/docs/source/api/evennia.commands.default.syscommands.rst +++ b/docs/source/api/evennia.commands.default.syscommands.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.syscommands =========================================== @@ -5,3 +6,5 @@ evennia.commands.default.syscommands :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.system.rst b/docs/source/api/evennia.commands.default.system.md similarity index 90% rename from docs/source/api/evennia.commands.default.system.rst rename to docs/source/api/evennia.commands.default.system.md index 0a17a98249..a8a4d64ca9 100644 --- a/docs/source/api/evennia.commands.default.system.rst +++ b/docs/source/api/evennia.commands.default.system.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.system ====================================== @@ -5,3 +6,5 @@ evennia.commands.default.system :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.tests.rst b/docs/source/api/evennia.commands.default.tests.md similarity index 90% rename from docs/source/api/evennia.commands.default.tests.rst rename to docs/source/api/evennia.commands.default.tests.md index ee49a77bef..cd23bcc6f5 100644 --- a/docs/source/api/evennia.commands.default.tests.rst +++ b/docs/source/api/evennia.commands.default.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.tests ===================================== @@ -5,3 +6,5 @@ evennia.commands.default.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.default.unloggedin.rst b/docs/source/api/evennia.commands.default.unloggedin.md similarity index 91% rename from docs/source/api/evennia.commands.default.unloggedin.rst rename to docs/source/api/evennia.commands.default.unloggedin.md index 87ccf8cbce..5818459d91 100644 --- a/docs/source/api/evennia.commands.default.unloggedin.rst +++ b/docs/source/api/evennia.commands.default.unloggedin.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands.default.unloggedin ========================================== @@ -5,3 +6,5 @@ evennia.commands.default.unloggedin :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.commands.rst b/docs/source/api/evennia.commands.md similarity index 95% rename from docs/source/api/evennia.commands.rst rename to docs/source/api/evennia.commands.md index d88c62a7e1..f689f8bade 100644 --- a/docs/source/api/evennia.commands.rst +++ b/docs/source/api/evennia.commands.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.commands ======================== @@ -22,3 +23,5 @@ evennia.commands :maxdepth: 6 evennia.commands.default + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.comms.comms.rst b/docs/source/api/evennia.comms.comms.md similarity index 88% rename from docs/source/api/evennia.comms.comms.rst rename to docs/source/api/evennia.comms.comms.md index 0d137a7f0e..7058f8dbce 100644 --- a/docs/source/api/evennia.comms.comms.rst +++ b/docs/source/api/evennia.comms.comms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.comms.comms ========================== @@ -5,3 +6,5 @@ evennia.comms.comms :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.comms.managers.rst b/docs/source/api/evennia.comms.managers.md similarity index 89% rename from docs/source/api/evennia.comms.managers.rst rename to docs/source/api/evennia.comms.managers.md index 32c444ac3f..a67a3145a4 100644 --- a/docs/source/api/evennia.comms.managers.rst +++ b/docs/source/api/evennia.comms.managers.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.comms.managers ============================= @@ -5,3 +6,5 @@ evennia.comms.managers :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.comms.rst b/docs/source/api/evennia.comms.md similarity index 92% rename from docs/source/api/evennia.comms.rst rename to docs/source/api/evennia.comms.md index fe7ea8d5b6..8435d32078 100644 --- a/docs/source/api/evennia.comms.rst +++ b/docs/source/api/evennia.comms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.comms ===================== @@ -14,3 +15,5 @@ evennia.comms evennia.comms.comms evennia.comms.managers evennia.comms.models + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.comms.models.rst b/docs/source/api/evennia.comms.models.md similarity index 88% rename from docs/source/api/evennia.comms.models.rst rename to docs/source/api/evennia.comms.models.md index 502abf6077..9fbd238539 100644 --- a/docs/source/api/evennia.comms.models.rst +++ b/docs/source/api/evennia.comms.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.comms.models =========================== @@ -5,3 +6,5 @@ evennia.comms.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.rst b/docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.md similarity index 91% rename from docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.rst rename to docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.md index d8459814bd..9b0e3f4ab0 100644 --- a/docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.rst +++ b/docs/source/api/evennia.contrib.awsstorage.aws_s3_cdn.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.awsstorage.aws\_s3\_cdn ============================================== @@ -5,3 +6,5 @@ evennia.contrib.awsstorage.aws\_s3\_cdn :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.awsstorage.rst b/docs/source/api/evennia.contrib.awsstorage.md similarity index 93% rename from docs/source/api/evennia.contrib.awsstorage.rst rename to docs/source/api/evennia.contrib.awsstorage.md index 71e76a6080..352e1cea4f 100644 --- a/docs/source/api/evennia.contrib.awsstorage.rst +++ b/docs/source/api/evennia.contrib.awsstorage.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.awsstorage ================================== @@ -13,3 +14,5 @@ evennia.contrib.awsstorage evennia.contrib.awsstorage.aws_s3_cdn evennia.contrib.awsstorage.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.awsstorage.tests.rst b/docs/source/api/evennia.contrib.awsstorage.tests.md similarity index 90% rename from docs/source/api/evennia.contrib.awsstorage.tests.rst rename to docs/source/api/evennia.contrib.awsstorage.tests.md index 2c6b839c33..9f78aa2340 100644 --- a/docs/source/api/evennia.contrib.awsstorage.tests.rst +++ b/docs/source/api/evennia.contrib.awsstorage.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.awsstorage.tests ======================================= @@ -5,3 +6,5 @@ evennia.contrib.awsstorage.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.barter.rst b/docs/source/api/evennia.contrib.barter.md similarity index 89% rename from docs/source/api/evennia.contrib.barter.rst rename to docs/source/api/evennia.contrib.barter.md index d9310e1c04..fe80a4cb16 100644 --- a/docs/source/api/evennia.contrib.barter.rst +++ b/docs/source/api/evennia.contrib.barter.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.barter ============================= @@ -5,3 +6,5 @@ evennia.contrib.barter :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.building_menu.rst b/docs/source/api/evennia.contrib.building_menu.md similarity index 90% rename from docs/source/api/evennia.contrib.building_menu.rst rename to docs/source/api/evennia.contrib.building_menu.md index 48311502d9..68b3756b11 100644 --- a/docs/source/api/evennia.contrib.building_menu.rst +++ b/docs/source/api/evennia.contrib.building_menu.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.building\_menu ===================================== @@ -5,3 +6,5 @@ evennia.contrib.building\_menu :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.chargen.rst b/docs/source/api/evennia.contrib.chargen.md similarity index 89% rename from docs/source/api/evennia.contrib.chargen.rst rename to docs/source/api/evennia.contrib.chargen.md index 2798f01af2..54e2b1c89c 100644 --- a/docs/source/api/evennia.contrib.chargen.rst +++ b/docs/source/api/evennia.contrib.chargen.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.chargen ============================== @@ -5,3 +6,5 @@ evennia.contrib.chargen :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.clothing.rst b/docs/source/api/evennia.contrib.clothing.md similarity index 89% rename from docs/source/api/evennia.contrib.clothing.rst rename to docs/source/api/evennia.contrib.clothing.md index 294a5bbfe8..06b083fef6 100644 --- a/docs/source/api/evennia.contrib.clothing.rst +++ b/docs/source/api/evennia.contrib.clothing.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.clothing =============================== @@ -5,3 +6,5 @@ evennia.contrib.clothing :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.color_markups.rst b/docs/source/api/evennia.contrib.color_markups.md similarity index 90% rename from docs/source/api/evennia.contrib.color_markups.rst rename to docs/source/api/evennia.contrib.color_markups.md index af0f20555d..6f1040358e 100644 --- a/docs/source/api/evennia.contrib.color_markups.rst +++ b/docs/source/api/evennia.contrib.color_markups.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.color\_markups ===================================== @@ -5,3 +6,5 @@ evennia.contrib.color\_markups :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.crafting.crafting.rst b/docs/source/api/evennia.contrib.crafting.crafting.md similarity index 90% rename from docs/source/api/evennia.contrib.crafting.crafting.rst rename to docs/source/api/evennia.contrib.crafting.crafting.md index fcc8cf0b1a..48924ab015 100644 --- a/docs/source/api/evennia.contrib.crafting.crafting.rst +++ b/docs/source/api/evennia.contrib.crafting.crafting.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.crafting.crafting ======================================== @@ -5,3 +6,5 @@ evennia.contrib.crafting.crafting :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.crafting.example_recipes.rst b/docs/source/api/evennia.contrib.crafting.example_recipes.md similarity index 91% rename from docs/source/api/evennia.contrib.crafting.example_recipes.rst rename to docs/source/api/evennia.contrib.crafting.example_recipes.md index 26733502f9..e162f98c73 100644 --- a/docs/source/api/evennia.contrib.crafting.example_recipes.rst +++ b/docs/source/api/evennia.contrib.crafting.example_recipes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.crafting.example\_recipes ================================================ @@ -5,3 +6,5 @@ evennia.contrib.crafting.example\_recipes :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.crafting.rst b/docs/source/api/evennia.contrib.crafting.md similarity index 94% rename from docs/source/api/evennia.contrib.crafting.rst rename to docs/source/api/evennia.contrib.crafting.md index c24b3ebcd5..3093c21711 100644 --- a/docs/source/api/evennia.contrib.crafting.rst +++ b/docs/source/api/evennia.contrib.crafting.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.crafting ================================ @@ -14,3 +15,5 @@ evennia.contrib.crafting evennia.contrib.crafting.crafting evennia.contrib.crafting.example_recipes evennia.contrib.crafting.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.crafting.tests.rst b/docs/source/api/evennia.contrib.crafting.tests.md similarity index 90% rename from docs/source/api/evennia.contrib.crafting.tests.rst rename to docs/source/api/evennia.contrib.crafting.tests.md index f6cd3e51d1..0b0e3ae777 100644 --- a/docs/source/api/evennia.contrib.crafting.tests.rst +++ b/docs/source/api/evennia.contrib.crafting.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.crafting.tests ===================================== @@ -5,3 +6,5 @@ evennia.contrib.crafting.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.custom_gametime.rst b/docs/source/api/evennia.contrib.custom_gametime.md similarity index 90% rename from docs/source/api/evennia.contrib.custom_gametime.rst rename to docs/source/api/evennia.contrib.custom_gametime.md index b0e88bf61f..b0292d6405 100644 --- a/docs/source/api/evennia.contrib.custom_gametime.rst +++ b/docs/source/api/evennia.contrib.custom_gametime.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.custom\_gametime ======================================= @@ -5,3 +6,5 @@ evennia.contrib.custom\_gametime :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.dice.rst b/docs/source/api/evennia.contrib.dice.md similarity index 88% rename from docs/source/api/evennia.contrib.dice.rst rename to docs/source/api/evennia.contrib.dice.md index dffa191433..2a9b9e0b21 100644 --- a/docs/source/api/evennia.contrib.dice.rst +++ b/docs/source/api/evennia.contrib.dice.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.dice =========================== @@ -5,3 +6,5 @@ evennia.contrib.dice :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.email_login.rst b/docs/source/api/evennia.contrib.email_login.md similarity index 90% rename from docs/source/api/evennia.contrib.email_login.rst rename to docs/source/api/evennia.contrib.email_login.md index 7b93c80e84..2c9121c193 100644 --- a/docs/source/api/evennia.contrib.email_login.rst +++ b/docs/source/api/evennia.contrib.email_login.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.email\_login =================================== @@ -5,3 +6,5 @@ evennia.contrib.email\_login :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.commands.rst b/docs/source/api/evennia.contrib.evscaperoom.commands.md similarity index 91% rename from docs/source/api/evennia.contrib.evscaperoom.commands.rst rename to docs/source/api/evennia.contrib.evscaperoom.commands.md index 7cfa1127f6..4862735b58 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.commands.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.commands.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.commands =========================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.commands :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.rst b/docs/source/api/evennia.contrib.evscaperoom.md similarity index 96% rename from docs/source/api/evennia.contrib.evscaperoom.rst rename to docs/source/api/evennia.contrib.evscaperoom.md index 3bb5625be4..2698a22e50 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom =================================== @@ -19,3 +20,5 @@ evennia.contrib.evscaperoom evennia.contrib.evscaperoom.state evennia.contrib.evscaperoom.tests evennia.contrib.evscaperoom.utils + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.menu.rst b/docs/source/api/evennia.contrib.evscaperoom.menu.md similarity index 90% rename from docs/source/api/evennia.contrib.evscaperoom.menu.rst rename to docs/source/api/evennia.contrib.evscaperoom.menu.md index f06cef17af..7d0ecf8b14 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.menu.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.menu.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.menu ======================================= @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.menu :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.objects.rst b/docs/source/api/evennia.contrib.evscaperoom.objects.md similarity index 91% rename from docs/source/api/evennia.contrib.evscaperoom.objects.rst rename to docs/source/api/evennia.contrib.evscaperoom.objects.md index 5fad35fc00..4df4d800fb 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.objects.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.objects ========================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.objects :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.room.rst b/docs/source/api/evennia.contrib.evscaperoom.room.md similarity index 90% rename from docs/source/api/evennia.contrib.evscaperoom.room.rst rename to docs/source/api/evennia.contrib.evscaperoom.room.md index 5e0c7dad0f..4d6fd4a2de 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.room.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.room.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.room ======================================= @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.room :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.scripts.rst b/docs/source/api/evennia.contrib.evscaperoom.scripts.md similarity index 91% rename from docs/source/api/evennia.contrib.evscaperoom.scripts.rst rename to docs/source/api/evennia.contrib.evscaperoom.scripts.md index 4188d69b3e..cd23004c16 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.scripts.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.scripts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.scripts ========================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.scripts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.state.rst b/docs/source/api/evennia.contrib.evscaperoom.state.md similarity index 90% rename from docs/source/api/evennia.contrib.evscaperoom.state.rst rename to docs/source/api/evennia.contrib.evscaperoom.state.md index 9be9727aae..266820c5c0 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.state.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.state.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.state ======================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.state :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.tests.rst b/docs/source/api/evennia.contrib.evscaperoom.tests.md similarity index 90% rename from docs/source/api/evennia.contrib.evscaperoom.tests.rst rename to docs/source/api/evennia.contrib.evscaperoom.tests.md index da9d7ab4e6..7a78bd512c 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.tests.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.tests ======================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.evscaperoom.utils.rst b/docs/source/api/evennia.contrib.evscaperoom.utils.md similarity index 90% rename from docs/source/api/evennia.contrib.evscaperoom.utils.rst rename to docs/source/api/evennia.contrib.evscaperoom.utils.md index 85a1bbc237..83d3fd4fc0 100644 --- a/docs/source/api/evennia.contrib.evscaperoom.utils.rst +++ b/docs/source/api/evennia.contrib.evscaperoom.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.evscaperoom.utils ======================================== @@ -5,3 +6,5 @@ evennia.contrib.evscaperoom.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.extended_room.rst b/docs/source/api/evennia.contrib.extended_room.md similarity index 90% rename from docs/source/api/evennia.contrib.extended_room.rst rename to docs/source/api/evennia.contrib.extended_room.md index 0a42631a15..2abc52496d 100644 --- a/docs/source/api/evennia.contrib.extended_room.rst +++ b/docs/source/api/evennia.contrib.extended_room.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.extended\_room ===================================== @@ -5,3 +6,5 @@ evennia.contrib.extended\_room :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.fieldfill.rst b/docs/source/api/evennia.contrib.fieldfill.md similarity index 89% rename from docs/source/api/evennia.contrib.fieldfill.rst rename to docs/source/api/evennia.contrib.fieldfill.md index 9444e16f70..db6f38c686 100644 --- a/docs/source/api/evennia.contrib.fieldfill.rst +++ b/docs/source/api/evennia.contrib.fieldfill.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.fieldfill ================================ @@ -5,3 +6,5 @@ evennia.contrib.fieldfill :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.gendersub.rst b/docs/source/api/evennia.contrib.gendersub.md similarity index 89% rename from docs/source/api/evennia.contrib.gendersub.rst rename to docs/source/api/evennia.contrib.gendersub.md index fbc19b68d1..e741f28541 100644 --- a/docs/source/api/evennia.contrib.gendersub.rst +++ b/docs/source/api/evennia.contrib.gendersub.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.gendersub ================================ @@ -5,3 +6,5 @@ evennia.contrib.gendersub :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.health_bar.rst b/docs/source/api/evennia.contrib.health_bar.md similarity index 90% rename from docs/source/api/evennia.contrib.health_bar.rst rename to docs/source/api/evennia.contrib.health_bar.md index af113dc131..7796497196 100644 --- a/docs/source/api/evennia.contrib.health_bar.rst +++ b/docs/source/api/evennia.contrib.health_bar.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.health\_bar ================================== @@ -5,3 +6,5 @@ evennia.contrib.health\_bar :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.callbackhandler.rst b/docs/source/api/evennia.contrib.ingame_python.callbackhandler.md similarity index 92% rename from docs/source/api/evennia.contrib.ingame_python.callbackhandler.rst rename to docs/source/api/evennia.contrib.ingame_python.callbackhandler.md index d35d74a8b2..54be3910c6 100644 --- a/docs/source/api/evennia.contrib.ingame_python.callbackhandler.rst +++ b/docs/source/api/evennia.contrib.ingame_python.callbackhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.callbackhandler ===================================================== @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.callbackhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.commands.rst b/docs/source/api/evennia.contrib.ingame_python.commands.md similarity index 91% rename from docs/source/api/evennia.contrib.ingame_python.commands.rst rename to docs/source/api/evennia.contrib.ingame_python.commands.md index 04461dd95d..dbe8d1d206 100644 --- a/docs/source/api/evennia.contrib.ingame_python.commands.rst +++ b/docs/source/api/evennia.contrib.ingame_python.commands.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.commands ============================================== @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.commands :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.eventfuncs.rst b/docs/source/api/evennia.contrib.ingame_python.eventfuncs.md similarity index 91% rename from docs/source/api/evennia.contrib.ingame_python.eventfuncs.rst rename to docs/source/api/evennia.contrib.ingame_python.eventfuncs.md index 1c534da396..b2dc7c0b57 100644 --- a/docs/source/api/evennia.contrib.ingame_python.eventfuncs.rst +++ b/docs/source/api/evennia.contrib.ingame_python.eventfuncs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.eventfuncs ================================================ @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.eventfuncs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.rst b/docs/source/api/evennia.contrib.ingame_python.md similarity index 96% rename from docs/source/api/evennia.contrib.ingame_python.rst rename to docs/source/api/evennia.contrib.ingame_python.md index d3abba10b2..75930be320 100644 --- a/docs/source/api/evennia.contrib.ingame_python.rst +++ b/docs/source/api/evennia.contrib.ingame_python.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python ====================================== @@ -18,3 +19,5 @@ evennia.contrib.ingame\_python evennia.contrib.ingame_python.tests evennia.contrib.ingame_python.typeclasses evennia.contrib.ingame_python.utils + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.scripts.rst b/docs/source/api/evennia.contrib.ingame_python.scripts.md similarity index 91% rename from docs/source/api/evennia.contrib.ingame_python.scripts.rst rename to docs/source/api/evennia.contrib.ingame_python.scripts.md index e10d643df5..25dd4ee6e4 100644 --- a/docs/source/api/evennia.contrib.ingame_python.scripts.rst +++ b/docs/source/api/evennia.contrib.ingame_python.scripts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.scripts ============================================= @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.scripts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.tests.rst b/docs/source/api/evennia.contrib.ingame_python.tests.md similarity index 91% rename from docs/source/api/evennia.contrib.ingame_python.tests.rst rename to docs/source/api/evennia.contrib.ingame_python.tests.md index de2edcf047..5392da43f0 100644 --- a/docs/source/api/evennia.contrib.ingame_python.tests.rst +++ b/docs/source/api/evennia.contrib.ingame_python.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.tests =========================================== @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.typeclasses.rst b/docs/source/api/evennia.contrib.ingame_python.typeclasses.md similarity index 92% rename from docs/source/api/evennia.contrib.ingame_python.typeclasses.rst rename to docs/source/api/evennia.contrib.ingame_python.typeclasses.md index fdd43475de..6db7d68994 100644 --- a/docs/source/api/evennia.contrib.ingame_python.typeclasses.rst +++ b/docs/source/api/evennia.contrib.ingame_python.typeclasses.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.typeclasses ================================================= @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.typeclasses :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.ingame_python.utils.rst b/docs/source/api/evennia.contrib.ingame_python.utils.md similarity index 91% rename from docs/source/api/evennia.contrib.ingame_python.utils.rst rename to docs/source/api/evennia.contrib.ingame_python.utils.md index aefcdd3bc5..ef6d6abe8e 100644 --- a/docs/source/api/evennia.contrib.ingame_python.utils.rst +++ b/docs/source/api/evennia.contrib.ingame_python.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.ingame\_python.utils =========================================== @@ -5,3 +6,5 @@ evennia.contrib.ingame\_python.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.mail.rst b/docs/source/api/evennia.contrib.mail.md similarity index 88% rename from docs/source/api/evennia.contrib.mail.rst rename to docs/source/api/evennia.contrib.mail.md index d0999aeb18..98b7d74e29 100644 --- a/docs/source/api/evennia.contrib.mail.rst +++ b/docs/source/api/evennia.contrib.mail.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.mail =========================== @@ -5,3 +6,5 @@ evennia.contrib.mail :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.mapbuilder.rst b/docs/source/api/evennia.contrib.mapbuilder.md similarity index 89% rename from docs/source/api/evennia.contrib.mapbuilder.rst rename to docs/source/api/evennia.contrib.mapbuilder.md index 6353d674a2..cefd748613 100644 --- a/docs/source/api/evennia.contrib.mapbuilder.rst +++ b/docs/source/api/evennia.contrib.mapbuilder.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.mapbuilder ================================= @@ -5,3 +6,5 @@ evennia.contrib.mapbuilder :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.rst b/docs/source/api/evennia.contrib.md similarity index 98% rename from docs/source/api/evennia.contrib.rst rename to docs/source/api/evennia.contrib.md index 1fe1ccd29f..7ce74eb5d3 100644 --- a/docs/source/api/evennia.contrib.rst +++ b/docs/source/api/evennia.contrib.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib ======================= @@ -53,3 +54,5 @@ evennia.contrib evennia.contrib.tutorial_examples evennia.contrib.tutorial_world evennia.contrib.xyzgrid + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.menu_login.rst b/docs/source/api/evennia.contrib.menu_login.md similarity index 90% rename from docs/source/api/evennia.contrib.menu_login.rst rename to docs/source/api/evennia.contrib.menu_login.md index 72dd5f21cd..75f3ba790d 100644 --- a/docs/source/api/evennia.contrib.menu_login.rst +++ b/docs/source/api/evennia.contrib.menu_login.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.menu\_login ================================== @@ -5,3 +6,5 @@ evennia.contrib.menu\_login :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.multidescer.rst b/docs/source/api/evennia.contrib.multidescer.md similarity index 90% rename from docs/source/api/evennia.contrib.multidescer.rst rename to docs/source/api/evennia.contrib.multidescer.md index 2e208b96c9..34c7f089c6 100644 --- a/docs/source/api/evennia.contrib.multidescer.rst +++ b/docs/source/api/evennia.contrib.multidescer.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.multidescer ================================== @@ -5,3 +6,5 @@ evennia.contrib.multidescer :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.puzzles.rst b/docs/source/api/evennia.contrib.puzzles.md similarity index 89% rename from docs/source/api/evennia.contrib.puzzles.rst rename to docs/source/api/evennia.contrib.puzzles.md index 709ab98bb9..09940d7206 100644 --- a/docs/source/api/evennia.contrib.puzzles.rst +++ b/docs/source/api/evennia.contrib.puzzles.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.puzzles ============================== @@ -5,3 +6,5 @@ evennia.contrib.puzzles :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.random_string_generator.rst b/docs/source/api/evennia.contrib.random_string_generator.md similarity index 91% rename from docs/source/api/evennia.contrib.random_string_generator.rst rename to docs/source/api/evennia.contrib.random_string_generator.md index e03fc819a3..1c943f6140 100644 --- a/docs/source/api/evennia.contrib.random_string_generator.rst +++ b/docs/source/api/evennia.contrib.random_string_generator.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.random\_string\_generator ================================================ @@ -5,3 +6,5 @@ evennia.contrib.random\_string\_generator :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.rplanguage.rst b/docs/source/api/evennia.contrib.rplanguage.md similarity index 89% rename from docs/source/api/evennia.contrib.rplanguage.rst rename to docs/source/api/evennia.contrib.rplanguage.md index b3b4c96135..dcce2f960a 100644 --- a/docs/source/api/evennia.contrib.rplanguage.rst +++ b/docs/source/api/evennia.contrib.rplanguage.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.rplanguage ================================= @@ -5,3 +6,5 @@ evennia.contrib.rplanguage :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.rpsystem.rst b/docs/source/api/evennia.contrib.rpsystem.md similarity index 89% rename from docs/source/api/evennia.contrib.rpsystem.rst rename to docs/source/api/evennia.contrib.rpsystem.md index 0909f232b5..f968540d66 100644 --- a/docs/source/api/evennia.contrib.rpsystem.rst +++ b/docs/source/api/evennia.contrib.rpsystem.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.rpsystem =============================== @@ -5,3 +6,5 @@ evennia.contrib.rpsystem :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.security.auditing.rst b/docs/source/api/evennia.contrib.security.auditing.md similarity index 95% rename from docs/source/api/evennia.contrib.security.auditing.rst rename to docs/source/api/evennia.contrib.security.auditing.md index fb6c40a1c4..93f07ffb58 100644 --- a/docs/source/api/evennia.contrib.security.auditing.rst +++ b/docs/source/api/evennia.contrib.security.auditing.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.security.auditing ========================================= @@ -14,3 +15,5 @@ evennia.contrib.security.auditing evennia.contrib.security.auditing.outputs evennia.contrib.security.auditing.server evennia.contrib.security.auditing.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.security.auditing.outputs.rst b/docs/source/api/evennia.contrib.security.auditing.outputs.md similarity index 91% rename from docs/source/api/evennia.contrib.security.auditing.outputs.rst rename to docs/source/api/evennia.contrib.security.auditing.outputs.md index 3f00916652..9841ec0d70 100644 --- a/docs/source/api/evennia.contrib.security.auditing.outputs.rst +++ b/docs/source/api/evennia.contrib.security.auditing.outputs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.security.auditing.outputs ================================================ @@ -5,3 +6,5 @@ evennia.contrib.security.auditing.outputs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.security.auditing.server.rst b/docs/source/api/evennia.contrib.security.auditing.server.md similarity index 91% rename from docs/source/api/evennia.contrib.security.auditing.server.rst rename to docs/source/api/evennia.contrib.security.auditing.server.md index 0f3969d39a..8d03d16ab2 100644 --- a/docs/source/api/evennia.contrib.security.auditing.server.rst +++ b/docs/source/api/evennia.contrib.security.auditing.server.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.security.auditing.server =============================================== @@ -5,3 +6,5 @@ evennia.contrib.security.auditing.server :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.security.auditing.tests.rst b/docs/source/api/evennia.contrib.security.auditing.tests.md similarity index 91% rename from docs/source/api/evennia.contrib.security.auditing.tests.rst rename to docs/source/api/evennia.contrib.security.auditing.tests.md index 5daead6967..97f359435e 100644 --- a/docs/source/api/evennia.contrib.security.auditing.tests.rst +++ b/docs/source/api/evennia.contrib.security.auditing.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.security.auditing.tests ============================================== @@ -5,3 +6,5 @@ evennia.contrib.security.auditing.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.security.rst b/docs/source/api/evennia.contrib.security.md similarity index 92% rename from docs/source/api/evennia.contrib.security.rst rename to docs/source/api/evennia.contrib.security.md index 4e6fef9eb8..157574ff02 100644 --- a/docs/source/api/evennia.contrib.security.rst +++ b/docs/source/api/evennia.contrib.security.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.security ================================ @@ -11,3 +12,5 @@ evennia.contrib.security :maxdepth: 6 evennia.contrib.security.auditing + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.simpledoor.rst b/docs/source/api/evennia.contrib.simpledoor.md similarity index 89% rename from docs/source/api/evennia.contrib.simpledoor.rst rename to docs/source/api/evennia.contrib.simpledoor.md index 3d6921be0c..9546d763ff 100644 --- a/docs/source/api/evennia.contrib.simpledoor.rst +++ b/docs/source/api/evennia.contrib.simpledoor.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.simpledoor ================================= @@ -5,3 +6,5 @@ evennia.contrib.simpledoor :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.slow_exit.rst b/docs/source/api/evennia.contrib.slow_exit.md similarity index 89% rename from docs/source/api/evennia.contrib.slow_exit.rst rename to docs/source/api/evennia.contrib.slow_exit.md index 497e45659d..e201bc5ce0 100644 --- a/docs/source/api/evennia.contrib.slow_exit.rst +++ b/docs/source/api/evennia.contrib.slow_exit.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.slow\_exit ================================= @@ -5,3 +6,5 @@ evennia.contrib.slow\_exit :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.talking_npc.rst b/docs/source/api/evennia.contrib.talking_npc.md similarity index 90% rename from docs/source/api/evennia.contrib.talking_npc.rst rename to docs/source/api/evennia.contrib.talking_npc.md index cd652e66b5..822a12f136 100644 --- a/docs/source/api/evennia.contrib.talking_npc.rst +++ b/docs/source/api/evennia.contrib.talking_npc.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.talking\_npc =================================== @@ -5,3 +6,5 @@ evennia.contrib.talking\_npc :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.test_traits.rst b/docs/source/api/evennia.contrib.test_traits.md similarity index 90% rename from docs/source/api/evennia.contrib.test_traits.rst rename to docs/source/api/evennia.contrib.test_traits.md index a031821cba..4c807c6eac 100644 --- a/docs/source/api/evennia.contrib.test_traits.rst +++ b/docs/source/api/evennia.contrib.test_traits.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.test\_traits =================================== @@ -5,3 +6,5 @@ evennia.contrib.test\_traits :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.traits.rst b/docs/source/api/evennia.contrib.traits.md similarity index 89% rename from docs/source/api/evennia.contrib.traits.rst rename to docs/source/api/evennia.contrib.traits.md index 95b3693819..e9db4e5aa3 100644 --- a/docs/source/api/evennia.contrib.traits.rst +++ b/docs/source/api/evennia.contrib.traits.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.traits ============================= @@ -5,3 +6,5 @@ evennia.contrib.traits :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tree_select.rst b/docs/source/api/evennia.contrib.tree_select.md similarity index 90% rename from docs/source/api/evennia.contrib.tree_select.rst rename to docs/source/api/evennia.contrib.tree_select.md index 887cdff507..65322c3bc7 100644 --- a/docs/source/api/evennia.contrib.tree_select.rst +++ b/docs/source/api/evennia.contrib.tree_select.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tree\_select =================================== @@ -5,3 +6,5 @@ evennia.contrib.tree\_select :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.rst b/docs/source/api/evennia.contrib.turnbattle.md similarity index 95% rename from docs/source/api/evennia.contrib.turnbattle.rst rename to docs/source/api/evennia.contrib.turnbattle.md index 03bb3737df..267e02d20c 100644 --- a/docs/source/api/evennia.contrib.turnbattle.rst +++ b/docs/source/api/evennia.contrib.turnbattle.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle ================================== @@ -16,3 +17,5 @@ evennia.contrib.turnbattle evennia.contrib.turnbattle.tb_items evennia.contrib.turnbattle.tb_magic evennia.contrib.turnbattle.tb_range + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.tb_basic.rst b/docs/source/api/evennia.contrib.turnbattle.tb_basic.md similarity index 91% rename from docs/source/api/evennia.contrib.turnbattle.tb_basic.rst rename to docs/source/api/evennia.contrib.turnbattle.tb_basic.md index 47e51a9813..b65fe3ceb5 100644 --- a/docs/source/api/evennia.contrib.turnbattle.tb_basic.rst +++ b/docs/source/api/evennia.contrib.turnbattle.tb_basic.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle.tb\_basic =========================================== @@ -5,3 +6,5 @@ evennia.contrib.turnbattle.tb\_basic :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.tb_equip.rst b/docs/source/api/evennia.contrib.turnbattle.tb_equip.md similarity index 91% rename from docs/source/api/evennia.contrib.turnbattle.tb_equip.rst rename to docs/source/api/evennia.contrib.turnbattle.tb_equip.md index 7413f0f5a8..14fc4b0a7c 100644 --- a/docs/source/api/evennia.contrib.turnbattle.tb_equip.rst +++ b/docs/source/api/evennia.contrib.turnbattle.tb_equip.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle.tb\_equip =========================================== @@ -5,3 +6,5 @@ evennia.contrib.turnbattle.tb\_equip :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.tb_items.rst b/docs/source/api/evennia.contrib.turnbattle.tb_items.md similarity index 91% rename from docs/source/api/evennia.contrib.turnbattle.tb_items.rst rename to docs/source/api/evennia.contrib.turnbattle.tb_items.md index 8e3b47452a..cec6a5562e 100644 --- a/docs/source/api/evennia.contrib.turnbattle.tb_items.rst +++ b/docs/source/api/evennia.contrib.turnbattle.tb_items.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle.tb\_items =========================================== @@ -5,3 +6,5 @@ evennia.contrib.turnbattle.tb\_items :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.tb_magic.rst b/docs/source/api/evennia.contrib.turnbattle.tb_magic.md similarity index 91% rename from docs/source/api/evennia.contrib.turnbattle.tb_magic.rst rename to docs/source/api/evennia.contrib.turnbattle.tb_magic.md index 8b22a80979..402f06e966 100644 --- a/docs/source/api/evennia.contrib.turnbattle.tb_magic.rst +++ b/docs/source/api/evennia.contrib.turnbattle.tb_magic.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle.tb\_magic =========================================== @@ -5,3 +6,5 @@ evennia.contrib.turnbattle.tb\_magic :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.turnbattle.tb_range.rst b/docs/source/api/evennia.contrib.turnbattle.tb_range.md similarity index 91% rename from docs/source/api/evennia.contrib.turnbattle.tb_range.rst rename to docs/source/api/evennia.contrib.turnbattle.tb_range.md index 604e6f6dd3..1643487f16 100644 --- a/docs/source/api/evennia.contrib.turnbattle.tb_range.rst +++ b/docs/source/api/evennia.contrib.turnbattle.tb_range.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.turnbattle.tb\_range =========================================== @@ -5,3 +6,5 @@ evennia.contrib.turnbattle.tb\_range :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.rst b/docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.md similarity index 92% rename from docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.rst rename to docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.md index 22ba12c821..7927676910 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.bodyfunctions.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples.bodyfunctions ======================================================= @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_examples.bodyfunctions :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.rst b/docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.md similarity index 93% rename from docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.rst rename to docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.md index 606cf5d236..1f23e16fbc 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.example_batch_code.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples.example\_batch\_code ============================================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_examples.example\_batch\_code :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.rst b/docs/source/api/evennia.contrib.tutorial_examples.md similarity index 96% rename from docs/source/api/evennia.contrib.tutorial_examples.rst rename to docs/source/api/evennia.contrib.tutorial_examples.md index b6935063e2..182e3968d7 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples ========================================== @@ -16,3 +17,5 @@ evennia.contrib.tutorial\_examples evennia.contrib.tutorial_examples.mirror evennia.contrib.tutorial_examples.red_button evennia.contrib.tutorial_examples.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.mirror.rst b/docs/source/api/evennia.contrib.tutorial_examples.mirror.md similarity index 91% rename from docs/source/api/evennia.contrib.tutorial_examples.mirror.rst rename to docs/source/api/evennia.contrib.tutorial_examples.mirror.md index d02f59d726..c086b8f2d9 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.mirror.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.mirror.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples.mirror ================================================ @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_examples.mirror :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.red_button.rst b/docs/source/api/evennia.contrib.tutorial_examples.red_button.md similarity index 92% rename from docs/source/api/evennia.contrib.tutorial_examples.red_button.rst rename to docs/source/api/evennia.contrib.tutorial_examples.red_button.md index 076b68b44f..b37bb6bb06 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.red_button.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.red_button.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples.red\_button ===================================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_examples.red\_button :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_examples.tests.rst b/docs/source/api/evennia.contrib.tutorial_examples.tests.md similarity index 91% rename from docs/source/api/evennia.contrib.tutorial_examples.tests.rst rename to docs/source/api/evennia.contrib.tutorial_examples.tests.md index fe4da272e3..9e27c81be5 100644 --- a/docs/source/api/evennia.contrib.tutorial_examples.tests.rst +++ b/docs/source/api/evennia.contrib.tutorial_examples.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_examples.tests =============================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_examples.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_world.intro_menu.rst b/docs/source/api/evennia.contrib.tutorial_world.intro_menu.md similarity index 92% rename from docs/source/api/evennia.contrib.tutorial_world.intro_menu.rst rename to docs/source/api/evennia.contrib.tutorial_world.intro_menu.md index 03e2278773..7e844136b9 100644 --- a/docs/source/api/evennia.contrib.tutorial_world.intro_menu.rst +++ b/docs/source/api/evennia.contrib.tutorial_world.intro_menu.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_world.intro\_menu ================================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_world.intro\_menu :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_world.rst b/docs/source/api/evennia.contrib.tutorial_world.md similarity index 95% rename from docs/source/api/evennia.contrib.tutorial_world.rst rename to docs/source/api/evennia.contrib.tutorial_world.md index d7f29ea729..50c4b54d16 100644 --- a/docs/source/api/evennia.contrib.tutorial_world.rst +++ b/docs/source/api/evennia.contrib.tutorial_world.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_world ======================================= @@ -15,3 +16,5 @@ evennia.contrib.tutorial\_world evennia.contrib.tutorial_world.mob evennia.contrib.tutorial_world.objects evennia.contrib.tutorial_world.rooms + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_world.mob.rst b/docs/source/api/evennia.contrib.tutorial_world.mob.md similarity index 91% rename from docs/source/api/evennia.contrib.tutorial_world.mob.rst rename to docs/source/api/evennia.contrib.tutorial_world.mob.md index 582e0c73a9..1780dc3f8b 100644 --- a/docs/source/api/evennia.contrib.tutorial_world.mob.rst +++ b/docs/source/api/evennia.contrib.tutorial_world.mob.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_world.mob ========================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_world.mob :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_world.objects.rst b/docs/source/api/evennia.contrib.tutorial_world.objects.md similarity index 91% rename from docs/source/api/evennia.contrib.tutorial_world.objects.rst rename to docs/source/api/evennia.contrib.tutorial_world.objects.md index c06b56a556..7565805f52 100644 --- a/docs/source/api/evennia.contrib.tutorial_world.objects.rst +++ b/docs/source/api/evennia.contrib.tutorial_world.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_world.objects ============================================== @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_world.objects :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.tutorial_world.rooms.rst b/docs/source/api/evennia.contrib.tutorial_world.rooms.md similarity index 91% rename from docs/source/api/evennia.contrib.tutorial_world.rooms.rst rename to docs/source/api/evennia.contrib.tutorial_world.rooms.md index c229d89ab2..9dc28d3c58 100644 --- a/docs/source/api/evennia.contrib.tutorial_world.rooms.rst +++ b/docs/source/api/evennia.contrib.tutorial_world.rooms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.tutorial\_world.rooms ============================================ @@ -5,3 +6,5 @@ evennia.contrib.tutorial\_world.rooms :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.unixcommand.rst b/docs/source/api/evennia.contrib.unixcommand.md similarity index 90% rename from docs/source/api/evennia.contrib.unixcommand.rst rename to docs/source/api/evennia.contrib.unixcommand.md index ac6ddaff56..7cd2bdab3a 100644 --- a/docs/source/api/evennia.contrib.unixcommand.rst +++ b/docs/source/api/evennia.contrib.unixcommand.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.unixcommand ================================== @@ -5,3 +6,5 @@ evennia.contrib.unixcommand :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.wilderness.rst b/docs/source/api/evennia.contrib.wilderness.md similarity index 89% rename from docs/source/api/evennia.contrib.wilderness.rst rename to docs/source/api/evennia.contrib.wilderness.md index 03f01a3996..86f91a7e09 100644 --- a/docs/source/api/evennia.contrib.wilderness.rst +++ b/docs/source/api/evennia.contrib.wilderness.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.wilderness ================================= @@ -5,3 +6,5 @@ evennia.contrib.wilderness :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.commands.rst b/docs/source/api/evennia.contrib.xyzgrid.commands.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.commands.rst rename to docs/source/api/evennia.contrib.xyzgrid.commands.md index 57b7674a68..17024157c9 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.commands.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.commands.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.commands ======================================= @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.commands :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.example.rst b/docs/source/api/evennia.contrib.xyzgrid.example.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.example.rst rename to docs/source/api/evennia.contrib.xyzgrid.example.md index 10747ba83d..d8dde90b40 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.example.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.example.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.example ====================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.example :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.launchcmd.rst b/docs/source/api/evennia.contrib.xyzgrid.launchcmd.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.launchcmd.rst rename to docs/source/api/evennia.contrib.xyzgrid.launchcmd.md index fc973d6919..720a27963e 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.launchcmd.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.launchcmd.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.launchcmd ======================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.launchcmd :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.rst b/docs/source/api/evennia.contrib.xyzgrid.md similarity index 96% rename from docs/source/api/evennia.contrib.xyzgrid.rst rename to docs/source/api/evennia.contrib.xyzgrid.md index d70ed6bac5..91993133e9 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid =============================== @@ -21,3 +22,5 @@ evennia.contrib.xyzgrid evennia.contrib.xyzgrid.xymap_legend evennia.contrib.xyzgrid.xyzgrid evennia.contrib.xyzgrid.xyzroom + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.prototypes.rst b/docs/source/api/evennia.contrib.xyzgrid.prototypes.md similarity index 91% rename from docs/source/api/evennia.contrib.xyzgrid.prototypes.rst rename to docs/source/api/evennia.contrib.xyzgrid.prototypes.md index ab7a51e9e5..6cb097dfc0 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.prototypes.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.prototypes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.prototypes ========================================= @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.prototypes :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.tests.rst b/docs/source/api/evennia.contrib.xyzgrid.tests.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.tests.rst rename to docs/source/api/evennia.contrib.xyzgrid.tests.md index 59a50fae20..382cc88e68 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.tests.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.tests ==================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.utils.rst b/docs/source/api/evennia.contrib.xyzgrid.utils.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.utils.rst rename to docs/source/api/evennia.contrib.xyzgrid.utils.md index 433210f782..cacbf0b2ea 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.utils.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.utils ==================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.xymap.rst b/docs/source/api/evennia.contrib.xyzgrid.xymap.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.xymap.rst rename to docs/source/api/evennia.contrib.xyzgrid.xymap.md index ecb16f40f8..54f2d922bc 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.xymap.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.xymap.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.xymap ==================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.xymap :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.xymap_legend.rst b/docs/source/api/evennia.contrib.xyzgrid.xymap_legend.md similarity index 91% rename from docs/source/api/evennia.contrib.xyzgrid.xymap_legend.rst rename to docs/source/api/evennia.contrib.xyzgrid.xymap_legend.md index 0ace0ff162..340647af94 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.xymap_legend.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.xymap_legend.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.xymap\_legend ============================================ @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.xymap\_legend :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.xyzgrid.rst b/docs/source/api/evennia.contrib.xyzgrid.xyzgrid.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.xyzgrid.rst rename to docs/source/api/evennia.contrib.xyzgrid.xyzgrid.md index cfdfc8c5f4..caed6f4b32 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.xyzgrid.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.xyzgrid.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.xyzgrid ====================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.xyzgrid :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.contrib.xyzgrid.xyzroom.rst b/docs/source/api/evennia.contrib.xyzgrid.xyzroom.md similarity index 90% rename from docs/source/api/evennia.contrib.xyzgrid.xyzroom.rst rename to docs/source/api/evennia.contrib.xyzgrid.xyzroom.md index a74e882393..228882ca01 100644 --- a/docs/source/api/evennia.contrib.xyzgrid.xyzroom.rst +++ b/docs/source/api/evennia.contrib.xyzgrid.xyzroom.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.contrib.xyzgrid.xyzroom ====================================== @@ -5,3 +6,5 @@ evennia.contrib.xyzgrid.xyzroom :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.help.filehelp.rst b/docs/source/api/evennia.help.filehelp.md similarity index 88% rename from docs/source/api/evennia.help.filehelp.rst rename to docs/source/api/evennia.help.filehelp.md index 1947254237..bb518c0a20 100644 --- a/docs/source/api/evennia.help.filehelp.rst +++ b/docs/source/api/evennia.help.filehelp.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.help.filehelp ============================ @@ -5,3 +6,5 @@ evennia.help.filehelp :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.help.manager.rst b/docs/source/api/evennia.help.manager.md similarity index 88% rename from docs/source/api/evennia.help.manager.rst rename to docs/source/api/evennia.help.manager.md index b5a7c258e0..df99fbe2a4 100644 --- a/docs/source/api/evennia.help.manager.rst +++ b/docs/source/api/evennia.help.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.help.manager =========================== @@ -5,3 +6,5 @@ evennia.help.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.help.rst b/docs/source/api/evennia.help.md similarity index 93% rename from docs/source/api/evennia.help.rst rename to docs/source/api/evennia.help.md index fe2b792ea6..050e378e7d 100644 --- a/docs/source/api/evennia.help.rst +++ b/docs/source/api/evennia.help.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.help ==================== @@ -15,3 +16,5 @@ evennia.help evennia.help.manager evennia.help.models evennia.help.utils + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.help.models.rst b/docs/source/api/evennia.help.models.md similarity index 88% rename from docs/source/api/evennia.help.models.rst rename to docs/source/api/evennia.help.models.md index ae17110e65..8e7ba3d093 100644 --- a/docs/source/api/evennia.help.models.rst +++ b/docs/source/api/evennia.help.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.help.models ========================== @@ -5,3 +6,5 @@ evennia.help.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.help.utils.rst b/docs/source/api/evennia.help.utils.md similarity index 88% rename from docs/source/api/evennia.help.utils.rst rename to docs/source/api/evennia.help.utils.md index 74425cec91..82006ad1ae 100644 --- a/docs/source/api/evennia.help.utils.rst +++ b/docs/source/api/evennia.help.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.help.utils ========================= @@ -5,3 +6,5 @@ evennia.help.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.locks.lockfuncs.rst b/docs/source/api/evennia.locks.lockfuncs.md similarity index 89% rename from docs/source/api/evennia.locks.lockfuncs.rst rename to docs/source/api/evennia.locks.lockfuncs.md index b7afd6b666..3bf25f301d 100644 --- a/docs/source/api/evennia.locks.lockfuncs.rst +++ b/docs/source/api/evennia.locks.lockfuncs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.locks.lockfuncs ============================== @@ -5,3 +6,5 @@ evennia.locks.lockfuncs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.locks.lockhandler.rst b/docs/source/api/evennia.locks.lockhandler.md similarity index 89% rename from docs/source/api/evennia.locks.lockhandler.rst rename to docs/source/api/evennia.locks.lockhandler.md index 7b6b7312a8..97afd49eba 100644 --- a/docs/source/api/evennia.locks.lockhandler.rst +++ b/docs/source/api/evennia.locks.lockhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.locks.lockhandler ================================ @@ -5,3 +6,5 @@ evennia.locks.lockhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.locks.rst b/docs/source/api/evennia.locks.md similarity index 92% rename from docs/source/api/evennia.locks.rst rename to docs/source/api/evennia.locks.md index 5141ff2dd8..db4420cde7 100644 --- a/docs/source/api/evennia.locks.rst +++ b/docs/source/api/evennia.locks.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.locks ===================== @@ -13,3 +14,5 @@ evennia.locks evennia.locks.lockfuncs evennia.locks.lockhandler + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.rst b/docs/source/api/evennia.md similarity index 96% rename from docs/source/api/evennia.rst rename to docs/source/api/evennia.md index 73909713b5..d78ca609c8 100644 --- a/docs/source/api/evennia.rst +++ b/docs/source/api/evennia.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia =============== @@ -30,3 +31,5 @@ evennia evennia.typeclasses evennia.utils evennia.web + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.objects.manager.rst b/docs/source/api/evennia.objects.manager.md similarity index 89% rename from docs/source/api/evennia.objects.manager.rst rename to docs/source/api/evennia.objects.manager.md index 630f96ac16..5a4f69550c 100644 --- a/docs/source/api/evennia.objects.manager.rst +++ b/docs/source/api/evennia.objects.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.objects.manager ============================== @@ -5,3 +6,5 @@ evennia.objects.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.objects.rst b/docs/source/api/evennia.objects.md similarity index 93% rename from docs/source/api/evennia.objects.rst rename to docs/source/api/evennia.objects.md index b31bc08167..cf71109bb5 100644 --- a/docs/source/api/evennia.objects.rst +++ b/docs/source/api/evennia.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.objects ======================= @@ -14,3 +15,5 @@ evennia.objects evennia.objects.manager evennia.objects.models evennia.objects.objects + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.objects.models.rst b/docs/source/api/evennia.objects.models.md similarity index 89% rename from docs/source/api/evennia.objects.models.rst rename to docs/source/api/evennia.objects.models.md index e1e9ab3ba3..d1e3e06442 100644 --- a/docs/source/api/evennia.objects.models.rst +++ b/docs/source/api/evennia.objects.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.objects.models ============================= @@ -5,3 +6,5 @@ evennia.objects.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.objects.objects.rst b/docs/source/api/evennia.objects.objects.md similarity index 89% rename from docs/source/api/evennia.objects.objects.rst rename to docs/source/api/evennia.objects.objects.md index 8a4104feba..31ec2f75a8 100644 --- a/docs/source/api/evennia.objects.objects.rst +++ b/docs/source/api/evennia.objects.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.objects.objects ============================== @@ -5,3 +6,5 @@ evennia.objects.objects :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.prototypes.rst b/docs/source/api/evennia.prototypes.md similarity index 94% rename from docs/source/api/evennia.prototypes.rst rename to docs/source/api/evennia.prototypes.md index 6051fb58b5..6dc1a42462 100644 --- a/docs/source/api/evennia.prototypes.rst +++ b/docs/source/api/evennia.prototypes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.prototypes ========================== @@ -15,3 +16,5 @@ evennia.prototypes evennia.prototypes.protfuncs evennia.prototypes.prototypes evennia.prototypes.spawner + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.prototypes.menus.rst b/docs/source/api/evennia.prototypes.menus.md similarity index 89% rename from docs/source/api/evennia.prototypes.menus.rst rename to docs/source/api/evennia.prototypes.menus.md index 57750c87c1..6ce545f121 100644 --- a/docs/source/api/evennia.prototypes.menus.rst +++ b/docs/source/api/evennia.prototypes.menus.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.prototypes.menus =============================== @@ -5,3 +6,5 @@ evennia.prototypes.menus :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.prototypes.protfuncs.rst b/docs/source/api/evennia.prototypes.protfuncs.md similarity index 90% rename from docs/source/api/evennia.prototypes.protfuncs.rst rename to docs/source/api/evennia.prototypes.protfuncs.md index c4ba2440a8..e99e28c196 100644 --- a/docs/source/api/evennia.prototypes.protfuncs.rst +++ b/docs/source/api/evennia.prototypes.protfuncs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.prototypes.protfuncs =================================== @@ -5,3 +6,5 @@ evennia.prototypes.protfuncs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.prototypes.prototypes.rst b/docs/source/api/evennia.prototypes.prototypes.md similarity index 90% rename from docs/source/api/evennia.prototypes.prototypes.rst rename to docs/source/api/evennia.prototypes.prototypes.md index 49f1c4626b..0de5ed3630 100644 --- a/docs/source/api/evennia.prototypes.prototypes.rst +++ b/docs/source/api/evennia.prototypes.prototypes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.prototypes.prototypes ==================================== @@ -5,3 +6,5 @@ evennia.prototypes.prototypes :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.prototypes.spawner.rst b/docs/source/api/evennia.prototypes.spawner.md similarity index 89% rename from docs/source/api/evennia.prototypes.spawner.rst rename to docs/source/api/evennia.prototypes.spawner.md index 42b76f5acb..22cb8fe457 100644 --- a/docs/source/api/evennia.prototypes.spawner.rst +++ b/docs/source/api/evennia.prototypes.spawner.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.prototypes.spawner ================================= @@ -5,3 +6,5 @@ evennia.prototypes.spawner :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.manager.rst b/docs/source/api/evennia.scripts.manager.md similarity index 89% rename from docs/source/api/evennia.scripts.manager.rst rename to docs/source/api/evennia.scripts.manager.md index 724e6f63c8..6977deb554 100644 --- a/docs/source/api/evennia.scripts.manager.rst +++ b/docs/source/api/evennia.scripts.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.manager ============================== @@ -5,3 +6,5 @@ evennia.scripts.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.rst b/docs/source/api/evennia.scripts.md similarity index 95% rename from docs/source/api/evennia.scripts.rst rename to docs/source/api/evennia.scripts.md index 89c551ee98..6ea836f428 100644 --- a/docs/source/api/evennia.scripts.rst +++ b/docs/source/api/evennia.scripts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts ======================= @@ -18,3 +19,5 @@ evennia.scripts evennia.scripts.scripts evennia.scripts.taskhandler evennia.scripts.tickerhandler + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.models.rst b/docs/source/api/evennia.scripts.models.md similarity index 89% rename from docs/source/api/evennia.scripts.models.rst rename to docs/source/api/evennia.scripts.models.md index b7df7127e5..a3def52365 100644 --- a/docs/source/api/evennia.scripts.models.rst +++ b/docs/source/api/evennia.scripts.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.models ============================= @@ -5,3 +6,5 @@ evennia.scripts.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.monitorhandler.rst b/docs/source/api/evennia.scripts.monitorhandler.md similarity index 90% rename from docs/source/api/evennia.scripts.monitorhandler.rst rename to docs/source/api/evennia.scripts.monitorhandler.md index 8134d61860..fe89ead446 100644 --- a/docs/source/api/evennia.scripts.monitorhandler.rst +++ b/docs/source/api/evennia.scripts.monitorhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.monitorhandler ===================================== @@ -5,3 +6,5 @@ evennia.scripts.monitorhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.scripthandler.rst b/docs/source/api/evennia.scripts.scripthandler.md similarity index 90% rename from docs/source/api/evennia.scripts.scripthandler.rst rename to docs/source/api/evennia.scripts.scripthandler.md index f5847cfeff..7d07ea0b87 100644 --- a/docs/source/api/evennia.scripts.scripthandler.rst +++ b/docs/source/api/evennia.scripts.scripthandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.scripthandler ==================================== @@ -5,3 +6,5 @@ evennia.scripts.scripthandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.scripts.rst b/docs/source/api/evennia.scripts.scripts.md similarity index 89% rename from docs/source/api/evennia.scripts.scripts.rst rename to docs/source/api/evennia.scripts.scripts.md index 81e470a811..b0503240ba 100644 --- a/docs/source/api/evennia.scripts.scripts.rst +++ b/docs/source/api/evennia.scripts.scripts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.scripts ============================== @@ -5,3 +6,5 @@ evennia.scripts.scripts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.taskhandler.rst b/docs/source/api/evennia.scripts.taskhandler.md similarity index 90% rename from docs/source/api/evennia.scripts.taskhandler.rst rename to docs/source/api/evennia.scripts.taskhandler.md index afd858d97b..d95eee9fbb 100644 --- a/docs/source/api/evennia.scripts.taskhandler.rst +++ b/docs/source/api/evennia.scripts.taskhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.taskhandler ================================== @@ -5,3 +6,5 @@ evennia.scripts.taskhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.scripts.tickerhandler.rst b/docs/source/api/evennia.scripts.tickerhandler.md similarity index 90% rename from docs/source/api/evennia.scripts.tickerhandler.rst rename to docs/source/api/evennia.scripts.tickerhandler.md index 2489a6b500..fbc2f16b90 100644 --- a/docs/source/api/evennia.scripts.tickerhandler.rst +++ b/docs/source/api/evennia.scripts.tickerhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.scripts.tickerhandler ==================================== @@ -5,3 +6,5 @@ evennia.scripts.tickerhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.amp_client.rst b/docs/source/api/evennia.server.amp_client.md similarity index 89% rename from docs/source/api/evennia.server.amp_client.rst rename to docs/source/api/evennia.server.amp_client.md index 763a2d9018..d3772d958d 100644 --- a/docs/source/api/evennia.server.amp_client.rst +++ b/docs/source/api/evennia.server.amp_client.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.amp\_client ================================= @@ -5,3 +6,5 @@ evennia.server.amp\_client :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.connection_wizard.rst b/docs/source/api/evennia.server.connection_wizard.md similarity index 90% rename from docs/source/api/evennia.server.connection_wizard.rst rename to docs/source/api/evennia.server.connection_wizard.md index 96d614c9f0..65f85d3f94 100644 --- a/docs/source/api/evennia.server.connection_wizard.rst +++ b/docs/source/api/evennia.server.connection_wizard.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.connection\_wizard ======================================== @@ -5,3 +6,5 @@ evennia.server.connection\_wizard :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.deprecations.rst b/docs/source/api/evennia.server.deprecations.md similarity index 90% rename from docs/source/api/evennia.server.deprecations.rst rename to docs/source/api/evennia.server.deprecations.md index b5e535c387..f6f5b5dccd 100644 --- a/docs/source/api/evennia.server.deprecations.rst +++ b/docs/source/api/evennia.server.deprecations.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.deprecations ================================== @@ -5,3 +6,5 @@ evennia.server.deprecations :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.evennia_launcher.rst b/docs/source/api/evennia.server.evennia_launcher.md similarity index 90% rename from docs/source/api/evennia.server.evennia_launcher.rst rename to docs/source/api/evennia.server.evennia_launcher.md index 44f5481260..6865277b19 100644 --- a/docs/source/api/evennia.server.evennia_launcher.rst +++ b/docs/source/api/evennia.server.evennia_launcher.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.evennia\_launcher ======================================= @@ -5,3 +6,5 @@ evennia.server.evennia\_launcher :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.game_index_client.client.rst b/docs/source/api/evennia.server.game_index_client.client.md similarity index 91% rename from docs/source/api/evennia.server.game_index_client.client.rst rename to docs/source/api/evennia.server.game_index_client.client.md index 44b4ba8dac..1154de3143 100644 --- a/docs/source/api/evennia.server.game_index_client.client.rst +++ b/docs/source/api/evennia.server.game_index_client.client.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.game\_index\_client.client ================================================ @@ -5,3 +6,5 @@ evennia.server.game\_index\_client.client :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.game_index_client.rst b/docs/source/api/evennia.server.game_index_client.md similarity index 94% rename from docs/source/api/evennia.server.game_index_client.rst rename to docs/source/api/evennia.server.game_index_client.md index fd0ed5954d..1f3e011083 100644 --- a/docs/source/api/evennia.server.game_index_client.rst +++ b/docs/source/api/evennia.server.game_index_client.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.game\_index\_client ========================================== @@ -13,3 +14,5 @@ evennia.server.game\_index\_client evennia.server.game_index_client.client evennia.server.game_index_client.service + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.game_index_client.service.rst b/docs/source/api/evennia.server.game_index_client.service.md similarity index 91% rename from docs/source/api/evennia.server.game_index_client.service.rst rename to docs/source/api/evennia.server.game_index_client.service.md index f60df1f31e..96b1905d73 100644 --- a/docs/source/api/evennia.server.game_index_client.service.rst +++ b/docs/source/api/evennia.server.game_index_client.service.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.game\_index\_client.service ================================================= @@ -5,3 +6,5 @@ evennia.server.game\_index\_client.service :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.initial_setup.rst b/docs/source/api/evennia.server.initial_setup.md similarity index 90% rename from docs/source/api/evennia.server.initial_setup.rst rename to docs/source/api/evennia.server.initial_setup.md index c7f8d2d38c..65baae03ba 100644 --- a/docs/source/api/evennia.server.initial_setup.rst +++ b/docs/source/api/evennia.server.initial_setup.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.initial\_setup ==================================== @@ -5,3 +6,5 @@ evennia.server.initial\_setup :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.inputfuncs.rst b/docs/source/api/evennia.server.inputfuncs.md similarity index 89% rename from docs/source/api/evennia.server.inputfuncs.rst rename to docs/source/api/evennia.server.inputfuncs.md index cbdc1fdc03..6a422aebfe 100644 --- a/docs/source/api/evennia.server.inputfuncs.rst +++ b/docs/source/api/evennia.server.inputfuncs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.inputfuncs ================================ @@ -5,3 +6,5 @@ evennia.server.inputfuncs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.manager.rst b/docs/source/api/evennia.server.manager.md similarity index 89% rename from docs/source/api/evennia.server.manager.rst rename to docs/source/api/evennia.server.manager.md index 8e32f2999b..ce2a502be7 100644 --- a/docs/source/api/evennia.server.manager.rst +++ b/docs/source/api/evennia.server.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.manager ============================= @@ -5,3 +6,5 @@ evennia.server.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.rst b/docs/source/api/evennia.server.md similarity index 97% rename from docs/source/api/evennia.server.rst rename to docs/source/api/evennia.server.md index 2e95dfc084..5a8fc21fb4 100644 --- a/docs/source/api/evennia.server.rst +++ b/docs/source/api/evennia.server.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server ====================== @@ -35,3 +36,5 @@ evennia.server evennia.server.game_index_client evennia.server.portal evennia.server.profiling + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.models.rst b/docs/source/api/evennia.server.models.md similarity index 88% rename from docs/source/api/evennia.server.models.rst rename to docs/source/api/evennia.server.models.md index ca0707bb57..f466058916 100644 --- a/docs/source/api/evennia.server.models.rst +++ b/docs/source/api/evennia.server.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.models ============================ @@ -5,3 +6,5 @@ evennia.server.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.amp.rst b/docs/source/api/evennia.server.portal.amp.md similarity index 89% rename from docs/source/api/evennia.server.portal.amp.rst rename to docs/source/api/evennia.server.portal.amp.md index b59d7b2da9..66dda6f75b 100644 --- a/docs/source/api/evennia.server.portal.amp.rst +++ b/docs/source/api/evennia.server.portal.amp.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.amp ================================ @@ -5,3 +6,5 @@ evennia.server.portal.amp :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.amp_server.rst b/docs/source/api/evennia.server.portal.amp_server.md similarity index 90% rename from docs/source/api/evennia.server.portal.amp_server.rst rename to docs/source/api/evennia.server.portal.amp_server.md index c6a598cb63..042a3dfbae 100644 --- a/docs/source/api/evennia.server.portal.amp_server.rst +++ b/docs/source/api/evennia.server.portal.amp_server.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.amp\_server ======================================== @@ -5,3 +6,5 @@ evennia.server.portal.amp\_server :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.grapevine.rst b/docs/source/api/evennia.server.portal.grapevine.md similarity index 90% rename from docs/source/api/evennia.server.portal.grapevine.rst rename to docs/source/api/evennia.server.portal.grapevine.md index 6287761e2b..3f1b90c46b 100644 --- a/docs/source/api/evennia.server.portal.grapevine.rst +++ b/docs/source/api/evennia.server.portal.grapevine.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.grapevine ====================================== @@ -5,3 +6,5 @@ evennia.server.portal.grapevine :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.irc.rst b/docs/source/api/evennia.server.portal.irc.md similarity index 89% rename from docs/source/api/evennia.server.portal.irc.rst rename to docs/source/api/evennia.server.portal.irc.md index e15163e5ba..4fc3a271ee 100644 --- a/docs/source/api/evennia.server.portal.irc.rst +++ b/docs/source/api/evennia.server.portal.irc.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.irc ================================ @@ -5,3 +6,5 @@ evennia.server.portal.irc :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.mccp.rst b/docs/source/api/evennia.server.portal.mccp.md similarity index 89% rename from docs/source/api/evennia.server.portal.mccp.rst rename to docs/source/api/evennia.server.portal.mccp.md index 8f553bb148..34a5fa4c33 100644 --- a/docs/source/api/evennia.server.portal.mccp.rst +++ b/docs/source/api/evennia.server.portal.mccp.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.mccp ================================= @@ -5,3 +6,5 @@ evennia.server.portal.mccp :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.rst b/docs/source/api/evennia.server.portal.md similarity index 97% rename from docs/source/api/evennia.server.portal.rst rename to docs/source/api/evennia.server.portal.md index a0624dfd11..28004c1f15 100644 --- a/docs/source/api/evennia.server.portal.rst +++ b/docs/source/api/evennia.server.portal.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal ============================= @@ -32,3 +33,5 @@ evennia.server.portal evennia.server.portal.ttype evennia.server.portal.webclient evennia.server.portal.webclient_ajax + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.mssp.rst b/docs/source/api/evennia.server.portal.mssp.md similarity index 89% rename from docs/source/api/evennia.server.portal.mssp.rst rename to docs/source/api/evennia.server.portal.mssp.md index 5f252224fc..90a5998a8e 100644 --- a/docs/source/api/evennia.server.portal.mssp.rst +++ b/docs/source/api/evennia.server.portal.mssp.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.mssp ================================= @@ -5,3 +6,5 @@ evennia.server.portal.mssp :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.mxp.rst b/docs/source/api/evennia.server.portal.mxp.md similarity index 89% rename from docs/source/api/evennia.server.portal.mxp.rst rename to docs/source/api/evennia.server.portal.mxp.md index 7e313e75f5..77c4dd78a8 100644 --- a/docs/source/api/evennia.server.portal.mxp.rst +++ b/docs/source/api/evennia.server.portal.mxp.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.mxp ================================ @@ -5,3 +6,5 @@ evennia.server.portal.mxp :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.naws.rst b/docs/source/api/evennia.server.portal.naws.md similarity index 89% rename from docs/source/api/evennia.server.portal.naws.rst rename to docs/source/api/evennia.server.portal.naws.md index 171887ac80..11ead0319e 100644 --- a/docs/source/api/evennia.server.portal.naws.rst +++ b/docs/source/api/evennia.server.portal.naws.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.naws ================================= @@ -5,3 +6,5 @@ evennia.server.portal.naws :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.portal.rst b/docs/source/api/evennia.server.portal.portal.md similarity index 90% rename from docs/source/api/evennia.server.portal.portal.rst rename to docs/source/api/evennia.server.portal.portal.md index cefe2044c2..f388f9a206 100644 --- a/docs/source/api/evennia.server.portal.portal.rst +++ b/docs/source/api/evennia.server.portal.portal.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.portal =================================== @@ -5,3 +6,5 @@ evennia.server.portal.portal :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.portalsessionhandler.rst b/docs/source/api/evennia.server.portal.portalsessionhandler.md similarity index 92% rename from docs/source/api/evennia.server.portal.portalsessionhandler.rst rename to docs/source/api/evennia.server.portal.portalsessionhandler.md index aee1ee4291..60115e0654 100644 --- a/docs/source/api/evennia.server.portal.portalsessionhandler.rst +++ b/docs/source/api/evennia.server.portal.portalsessionhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.portalsessionhandler ================================================= @@ -5,3 +6,5 @@ evennia.server.portal.portalsessionhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.rss.rst b/docs/source/api/evennia.server.portal.rss.md similarity index 89% rename from docs/source/api/evennia.server.portal.rss.rst rename to docs/source/api/evennia.server.portal.rss.md index 8c315fff1f..7ec2f823df 100644 --- a/docs/source/api/evennia.server.portal.rss.rst +++ b/docs/source/api/evennia.server.portal.rss.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.rss ================================ @@ -5,3 +6,5 @@ evennia.server.portal.rss :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.ssh.rst b/docs/source/api/evennia.server.portal.ssh.md similarity index 89% rename from docs/source/api/evennia.server.portal.ssh.rst rename to docs/source/api/evennia.server.portal.ssh.md index 81be6edfe2..01166252ad 100644 --- a/docs/source/api/evennia.server.portal.ssh.rst +++ b/docs/source/api/evennia.server.portal.ssh.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.ssh ================================ @@ -5,3 +6,5 @@ evennia.server.portal.ssh :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.ssl.rst b/docs/source/api/evennia.server.portal.ssl.md similarity index 89% rename from docs/source/api/evennia.server.portal.ssl.rst rename to docs/source/api/evennia.server.portal.ssl.md index 40d8e43c50..7097147982 100644 --- a/docs/source/api/evennia.server.portal.ssl.rst +++ b/docs/source/api/evennia.server.portal.ssl.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.ssl ================================ @@ -5,3 +6,5 @@ evennia.server.portal.ssl :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.suppress_ga.rst b/docs/source/api/evennia.server.portal.suppress_ga.md similarity index 91% rename from docs/source/api/evennia.server.portal.suppress_ga.rst rename to docs/source/api/evennia.server.portal.suppress_ga.md index 995605401e..168273b06a 100644 --- a/docs/source/api/evennia.server.portal.suppress_ga.rst +++ b/docs/source/api/evennia.server.portal.suppress_ga.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.suppress\_ga ========================================= @@ -5,3 +6,5 @@ evennia.server.portal.suppress\_ga :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.telnet.rst b/docs/source/api/evennia.server.portal.telnet.md similarity index 90% rename from docs/source/api/evennia.server.portal.telnet.rst rename to docs/source/api/evennia.server.portal.telnet.md index e0907d6adf..a7ed8cadea 100644 --- a/docs/source/api/evennia.server.portal.telnet.rst +++ b/docs/source/api/evennia.server.portal.telnet.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.telnet =================================== @@ -5,3 +6,5 @@ evennia.server.portal.telnet :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.telnet_oob.rst b/docs/source/api/evennia.server.portal.telnet_oob.md similarity index 90% rename from docs/source/api/evennia.server.portal.telnet_oob.rst rename to docs/source/api/evennia.server.portal.telnet_oob.md index e022fdc155..3bea639e5d 100644 --- a/docs/source/api/evennia.server.portal.telnet_oob.rst +++ b/docs/source/api/evennia.server.portal.telnet_oob.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.telnet\_oob ======================================== @@ -5,3 +6,5 @@ evennia.server.portal.telnet\_oob :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.telnet_ssl.rst b/docs/source/api/evennia.server.portal.telnet_ssl.md similarity index 90% rename from docs/source/api/evennia.server.portal.telnet_ssl.rst rename to docs/source/api/evennia.server.portal.telnet_ssl.md index e7d0793c63..02114e5754 100644 --- a/docs/source/api/evennia.server.portal.telnet_ssl.rst +++ b/docs/source/api/evennia.server.portal.telnet_ssl.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.telnet\_ssl ======================================== @@ -5,3 +6,5 @@ evennia.server.portal.telnet\_ssl :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.tests.rst b/docs/source/api/evennia.server.portal.tests.md similarity index 90% rename from docs/source/api/evennia.server.portal.tests.rst rename to docs/source/api/evennia.server.portal.tests.md index a614af7899..ff5b4db715 100644 --- a/docs/source/api/evennia.server.portal.tests.rst +++ b/docs/source/api/evennia.server.portal.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.tests ================================== @@ -5,3 +6,5 @@ evennia.server.portal.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.ttype.rst b/docs/source/api/evennia.server.portal.ttype.md similarity index 90% rename from docs/source/api/evennia.server.portal.ttype.rst rename to docs/source/api/evennia.server.portal.ttype.md index e3b9194f09..732143b7c5 100644 --- a/docs/source/api/evennia.server.portal.ttype.rst +++ b/docs/source/api/evennia.server.portal.ttype.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.ttype ================================== @@ -5,3 +6,5 @@ evennia.server.portal.ttype :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.webclient.rst b/docs/source/api/evennia.server.portal.webclient.md similarity index 90% rename from docs/source/api/evennia.server.portal.webclient.rst rename to docs/source/api/evennia.server.portal.webclient.md index 8094e933c1..2335ea43f0 100644 --- a/docs/source/api/evennia.server.portal.webclient.rst +++ b/docs/source/api/evennia.server.portal.webclient.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.webclient ====================================== @@ -5,3 +6,5 @@ evennia.server.portal.webclient :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.portal.webclient_ajax.rst b/docs/source/api/evennia.server.portal.webclient_ajax.md similarity index 91% rename from docs/source/api/evennia.server.portal.webclient_ajax.rst rename to docs/source/api/evennia.server.portal.webclient_ajax.md index 0b1dc79d7f..d867edacbe 100644 --- a/docs/source/api/evennia.server.portal.webclient_ajax.rst +++ b/docs/source/api/evennia.server.portal.webclient_ajax.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.portal.webclient\_ajax ============================================ @@ -5,3 +6,5 @@ evennia.server.portal.webclient\_ajax :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.dummyrunner.rst b/docs/source/api/evennia.server.profiling.dummyrunner.md similarity index 91% rename from docs/source/api/evennia.server.profiling.dummyrunner.rst rename to docs/source/api/evennia.server.profiling.dummyrunner.md index e94afaa250..a1283aa0ee 100644 --- a/docs/source/api/evennia.server.profiling.dummyrunner.rst +++ b/docs/source/api/evennia.server.profiling.dummyrunner.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.dummyrunner =========================================== @@ -5,3 +6,5 @@ evennia.server.profiling.dummyrunner :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.dummyrunner_settings.rst b/docs/source/api/evennia.server.profiling.dummyrunner_settings.md similarity index 92% rename from docs/source/api/evennia.server.profiling.dummyrunner_settings.rst rename to docs/source/api/evennia.server.profiling.dummyrunner_settings.md index 76e6c0d337..1d6b07ffbe 100644 --- a/docs/source/api/evennia.server.profiling.dummyrunner_settings.rst +++ b/docs/source/api/evennia.server.profiling.dummyrunner_settings.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.dummyrunner\_settings ===================================================== @@ -5,3 +6,5 @@ evennia.server.profiling.dummyrunner\_settings :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.rst b/docs/source/api/evennia.server.profiling.md similarity index 96% rename from docs/source/api/evennia.server.profiling.rst rename to docs/source/api/evennia.server.profiling.md index 7e943d258a..5a7abe64f3 100644 --- a/docs/source/api/evennia.server.profiling.rst +++ b/docs/source/api/evennia.server.profiling.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling ================================ @@ -18,3 +19,5 @@ evennia.server.profiling evennia.server.profiling.test_queries evennia.server.profiling.tests evennia.server.profiling.timetrace + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.memplot.rst b/docs/source/api/evennia.server.profiling.memplot.md similarity index 90% rename from docs/source/api/evennia.server.profiling.memplot.rst rename to docs/source/api/evennia.server.profiling.memplot.md index 76aa3a695b..a3193c3b6d 100644 --- a/docs/source/api/evennia.server.profiling.memplot.rst +++ b/docs/source/api/evennia.server.profiling.memplot.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.memplot ======================================= @@ -5,3 +6,5 @@ evennia.server.profiling.memplot :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.settings_mixin.rst b/docs/source/api/evennia.server.profiling.settings_mixin.md similarity index 91% rename from docs/source/api/evennia.server.profiling.settings_mixin.rst rename to docs/source/api/evennia.server.profiling.settings_mixin.md index a1ad9e2c7f..e96c1c07a0 100644 --- a/docs/source/api/evennia.server.profiling.settings_mixin.rst +++ b/docs/source/api/evennia.server.profiling.settings_mixin.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.settings\_mixin =============================================== @@ -5,3 +6,5 @@ evennia.server.profiling.settings\_mixin :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.test_queries.rst b/docs/source/api/evennia.server.profiling.test_queries.md similarity index 91% rename from docs/source/api/evennia.server.profiling.test_queries.rst rename to docs/source/api/evennia.server.profiling.test_queries.md index eb741b38c2..19f5e1614e 100644 --- a/docs/source/api/evennia.server.profiling.test_queries.rst +++ b/docs/source/api/evennia.server.profiling.test_queries.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.test\_queries ============================================= @@ -5,3 +6,5 @@ evennia.server.profiling.test\_queries :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.tests.rst b/docs/source/api/evennia.server.profiling.tests.md similarity index 90% rename from docs/source/api/evennia.server.profiling.tests.rst rename to docs/source/api/evennia.server.profiling.tests.md index 7aa7dfe7b6..a8535a082c 100644 --- a/docs/source/api/evennia.server.profiling.tests.rst +++ b/docs/source/api/evennia.server.profiling.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.tests ===================================== @@ -5,3 +6,5 @@ evennia.server.profiling.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.profiling.timetrace.rst b/docs/source/api/evennia.server.profiling.timetrace.md similarity index 91% rename from docs/source/api/evennia.server.profiling.timetrace.rst rename to docs/source/api/evennia.server.profiling.timetrace.md index b6f2be3640..d01ca1839c 100644 --- a/docs/source/api/evennia.server.profiling.timetrace.rst +++ b/docs/source/api/evennia.server.profiling.timetrace.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.profiling.timetrace ========================================= @@ -5,3 +6,5 @@ evennia.server.profiling.timetrace :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.server.rst b/docs/source/api/evennia.server.server.md similarity index 88% rename from docs/source/api/evennia.server.server.rst rename to docs/source/api/evennia.server.server.md index b91f32f316..6bdc50a34c 100644 --- a/docs/source/api/evennia.server.server.rst +++ b/docs/source/api/evennia.server.server.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.server ============================ @@ -5,3 +6,5 @@ evennia.server.server :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.serversession.rst b/docs/source/api/evennia.server.serversession.md similarity index 90% rename from docs/source/api/evennia.server.serversession.rst rename to docs/source/api/evennia.server.serversession.md index 88ea4c1d91..482d6a8792 100644 --- a/docs/source/api/evennia.server.serversession.rst +++ b/docs/source/api/evennia.server.serversession.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.serversession =================================== @@ -5,3 +6,5 @@ evennia.server.serversession :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.session.rst b/docs/source/api/evennia.server.session.md similarity index 89% rename from docs/source/api/evennia.server.session.rst rename to docs/source/api/evennia.server.session.md index af1796466d..b2dadbf11a 100644 --- a/docs/source/api/evennia.server.session.rst +++ b/docs/source/api/evennia.server.session.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.session ============================= @@ -5,3 +6,5 @@ evennia.server.session :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.sessionhandler.rst b/docs/source/api/evennia.server.sessionhandler.md similarity index 90% rename from docs/source/api/evennia.server.sessionhandler.rst rename to docs/source/api/evennia.server.sessionhandler.md index 47e62524bd..d4e610ccdd 100644 --- a/docs/source/api/evennia.server.sessionhandler.rst +++ b/docs/source/api/evennia.server.sessionhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.sessionhandler ==================================== @@ -5,3 +6,5 @@ evennia.server.sessionhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.signals.rst b/docs/source/api/evennia.server.signals.md similarity index 89% rename from docs/source/api/evennia.server.signals.rst rename to docs/source/api/evennia.server.signals.md index 00cae2d4cf..95e2ecd822 100644 --- a/docs/source/api/evennia.server.signals.rst +++ b/docs/source/api/evennia.server.signals.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.signals ============================= @@ -5,3 +6,5 @@ evennia.server.signals :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.throttle.rst b/docs/source/api/evennia.server.throttle.md similarity index 89% rename from docs/source/api/evennia.server.throttle.rst rename to docs/source/api/evennia.server.throttle.md index 6d3ccdd516..fa7576f012 100644 --- a/docs/source/api/evennia.server.throttle.rst +++ b/docs/source/api/evennia.server.throttle.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.throttle ============================== @@ -5,3 +6,5 @@ evennia.server.throttle :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.validators.rst b/docs/source/api/evennia.server.validators.md similarity index 89% rename from docs/source/api/evennia.server.validators.rst rename to docs/source/api/evennia.server.validators.md index defe37284f..7f452b197b 100644 --- a/docs/source/api/evennia.server.validators.rst +++ b/docs/source/api/evennia.server.validators.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.validators ================================ @@ -5,3 +6,5 @@ evennia.server.validators :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.server.webserver.rst b/docs/source/api/evennia.server.webserver.md similarity index 89% rename from docs/source/api/evennia.server.webserver.rst rename to docs/source/api/evennia.server.webserver.md index 0ff51e3aa7..7392273cc9 100644 --- a/docs/source/api/evennia.server.webserver.rst +++ b/docs/source/api/evennia.server.webserver.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.server.webserver =============================== @@ -5,3 +6,5 @@ evennia.server.webserver :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.settings_default.rst b/docs/source/api/evennia.settings_default.md similarity index 89% rename from docs/source/api/evennia.settings_default.rst rename to docs/source/api/evennia.settings_default.md index 957d582a6f..9f05e4ff62 100644 --- a/docs/source/api/evennia.settings_default.rst +++ b/docs/source/api/evennia.settings_default.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.settings\_default ================================ @@ -5,3 +6,5 @@ evennia.settings\_default :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.typeclasses.attributes.rst b/docs/source/api/evennia.typeclasses.attributes.md similarity index 90% rename from docs/source/api/evennia.typeclasses.attributes.rst rename to docs/source/api/evennia.typeclasses.attributes.md index 35cc09605f..bf1918d417 100644 --- a/docs/source/api/evennia.typeclasses.attributes.rst +++ b/docs/source/api/evennia.typeclasses.attributes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.typeclasses.attributes ===================================== @@ -5,3 +6,5 @@ evennia.typeclasses.attributes :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.typeclasses.managers.rst b/docs/source/api/evennia.typeclasses.managers.md similarity index 90% rename from docs/source/api/evennia.typeclasses.managers.rst rename to docs/source/api/evennia.typeclasses.managers.md index 0aa284fa34..d543efb458 100644 --- a/docs/source/api/evennia.typeclasses.managers.rst +++ b/docs/source/api/evennia.typeclasses.managers.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.typeclasses.managers =================================== @@ -5,3 +6,5 @@ evennia.typeclasses.managers :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.typeclasses.rst b/docs/source/api/evennia.typeclasses.md similarity index 94% rename from docs/source/api/evennia.typeclasses.rst rename to docs/source/api/evennia.typeclasses.md index 875b1491ab..27dc7ac2aa 100644 --- a/docs/source/api/evennia.typeclasses.rst +++ b/docs/source/api/evennia.typeclasses.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.typeclasses =========================== @@ -15,3 +16,5 @@ evennia.typeclasses evennia.typeclasses.managers evennia.typeclasses.models evennia.typeclasses.tags + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.typeclasses.models.rst b/docs/source/api/evennia.typeclasses.models.md similarity index 89% rename from docs/source/api/evennia.typeclasses.models.rst rename to docs/source/api/evennia.typeclasses.models.md index cf953234aa..d672e4b1a3 100644 --- a/docs/source/api/evennia.typeclasses.models.rst +++ b/docs/source/api/evennia.typeclasses.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.typeclasses.models ================================= @@ -5,3 +6,5 @@ evennia.typeclasses.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.typeclasses.tags.rst b/docs/source/api/evennia.typeclasses.tags.md similarity index 89% rename from docs/source/api/evennia.typeclasses.tags.rst rename to docs/source/api/evennia.typeclasses.tags.md index b06a17c992..3444b4eb9d 100644 --- a/docs/source/api/evennia.typeclasses.tags.rst +++ b/docs/source/api/evennia.typeclasses.tags.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.typeclasses.tags =============================== @@ -5,3 +6,5 @@ evennia.typeclasses.tags :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.ansi.rst b/docs/source/api/evennia.utils.ansi.md similarity index 88% rename from docs/source/api/evennia.utils.ansi.rst rename to docs/source/api/evennia.utils.ansi.md index afcff5068e..062fe2aeda 100644 --- a/docs/source/api/evennia.utils.ansi.rst +++ b/docs/source/api/evennia.utils.ansi.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.ansi ========================= @@ -5,3 +6,5 @@ evennia.utils.ansi :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.batchprocessors.rst b/docs/source/api/evennia.utils.batchprocessors.md similarity index 90% rename from docs/source/api/evennia.utils.batchprocessors.rst rename to docs/source/api/evennia.utils.batchprocessors.md index d57178f06f..2c6e191196 100644 --- a/docs/source/api/evennia.utils.batchprocessors.rst +++ b/docs/source/api/evennia.utils.batchprocessors.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.batchprocessors ==================================== @@ -5,3 +6,5 @@ evennia.utils.batchprocessors :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.containers.rst b/docs/source/api/evennia.utils.containers.md similarity index 89% rename from docs/source/api/evennia.utils.containers.rst rename to docs/source/api/evennia.utils.containers.md index afb8d3be8e..e8a82b25c3 100644 --- a/docs/source/api/evennia.utils.containers.rst +++ b/docs/source/api/evennia.utils.containers.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.containers =============================== @@ -5,3 +6,5 @@ evennia.utils.containers :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.create.rst b/docs/source/api/evennia.utils.create.md similarity index 88% rename from docs/source/api/evennia.utils.create.rst rename to docs/source/api/evennia.utils.create.md index 82155c6a1f..d215c94b1c 100644 --- a/docs/source/api/evennia.utils.create.rst +++ b/docs/source/api/evennia.utils.create.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.create =========================== @@ -5,3 +6,5 @@ evennia.utils.create :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.dbserialize.rst b/docs/source/api/evennia.utils.dbserialize.md similarity index 89% rename from docs/source/api/evennia.utils.dbserialize.rst rename to docs/source/api/evennia.utils.dbserialize.md index 1e1252833d..acfdc0c40c 100644 --- a/docs/source/api/evennia.utils.dbserialize.rst +++ b/docs/source/api/evennia.utils.dbserialize.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.dbserialize ================================ @@ -5,3 +6,5 @@ evennia.utils.dbserialize :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.eveditor.rst b/docs/source/api/evennia.utils.eveditor.md similarity index 89% rename from docs/source/api/evennia.utils.eveditor.rst rename to docs/source/api/evennia.utils.eveditor.md index 8786ac7cb4..7c5cde467c 100644 --- a/docs/source/api/evennia.utils.eveditor.rst +++ b/docs/source/api/evennia.utils.eveditor.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.eveditor ============================= @@ -5,3 +6,5 @@ evennia.utils.eveditor :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.evform.rst b/docs/source/api/evennia.utils.evform.md similarity index 88% rename from docs/source/api/evennia.utils.evform.rst rename to docs/source/api/evennia.utils.evform.md index d64f6d53c0..8f0126886b 100644 --- a/docs/source/api/evennia.utils.evform.rst +++ b/docs/source/api/evennia.utils.evform.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.evform =========================== @@ -5,3 +6,5 @@ evennia.utils.evform :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.evmenu.rst b/docs/source/api/evennia.utils.evmenu.md similarity index 88% rename from docs/source/api/evennia.utils.evmenu.rst rename to docs/source/api/evennia.utils.evmenu.md index fb39ca682e..8b545b5b3f 100644 --- a/docs/source/api/evennia.utils.evmenu.rst +++ b/docs/source/api/evennia.utils.evmenu.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.evmenu =========================== @@ -5,3 +6,5 @@ evennia.utils.evmenu :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.evmore.rst b/docs/source/api/evennia.utils.evmore.md similarity index 88% rename from docs/source/api/evennia.utils.evmore.rst rename to docs/source/api/evennia.utils.evmore.md index 3c7b5ce0cf..1f30b04453 100644 --- a/docs/source/api/evennia.utils.evmore.rst +++ b/docs/source/api/evennia.utils.evmore.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.evmore =========================== @@ -5,3 +6,5 @@ evennia.utils.evmore :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.evtable.rst b/docs/source/api/evennia.utils.evtable.md similarity index 88% rename from docs/source/api/evennia.utils.evtable.rst rename to docs/source/api/evennia.utils.evtable.md index c9bc29d19c..28fe18bc76 100644 --- a/docs/source/api/evennia.utils.evtable.rst +++ b/docs/source/api/evennia.utils.evtable.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.evtable ============================ @@ -5,3 +6,5 @@ evennia.utils.evtable :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.funcparser.rst b/docs/source/api/evennia.utils.funcparser.md similarity index 89% rename from docs/source/api/evennia.utils.funcparser.rst rename to docs/source/api/evennia.utils.funcparser.md index 151811e406..2f27f96630 100644 --- a/docs/source/api/evennia.utils.funcparser.rst +++ b/docs/source/api/evennia.utils.funcparser.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.funcparser =============================== @@ -5,3 +6,5 @@ evennia.utils.funcparser :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.gametime.rst b/docs/source/api/evennia.utils.gametime.md similarity index 89% rename from docs/source/api/evennia.utils.gametime.rst rename to docs/source/api/evennia.utils.gametime.md index 2dc576077f..b48f32923e 100644 --- a/docs/source/api/evennia.utils.gametime.rst +++ b/docs/source/api/evennia.utils.gametime.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.gametime ============================= @@ -5,3 +6,5 @@ evennia.utils.gametime :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.idmapper.manager.rst b/docs/source/api/evennia.utils.idmapper.manager.md similarity index 90% rename from docs/source/api/evennia.utils.idmapper.manager.rst rename to docs/source/api/evennia.utils.idmapper.manager.md index d06168459f..245ad5a650 100644 --- a/docs/source/api/evennia.utils.idmapper.manager.rst +++ b/docs/source/api/evennia.utils.idmapper.manager.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.idmapper.manager ===================================== @@ -5,3 +6,5 @@ evennia.utils.idmapper.manager :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.idmapper.rst b/docs/source/api/evennia.utils.idmapper.md similarity index 93% rename from docs/source/api/evennia.utils.idmapper.rst rename to docs/source/api/evennia.utils.idmapper.md index d8b39a8184..77632cba58 100644 --- a/docs/source/api/evennia.utils.idmapper.rst +++ b/docs/source/api/evennia.utils.idmapper.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.idmapper ============================== @@ -14,3 +15,5 @@ evennia.utils.idmapper evennia.utils.idmapper.manager evennia.utils.idmapper.models evennia.utils.idmapper.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.idmapper.models.rst b/docs/source/api/evennia.utils.idmapper.models.md similarity index 90% rename from docs/source/api/evennia.utils.idmapper.models.rst rename to docs/source/api/evennia.utils.idmapper.models.md index 4859c68678..2763cc8c97 100644 --- a/docs/source/api/evennia.utils.idmapper.models.rst +++ b/docs/source/api/evennia.utils.idmapper.models.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.idmapper.models ==================================== @@ -5,3 +6,5 @@ evennia.utils.idmapper.models :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.idmapper.tests.rst b/docs/source/api/evennia.utils.idmapper.tests.md similarity index 90% rename from docs/source/api/evennia.utils.idmapper.tests.rst rename to docs/source/api/evennia.utils.idmapper.tests.md index f74a28e5df..9a2b694044 100644 --- a/docs/source/api/evennia.utils.idmapper.tests.rst +++ b/docs/source/api/evennia.utils.idmapper.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.idmapper.tests =================================== @@ -5,3 +6,5 @@ evennia.utils.idmapper.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.logger.rst b/docs/source/api/evennia.utils.logger.md similarity index 88% rename from docs/source/api/evennia.utils.logger.rst rename to docs/source/api/evennia.utils.logger.md index 06300bb978..409bb8855a 100644 --- a/docs/source/api/evennia.utils.logger.rst +++ b/docs/source/api/evennia.utils.logger.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.logger =========================== @@ -5,3 +6,5 @@ evennia.utils.logger :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.rst b/docs/source/api/evennia.utils.md similarity index 97% rename from docs/source/api/evennia.utils.rst rename to docs/source/api/evennia.utils.md index 32653d5c5f..fb5b98c44a 100644 --- a/docs/source/api/evennia.utils.rst +++ b/docs/source/api/evennia.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils ===================== @@ -39,3 +40,5 @@ evennia.utils evennia.utils.idmapper evennia.utils.verb_conjugation + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.optionclasses.rst b/docs/source/api/evennia.utils.optionclasses.md similarity index 90% rename from docs/source/api/evennia.utils.optionclasses.rst rename to docs/source/api/evennia.utils.optionclasses.md index 69a2656b51..8d56178cf5 100644 --- a/docs/source/api/evennia.utils.optionclasses.rst +++ b/docs/source/api/evennia.utils.optionclasses.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.optionclasses ================================== @@ -5,3 +6,5 @@ evennia.utils.optionclasses :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.optionhandler.rst b/docs/source/api/evennia.utils.optionhandler.md similarity index 90% rename from docs/source/api/evennia.utils.optionhandler.rst rename to docs/source/api/evennia.utils.optionhandler.md index a20707622f..184dfc9727 100644 --- a/docs/source/api/evennia.utils.optionhandler.rst +++ b/docs/source/api/evennia.utils.optionhandler.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.optionhandler ================================== @@ -5,3 +6,5 @@ evennia.utils.optionhandler :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.picklefield.rst b/docs/source/api/evennia.utils.picklefield.md similarity index 89% rename from docs/source/api/evennia.utils.picklefield.rst rename to docs/source/api/evennia.utils.picklefield.md index e01f222211..a9e7076ffb 100644 --- a/docs/source/api/evennia.utils.picklefield.rst +++ b/docs/source/api/evennia.utils.picklefield.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.picklefield ================================ @@ -5,3 +6,5 @@ evennia.utils.picklefield :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.search.rst b/docs/source/api/evennia.utils.search.md similarity index 88% rename from docs/source/api/evennia.utils.search.rst rename to docs/source/api/evennia.utils.search.md index 6386e9f9c4..e77e4731e4 100644 --- a/docs/source/api/evennia.utils.search.rst +++ b/docs/source/api/evennia.utils.search.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.search =========================== @@ -5,3 +6,5 @@ evennia.utils.search :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.test_resources.rst b/docs/source/api/evennia.utils.test_resources.md similarity index 90% rename from docs/source/api/evennia.utils.test_resources.rst rename to docs/source/api/evennia.utils.test_resources.md index 21fff53743..2e03998529 100644 --- a/docs/source/api/evennia.utils.test_resources.rst +++ b/docs/source/api/evennia.utils.test_resources.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.test\_resources ==================================== @@ -5,3 +6,5 @@ evennia.utils.test\_resources :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.text2html.rst b/docs/source/api/evennia.utils.text2html.md similarity index 89% rename from docs/source/api/evennia.utils.text2html.rst rename to docs/source/api/evennia.utils.text2html.md index 07ea0382e2..d205282f96 100644 --- a/docs/source/api/evennia.utils.text2html.rst +++ b/docs/source/api/evennia.utils.text2html.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.text2html ============================== @@ -5,3 +6,5 @@ evennia.utils.text2html :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.utils.rst b/docs/source/api/evennia.utils.utils.md similarity index 88% rename from docs/source/api/evennia.utils.utils.rst rename to docs/source/api/evennia.utils.utils.md index 468fb50711..85c523395d 100644 --- a/docs/source/api/evennia.utils.utils.rst +++ b/docs/source/api/evennia.utils.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.utils ========================== @@ -5,3 +6,5 @@ evennia.utils.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.validatorfuncs.rst b/docs/source/api/evennia.utils.validatorfuncs.md similarity index 90% rename from docs/source/api/evennia.utils.validatorfuncs.rst rename to docs/source/api/evennia.utils.validatorfuncs.md index e2781cb83f..06ee8ff4ec 100644 --- a/docs/source/api/evennia.utils.validatorfuncs.rst +++ b/docs/source/api/evennia.utils.validatorfuncs.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.validatorfuncs =================================== @@ -5,3 +6,5 @@ evennia.utils.validatorfuncs :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.verb_conjugation.conjugate.rst b/docs/source/api/evennia.utils.verb_conjugation.conjugate.md similarity index 91% rename from docs/source/api/evennia.utils.verb_conjugation.conjugate.rst rename to docs/source/api/evennia.utils.verb_conjugation.conjugate.md index 5f60d2e589..a0979cc5c3 100644 --- a/docs/source/api/evennia.utils.verb_conjugation.conjugate.rst +++ b/docs/source/api/evennia.utils.verb_conjugation.conjugate.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.verb\_conjugation.conjugate ================================================ @@ -5,3 +6,5 @@ evennia.utils.verb\_conjugation.conjugate :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.verb_conjugation.rst b/docs/source/api/evennia.utils.verb_conjugation.md similarity index 94% rename from docs/source/api/evennia.utils.verb_conjugation.rst rename to docs/source/api/evennia.utils.verb_conjugation.md index ab6df6f377..a3359e1408 100644 --- a/docs/source/api/evennia.utils.verb_conjugation.rst +++ b/docs/source/api/evennia.utils.verb_conjugation.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.verb\_conjugation ======================================= @@ -13,3 +14,5 @@ evennia.utils.verb\_conjugation evennia.utils.verb_conjugation.conjugate evennia.utils.verb_conjugation.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.utils.verb_conjugation.tests.rst b/docs/source/api/evennia.utils.verb_conjugation.tests.md similarity index 91% rename from docs/source/api/evennia.utils.verb_conjugation.tests.rst rename to docs/source/api/evennia.utils.verb_conjugation.tests.md index a61eb6e472..6a14f99793 100644 --- a/docs/source/api/evennia.utils.verb_conjugation.tests.rst +++ b/docs/source/api/evennia.utils.verb_conjugation.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.utils.verb\_conjugation.tests ============================================ @@ -5,3 +6,5 @@ evennia.utils.verb\_conjugation.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.accounts.rst b/docs/source/api/evennia.web.admin.accounts.md similarity index 89% rename from docs/source/api/evennia.web.admin.accounts.rst rename to docs/source/api/evennia.web.admin.accounts.md index 39a64ce74c..270bbe9a95 100644 --- a/docs/source/api/evennia.web.admin.accounts.rst +++ b/docs/source/api/evennia.web.admin.accounts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.accounts ================================= @@ -5,3 +6,5 @@ evennia.web.admin.accounts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.attributes.rst b/docs/source/api/evennia.web.admin.attributes.md similarity index 90% rename from docs/source/api/evennia.web.admin.attributes.rst rename to docs/source/api/evennia.web.admin.attributes.md index a633f3ed5a..111ae372f5 100644 --- a/docs/source/api/evennia.web.admin.attributes.rst +++ b/docs/source/api/evennia.web.admin.attributes.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.attributes =================================== @@ -5,3 +6,5 @@ evennia.web.admin.attributes :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.comms.rst b/docs/source/api/evennia.web.admin.comms.md similarity index 89% rename from docs/source/api/evennia.web.admin.comms.rst rename to docs/source/api/evennia.web.admin.comms.md index 432abaa402..377a493791 100644 --- a/docs/source/api/evennia.web.admin.comms.rst +++ b/docs/source/api/evennia.web.admin.comms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.comms ============================== @@ -5,3 +6,5 @@ evennia.web.admin.comms :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.frontpage.rst b/docs/source/api/evennia.web.admin.frontpage.md similarity index 90% rename from docs/source/api/evennia.web.admin.frontpage.rst rename to docs/source/api/evennia.web.admin.frontpage.md index 032c948c42..e3a4c9487b 100644 --- a/docs/source/api/evennia.web.admin.frontpage.rst +++ b/docs/source/api/evennia.web.admin.frontpage.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.frontpage ================================== @@ -5,3 +6,5 @@ evennia.web.admin.frontpage :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.help.rst b/docs/source/api/evennia.web.admin.help.md similarity index 89% rename from docs/source/api/evennia.web.admin.help.rst rename to docs/source/api/evennia.web.admin.help.md index 87b2f22c2f..45ca5db160 100644 --- a/docs/source/api/evennia.web.admin.help.rst +++ b/docs/source/api/evennia.web.admin.help.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.help ============================= @@ -5,3 +6,5 @@ evennia.web.admin.help :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.rst b/docs/source/api/evennia.web.admin.md similarity index 96% rename from docs/source/api/evennia.web.admin.rst rename to docs/source/api/evennia.web.admin.md index 8b01fdb670..a064902a7d 100644 --- a/docs/source/api/evennia.web.admin.rst +++ b/docs/source/api/evennia.web.admin.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin ========================= @@ -22,3 +23,5 @@ evennia.web.admin evennia.web.admin.tags evennia.web.admin.urls evennia.web.admin.utils + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.objects.rst b/docs/source/api/evennia.web.admin.objects.md similarity index 89% rename from docs/source/api/evennia.web.admin.objects.rst rename to docs/source/api/evennia.web.admin.objects.md index 54a674e71e..e176bc8d8a 100644 --- a/docs/source/api/evennia.web.admin.objects.rst +++ b/docs/source/api/evennia.web.admin.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.objects ================================ @@ -5,3 +6,5 @@ evennia.web.admin.objects :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.scripts.rst b/docs/source/api/evennia.web.admin.scripts.md similarity index 89% rename from docs/source/api/evennia.web.admin.scripts.rst rename to docs/source/api/evennia.web.admin.scripts.md index b13290aeea..e65a5f4b23 100644 --- a/docs/source/api/evennia.web.admin.scripts.rst +++ b/docs/source/api/evennia.web.admin.scripts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.scripts ================================ @@ -5,3 +6,5 @@ evennia.web.admin.scripts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.server.rst b/docs/source/api/evennia.web.admin.server.md similarity index 89% rename from docs/source/api/evennia.web.admin.server.rst rename to docs/source/api/evennia.web.admin.server.md index 7c8b09ce43..6c9314bdeb 100644 --- a/docs/source/api/evennia.web.admin.server.rst +++ b/docs/source/api/evennia.web.admin.server.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.server =============================== @@ -5,3 +6,5 @@ evennia.web.admin.server :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.tags.rst b/docs/source/api/evennia.web.admin.tags.md similarity index 89% rename from docs/source/api/evennia.web.admin.tags.rst rename to docs/source/api/evennia.web.admin.tags.md index b3cf2445a1..84e1bd2d00 100644 --- a/docs/source/api/evennia.web.admin.tags.rst +++ b/docs/source/api/evennia.web.admin.tags.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.tags ============================= @@ -5,3 +6,5 @@ evennia.web.admin.tags :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.urls.rst b/docs/source/api/evennia.web.admin.urls.md similarity index 89% rename from docs/source/api/evennia.web.admin.urls.rst rename to docs/source/api/evennia.web.admin.urls.md index 9bd1651964..0f84751fa3 100644 --- a/docs/source/api/evennia.web.admin.urls.rst +++ b/docs/source/api/evennia.web.admin.urls.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.urls ============================= @@ -5,3 +6,5 @@ evennia.web.admin.urls :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.admin.utils.rst b/docs/source/api/evennia.web.admin.utils.md similarity index 89% rename from docs/source/api/evennia.web.admin.utils.rst rename to docs/source/api/evennia.web.admin.utils.md index 7f62f621f7..0f3752ed42 100644 --- a/docs/source/api/evennia.web.admin.utils.rst +++ b/docs/source/api/evennia.web.admin.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.admin.utils ============================== @@ -5,3 +6,5 @@ evennia.web.admin.utils :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.filters.rst b/docs/source/api/evennia.web.api.filters.md similarity index 89% rename from docs/source/api/evennia.web.api.filters.rst rename to docs/source/api/evennia.web.api.filters.md index 9fbf183043..48085afc17 100644 --- a/docs/source/api/evennia.web.api.filters.rst +++ b/docs/source/api/evennia.web.api.filters.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.filters ============================== @@ -5,3 +6,5 @@ evennia.web.api.filters :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.rst b/docs/source/api/evennia.web.api.md similarity index 95% rename from docs/source/api/evennia.web.api.rst rename to docs/source/api/evennia.web.api.md index 4dab10c9c5..e61eff0212 100644 --- a/docs/source/api/evennia.web.api.rst +++ b/docs/source/api/evennia.web.api.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api ======================= @@ -18,3 +19,5 @@ evennia.web.api evennia.web.api.tests evennia.web.api.urls evennia.web.api.views + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.permissions.rst b/docs/source/api/evennia.web.api.permissions.md similarity index 90% rename from docs/source/api/evennia.web.api.permissions.rst rename to docs/source/api/evennia.web.api.permissions.md index cf1fd8dc4c..61d3b47866 100644 --- a/docs/source/api/evennia.web.api.permissions.rst +++ b/docs/source/api/evennia.web.api.permissions.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.permissions ================================== @@ -5,3 +6,5 @@ evennia.web.api.permissions :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.root.rst b/docs/source/api/evennia.web.api.root.md similarity index 88% rename from docs/source/api/evennia.web.api.root.rst rename to docs/source/api/evennia.web.api.root.md index 17f8111937..896ebbb47c 100644 --- a/docs/source/api/evennia.web.api.root.rst +++ b/docs/source/api/evennia.web.api.root.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.root =========================== @@ -5,3 +6,5 @@ evennia.web.api.root :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.serializers.rst b/docs/source/api/evennia.web.api.serializers.md similarity index 90% rename from docs/source/api/evennia.web.api.serializers.rst rename to docs/source/api/evennia.web.api.serializers.md index 6c98642c96..f6a2c2995b 100644 --- a/docs/source/api/evennia.web.api.serializers.rst +++ b/docs/source/api/evennia.web.api.serializers.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.serializers ================================== @@ -5,3 +6,5 @@ evennia.web.api.serializers :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.tests.rst b/docs/source/api/evennia.web.api.tests.md similarity index 88% rename from docs/source/api/evennia.web.api.tests.rst rename to docs/source/api/evennia.web.api.tests.md index 033b05871e..45618b1e9d 100644 --- a/docs/source/api/evennia.web.api.tests.rst +++ b/docs/source/api/evennia.web.api.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.tests ============================ @@ -5,3 +6,5 @@ evennia.web.api.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.urls.rst b/docs/source/api/evennia.web.api.urls.md similarity index 88% rename from docs/source/api/evennia.web.api.urls.rst rename to docs/source/api/evennia.web.api.urls.md index bff2799de3..ccc88d41ec 100644 --- a/docs/source/api/evennia.web.api.urls.rst +++ b/docs/source/api/evennia.web.api.urls.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.urls =========================== @@ -5,3 +6,5 @@ evennia.web.api.urls :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.api.views.rst b/docs/source/api/evennia.web.api.views.md similarity index 88% rename from docs/source/api/evennia.web.api.views.rst rename to docs/source/api/evennia.web.api.views.md index a9fe57ff7e..445c805f37 100644 --- a/docs/source/api/evennia.web.api.views.rst +++ b/docs/source/api/evennia.web.api.views.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.api.views ============================ @@ -5,3 +6,5 @@ evennia.web.api.views :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.rst b/docs/source/api/evennia.web.md similarity index 94% rename from docs/source/api/evennia.web.rst rename to docs/source/api/evennia.web.md index 51163bc707..a7e5a19a9e 100644 --- a/docs/source/api/evennia.web.rst +++ b/docs/source/api/evennia.web.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web =================== @@ -23,3 +24,5 @@ evennia.web evennia.web.utils evennia.web.webclient evennia.web.website + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.templatetags.addclass.rst b/docs/source/api/evennia.web.templatetags.addclass.md similarity index 90% rename from docs/source/api/evennia.web.templatetags.addclass.rst rename to docs/source/api/evennia.web.templatetags.addclass.md index 120ca1c546..d352d4509f 100644 --- a/docs/source/api/evennia.web.templatetags.addclass.rst +++ b/docs/source/api/evennia.web.templatetags.addclass.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.templatetags.addclass ======================================== @@ -5,3 +6,5 @@ evennia.web.templatetags.addclass :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.templatetags.rst b/docs/source/api/evennia.web.templatetags.md similarity index 92% rename from docs/source/api/evennia.web.templatetags.rst rename to docs/source/api/evennia.web.templatetags.md index 83d842aa6b..294ed3a2f8 100644 --- a/docs/source/api/evennia.web.templatetags.rst +++ b/docs/source/api/evennia.web.templatetags.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.templatetags ================================ @@ -12,3 +13,5 @@ evennia.web.templatetags :maxdepth: 6 evennia.web.templatetags.addclass + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.urls.rst b/docs/source/api/evennia.web.urls.md similarity index 87% rename from docs/source/api/evennia.web.urls.rst rename to docs/source/api/evennia.web.urls.md index e149189b50..516e04a6f4 100644 --- a/docs/source/api/evennia.web.urls.rst +++ b/docs/source/api/evennia.web.urls.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.urls ======================= @@ -5,3 +6,5 @@ evennia.web.urls :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.adminsite.rst b/docs/source/api/evennia.web.utils.adminsite.md similarity index 90% rename from docs/source/api/evennia.web.utils.adminsite.rst rename to docs/source/api/evennia.web.utils.adminsite.md index ce522ffc5f..088d276070 100644 --- a/docs/source/api/evennia.web.utils.adminsite.rst +++ b/docs/source/api/evennia.web.utils.adminsite.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils.adminsite ================================== @@ -5,3 +6,5 @@ evennia.web.utils.adminsite :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.backends.rst b/docs/source/api/evennia.web.utils.backends.md similarity index 89% rename from docs/source/api/evennia.web.utils.backends.rst rename to docs/source/api/evennia.web.utils.backends.md index 801ee69b23..8cc71c0a13 100644 --- a/docs/source/api/evennia.web.utils.backends.rst +++ b/docs/source/api/evennia.web.utils.backends.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils.backends ================================= @@ -5,3 +6,5 @@ evennia.web.utils.backends :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.general_context.rst b/docs/source/api/evennia.web.utils.general_context.md similarity index 91% rename from docs/source/api/evennia.web.utils.general_context.rst rename to docs/source/api/evennia.web.utils.general_context.md index 469a2219d7..a95ee1cf70 100644 --- a/docs/source/api/evennia.web.utils.general_context.rst +++ b/docs/source/api/evennia.web.utils.general_context.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils.general\_context ========================================= @@ -5,3 +6,5 @@ evennia.web.utils.general\_context :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.rst b/docs/source/api/evennia.web.utils.md similarity index 94% rename from docs/source/api/evennia.web.utils.rst rename to docs/source/api/evennia.web.utils.md index 22f52fef41..cdafa89a39 100644 --- a/docs/source/api/evennia.web.utils.rst +++ b/docs/source/api/evennia.web.utils.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils ========================= @@ -16,3 +17,5 @@ evennia.web.utils evennia.web.utils.general_context evennia.web.utils.middleware evennia.web.utils.tests + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.middleware.rst b/docs/source/api/evennia.web.utils.middleware.md similarity index 90% rename from docs/source/api/evennia.web.utils.middleware.rst rename to docs/source/api/evennia.web.utils.middleware.md index 60fc1884f0..9c277aca98 100644 --- a/docs/source/api/evennia.web.utils.middleware.rst +++ b/docs/source/api/evennia.web.utils.middleware.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils.middleware =================================== @@ -5,3 +6,5 @@ evennia.web.utils.middleware :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.utils.tests.rst b/docs/source/api/evennia.web.utils.tests.md similarity index 89% rename from docs/source/api/evennia.web.utils.tests.rst rename to docs/source/api/evennia.web.utils.tests.md index 8c10659d0c..8152441f41 100644 --- a/docs/source/api/evennia.web.utils.tests.rst +++ b/docs/source/api/evennia.web.utils.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.utils.tests ============================== @@ -5,3 +6,5 @@ evennia.web.utils.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.webclient.rst b/docs/source/api/evennia.web.webclient.md similarity index 93% rename from docs/source/api/evennia.web.webclient.rst rename to docs/source/api/evennia.web.webclient.md index 1f80bbf43b..ddb732d192 100644 --- a/docs/source/api/evennia.web.webclient.rst +++ b/docs/source/api/evennia.web.webclient.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.webclient ============================= @@ -13,3 +14,5 @@ evennia.web.webclient evennia.web.webclient.urls evennia.web.webclient.views + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.webclient.urls.rst b/docs/source/api/evennia.web.webclient.urls.md similarity index 89% rename from docs/source/api/evennia.web.webclient.urls.rst rename to docs/source/api/evennia.web.webclient.urls.md index 3f5c6df062..0d8fc75f67 100644 --- a/docs/source/api/evennia.web.webclient.urls.rst +++ b/docs/source/api/evennia.web.webclient.urls.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.webclient.urls ================================= @@ -5,3 +6,5 @@ evennia.web.webclient.urls :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.webclient.views.rst b/docs/source/api/evennia.web.webclient.views.md similarity index 90% rename from docs/source/api/evennia.web.webclient.views.rst rename to docs/source/api/evennia.web.webclient.views.md index 4c8be0d347..fa2923148b 100644 --- a/docs/source/api/evennia.web.webclient.views.rst +++ b/docs/source/api/evennia.web.webclient.views.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.webclient.views ================================== @@ -5,3 +6,5 @@ evennia.web.webclient.views :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.forms.rst b/docs/source/api/evennia.web.website.forms.md similarity index 89% rename from docs/source/api/evennia.web.website.forms.rst rename to docs/source/api/evennia.web.website.forms.md index 8847576f1f..39bd6f8058 100644 --- a/docs/source/api/evennia.web.website.forms.rst +++ b/docs/source/api/evennia.web.website.forms.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.forms ================================ @@ -5,3 +6,5 @@ evennia.web.website.forms :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.rst b/docs/source/api/evennia.web.website.md similarity index 94% rename from docs/source/api/evennia.web.website.rst rename to docs/source/api/evennia.web.website.md index f895a71560..301e9e3b8e 100644 --- a/docs/source/api/evennia.web.website.rst +++ b/docs/source/api/evennia.web.website.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website =========================== @@ -20,3 +21,5 @@ evennia.web.website :maxdepth: 6 evennia.web.website.views + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.tests.rst b/docs/source/api/evennia.web.website.tests.md similarity index 89% rename from docs/source/api/evennia.web.website.tests.rst rename to docs/source/api/evennia.web.website.tests.md index b06e8b8b9e..7ad5f279a1 100644 --- a/docs/source/api/evennia.web.website.tests.rst +++ b/docs/source/api/evennia.web.website.tests.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.tests ================================ @@ -5,3 +6,5 @@ evennia.web.website.tests :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.urls.rst b/docs/source/api/evennia.web.website.urls.md similarity index 89% rename from docs/source/api/evennia.web.website.urls.rst rename to docs/source/api/evennia.web.website.urls.md index 3ec3132b4c..9bc10a73f7 100644 --- a/docs/source/api/evennia.web.website.urls.rst +++ b/docs/source/api/evennia.web.website.urls.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.urls =============================== @@ -5,3 +6,5 @@ evennia.web.website.urls :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.accounts.rst b/docs/source/api/evennia.web.website.views.accounts.md similarity index 91% rename from docs/source/api/evennia.web.website.views.accounts.rst rename to docs/source/api/evennia.web.website.views.accounts.md index 99a396777a..7fb51d3ae0 100644 --- a/docs/source/api/evennia.web.website.views.accounts.rst +++ b/docs/source/api/evennia.web.website.views.accounts.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.accounts ========================================= @@ -5,3 +6,5 @@ evennia.web.website.views.accounts :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.channels.rst b/docs/source/api/evennia.web.website.views.channels.md similarity index 91% rename from docs/source/api/evennia.web.website.views.channels.rst rename to docs/source/api/evennia.web.website.views.channels.md index 8dcf8b398e..93fe0e8ae9 100644 --- a/docs/source/api/evennia.web.website.views.channels.rst +++ b/docs/source/api/evennia.web.website.views.channels.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.channels ========================================= @@ -5,3 +6,5 @@ evennia.web.website.views.channels :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.characters.rst b/docs/source/api/evennia.web.website.views.characters.md similarity index 91% rename from docs/source/api/evennia.web.website.views.characters.rst rename to docs/source/api/evennia.web.website.views.characters.md index 4abe1a82ec..ce70289f1e 100644 --- a/docs/source/api/evennia.web.website.views.characters.rst +++ b/docs/source/api/evennia.web.website.views.characters.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.characters =========================================== @@ -5,3 +6,5 @@ evennia.web.website.views.characters :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.errors.rst b/docs/source/api/evennia.web.website.views.errors.md similarity index 90% rename from docs/source/api/evennia.web.website.views.errors.rst rename to docs/source/api/evennia.web.website.views.errors.md index 85da064c13..85d011be5c 100644 --- a/docs/source/api/evennia.web.website.views.errors.rst +++ b/docs/source/api/evennia.web.website.views.errors.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.errors ======================================= @@ -5,3 +6,5 @@ evennia.web.website.views.errors :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.help.rst b/docs/source/api/evennia.web.website.views.help.md similarity index 90% rename from docs/source/api/evennia.web.website.views.help.rst rename to docs/source/api/evennia.web.website.views.help.md index 0223c48881..52e0f8f056 100644 --- a/docs/source/api/evennia.web.website.views.help.rst +++ b/docs/source/api/evennia.web.website.views.help.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.help ===================================== @@ -5,3 +6,5 @@ evennia.web.website.views.help :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.index.rst b/docs/source/api/evennia.web.website.views.index.md similarity index 90% rename from docs/source/api/evennia.web.website.views.index.rst rename to docs/source/api/evennia.web.website.views.index.md index 5b885e7580..2283b9d61e 100644 --- a/docs/source/api/evennia.web.website.views.index.rst +++ b/docs/source/api/evennia.web.website.views.index.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.index ====================================== @@ -5,3 +6,5 @@ evennia.web.website.views.index :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.rst b/docs/source/api/evennia.web.website.views.md similarity index 96% rename from docs/source/api/evennia.web.website.views.rst rename to docs/source/api/evennia.web.website.views.md index 35489078b9..2cae546fc8 100644 --- a/docs/source/api/evennia.web.website.views.rst +++ b/docs/source/api/evennia.web.website.views.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views ================================= @@ -19,3 +20,5 @@ evennia.web.website.views evennia.web.website.views.index evennia.web.website.views.mixins evennia.web.website.views.objects + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.mixins.rst b/docs/source/api/evennia.web.website.views.mixins.md similarity index 90% rename from docs/source/api/evennia.web.website.views.mixins.rst rename to docs/source/api/evennia.web.website.views.mixins.md index 5cf685bfb1..338a17ae0e 100644 --- a/docs/source/api/evennia.web.website.views.mixins.rst +++ b/docs/source/api/evennia.web.website.views.mixins.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.mixins ======================================= @@ -5,3 +6,5 @@ evennia.web.website.views.mixins :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/api/evennia.web.website.views.objects.rst b/docs/source/api/evennia.web.website.views.objects.md similarity index 90% rename from docs/source/api/evennia.web.website.views.objects.rst rename to docs/source/api/evennia.web.website.views.objects.md index 787c006aae..920de88b96 100644 --- a/docs/source/api/evennia.web.website.views.objects.rst +++ b/docs/source/api/evennia.web.website.views.objects.md @@ -1,3 +1,4 @@ +```{eval-rst} evennia.web.website.views.objects ======================================== @@ -5,3 +6,5 @@ evennia.web.website.views.objects :members: :undoc-members: :show-inheritance: + +``` \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index e43c5f62a2..41d8edf06d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,7 +7,7 @@ import os import sys import re -from recommonmark.transform import AutoStructify +# from recommonmark.transform import AutoStructify from sphinx.util.osutil import cd @@ -25,14 +25,13 @@ release = "1.0-dev" # -- General configuration --------------------------------------------------- extensions = [ - "recommonmark", "sphinx_multiversion", "sphinx.ext.napoleon", "sphinx.ext.autosectionlabel", "sphinx.ext.viewcode", - # "sphinxcontrib.lunrsearch", "sphinx.ext.todo", "sphinx.ext.githubpages", + "myst_parser" ] source_suffix = [".md", ".rst"] @@ -106,69 +105,111 @@ latex_documents = [ ] -# -- Recommonmark ------------------------------------------------------------ -# allows for writing Markdown and convert to rst dynamically +# -- MyST Markdown parsing ----------------------------------------------------- + +myst_enable_extensions = [ + "amsmath", + "colon_fence", # Use ::: instead of ``` for some extra features + "deflist", # use : to mark sublevel of list + "dollarmath", + "html_admonition", # Add admonitions in html (usually use ```{admonition} directive) + "html_image", # parse raw tags + "linkify", # convert bare urls to md links + "replacements", # (c) to copyright sign etc + "smartquotes", + "substitution", + "tasklist", +] + +myst_dmath_allow_space = False # requires $a$, not $ a$ or $a $ +myst_dmath_allow_digits = False # requires $a$, not 1$a$ or $a$2 +myst_dmath_double_inline = True # allow $$ ... $$ math blocks + +myst_substitution = { + # used with Jinja2. Can also be set in a substitutions: block in front-matter of page +} +# add anchors to h1, h2, ... level headings +myst_heading_anchors = 4 + # reroute to github links or to the api +# shortcuts +_githubstart = "github:" +_apistart = "api:" +_choose_issue = "github:issue" +_sourcestart = "src:" +# remaps _github_code_root = "https://github.com/evennia/evennia/blob/" _github_doc_root = "https://github.com/evennia/tree/master/docs/sources/" _github_issue_choose = "https://github.com/evennia/evennia/issues/new/choose" +_ref_regex = re.compile( # normal reference-links [txt](url) + r"\[(?P[\w -\[\]\`\n]+?)\]\((?P.+?)\)", re.I + re.S + re.U + re.M) +_ref_doc_regex = re.compile( # in-document bottom references [txt]: url + r"\[(?P[\w -\`]+?)\\n]:\s+?(?P.+?)(?=$|\n)", re.I + re.S + re.U + re.M) -def url_resolver(url): +def url_resolver(app, docname, source): """ + A handler acting on the `source-read` signal. The `source` + is a list with one element that should be updated. Convert urls by catching special markers. + + Supported replacements (used e.g. as [txt](github:...) + github:master/ - add path to Evennia github master branch + github:develop/ - add path to Evennia github develop branch + github:issue - add link to the Evennia github issue-create page + src:foo.bar#Foo - add link to source doc in _modules + api:foo.bar#Foo - add link to api autodoc page + + """ - githubstart = "github:" - apistart = "api:" - choose_issue = "github:issue" - sourcestart = "src:" + def _url_remap(url): - if url.endswith(choose_issue): - return _github_issue_choose - elif githubstart in url: - urlpath = url[url.index(githubstart) + len(githubstart) :] - if not (urlpath.startswith("develop/") or urlpath.startswith("master")): - urlpath = "master/" + urlpath - return _github_code_root + urlpath - elif apistart in url: - # locate the api/ folder in the doc structure - ind = url.index(apistart) - depth = url[:ind].count("/") + 1 - path = "../".join("" for _ in range(depth)) - urlpath = path + "api/" + url[ind + len(apistart) :] + ".html" - return urlpath - elif sourcestart in url: - ind = url.index(sourcestart) - depth = url[:ind].count("/") + 1 - path = "../".join("" for _ in range(depth)) + # determine depth in tree of current document + docdepth = docname.count('/') + 1 + relative_path = "../".join("" for _ in range(docdepth)) - modpath, *inmodule = url[ind + len(sourcestart) :].rsplit("#", 1) - modpath = "/".join(modpath.split(".")) - inmodule = "#" + inmodule[0] if inmodule else "" - modpath = modpath + ".html" + inmodule + if url.endswith(_choose_issue): + # github:issue shortcut + return _github_issue_choose + elif _githubstart in url: + # github:develop/... shortcut + urlpath = url[url.index(_githubstart) + len(_githubstart):] + if not (urlpath.startswith("develop/") or urlpath.startswith("master")): + urlpath = "master/" + urlpath + return _github_code_root + urlpath + elif _sourcestart in url: + ind = url.index(_sourcestart) - urlpath = path + "_modules/" + modpath - return urlpath + modpath, *inmodule = url[ind + len(_sourcestart):].rsplit("#", 1) + modpath = "/".join(modpath.split(".")) + inmodule = "#" + inmodule[0] if inmodule else "" + modpath = modpath + ".html" + inmodule - return url + urlpath = relative_path + "_modules/" + modpath + return urlpath + + return url + + def _re_ref_sub(match): + txt = match.group('txt') + url = _url_remap(match.group('url')) + return f"[{txt}]({url})" + + def _re_docref_sub(match): + txt = match.group('txt') + url = _url_remap(match.group('url')) + return f"[{txt}]: {url}" + + src = source[0] + src = _ref_regex.sub(_re_ref_sub, src) + src = _ref_doc_regex.sub(_re_docref_sub, src) + source[0] = src -# auto-create TOCs if a list of links is under these headers -auto_toc_sections = ["Contents", "Toc", "Index", "API", "Overview"] - -recommonmark_config = { - "enable_auto_toc_tree": True, - "url_resolver": url_resolver, - "auto_toc_maxdepth": 1, - "auto_toc_tree_section": ["Contents", "Toc", "Index"], - "code_highlight_options": {"force": True, "linenos": True}, -} - - -# -- API/Autodoc --------------------------------------------------------------- -# automatic creation of API documentation. This requires a valid Evennia setup +# # -- API/Autodoc --------------------------------------------------------------- +# # automatic creation of API documentation. This requires a valid Evennia setup _no_autodoc = os.environ.get("NOAUTODOC") @@ -198,7 +239,7 @@ if not _no_autodoc: if _no_autodoc: exclude_patterns = ["api/*"] else: - exclude_patterns = ["api/*migrations.rst"] + exclude_patterns = ["api/*migrations.rst", "api/*migrations.md"] autodoc_default_options = { "members": True, @@ -206,7 +247,7 @@ autodoc_default_options = { "show-inheritance": True, "special-members": "__init__", "enable_eval_rst": True, - # "inherited_members": True + "inherited_members": True } autodoc_member_order = "bysource" @@ -299,13 +340,14 @@ napoleon_use_rtype = False def setup(app): app.connect("autodoc-skip-member", autodoc_skip_member) app.connect("autodoc-process-docstring", autodoc_post_process_docstring) - app.add_transform(AutoStructify) + app.connect("source-read", url_resolver) # build toctree file sys.path.insert(1, os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) - from docs.pylib import auto_link_remapper + from docs.pylib import auto_link_remapper, update_default_cmd_index _no_autodoc = os.environ.get("NOAUTODOC") + update_default_cmd_index.run_update(no_autodoc=_no_autodoc) auto_link_remapper.auto_link_remapper(no_autodoc=_no_autodoc) print("Updated source/toc.md file") diff --git a/docs/source/index.md b/docs/source/index.md index 1fe5d806f9..0b176d3a39 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -1,13 +1,13 @@ -```warning:: +```{warning} This is the **WIP** documentation for the - development branch of Evennia (v1.0-dev). The text is based on the - original Evennia `wiki `_ - but it's being refactored heavily. There are known conversion issues + development branch of Evennia (v1.0-dev). The text is based on the + original Evennia `wiki `_ + but it's being refactored heavily. There are known conversion issues and missing links. This will slowly be ironed out as this is developed. - New things will be added to this version only, but for now you are best + New things will be added to this version only, but for now you are best off using v0.9.5 of the docs, or the original wiki. You have been warned. ``` @@ -16,43 +16,45 @@ This is the manual of [Evennia](https://www.evennia.com), the open source Python `MU*` creation system. -- [Evennia Introduction](./Evennia-Introduction) -- [Install & Setup Quickstart](Setup/Setup-Quickstart) -- [Starting tutorial](Howto/Starting/Part1/Starting-Part1) -- [How to get (and give) help](./How-To-Get-And-Give-Help) +- [Evennia Introduction](./Evennia-Introduction.md) +- [Install & Setup Quickstart](Setup/Setup-Quickstart.md) +- [Starting tutorial](Howto/Starting/Part1/Starting-Part1.md) +- [How to get (and give) help](./How-To-Get-And-Give-Help.md) ## Main sections -- [Server Setup, Maintenance and Life](Setup/Setup-Overview) - how to run, maintain and release -- [Tutorials and Howto's](Howto/Howto-Overview) - projects and hints for reaching particular effects and goals +- [Server Setup, Maintenance and Life](Setup/Setup-Overview.md) - how to run, maintain and release +- [Tutorials and Howto's](Howto/Howto-Overview.md) - projects and hints for reaching particular effects and goals ---- -- [Core components](Components/Components-Overview) - the core building blocks of Evennia -- [Concepts](Concepts/Concepts-Overview) - larger-scale concepts and features +- [Core components](Components/Components-Overview.md) - the core building blocks of Evennia +- [Concepts](Concepts/Concepts-Overview.md) - larger-scale concepts and features ---- -- [API](./Evennia-API) - the full API-reference, generated from source -- [Coding](Coding/Coding-Overview) - coding and development hints and resources -- [Contributions](Contribs/Contrib-Overview) - game-specific tools and code added by the community +- [API](./Evennia-API.md) - the full API-reference, generated from source +- [Default Commands](Components/Default-Commands.md) - list of game commands included out of the box +- [Coding](Coding/Coding-Overview.md) - coding and development hints and resources +- [Contributions](Contribs/Contrib-Overview.md) - game-specific tools and code added by the community ---- -- [Links](./Links) - useful links -- [Table of Contents](./toc) - an alphabetical listing of all regular documentation pages +- [Links](./Links.md) - useful links +- [Table of Contents](./toc.md) - an alphabetical listing of all regular documentation pages -Want to help improve the docs? See the page on [Contributing to the docs](./Contributing-Docs)! +Want to help improve the docs? See the page on [Contributing to the docs](./Contributing-Docs.md)! -```toctree:: - :hidden: +```{toctree} +:hidden: - Evennia-Introduction - Setup/Setup-Quickstart - Howto/Starting/Part1/Starting-Part1 - How-To-Get-And-Give-Help - Setup/Setup-Overview - Howto/Howto-Overview - Components/Components-Overview - Concepts/Concepts-Overview - Evennia-API - Coding/Coding-Overview - Contribs/Contrib-Overview - Links +Evennia-Introduction +Setup/Setup-Quickstart.md +Howto/Starting/Part1/Starting-Part1.md +How-To-Get-And-Give-Help.md +Setup/Setup-Overview.md +Howto/Howto-Overview.md +Components/Components-Overview.md +Concepts/Concepts-Overview.md +Evennia-API.md +Components/Default-Commands.md +Coding/Coding-Overview.md +Contribs/Contrib-Overview.md +Links.md -``` \ No newline at end of file +``` diff --git a/docs/source/toc.md b/docs/source/toc.md index 51f74ca686..b7ccdaf8d2 100644 --- a/docs/source/toc.md +++ b/docs/source/toc.md @@ -1,172 +1,450 @@ -# Toc +```{toctree} - [API root](api/evennia-api.rst) -- [Coding/Coding Introduction](Coding/Coding-Introduction) -- [Coding/Coding Overview](Coding/Coding-Overview) -- [Coding/Continuous Integration](Coding/Continuous-Integration) -- [Coding/Debugging](Coding/Debugging) -- [Coding/Flat API](Coding/Flat-API) -- [Coding/Profiling](Coding/Profiling) -- [Coding/Quirks](Coding/Quirks) -- [Coding/Setting up PyCharm](Coding/Setting-up-PyCharm) -- [Coding/Unit Testing](Coding/Unit-Testing) -- [Coding/Updating Your Game](Coding/Updating-Your-Game) -- [Coding/Using Travis](Coding/Using-Travis) -- [Coding/Version Control](Coding/Version-Control) -- [Components/Accounts](Components/Accounts) -- [Components/Attributes](Components/Attributes) -- [Components/Batch Code Processor](Components/Batch-Code-Processor) -- [Components/Batch Command Processor](Components/Batch-Command-Processor) -- [Components/Batch Processors](Components/Batch-Processors) -- [Components/Bootstrap Components and Utilities](Components/Bootstrap-Components-and-Utilities) -- [Components/Channels](Components/Channels) -- [Components/Coding Utils](Components/Coding-Utils) -- [Components/Command Sets](Components/Command-Sets) -- [Components/Command System](Components/Command-System) -- [Components/Commands](Components/Commands) -- [Components/Communications](Components/Communications) -- [Components/Components Overview](Components/Components-Overview) -- [Components/Connection Screen](Components/Connection-Screen) -- [Components/EvEditor](Components/EvEditor) -- [Components/EvMenu](Components/EvMenu) -- [Components/EvMore](Components/EvMore) -- [Components/FuncParser](Components/FuncParser) -- [Components/Help System](Components/Help-System) -- [Components/Inputfuncs](Components/Inputfuncs) -- [Components/Locks](Components/Locks) -- [Components/MonitorHandler](Components/MonitorHandler) -- [Components/Msg](Components/Msg) -- [Components/Nicks](Components/Nicks) -- [Components/Objects](Components/Objects) -- [Components/Outputfuncs](Components/Outputfuncs) -- [Components/Permissions](Components/Permissions) -- [Components/Portal And Server](Components/Portal-And-Server) -- [Components/Prototypes](Components/Prototypes) -- [Components/Scripts](Components/Scripts) -- [Components/Server](Components/Server) -- [Components/Server Conf](Components/Server-Conf) -- [Components/Sessions](Components/Sessions) -- [Components/Signals](Components/Signals) -- [Components/Tags](Components/Tags) -- [Components/TickerHandler](Components/TickerHandler) -- [Components/Typeclasses](Components/Typeclasses) -- [Components/Web API](Components/Web-API) -- [Components/Web Admin](Components/Web-Admin) -- [Components/Webclient](Components/Webclient) -- [Components/Webserver](Components/Webserver) -- [Components/Website](Components/Website) -- [Concepts/Async Process](Concepts/Async-Process) -- [Concepts/Banning](Concepts/Banning) -- [Concepts/Bootstrap & Evennia](Concepts/Bootstrap-&-Evennia) -- [Concepts/Building Permissions](Concepts/Building-Permissions) -- [Concepts/Clickable Links](Concepts/Clickable-Links) -- [Concepts/Colors](Concepts/Colors) -- [Concepts/Concepts Overview](Concepts/Concepts-Overview) -- [Concepts/Custom Protocols](Concepts/Custom-Protocols) -- [Concepts/Guest Logins](Concepts/Guest-Logins) -- [Concepts/Internationalization](Concepts/Internationalization) -- [Concepts/Messagepath](Concepts/Messagepath) -- [Concepts/Multisession modes](Concepts/Multisession-modes) -- [Concepts/New Models](Concepts/New-Models) -- [Concepts/OOB](Concepts/OOB) -- [Concepts/Soft Code](Concepts/Soft-Code) -- [Concepts/Text Encodings](Concepts/Text-Encodings) -- [Concepts/TextTags](Concepts/TextTags) -- [Concepts/Using MUX as a Standard](Concepts/Using-MUX-as-a-Standard) -- [Concepts/Web Features](Concepts/Web-Features) -- [Concepts/Zones](Concepts/Zones) -- [Contribs/A voice operated elevator using events](Contribs/A-voice-operated-elevator-using-events) -- [Contribs/Arxcode installing help](Contribs/Arxcode-installing-help) -- [Contribs/Building menus](Contribs/Building-menus) -- [Contribs/Contrib Overview](Contribs/Contrib-Overview) -- [Contribs/Crafting](Contribs/Crafting) -- [Contribs/Dialogues in events](Contribs/Dialogues-in-events) -- [Contribs/Dynamic In Game Map](Contribs/Dynamic-In-Game-Map) -- [Contribs/Static In Game Map](Contribs/Static-In-Game-Map) -- [Contribs/XYZGrid](Contribs/XYZGrid) -- [./Contributing](./Contributing) -- [./Contributing Docs](./Contributing-Docs) -- [./Evennia API](./Evennia-API) -- [./Evennia Introduction](./Evennia-Introduction) -- [./Glossary](./Glossary) -- [./How To Get And Give Help](./How-To-Get-And-Give-Help) -- [Howto/Add a wiki on your website](Howto/Add-a-wiki-on-your-website) -- [Howto/Building a mech tutorial](Howto/Building-a-mech-tutorial) -- [Howto/Coding FAQ](Howto/Coding-FAQ) -- [Howto/Command Cooldown](Howto/Command-Cooldown) -- [Howto/Command Duration](Howto/Command-Duration) -- [Howto/Command Prompt](Howto/Command-Prompt) -- [Howto/Coordinates](Howto/Coordinates) -- [Howto/Default Exit Errors](Howto/Default-Exit-Errors) -- [Howto/Evennia for Diku Users](Howto/Evennia-for-Diku-Users) -- [Howto/Evennia for MUSH Users](Howto/Evennia-for-MUSH-Users) -- [Howto/Evennia for roleplaying sessions](Howto/Evennia-for-roleplaying-sessions) -- [Howto/Gametime Tutorial](Howto/Gametime-Tutorial) -- [Howto/Help System Tutorial](Howto/Help-System-Tutorial) -- [Howto/Howto Overview](Howto/Howto-Overview) -- [Howto/Manually Configuring Color](Howto/Manually-Configuring-Color) -- [Howto/Mass and weight for objects](Howto/Mass-and-weight-for-objects) -- [Howto/NPC shop Tutorial](Howto/NPC-shop-Tutorial) -- [Howto/Parsing commands tutorial](Howto/Parsing-commands-tutorial) -- [Howto/Starting/Part1/Adding Commands](Howto/Starting/Part1/Adding-Commands) -- [Howto/Starting/Part1/Building Quickstart](Howto/Starting/Part1/Building-Quickstart) -- [Howto/Starting/Part1/Creating Things](Howto/Starting/Part1/Creating-Things) -- [Howto/Starting/Part1/Django queries](Howto/Starting/Part1/Django-queries) -- [Howto/Starting/Part1/Evennia Library Overview](Howto/Starting/Part1/Evennia-Library-Overview) -- [Howto/Starting/Part1/Gamedir Overview](Howto/Starting/Part1/Gamedir-Overview) -- [Howto/Starting/Part1/Learning Typeclasses](Howto/Starting/Part1/Learning-Typeclasses) -- [Howto/Starting/Part1/More on Commands](Howto/Starting/Part1/More-on-Commands) -- [Howto/Starting/Part1/Python basic introduction](Howto/Starting/Part1/Python-basic-introduction) -- [Howto/Starting/Part1/Python classes and objects](Howto/Starting/Part1/Python-classes-and-objects) -- [Howto/Starting/Part1/Searching Things](Howto/Starting/Part1/Searching-Things) -- [Howto/Starting/Part1/Starting Part1](Howto/Starting/Part1/Starting-Part1) -- [Howto/Starting/Part1/Tutorial World Introduction](Howto/Starting/Part1/Tutorial-World-Introduction) -- [Howto/Starting/Part2/Game Planning](Howto/Starting/Part2/Game-Planning) -- [Howto/Starting/Part2/Planning Some Useful Contribs](Howto/Starting/Part2/Planning-Some-Useful-Contribs) -- [Howto/Starting/Part2/Planning The Tutorial Game](Howto/Starting/Part2/Planning-The-Tutorial-Game) -- [Howto/Starting/Part2/Planning Where Do I Begin](Howto/Starting/Part2/Planning-Where-Do-I-Begin) -- [Howto/Starting/Part2/Starting Part2](Howto/Starting/Part2/Starting-Part2) -- [Howto/Starting/Part3/A Sittable Object](Howto/Starting/Part3/A-Sittable-Object) -- [Howto/Starting/Part3/Implementing a game rule system](Howto/Starting/Part3/Implementing-a-game-rule-system) -- [Howto/Starting/Part3/Starting Part3](Howto/Starting/Part3/Starting-Part3) -- [Howto/Starting/Part3/Turn based Combat System](Howto/Starting/Part3/Turn-based-Combat-System) -- [Howto/Starting/Part3/Tutorial for basic MUSH like game](Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game) -- [Howto/Starting/Part4/Starting Part4](Howto/Starting/Part4/Starting-Part4) -- [Howto/Starting/Part5/Add a simple new web page](Howto/Starting/Part5/Add-a-simple-new-web-page) -- [Howto/Starting/Part5/Starting Part5](Howto/Starting/Part5/Starting-Part5) -- [Howto/Starting/Part5/Web Tutorial](Howto/Starting/Part5/Web-Tutorial) -- [Howto/Tutorial Aggressive NPCs](Howto/Tutorial-Aggressive-NPCs) -- [Howto/Tutorial NPCs listening](Howto/Tutorial-NPCs-listening) -- [Howto/Tutorial Tweeting Game Stats](Howto/Tutorial-Tweeting-Game-Stats) -- [Howto/Tutorial Vehicles](Howto/Tutorial-Vehicles) -- [Howto/Understanding Color Tags](Howto/Understanding-Color-Tags) -- [Howto/Weather Tutorial](Howto/Weather-Tutorial) -- [Howto/Web Character Generation](Howto/Web-Character-Generation) -- [Howto/Web Character View Tutorial](Howto/Web-Character-View-Tutorial) -- [./Licensing](./Licensing) -- [./Links](./Links) -- [Setup/Apache Config](Setup/Apache-Config) -- [Setup/Choosing An SQL Server](Setup/Choosing-An-SQL-Server) -- [Setup/Client Support Grid](Setup/Client-Support-Grid) -- [Setup/Evennia Game Index](Setup/Evennia-Game-Index) -- [Setup/Extended Installation](Setup/Extended-Installation) -- [Setup/Grapevine](Setup/Grapevine) -- [Setup/HAProxy Config](Setup/HAProxy-Config) -- [Setup/How to connect Evennia to Twitter](Setup/How-to-connect-Evennia-to-Twitter) -- [Setup/IRC](Setup/IRC) -- [Setup/Installing on Android](Setup/Installing-on-Android) -- [Setup/Online Setup](Setup/Online-Setup) -- [Setup/RSS](Setup/RSS) -- [Setup/Running Evennia in Docker](Setup/Running-Evennia-in-Docker) -- [Setup/Security](Setup/Security) -- [Setup/Settings File](Setup/Settings-File) -- [Setup/Setup Overview](Setup/Setup-Overview) -- [Setup/Setup Quickstart](Setup/Setup-Quickstart) -- [Setup/Start Stop Reload](Setup/Start-Stop-Reload) -- [./Unimplemented](./Unimplemented) -- [./index](./index) +Coding/Coding-Introduction +Coding/Coding-Overview +Coding/Continuous-Integration +Coding/Debugging +Coding/Flat-API +Coding/Profiling +Coding/Quirks +Coding/Setting-up-PyCharm +Coding/Unit-Testing +Coding/Updating-Your-Game +Coding/Using-Travis +Coding/Version-Control +Components/Accounts +Components/Attributes +Components/Batch-Code-Processor +Components/Batch-Command-Processor +Components/Batch-Processors +Components/Bootstrap-Components-and-Utilities +Components/Channels +Components/Coding-Utils +Components/Command-Sets +Components/Command-System +Components/Commands +Components/Communications +Components/Components-Overview +Components/Connection-Screen +Components/Default-Commands +Components/EvEditor +Components/EvMenu +Components/EvMore +Components/FuncParser +Components/Help-System +Components/Inputfuncs +Components/Locks +Components/MonitorHandler +Components/Msg +Components/Nicks +Components/Objects +Components/Outputfuncs +Components/Permissions +Components/Portal-And-Server +Components/Prototypes +Components/Scripts +Components/Server +Components/Sessions +Components/Signals +Components/Tags +Components/TickerHandler +Components/Typeclasses +Components/Web-API +Components/Web-Admin +Components/Webclient +Components/Webserver +Components/Website +Concepts/Async-Process +Concepts/Banning +Concepts/Bootstrap-&-Evennia +Concepts/Building-Permissions +Concepts/Clickable-Links +Concepts/Colors +Concepts/Concepts-Overview +Concepts/Custom-Protocols +Concepts/Guest-Logins +Concepts/Internationalization +Concepts/Messagepath +Concepts/Multisession-modes +Concepts/New-Models +Concepts/OOB +Concepts/Soft-Code +Concepts/Text-Encodings +Concepts/TextTags +Concepts/Using-MUX-as-a-Standard +Concepts/Web-Features +Concepts/Zones +Contribs/A-voice-operated-elevator-using-events +Contribs/Arxcode-installing-help +Contribs/Building-menus +Contribs/Contrib-Overview +Contribs/Crafting +Contribs/Dialogues-in-events +Contribs/Dynamic-In-Game-Map +Contribs/Static-In-Game-Map +Contribs/XYZGrid +Contributing +Contributing-Docs +Evennia-API +Evennia-Introduction +Glossary +How-To-Get-And-Give-Help +Howto/Add-a-wiki-on-your-website +Howto/Building-a-mech-tutorial +Howto/Coding-FAQ +Howto/Command-Cooldown +Howto/Command-Duration +Howto/Command-Prompt +Howto/Coordinates +Howto/Default-Exit-Errors +Howto/Evennia-for-Diku-Users +Howto/Evennia-for-MUSH-Users +Howto/Evennia-for-roleplaying-sessions +Howto/Gametime-Tutorial +Howto/Help-System-Tutorial +Howto/Howto-Overview +Howto/Manually-Configuring-Color +Howto/Mass-and-weight-for-objects +Howto/NPC-shop-Tutorial +Howto/Parsing-commands-tutorial +Howto/Starting/Part1/Adding-Commands +Howto/Starting/Part1/Building-Quickstart +Howto/Starting/Part1/Creating-Things +Howto/Starting/Part1/Django-queries +Howto/Starting/Part1/Evennia-Library-Overview +Howto/Starting/Part1/Gamedir-Overview +Howto/Starting/Part1/Learning-Typeclasses +Howto/Starting/Part1/More-on-Commands +Howto/Starting/Part1/Python-basic-introduction +Howto/Starting/Part1/Python-classes-and-objects +Howto/Starting/Part1/Searching-Things +Howto/Starting/Part1/Starting-Part1 +Howto/Starting/Part1/Tutorial-World-Introduction +Howto/Starting/Part2/Game-Planning +Howto/Starting/Part2/Planning-Some-Useful-Contribs +Howto/Starting/Part2/Planning-The-Tutorial-Game +Howto/Starting/Part2/Planning-Where-Do-I-Begin +Howto/Starting/Part2/Starting-Part2 +Howto/Starting/Part3/A-Sittable-Object +Howto/Starting/Part3/Implementing-a-game-rule-system +Howto/Starting/Part3/Starting-Part3 +Howto/Starting/Part3/Turn-based-Combat-System +Howto/Starting/Part3/Tutorial-for-basic-MUSH-like-game +Howto/Starting/Part4/Starting-Part4 +Howto/Starting/Part5/Add-a-simple-new-web-page +Howto/Starting/Part5/Starting-Part5 +Howto/Starting/Part5/Web-Tutorial +Howto/Tutorial-Aggressive-NPCs +Howto/Tutorial-NPCs-listening +Howto/Tutorial-Tweeting-Game-Stats +Howto/Tutorial-Vehicles +Howto/Understanding-Color-Tags +Howto/Weather-Tutorial +Howto/Web-Character-Generation +Howto/Web-Character-View-Tutorial +Licensing +Links +Setup/Apache-Config +Setup/Choosing-An-SQL-Server +Setup/Client-Support-Grid +Setup/Evennia-Game-Index +Setup/Extended-Installation +Setup/Grapevine +Setup/HAProxy-Config +Setup/How-to-connect-Evennia-to-Twitter +Setup/IRC +Setup/Installing-on-Android +Setup/Online-Setup +Setup/RSS +Setup/Running-Evennia-in-Docker +Setup/Security +Setup/Server-Conf +Setup/Settings-File +Setup/Setup-Overview +Setup/Setup-Quickstart +Setup/Start-Stop-Reload +Unimplemented +api/evennia +api/evennia-api +api/evennia.accounts +api/evennia.accounts.accounts +api/evennia.accounts.bots +api/evennia.accounts.manager +api/evennia.accounts.models +api/evennia.commands +api/evennia.commands.cmdhandler +api/evennia.commands.cmdparser +api/evennia.commands.cmdset +api/evennia.commands.cmdsethandler +api/evennia.commands.command +api/evennia.commands.default +api/evennia.commands.default.account +api/evennia.commands.default.admin +api/evennia.commands.default.batchprocess +api/evennia.commands.default.building +api/evennia.commands.default.cmdset_account +api/evennia.commands.default.cmdset_character +api/evennia.commands.default.cmdset_session +api/evennia.commands.default.cmdset_unloggedin +api/evennia.commands.default.comms +api/evennia.commands.default.general +api/evennia.commands.default.help +api/evennia.commands.default.muxcommand +api/evennia.commands.default.syscommands +api/evennia.commands.default.system +api/evennia.commands.default.tests +api/evennia.commands.default.unloggedin +api/evennia.comms +api/evennia.comms.comms +api/evennia.comms.managers +api/evennia.comms.models +api/evennia.contrib +api/evennia.contrib.awsstorage +api/evennia.contrib.awsstorage.aws_s3_cdn +api/evennia.contrib.awsstorage.tests +api/evennia.contrib.barter +api/evennia.contrib.building_menu +api/evennia.contrib.chargen +api/evennia.contrib.clothing +api/evennia.contrib.color_markups +api/evennia.contrib.crafting +api/evennia.contrib.crafting.crafting +api/evennia.contrib.crafting.example_recipes +api/evennia.contrib.crafting.tests +api/evennia.contrib.custom_gametime +api/evennia.contrib.dice +api/evennia.contrib.email_login +api/evennia.contrib.evscaperoom +api/evennia.contrib.evscaperoom.commands +api/evennia.contrib.evscaperoom.menu +api/evennia.contrib.evscaperoom.objects +api/evennia.contrib.evscaperoom.room +api/evennia.contrib.evscaperoom.scripts +api/evennia.contrib.evscaperoom.state +api/evennia.contrib.evscaperoom.tests +api/evennia.contrib.evscaperoom.utils +api/evennia.contrib.extended_room +api/evennia.contrib.fieldfill +api/evennia.contrib.gendersub +api/evennia.contrib.health_bar +api/evennia.contrib.ingame_python +api/evennia.contrib.ingame_python.callbackhandler +api/evennia.contrib.ingame_python.commands +api/evennia.contrib.ingame_python.eventfuncs +api/evennia.contrib.ingame_python.scripts +api/evennia.contrib.ingame_python.tests +api/evennia.contrib.ingame_python.typeclasses +api/evennia.contrib.ingame_python.utils +api/evennia.contrib.mail +api/evennia.contrib.mapbuilder +api/evennia.contrib.menu_login +api/evennia.contrib.multidescer +api/evennia.contrib.puzzles +api/evennia.contrib.random_string_generator +api/evennia.contrib.rplanguage +api/evennia.contrib.rpsystem +api/evennia.contrib.security +api/evennia.contrib.security.auditing +api/evennia.contrib.security.auditing.outputs +api/evennia.contrib.security.auditing.server +api/evennia.contrib.security.auditing.tests +api/evennia.contrib.simpledoor +api/evennia.contrib.slow_exit +api/evennia.contrib.talking_npc +api/evennia.contrib.test_traits +api/evennia.contrib.traits +api/evennia.contrib.tree_select +api/evennia.contrib.turnbattle +api/evennia.contrib.turnbattle.tb_basic +api/evennia.contrib.turnbattle.tb_equip +api/evennia.contrib.turnbattle.tb_items +api/evennia.contrib.turnbattle.tb_magic +api/evennia.contrib.turnbattle.tb_range +api/evennia.contrib.tutorial_examples +api/evennia.contrib.tutorial_examples.bodyfunctions +api/evennia.contrib.tutorial_examples.example_batch_code +api/evennia.contrib.tutorial_examples.mirror +api/evennia.contrib.tutorial_examples.red_button +api/evennia.contrib.tutorial_examples.tests +api/evennia.contrib.tutorial_world +api/evennia.contrib.tutorial_world.intro_menu +api/evennia.contrib.tutorial_world.mob +api/evennia.contrib.tutorial_world.objects +api/evennia.contrib.tutorial_world.rooms +api/evennia.contrib.unixcommand +api/evennia.contrib.wilderness +api/evennia.contrib.xyzgrid +api/evennia.contrib.xyzgrid.commands +api/evennia.contrib.xyzgrid.example +api/evennia.contrib.xyzgrid.launchcmd +api/evennia.contrib.xyzgrid.prototypes +api/evennia.contrib.xyzgrid.tests +api/evennia.contrib.xyzgrid.utils +api/evennia.contrib.xyzgrid.xymap +api/evennia.contrib.xyzgrid.xymap_legend +api/evennia.contrib.xyzgrid.xyzgrid +api/evennia.contrib.xyzgrid.xyzroom +api/evennia.help +api/evennia.help.filehelp +api/evennia.help.manager +api/evennia.help.models +api/evennia.help.utils +api/evennia.locks +api/evennia.locks.lockfuncs +api/evennia.locks.lockhandler +api/evennia.objects +api/evennia.objects.manager +api/evennia.objects.models +api/evennia.objects.objects +api/evennia.prototypes +api/evennia.prototypes.menus +api/evennia.prototypes.protfuncs +api/evennia.prototypes.prototypes +api/evennia.prototypes.spawner +api/evennia.scripts +api/evennia.scripts.manager +api/evennia.scripts.models +api/evennia.scripts.monitorhandler +api/evennia.scripts.scripthandler +api/evennia.scripts.scripts +api/evennia.scripts.taskhandler +api/evennia.scripts.tickerhandler +api/evennia.server +api/evennia.server.amp_client +api/evennia.server.connection_wizard +api/evennia.server.deprecations +api/evennia.server.evennia_launcher +api/evennia.server.game_index_client +api/evennia.server.game_index_client.client +api/evennia.server.game_index_client.service +api/evennia.server.initial_setup +api/evennia.server.inputfuncs +api/evennia.server.manager +api/evennia.server.models +api/evennia.server.portal +api/evennia.server.portal.amp +api/evennia.server.portal.amp_server +api/evennia.server.portal.grapevine +api/evennia.server.portal.irc +api/evennia.server.portal.mccp +api/evennia.server.portal.mssp +api/evennia.server.portal.mxp +api/evennia.server.portal.naws +api/evennia.server.portal.portal +api/evennia.server.portal.portalsessionhandler +api/evennia.server.portal.rss +api/evennia.server.portal.ssh +api/evennia.server.portal.ssl +api/evennia.server.portal.suppress_ga +api/evennia.server.portal.telnet +api/evennia.server.portal.telnet_oob +api/evennia.server.portal.telnet_ssl +api/evennia.server.portal.tests +api/evennia.server.portal.ttype +api/evennia.server.portal.webclient +api/evennia.server.portal.webclient_ajax +api/evennia.server.profiling +api/evennia.server.profiling.dummyrunner +api/evennia.server.profiling.dummyrunner_settings +api/evennia.server.profiling.memplot +api/evennia.server.profiling.settings_mixin +api/evennia.server.profiling.test_queries +api/evennia.server.profiling.tests +api/evennia.server.profiling.timetrace +api/evennia.server.server +api/evennia.server.serversession +api/evennia.server.session +api/evennia.server.sessionhandler +api/evennia.server.signals +api/evennia.server.throttle +api/evennia.server.validators +api/evennia.server.webserver +api/evennia.settings_default +api/evennia.typeclasses +api/evennia.typeclasses.attributes +api/evennia.typeclasses.managers +api/evennia.typeclasses.models +api/evennia.typeclasses.tags +api/evennia.utils +api/evennia.utils.ansi +api/evennia.utils.batchprocessors +api/evennia.utils.containers +api/evennia.utils.create +api/evennia.utils.dbserialize +api/evennia.utils.eveditor +api/evennia.utils.evform +api/evennia.utils.evmenu +api/evennia.utils.evmore +api/evennia.utils.evtable +api/evennia.utils.funcparser +api/evennia.utils.gametime +api/evennia.utils.idmapper +api/evennia.utils.idmapper.manager +api/evennia.utils.idmapper.models +api/evennia.utils.idmapper.tests +api/evennia.utils.logger +api/evennia.utils.optionclasses +api/evennia.utils.optionhandler +api/evennia.utils.picklefield +api/evennia.utils.search +api/evennia.utils.test_resources +api/evennia.utils.text2html +api/evennia.utils.utils +api/evennia.utils.validatorfuncs +api/evennia.utils.verb_conjugation +api/evennia.utils.verb_conjugation.conjugate +api/evennia.utils.verb_conjugation.tests +api/evennia.web +api/evennia.web.admin +api/evennia.web.admin.accounts +api/evennia.web.admin.attributes +api/evennia.web.admin.comms +api/evennia.web.admin.frontpage +api/evennia.web.admin.help +api/evennia.web.admin.objects +api/evennia.web.admin.scripts +api/evennia.web.admin.server +api/evennia.web.admin.tags +api/evennia.web.admin.urls +api/evennia.web.admin.utils +api/evennia.web.api +api/evennia.web.api.filters +api/evennia.web.api.permissions +api/evennia.web.api.root +api/evennia.web.api.serializers +api/evennia.web.api.tests +api/evennia.web.api.urls +api/evennia.web.api.views +api/evennia.web.templatetags +api/evennia.web.templatetags.addclass +api/evennia.web.urls +api/evennia.web.utils +api/evennia.web.utils.adminsite +api/evennia.web.utils.backends +api/evennia.web.utils.general_context +api/evennia.web.utils.middleware +api/evennia.web.utils.tests +api/evennia.web.webclient +api/evennia.web.webclient.urls +api/evennia.web.webclient.views +api/evennia.web.website +api/evennia.web.website.forms +api/evennia.web.website.tests +api/evennia.web.website.urls +api/evennia.web.website.views +api/evennia.web.website.views.accounts +api/evennia.web.website.views.channels +api/evennia.web.website.views.characters +api/evennia.web.website.views.errors +api/evennia.web.website.views.help +api/evennia.web.website.views.index +api/evennia.web.website.views.mixins +api/evennia.web.website.views.objects +index +``` -```toctree:: +```{toctree} :hidden: - toc +toc ``` \ No newline at end of file diff --git a/evennia/accounts/manager.py b/evennia/accounts/manager.py index 3679444d00..b193ef3729 100644 --- a/evennia/accounts/manager.py +++ b/evennia/accounts/manager.py @@ -7,7 +7,7 @@ from django.utils import timezone from django.contrib.auth.models import UserManager from evennia.typeclasses.managers import TypedObjectManager, TypeclassManager -__all__ = ("AccountManager",) +__all__ = ("AccountManager", "AccountDBManager") # diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index c7c95cac62..6b1d8bcca3 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -26,6 +26,7 @@ CHANNEL_DEFAULT_TYPECLASS = class_from_module( # limit symbol import for API __all__ = ( "CmdChannel", + "CmdObjectChannel", "CmdAddCom", "CmdDelCom", diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index c439fe4eaa..588fd63eb5 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -34,6 +34,7 @@ _IDMAPPER = None # limit symbol import for API __all__ = ( + "CmdAccounts", "CmdReload", "CmdReset", "CmdShutdown", @@ -43,6 +44,7 @@ __all__ = ( "CmdTime", "CmdServerLoad", "CmdTasks", + "CmdTickers", ) diff --git a/evennia/commands/default/unloggedin.py b/evennia/commands/default/unloggedin.py index 533e0677b6..e6837551ec 100644 --- a/evennia/commands/default/unloggedin.py +++ b/evennia/commands/default/unloggedin.py @@ -20,6 +20,9 @@ __all__ = ( "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp", + "CmdUnconnectedEncoding", + "CmdUnconnectedInfo", + "CmdUnconnectedScreenreader", ) MULTISESSION_MODE = settings.MULTISESSION_MODE diff --git a/evennia/comms/models.py b/evennia/comms/models.py index 5d03b06b27..2200b6b2db 100644 --- a/evennia/comms/models.py +++ b/evennia/comms/models.py @@ -28,7 +28,7 @@ from evennia.comms import managers from evennia.locks.lockhandler import LockHandler from evennia.utils.utils import crop, make_iter, lazy_property -__all__ = ("Msg", "TempMsg", "ChannelDB") +__all__ = ("Msg", "TempMsg", "ChannelDB", "SubscriptionHandler") _GA = object.__getattribute__ diff --git a/evennia/objects/manager.py b/evennia/objects/manager.py index 993a5d6e1c..49a5473f80 100644 --- a/evennia/objects/manager.py +++ b/evennia/objects/manager.py @@ -8,7 +8,7 @@ from django.db.models.fields import exceptions from evennia.typeclasses.managers import TypedObjectManager, TypeclassManager from evennia.utils.utils import is_iter, make_iter, string_partial_matching -__all__ = ("ObjectManager",) +__all__ = ("ObjectManager", "ObjectDBManager") _GA = object.__getattribute__ # delayed import diff --git a/evennia/scripts/manager.py b/evennia/scripts/manager.py index 831aaa4876..6a8579fc12 100644 --- a/evennia/scripts/manager.py +++ b/evennia/scripts/manager.py @@ -6,7 +6,7 @@ from django.db.models import Q from evennia.typeclasses.managers import TypedObjectManager, TypeclassManager from evennia.utils.utils import make_iter -__all__ = ("ScriptManager",) +__all__ = ("ScriptManager", "ScriptDBManager") _GA = object.__getattribute__ VALIDATE_ITERATION = 0