Change to MyST parser

This commit is contained in:
Griatch 2021-10-21 21:04:14 +02:00
parent 53106e1dba
commit a51e4af609
443 changed files with 4925 additions and 3524 deletions

View file

@ -11,6 +11,7 @@ SPHINXBUILD ?= sphinx-build
SPHINXMULTIVERSION ?= sphinx-multiversion SPHINXMULTIVERSION ?= sphinx-multiversion
SPHINXAPIDOC ?= sphinx-apidoc SPHINXAPIDOC ?= sphinx-apidoc
SPHINXAPIDOCOPTS = --tocfile evennia-api --module-first --force -d 6 --separate --templatedir=$(SOURCEDIR)/_templates/ 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 SPHINXAPIDOCENV = members,undoc-members,show-inheritance
SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../evennia/*/tests/* ../evennia/*/tests.py SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../evennia/*/tests/* ../evennia/*/tests.py
@ -28,9 +29,12 @@ QUICKFILES=
help: help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@echo "Evennia-specific: " @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)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)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)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)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)" @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 make _clean_api_index
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTS) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE) @EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTS) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE)
make _reformat_apidoc_headers 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: _multiversion-autodoc-index:
make _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." @echo "To see result, open evennia/docs/build/latex/evennia.pdf in a PDF reader."
quick: quick:
make _quick_autodoc-index
make _quick-html-build $(FILES) make _quick-html-build $(FILES)
@echo "" @echo ""
@echo "Documentation built (single version, no autodocs)." @echo "Documentation built (single version, no autodocs)."

View file

@ -348,7 +348,7 @@ See below for examples of this.
This will display a one-line note that will pop even more than a normal `> note`. This will display a one-line note that will pop even more than a normal `> note`.
```` ````
```important:: ```{important}
This is important because it is! This is important because it is!
``` ```
```` ````
@ -359,7 +359,7 @@ A warning block is used to draw attention to particularly dangerous things, or f
mess up. mess up.
```` ````
```warning:: ```warning
Be careful about this ... Be careful about this ...
```` ````
@ -369,17 +369,17 @@ These will show up as one-line warnings that suggest an added, changed or deprec
feature beginning with particular version. feature beginning with particular version.
```` ````
```versionadded:: 1.0 ```{versionadded} 1.0
``` ```
```` ````
```` ````
```versionchanged:: 1.0 ```{versionchanged} 1.0
How the feature changed with this version. How the feature changed with this version.
``` ```
```` ````
```` ````
```deprecated:: 1.0 ```{deprecated} 1.0
``` ```
```` ````
@ -390,7 +390,7 @@ This will display an informative sidebar that floats to the side of regular cont
for example to remind the reader of some concept relevant to the text. 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 - There can be bullet lists
- in here. - in here.

31
docs/pylib/api_rst2md.py Executable file
View file

@ -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))

View file

@ -19,13 +19,19 @@ _NO_REMAP_STARTSWITH = [
"http://", "http://",
"https://", "https://",
"github:", "github:",
"api:",
"feature-request", "feature-request",
"report-bug", "report-bug",
"issue", "issue",
"bug-report", "bug-report",
] ]
# remove these prefixes from the url
_STRIP_PREFIX = [
"../../api/",
"../api/",
"./api/",
"api/",
"api:",
]
TXT_REMAPS = { TXT_REMAPS = {
"Developer Central": "Evennia Components overview", "Developer Central": "Evennia Components overview",
"Getting Started": "Setup Quickstart", "Getting Started": "Setup Quickstart",
@ -54,6 +60,8 @@ URL_REMAPS = {
"./Default-Command-Help": "api:evennia.commands.default#modules", "./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",
"../../../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 = {} _USED_REFS = {}
@ -123,11 +131,11 @@ def auto_link_remapper(no_autodoc=False):
# normal reference-links [txt](urls) # normal reference-links [txt](urls)
ref_regex = re.compile( ref_regex = re.compile(
r"\[(?P<txt>[\w -\[\]\`]+?)\]\((?P<url>.+?)\)", re.I + re.S + re.U + re.M r"\[(?P<txt>[\n\w -\[\]\`]+?)\]\((?P<url>.+?)\)", re.I + re.S + re.U + re.M
) )
# in document references # in document references
ref_doc_regex = re.compile( ref_doc_regex = re.compile(
r"\[(?P<txt>[\w -\`]+?)\]:\s+?(?P<url>.+?)(?=$|\n)", re.I + re.S + re.U + re.M r"\[(?P<txt>[\n\w -\`]+?)\]:\s+?(?P<url>.+?)(?=$|\n)", re.I + re.S + re.U + re.M
) )
def _sub(match): def _sub(match):
@ -139,23 +147,34 @@ def auto_link_remapper(no_autodoc=False):
txt = TXT_REMAPS.get(txt, txt) txt = TXT_REMAPS.get(txt, txt)
url = URL_REMAPS.get(url, url) 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): if any(url.startswith(noremap) for noremap in _NO_REMAP_STARTSWITH):
# skip regular http/s urls etc
return f"[{txt}]({url})"
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})" return f"[{txt}]({url})"
if "http" in url and "://" in url:
urlout = url
else:
fname, *part = url.rsplit("/", 1) fname, *part = url.rsplit("/", 1)
fname = part[0] if part else fname fname = part[0] if part else fname
fname = fname.rsplit(".", 1)[0]
fname, *anchor = fname.rsplit("#", 1) fname, *anchor = fname.rsplit("#", 1)
if ".md" in fname:
fname = fname.rsplit(".", 1)[0]
if not _CURRFILE.endswith("toc.md"): if not _CURRFILE.endswith("toc.md"):
_USED_REFS[fname] = url _USED_REFS[fname] = url
if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]: if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]:
cfilename = _CURRFILE.rsplit("/", 1)[-1] cfilename = _CURRFILE.rsplit("/", 1)[-1]
urlout = docref_map[_CURRFILE][fname] + ("#" + anchor[0] if anchor else "") urlout = docref_map[_CURRFILE][fname] + ".md" + ("#" + anchor[0].lower() if anchor else "")
if urlout != url: if urlout != url:
print(f" {cfilename}: [{txt}]({url}) -> [{txt}]({urlout})") print(f" {cfilename}: [{txt}]({url}) -> [{txt}]({urlout})")
else: else:
@ -172,11 +191,19 @@ def auto_link_remapper(no_autodoc=False):
txt = TXT_REMAPS.get(txt, txt) txt = TXT_REMAPS.get(txt, txt)
url = URL_REMAPS.get(url, url) 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): if any(url.startswith(noremap) for noremap in _NO_REMAP_STARTSWITH):
return f"[{txt}]: {url}" return f"[{txt}]: {url}"
if "http" in url and "://" in url: if "http" in url and "://" in url:
urlout = url urlout = url
elif url.startswith("evennia."):
# api link - we want to remove legacy #reference
if '#' in url:
_, urlout = url.rsplit('#', 1)
else: else:
fname, *part = url.rsplit("/", 1) fname, *part = url.rsplit("/", 1)
fname = part[0] if part else fname 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.") print(f" -- Auto-corrected links in {count} documents.")
for (fname, src_url) in sorted(toc_map.items(), key=lambda tup: tup[0]): 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") print(f" ORPHANED DOC: no refs found to {src_url}.md")
# write tocfile # write tocfile
with open(_TOC_FILE, "w") as fil: with open(_TOC_FILE, "w") as fil:
fil.write("# Toc\n") fil.write("```{toctree}\n")
if not no_autodoc: if not no_autodoc:
fil.write("- [API root](api/evennia-api.rst)") fil.write("- [API root](api/evennia-api.rst)")
@ -232,14 +259,14 @@ def auto_link_remapper(no_autodoc=False):
if ref == "toc": if ref == "toc":
continue continue
if not "/" in ref: # if not "/" in ref:
ref = "./" + ref # ref = "./" + ref
linkname = ref.replace("-", " ") # linkname = ref.replace("-", " ")
fil.write(f"\n- [{linkname}]({ref})") fil.write(f"\n{ref}") # - [{linkname}]({ref})")
# we add a self-reference so the toc itself is also a part of a toctree # 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.") print(" -- Auto-Remapper finished.")

View file

@ -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()

View file

@ -2,10 +2,11 @@
sphinx==3.2.1 sphinx==3.2.1
sphinx-multiversion==0.2.4 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 # 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 # 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

View file

@ -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. 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. 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 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, 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 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 special interactive python shell that allows you to experiment and try out things. It's recommended
@ -35,10 +35,10 @@ This will open an Evennia-aware python shell (using ipython). From within this s
evennia.<TAB> evennia.<TAB>
That is, enter `evennia.` and press the `<TAB>` key. This will show you all the resources made That is, enter `evennia.` and press the `<TAB>` 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. 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 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
@ -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`. 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 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 [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. 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 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 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 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. 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. 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 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 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 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 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 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 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 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. 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 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 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 group](https://sites.google.com/site/evenniaserver/discussions) and the [irc
chat](https://webchat.freenode.net/?channels=evennia) are also there for you. 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! And finally, of course, have fun!

View file

@ -7,24 +7,24 @@ to you, but some things may still be useful.
## Find your way ## Find your way
- [Directory-Overview](../Howto/Starting/Part1/Gamedir-Overview) - [Directory-Overview](../Howto/Starting/Part1/Gamedir-Overview.md)
- [Quirks of Evennia](./Quirks) - [Quirks of Evennia](./Quirks.md)
## Setting up a workflow ## Setting up a workflow
- [Setting up PyCharm](./Setting-up-PyCharm) - [Setting up PyCharm](./Setting-up-PyCharm.md)
- [Using Version-Control](./Version-Control) - [Using Version-Control](./Version-Control.md)
- [Updating Evennia sources](./Updating-Your-Game) - [Updating Evennia sources](./Updating-Your-Game.md)
## Coding away ## Coding away
- [Coding Introduction](./Coding-Introduction) - [Coding Introduction](./Coding-Introduction.md)
- [Ways to Debug](./Debugging) - [Ways to Debug](./Debugging.md)
- [Adding unit-tests](./Unit-Testing) - [Adding unit-tests](./Unit-Testing.md)
- [Things to remember when importing from evennia](./Flat-API) - [Things to remember when importing from evennia](./Flat-API.md)
## Advanced concepts ## Advanced concepts
- [Continuous Integration](./Continuous-Integration) - [Continuous Integration](./Continuous-Integration.md)
- [Using Travis](./Using-Travis) - [Using Travis](./Using-Travis.md)
- [Profiling](./Profiling) - [Profiling](./Profiling.md)

View file

@ -27,7 +27,7 @@ Among those you will need:
* A Continuous Integration Environment. * A Continuous Integration Environment.
* I recommend [TeamCity](https://www.jetbrains.com/teamcity/) which has an in-depth [Setup * 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) 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. * This could be Git or SVN or any other available SC.
## Linux TeamCity Setup ## Linux TeamCity Setup

View file

@ -1,7 +1,7 @@
# Things to remember about the flat API # Things to remember about the flat API
The flat API is a series of 'shortcuts' on the `evennia` main library root (defined in 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` ## To remember when importing from `evennia`

View file

@ -58,7 +58,7 @@ through the launcher:
This will start Evennia with the Server component running (in daemon mode) under This will start Evennia with the Server component running (in daemon mode) under
cProfile. You could instead try `--profile` with the `portal` argument to cProfile. You could instead try `--profile` with the `portal` argument to
profile the Portal (you would then need 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 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 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 dummies will semi-randomly perform various tasks from a list of possible
actions. Use `Ctrl-C` to stop the Dummyrunner. actions. Use `Ctrl-C` to stop the Dummyrunner.
```warning:: ```{warning}
You should not run the Dummyrunner on a production database. It You should not run the Dummyrunner on a production database. It
will spawn many objects and also needs to run with general permissions. will spawn many objects and also needs to run with general permissions.

View file

@ -4,7 +4,7 @@
This is a list of various quirks or common stumbling blocks that people often ask about or report 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. 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 Firstly: Reloading the server is a safe and usually quick operation which will *not* disconnect any
accounts. 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` 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. 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 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 account, you need to consider which `MULTIACCOUNT_MODE` you are in. If you are in
@ -28,7 +28,7 @@ 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 other. You must also set the lockstring of the Character to allow the Account to "puppet" this
particular character. 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 When storing a mutable object (usually a list or a dictionary) in an Attribute
@ -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 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. 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 *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. 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 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 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. 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 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 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 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. 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 Python implements a system of [magic
methods](https://docs.python.org/3/reference/datamodel.html#emulating-container-types), usually methods](https://docs.python.org/3/reference/datamodel.html#emulating-container-types), usually
@ -104,13 +104,13 @@ 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. The moral of the story-- it can be dangerous to tinker with magic methods on typeclassed objects.
Try to avoid doing so. 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 - 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 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` 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 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: instructions, use the following command to fix it:
```shell ```shell

View file

@ -153,7 +153,7 @@ class in the same module to get access to the command-specific utilities mention
### Unit testing contribs with custom models ### 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 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 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 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 add the model to Evennia's central `settings_default.py` file - this would always create your
@ -330,7 +330,7 @@ to see how it looks when it fails.
### Testing commands ### 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 This section will test the proper execution of the 'abilities' command, as described in the DELETED

View file

@ -2,9 +2,9 @@
Fortunately, it's extremely easy to keep your Evennia server up-to-date. If you haven't already, see 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 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 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 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). 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 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 dependency). This will be announced on the mailing list/forum. If you run into errors when starting
@ -72,7 +72,7 @@ When the database schema changes, you just go to your game folder and run
evennia migrate evennia migrate
> Hint: If the `evennia` command is not found, you most likely need to activate your > 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 ## Resetting your database

View file

@ -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 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. 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 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 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 change into the upstream master and you then do `git pull` to update master usual. Now that the

View file

@ -1,27 +1,27 @@
# Accounts # 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 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) game account. In order to actually get on the game the Account must *puppet* an [Object](./Objects.md)
(normally a [Character](./Objects#Character)). (normally a [Character](./Objects.md#characters)).
Exactly how many Sessions can interact with an Account and its Puppets at once is determined by 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 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 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 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 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 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 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 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 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 allows for exploring the game using a different permission set (but you can't escalate your
@ -76,7 +76,7 @@ You should now see the Attributes on yourself.
## Properties on Accounts ## Properties on Accounts
Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses)), the Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses.md)), the
Account also has the following custom properties: Account also has the following custom properties:
- `user` - a unique link to a `User` Django object, representing the logged-in user. - `user` - a unique link to a `User` Django object, representing the logged-in user.
@ -91,11 +91,11 @@ as
- `is_superuser` (bool: True/False) - if this account is a superuser. - `is_superuser` (bool: True/False) - if this account is a superuser.
Special handlers: 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`. 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 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): 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 - `get_puppet` - get a currently puppeted object connected to the Account and a given session id, if

View file

@ -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 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. probably need to store roleplaying-attributes like strength and agility. And so on.
[Typeclassed](./Typeclasses) game entities ([Accounts](./Accounts), [Objects](./Objects), [Typeclassed](./Typeclasses.md) game entities ([Accounts](./Accounts.md), [Objects](./Objects.md),
[Scripts](./Scripts) and [Channels](./Communications)) always have *Attributes* associated with them. [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 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 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 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. 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 **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 ## The .db and .ndb shortcuts
To save persistent data on a Typeclassed object you normally use the `db` (DataBase) operator. Let's 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 ```python
# saving # 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 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 `accessing_object` to the call one can also make sure to check permissions before modifying
anything. 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. 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 - `remove(...)` - Remove the given Attribute. This can optionally be made to check for permission
before performing the deletion. - `clear(...)` - removes all Attributes from object. before performing the deletion. - `clear(...)` - removes all Attributes from object.
- `all(...)` - returns all Attributes (of the given category) attached to this 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. access and editing. The `Nattribute` offers no concept of access control.
Some examples: Some examples:
@ -118,23 +118,23 @@ An Attribute object is stored in the database. It has the following properties:
to `attrname`. to `attrname`.
- `value` - this is the value of the Attribute. This value can be anything which can be pickled - - `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 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 example
`obj.db.attrname = value`, the `value` is stored here. `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 - `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 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 Attributes
in this way). To modify this property you need to use the [Attribute in this way). To modify this property you need to use the
Handler](Attributes#The_Attribute_Handler). [Attribute Handler](./Attributes.md#the-attributehandler).
- `strvalue` - this is a separate value field that only accepts strings. This severely limits the - `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 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 except when re-using Attributes for some other purpose ([Nicks](./Nicks.md) use it). It is only
accessible via the [Attribute Handler](./Attributes#The_Attribute_Handler). accessible via the [Attribute Handler](./Attributes.md#the-attributehandler).
There are also two special properties: 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). use Attributes behind the scenes).
- `model` - this is a *natural-key* describing the model this Attribute is attached to. This is on - `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 the form *appname.modelclass*, like `objects.objectdb`. It is used by the Attribute and
@ -162,7 +162,7 @@ default
during heavy loads. during heavy loads.
- A more valid reason for using non-persistent data is if you *want* to lose your state when logging - 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 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 does potentially harmful stuff to your character object. With non-persistent storage you can be
sure sure
that whatever is messed up, it's nothing a server reboot can't clear up. 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 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 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, `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. below.
### Storing single objects ### 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 Since you can use any combination of the above iterables, this is generally not much of a
limitation. 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. stored in the iterable.
> As mentioned in the previous section, database entities (aka typeclasses) are not possible to > 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 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). 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 The relevant lock types are
- `attrread` - limits who may read the value of the Attribute - `attrread` - limits who may read the value of the Attribute

View file

@ -1,7 +1,7 @@
# Batch Code Processor # 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- page describes the Batch-*code* processor. The Batch-*command* one is covered [here](Batch-Command-
Processor). 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 - 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 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 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 aliases is unique to the room (like "room56") and you will henceforth be able to always uniquely
search and find it later. search and find it later.

View file

@ -1,7 +1,7 @@
# Batch Command Processor # 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- page describes the Batch-*command* processor. The Batch-*code* one is covered [here](Batch-Code-
Processor). 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 This also means there are several pitfalls when designing and adding certain types of objects. Here
are some examples: 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 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 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 ... 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 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 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 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' - [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 *evennia mode*. This is an Emacs major mode found in `evennia/utils/evennia-mode.el`. It offers

View file

@ -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 powerful but also more complex - it lets you use Evennia's API to code your world in full-fledged
Python code. Python code.
- The [Batch Command Processor](./Batch-Command-Processor) - The [Batch Command Processor](./Batch-Command-Processor.md)
- The [Batch Code Processor](./Batch-Code-Processor) - 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 If you plan to use international characters in your batchfiles you are wise to read about *file
encodings* below. 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 file with lots of non-ASCII letters in the editor of your choice, then import to make sure it works
as it should. 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). 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 **A footnote for the batch-code processor**: Just because *Evennia* can parse your file and your

View file

@ -2,8 +2,8 @@
Bootstrap provides many utilities and components you can use when customizing Evennia's web 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. 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 > 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) >[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. > to get a feel for how to add pages to Evennia's website to test these examples.
## General Styling ## General Styling
@ -77,4 +77,4 @@ width of the page - Evennia's base site uses the former.
### Forms ### Forms
[Forms](https://getbootstrap.com/docs/4.0/components/forms/) are highly customizable with Bootstrap. [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 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) over [the web character gen tutorial.](../Howto/Web-Character-Generation.md)

View file

@ -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 connected to a channel, sending a message to it will automatically distribute
it to every other subscriber. it to every other subscriber.
Channels can be used both for chats between [Accounts](./Accounts) and between Channels can be used both for chats between [Accounts](./Accounts.md) and between
[Objects](./Objects) (usually Characters). Chats could be both OOC [Objects](./Objects.md) (usually Characters). Chats could be both OOC
(out-of-character) or IC (in-charcter) in nature. Some examples: (out-of-character) or IC (in-charcter) in nature. Some examples:
- A support channel for contacting staff (OOC) - 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) - Group telephathy (IC)
- Walkie talkies (IC) - Walkie talkies (IC)
```versionchanged:: 1.0 ```{versionchanged} 1.0
Channel system changed to use a central 'channel' command and nicks instead of Channel system changed to use a central 'channel' command and nicks instead of
auto-generated channel-commands and -cmdset. ChannelHandler was removed. 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 ## Using channels in-game
In the default command set, channels are all handled via the mighty 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 `chan`). By default, this command will assume all entities dealing with
channels are `Accounts`. channels are `Accounts`.
@ -66,7 +67,7 @@ system automatically sets up an personal alias so you can do this instead:
public Hello world public Hello world
```warning:: ```{warning}
This shortcut will not work if the channel-name has spaces in it. 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 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! 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`, > 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 > 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 > 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 able to _rejoin_ if you boot them. You will need to run `channel/boot` to
actually kick them out. 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. 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) channel/lock buildchannel = listen:all();send:perm(Builders)
@ -158,7 +159,7 @@ Channels use three lock-types by default:
#### Restricting channel administration #### 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 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 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 (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)" 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. - `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 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 ## Allowing Characters to use Channels
The default `channel` command ([evennia.commands.default.comms.CmdChannel](api:evennia.commands.default.comms.CmdChannel)) The default `channel` command ([evennia.commands.default.comms.CmdChannel](evennia.commands.default.comms.CmdChannel))
sits in the `Account` [command set](./Command-Sets). It is set up such that it will 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 always operate on `Accounts`, even if you were to add it to the
`CharacterCmdSet`. `CharacterCmdSet`.
It's a one-line change to make this command accept non-account callers. But for 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 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. and inherit from that instead.
## Customizing channel output and behavior ## 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 overriding the `channel` command will get you very far. But you can also tweak
channels themselves. channels themselves.
Channels are [Typeclassed](./Typeclasses) entities. This means they are Channels are [Typeclassed](./Typeclasses.md) entities. This means they are
persistent in the database, can have [attributes](./Attributes) and [Tags](./Tags) persistent in the database, can have [attributes](./Attributes.md) and [Tags](./Tags.md)
and can be easily extended. and can be easily extended.
To change which channel typeclass Evennia uses for default commands, change To change which channel typeclass Evennia uses for default commands, change
`settings.BASE_CHANNEL_TYPECLASS`. The base command class is `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 There is an empty child class in `mygame/typeclasses/channels.py`, same
as for other typelass-bases. as for other typelass-bases.
@ -299,11 +300,11 @@ details.
## Channel logging ## Channel logging
```versionchanged:: 0.7 ```{versionchanged} 0.7
Channels changed from using Msg to TmpMsg and optional log files. 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. 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`, Channels have all the standard properties of a Typeclassed entity (`key`,
`aliases`, `attributes`, `tags`, `locks` etc). This is not an exhaustive list; `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 - `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. 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. `mygame/server/logs/`). You should usually not change this.
- `channel_prefix_string` - this property is a string to easily change how - `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}] "` the channel is prefixed. It takes the `channelname` format key. Default is `"[{channelname}] "`
and produces output like `[public] ...``. and produces output like `[public] ...`.
- `subscriptions` - this is the [SubscriptionHandler](api:evennia.comms.comms#SubscriptionHandler), which - `subscriptions` - this is the [SubscriptionHandler](evennia.comms.models.SubscriptionHandler), which
has methods `has`, `add`, `remove`, `all`, `clear` and also `online` (to get has methods `has`, `add`, `remove`, `all`, `clear` and also `online` (to get
only actually online channel-members). only actually online channel-members).
- `wholist`, `mutelist`, `banlist` are properties that return a list of subscribers, - `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 This pattern accepts an `{alias}` formatting marker. Don't mess with this unless you really
want to change how channels work. want to change how channels work.
- `channel_msg_nick_replacement` - this is a string on the [nick replacement - `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`. `channel` command and is by default `channel {channelname} = $1`.
Notable `Channel` hooks: Notable `Channel` hooks:

View file

@ -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) obj = search_object(objname)
``` ```
- [evennia.search_account](../wiki/evennia.accounts.manager#accountdbmanagersearch_account) - [`evennia.search_account`](evennia.accounts.manager.AccountDBManager.search_account)
- [evennia.search_object](../wiki/evennia.objects.manager#objectdbmanagersearch_object) - [`evennia.search_object`](evennia.objects.manager.ObjectDBManager.search_object)
- [evennia.search_object_by_tag](../wiki/evennia.utils.search#search_object_by_tag) - [`evennia.search(object)_by_tag`](evennia.utils.search.search_tag)
- [evennia.search_script](../wiki/evennia.scripts.manager#scriptdbmanagersearch_script) - [`evennia.search_script`](evennia.scripts.manager.ScriptDBManager.search_script)
- [evennia.search_channel](../wiki/evennia.comms.managers#channeldbmanagersearch_channel) - [`evennia.search_channel`](evennia.comms.managers.ChannelDBManager.search_channel)
- [evennia.search_message](../wiki/evennia.comms.managers#msgmanagersearch_message) - [`evennia.search_message`](evennia.comms.managers.MsgManager.search_message)
- [evennia.search_help](../wiki/evennia.help.manager#helpentrymanagersearch_help) - [`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 Note that these latter methods will always return a `list` of results, even if the list has one or
zero entries. 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") myobj = evennia.create_objects("game.gamesrc.objects.myobj.MyObj", key="MyObj")
``` ```
- [evennia.create_account](../wiki/evennia.utils.create#create_account) - [`evennia.create_account`](evennia.utils.create.create_account)
- [evennia.create_object](../wiki/evennia.utils.create#create_object) - [`evennia.create_object`](evennia.utils.create.create_object)
- [evennia.create_script](../wiki/evennia.utils.create#create_script) - [`evennia.create_script`](evennia.utils.create.create_script)
- [evennia.create_channel](../wiki/evennia.utils.create#create_channel) - [`evennia.create_channel`](evennia.utils.create.create_channel)
- [evennia.create_help_entry](../wiki/evennia.utils.create#create_help_entry) - [`evennia.create_help_entry`](evennia.utils.create.create_help_entry)
- [evennia.create_message](../wiki/evennia.utils.create#create_message) - [`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 Each of these create-functions have a host of arguments to further customize the created entity. See
`evennia/utils/create.py` for more information. `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 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 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 ```python
import evennia 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 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 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 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 `deferred` return object can usually be ignored, but calling its `.cancel()` method will abort
the delay prematurely. the delay prematurely.
`utils.delay` is the lightest form of delayed call in Evennia. For other way to create time-bound `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 > 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 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 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 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 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 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: `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 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 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 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 ### Ansi Coloring Tools
- [evennia.ansi](api:evennia.utils.ansi) - [evennia.utils.ansi](evennia.utils.ansi)
## Display utilities ## Display utilities
### Making ascii tables ### 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 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 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. 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. instructions.
### Menus ### Menus
- [evennia.EvMenu](github:evennia.utils.evmenu#evmenu) - [evennia.EvMenu](evennia.utils.evmenu.EvMenu)

View file

@ -1,7 +1,7 @@
# Command Sets # 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. 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 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 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 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` 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). topic).
When an account enters a command, cmdsets from the Account, Character, its location, and elsewhere 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. 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 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. without the explanations.
## Defining Command Sets ## 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()`. 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 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 customize which command sets are added to your objects by using `self.cmdset.add()` or
`self.cmdset.add_default()`. `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 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 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 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 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, 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. 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 - `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 - `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 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 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- 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 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): 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 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 `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 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`. before using `key_mergetype`.
- `duplicates` (bool/None default `None`) - this determines what happens when merging same-priority - `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 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 ## 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 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). 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 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`. `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`. `-10`.
- All cmdsets on the Character/Object (assuming the Account is currently puppeting such a - All cmdsets on the Character/Object (assuming the Account is currently puppeting such a
Character/Object). Merge priority `0`. 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. `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` - 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. *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` or character is currently connected to. Merge priority `+101`. Will not be included if `no_channels`
option is active in the merge stack. option is active in the merge stack.
Note that an object does not *have* to share its commands with its surroundings. A Character's 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 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` 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 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 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. objects inside them, or `cmd:holds()` to make their commands available only if they are held.

View file

@ -1,9 +1,9 @@
# Command System # Command System
- [Commands](./Commands) - [Commands](./Commands.md)
- [Command Sets](./Command-Sets) - [Command Sets](./Command-Sets.md)
- [Command Auto-help](./Help-System#command-auto-help-system) - [Command Auto-help](./Help-System.md#command-auto-help-system)
See also: See also:
- [Default Command Help](api:evennia.commands.default#modules) - [Default Commands](./Default-Commands.md)
- [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) - [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md)

View file

@ -1,14 +1,14 @@
# Commands # 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. 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 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 directly related to the game world such as *look*, *get*, *drop* and so on, or administrative
commands such as *examine* or *@dig*. 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 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 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 - can find the default commands in `evennia/commands/default`. You should not edit these directly -
@ -16,7 +16,7 @@ they will be updated by the Evennia team as new features are added. Rather you s
for inspiration and inherit your own designs from them. for inspiration and inherit your own designs from them.
There are two components to having a command running - the *Command* class and the 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). [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 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. 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*. *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 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 page detailing [Command Sets](./Command-Sets.md). There is also a step-by-step
[Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) that will get you started quickly without the [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) that will get you started quickly without the
extra explanations. extra explanations.
## Defining Commands ## 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` 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`. 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. 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 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. 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. * `sessid` - `sessid.id`, a unique integer identifier of the session.
* `account` - the [Account](./Accounts) object connected to this Session. None if not logged in. * `account` - the [Account](./Accounts.md) object connected to this Session. None if not logged in.
* An [Account](./Accounts). This only happens if `account.execute_cmd()` was used. No Session * An [Account](./Accounts.md). This only happens if `account.execute_cmd()` was used. No Session
information can be obtained in this case. information can be obtained in this case.
* `caller` - this is set to the puppeted Object if such an object can be determined (without * `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, 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*` * `session` - `None*`
* `sessid` - `None*` * `sessid` - `None*`
* `account` - Set to the Account object. * `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). NPC).
* `caller` - This is set to the calling Object in question. * `caller` - This is set to the calling Object in question.
* `session` - `None*` * `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 - `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 command. The value of this depends on what type of object is calling the command; see the previous
section. 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). previous section).
- `sessid` - the unique id of `self.session`, for quick lookup. - `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. - `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 - `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 *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 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 `arg_regex` property if you want to enforce a space to make `lookat sword` give a command-not-found
error. 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 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 `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. commands defined on it, like in the example of the "check time" command defined on a "Clock" object.
@ -150,7 +150,7 @@ not
used, but they could be used to implement alternate help-display systems. 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 - `.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. 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 evennia.utils.evtable) styled based on the
session calling this command. The args/kwargs are the same as for EvTable, except styling defaults session calling this command. The args/kwargs are the same as for EvTable, except styling defaults
are set. are set.
@ -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. either matches. This is important for merging cmdsets described below.
- `aliases` (optional list) - a list of alternate names for the command (`["glance", "see", "l"]`). - `aliases` (optional list) - a list of alternate names for the command (`["glance", "see", "l"]`).
Same name rules as for `key` applies. Same name rules as for `key` applies.
- `locks` (string) - a [lock definition](./Locks), usually on the form `cmd:<lockfuncs>`. Locks is a - `locks` (string) - a [lock definition](./Locks.md), usually on the form `cmd:<lockfuncs>`. Locks is a
rather big topic, so until you learn more about locks, stick to giving the lockstring `"cmd:all()"` 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 to make the command available to everyone (if you don't provide a lock string, this will be assigned
for you). 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. or replace the storage.
- `arg_regex` (optional raw string): Used to force the parser to limit itself and tell it when the - `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 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. 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` (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 [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 either want to write your help entries manually or hide the existence of a command from `help`'s
generated list. generated list.
- `is_exit` (bool) - this marks the command as being used for an in-game exit. This is, by default, - `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 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 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. 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: Below is how you define a simple alternative "`smile`" command:
@ -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. 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 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 ### 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 > 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 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 ## System commands
@ -458,7 +458,7 @@ display the "Huh?" error message.
matches. matches.
- User is not allowed to execute the command (`syscmdkeys.CMD_NOPERM`) - Default is to display the - User is not allowed to execute the command (`syscmdkeys.CMD_NOPERM`) - Default is to display the
"Huh?" error message. "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 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. 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 - 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 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- 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 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 (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.* *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 The functionality of [Exit](./Objects.md) 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 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 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, 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 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 current account, if caller is a puppeted object.
- CmdSets defined on the Session itself. - CmdSets defined on the Session itself.
- The active CmdSets of eventual objects in the same location (if any). This includes commands - 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 - 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- 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. 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 8. All the grouped CmdSets are *merged* in reverse priority into one combined CmdSet according to

View file

@ -2,7 +2,7 @@
TODO: Remove this page? TODO: Remove this page?
- [Channels](./Channels) - are used for implementing in-game chat rooms. - [Channels](./Channels.md) - are used for implementing in-game chat rooms.
- [Msg](./Msg)-objects are used for storing messages in the database (email-like) - [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 and is a building block for implementing other game systems. It's used by the
`page` command by default. `page` command by default.

View file

@ -1,54 +1,54 @@
# Core Components # Core Components
These are the 'building blocks' out of which Evennia is built. This documentation is complementary to, and often goes deeper 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) - [Typeclasses](./Typeclasses.md)
- [Sessions](./Sessions) - [Sessions](./Sessions.md)
- [Acccounts](./Accounts) - [Acccounts](./Accounts.md)
- [Guests](../Concepts/Guest-Logins) - [Guests](../Concepts/Guest-Logins.md)
- [Objects](./Objects) - [Objects](./Objects.md)
- [Scripts](./Scripts) - [Scripts](./Scripts.md)
- [Channels and Messages](./Communications) - [Channels and Messages](./Communications.md)
- [Attributes](./Attributes) - [Attributes](./Attributes.md)
- [Nicks](./Nicks) - [Nicks](./Nicks.md)
- [Tags](./Tags) - [Tags](./Tags.md)
- [Spawner and prototypes](./Prototypes) - [Spawner and prototypes](./Prototypes.md)
- [Help entries](./Help-System) - [Help entries](./Help-System.md)
## Commands ## Commands
- [Command system](./Command-System) - [Available Default Commands](./Default-Commands.md)
- [Commands](./Commands) - [Command system](./Command-System.md)
- [Command-Sets](./Command-Sets) - [Commands](./Commands.md)
- [The Connection Screen](./Connection-Screen) - [Command-Sets](./Command-Sets.md)
- [Available default Commands](api:evennia.commands.default#modules) - [The Connection Screen](./Connection-Screen.md)
- [Batch-Processors](./Batch-Processors) - [Batch-Processors](./Batch-Processors.md)
- [Batch-Code-Processor](./Batch-Code-Processor) - [Batch-Code-Processor](./Batch-Code-Processor.md)
- [Batch-Command-Processor](./Batch-Command-Processor) - [Batch-Command-Processor](./Batch-Command-Processor.md)
## Utils and tools ## Utils and tools
- [Misc Utils](./Coding-Utils) - [Misc Utils](./Coding-Utils.md)
- [EvEditor](./EvEditor) - [EvEditor](./EvEditor.md)
- [EvMenu](./EvMenu) - [EvMenu](./EvMenu.md)
- [EvMore](./EvMore) - [EvMore](./EvMore.md)
- [MonitorHandler](./MonitorHandler) - [MonitorHandler](./MonitorHandler.md)
- [TickerHandler](./TickerHandler) - [TickerHandler](./TickerHandler.md)
- [Lock system](./Locks) - [Lock system](./Locks.md)
- [FuncParser](./FuncParser) - [FuncParser](./FuncParser.md)
## Server and network ## Server and network
- [Portal](./Portal-And-Server) - [Portal](./Portal-And-Server.md)
- [Inputfuncs](./Inputfuncs) - [Inputfuncs](./Inputfuncs.md)
- [Outputfuncs](./Outputfuncs) - [Outputfuncs](./Outputfuncs.md)
- [Protocols](../Concepts/Custom-Protocols) - [Protocols](../Concepts/Custom-Protocols.md)
- [Server](./Server) - [Server](./Server.md)
- [Server conf object](./Server-Conf) - [Server conf object](../Setup/Server-Conf.md)
- [Webserver](./Webserver) - [Webserver](./Webserver.md)
- [Webclient](./Webclient) - [Webclient](./Webclient.md)
- [Bootstrap](./Bootstrap-Components-and-Utilities) - [Bootstrap](./Bootstrap-Components-and-Utilities.md)
- [Signals](./Signals) - [Signals](./Signals.md)

View file

@ -20,17 +20,17 @@ Effective, but not very exciting. You will most likely want to change this to be
your game. This is simple: your game. This is simple:
1. Edit `mygame/server/conf/connection_screens.py`. 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 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 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 one such string/screen is defined in the module, a *random* screen will be picked from among those
available. 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 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 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 `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. tutorial section on how to add new commands to a default command set.

View file

@ -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_)

View file

@ -5,7 +5,7 @@ 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, mimicking the well-known VI line editor. It offers line-by-line editing, undo/redo, line deletes,
search/replace, fill, dedent and more. search/replace, fill, dedent and more.
### Launching the editor ## Launching the editor
The editor is created as follows: The editor is created as follows:
@ -29,7 +29,7 @@ cleanup and exit messages to the user must be handled by this function.
It has no other mechanical function. It has no other mechanical function.
- `persistent` (default `False`): if set to `True`, the editor will survive a reboot. - `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. This is an example command for setting a specific Attribute using the editor.
@ -65,7 +65,7 @@ class CmdSetTestAttr(Command):
key=key) key=key)
``` ```
### Persistent editor ## Persistent editor
If you set the `persistent` keyword to `True` when creating the editor, it will remain open even 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 when reloading the game. In order to be persistent, an editor needs to have its callback functions
@ -107,7 +107,7 @@ class CmdSetTestAttr(Command):
key=key, persistent=True) 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 editor mimics the `VIM` editor as best as possible. The below is an excerpt of the return from
the in-editor help command (`:h`). the in-editor help command (`:h`).
@ -154,7 +154,7 @@ the in-editor help command (`:h`).
<txt> - longer string, usually not needed to be enclosed in quotes. <txt> - 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 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 `/edit` switch that will open the EvEditor in code mode. This mode isn't significantly different

View file

@ -33,7 +33,7 @@ said functions, like `{"nodename": <function>, ...}`
## Launching the menu ## Launching the menu
Initializing the menu is done using a call to the `evennia.utils.evmenu.EvMenu` class. This is the 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 ```python
# in, for example gamedir/commands/command.py # 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 - `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 - `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 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 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 - `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 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. 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. `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 - `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 <variable>` to inspect a specific state list the current state of the menu and use `menudebug <variable>` to inspect a specific state
@ -428,16 +428,15 @@ See `evennia/utils/evmenu.py` for the details of their default implementations.
## Examples: ## Examples:
- **[Simple branching menu](./EvMenu#example-simple-branching-menu)** - choose from options - **[Simple branching menu](./EvMenu.md#example-simple-branching-menu)** - choose from options
- **[Dynamic goto](./EvMenu#example-dynamic-goto)** - jumping to different nodes based on response - **[Dynamic goto](./EvMenu.md#example-dynamic-goto)** - jumping to different nodes based on response
- **[Set caller properties](./EvMenu#example-set-caller-properties)** - a menu that changes things - **[Set caller properties](./EvMenu.md#example-set-caller-properties)** - a menu that changes things
- **[Getting arbitrary input](./EvMenu#example-get-arbitrary-input)** - entering text - **[Getting arbitrary input](./EvMenu.md#example-get-arbitrary-input)** - entering text
- **[Storing data between nodes](./EvMenu#example-storing-data-between-nodes)** - keeping states and - **[Storing data between nodes](./EvMenu.md#example-storing-data-between-nodes)** - keeping states and
information while in the menu 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 before moving to the next
- **[Full Menu](./EvMenu#example-full-menu):** a complete example - **[Yes/No prompt](#example-yesno-prompt)** - entering text with limited possible responses
- **[Yes/No prompt](./EvMenu#example-yesno-prompt)** - entering text with limited possible responses
(this is *not* using EvMenu but the conceptually similar yet technically unrelated `get_input` (this is *not* using EvMenu but the conceptually similar yet technically unrelated `get_input`
helper function accessed as `evennia.utils.evmenu.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 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 `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 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. 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 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 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 ## 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 > 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 > 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 > 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 > you can look at [this extension suggested on the mailing
> list](https://groups.google.com/forum/#!category-topic/evennia/evennia-questions/16pi0SfMO5U). > list](https://groups.google.com/forum/#!category-topic/evennia/evennia-questions/16pi0SfMO5U).
@ -993,8 +992,8 @@ auto-created by the `list_node` decorator.
## Assorted notes ## Assorted notes
The EvMenu is implemented using [Commands](./Commands). When you start a new EvMenu, the user of the 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) with the commands they need to navigate the menu. 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 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 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 of the menu, you should store the cmdset on `caller.ndb._menutree` and wait to actually assign it

View file

@ -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. 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: 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) 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`) client's screen height (as determined by the NAWS handshake or by `settings.CLIENT_DEFAULT_HEIGHT`)
the pager will show up, something like this: the pager will show up, something like this:

View file

@ -1,10 +1,6 @@
# The Inline Function Parser # The Inline Function Parser
``` The [FuncParser](evennia.utils.funcparser.FuncParser) extracts and executes
```
The [FuncParser](api:evennia.utils.funcparser#evennia.utils.funcparser.FuncParser) extracts and executes
'inline functions' 'inline functions'
embedded in a string on the form `$funcname(args, kwargs)`. Under the hood, this will 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 lead to a call to a Python function you control. The inline function call will be replaced by
@ -48,18 +44,18 @@ 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: 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 - _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. 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 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 to safely call functions to set non-string values to prototype values, get random values, reference
other fields of the prototype, and more. other fields of the prototype, and more.
- _Actor-stance in messages to others_. In the - _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 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. 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 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 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 do very advanced things and allow builders a lot of power, all-out coding is something
@ -69,7 +65,7 @@ The FuncParser can be applied to any string. Out of the box it's applied in a fe
## Using the FuncParser ## Using the FuncParser
You can apply inline function parsing to any string. The You can apply inline function parsing to any string. The
[FuncParser](api:evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`. [FuncParser](evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`.
```python ```python
from evennia.utils import funcparser from evennia.utils import funcparser
@ -200,7 +196,7 @@ non-developer players/builders and some things (such as complex classes/callable
safe/possible to convert from string representation. safe/possible to convert from string representation.
In `evennia.utils.utils` is a helper called 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 [safe_convert_to_types](evennia.utils.utils.safe_convert_to_types). This function
automates the conversion of simple data types in a safe way: automates the conversion of simple data types in a safe way:
```python ```python
@ -239,10 +235,10 @@ following tools (which you may also find useful to experiment with on your own):
lists/dicts from the input line to real Python objects. 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 - [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 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 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. containers like lists/dicts etc, so this and `literal_eval` are complementary to each other.
```warning:: ```{warning}
It may be tempting to run use Python's in-built ``eval()`` or ``exec()`` functions as converters since 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 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 know that ONLY developers will ever modify the string going into the callable. The parser is intended
@ -262,39 +258,39 @@ more to them when you create your `FuncParser` instance to have those callables
These are the 'base' callables. These are the 'base' callables.
- `$eval(expression)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_eval)) - - `$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 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"`. 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. 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)) - - `$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 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`; `$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]`. 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`. 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)) - - `$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 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. 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. works like the `randint()` python function and always returns an integer.
- `$choice(list)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_choice)) - - `$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 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. 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 `-` this will pad content. `$pad("Hello", 30, c, -)` will lead to a text centered in a 30-wide block surrounded by `-`
characters. 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 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. 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. 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). 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`. - `$ljust` - shortcut to justify-left. Takes all other kwarg of `$just`.
- `$rjust` - shortcut to right justify. - `$rjust` - shortcut to right justify.
- `$cjust` - shortcut to center justify. - `$cjust` - shortcut to center justify.
- `$clr(startcolor, text[, endcolor])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_clr)) - - `$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 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`. given, the string will go back to neutral, so `$clr(r, Hello)` is equivalent to `|rHello|n`.
@ -304,13 +300,14 @@ These are callables that requires access-checks in order to search for objects.
extra reserved kwargs to be passed when running the parser: extra reserved kwargs to be passed when running the parser:
```python ```python
parser.parse_to_any(string, caller=<object or account>, access="control", ...)`
parser.parse_to_any(string, caller=<object or account>, access="control", ...)
``` ```
The `caller` is required, it's the the object to do the access-check for. The `access` kwarg is the 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"`. [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)) - - `$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 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 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. match; if `return_list` is `True` a list of 0, 1 or more matches will be returned instead.
@ -321,7 +318,7 @@ The `caller` is required, it's the the object to do the access-check for. The `a
### `evennia.utils.funcparser.ACTOR_STANCE_CALLABLES` ### `evennia.utils.funcparser.ACTOR_STANCE_CALLABLES`
These are used to implement actor-stance emoting. They are used by the 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 [DefaultObject.msg_contents](evennia.objects.objects.DefaultObject.msg_contents) method
by default. by default.
These all require extra kwargs be passed into the parser: These all require extra kwargs be passed into the parser:
@ -333,16 +330,16 @@ parser.parse(string, caller=<obj>, receiver=<obj>, mapping={'key': <obj>, ...})
Here the `caller` is the one sending the message and `receiver` the one to see it. The `mapping` contains 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. references to other objects accessible via these callables.
- `$you([key])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_you)) - - `$you([key])` ([code](evennia.utils.funcparser.funcparser_callable_you)) -
if no `key` is given, this represents the `caller`, otherwise an object from `mapping` 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 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 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 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. depending on who sees it, and also to reference other people in the same way.
- `$You([key])` - same as `$you` but always capitalized. - `$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 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. to do this, and only works for English verbs.
### Example ### Example

View file

@ -64,7 +64,7 @@ regular code editor, see below).
Evennia collects help entries from three sources: Evennia collects help entries from three sources:
- _Auto-generated command help_ - this is literally the doc-strings of - _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 easier to maintain and keep up-to-date if the developer can change them at the
same time as they do the code. same time as they do the code.
- _Database-stored help entries_ - These are created in-game (using the - _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. extra space at beginning and end.
A `text` that scrolls off the screen will automatically be paginated by 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 `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 exactly where the pager should break the page, mark the break with the control
character `\f`. character `\f`.
#### Subtopics #### Subtopics
```versionadded:: 1.0 ```{versionadded} 1.0
``` ```
Rather than making a very long help entry, the `text` may also be broken up 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. 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 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 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 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 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 (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 can explicitly set `auto_help` class property to `False` in your command
definition. definition.
@ -233,8 +233,8 @@ entry = create_help_entry("emote",
category="Roleplaying", locks="view:all()") category="Roleplaying", locks="view:all()")
``` ```
The entity being created is a [evennia.help.models.HelpEntry](api:evennia.help.models.HelpEntry) The entity being created is a [evennia.help.models.HelpEntry](evennia.help.models.HelpEntry)
object. This is _not_ a [Typeclassed](./Typeclasses) entity and is not meant to 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 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 text is stored in a field `entrytext`. It does not provide a `get_help` method
like commands, stores and returns the `entrytext` directly. 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 ### File-help entries
```versionadded:: 1.0 ```{versionadded} 1.0
``` ```
File-help entries are created by the game development team outside of the game. The 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 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. 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 ## Customizing the look of the help system
This is done almost exclusively by overriding the `help` command 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 Since the available commands may vary from moment to moment, `help` is
responsible for collating the three sources of help-entries (commands/db/file) 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 simple `==`, `startswith` and `in` matching (there are so relatively few of them
at that point). at that point).
```versionchanged:: 1.0 ```{versionchanged} 1.0
Replaced the old bag-of-words algorithm with lunr package. Replaced the old bag-of-words algorithm with lunr package.
``` ```

View file

@ -1,9 +1,9 @@
# Inputfuncs # 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 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 (args), {kwargs})` and Evennia will use this to try to find and call an inputfunc on the form
```python ```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 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 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. and then pass on the input to the central Commandhandler.
### echo ### echo
@ -134,7 +134,7 @@ to expand. By default the following values can be retrieved:
accepted names if given an unfamiliar callback name. 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 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. 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 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 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 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 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 that you must supply the name also when stopping to let the system know which monitor should be
cancelled. cancelled.

View file

@ -2,9 +2,9 @@
For most games it is a good idea to restrict what people can do. In Evennia such restrictions are 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), applied and checked by something called *locks*. All Evennia entities ([Commands](./Commands.md),
[Objects](./Objects), [Scripts](./Scripts), [Accounts](./Accounts), [Help System](./Help-System), [Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md), [Help System](./Help-System.md),
[messages](./Communications#Msg) and [channels](./Communications#Channels)) are accessed through locks. [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. 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 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. 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. - `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 - `control` - who is the "owner" of the object. Can set locks, delete it etc. Defaults to the
creator of the object. creator of the object.
- `call` - who may call Object-commands stored on this Object except for the Object itself. By - `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. - `get`- who may pick up the object and carry it around.
- `puppet` - who may "become" this object and control it as their "character". - `puppet` - who may "become" this object and control it as their "character".
- `attrcreate` - who may create new attributes on the object (default True) - `attrcreate` - who may create new attributes on the object (default True)
- [Characters](./Objects#Characters): - [Characters](./Objects.md#characters):
- Same as for Objects - Same as for Objects
- [Exits](./Objects#Exits): - [Exits](./Objects.md#exits):
- Same as for Objects - Same as for Objects
- `traverse` - who may pass the exit. - `traverse` - who may pass the exit.
- [Accounts](./Accounts): - [Accounts](./Accounts.md):
- `examine` - who may examine the account's properties. - `examine` - who may examine the account's properties.
- `delete` - who may delete the account. - `delete` - who may delete the account.
- `edit` - who may edit the account's attributes and properties. - `edit` - who may edit the account's attributes and properties.
- `msg` - who may send messages to the account. - `msg` - who may send messages to the account.
- `boot` - who may boot 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 - `attrread` - see/access attribute
- `attredit` - change/delete 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, - `control` - who is administrating the channel. This means the ability to delete the channel,
boot listeners etc. boot listeners etc.
- `send` - who may send to the channel. - `send` - who may send to the channel.
- `listen` - who may subscribe and listen 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) - `examine` - who may view this help entry (usually everyone)
- `edit` - who may edit this help entry. - `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 - `false()/none()/superuser()` - give access to none. Superusers bypass the check entirely and are
thus the only ones who will pass this check. 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 - `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. - `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. - `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 - `attr(attrname, value)` - checks so an attribute exists on accessing_object *and* has the given
value. value.
- `attr_gt(attrname, value)` - checks so accessing_object has a value larger (`>`) than the given - `attr_gt(attrname, value)` - checks so accessing_object has a value larger (`>`) than the given
@ -250,7 +250,7 @@ a Lock lookup.
## Default locks ## Default locks
Evennia sets up a few basic locks on all new objects and accounts (if we didn't, noone would have 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 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). 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 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 ## 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`. called `box`.
> create/drop 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 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: 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. > set box/get_err_msg = You are not strong enough to lift this box.

View file

@ -23,10 +23,10 @@ MONITOR_HANDLER.add(obj, fieldname, callback,
``` ```
- `obj` ([Typeclassed](./Typeclasses) entity) - the object to monitor. Since this must be - `obj` ([Typeclassed](./Typeclasses.md) entity) - the object to monitor. Since this must be
typeclassed, it means you can't monitor changes on [Sessions](./Sessions) with the monitorhandler, for typeclassed, it means you can't monitor changes on [Sessions](./Sessions.md) with the monitorhandler, for
example. 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 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 `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 of Attributes. This difference matters, since the MonitorHandler will automatically know to watch

View file

@ -1,6 +1,6 @@
# Msg # 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 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 a message, some metadata and will always have a sender and one or more
recipients. recipients.
@ -14,7 +14,7 @@ good uses for `Msg` objects:
- game-wide email stored in 'mailboxes'. - game-wide email stored in 'mailboxes'.
```important:: ```{important}
A `Msg` does not have any in-game representation. So if you want to use them 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 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. Channels dropped Msg-support. Now only used in `page` command by default.
``` ```
## Msg in code ## Msg in code
The Msg is intended to be used exclusively in code, to build other game systems. It is _not_ 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 a [Typeclassed](./Typeclasses.md) entity, which means it cannot (easily) be overridden. It
doesn't support Attributes (but it _does_ support [Tags](./Tags)). It tries to be lean 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. and small since a new one is created for every message.
You create a new message with `evennia.create_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 ### Properties on Msg
- `senders` - there must always be at least one sender. This is a set of - `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). 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 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 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 python-path, for example). While most systems expect a single sender, it's
possible to have any number of them. possible to have any number of them.
- `receivers` - these are the ones to see the Msg. These are again any combination of - `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. 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 - `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 an email-like system it would be the subject line. This can be independently searched, making
this a powerful place for quickly finding messages. this a powerful place for quickly finding messages.
- `message` - the actual text being sent. - `message` - the actual text being sent.
- `date_sent` - this is auto-set to the time the Msg was created (and thus presumably 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 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'`. 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 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 reasons since it allows quick filtering of messages not intended for a given
target. target.
@ -88,7 +88,7 @@ You can search for `Msg` objects in various ways:
## TempMsg ## 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 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 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 expecting a `Msg` but where you just want to process the message without saving

View file

@ -1,7 +1,7 @@
# Nicks # 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. 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 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 ## Coding with nicks
Nicks are stored as the `Nick` database model and are referred from the normal Evennia 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. offers effective error checking, searches and conversion.
```python ```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` 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. 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. `nick_type="channel"` in order to allow users to create their own custom aliases to channels.
# Advanced note # 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`). Attributes has this set to `None`).
The nick stores the replacement data in the Attribute.db_value field as a tuple with four fields The nick stores the replacement data in the Attribute.db_value field as a tuple with four fields

View file

@ -3,7 +3,7 @@
All in-game objects in Evennia, be it characters, chairs, monsters, rooms or hand grenades are 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 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 ## 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 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 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 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 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 `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 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. to use though - see next section.
## Properties and functions on Objects ## 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: 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 - `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 - `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. 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 - `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. main use is for [Exits](./Objects.md#exits), it's otherwise usually unset.
- `nicks` - as opposed to aliases, a [Nick](./Nicks) holds a convenient nickname replacement for a - `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 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 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. 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 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. 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 - `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: 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). 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 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. `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. - `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 - `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. 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 - `clear_contents()` - this will not delete anything, but rather move all contents (except Exits) to
their designated `Home` locations. their designated `Home` locations.
- `delete()` - deletes this object, first calling `clear_exits()` and - `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 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 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 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 updated list of all the available hooks or the [API for DefaultObject here](evennia.objects.objects.DefaultObject).
here](api:evennia.objects.objects#defaultobject).
## Subclasses of `Object` ## Subclasses of `Object`
@ -126,10 +125,10 @@ practice they are all pretty similar to the base Object.
### Characters ### 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 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 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 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 inherit your own class from `evennia.DefaultCharacter` and make sure to use
`super()` to call the parent methods you should be fine. In `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 *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 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 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 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 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. 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 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 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. 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. In `mygame/typeclasses/exits.py` there is an empty `Exit` class for you to modify.
The process of traversing an exit is as follows: 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 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 involves the "source" (the current location) and the `destination` (this is stored on the Exit
object). object).
1. The Exit command checks the `traverse` lock on the Exit object 1. The Exit command checks the `traverse` lock on the Exit object

View file

@ -1,3 +1,3 @@
# Outputfuncs # Outputfuncs
TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB). TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB.md).

View file

@ -1,15 +1,15 @@
# Permissions # Permissions
A *permission* is simply a text string stored in the handler `permissions` on `Objects` 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 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). 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" Permission strings are not case-sensitive, so "Builder" is the same as "builder"
etc. etc.
Permissions are used as a convenient way to structure access levels and Permissions are used as a convenient way to structure access levels and
hierarchies. It is set by the `perm` command and checked by the hierarchies. It is set by the `perm` command and checked by the
`PermissionHandler.check` method as well as by the specially the `perm()` and `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 All new accounts are given a default set of permissions defined by
`settings.PERMISSION_ACCOUNT_DEFAULT`. `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 perm/account/del Tommy = Builders
Note the use of the `/account` switch. It means you assign the permission to the 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". happens to be named "Tommy".
There can be reasons for putting permissions on Objects (especially NPCS), but 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 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 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, 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 In code, you add/remove Permissions via the `PermissionHandler`, which sits on all
typeclassed entities as the property `.permissions`: typeclassed entities as the property `.permissions`:
@ -73,7 +73,7 @@ that permission to pass.
## Checking permissions ## Checking permissions
It's important to note that you check for the permission of a *puppeted* 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 of any `Account` connected to that Object before checking for
permissions on the Object. In the case of hierarchical permissions (Admins, permissions on the Object. In the case of hierarchical permissions (Admins,
Builders etc), the Account permission will always be used (this stops an Account 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 Using the `.check` method is the way to go, it will take hierarchical
permissions into account, check accounts/sessions etc. permissions into account, check accounts/sessions etc.
```warning ```{warning}
Don't confuse `.permissions.check()` with `.permissions.has()`. The .has() Don't confuse `.permissions.check()` with `.permissions.has()`. The .has()
method checks if a string is defined specifically on that PermissionHandler. method checks if a string is defined specifically on that PermissionHandler.
@ -111,7 +111,7 @@ permissions into account, check accounts/sessions etc.
### Lock funcs ### Lock funcs
While the `PermissionHandler` offers a simple way to check perms, [Lock 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. 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 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). objects (regardless of hierarchical perm or not).
- `pperm_above` - like `perm_above`, but for Accounts only. - `pperm_above` - like `perm_above`, but for Accounts only.
### Some examples ### Some examples
Adding permissions and checking with locks Adding permissions and checking with locks

View file

@ -2,7 +2,7 @@
Evennia consists of two processes, known as *Portal* and *Server*. They can be controlled from 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 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 the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the

View file

@ -2,10 +2,10 @@
The *spawner* is a system for defining and creating individual objects from a base template called a 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. 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 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 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 first create a `Mobile` typeclass that holds everything common to mobiles in the game, like generic
@ -105,12 +105,12 @@ instead.
exist. exist.
- `destination` - a valid `#dbref`. Only used by exits. - `destination` - a valid `#dbref`. Only used by exits.
- `permissions` - list of permission strings, like `["Accounts", "may_use_red_door"]` - `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 - `aliases` - list of strings for use as aliases
- `tags` - list [Tags](./Tags). These are given as tuples `(tag, category, data)`. - `tags` - list [Tags](./Tags.md). These are given as tuples `(tag, category, data)`.
- `attrs` - list of [Attributes](./Attributes). These are given as tuples `(attrname, value, - `attrs` - list of [Attributes](./Attributes.md). These are given as tuples `(attrname, value,
category, lockstring)` 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 This is
convenient for simple Attributes - use `attrs` for full control of Attributes. convenient for simple Attributes - use `attrs` for full control of Attributes.
@ -119,7 +119,7 @@ Deprecated as of Evennia 0.8:
- `ndb_<name>` - sets the value of a non-persistent attribute (`"ndb_"` is stripped from the name). - `ndb_<name>` - 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. 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 - - `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 ### 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."} "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 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 called (this is always a string). A protfunc is a [FuncParser function](./FuncParser.md) run
[InlineFunc](../Concepts/TextTags#inline-functions) - they are actually every time the prototype is used to spawn a new object.
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).
Here is how a protfunc is defined (same as an inlinefunc). 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 ### 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 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 advantage of being easily modifiable and sharable between builders but you need to work with them
using in-game tools. using in-game tools.

View file

@ -1,19 +1,19 @@
# Scripts # 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 *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 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`. (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. 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 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 location or command-execution like [Objects](./Objects.md) and no connection to a particular
player/session like [Accounts](./Accounts). This means they are perfectly suitable for acting 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, 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 who is involved in the current fight, tracking an ongoing barter and so on. They are great as
persistent system handlers. 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 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 independently of the rest of the script as needed. This component is optional
and complementary to other timing functions in Evennia, like and complementary to other timing functions in Evennia, like
[evennia.utils.delay](api:evennia.utils.utils#evennia.utils.utils.delay) and [evennia.utils.delay](evennia.utils.utils.delay) and
[evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat). [evennia.utils.repeat](evennia.utils.utils.repeat).
- Scripts can _attach_ to Objects and Accounts via e.g. `obj.scripts.add/remove`. In the - 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 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 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 in various ways. For historical reasons, a Script _not_ attached to an object is referred to as a
_Global_ Script. _Global_ Script.
```versionchanged:: 1.0 ```{versionchanged} 1.0
In previus Evennia versions, stopping the Script's timer also meant deleting the Script object. 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 Starting with this version, the timer can be start/stopped separately and `.delete()` must be called
on the Script explicitly to delete it. 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: 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/pause #11
> scripts/delete #566 > scripts/delete #566
```versionchanged:: 1.0 ```{versionchanged} 1.0
The `addscript` command used to be only `script` which was easy to confuse with `scripts`. 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 Here are some examples of working with Scripts in-code (more details to follow in later
sections). sections).
@ -111,13 +111,13 @@ new_script.delete()
timed_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 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 In `mygame/typeclasses/scripts.py` is an empty `Script` class already set up. You
can use this as a base for your own scripts. 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 See the [create_script](evennia.utils.create.create_script) and
[search_script](api:evennia.utils.search#evennia.utils.search.search_script) API documentation for more options [search_script](evennia.utils.search.search_script) API documentation for more options
on creating and finding Scripts. on creating and finding Scripts.
### Timed Scripts ## Timed Scripts
There are several properties one can set on the Script to control its timer component. 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 - `.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. 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 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.delay](evennia.utils.utils.delay) and
[evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat) functions [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. 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 In fact, for making a single delayed call (`script.repeats==1`), the `utils.delay` call is
probably always the better choice. 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 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`. 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`. 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) 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 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 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`. 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 - `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. 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. 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 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. 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`. 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), 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 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 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 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 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. supported here.
```warning:: ```{warning}
Before setting up Evennia to manage your script like this, make sure that your Script typeclass 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 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. 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. 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 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 parts of the execution mechanism that is hard to interpret. One way to make it

View file

@ -1,3 +1,3 @@
# Server component # Server component
TODO: This is currently in [Portal-and-Server](./Portal-And-Server). TODO: This is currently in [Portal-and-Server](./Portal-And-Server.md).

View file

@ -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 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. 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 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 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 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. 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 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 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), 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. - `sessid` - The unique session-id. This is an integer starting from 1.
- `address` - The connected client's address. Different protocols give different information here. - `address` - The connected client's address. Different protocols give different information here.
- `logged_in` - `True` if the user authenticated to this session. - `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`. `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`. 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`. - `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. 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. `command.msg()` is often the safest bet.
You can get the `session` in two main ways: 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. 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. `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 * 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.* *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. its own Sessions, syncing them to each other.
The "Session" we normally refer to is actually the `ServerSession`. Its counter-part on the Portal 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 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 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 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. on building new protocols.
To get all Sessions in the game (i.e. all currently connected clients), you access the server-side To get all Sessions in the game (i.e. all currently connected clients), you access the server-side

View file

@ -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 used way for users to themselves create accounts during login. It passes and extra kwarg `ip` with
the client IP of the connecting account. the client IP of the connecting account.
- `SIGNAL_ACCOUNT_POST_LOGIN` - this will always fire when the account has authenticated. Sends - `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 - `SIGNAL_ACCCOUNT_POST_FIRST_LOGIN` - this fires just before `SIGNAL_ACCOUNT_POST_LOGIN` but only
if if
this is the *first* connection done (that is, if there are no previous sessions connected). Also this is the *first* connection done (that is, if there are no previous sessions connected). Also

View file

@ -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 *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 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 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. object.
In Evennia, Tags are technically also used to implement `Aliases` (alternative names for objects) 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) ## 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 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 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. makes them very quick to lookup in the database - this is the whole point.
Tags have the following properties, stored in the database: 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 ## Adding/Removing Tags
You can tag any *typeclassed* object, namely [Objects](./Objects), [Accounts](./Accounts), You can tag any *typeclassed* object, namely [Objects](./Objects.md), [Accounts](./Accounts.md),
[Scripts](./Scripts) and [Channels](./Communications). General tags are added by the *Taghandler*. The [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: tag handler is accessed as a property `tags` on the relevant entity:
```python ```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 @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 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 created elsewhere. You can then supply custom search methods that *only* find objects tagged with
tags of that category. An example of this tags of that category. An example of this
is found in the [Zone tutorial](../Concepts/Zones). is found in the [Zone tutorial](../Concepts/Zones.md).

View file

@ -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 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. 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 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. 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 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 > 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 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. may store.
When testing, you can stop all tickers in the entire game with `tickerhandler.clear()`. You can also 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()`. 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 ### When *not* to use TickerHandler

View file

@ -5,8 +5,8 @@
different game entities as Python classes, without having to modify the database schema for every different game entities as Python classes, without having to modify the database schema for every
new type. new type.
In Evennia the most important game entities, [Accounts](./Accounts), [Objects](./Objects), In Evennia the most important game entities, [Accounts](./Accounts.md), [Objects](./Objects.md),
[Scripts](./Scripts) and [Channels](./Communications#Channels) are all Python classes inheriting, at [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 varying distance, from `evennia.typeclasses.models.TypedObject`. In the documentation we refer to
these objects as being "typeclassed" or even "being a typeclass". 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. 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 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". 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 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. 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_ 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 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 code would give an error (since `DefaultObject` is now globally found both in this module and in the
@ -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 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 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- `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 functions take a lot of extra keywords allowing you to set things like [Attributes](./Attributes.md) and
[Tags](./Tags) all in one go. These keywords don't use the `db_*` prefix. This will also automatically [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. 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 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`: 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: The typeclassed entity has several common handlers:
- `tags` - the [TagHandler](./Tags) that handles tagging. Use `tags.add()` , `tags.get()` etc. - `tags` - the [TagHandler](./Tags.md) that handles tagging. Use `tags.add()` , `tags.get()` etc.
- `locks` - the [LockHandler](./Locks) that manages access restrictions. Use `locks.add()`, - `locks` - the [LockHandler](./Locks.md) that manages access restrictions. Use `locks.add()`,
`locks.get()` etc. `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()` `attributes.add()`
etc. etc.
- `db` (DataBase) - a shortcut property to the AttributeHandler; allowing `obj.db.attrname = value` - `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. database.
- `ndb` (NotDataBase) - a shortcut property to the Non-peristent AttributeHandler. Allows - `ndb` (NotDataBase) - a shortcut property to the Non-peristent AttributeHandler. Allows
`obj.ndb.attrname = value` `obj.ndb.attrname = value`
Each of the typeclassed entities then extend this list with their own properties. Go to the 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 respective pages for [Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md) and
[Channels](./Communications) for more info. It's also recommended that you explore the available [Channels](./Communications.md) 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 entities using [Evennia's flat API](../Evennia-API.md) to explore which properties and methods they have
available. available.
### Overloading hooks ## Overloading hooks
The way to customize typeclasses is usually to overload *hook methods* on them. Hooks are methods 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`, 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 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. 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 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 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 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` - 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. 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 - 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 due to how Python inheritance works your changes will automatically be applied to all children once
you have reloaded the server. 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 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: 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). here](github:evennia.typeclasses.models#typedobjectswap_typeclass).
## How typeclasses actually work # How typeclasses actually work
*This is considered an advanced section.* *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](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 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 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 subclasses of them are "proxies", extending them with Python code without actually modifying the
database layout. 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 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. 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 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 allows things like on-object handlers and properties to be stored on typeclass instances and to not

View file

@ -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 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. 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 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 data for the resource you want. You can also _send_ such JSON data
in order to update the database from the outside. 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 The main controlling setting is `REST_FRAMEWORK`, which is a dict. The keys
`DEFAULT_LIST_PERMISSION` and `DEFAULT_CREATE_PERMISSIONS` control who may `DEFAULT_LIST_PERMISSION` and `DEFAULT_CREATE_PERMISSIONS` control who may
view and create new objects via the api respectively. By default, users with 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 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` 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",...}] "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"} >>> data = {"db_key": "A shiny sword"}
>>> response = requests.post("https://www.mygame.com/api/objects", >>> 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 other parts of their documentation is required for expanding and
customizing the API. 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. and static files.
- API templates (for the web-display) is located in `evennia/web/api/templates/rest_framework/` (it must - 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). be named such to allow override of the original REST framework templates).

View file

@ -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 permissions to accounts. The superuser is the only permission level that is
also relevant in-game. `User Permissions` and `Groups` found on the `Account` 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 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 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 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 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. the `Can delete Account` permission, for example.
```important:: ```{important}
If you grant staff-status and permissions to an Account and they still cannot If you grant staff-status and permissions to an Account and they still cannot
access the admin's content, try reloading the server. 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 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`` well have their admin ``Superuser status`` set too. The reason is that ``py``
@ -116,7 +116,7 @@ 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 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 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. Django provides a lot of tools to automate the admin-generation for us.

View file

@ -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 webserver is responsible for serving the html pages of the game's website. It
can also serve static resources like images and music. 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 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 in-game, and there is no risk of working with objects that are temporarily
out-of-sync in the database. 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 The webserver runs on Twisted and is meant to be used in a production
environment. It leverages the Django web framework and provides: 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 `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 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 do so with the webclient since they share the same login credentials (there
is no way to safely do auto-login with telnet clients). 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. 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 game communication (sending/receiving data) is done by the javascript client
on the page opening a websocket connection directly to Evennia's Portal. 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). (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 used on a page to have buttons react, make small animations etc that doesn't
require the server. 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 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. for actually displaying the client GUI, allows you to resize windows etc.

View file

@ -1,14 +1,14 @@
# Game website # Game website
When Evennia starts it will also start a [Webserver](./Webserver) as part of the When Evennia starts it will also start a [Webserver](./Webserver.md) as part of the
[Server](./Portal-And-Server) process. This uses [Django](https://docs.djangoproject.com) [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, 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. to see it.
The website allows existing players to log in using an account-name and 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 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 So if you are logged into the website, opening the webclient will automatically
log you into the game as that account. log you into the game as that account.
@ -28,11 +28,11 @@ In the top menu you can find
show a list of all channels available to you and allow you to view the latest 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 discussions. Most channels require logging in, but the `Public` channel can
also be viewed by non-loggedin users. 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 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 account can be read. This is a good way to present a body of help for people
to read outside of the game. 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. - _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 - _Log in/out_ - Allows you to authenticate using the same credentials you use
in the game. in the game.
@ -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 > DEBUG mode leaks memory (for retaining debug info) and is *not* safe to use
> for a production game! > 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 page is
1. Web browser sends HTTP request to server with an URL 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 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, 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 ## Examples of commom web changes
```important:: ```{important}
Django is a very mature web-design framework. There are endless Django is a very mature web-design framework. There are endless
internet-tutorials, courses and books available to explain how to use Django. internet-tutorials, courses and books available to explain how to use Django.
@ -321,7 +321,7 @@ your copy. Just remember to reload.
### Using Flat Pages ### Using Flat Pages
The absolutely simplest way to add a new web page is to use the `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. styling as the rest of the site.
For the `Flat pages` module to work you must first set up a _Site_ (or For the `Flat pages` module to work you must first set up a _Site_ (or

View file

@ -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` - `at_err_kwargs` - an optional dictionary that will be fed as keyword arguments to the `at_err`
errback. 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 ```python
from evennia import utils, Command 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 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: You can also try the following snippet just see how it works:

View file

@ -114,14 +114,14 @@ is not what you want in this case.
- **cboot mychannel = thomas** -- Boot a subscriber from a channel you control - **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 - **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: Locking a specific command (like `page`) is accomplished like so:
1. Examine the source of the command. [The default `page` command class]( 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 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' 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 "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. current location etc.
2. **perm/account thomas = page_banned** -- Give the account the 'permission' which causes (in this 2. **perm/account thomas = page_banned** -- Give the account the 'permission' which causes (in this
case) the lock to fail. case) the lock to fail.

View file

@ -2,7 +2,7 @@
*OBS: This gives only a brief introduction to the access system. Locks and permissions are fully *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 ## 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 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 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): 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 1. **Developers** basically have the same access as superusers except that they do *not* sidestep

View file

@ -1,4 +1,4 @@
## Clickable links # Clickable links
Evennia supports clickable links for clients that supports it. This marks certain text so it can be 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 clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web

View file

@ -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 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 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 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 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`. 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, 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, 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" 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 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 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). them anyway).
To colour your text you put special tags in it. Evennia will parse these and convert them to the To colour your text you put special tags in it. Evennia will parse these and convert them to the
@ -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 > 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 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 Xterm256 the ANSI colors will be used instead and there will be no visible difference between using
upper- and lower-case background tags. upper- and lower-case background tags.
@ -100,7 +100,7 @@ space.
- `|*` This will invert the current text/background colours. Can be useful to mark things (but see - `|*` This will invert the current text/background colours. Can be useful to mark things (but see
below). below).
##### Caveats of `|*` ### Caveats of `|*`
The `|*` tag (inverse video) is an old ANSI standard and should usually not be used for more than to 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 mark short snippets of text. If combined with other tags it comes with a series of potentially
@ -178,6 +178,6 @@ to activate some features manually.
## More reading ## 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. use of ANSI color tags and the pitfalls of mixing ANSI and Xterms256 color tags in the same context.

View file

@ -1,30 +1,30 @@
# Core Concepts # 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 ## General concepts
- [Asynchronous processing](./Async-Process) - [Asynchronous processing](./Async-Process.md)
- [On Soft-Code](./Soft-Code) - [On Soft-Code](./Soft-Code.md)
- [Using MUX as standard for default commands](./Using-MUX-as-a-Standard) - [Using MUX as standard for default commands](./Using-MUX-as-a-Standard.md)
## Access ## Access
- [Multisession modes](./Multisession-modes) - [Multisession modes](./Multisession-modes.md)
- [Permissions](./Building-Permissions) - [Permissions](./Building-Permissions.md)
- [Banning](./Banning) - [Banning](./Banning.md)
## Extending the Server ## Extending the Server
- [Custom Protocols](./Custom-Protocols) - [Custom Protocols](./Custom-Protocols.md)
- [Bootstrap](./Bootstrap-&-Evennia) - [Bootstrap](./Bootstrap-&-Evennia.md)
- [Creating new models](./New-Models) - [Creating new models](./New-Models.md)
## Text processing ## Text processing
- [Change the language of the server](./Internationalization) - [Change the language of the server](./Internationalization.md)
- [Server text-encoding](./Text-Encodings) - [Server text-encoding](./Text-Encodings.md)
- [Text tags](./TextTags) - [Text tags](./TextTags.md)
## Web features ## Web features
- [Web features](./Web-Features) - [Web features](./Web-Features.md)

View file

@ -5,9 +5,9 @@
their own custom client protocol.* 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 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 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 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*. *Telnet* protocol. All Portal Sessions are stored and managed by the Portal's *sessionhandler*.
@ -27,7 +27,7 @@ You <->
InputFunc 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` 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) (which translates between data coming in/out over the wire to/from Evennia internal representation)
as well as the `InputFunc` (which handles incoming data). as well as the `InputFunc` (which handles incoming data).
@ -219,11 +219,11 @@ in our case means sending "foo" across the network.
### Receiving data ### Receiving data
Just because the protocol is there, does not mean Evennia knows what to do with it. An 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 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 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 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 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 components - however they are accessed - links to the *Portal Session*, which is the actual common

View file

@ -10,16 +10,16 @@ Guest accounts are turned off by default. To activate, add this to your `game/se
GUEST_ENABLED = True GUEST_ENABLED = True
Henceforth users can use `connect guest` (in the default command set) to login with a guest account. 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* 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- whenever the user logs off or the server resets (but not during a reload). They are literally re-
usable throw-away accounts. usable throw-away accounts.
You can add a few more variables to your `settings.py` file to customize your guests: 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"`. 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. which is the lowest permission level in the hierarchy.
- `GUEST_START_LOCATION` - the `#dbref` to the starting location newly logged-in guests should - `GUEST_START_LOCATION` - the `#dbref` to the starting location newly logged-in guests should
appear at. Defaults to `"#2` (Limbo). appear at. Defaults to `"#2` (Limbo).

View file

@ -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 (besides English) with some level of support. Generally, any language not
updated after May 2021 will be missing some translations. updated after May 2021 will be missing some translations.
```eval_rst ```{eval-rst}
+---------------+----------------------+--------------+ +---------------+----------------------+--------------+
| Language Code | Language | Last updated | | 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 of the supported languages found in `locale/` (and in the list above). Restart
the server to activate i18n. the server to activate i18n.
```important:: ```{important}
Even for a 'fully translated' language you will still see English text 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 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, If you get errors concerning `gettext` or `xgettext` on Windows,
see the `Django documentation <https://docs.djangoproject.com/en/3.2/topics/i18n/translation/#gettext-on-windows>`_ see the `Django documentation <https://docs.djangoproject.com/en/3.2/topics/i18n/translation/#gettext-on-windows>`_
@ -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 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 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/` 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 repo itself. If you see the `locale/` folder you are in the right place. Make

View file

@ -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 - 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 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 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 are later synced to the Server Session. Since this is not something the player
controls, we'll not explore this further here. controls, we'll not explore this further here.
- The client can send an *inputcommand* to the server. Traditionally this only - 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. 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 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 - 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 be formatted in a special way, but it's still a raw string. If Telnet SSL is
active, the string will be encrypted. active, the string will be encrypted.
@ -73,7 +73,7 @@ it belongs. This is then sent over the AMP connection.
### ServerSessionHandler (ingoing) ### ServerSessionHandler (ingoing)
On the Server side, the AMP unpickles the data and associates the session id with the server-side 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()` in turn calls `ServerSession.data_in()`
### ServerSession (ingoing) ### ServerSession (ingoing)
@ -101,7 +101,7 @@ not found, an error will be raised.
### Inputfunc ### 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` the `default` inputfunc which has form `default(session, cmdname, *args, **kwargs)`, where `cmdname`
is the un-matched inputcommand string. 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 This will intelligently convert different input to the same form. So `msg("Hello")` will end up as
an outputcommand `("text", ("Hello",), {})`. 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 session to receive the data. Said data is pickled together with the Session id then sent over the
AMP bridge. AMP bridge.

View file

@ -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 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- 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 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. sometimes things may be easier to handle by adding your own database model.
## Overview of database tables ## 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 evennia migrate
This will add your new database table to the database. If you have put your game under version 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. to version control.
## Defining your models ## 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. 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 > 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. 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 `obj.db.myinstance = mydatastore`. If you know you'll never store your model instances in Attributes
the `db_date_created` field is optional. the `db_date_created` field is optional.

View file

@ -8,7 +8,7 @@ window pane.
## Briefly on input/outputcommands ## Briefly on input/outputcommands
Inside Evennia, all server-client communication happens in the same way (so plain text is also an 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 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: 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 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 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 `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). details).
When a message is outgoing (at the 'Client-end' of the message path) the outputcommand is handled by 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 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 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 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 ## Sending and receiving an OOB message
@ -59,7 +59,7 @@ drop any other types of outputfuncs.
you turn off telnet completely and only rely on the webclient, you should never rely on non-`text` you turn off telnet completely and only rely on the webclient, you should never rely on non-`text`
OOB messages always reaching all targets. 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). accept more you need to add more inputfuncs (see that page for more info).
## Supported OOB protocols ## Supported OOB protocols
@ -105,7 +105,6 @@ where all the capitalized words are telnet character constants specified in
these in the listings below. these in the listings below.
Input/Outputfunc | GMCP-Command Input/Outputfunc | GMCP-Command
------------------
`[cmd_name, [], {}]` | Cmd.Name `[cmd_name, [], {}]` | Cmd.Name
`[cmd_name, [arg], {}]` | Cmd.Name arg `[cmd_name, [arg], {}]` | Cmd.Name arg
`[cmd_na_me, [args],{}]` | Cmd.Na.Me [args] `[cmd_na_me, [args],{}]` | Cmd.Na.Me [args]
@ -116,7 +115,6 @@ 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: common GMCP implementations we have a few hard-coded mappings for those:
GMCP command name | Input/Outputfunc name GMCP command name | Input/Outputfunc name
-----------------
"Core.Hello" | "client_options" "Core.Hello" | "client_options"
"Core.Supports.Get" | "client_options" "Core.Supports.Get" | "client_options"
"Core.Commands.Get" | "get_inputfuncs" "Core.Commands.Get" | "get_inputfuncs"
@ -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`. and `TABLEOPEN`/`TABLECLOSE` are specified in `evennia/server/portal/telnet_oob`.
Outputfunc/Inputfunc | MSDP instruction Outputfunc/Inputfunc | MSDP instruction
-------------------------
`[cmdname, [], {}]` | VAR cmdname VAL `[cmdname, [], {}]` | VAR cmdname VAL
`[cmdname, [arg], {}]` | VAR cmdname VAL arg `[cmdname, [arg], {}]` | VAR cmdname VAL arg
`[cmdname, [args],{}]` | VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE `[cmdname, [args],{}]` | VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE

View file

@ -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 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 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 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. pseudo-softcode plugin aimed at developers wanting to script their game from inside it.

View file

@ -2,16 +2,17 @@
Evennia understands various extra information embedded in text: 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. 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`. 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 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` circumstances. The parser is run on all outgoing messages if `settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED=True`
(disabled by default). (disabled by default).
```toctree:: ```{toctree}
:hidden"
Colors.md Colors.md
Clickable-Links.md Clickable-Links.md

View file

@ -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 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 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 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". all the default command syntax should at most be referred to as "MUX-like" or "MUX-inspired".

View file

@ -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`. 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 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 ### 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 Evennia comes with a MUD client accessible from a normal web browser. During
development you can try it at `http://localhost:4001/webclient`. 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 ## The Django 'Admin' Page

View file

@ -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. 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. 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 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: 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 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 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 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 inherit from a given typeclass parent - and then limit your searches to objects inheriting from that

View file

@ -1,7 +1,7 @@
# A voice operated elevator using events # 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- This tutorial will walk you through the steps to create a voice-operated elevator, using the [in-
game Python 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 But what we want now is to be able to say "1", "2" or "3" and have the elevator move in that
direction. 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 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). 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 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 with the expected behavior, which makes porting code very easy. This side of chained events will be
shown in the next tutorial. shown in the next tutorial.
- Previous tutorial: [Adding dialogues in events](./Dialogues-in-events) - Previous tutorial: [Adding dialogues in events](./Dialogues-in-events.md)

View file

@ -11,7 +11,7 @@ to pick ideas or even get a starting game to build on. These instructions are ba
released as of *Aug 12, 2018*. released as of *Aug 12, 2018*.
If you are not familiar with what Evennia is, you can read If you are not familiar with what Evennia is, you can read
[an introduction here](../Evennia-Introduction). [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 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. since part of Arx has grown organically, it doesn't follow standard Evennia paradigms everywhere.
@ -23,7 +23,7 @@ better match with the vanilla Evennia install.
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 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 [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 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 Evennia 0.8 [fork](https://github.com/TehomCD/evennia), notably still using Python2. This detail is
important if referring to newer Evennia documentation. important if referring to newer Evennia documentation.
@ -31,7 +31,7 @@ important if referring to newer Evennia documentation.
If you are new to Evennia it's *highly* recommended that you run through the 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. 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 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 operating system. You can also drop into our
[forums](https://groups.google.com/forum/#%21forum/evennia), join `#evennia` on `irc.freenode.net` [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).
@ -63,7 +63,7 @@ A new folder `myarx` should appear next to the ones you already had. You could r
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 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). [read more about it here](../Howto/Starting/Part1/Gamedir-Overview.md).
### Clean up settings ### Clean up settings

View file

@ -1,6 +1,6 @@
# Contrib modules # 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 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. 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. 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 Adds an XYZgrid to Evennia, with map-display and pathfinding. Created via map
strings and maintained outside of the game via Evennia launch commands. strings and maintained outside of the game via Evennia launch commands.
- [XYZGrid documentation](./XYZGrid) - [XYZGrid documentation](./XYZGrid.md)
### Extended Room ### 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. 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 ### 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. 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. A full, extendable crafting system.
- [Crafting overview](./Crafting) - [Crafting overview](./Crafting.md)
- [Crafting API documentation](api:evennia.contrib.crafting.crafting) - [Crafting API documentation](evennia.contrib.crafting.crafting)
- [Example of a sword crafting tree](api:evennia.contrib.crafting.example_recipes) - [Example of a sword crafting tree](evennia.contrib.crafting.example_recipes)
### Dice ### 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!) 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) - [A voice-operated elevator using events](./A-voice-operated-elevator-using-events.md)
- [Dialogues using events](./Dialogues-in-events) - [Dialogues using events](./Dialogues-in-events.md)
### Menu-builder ### Menu-builder
A tool for building using an in-game menu instead of the normal build commands. Meant to 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. be expanded for the needs of your game.
- [Building Menus](./Building-menus) - [Building Menus](./Building-menus.md)
### Security/Auditing ### 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 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 repository on github](https://github.com/Arx-Game/arxcode)
- [Arxcode issue tracker](https://github.com/Arx-Game/arxcode/issues) - [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! latest Evennia. Report your findings!
### Evscaperoom ### 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. A full engine for making multiplayer 'escape-rooms' completely in code.
This is based on the 2019 MUD Game jam winner *Evscaperoom*. 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 - [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. 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 - https://github.com/Griatch/evscaperoom - the original game's source code (warning for spoilers if you
@ -319,7 +319,7 @@ This is based on the 2019 MUD Game jam winner *Evscaperoom*.
```toctree:: ```{toctree}
:hidden: :hidden:
./Crafting ./Crafting

View file

@ -1,14 +1,14 @@
# Crafting system contrib # Crafting system contrib
_Contrib by Griatch 2020_ _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. 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. 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. a crafting tree for crafting a sword from base elements.
From in-game it uses the new `craft` command: 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 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. The `result` is always a list.
## Adding new recipes ## 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). 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 Instead of specifying the full prototype-dict, you could also just provide a list of `prototype_key`s to
existing prototypes you have. 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. 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 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 `.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: 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 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 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 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. 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 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. 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. of a random skill-check being implemented in a parent and then inherited for multiple use.
## Even more customization ## Even more customization

View file

@ -4,7 +4,7 @@
## Introduction ## Introduction
An often desired feature in a MUD is to show an in-game map to help navigation. The [Static in-game 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 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. 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 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). 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 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 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 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 "logical" layout. In this tutorial we assume you have such a grid of rooms that we can generate the
map from. 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 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 [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. legend and other features.
Below is the whole `map.py` for your reference. You need to update your `Room` typeclass (see above) Below is the whole `map.py` for your reference. You need to update your `Room` typeclass (see above)

View file

@ -4,8 +4,8 @@
## Introduction ## Introduction
This tutorial describes the creation of an in-game map display based on a pre-drawn map. It also 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 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) that works in the opposite direction, 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. 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 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 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. don't show in the documentation wiki.
## Planning the Map ## 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 In this section we will try to create an actual "map" object that an account can pick up and look
at. at.
Evennia offers a range of [default commands](api:evennia.commands.default#modules) for Evennia offers a range of [default commands](../Components/Default-Commands.md) for
[creating objects and rooms in-game](../Howto/Starting/Part1/Building-Quickstart). While readily accessible, these commands are made to do very [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 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 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. 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 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 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 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 for easy editing and creation in whatever text editor you prefer, avoiding having to manually build
the world line-by-line inside the game. the world line-by-line inside the game.
> Important warning: `@batchcode`'s power is only rivaled by the `@py` command. Batchcode is so > 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 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. 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 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- 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 Tutorial), [fill your world with NPC's](../Howto/Tutorial-Aggressive-NPCs.md) or
[implement a combat system](../Howto/Starting/Part3/Turn-based-Combat-System). [implement a combat system](../Howto/Starting/Part3/Turn-based-Combat-System.md).

View file

@ -1,6 +1,6 @@
# XYZGrid contrib # XYZGrid contrib
```versionadded:: 1.0 ```{versionadded} 1.0
``` ```
This optional contrib adds a 'coordinate grid' to Evennia. It allows for 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. available for use as prototype-parents when spawning the grid.
4. Run `evennia xyzgrid help` for available options. 4. Run `evennia xyzgrid help` for available options.
5. (Optional): By default, the xyzgrid will only spawn module-based 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 since the grid is entirely defined outside the game anyway. If you want to
also make use of in-game (db-) created prototypes, add also make use of in-game (db-) created prototypes, add
`XYZGRID_USE_DB_PROTOTYPES = True` to settings. `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_ 1. The `XYMap` - This class parses modules with special _Map strings_
and _Map legends_ into one Python object. It has helpers for pathfinding and and _Map legends_ into one Python object. It has helpers for pathfinding and
visual-range handling. 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' stores all `XYMaps` in the game. It is the central point for managing the 'grid'
of the game. of the game.
3. `XYZRoom` and `XYZExit`are custom typeclasses that use 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 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 abstract until it is used to _spawn_ these database entities into
something you can actually interract with in the game. The `XYZRoom` 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 $ evennia xyzgrid init
use `evennia xyzgrid help` to see all options) 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 `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: 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" $ evennia xyzgrid show "the small cave"
If you want to peek at how the grid's code, open 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). (We'll explain the details in later sections).
So far the grid is 'abstract' and has no actual in-game presence. Let's 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 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). 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. 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. is the base class for all links.
As the _Map String_ is parsed, each found symbol is looked up in the legend and 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). (described in the next section).
Some useful properties of the 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): class (see class doc for hook methods):
- `symbol` (str) - The character to parse from the map into this node. By default this - `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). useful for various reasons, mostly map-transitions).
Some useful properties of the 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): class (see class doc for hook methods):
- `symbol` (str) - The character to parse from the map into this node. This must - `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 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. their names are included to make it easy to know what to override.
```eval_rst ```{eval-rst}
============= ============== ==== =================== ========================================= ============= ============== ==== =================== =========================================
symbol display-symbol type class description symbol display-symbol type class description
============= ============== ==== =================== ========================================= ============= ============== ==== =================== =========================================
@ -921,11 +921,11 @@ across the map boundary.
### Prototypes ### 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 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 that allows the `evennia xyzgrid spawn` command to convert them to
a [XYZRoom](api:evennia.contrib.xyzgrid.xyzroom#XYZRoom) a [XYZRoom](evennia.contrib.xyzgrid.xyzroom.XYZRoom)
or an [XYZExit](api:evennia.contrib.xyzgrid.xyzroom#XYZExit) respectively. or an [XYZExit](evennia.contrib.xyzgrid.xyzroom.XYZRoom) respectively.
The default prototypes are found in `evennia.contrib.xyzgrid.prototypes` (added The default prototypes are found in `evennia.contrib.xyzgrid.prototypes` (added
during installation of this contrib), with `prototype_key`s `"xyz_room"` and 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 ## 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. the grid. There should be only one XYZGrid created at any time.
To access the grid in-code, there are several ways: 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_shortest_path(start_xy, end_xy)`
- `xymap.get_visual_range(xy, dist=2, **kwargs)` - `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. details.
## XYZRoom and XYZExit ## 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 `evennia.contrib.xyzgrid.xyzroom`. They extend the base `DefaultRoom` and
`DefaultExit` to be aware of their `X`, `Y` and `Z` coordinates. `DefaultExit` to be aware of their `X`, `Y` and `Z` coordinates.
```warning:: ```{warning}
You should usually **not** create XYZRooms/Exits manually. They are intended 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 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 - `xyz_destination` (only for `XYZExits`) - this gives the xyz-coordinate of
the exit's destination. 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` 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 while exits use the same in addition to tags for their destination, with tag
categories `exit_dest_x_coordinate`, `exit_dest_y_coordinate` and 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 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 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 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 ## Working with the grid

File diff suppressed because it is too large Load diff

View file

@ -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 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. you had in mind when creating it.
* To make the licensing situation clear we assume all contributions are released with the same * 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. 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, 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 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 module, you can add your unit tests to `evennia/contribs/tests.py`. If your contribution is bigger

View file

@ -1,19 +1,19 @@
# API Summary # API Summary
[evennia](api:evennia) - library root [evennia](api/evennia-api.md) - library source tree
- [evennia.accounts](api:evennia.accounts) - the out-of-character entities representing players - [evennia.accounts](evennia.accounts) - the out-of-character entities representing players
- [evennia.commands](api:evennia.commands) - handle all inputs. Also includes default commands - [evennia.commands](evennia.commands) - handle all inputs. Also includes default commands
- [evennia.comms](api:evennia.comms) - in-game channels and messaging - [evennia.comms](evennia.comms) - in-game channels and messaging
- [evennia.contrib](api:evennia.contrib) - game-specific tools and code contributed by the community - [evennia.contrib](evennia.contrib) - game-specific tools and code contributed by the community
- [evennia.help](api:evennia.help) - in-game help system - [evennia.help](evennia.help) - in-game help system
- [evennia.locks](api:evennia.locks) - limiting access to various systems and resources - [evennia.locks](evennia.locks) - limiting access to various systems and resources
- [evennia.objects](api:evennia.objects) - all in-game entities, like Rooms, Characters, Exits etc - [evennia.objects](evennia.objects) - all in-game entities, like Rooms, Characters, Exits etc
- [evennia.prototypes](api:evennia.prototypes) - customize entities using dicts - [evennia.prototypes](evennia.prototypes) - customize entities using dicts
- [evennia.scripts](api:evennia.scripts) - all out-of-character game objects - [evennia.scripts](evennia.scripts) - all out-of-character game objects
- [evennia.server](api:evennia.server) - core Server and Portal programs, also network protocols - [evennia.server](evennia.server) - core Server and Portal programs, also network protocols
- [evennia.typeclasses](api:evennia.typeclasses) - core database-python bridge - [evennia.typeclasses](evennia.typeclasses) - core database-python bridge
- [evennia.utils](api:evennia.utils) - lots of useful coding tools and utilities - [evennia.utils](evennia.utils) - lots of useful coding tools and utilities
- [evennia.web](api:evennia.web) - webclient, website and other web resources - [evennia.web](evennia.web) - webclient, website and other web resources
## Shortcuts ## Shortcuts
@ -28,71 +28,70 @@ The flat API is defined in `__init__.py` [viewable here](github:evennia/__init__
### Search functions ### Search functions
- [evennia.search_account](api:evennia.utils.search#evennia.utils.search.search_account) - [evennia.search_account](evennia.utils.search.search_account)
- [evennia.search_object](api:evennia.utils.search#evennia.utils.search.search_object) - [evennia.search_object](evennia.utils.search.search_object)
- [evennia.search_object_by_tag](api:evennia.utils.search#evennia.utils.search_object_by_tag) - [evennia.search_tag](evennia.utils.search.search_tag)
- [evennia.search_script](api:evennia.utils.search#evennia.utils.search_script) - [evennia.search_script](evennia.utils.search.search_script)
- [evennia.search_channel](api:evennia.utils.search#evennia.utils.search_channel) - [evennia.search_channel](evennia.utils.search.search_channel)
- [evennia.search_message](api:evennia.utils.search#evennia.utils.search_message) - [evennia.search_message](evennia.utils.search.search_message)
- [evennia.search_help](api:evennia.utils.search#evennia.utils.search.search_help) - [evennia.search_help](evennia.utils.search.search_help_entry)
### Create functions ### Create functions
- [evennia.create_account](api:evennia.utils.create#evennia.utils.create.create_account) - [evennia.create_account](evennia.utils.create.create_account)
- [evennia.create_object](api:evennia.utils.create#evennia.utils.create.create_object) - [evennia.create_object](evennia.utils.create.create_object)
- [evennia.create_script](api:evennia.utils.create#evennia.utils.create.create_script) - [evennia.create_script](evennia.utils.create.create_script)
- [evennia.create_channel](api:evennia.utils.create#evennia.utils.create.create_channel) - [evennia.create_channel](evennia.utils.create.create_channel)
- [evennia.create_help_entry](api:evennia.utils.create#evennia.utils.create.create_help_entry) - [evennia.create_help_entry](evennia.utils.create.create_help_entry)
- [evennia.create_message](api:evennia.utils.create#evennia.utils.create.create_message) - [evennia.create_message](evennia.utils.create.create_message)
### Typeclasses ### Typeclasses
- [evennia.Defaultaccount](api:evennia.accounts.accounts#evennia.accounts.accounts.DefaultAccount) - player account class ([docs](Components/Accounts)) - [evennia.Defaultaccount](evennia.accounts.accounts.DefaultAccount) - player account class ([docs](Components/Accounts.md))
- [evennia.DefaultGuest](api:evennia.accounts.accounts#evennia.accounts.accounts.DefaultGuest) - base guest account class - [evennia.DefaultGuest](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.DefaultObject](evennia.objects.objects.DefaultObject) - base class for all objects ([docs](Components/Objects.md))
- [evennia.DefaultCharacter](api:evennia.objects.objects#evennia.objects.objects.DefaultCharacter) - base class for in-game characters ([docs](Components/Objects#Character)) - [evennia.DefaultCharacter](evennia.objects.objects.DefaultCharacter) - base class for in-game characters ([docs](Components/Objects.md#characters))
- [evennia.DefaultRoom](api:evennia.objects.objects#evennia.objects.objects.DefaultRoom) - base class for rooms ([docs](Components/Objects#Room)) - [evennia.DefaultRoom](evennia.objects.objects.DefaultRoom) - base class for rooms ([docs](Components/Objects.md#rooms))
- [evennia.DefaultExit](api:evennia.objects.objects#evennia.objects.objects.DefaultExit) - base class for exits ([docs](Components/Objects#Exit)) - [evennia.DefaultExit](evennia.objects.objects.DefaultExit) - base class for exits ([docs](Components/Objects.md#exits))
- [evennia.DefaultScript](api:evennia.scripts.scripts#evennia.scripts.scripts.DefaultScript) - base class for OOC-objects ([docs](Components/Scripts)) - [evennia.DefaultScript](evennia.scripts.scripts.DefaultScript) - base class for OOC-objects ([docs](Components/Scripts.md))
- [evennia.DefaultChannel](api:evennia.comms.comms#evennia.comms.comms.DefaultChannel) - base class for in-game channels ([docs](Components/Channels)) - [evennia.DefaultChannel](evennia.comms.comms.DefaultChannel) - base class for in-game channels ([docs](Components/Channels.md))
### Commands ### Commands
- [evennia.Command](api:evennia.commands.command#evennia.commands.command.Command) - base [Command](Components/Commands) class. See also `evennia.default_cmds.MuxCommand` - [evennia.Command](evennia.commands.command.Command) - base [Command](Components/Commands.md) class. See also `evennia.default_cmds.MuxCommand`
- [evennia.CmdSet](api:evennia.commands.cmdset#evennia.commands.cmdset.CmdSet) - base [Cmdset](Components/Command-Sets) class - [evennia.CmdSet](evennia.commands.cmdset.CmdSet) - base [CmdSet](Components/Command-Sets.md) class
- [evennia.default_cmds](api:Default-Command-Help) - access all default command classes as properties - [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 ### Utilities
- [evennia.utils.utils](api:evennia.utils.utils) - mixed useful utilities - [evennia.utils.utils](evennia.utils.utils) - mixed useful utilities
- [evennia.gametime](api:evennia.utils.gametime) - server run- and game time ([docs](Components/Coding-Utils#gametime)) - [evennia.gametime](evennia.utils.gametime.TimeScript) - server run- and game time ([docs](Components/Coding-Utils.md#game-time))
- [evennia.logger](api:evennia.utils.logger) - logging tools - [evennia.logger](evennia.utils.logger) - logging tools
- [evennia.ansi](api:evennia.utils.ansi) - ansi coloring tools - [evennia.ansi](evennia.utils.ansi) - ansi coloring tools
- [evennia.spawn](api:evennia.prototypes.spawner#evennia.prototypes.spawner.Spawn) - spawn/prototype system ([docs](Components/Prototypes)) - [evennia.spawn](evennia.prototypes.spawner.spawn) - spawn/prototype system ([docs](Components/Prototypes.md))
- [evennia.lockfuncs](api:evennia.locks.lockfuncs) - default lock functions for access control ([docs](Components/Locks)) - [evennia.lockfuncs](evennia.locks.lockfuncs) - default lock functions for access control ([docs](Components/Locks.md))
- [evennia.EvMenu](api:evennia.utils.evmenu#evennia.utils.evmenu.EvMenu) - menu system ([docs](Components/EvMenu)) - [evennia.EvMenu](evennia.utils.evmenu.EvMenu) - menu system ([docs](Components/EvMenu.md))
- [evennia.EvTable](api:evennia.utils.evtable#evennia.utils.evtable.EvTable) - text table creater - [evennia.EvTable](evennia.utils.evtable.EvTable) - text table creater
- [evennia.EvForm](api:evennia.utils.evform#evennia.utils.evform.EvForm) - text form creator - [evennia.EvForm](evennia.utils.evform.EvForm) - text form creator
- Evennia.EvMore - text paginator - Evennia.EvMore - text paginator
- [evennia.EvEditor](api:evennia.utils.eveditor#evennia.utils.eveditor.EvEditor) - in game text line editor ([docs](Components/EvEditor)) - [evennia.EvEditor](evennia.utils.eveditor.EvEditor) - in game text line editor ([docs](Components/EvEditor.md))
- [evennia.utils.funcparser.Funcparser](api:evennia.utils.funcparser) - inline parsing of functions ([docs](Components/FuncParser)) - [evennia.utils.funcparser.Funcparser](evennia.utils.funcparser.FuncParser) - inline parsing of functions ([docs](Components/FuncParser.md))
### Global singleton handlers ### Global singleton handlers
- [evennia.TICKER_HANDLER](api:evennia.scripts.tickerhandler) - allow objects subscribe to tickers ([docs](Components/TickerHandler)) - [evennia.TICKER_HANDLER](evennia.scripts.tickerhandler.TickerHandler) - allow objects subscribe to tickers ([docs](Components/TickerHandler.md))
- [evennia.MONITOR_HANDLER](api:evennia.scripts.monitorhandler) - monitor changes ([docs](Components/MonitorHandler)) - [evennia.MONITOR_HANDLER](evennia.scripts.monitorhandler.MonitorHandler) - monitor changes ([docs](Components/MonitorHandler.md))
- [evennia.CHANNEL_HANDLER](api:evennia.comms.channelhandler) - maintains channels - [evennia.SESSION_HANDLER](evennia.server.sessionhandler.SessionHandler) - manages all sessionsmain session handler
- [evennia.SESSION_HANDLER](api:evennia.server.serverhandler) - manages all sessionsmain session handler
### Database core models (for more advanced lookups) ### Database core models (for more advanced lookups)
- [evennia.ObjectDB](api:evennia.objects.models#evennia.objects.models.ObjectDB) - [evennia.ObjectDB](evennia.objects.models.ObjectDB)
- [evennia.accountDB](api:evennia.accounts.models#evennia.accounts.models.AccountDB) - [evennia.accountDB](evennia.accounts.models.AccountDB)
- [evennia.ScriptDB](api:evennia.scripts.models#evennia.scripts.models.ScriptDB) - [evennia.ScriptDB](evennia.scripts.models.ScriptDB)
- [evennia.ChannelDB](api:evennia.channels.models#evennia.channels.models.ChannelDB) - [evennia.ChannelDB](evennia.comms.models.ChannelDB)
- [evennia.Msg](api:evennia.comms.models#evennia.comms.models.Msg) - [evennia.Msg](evennia.comms.models.Msg)
- evennia.managers - contains shortcuts to all database managers - evennia.managers - contains shortcuts to all database managers
### Contributions ### Contributions

View file

@ -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 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). 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. would you want something to build from.
Using the full power of Python throughout the server offers some distinct advantages. All your 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, 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 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 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. 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. 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 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 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 ## 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 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. 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 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 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 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 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) but you should probably also sit down 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 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 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 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: 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 [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. 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 With just basic knowledge you should be able to define your own [Commands](Components/Commands.md), create custom
[Objects](Components/Objects) as well as make your world come alive with basic [Scripts](Components/Scripts). You can [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. 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! ### 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? ### Where to from here?
From here you can continue browsing the [online documentation]([online documentation](index:Evennia-documentation)) to 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) and get your hands 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 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. 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 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 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. 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 state of mind you should aim for - including cutting down the scope of your game for its first
release. 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 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. your own game, you will end up with a small (very small) game that you can build or learn from.

View file

@ -3,92 +3,93 @@
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 - _[account](./Glossary.md#account)_ - the player's account on the game
- _[admin-site](./Glossary#admin-site)_ - the Django web page for manipulating the database - _[admin-site](./Glossary.md#admin-site)_ - the Django web page for manipulating the database
- _[attribute](./Glossary#attribute)_ - persistent, custom data stored on typeclasses - _[attribute](./Glossary.md#attribute)_ - persistent, custom data stored on typeclasses
- _[channel](./Glossary#channel)_ - game communication channels - _[channel](./Glossary.md#channel)_ - game communication channels
- _[character](./Glossary#character)_ - the player's avatar in the game, controlled from - _[character](./Glossary.md#character)_ - the player's avatar in the game, controlled from
_[account](./Glossary#account)_ _[account](./Glossary.md#account)_
- _[core](./Glossary#core)_ - a term used for the code distributed with Evennia proper - _[contrib](./Glossary.md#contrib)_ - a term used for optional code contributed by the community.
- _[django](./Glossary#django)_ - web framework Evennia uses for database access and web integration - _[core](./Glossary.md#core)_ - a term used for the code distributed with Evennia proper
- _[field](./Glossary#field)_ - a _[typeclass](./Glossary#typeclass)_ property representing a database - _[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 column
- _[git](./Glossary#git)_ - the version-control system we use - _[git](./Glossary.md#git)_ - the version-control system we use
- _[github](./Glossary#github)_ - the online hosting of our source code - _[github](./Glossary.md#github)_ - the online hosting of our source code
- _[migrate](./Glossary#migrate)_ - updating the database schema - _[migrate](./Glossary.md#migrate)_ - updating the database schema
- _[multisession mode`](#multisession-mode)_ - a setting defining how users connect to Evennia - _[multisession mode`](#multisession-mode)_ - a setting defining how users connect to Evennia
- _[object](./Glossary#object)_ - Python instance, general term or in-game - _[object](./Glossary.md#object)_ - Python instance, general term or in-game
_[typeclass](./Glossary#typeclass)_ _[typeclass](./Glossary.md#typeclass)_
- _[pip](./Glossary#pip)_ - the Python installer - _[pip](./Glossary.md#pip)_ - the Python installer
- _player_ - the human connecting to the game with their client - _player_ - the human connecting to the game with their client
- _[puppet](./Glossary#puppet)_ - when an [account](./Glossary#account) controls an in-game - _[puppet](./Glossary.md#puppet)_ - when an [account](./Glossary.md#account) controls an in-game
[object](./Glossary#object) [object](./Glossary.md#object)
- _[property](./Glossary#property)_ - a python property - _[property](./Glossary.md#property)_ - a python property
- _evenv_ - see _[virtualenv](./Glossary#virtualenv)_ - _evenv_ - see _[virtualenv](./Glossary.md#virtualenv)_
- _[repository](./Glossary#repository)_ - a store of source code + source history - _[repository](./Glossary.md#repository)_ - a store of source code + source history
- _[script](./Glossary#script)_ - a building block for custom storage, systems and time-keepint - _[script](./Glossary.md#script)_ - a building block for custom storage, systems and time-keepint
- _[session](./Glossary#session)_ - represents one client connection - _[session](./Glossary.md#session)_ - represents one client connection
- _[ticker](./Glossary#ticker)_ - Allows to run events on a steady 'tick' - _[ticker](./Glossary.md#ticker)_ - Allows to run events on a steady 'tick'
- _[twisted](./Glossary#twisted)_ - networking engine responsible for Evennia's event loop and - _[twisted](./Glossary.md#twisted)_ - networking engine responsible for Evennia's event loop and
communications communications
- _[typeclass](./Glossary#typeclass)_ - Evennia's database-connected Python class - _[typeclass](./Glossary.md#typeclass)_ - Evennia's database-connected Python class
- _upstream_ - see _[github](./Glossary#github)_ - _upstream_ - see _[github](./Glossary.md#github)_
- _[virtualenv](./Glossary#virtualenv)_ - a Python program and way to make an isolated Python install - _[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 The term 'account' refers to the [player's](./Glossary.md#account) unique account on the game. It is
represented by the `Account` [typeclass](./Glossary#typeclass) and holds things like email, password, represented by the `Account` [typeclass](./Glossary.md#typeclass) and holds things like email, password,
configuration etc. configuration etc.
When a player connects to the game, they connect to their account. The account has *no* 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 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. 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 puppeting a Character with the same name as your Account when you log in - mimicking how older
servers used to work. 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 ([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 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. 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 The term _Attribute_ should not be confused with ([properties](./Glossary.md#property) or
[fields](./Glossary#field). The `Attribute` represents arbitrary pieces of data that can be attached [fields](./Glossary.md#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 to any [typeclassed](./Glossary.md#typeclass) entity in Evennia. Attributes allows storing new persistent
data on typeclasses without changing their underlying database schemas. data on typeclasses without changing their underlying database schemas.
[Read more about Attributes here](Components/Attributes). [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 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 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 [Accounts](./Glossary.md#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- 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 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 The _Character_ is the term we use for the default avatar being [puppeted](./Glossary.md#puppet) by the
[account](./Glossary#account) in the game world. It is represented by the `Character` typeclass (which [account](./Glossary.md#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 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#subclasses-of-object). 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, [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 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. database operations to Python and for structuring our web site.
Through Django, we can work with any supported database (SQlite3, Postgres, MySQL ...) using generic Through Django, we can work with any supported database (SQlite3, Postgres, MySQL ...) using generic
@ -97,9 +98,9 @@ Python instead of database-specific SQL: A database table is represented in Djan
There is usually no need to know the details of Django's database handling in order to use Evennia - 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 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 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 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 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- 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 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 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- 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. 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 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 > 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. core. Better make it a contrib.
### _field_ ## _contrib_
A _field_ or _database field_ in Evennia refers to a [property](./Glossary#property) on a Game-specific code and examples are distributed in evennia's [contribs/](Contribs/Contrib-Overview.md) folder.
[typeclass](./Glossary#typeclass) directly linked to an underlying database column. Only a few fixed This is game-specific, optional code created by the Evennia community.
## _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 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 that base typeclass (for example [Objects](./Glossary.md#object) store its location as a field). In all
other cases, [attributes](./Glossary#attribute) are used to add new persistent data to the typeclass. other cases, [attributes](./Glossary.md#attribute) are used to add new persistent data to the typeclass.
[Read more about typeclass properties here](Components/Typeclasses#about-typeclass-properties). [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) [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 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' come back to it later if later changes caused problems. By tracking commits we know what 'version'
of the code we are currently using. of the code we are currently using.
Evennia's source code + its source history is jointly called a [repository](./Glossary#repository). 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#github). Everyone using or 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 developing Evennia makes a 'clone' of this repository to their own computer - everyone
automatically gets everything that is online, including all the code history. 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 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). others to see (among other things).
@ -167,53 +173,53 @@ 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. - `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 > 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. [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 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 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#git) to pull the 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 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` 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) for more details. 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 > 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 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. 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 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 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 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. [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 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 similarity in name, don't confuse GitHub the website with [Git](./Glossary.md#git), the versioning
system. Github hosts Git [repositories](./Glossary#repository) online and helps with collaboration and system. Github hosts Git [repositories](./Glossary.md#repository) online and helps with collaboration and
infrastructure. Git itself is a separate project. infrastructure. Git itself is a separate project.
### _object_ ## _object_
In general Python (and other [object-oriented languages](https://en.wikipedia.org/wiki/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 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 try to use `object` to refer to the general term and capitalized `Object` when we refer to the
typeclass. typeclass.
The `Object` is a typeclass that represents all *in-game* entities, including 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- _[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 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 `<folder>` changes, the installed Python package is im
If not using `-e`, one would need to run `pip install --upgrade <folder>` every time to make the If not using `-e`, one would need to run `pip install --upgrade <folder>` every time to make the
changes available when you import this package into your code. Evennia is installed this way. 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. 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)). 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. not have to be.
### _property_ ## _property_
A _property_ is a general term used for properties on any Python object. The term also sometimes 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- 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, 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. 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 > 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. 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 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 repository). If you put your game dir under version control, that of course becomes a repository as
well. well.
### _script_ ## _script_
When we refer to _Scripts_, we generally refer to the `Script` [typeclass](Components/Typeclasses). Scripts are 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#object) but without any in-game 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 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- 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). time persistent time keeping (for fast updates other types of timers may be better though).
[Read more about Scripts here](Components/Scripts) [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 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 (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 always exist (also when not logged in), they share some common functionality with typeclasses that
can be useful for certain game states. 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 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 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. 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 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. 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 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_. such code entities as _being typeclassed_.
Evennia's main typeclasses are [Account](./Glossary#account), [Object](./Glossary#object), Evennia's main typeclasses are [Account](./Glossary.md#account), [Object](./Glossary.md#object),
[Script](./Glossary#script) and [Channel](./Glossary#channel). Children of the base class (such as [Script](./Glossary.md#script) and [Channel](./Glossary.md#channel). Children of the base class (such as
[Character](./Glossary#character)) will use the same database table as the parent, but can have vastly [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#attributes) and different Python capabilities (and persistent features through [Attributes](./Glossary.md#attribute) and
[Tags](./Glossary#tags). A typeclass can be coded and treated pretty much like any other Python class [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 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. 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 `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. 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 [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 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 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 version of Telnet, Telnet+SSL, SSH, webclient-websockets etc. Twisted also runs our integrated web
server, serving the Django-based website for your game. 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 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 used to isolate all Python packages needed by a given Python project into one folder (we call that
@ -339,7 +350,7 @@ Python version than default.
A virtualenv is 'activated' only for the console/terminal it was started in, but it's safe to 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 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`. 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 > Note that if you have root/admin access you *could* install Evennia globally just fine, without

View file

@ -1,7 +1,7 @@
# How To Get And Give Help # 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: 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! 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. 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]. - 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). - 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! 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: 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 - 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) on how you documentation (even small things like fixing typos!). [See here](./Contributing-Docs.md) on how you
contribute to the docs. contribute to the docs.
- Send a message to our [discussion group][group] and/or our [IRC chat][chat] asking about what - 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. 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. - 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 [here are bugs][issues-master] that need fixes. At any given time there may also be some
[bounties][issues-bounties] open. [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. github.
... And finally, if you want to help motivate and support development you can also drop some coins ... And finally, if you want to help motivate and support development you can also drop some coins

View file

@ -2,7 +2,7 @@
**Before doing this tutorial you will probably want to read the intro in **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. [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. This tutorial will provide a step-by-step process to installing a wiki on your website.

View file

@ -28,9 +28,9 @@ Before we continue, lets 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 more flexible about using and adding commands to those objects. Here are some ground rules well
worth remembering for the remainder of this article: worth remembering for the remainder of this article:
- The [Account](../Components/Accounts) represents the real person logging in and has no game-world existence. - The [Account](../Components/Accounts.md) 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). - Any [Object](../Components/Objects.md) can be puppeted by an Account (with proper permissions).
- [Characters](../Components/Objects#characters), [Rooms](../Components/Objects#rooms), and [Exits](../Components/Objects#exits) are just - [Characters](../Components/Objects.md#characters), [Rooms](../Components/Objects.md#rooms), and [Exits](../Components/Objects.md#exits) are just
children of normal Objects. children of normal Objects.
- Any Object can be inside another (except if it creates a loop). - 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: - 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 that up to you to create as an exercise. You could have it print "WOOSH! The
mech launches missiles against <target>!", for example. mech launches missiles against <target>!", 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. holding any number of commands. The command set is what we will store on the mech.
```python ```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 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. 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: behind the scenes. A Typeclass is created in a normal Python source file:
```python ```python

View file

@ -7,28 +7,28 @@ exists before answering - maybe you can clarify that answer rather than to make
## Table of Contents ## Table of Contents
- [Removing default commands](./Coding-FAQ#removing-default-commands) - [Removing default commands](./Coding-FAQ.md#removing-default-commands)
- [Preventing character from moving based on a condition](./Coding-FAQ#preventing-character-from- - [Preventing character from moving based on a condition](./Coding-FAQ.md#preventing-character-from-
moving-based-on-a-condition) 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) evmenu-command)
- [Adding color to default Evennia Channels](./Coding-FAQ#adding-color-to-default-evennia-channels) - [Adding color to default Evennia Channels](./Coding-FAQ.md#adding-color-to-default-evennia-channels)
- [Selectively turn off commands in a room](./Coding-FAQ#selectively-turn-off-commands-in-a-room) - [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#select-command-based-on-a-condition) - [Select Command based on a condition](./Coding-FAQ.md#select-command-based-on-a-condition)
- [Automatically updating code when reloading](./Coding-FAQ#automatically-updating-code-when- - [Automatically updating code when reloading](./Coding-FAQ.md#automatically-updating-code-when-
reloading) reloading)
- [Changing all exit messages](./Coding-FAQ#changing-all-exit-messages) - [Changing all exit messages](./Coding-FAQ.md#changing-all-exit-messages)
- [Add parsing with the "to" delimiter](./Coding-FAQ#add-parsing-with-the-to-delimiter) - [Add parsing with the "to" delimiter](./Coding-FAQ.md#add-parsing-with-the-to-delimiter)
- [Store last used session IP address](./Coding-FAQ#store-last-used-session-ip-address) - [Store last used session IP address](./Coding-FAQ.md#store-last-used-session-ip-address)
- [Use wide characters with EvTable](./Coding-FAQ#non-latin-characters-in-evtable) - [Use wide characters with EvTable](./Coding-FAQ.md#non-latin-characters-in-evtable)
## Removing default commands ## Removing default commands
**Q:** How does one *remove* (not replace) e.g. the default `get` [Command](../Components/Commands) from the **Q:** How does one *remove* (not replace) e.g. the default `get` [Command](../Components/Commands.md) from the
Character [Command Set](../Components/Command-Sets)? Character [Command Set](../Components/Command-Sets.md)?
**A:** Go to `mygame/commands/default_cmdsets.py`. Find the `CharacterCmdSet` class. It has one **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: 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. for more info.
## Preventing character from moving based on a condition ## Preventing character from moving based on a condition
@ -36,7 +36,7 @@ for more info.
combat, immobilized, etc.) combat, immobilized, etc.)
**A:** The `at_before_move` hook is called by Evennia just before performing any move. If it returns **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: Add the following code to the `Character` class:
```python ```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 **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? 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 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 closes. When initiating the menu, any additional keywords you give will be available for you as
properties on this menu object: 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 **Q:** I want certain commands to turn off in a given room. They should still work normally for
staff. 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 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: 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. 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, **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. command be available.
```python ```python
@ -156,8 +156,8 @@ class CmdWerewolf(Command):
def func(self): def func(self):
# ... # ...
``` ```
Add this to the [default cmdset as usual](Starting/Part1/Adding-Commands). The `is_full_moon` [lock Add this to the [default cmdset as usual](Starting/Part1/Adding-Commands.md). The `is_full_moon` [lock
function](Locks#lock-functions) does not yet exist. We must create that: function](../Components/Locks.md#lock-functions) does not yet exist. We must create that:
```python ```python
# in mygame/server/conf/lockfuncs.py # in mygame/server/conf/lockfuncs.py

View file

@ -9,7 +9,7 @@ a while. Such effects are called *cooldowns*.
This page exemplifies a very resource-efficient way to do cooldowns. A more 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 '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. combine if you want to echo some message to the user after the cooldown ends.
## Non-persistent cooldown ## Non-persistent cooldown
@ -88,7 +88,7 @@ database, you need to use the caster for the storage.
self.caller.db.firestorm_lastcast = now 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 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 likely have other skills with cooldowns after all). But this method of
using cooldowns also has the advantage of working *between* commands - you can using cooldowns also has the advantage of working *between* commands - you can

View file

@ -2,7 +2,7 @@
Before reading this tutorial, if you haven't done so already, you might want to 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. how commands work in Evennia.
In some types of games a command should not start and finish immediately. 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 > Important: The `yield` functionality will *only* work in the `func` method of
> Commands. It only works because Evennia has especially > Commands. It only works because Evennia has especially
> catered for it in Commands. If you want the same functionality elsewhere you > 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 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 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. should not be able to do it again immediately.
The simplest way of implementing blocking is to use the technique covered in the [Command 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 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* 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 efficient, reliable and passive solution. The drawback is that there is nothing to tell the Player

View file

@ -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") 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 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. the prompt when they cause a change in health, for example.

View file

@ -23,7 +23,7 @@ instance.
## Coordinates as tags ## Coordinates as tags
The first concept might be the most surprising at first glance: we will create coordinates as 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? > Why not attributes, wouldn't that be easier?

View file

@ -2,8 +2,8 @@
Evennia allows for exits to have any name. The command "kitchen" is a valid exit name as well as 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) "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) stored on said exit object. The command has the same key and aliases 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. 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 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 ## 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. 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 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 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. You cannot move east.
Further expansions by the exit system (including manipulating the way the Exit command itself is 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 ## 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 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. 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* by `key` and by `aliases`. If *either* of those match, the two commands are considered *identical*
as far as cmdset merging system is concerned. as far as cmdset merging system is concerned.

View file

@ -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 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. 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 - 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 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 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. are also highly optimized for querying large data sets efficiently.
### Some Familiar Things ## Some Familiar Things
Diku expresses the character object referenced normally by: Diku expresses the character object referenced normally by:

View file

@ -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 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, 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 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 nothing *in principle* stopping a Developer from offering a softcode-like language to Players if
that is deemed necessary. 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 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 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 ## A first step making things more familiar
@ -203,7 +203,7 @@ developer changing the underlying Python code.
## Next steps ## Next steps
If you are a *Developer* and are interested in making a more MUSH-like Evennia game, a good start is 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 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- various corners of Evennia. There is also the [Tutorial for running roleplaying sessions](Evennia-
for-roleplaying-sessions) that can be of interest. 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 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- 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). 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 (its not very MUSH- [Tutorial world](Starting/Part1/Tutorial-World-Introduction.md) is a small single-player quest you can try (its not very MUSH-
like but it does show many Evennia concepts in action). Beyond that there are [many more tutorials](./Howto-Overview) 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 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). [Evennia in pictures](https://evennia.blogspot.se/2016/05/evennia-in-pictures.html).

View file

@ -26,12 +26,12 @@ defaults for our particular use-case. Below we will flesh out these components f
## Starting out ## 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 instructions. Initialize a new game directory with `evennia init
<gamedirname>`. In this tutorial we assume your game dir is simply named `mygame`. You can use the <gamedirname>`. 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 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 `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 ## The Game Master role
@ -44,7 +44,7 @@ to show your renewed GM status to the other accounts.
### The permission hierarchy ### 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 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 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. 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 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. 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. completely bypasses it. We'll assume server admin(s) will "just" be Developers.
### How to grant permissions ### How to grant permissions
@ -102,7 +102,7 @@ its name will have the string`(GM)` added to the end.
#### Character modification #### Character modification
Let's first start by customizing the Character. We recommend you browse the beginning of the 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 objects" (not to be confused with the `Accounts` permission, which is just a string specifying your
access) and the IC "Character objects". 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 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 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- 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. actually get this flag below.
> **Extra exercise:** This will only show the `(GM)` text on *Characters* puppeted by a GM account, > **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 #### 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 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. 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. 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 > 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 #### Making a sheet with EvTable
@ -686,7 +686,7 @@ implemented.
## Rooms ## Rooms
Evennia comes with rooms out of the box, so no extra work needed. A GM will automatically have all 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: Here are some useful highlights:
* `@dig roomname;alias = exit_there;alias, exit_back;alias` - this is the basic command for digging * `@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 ## 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: documentation. For brevity, here are the relevant commands for normal use:
* `@ccreate new_channel;alias;alias = short description` - Creates a new channel. * `@ccreate new_channel;alias;alias = short description` - Creates a new channel.

View file

@ -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 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. 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 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 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 Evennia's game time features assume a standard calendar (see the relevant section below for a custom
calendar). 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 All is done through the settings. Here are the settings you should use if you want a game time with
a standard calendar: 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 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 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 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 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 instance, it can be used to have a specific message every (in-game) day at 6:00 AM showing how the
sun rises. 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 additional features to make sure the script is always executed when the game time matches the given
parameters. parameters.
@ -166,7 +166,7 @@ days.
Evennia handles custom calendars through an optional *contrib* module, called `custom_gametime`. 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. 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 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. need the notion of weeks... but we need the notion of months having 30 days, not 28.
@ -293,7 +293,7 @@ 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. 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. 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 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 your game time (and your custom calendar). It can be used to have a specific message every day at

View file

@ -3,7 +3,7 @@
The documents in this section aims to teach how to use Evennia in a tutorial or 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 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 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. docs for those that want to dive deeper.
## The Starting Tutorial ## 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 ### Part 1: What we have
1. [Introduction & Overview](Starting/Part1/Starting-Part1) 1. [Introduction & Overview](Starting/Part1/Starting-Part1.md)
1. [Building stuff](Starting/Part1/Building-Quickstart) 1. [Building stuff](Starting/Part1/Building-Quickstart.md)
1. [The Tutorial World](Starting/Part1/Tutorial-World-Introduction) 1. [The Tutorial World](Starting/Part1/Tutorial-World-Introduction.md)
1. [Python basics](Starting/Part1/Python-basic-introduction) 1. [Python basics](Starting/Part1/Python-basic-introduction.md)
1. [Game dir overview](Starting/Part1/Gamedir-Overview) 1. [Game dir overview](Starting/Part1/Gamedir-Overview.md)
1. [Python classes and objects](Starting/Part1/Python-classes-and-objects) 1. [Python classes and objects](Starting/Part1/Python-classes-and-objects.md)
1. [Accessing the Evennia library](Starting/Part1/Evennia-Library-Overview) 1. [Accessing the Evennia library](Starting/Part1/Evennia-Library-Overview.md)
1. [Typeclasses - Persistent objects](Starting/Part1/Learning-Typeclasses) 1. [Typeclasses - Persistent objects](Starting/Part1/Learning-Typeclasses.md)
1. [Making our first own commands](Starting/Part1/Adding-Commands) 1. [Making our first own commands](Starting/Part1/Adding-Commands.md)
1. [Parsing and replacing default Commands](Starting/Part1/More-on-Commands) 1. [Parsing and replacing default Commands](Starting/Part1/More-on-Commands.md)
1. [Creating things](Starting/Part1/Creating-Things) 1. [Creating things](Starting/Part1/Creating-Things.md)
1. [Searching for things](Starting/Part1/Searching-Things) 1. [Searching for things](Starting/Part1/Searching-Things.md)
1. [Advanced searching with Django queries](Starting/Part1/Django-queries) 1. [Advanced searching with Django queries](Starting/Part1/Django-queries.md)
### Part 2: What we want ### Part 2: What we want
1. [Introduction & Overview](Starting/Part2/Starting-Part2) 1. [Introduction & Overview](Starting/Part2/Starting-Part2.md)
1. [On planning a game](Starting/Part2/Game-Planning) 1. [On planning a game](Starting/Part2/Game-Planning.md)
1. [Planning to use some useful Contribs](Starting/Part2/Planning-Some-Useful-Contribs) 1. [Planning to use some useful Contribs](Starting/Part2/Planning-Some-Useful-Contribs.md)
### Part3: How we get there ### Part3: How we get there
1. [Introduction & Overview](Starting/Part3/Starting-Part3) 1. [Introduction & Overview](Starting/Part3/Starting-Part3.md)
1. [Making a custom Character](Starting/Part3/Implementing-a-game-rule-system) 1. [Making a custom Character](Starting/Part3/Implementing-a-game-rule-system.md)
1. [Character generation](../Unimplemented) 1. [Character generation](../Unimplemented.md)
1. [Resolving skills and challenges](../Unimplemented) 1. [Resolving skills and challenges](../Unimplemented.md)
1. [NPCs and mobiles](./Coordinates) 1. [NPCs and mobiles](./Coordinates.md)
1. [Quests and Zones](../Unimplemented) 1. [Quests and Zones](../Unimplemented.md)
1. [A Combat system](../Unimplemented) 1. [A Combat system](../Unimplemented.md)
### Part 4: Using what we created ### Part 4: Using what we created
1. [Introduction & Overview](Starting/Part4/Starting-Part4) 1. [Introduction & Overview](Starting/Part4/Starting-Part4.md)
1. [Building the tech demo](../Unimplemented) 1. [Building the tech demo](../Unimplemented.md)
1. [Creating a game world](../Unimplemented) 1. [Creating a game world](../Unimplemented.md)
### Part 5: Showing the world ### Part 5: Showing the world
1. [Introduction & Overview](Starting/Part5/Starting-Part5) 1. [Introduction & Overview](Starting/Part5/Starting-Part5.md)
1. [Add a web page](Starting/Part5/Add-a-simple-new-web-page) 1. [Add a web page](Starting/Part5/Add-a-simple-new-web-page.md)
1. [More on adding web features](Starting/Part5/Web-Tutorial) 1. [More on adding web features](Starting/Part5/Web-Tutorial.md)
1. [Taking your game online](../Unimplemented) 1. [Taking your game online](../Unimplemented.md)
1. [Next steps](../Unimplemented) 1. [Next steps](../Unimplemented.md)
## FAQs ## FAQs
- [Coding FAQ](./Coding-FAQ) - [Coding FAQ](./Coding-FAQ.md)
## Howto's ## Howto's
- [Giving Exits a default error](./Default-Exit-Errors) - [Giving Exits a default error](./Default-Exit-Errors.md)
- [Add a command prompt](./Command-Prompt) - [Add a command prompt](./Command-Prompt.md)
- [Don't allow spamming commands](./Command-Cooldown) - [Don't allow spamming commands](./Command-Cooldown.md)
- [Commands that take time](./Command-Duration) - [Commands that take time](./Command-Duration.md)
- [Configuring color](./Manually-Configuring-Color) - [Configuring color](./Manually-Configuring-Color.md)
- [Tweet game stats](./Tutorial-Tweeting-Game-Stats) - [Tweet game stats](./Tutorial-Tweeting-Game-Stats.md)
## Mobs and NPCs ## Mobs and NPCs
- [NPCs that listen to you](./Tutorial-NPCs-listening) - [NPCs that listen to you](./Tutorial-NPCs-listening.md)
- [Mobs that attack you](./Tutorial-Aggressive-NPCs) - [Mobs that attack you](./Tutorial-Aggressive-NPCs.md)
- [Shopkeepers](./NPC-shop-Tutorial) - [Shopkeepers](./NPC-shop-Tutorial.md)
## Vehicles ## Vehicles
- [Building a mech](./Building-a-mech-tutorial) - [Building a mech](./Building-a-mech-tutorial.md)
- [Building a train](./Tutorial-Vehicles) - [Building a train](./Tutorial-Vehicles.md)
## Systems ## Systems
- [Understanding In-game time](./Gametime-Tutorial) - [Understanding In-game time](./Gametime-Tutorial.md)
- [Understanding the Help system](./Help-System-Tutorial) - [Understanding the Help system](./Help-System-Tutorial.md)
- [Adding mass to objects](./Mass-and-weight-for-objects) - [Adding mass to objects](./Mass-and-weight-for-objects.md)
- [Add weather](./Weather-Tutorial) - [Add weather](./Weather-Tutorial.md)
## Web-related tutorials ## Web-related tutorials
- [Add a wiki](./Add-a-wiki-on-your-website) - [Add a wiki](./Add-a-wiki-on-your-website.md)
- [A web-based character generation](./Web-Character-Generation) - [A web-based character generation](./Web-Character-Generation.md)
- [View Character on website](./Web-Character-View-Tutorial) - [View Character on website](./Web-Character-View-Tutorial.md)
## Deep-dives ## Deep-dives
- [Parsing command inputs](./Parsing-commands-tutorial) - [Parsing command inputs](./Parsing-commands-tutorial.md)
- [Understanding color-tags](./Understanding-Color-Tags) - [Understanding color-tags](./Understanding-Color-Tags.md)
- [Play paper&pen RPGs online with Evennia](./Evennia-for-roleplaying-sessions) - [Play paper&pen RPGs online with Evennia](./Evennia-for-roleplaying-sessions.md)
- [Evennia for Diku Users](./Evennia-for-Diku-Users) - [Evennia for Diku Users](./Evennia-for-Diku-Users.md)
- [Evennia for MUSH-Users](./Evennia-for-MUSH-Users) - [Evennia for MUSH-Users](./Evennia-for-MUSH-Users.md)

View file

@ -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 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. 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. 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 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 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 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'. 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. `evennia.DefaultCharacter`. We will also import `evennia.utils.ansi`, which we will use later.
```python ```python
@ -39,7 +39,7 @@ In your new module(or characters.py), create a new [Typeclass](../Components/Typ
self.db.config_color = True 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 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 `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 ## 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 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 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. regardless of if Evennia thinks their client supports it or not.

Some files were not shown because too many files have changed in this diff Show more