Move starting tutorial to different name, add relative auto-relinking
This commit is contained in:
parent
cf71ea4486
commit
3e8017a874
21 changed files with 158 additions and 111 deletions
|
|
@ -6,40 +6,69 @@ directive somewhere.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
from collections import defaultdict
|
||||||
from sphinx.errors import DocumentError
|
from sphinx.errors import DocumentError
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from os.path import abspath, dirname, join as pathjoin, sep
|
from os.path import abspath, dirname, join as pathjoin, sep, relpath
|
||||||
|
|
||||||
_IGNORE_FILES = []
|
_IGNORE_FILES = []
|
||||||
_SOURCE_DIR = pathjoin(dirname(dirname(abspath(__file__))), "source")
|
_SOURCEDIR_NAME = "source"
|
||||||
|
_SOURCE_DIR = pathjoin(dirname(dirname(abspath(__file__))), _SOURCEDIR_NAME)
|
||||||
_TOC_FILE = pathjoin(_SOURCE_DIR, "toc.md")
|
_TOC_FILE = pathjoin(_SOURCE_DIR, "toc.md")
|
||||||
|
|
||||||
|
_CURRFILE = None
|
||||||
|
|
||||||
def create_toctree():
|
def create_toctree():
|
||||||
"""
|
"""
|
||||||
Create source/toc.md file
|
Create source/toc.md file
|
||||||
"""
|
|
||||||
|
|
||||||
docref_map = {}
|
"""
|
||||||
|
global _CURRFILE
|
||||||
|
|
||||||
|
def _get_rel_source_ref(path):
|
||||||
|
"""Get the path relative the source/ dir"""
|
||||||
|
pathparts = path.split("/")
|
||||||
|
# we allow a max of 4 levels of nesting in the source dir
|
||||||
|
ind = pathparts[-4:].index(_SOURCEDIR_NAME)
|
||||||
|
# get the part after source/
|
||||||
|
pathparts = pathparts[-4 + 1 + ind:]
|
||||||
|
url = "/".join(pathparts)
|
||||||
|
# get the reference, without .md
|
||||||
|
url = url.rsplit(".", 1)[0]
|
||||||
|
return url
|
||||||
|
|
||||||
|
toc_map = {}
|
||||||
|
docref_map = defaultdict(dict)
|
||||||
|
|
||||||
for path in Path(_SOURCE_DIR).rglob("*.md"):
|
for path in Path(_SOURCE_DIR).rglob("*.md"):
|
||||||
# find the source/ part of the path and strip it out
|
# find the source/ part of the path and strip it out
|
||||||
# support nesting of 3 within source/ dir
|
|
||||||
fname = path.name
|
if path.name in _IGNORE_FILES:
|
||||||
if fname in _IGNORE_FILES:
|
|
||||||
# this is the name including .md
|
# this is the name including .md
|
||||||
continue
|
continue
|
||||||
ind = path.parts[-4:].index("source")
|
|
||||||
pathparts = path.parts[-4 + 1 + ind:]
|
sourcepath = path.as_posix()
|
||||||
url = "/".join(pathparts)
|
# get name and url relative to source/
|
||||||
url = url.rsplit(".", 1)[0]
|
fname = path.name.rsplit(".", 1)[0]
|
||||||
fname = fname.rsplit(".", 1)[0]
|
src_url = _get_rel_source_ref(sourcepath)
|
||||||
if fname in docref_map:
|
|
||||||
|
# check for duplicate files
|
||||||
|
if fname in toc_map:
|
||||||
|
duplicate_src_url = toc_map[fname]
|
||||||
raise DocumentError(
|
raise DocumentError(
|
||||||
f" Tried to add '{url}.md' when '{docref_map[fname]}.md' already exists.\n"
|
f" Tried to add {src_url}.md, but a file {duplicate_src_url}.md already exists.\n"
|
||||||
" Evennia's auto-link-corrector does not accept doc-files with the same \n"
|
" Evennia's auto-link-corrector does not accept doc-files with the same \n"
|
||||||
" name, even in different folders. Rename one.\n")
|
" name, even in different folders. Rename one.\n")
|
||||||
docref_map[fname] = url
|
toc_map[fname] = src_url
|
||||||
|
|
||||||
|
# find relative links to all other files
|
||||||
|
for targetpath in Path(_SOURCE_DIR).rglob("*.md"):
|
||||||
|
|
||||||
|
targetname = targetpath.name.rsplit(".", 1)[0]
|
||||||
|
targetpath = targetpath.as_posix()
|
||||||
|
url = relpath(targetpath, dirname(sourcepath))
|
||||||
|
docref_map[sourcepath][targetname] = url.rsplit(".", 1)[0]
|
||||||
|
|
||||||
|
|
||||||
# normal reference-links [txt](urls)
|
# normal reference-links [txt](urls)
|
||||||
ref_regex = re.compile(r"\[(?P<txt>[\w -\[\]]+?)\]\((?P<url>.+?)\)", re.I + re.S + re.U)
|
ref_regex = re.compile(r"\[(?P<txt>[\w -\[\]]+?)\]\((?P<url>.+?)\)", re.I + re.S + re.U)
|
||||||
|
|
@ -57,8 +86,8 @@ def create_toctree():
|
||||||
fname = part[0] if part else fname
|
fname = part[0] if part else fname
|
||||||
fname = fname.rsplit(".", 1)[0]
|
fname = fname.rsplit(".", 1)[0]
|
||||||
fname, *anchor = fname.rsplit("#", 1)
|
fname, *anchor = fname.rsplit("#", 1)
|
||||||
if fname in docref_map:
|
if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]:
|
||||||
urlout = docref_map[fname] + ('#' + anchor[0] if anchor else '')
|
urlout = docref_map[_CURRFILE][fname] + ('#' + anchor[0] if anchor else '')
|
||||||
if urlout != url:
|
if urlout != url:
|
||||||
print(f" Remapped link [{txt}]({url}) -> [{txt}]({urlout})")
|
print(f" Remapped link [{txt}]({url}) -> [{txt}]({urlout})")
|
||||||
else:
|
else:
|
||||||
|
|
@ -76,8 +105,8 @@ def create_toctree():
|
||||||
fname = part[0] if part else fname
|
fname = part[0] if part else fname
|
||||||
fname = fname.rsplit(".", 1)[0]
|
fname = fname.rsplit(".", 1)[0]
|
||||||
fname, *anchor = fname.rsplit("#", 1)
|
fname, *anchor = fname.rsplit("#", 1)
|
||||||
if fname in docref_map:
|
if _CURRFILE in docref_map and fname in docref_map[_CURRFILE]:
|
||||||
urlout = docref_map[fname] + ('#' + anchor[0] if anchor else '')
|
urlout = docref_map[_CURRFILE][fname] + ('#' + anchor[0] if anchor else '')
|
||||||
if urlout != url:
|
if urlout != url:
|
||||||
print(f" Remapped link [{txt}]: {url} -> [{txt}]: {urlout}")
|
print(f" Remapped link [{txt}]: {url} -> [{txt}]: {urlout}")
|
||||||
else:
|
else:
|
||||||
|
|
@ -86,7 +115,11 @@ def create_toctree():
|
||||||
|
|
||||||
# replace / correct links in all files
|
# replace / correct links in all files
|
||||||
count = 0
|
count = 0
|
||||||
for path in Path(_SOURCE_DIR).rglob("*.md"):
|
for path in sorted(Path(_SOURCE_DIR).rglob("*.md"), key=lambda p: p.name):
|
||||||
|
|
||||||
|
# from pudb import debugger;debugger.Debugger().set_trace()
|
||||||
|
_CURRFILE = path.as_posix()
|
||||||
|
|
||||||
with open(path, 'r') as fil:
|
with open(path, 'r') as fil:
|
||||||
intxt = fil.read()
|
intxt = fil.read()
|
||||||
outtxt = ref_regex.sub(_sub, intxt)
|
outtxt = ref_regex.sub(_sub, intxt)
|
||||||
|
|
@ -95,7 +128,7 @@ def create_toctree():
|
||||||
with open(path, 'w') as fil:
|
with open(path, 'w') as fil:
|
||||||
fil.write(outtxt)
|
fil.write(outtxt)
|
||||||
count += 1
|
count += 1
|
||||||
print(f"Auto-relinked links in {path.name}")
|
print(f" ----- Auto-relinked links in {path.name} ------")
|
||||||
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
print(f"Auto-corrected links in {count} documents.")
|
print(f"Auto-corrected links in {count} documents.")
|
||||||
|
|
@ -104,7 +137,7 @@ def create_toctree():
|
||||||
with open(_TOC_FILE, "w") as fil:
|
with open(_TOC_FILE, "w") as fil:
|
||||||
fil.write("# Toc\n")
|
fil.write("# Toc\n")
|
||||||
|
|
||||||
for ref in sorted(docref_map.values()):
|
for ref in sorted(toc_map.values()):
|
||||||
|
|
||||||
if ref == "toc":
|
if ref == "toc":
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
4
docs/source/Evennia-API.md
Normal file
4
docs/source/Evennia-API.md
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# API
|
||||||
|
|
||||||
|
- [evennia.accounts](api:evennia.accounts)
|
||||||
|
-
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Adding Command Tutorial
|
# Adding Command Tutorial
|
||||||
|
|
||||||
This is a quick first-time tutorial expanding on the [Commands](Component/Commands) documentation.
|
This is a quick first-time tutorial expanding on the [Commands](../../Component/Commands) documentation.
|
||||||
|
|
||||||
Let's assume you have just downloaded Evennia, installed it and created your game folder (let's call
|
Let's assume you have just downloaded Evennia, installed it and created your game folder (let's call
|
||||||
it just `mygame` here). Now you want to try to add a new command. This is the fastest way to do it.
|
it just `mygame` here). Now you want to try to add a new command. This is the fastest way to do it.
|
||||||
|
|
@ -16,7 +16,7 @@ example code.
|
||||||
1. Give your class a useful _docstring_. A docstring is the string at the very top of a class or
|
1. Give your class a useful _docstring_. A docstring is the string at the very top of a class or
|
||||||
function/method. The docstring at the top of the command class is read by Evennia to become the help
|
function/method. The docstring at the top of the command class is read by Evennia to become the help
|
||||||
entry for the Command (see
|
entry for the Command (see
|
||||||
[Command Auto-help](Component/Help-System#command-auto-help-system)).
|
[Command Auto-help](../../Component/Help-System#command-auto-help-system)).
|
||||||
1. Define a class method `func(self)` that echoes your input back to you.
|
1. Define a class method `func(self)` that echoes your input back to you.
|
||||||
|
|
||||||
Below is an example how this all could look for the echo command:
|
Below is an example how this all could look for the echo command:
|
||||||
|
|
@ -47,7 +47,7 @@ Below is an example how this all could look for the echo command:
|
||||||
|
|
||||||
## Step 2: Adding the Command to a default Cmdset
|
## Step 2: Adding the Command to a default Cmdset
|
||||||
|
|
||||||
The command is not available to use until it is part of a [Command Set](Component/Command-Sets). In this
|
The command is not available to use until it is part of a [Command Set](../../Component/Command-Sets). In this
|
||||||
example we will go the easiest route and add it to the default Character commandset that already
|
example we will go the easiest route and add it to the default Character commandset that already
|
||||||
exists.
|
exists.
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ If you want to overload existing default commands (such as `look` or `get`), jus
|
||||||
command with the same key as the old one - it will then replace it. Just remember that you must use
|
command with the same key as the old one - it will then replace it. Just remember that you must use
|
||||||
`@reload` to see any changes.
|
`@reload` to see any changes.
|
||||||
|
|
||||||
See [Commands](Component/Commands) for many more details and possibilities when defining Commands and using
|
See [Commands](../../Component/Commands) for many more details and possibilities when defining Commands and using
|
||||||
Cmdsets in various ways.
|
Cmdsets in various ways.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ only make the new merged cmdset permanent on that *single* object. Often you wan
|
||||||
this particular class to have this cmdset.
|
this particular class to have this cmdset.
|
||||||
|
|
||||||
To make sure all new created objects get your new merged set, put the `cmdset.add` call in your
|
To make sure all new created objects get your new merged set, put the `cmdset.add` call in your
|
||||||
custom [Typeclasses](Component/Typeclasses)' `at_object_creation` method:
|
custom [Typeclasses](../../Component/Typeclasses)' `at_object_creation` method:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# e.g. in mygame/typeclasses/objects.py
|
# e.g. in mygame/typeclasses/objects.py
|
||||||
|
|
@ -13,9 +13,9 @@ When you create a new Evennia game (with for example `evennia --init mygame`) Ev
|
||||||
automatically create empty child classes `Object`, `Character`, `Room` and `Exit` respectively. They
|
automatically create empty child classes `Object`, `Character`, `Room` and `Exit` respectively. They
|
||||||
are found `mygame/typeclasses/objects.py`, `mygame/typeclasses/rooms.py` etc.
|
are found `mygame/typeclasses/objects.py`, `mygame/typeclasses/rooms.py` etc.
|
||||||
|
|
||||||
> Technically these are all [Typeclassed](Component/Typeclasses), which can be ignored for now. In
|
> Technically these are all [Typeclassed](../../Component/Typeclasses), which can be ignored for now. In
|
||||||
> `mygame/typeclasses` are also base typeclasses for out-of-character things, notably
|
> `mygame/typeclasses` are also base typeclasses for out-of-character things, notably
|
||||||
> [Channels](Component/Communications), [Accounts](Component/Accounts) and [Scripts](Component/Scripts). We don't cover those in
|
> [Channels](../../Component/Communications), [Accounts](../../Component/Accounts) and [Scripts](../../Component/Scripts). We don't cover those in
|
||||||
> this tutorial.
|
> this tutorial.
|
||||||
|
|
||||||
For your own game you will most likely want to expand on these very simple beginnings. It's normal
|
For your own game you will most likely want to expand on these very simple beginnings. It's normal
|
||||||
|
|
@ -62,13 +62,13 @@ up.
|
||||||
you will find the traceback. The most common error is that you have some sort of syntax error in
|
you will find the traceback. The most common error is that you have some sort of syntax error in
|
||||||
your class.
|
your class.
|
||||||
|
|
||||||
Note that the [Locks](Component/Locks) and [Attribute](Component/Attributes) which are set in the typeclass could just
|
Note that the [Locks](../../Component/Locks) and [Attribute](../../Component/Attributes) which are set in the typeclass could just
|
||||||
as well have been set using commands in-game, so this is a *very* simple example.
|
as well have been set using commands in-game, so this is a *very* simple example.
|
||||||
|
|
||||||
## Storing data on initialization
|
## Storing data on initialization
|
||||||
|
|
||||||
The `at_object_creation` is only called once, when the object is first created. This makes it ideal
|
The `at_object_creation` is only called once, when the object is first created. This makes it ideal
|
||||||
for database-bound things like [Attributes](Component/Attributes). But sometimes you want to create temporary
|
for database-bound things like [Attributes](../../Component/Attributes). But sometimes you want to create temporary
|
||||||
properties (things that are not to be stored in the database but still always exist every time the
|
properties (things that are not to be stored in the database but still always exist every time the
|
||||||
object is created). Such properties can be initialized in the `at_init` method on the object.
|
object is created). Such properties can be initialized in the `at_init` method on the object.
|
||||||
`at_init` is called every time the object is loaded into memory.
|
`at_init` is called every time the object is loaded into memory.
|
||||||
|
|
@ -86,7 +86,7 @@ def at_init(self):
|
||||||
self.ndb.mylist = []
|
self.ndb.mylist = []
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: As mentioned in the [Typeclasses](Component/Typeclasses) documentation, `at_init` replaces the use of
|
> Note: As mentioned in the [Typeclasses](../../Component/Typeclasses) documentation, `at_init` replaces the use of
|
||||||
> the standard `__init__` method of typeclasses due to how the latter may be called in situations
|
> the standard `__init__` method of typeclasses due to how the latter may be called in situations
|
||||||
> other than you'd expect. So use `at_init` where you would normally use `__init__`.
|
> other than you'd expect. So use `at_init` where you would normally use `__init__`.
|
||||||
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Building Quickstart
|
# Building Quickstart
|
||||||
|
|
||||||
|
|
||||||
The [default command](Component/Default-Command-Help) definitions coming with Evennia
|
The [default command](../../Component/Default-Command-Help) definitions coming with Evennia
|
||||||
follows a style [similar](Concept/Using-MUX-as-a-Standard) to that of MUX, so the
|
follows a style [similar](../../Concept/Using-MUX-as-a-Standard) to that of MUX, so the
|
||||||
commands should be familiar if you used any such code bases before.
|
commands should be familiar if you used any such code bases before.
|
||||||
|
|
||||||
> Throughout the larger documentation you may come across commands prefixed
|
> Throughout the larger documentation you may come across commands prefixed
|
||||||
|
|
@ -85,14 +85,14 @@ dropped in the room, then try this:
|
||||||
|
|
||||||
lock box = get:false()
|
lock box = get:false()
|
||||||
|
|
||||||
Locks represent a rather [big topic](Component/Locks), but for now that will do what we want. This will lock
|
Locks represent a rather [big topic](../../Component/Locks), but for now that will do what we want. This will lock
|
||||||
the box so noone can lift it. The exception is superusers, they override all locks and will pick it
|
the box so noone can lift it. The exception is superusers, they override all locks and will pick it
|
||||||
up anyway. Make sure you are quelling your superuser powers and try to get the box now:
|
up anyway. Make sure you are quelling your superuser powers and try to get the box now:
|
||||||
|
|
||||||
> get box
|
> get box
|
||||||
You can't get that.
|
You can't get that.
|
||||||
|
|
||||||
Think thís default error message looks dull? The `get` command looks for an [Attribute](Component/Attributes)
|
Think thís default error message looks dull? The `get` command looks for an [Attribute](../../Component/Attributes)
|
||||||
named `get_err_msg` for returning a nicer error message (we just happen to know this, you would need
|
named `get_err_msg` for returning a nicer error message (we just happen to know this, you would need
|
||||||
to peek into the
|
to peek into the
|
||||||
[code](https://github.com/evennia/evennia/blob/master/evennia/commands/default/general.py#L235) for
|
[code](https://github.com/evennia/evennia/blob/master/evennia/commands/default/general.py#L235) for
|
||||||
|
|
@ -114,7 +114,7 @@ Commands tutorial](Adding-Command-Tutorial) for help with creating your first ow
|
||||||
|
|
||||||
## Get a Personality
|
## Get a Personality
|
||||||
|
|
||||||
[Scripts](Component/Scripts) are powerful out-of-character objects useful for many "under the hood" things.
|
[Scripts](../../Component/Scripts) are powerful out-of-character objects useful for many "under the hood" things.
|
||||||
One of their optional abilities is to do things on a timer. To try out a first script, let's put one
|
One of their optional abilities is to do things on a timer. To try out a first script, let's put one
|
||||||
on ourselves. There is an example script in `evennia/contrib/tutorial_examples/bodyfunctions.py`
|
on ourselves. There is an example script in `evennia/contrib/tutorial_examples/bodyfunctions.py`
|
||||||
that is called `BodyFunctions`. To add this to us we will use the `script` command:
|
that is called `BodyFunctions`. To add this to us we will use the `script` command:
|
||||||
|
|
@ -137,14 +137,14 @@ When you are tired of your character's "insights", kill the script with
|
||||||
script/stop self = tutorial_examples.bodyfunctions.BodyFunctions
|
script/stop self = tutorial_examples.bodyfunctions.BodyFunctions
|
||||||
|
|
||||||
You create your own scripts in Python, outside the game; the path you give to `script` is literally
|
You create your own scripts in Python, outside the game; the path you give to `script` is literally
|
||||||
the Python path to your script file. The [Scripts](Component/Scripts) page explains more details.
|
the Python path to your script file. The [Scripts](../../Component/Scripts) page explains more details.
|
||||||
|
|
||||||
## Pushing Your Buttons
|
## Pushing Your Buttons
|
||||||
|
|
||||||
If we get back to the box we made, there is only so much fun you can do with it at this point. It's
|
If we get back to the box we made, there is only so much fun you can do with it at this point. It's
|
||||||
just a dumb generic object. If you renamed it to `stone` and changed its description noone would be
|
just a dumb generic object. If you renamed it to `stone` and changed its description noone would be
|
||||||
the wiser. However, with the combined use of custom [Typeclasses](Component/Typeclasses), [Scripts](Component/Scripts)
|
the wiser. However, with the combined use of custom [Typeclasses](../../Component/Typeclasses), [Scripts](../../Component/Scripts)
|
||||||
and object-based [Commands](Component/Commands), you could expand it and other items to be as unique, complex
|
and object-based [Commands](../../Component/Commands), you could expand it and other items to be as unique, complex
|
||||||
and interactive as you want.
|
and interactive as you want.
|
||||||
|
|
||||||
Let's take an example. So far we have only created objects that use the default object typeclass
|
Let's take an example. So far we have only created objects that use the default object typeclass
|
||||||
|
|
@ -161,7 +161,7 @@ sure to look in`evennia/contrib/` so you don't have to write the full path every
|
||||||
- one red button.
|
- one red button.
|
||||||
|
|
||||||
The RedButton is an example object intended to show off a few of Evennia's features. You will find
|
The RedButton is an example object intended to show off a few of Evennia's features. You will find
|
||||||
that the [Typeclass](Component/Typeclasses) and [Commands](Component/Commands) controlling it are inside
|
that the [Typeclass](../../Component/Typeclasses) and [Commands](../../Component/Commands) controlling it are inside
|
||||||
`evennia/contrib/tutorial_examples/`.
|
`evennia/contrib/tutorial_examples/`.
|
||||||
|
|
||||||
If you wait for a while (make sure you dropped it!) the button will blink invitingly. Why don't you
|
If you wait for a while (make sure you dropped it!) the button will blink invitingly. Why don't you
|
||||||
|
|
@ -10,7 +10,7 @@ Here are some pointers to get you going.
|
||||||
|
|
||||||
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 two-part [Python introduction](Howto/StartingTutorial/Python-basic-introduction).
|
take a look at our two-part [Python introduction](Python-basic-introduction).
|
||||||
|
|
||||||
### Explore Evennia interactively
|
### Explore Evennia interactively
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ 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](Coding/Evennia-API) page for more
|
available at the top level of Evennia's "flat API". See the [flat API](../../Evennia-API) page for more
|
||||||
info on how to explore it efficiently.
|
info on how to explore it efficiently.
|
||||||
|
|
||||||
You can complement your exploration by peeking at the sections of the much more detailed [Developer
|
You can complement your exploration by peeking at the sections of the much more detailed [Developer
|
||||||
|
|
@ -52,7 +52,7 @@ 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/Game-Planning)
|
Before you start coding away at your dream game, take a look at our [Game Planning](../Game-Planning)
|
||||||
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
|
||||||
|
|
@ -64,7 +64,7 @@ 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](feature-request) about it. Same goes for [bugs][bug]. If you add features or fix bugs
|
Request](feature-request) 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) your changes upstream!
|
||||||
|
|
||||||
### Learn to read tracebacks
|
### Learn to read tracebacks
|
||||||
|
|
||||||
|
|
@ -16,11 +16,11 @@ system.
|
||||||
|
|
||||||
- **self** / **me** - the calling object (i.e. you)
|
- **self** / **me** - the calling object (i.e. you)
|
||||||
- **here** - the current caller's location
|
- **here** - the current caller's location
|
||||||
- **obj** - a dummy [Object](Component/Objects) instance
|
- **obj** - a dummy [Object](../../Component/Objects) instance
|
||||||
- **evennia** - Evennia's [flat API](Coding/Evennia-API) - through this you can access all of Evennia.
|
- **evennia** - Evennia's [flat API](../../Evennia-API) - through this you can access all of Evennia.
|
||||||
|
|
||||||
For accessing other objects in the same room you need to use `self.search(name)`. For objects in
|
For accessing other objects in the same room you need to use `self.search(name)`. For objects in
|
||||||
other locations, use one of the `evennia.search_*` methods. See [below](Howto/StartingTutorial/Execute-Python-Code#finding-
|
other locations, use one of the `evennia.search_*` methods. See [below](Execute-Python-Code#finding-
|
||||||
objects).
|
objects).
|
||||||
|
|
||||||
## Returning output
|
## Returning output
|
||||||
|
|
@ -117,4 +117,4 @@ of other editing features, such as tab-completion and `__doc__`-string reading.
|
||||||
In [2]: evennia.managers.objects.all()
|
In [2]: evennia.managers.objects.all()
|
||||||
Out[3]: [<ObjectDB: Harry>, <ObjectDB: Limbo>, ...]
|
Out[3]: [<ObjectDB: Harry>, <ObjectDB: Limbo>, ...]
|
||||||
|
|
||||||
See the page about the [Evennia-API](Coding/Evennia-API) for more things to explore.
|
See the page about the [Evennia-API](../../Evennia-API) for more things to explore.
|
||||||
|
|
@ -10,7 +10,7 @@ Started](Getting-Started) instructions. You should have initialized a new game f
|
||||||
`evennia --init foldername` command. We will in the following assume this folder is called
|
`evennia --init foldername` command. We will in the following assume this folder is called
|
||||||
"mygame".
|
"mygame".
|
||||||
|
|
||||||
It might be a good idea to eye through the brief [Coding Introduction](Howto/StartingTutorial/Coding-Introduction) too
|
It might be a good idea to eye through the brief [Coding Introduction](Coding-Introduction) too
|
||||||
(especially the recommendations in the section about the evennia "flat" API and about using `evennia
|
(especially the recommendations in the section about the evennia "flat" API and about using `evennia
|
||||||
shell` will help you here and in the future).
|
shell` will help you here and in the future).
|
||||||
|
|
||||||
|
|
@ -57,13 +57,13 @@ up with a new command to view those attributes.
|
||||||
return self.db.strength, self.db.agility, self.db.magic
|
return self.db.strength, self.db.agility, self.db.magic
|
||||||
```
|
```
|
||||||
|
|
||||||
1. [Reload](Setup/Start-Stop-Reload) the server (you will still be connected to the game after doing
|
1. [Reload](../../Setup/Start-Stop-Reload) the server (you will still be connected to the game after doing
|
||||||
this). Note that if you examine *yourself* you will *not* see any new Attributes appear yet. Read
|
this). Note that if you examine *yourself* you will *not* see any new Attributes appear yet. Read
|
||||||
the next section to understand why.
|
the next section to understand why.
|
||||||
|
|
||||||
#### Updating Yourself
|
#### Updating Yourself
|
||||||
|
|
||||||
It's important to note that the new [Attributes](Component/Attributes) we added above will only be stored on
|
It's important to note that the new [Attributes](../../Component/Attributes) we added above will only be stored on
|
||||||
*newly* created characters. The reason for this is simple: The `at_object_creation` method, where we
|
*newly* created characters. The reason for this is simple: The `at_object_creation` method, where we
|
||||||
added those Attributes, is per definition only called when the object is *first created*, then never
|
added those Attributes, is per definition only called when the object is *first created*, then never
|
||||||
again. This is usually a good thing since those Attributes may change over time - calling that hook
|
again. This is usually a good thing since those Attributes may change over time - calling that hook
|
||||||
|
|
@ -112,8 +112,8 @@ what the `@update` command does under the hood). From in-game you can do the sam
|
||||||
MyClass.objects.all()]
|
MyClass.objects.all()]
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [Object Typeclass tutorial](Howto/StartingTutorial/Adding-Object-Typeclass-Tutorial) for more help and the
|
See the [Object Typeclass tutorial](Adding-Object-Typeclass-Tutorial) for more help and the
|
||||||
[Typeclasses](Component/Typeclasses) and [Attributes](Component/Attributes) page for detailed documentation about
|
[Typeclasses](../../Component/Typeclasses) and [Attributes](../../Component/Attributes) page for detailed documentation about
|
||||||
Typeclasses and Attributes.
|
Typeclasses and Attributes.
|
||||||
|
|
||||||
#### Troubleshooting: Updating Yourself
|
#### Troubleshooting: Updating Yourself
|
||||||
|
|
@ -159,7 +159,7 @@ tracebacks and you'll be able to resolve the vast majority of common errors easi
|
||||||
### Add a New Default Command
|
### Add a New Default Command
|
||||||
|
|
||||||
The `@py` command used above is only available to privileged users. We want any player to be able to
|
The `@py` command used above is only available to privileged users. We want any player to be able to
|
||||||
see their stats. Let's add a new [command](Component/Commands) to list the abilities we added in the previous
|
see their stats. Let's add a new [command](../../Component/Commands) to list the abilities we added in the previous
|
||||||
section.
|
section.
|
||||||
|
|
||||||
1. Open `mygame/commands/command.py`. You could in principle put your command anywhere but this
|
1. Open `mygame/commands/command.py`. You could in principle put your command anywhere but this
|
||||||
|
|
@ -201,7 +201,7 @@ the bottom of this file:
|
||||||
self.add(CmdAbilities())
|
self.add(CmdAbilities())
|
||||||
```
|
```
|
||||||
|
|
||||||
1. [Reload](Setup/Start-Stop-Reload) the server (noone will be disconnected by doing this).
|
1. [Reload](../../Setup/Start-Stop-Reload) the server (noone will be disconnected by doing this).
|
||||||
|
|
||||||
You (and anyone else) should now be able to use `abilities` (or its alias `abi`) as part of your
|
You (and anyone else) should now be able to use `abilities` (or its alias `abi`) as part of your
|
||||||
normal commands in-game:
|
normal commands in-game:
|
||||||
|
|
@ -211,8 +211,8 @@ abilities
|
||||||
STR: 5, AGI: 4, MAG: 2
|
STR: 5, AGI: 4, MAG: 2
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [Adding a Command tutorial](Howto/StartingTutorial/Adding-Command-Tutorial) for more examples and the
|
See the [Adding a Command tutorial](Adding-Command-Tutorial) for more examples and the
|
||||||
[Commands](Component/Commands) section for detailed documentation about the Command system.
|
[Commands](../../Component/Commands) section for detailed documentation about the Command system.
|
||||||
|
|
||||||
### Make a New Type of Object
|
### Make a New Type of Object
|
||||||
|
|
||||||
|
|
@ -263,7 +263,7 @@ functionality. Here is an example of how the file could look:
|
||||||
|
|
||||||
1. Check your code for bugs. Tracebacks will appear on your command line or log. If you have a grave
|
1. Check your code for bugs. Tracebacks will appear on your command line or log. If you have a grave
|
||||||
Syntax Error in your code, the source file itself will fail to load which can cause issues with the
|
Syntax Error in your code, the source file itself will fail to load which can cause issues with the
|
||||||
entire cmdset. If so, fix your bug and [reload the server from the command line](Setup/Start-Stop-Reload)
|
entire cmdset. If so, fix your bug and [reload the server from the command line](../../Setup/Start-Stop-Reload)
|
||||||
(noone will be disconnected by doing this).
|
(noone will be disconnected by doing this).
|
||||||
1. Use `@create/drop stone:wiseobject.WiseObject` to create a talkative stone. If the `@create`
|
1. Use `@create/drop stone:wiseobject.WiseObject` to create a talkative stone. If the `@create`
|
||||||
command spits out a warning or cannot find the typeclass (it will tell you which paths it searched),
|
command spits out a warning or cannot find the typeclass (it will tell you which paths it searched),
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
|
|
||||||
This tutorial will elaborate on the many ways one can parse command arguments. The first step after
|
This tutorial will elaborate on the many ways one can parse command arguments. The first step after
|
||||||
[adding a command](Howto/StartingTutorial/Adding-Command-Tutorial) usually is to parse its arguments. There are lots of
|
[adding a command](Adding-Command-Tutorial) usually is to parse its arguments. There are lots of
|
||||||
ways to do it, but some are indeed better than others and this tutorial will try to present them.
|
ways to do it, but some are indeed better than others and this tutorial will try to present them.
|
||||||
|
|
||||||
If you're a Python beginner, this tutorial might help you a lot. If you're already familiar with
|
If you're a Python beginner, this tutorial might help you a lot. If you're already familiar with
|
||||||
|
|
@ -652,7 +652,7 @@ about... what is this `"book"`?
|
||||||
|
|
||||||
To get an object from a string, we perform an Evennia search. Evennia provides a `search` method on
|
To get an object from a string, we perform an Evennia search. Evennia provides a `search` method on
|
||||||
all typeclassed objects (you will most likely use the one on characters or accounts). This method
|
all typeclassed objects (you will most likely use the one on characters or accounts). This method
|
||||||
supports a very wide array of arguments and has [its own tutorial](Howto/StartingTutorial/Tutorial-Searching-For-Objects).
|
supports a very wide array of arguments and has [its own tutorial](Tutorial-Searching-For-Objects).
|
||||||
Some examples of useful cases follow:
|
Some examples of useful cases follow:
|
||||||
|
|
||||||
### Local searches
|
### Local searches
|
||||||
|
|
@ -7,14 +7,14 @@ and low on detail. There are countless Python guides and tutorials, books and vi
|
||||||
learning more in-depth - use them!
|
learning more in-depth - use them!
|
||||||
|
|
||||||
**Contents:**
|
**Contents:**
|
||||||
- [Evennia Hello world](Howto/StartingTutorial/Python-basic-introduction#evennia-hello-world)
|
- [Evennia Hello world](Python-basic-introduction#evennia-hello-world)
|
||||||
- [Importing modules](Howto/StartingTutorial/Python-basic-introduction#importing-modules)
|
- [Importing modules](Python-basic-introduction#importing-modules)
|
||||||
- [Parsing Python errors](Howto/StartingTutorial/Python-basic-introduction#parsing-python-errors)
|
- [Parsing Python errors](Python-basic-introduction#parsing-python-errors)
|
||||||
- [Our first function](Howto/StartingTutorial/Python-basic-introduction#our-first-function)
|
- [Our first function](Python-basic-introduction#our-first-function)
|
||||||
- [Looking at the log](Howto/StartingTutorial/Python-basic-introduction#looking-at-the-log)
|
- [Looking at the log](Python-basic-introduction#looking-at-the-log)
|
||||||
- (continued in [part 2](Howto/StartingTutorial/Python-basic-tutorial-part-two))
|
- (continued in [part 2](Python-basic-tutorial-part-two))
|
||||||
|
|
||||||
This quickstart assumes you have [gotten Evennia started](Setup/Getting-Started). You should make sure
|
This quickstart assumes you have [gotten Evennia started](../../Setup/Getting-Started). You should make sure
|
||||||
that you are able to see the output from the server in the console from which you started it. Log
|
that you are able to see the output from the server in the console from which you started it. Log
|
||||||
into the game either with a mud client on `localhost:4000` or by pointing a web browser to
|
into the game either with a mud client on `localhost:4000` or by pointing a web browser to
|
||||||
`localhost:4001/webclient`. Log in as your superuser (the user you created during install).
|
`localhost:4001/webclient`. Log in as your superuser (the user you created during install).
|
||||||
|
|
@ -263,5 +263,5 @@ enter `Ctrl-C` or `Cmd-C` depending on your system. As a game dev it is importa
|
||||||
log output when working in Evennia - many errors will only appear with full details here. You may
|
log output when working in Evennia - many errors will only appear with full details here. You may
|
||||||
sometimes have to scroll up in the history if you miss it.
|
sometimes have to scroll up in the history if you miss it.
|
||||||
|
|
||||||
This tutorial is continued in [Part 2](Howto/StartingTutorial/Python-basic-tutorial-part-two), where we'll start learning
|
This tutorial is continued in [Part 2](Python-basic-tutorial-part-two), where we'll start learning
|
||||||
about objects and to explore the Evennia library.
|
about objects and to explore the Evennia library.
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
# Python basic tutorial part two
|
# Python basic tutorial part two
|
||||||
|
|
||||||
[In the first part](Howto/StartingTutorial/Python-basic-introduction) of this Python-for-Evennia basic tutorial we learned
|
[In the first part](Python-basic-introduction) of this Python-for-Evennia basic tutorial we learned
|
||||||
how to run some simple Python code from inside the game. We also made our first new *module*
|
how to run some simple Python code from inside the game. We also made our first new *module*
|
||||||
containing a *function* that we called. Now we're going to start exploring the very important
|
containing a *function* that we called. Now we're going to start exploring the very important
|
||||||
subject of *objects*.
|
subject of *objects*.
|
||||||
|
|
||||||
**Contents:**
|
**Contents:**
|
||||||
- [On the subject of objects](Howto/StartingTutorial/Python-basic-tutorial-part-two#on-the-subject-of-objects)
|
- [On the subject of objects](Python-basic-tutorial-part-two#on-the-subject-of-objects)
|
||||||
- [Exploring the Evennia library](Howto/StartingTutorial/Python-basic-tutorial-part-two#exploring-the-evennia-library)
|
- [Exploring the Evennia library](Python-basic-tutorial-part-two#exploring-the-evennia-library)
|
||||||
- [Tweaking our Character class](Howto/StartingTutorial/Python-basic-tutorial-part-two#tweaking-our-character-class)
|
- [Tweaking our Character class](Python-basic-tutorial-part-two#tweaking-our-character-class)
|
||||||
- [The Evennia shell](Howto/StartingTutorial/Python-basic-tutorial-part-two#the-evennia-shell)
|
- [The Evennia shell](Python-basic-tutorial-part-two#the-evennia-shell)
|
||||||
- [Where to go from here](Howto/StartingTutorial/Python-basic-tutorial-part-two#where-to-go-from-here)
|
- [Where to go from here](Python-basic-tutorial-part-two#where-to-go-from-here)
|
||||||
|
|
||||||
### On the subject of objects
|
### On the subject of objects
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ There are lots of things in there. There are some docs but most of those have to
|
||||||
distribution of Evennia and does not concern us right now. The `evennia` subfolder is what we are
|
distribution of Evennia and does not concern us right now. The `evennia` subfolder is what we are
|
||||||
looking for. *This* is what you are accessing when you do `from evennia import ...`. It's set up by
|
looking for. *This* is what you are accessing when you do `from evennia import ...`. It's set up by
|
||||||
Evennia as a good place to find modules when the server starts. The exact layout of the Evennia
|
Evennia as a good place to find modules when the server starts. The exact layout of the Evennia
|
||||||
library [is covered by our directory overview](Coding/Directory-Overview#evennia-library-layout). You can
|
library [is covered by our directory overview](../../Coding/Directory-Overview#evennia-library-layout). You can
|
||||||
also explore it [online on github](https://github.com/evennia/evennia/tree/master/evennia).
|
also explore it [online on github](https://github.com/evennia/evennia/tree/master/evennia).
|
||||||
|
|
||||||
The structure of the library directly reflects how you import from it.
|
The structure of the library directly reflects how you import from it.
|
||||||
|
|
@ -224,7 +224,7 @@ is the same thing, just a little easier to remember.
|
||||||
|
|
||||||
> To access the shortcuts of the flat API you *must* use `from evennia import
|
> To access the shortcuts of the flat API you *must* use `from evennia import
|
||||||
> ...`. Using something like `import evennia.DefaultCharacter` will not work.
|
> ...`. Using something like `import evennia.DefaultCharacter` will not work.
|
||||||
> See [more about the Flat API here](Coding/Evennia-API).
|
> See [more about the Flat API here](../../Evennia-API).
|
||||||
|
|
||||||
|
|
||||||
### Tweaking our Character class
|
### Tweaking our Character class
|
||||||
|
|
@ -283,8 +283,8 @@ brief summary of the methods we find in `DefaultCharacter` (follow in the code t
|
||||||
roughly where things happen)::
|
roughly where things happen)::
|
||||||
|
|
||||||
- `basetype_setup` is called by Evennia only once, when a Character is first created. In the
|
- `basetype_setup` is called by Evennia only once, when a Character is first created. In the
|
||||||
`DefaultCharacter` class it sets some particular [Locks](Component/Locks) so that people can't pick up and
|
`DefaultCharacter` class it sets some particular [Locks](../../Component/Locks) so that people can't pick up and
|
||||||
puppet Characters just like that. It also adds the [Character Cmdset](Component/Command-Sets) so that
|
puppet Characters just like that. It also adds the [Character Cmdset](../../Component/Command-Sets) so that
|
||||||
Characters always can accept command-input (this should usually not be modified - the normal hook to
|
Characters always can accept command-input (this should usually not be modified - the normal hook to
|
||||||
override is `at_object_creation`, which is called after `basetype_setup` (it's in the parent)).
|
override is `at_object_creation`, which is called after `basetype_setup` (it's in the parent)).
|
||||||
- `at_after_move` makes it so that every time the Character moves, the `look` command is
|
- `at_after_move` makes it so that every time the Character moves, the `look` command is
|
||||||
|
|
@ -484,7 +484,7 @@ convenient for quickly exploring code without having to go digging through the f
|
||||||
|
|
||||||
This should give you a running start using Python with Evennia. If you are completely new to
|
This should give you a running start using Python with Evennia. If you are completely new to
|
||||||
programming or Python you might want to look at a more formal Python tutorial. You can find links
|
programming or Python you might want to look at a more formal Python tutorial. You can find links
|
||||||
and resources [on our link page](Links).
|
and resources [on our link page](../../Links).
|
||||||
|
|
||||||
We have touched upon many of the concepts here but to use Evennia and to be able to follow along in
|
We have touched upon many of the concepts here but to use Evennia and to be able to follow along in
|
||||||
the code, you will need basic understanding of Python
|
the code, you will need basic understanding of Python
|
||||||
3
docs/source/Howto/Starting/Starting-Introduction.md
Normal file
3
docs/source/Howto/Starting/Starting-Introduction.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Evennia Starting Tutorial
|
||||||
|
|
||||||
|
This starts your path towards making your own game in Evennia.
|
||||||
|
|
@ -31,7 +31,7 @@ allows for emoting as part of combat which is an advantage for roleplay-heavy ga
|
||||||
To implement a freeform combat system all you need is a dice roller and a roleplaying rulebook. See
|
To implement a freeform combat system all you need is a dice roller and a roleplaying rulebook. See
|
||||||
[contrib/dice.py](https://github.com/evennia/evennia/blob/master/evennia/contrib/dice.py) for an
|
[contrib/dice.py](https://github.com/evennia/evennia/blob/master/evennia/contrib/dice.py) for an
|
||||||
example dice roller. To implement at twitch-based system you basically need a few combat
|
example dice roller. To implement at twitch-based system you basically need a few combat
|
||||||
[commands](Component/Commands), possibly ones with a [cooldown](Howto/Command-Cooldown). You also need a [game rule
|
[commands](../../Component/Commands), possibly ones with a [cooldown](../Command-Cooldown). You also need a [game rule
|
||||||
module](Implementing-a-game-rule-system) that makes use of it. We will focus on the turn-based
|
module](Implementing-a-game-rule-system) that makes use of it. We will focus on the turn-based
|
||||||
variety here.
|
variety here.
|
||||||
|
|
||||||
|
|
@ -61,22 +61,22 @@ reported. A new turn then begins.
|
||||||
|
|
||||||
For creating the combat system we will need the following components:
|
For creating the combat system we will need the following components:
|
||||||
|
|
||||||
- A combat handler. This is the main mechanic of the system. This is a [Script](Component/Scripts) object
|
- A combat handler. This is the main mechanic of the system. This is a [Script](../../Component/Scripts) object
|
||||||
created for each combat. It is not assigned to a specific object but is shared by the combating
|
created for each combat. It is not assigned to a specific object but is shared by the combating
|
||||||
characters and handles all the combat information. Since Scripts are database entities it also means
|
characters and handles all the combat information. Since Scripts are database entities it also means
|
||||||
that the combat will not be affected by a server reload.
|
that the combat will not be affected by a server reload.
|
||||||
- A combat [command set](Component/Command-Sets) with the relevant commands needed for combat, such as the
|
- A combat [command set](../../Component/Command-Sets) with the relevant commands needed for combat, such as the
|
||||||
various attack/defend options and the `flee/disengage` command to leave the combat mode.
|
various attack/defend options and the `flee/disengage` command to leave the combat mode.
|
||||||
- A rule resolution system. The basics of making such a module is described in the [rule system
|
- A rule resolution system. The basics of making such a module is described in the [rule system
|
||||||
tutorial](Implementing-a-game-rule-system). We will only sketch such a module here for our end-turn
|
tutorial](Implementing-a-game-rule-system). We will only sketch such a module here for our end-turn
|
||||||
combat resolution.
|
combat resolution.
|
||||||
- An `attack` [command](Component/Commands) for initiating the combat mode. This is added to the default
|
- An `attack` [command](../../Component/Commands) for initiating the combat mode. This is added to the default
|
||||||
command set. It will create the combat handler and add the character(s) to it. It will also assign
|
command set. It will create the combat handler and add the character(s) to it. It will also assign
|
||||||
the combat command set to the characters.
|
the combat command set to the characters.
|
||||||
|
|
||||||
## The combat handler
|
## The combat handler
|
||||||
|
|
||||||
The _combat handler_ is implemented as a stand-alone [Script](Component/Scripts). This Script is created when
|
The _combat handler_ is implemented as a stand-alone [Script](../../Component/Scripts). This Script is created when
|
||||||
the first Character decides to attack another and is deleted when no one is fighting any more. Each
|
the first Character decides to attack another and is deleted when no one is fighting any more. Each
|
||||||
handler represents one instance of combat and one combat only. Each instance of combat can hold any
|
handler represents one instance of combat and one combat only. Each instance of combat can hold any
|
||||||
number of characters but each character can only be part of one combat at a time (a player would
|
number of characters but each character can only be part of one combat at a time (a player would
|
||||||
|
|
@ -89,7 +89,7 @@ don't use this very much here this might allow the combat commands on the charac
|
||||||
update the combat handler state directly.
|
update the combat handler state directly.
|
||||||
|
|
||||||
_Note: Another way to implement a combat handler would be to use a normal Python object and handle
|
_Note: Another way to implement a combat handler would be to use a normal Python object and handle
|
||||||
time-keeping with the [TickerHandler](Component/TickerHandler). This would require either adding custom hook
|
time-keeping with the [TickerHandler](../../Component/TickerHandler). This would require either adding custom hook
|
||||||
methods on the character or to implement a custom child of the TickerHandler class to track turns.
|
methods on the character or to implement a custom child of the TickerHandler class to track turns.
|
||||||
Whereas the TickerHandler is easy to use, a Script offers more power in this case._
|
Whereas the TickerHandler is easy to use, a Script offers more power in this case._
|
||||||
|
|
||||||
|
|
@ -506,7 +506,7 @@ class CmdAttack(Command):
|
||||||
```
|
```
|
||||||
|
|
||||||
The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g.
|
The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g.
|
||||||
the [Adding Command Tutorial](Howto/StartingTutorial/Adding-Command-Tutorial) if you are unsure about how to do this.
|
the [Adding Command Tutorial](Adding-Command-Tutorial) if you are unsure about how to do this.
|
||||||
|
|
||||||
## Expanding the example
|
## Expanding the example
|
||||||
|
|
||||||
|
|
@ -9,8 +9,8 @@ explains Evennia's tools for searching.
|
||||||
## Things to search for
|
## Things to search for
|
||||||
|
|
||||||
The first thing to consider is the base type of the thing you are searching for. Evennia organizes
|
The first thing to consider is the base type of the thing you are searching for. Evennia organizes
|
||||||
its database into a few main tables: [Objects](Component/Objects), [Accounts](Component/Accounts), [Scripts](Component/Scripts),
|
its database into a few main tables: [Objects](../../Component/Objects), [Accounts](../../Component/Accounts), [Scripts](../../Component/Scripts),
|
||||||
[Channels](Component/Communications#channels), [Messages](Communication#Msg) and [Help Entries](Component/Help-System).
|
[Channels](../../Component/Communications#channels), [Messages](Communication#Msg) and [Help Entries](../../Component/Help-System).
|
||||||
Most of the time you'll likely spend your time searching for Objects and the occasional Accounts.
|
Most of the time you'll likely spend your time searching for Objects and the occasional Accounts.
|
||||||
|
|
||||||
So to find an entity, what can be searched for?
|
So to find an entity, what can be searched for?
|
||||||
|
|
@ -22,20 +22,20 @@ the database field for `.key` is instead named `username` (this is a Django requ
|
||||||
don't specify search-type, you'll usually search based on key. *Aliases* are extra names given to
|
don't specify search-type, you'll usually search based on key. *Aliases* are extra names given to
|
||||||
Objects using something like `@alias` or `obj.aliases.add('name')`. The main search functions (see
|
Objects using something like `@alias` or `obj.aliases.add('name')`. The main search functions (see
|
||||||
below) will automatically search for aliases whenever you search by-key.
|
below) will automatically search for aliases whenever you search by-key.
|
||||||
- [Tags](Component/Tags) are the main way to group and identify objects in Evennia. Tags can most often be
|
- [Tags](../../Component/Tags) are the main way to group and identify objects in Evennia. Tags can most often be
|
||||||
used (sometimes together with keys) to uniquely identify an object. For example, even though you
|
used (sometimes together with keys) to uniquely identify an object. For example, even though you
|
||||||
have two locations with the same name, you can separate them by their tagging (this is how Evennia
|
have two locations with the same name, you can separate them by their tagging (this is how Evennia
|
||||||
implements 'zones' seen in other systems). Tags can also have categories, to further organize your
|
implements 'zones' seen in other systems). Tags can also have categories, to further organize your
|
||||||
data for quick lookups.
|
data for quick lookups.
|
||||||
- An object's [Attributes](Component/Attributes) can also used to find an object. This can be very useful but
|
- An object's [Attributes](../../Component/Attributes) can also used to find an object. This can be very useful but
|
||||||
since Attributes can store almost any data they are far less optimized to search for than Tags or
|
since Attributes can store almost any data they are far less optimized to search for than Tags or
|
||||||
keys.
|
keys.
|
||||||
- The object's [Typeclass](Component/Typeclasses) indicate the sub-type of entity. A Character, Flower or
|
- The object's [Typeclass](../../Component/Typeclasses) indicate the sub-type of entity. A Character, Flower or
|
||||||
Sword are all types of Objects. A Bot is a kind of Account. The database field is called
|
Sword are all types of Objects. A Bot is a kind of Account. The database field is called
|
||||||
`typeclass_path` and holds the full Python-path to the class. You can usually specify the
|
`typeclass_path` and holds the full Python-path to the class. You can usually specify the
|
||||||
`typeclass` as an argument to Evennia's search functions as well as use the class directly to limit
|
`typeclass` as an argument to Evennia's search functions as well as use the class directly to limit
|
||||||
queries.
|
queries.
|
||||||
- The `location` is only relevant for [Objects](Component/Objects) but is a very common way to weed down the
|
- The `location` is only relevant for [Objects](../../Component/Objects) but is a very common way to weed down the
|
||||||
number of candidates before starting to search. The reason is that most in-game commands tend to
|
number of candidates before starting to search. The reason is that most in-game commands tend to
|
||||||
operate on things nearby (in the same room) so the choices can be limited from the start.
|
operate on things nearby (in the same room) so the choices can be limited from the start.
|
||||||
- The database id or the '#dbref' is unique (and never re-used) within each database table. So while
|
- The database id or the '#dbref' is unique (and never re-used) within each database table. So while
|
||||||
|
|
@ -50,7 +50,7 @@ around and searching by Tags and/or keys will usually get you what you need.
|
||||||
|
|
||||||
## Getting objects inside another
|
## Getting objects inside another
|
||||||
|
|
||||||
All in-game [Objects](Component/Objects) have a `.contents` property that returns all objects 'inside' them
|
All in-game [Objects](../../Component/Objects) have a `.contents` property that returns all objects 'inside' them
|
||||||
(that is, all objects which has its `.location` property set to that object. This is a simple way to
|
(that is, all objects which has its `.location` property set to that object. This is a simple way to
|
||||||
get everything in a room and is also faster since this lookup is cached and won't hit the database.
|
get everything in a room and is also faster since this lookup is cached and won't hit the database.
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ location except `obj`.
|
||||||
|
|
||||||
## Searching using `Object.search`
|
## Searching using `Object.search`
|
||||||
|
|
||||||
Say you have a [command](Component/Commands), and you want it to do something to a target. You might be
|
Say you have a [command](../../Component/Commands), and you want it to do something to a target. You might be
|
||||||
wondering how you retrieve that target in code, and that's where Evennia's search utilities come in.
|
wondering how you retrieve that target in code, and that's where Evennia's search utilities come in.
|
||||||
In the most common case, you'll often use the `search` method of the `Object` or `Account`
|
In the most common case, you'll often use the `search` method of the `Object` or `Account`
|
||||||
typeclasses. In a command, the `.caller` property will refer back to the object using the command
|
typeclasses. In a command, the `.caller` property will refer back to the object using the command
|
||||||
|
|
@ -133,7 +133,7 @@ class CmdListHangouts(default_cmds.MuxCommand):
|
||||||
", ".join(str(ob) for ob in hangouts)))
|
", ".join(str(ob) for ob in hangouts)))
|
||||||
```
|
```
|
||||||
|
|
||||||
This uses the `search_tag` function to find all objects previously tagged with [Tags](Component/Tags)
|
This uses the `search_tag` function to find all objects previously tagged with [Tags](../../Component/Tags)
|
||||||
"hangout" and with category "location tags".
|
"hangout" and with category "location tags".
|
||||||
|
|
||||||
Other important search methods in `utils.search` are
|
Other important search methods in `utils.search` are
|
||||||
|
|
@ -303,7 +303,7 @@ nice enough to alias the `db_key` field so you can normally just do `char.key` t
|
||||||
name, the database field is actually called `db_key` and the real name must be used for the purpose
|
name, the database field is actually called `db_key` and the real name must be used for the purpose
|
||||||
of building a query.
|
of building a query.
|
||||||
|
|
||||||
> Don't confuse database fields with [Attributes](Component/Attributes) you set via `obj.db.attr = 'foo'` or
|
> Don't confuse database fields with [Attributes](../../Component/Attributes) you set via `obj.db.attr = 'foo'` or
|
||||||
`obj.attributes.add()`. Attributes are custom database entities *linked* to an object. They are not
|
`obj.attributes.add()`. Attributes are custom database entities *linked* to an object. They are not
|
||||||
separate fields *on* that object like `db_key` or `db_location` are. You can get attached Attributes
|
separate fields *on* that object like `db_key` or `db_location` are. You can get attached Attributes
|
||||||
manually through the `db_attributes` many-to-many field in the same way as `db_tags` above.
|
manually through the `db_attributes` many-to-many field in the same way as `db_tags` above.
|
||||||
|
|
@ -7,7 +7,7 @@ focused on free form storytelling. Even if you are not interested in MUSH:es, th
|
||||||
first game-type to try since it's not so code heavy. You will be able to use the same principles for
|
first game-type to try since it's not so code heavy. You will be able to use the same principles for
|
||||||
building other types of games.
|
building other types of games.
|
||||||
|
|
||||||
The tutorial starts from scratch. If you did the [First Steps Coding](Howto/StartingTutorial/First-Steps-Coding) tutorial
|
The tutorial starts from scratch. If you did the [First Steps Coding](First-Steps-Coding) tutorial
|
||||||
already you should have some ideas about how to do some of the steps already.
|
already you should have some ideas about how to do some of the steps already.
|
||||||
|
|
||||||
The following are the (very simplistic and cut-down) features we will implement (this was taken from
|
The following are the (very simplistic and cut-down) features we will implement (this was taken from
|
||||||
|
|
@ -61,7 +61,7 @@ class Character(DefaultCharacter):
|
||||||
self.db.combat_score = 1
|
self.db.combat_score = 1
|
||||||
```
|
```
|
||||||
|
|
||||||
We defined two new [Attributes](Component/Attributes) `power` and `combat_score` and set them to default
|
We defined two new [Attributes](../../Component/Attributes) `power` and `combat_score` and set them to default
|
||||||
values. Make sure to `@reload` the server if you had it already running (you need to reload every
|
values. Make sure to `@reload` the server if you had it already running (you need to reload every
|
||||||
time you update your python code, don't worry, no accounts will be disconnected by the reload).
|
time you update your python code, don't worry, no accounts will be disconnected by the reload).
|
||||||
|
|
||||||
|
|
@ -94,8 +94,8 @@ check it. Using this method however will make it easy to add more functionality
|
||||||
|
|
||||||
What we need are the following:
|
What we need are the following:
|
||||||
|
|
||||||
- One character generation [Command](Component/Commands) to set the "Power" on the `Character`.
|
- One character generation [Command](../../Component/Commands) to set the "Power" on the `Character`.
|
||||||
- A chargen [CmdSet](Component/Command-Sets) to hold this command. Lets call it `ChargenCmdset`.
|
- A chargen [CmdSet](../../Component/Command-Sets) to hold this command. Lets call it `ChargenCmdset`.
|
||||||
- A custom `ChargenRoom` type that makes this set of commands available to players in such rooms.
|
- A custom `ChargenRoom` type that makes this set of commands available to players in such rooms.
|
||||||
- One such room to test things in.
|
- One such room to test things in.
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ What we need are the following:
|
||||||
For this tutorial we will add all our new commands to `mygame/commands/command.py` but you could
|
For this tutorial we will add all our new commands to `mygame/commands/command.py` but you could
|
||||||
split your commands into multiple module if you prefered.
|
split your commands into multiple module if you prefered.
|
||||||
|
|
||||||
For this tutorial character generation will only consist of one [Command](Component/Commands) to set the
|
For this tutorial character generation will only consist of one [Command](../../Component/Commands) to set the
|
||||||
Character s "power" stat. It will be called on the following MUSH-like form:
|
Character s "power" stat. It will be called on the following MUSH-like form:
|
||||||
|
|
||||||
+setpower 4
|
+setpower 4
|
||||||
|
|
@ -156,7 +156,7 @@ This is a pretty straightforward command. We do some error checking, then set th
|
||||||
We use a `help_category` of "mush" for all our commands, just so they are easy to find and separate
|
We use a `help_category` of "mush" for all our commands, just so they are easy to find and separate
|
||||||
in the help list.
|
in the help list.
|
||||||
|
|
||||||
Save the file. We will now add it to a new [CmdSet](Component/Command-Sets) so it can be accessed (in a full
|
Save the file. We will now add it to a new [CmdSet](../../Component/Command-Sets) so it can be accessed (in a full
|
||||||
chargen system you would of course have more than one command here).
|
chargen system you would of course have more than one command here).
|
||||||
|
|
||||||
Open `mygame/commands/default_cmdsets.py` and import your `command.py` module at the top. We also
|
Open `mygame/commands/default_cmdsets.py` and import your `command.py` module at the top. We also
|
||||||
|
|
@ -210,7 +210,7 @@ class ChargenRoom(Room):
|
||||||
```
|
```
|
||||||
Note how new rooms created with this typeclass will always start with `ChargenCmdset` on themselves.
|
Note how new rooms created with this typeclass will always start with `ChargenCmdset` on themselves.
|
||||||
Don't forget the `permanent=True` keyword or you will lose the cmdset after a server reload. For
|
Don't forget the `permanent=True` keyword or you will lose the cmdset after a server reload. For
|
||||||
more information about [Command Sets](Component/Command-Sets) and [Commands](Component/Commands), see the respective
|
more information about [Command Sets](../../Component/Command-Sets) and [Commands](../../Component/Commands), see the respective
|
||||||
links.
|
links.
|
||||||
|
|
||||||
### Testing chargen
|
### Testing chargen
|
||||||
|
|
@ -242,7 +242,7 @@ between fixes. Don't continue until the creation seems to have worked okay.
|
||||||
This should bring you to the chargen room. Being in there you should now have the `+setpower`
|
This should bring you to the chargen room. Being in there you should now have the `+setpower`
|
||||||
command available, so test it out. When you leave (via the `finish` exit), the command will go away
|
command available, so test it out. When you leave (via the `finish` exit), the command will go away
|
||||||
and trying `+setpower` should now give you a command-not-found error. Use `ex me` (as a privileged
|
and trying `+setpower` should now give you a command-not-found error. Use `ex me` (as a privileged
|
||||||
user) to check so the `Power` [Attribute](Component/Attributes) has been set correctly.
|
user) to check so the `Power` [Attribute](../../Component/Attributes) has been set correctly.
|
||||||
|
|
||||||
If things are not working, make sure your typeclasses and commands are free of bugs and that you
|
If things are not working, make sure your typeclasses and commands are free of bugs and that you
|
||||||
have entered the paths to the various command sets and commands correctly. Check the logs or command
|
have entered the paths to the various command sets and commands correctly. Check the logs or command
|
||||||
|
|
@ -391,7 +391,7 @@ There are a few ways to define the NPC class. We could in theory create a custom
|
||||||
and put a custom NPC-specific cmdset on all NPCs. This cmdset could hold all manipulation commands.
|
and put a custom NPC-specific cmdset on all NPCs. This cmdset could hold all manipulation commands.
|
||||||
Since we expect NPC manipulation to be a common occurrence among the user base however, we will
|
Since we expect NPC manipulation to be a common occurrence among the user base however, we will
|
||||||
instead put all relevant NPC commands in the default command set and limit eventual access with
|
instead put all relevant NPC commands in the default command set and limit eventual access with
|
||||||
[Permissions and Locks](Component/Locks#Permissions).
|
[Permissions and Locks](../../Component/Locks#Permissions).
|
||||||
|
|
||||||
### Creating an NPC with +createNPC
|
### Creating an NPC with +createNPC
|
||||||
|
|
||||||
|
|
@ -443,13 +443,13 @@ class CmdCreateNPC(Command):
|
||||||
exclude=caller)
|
exclude=caller)
|
||||||
```
|
```
|
||||||
Here we define a `+createnpc` (`+createNPC` works too) that is callable by everyone *not* having the
|
Here we define a `+createnpc` (`+createNPC` works too) that is callable by everyone *not* having the
|
||||||
`nonpcs` "[permission](Component/Locks#Permissions)" (in Evennia, a "permission" can just as well be used to
|
`nonpcs` "[permission](../../Component/Locks#Permissions)" (in Evennia, a "permission" can just as well be used to
|
||||||
block access, it depends on the lock we define). We create the NPC object in the caller's current
|
block access, it depends on the lock we define). We create the NPC object in the caller's current
|
||||||
location, using our custom `Character` typeclass to do so.
|
location, using our custom `Character` typeclass to do so.
|
||||||
|
|
||||||
We set an extra lock condition on the NPC, which we will use to check who may edit the NPC later --
|
We set an extra lock condition on the NPC, which we will use to check who may edit the NPC later --
|
||||||
we allow the creator to do so, and anyone with the Builders permission (or higher). See
|
we allow the creator to do so, and anyone with the Builders permission (or higher). See
|
||||||
[Locks](Component/Locks) for more information about the lock system.
|
[Locks](../../Component/Locks) for more information about the lock system.
|
||||||
|
|
||||||
Note that we just give the object default permissions (by not specifying the `permissions` keyword
|
Note that we just give the object default permissions (by not specifying the `permissions` keyword
|
||||||
to the `create_object()` call). In some games one might want to give the NPC the same permissions
|
to the `create_object()` call). In some games one might want to give the NPC the same permissions
|
||||||
|
|
@ -464,7 +464,7 @@ Since we re-used our custom character typeclass, our new NPC already has a *Powe
|
||||||
defaults to 1. How do we change this?
|
defaults to 1. How do we change this?
|
||||||
|
|
||||||
There are a few ways we can do this. The easiest is to remember that the `power` attribute is just a
|
There are a few ways we can do this. The easiest is to remember that the `power` attribute is just a
|
||||||
simple [Attribute](Component/Attributes) stored on the NPC object. So as a Builder or Admin we could set this
|
simple [Attribute](../../Component/Attributes) stored on the NPC object. So as a Builder or Admin we could set this
|
||||||
right away with the default `@set` command:
|
right away with the default `@set` command:
|
||||||
|
|
||||||
@set mynpc/power = 6
|
@set mynpc/power = 6
|
||||||
|
|
@ -649,6 +649,6 @@ The simple "Power" game mechanic should be easily expandable to something more f
|
||||||
useful, same is true for the combat score principle. The `+attack` could be made to target a
|
useful, same is true for the combat score principle. The `+attack` could be made to target a
|
||||||
specific player (or npc) and automatically compare their relevant attributes to determine a result.
|
specific player (or npc) and automatically compare their relevant attributes to determine a result.
|
||||||
|
|
||||||
To continue from here, you can take a look at the [Tutorial World](Contrib/Tutorial-World-Introduction). For
|
To continue from here, you can take a look at the [Tutorial World](../../Contrib/Tutorial-World-Introduction). For
|
||||||
more specific ideas, see the [other tutorials and hints](Tutorials) as well
|
more specific ideas, see the [other tutorials and hints](Tutorials) as well
|
||||||
as the [Developer Central](Developer-Central).
|
as the [Developer Central](Developer-Central).
|
||||||
7
docs/source/api/modules.rst
Normal file
7
docs/source/api/modules.rst
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
evennia
|
||||||
|
=======
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 4
|
||||||
|
|
||||||
|
evennia
|
||||||
0
docs/source/evennia-api.md.py
Normal file
0
docs/source/evennia-api.md.py
Normal file
|
|
@ -40,7 +40,7 @@ from evennia.utils.optionhandler import OptionHandler
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from random import getrandbits
|
from random import getrandbits
|
||||||
|
|
||||||
__all__ = ("DefaultAccount",)
|
__all__ = ("DefaultAccount", "DefaultGuest")
|
||||||
|
|
||||||
_SESSIONS = None
|
_SESSIONS = None
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue