Fix pages

This commit is contained in:
Griatch 2020-06-20 22:40:47 +02:00
parent c4dc554179
commit cfd70ea837
8 changed files with 305 additions and 219 deletions

View file

@ -0,0 +1,111 @@
# Overview of your new Game Dir
[prev lesson](Tutorial-World-Introduction) | [next lesson]()
Now we have 'run the game' a bit and looked at what can be done in-game. It is time to start to look
at how things look 'outside of the game'. Let's do a tour of the game-dir you just created. Like
everywhere in the docs we'll assume it's called `mygame`.
You may have noticed when we were building things in-game that we would often refer to code through
"python paths", such as
```sidebar:: Python-paths
A 'python path' uses '.' instead of '/' or '`\\`' and
skips the `.py` ending of files. It can also point to
the code contents of python files. Since Evennia is already
looking for code in your game dir, your python paths can start
from there.
So a path `/home/foo/devel/mygame/commands/command.py`
would translate to a Python-path `commands.command`.
```
create/drop button:tutorial_examples.red_button.RedButton
This is a fundamental aspect of coding Evennia - _you create code and then you tell Evennia where that
code is and when it should be used_. Above we told it to create a red button by pulling from specific code
in the `contribs/` folder but the same principle is true everywhere. So it's important to know where code is
and how you point to it correctly.
- `mygame/`
- `commands/` - This holds all your custom commands (user-input handlers). You both add your own
and override Evennia's defaults from here.
- `server`/ - The structure of this folder should not change since Evennia expects it.
- `conf/` - All server configuration files sits here. The most important file is `settings.py`.
- `logs/` - Server log files are stored here. When you use `evennia --log` you are actually
tailing the files in this directory.
- `typeclasses/` - this holds empty templates describing all database-bound entities in the
game, like Characters, Scripts, Accounts etc. Adding code here allows to customize and extend
the defaults.
- `web/` - This is where you override and extend the default templates, views and static files used
for Evennia's web-presence, like the website and the HTML5 webclient.
- `world/` - this is a "miscellaneous" folder holding everything related to the world you are
building, such as build scripts and rules modules that don't fit with one of the other folders.
> The `server/` subfolder should remain the way it is - Evennia expects this. But you could in
> principle change the structure of the rest of your game dir as best fits your preference.
> Maybe you don't need a world/ folder but prefer many folders with different aspects of your world?
> Or a new folder 'rules' for your RPG rules? This is fine. If you move things around you just need
> to update Evennia's default settings to point to the right places in the new structure.
## commands/
The `commands/` folder holds Python _modules_ related to creating and extending the [Commands](../../Component/Commands)
of Evennia. These manifest in game like the server understanding input like `look` or `dig`.
```sidebar:: Python modules
A `module` is the common term for a file ending with the `.py` file ending. A module
is a text file containing Python source code.
```
## Evennia library layout:
If you cloned the GIT repo following the instructions, you will have a folder named `evennia`. The
top level of it contains Python package specific stuff such as a readme file, `setup.py` etc. It
also has two subfolders`bin/` and `evennia/` (again).
The `bin/` directory holds OS-specific binaries that will be used when installing Evennia with `pip`
as per the [Getting started](../Setup/Getting-Started) instructions. The library itself is in the `evennia`
subfolder. From your code you will access this subfolder simply by `import evennia`.
- evennia
- [`__init__.py`](Evennia-API) - The "flat API" of Evennia resides here.
- [`commands/`](Commands) - The command parser and handler.
- `default/` - The [default commands](../../Component/Default-Command-Help) and cmdsets.
- [`comms/`](Communications) - Systems for communicating in-game.
- `contrib/` - Optional plugins too game-specific for core Evennia.
- `game_template/` - Copied to become the "game directory" when using `evennia --init`.
- [`help/`](Help-System) - Handles the storage and creation of help entries.
- `locale/` - Language files ([i18n](../../Concept/Internationalization)).
- [`locks/`](Locks) - Lock system for restricting access to in-game entities.
- [`objects/`](Objects) - In-game entities (all types of items and Characters).
- [`prototypes/`](Spawner-and-Prototypes) - Object Prototype/spawning system and OLC menu
- [`accounts/`](Accounts) - Out-of-game Session-controlled entities (accounts, bots etc)
- [`scripts/`](Scripts) - Out-of-game entities equivalence to Objects, also with timer support.
- [`server/`](Portal-And-Server) - Core server code and Session handling.
- `portal/` - Portal proxy and connection protocols.
- [`settings_default.py`](Server-Conf#Settings-file) - Root settings of Evennia. Copy settings
from here to `mygame/server/settings.py` file.
- [`typeclasses/`](Typeclasses) - Abstract classes for the typeclass storage and database system.
- [`utils/`](Coding-Utils) - Various miscellaneous useful coding resources.
- [`web/`](Web-Features) - Web resources and webserver. Partly copied into game directory on
initialization.
All directories contain files ending in `.py`. These are Python *modules* and are the basic units of
Python code. The roots of directories also have (usually empty) files named `__init__.py`. These are
required by Python so as to be able to find and import modules in other directories. When you have
run Evennia at least once you will find that there will also be `.pyc` files appearing, these are
pre-compiled binary versions of the `.py` files to speed up execution.
The root of the `evennia` folder has an `__init__.py` file containing the "[flat API](../../Evennia-API)".
This holds shortcuts to various subfolders in the evennia library. It is provided to make it easier
to find things; it allows you to just import `evennia` and access things from that rather than
having to import from their actual locations inside the source tree.
[prev lesson](Tutorial-World-Introduction) | [next lesson]()

View file

@ -1,76 +1,91 @@
# Python basic introduction
# Starting to code Evennia
This is the first part of our beginner's guide to the basics of using Python with Evennia. It's
aimed at you with limited or no programming/Python experience. But also if you are an experienced
programmer new to Evennia or Python you might still pick up a thing or two. It is by necessity brief
and low on detail. There are countless Python guides and tutorials, books and videos out there for
learning more in-depth - use them!
[prev lesson](Tutorial-World-Introduction) | [next lesson](Directory-Overview)
**Contents:**
- [Evennia Hello world](Python-basic-introduction#evennia-hello-world)
- [Importing modules](Python-basic-introduction#importing-modules)
- [Parsing Python errors](Python-basic-introduction#parsing-python-errors)
- [Our first function](Python-basic-introduction#our-first-function)
- [Looking at the log](Python-basic-introduction#looking-at-the-log)
- (continued in [part 2](Python-basic-tutorial-part-two))
Time to dip our toe into some coding! Evennia is written and extended in [Python](http://python.org), which
is a mature and professional programming language that is very fast to work with.
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
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).
That said, even though Python is widely considered easy to learn, we can only cover the most immediately
important aspects of Python in this series of starting tutorials. Hopefully we can get you started
but then you'll need to continue learning from there. See our [link section](../../Links) for finding
more reference material and dedicated Python tutorials.
> While this will be quite basic if you are an experienced developer, you may want to at least
> stay around for the first few sections where we cover how to run Python from inside Evennia.
First, if you were quelling yourself to play the tutorial world, make sure to get your
superuser powers back:
unquell
Below, lines starting with a single `>` means command input.
### Evennia Hello world
The `py` (or `!` which is an alias) command allows you as a superuser to run raw Python from in-
game. From the game's input line, enter the following:
The `py` Command (or `!`, which is an alias) allows you as a superuser to execute raw Python from in-
game. This is useful for quick testing. From the game's input line, enter the following:
> py print("Hello World!")
```sidebar:: Command input
The lines with a `>` indicate input to enter in-game, while the lines below are the
expected return from that input.
```
You will see
> print("Hello world!")
Hello World
Hello World!
To understand what is going on: some extra info: The `print(...)` *function* is the basic, in-built
way to output text in Python. The quotes `"..."` means you are inputing a *string* (i.e. text). You
could also have used single-quotes `'...'`, Python accepts both.
way to output text in Python. We are sending "Hello World" as an _argument_ to this function. The quotes `"..."`
mean that you are inputting a *string* (i.e. text). You could also have used single-quotes `'...'`,
Python accepts both.
The first return line (with `>>>`) is just `py` echoing what you input (we won't include that in the
examples henceforth).
> Note: You may sometimes see people/docs refer to `@py` or other commands starting with `@`.
Evennia ignores `@` by default, so `@py` is the exact same thing as `py`.
The `print` command is a standard Python structure. We can use that here in the `py` command, and
it's great for debugging and quick testing. But if you need to send a text to an actual player,
`print` won't do, because it doesn't know _who_ to send to. Try this:
The `print` command is a standard Python structure. We can use that here in the `py` command since
we can se the output. It's great for debugging and quick testing. But if you need to send a text
to an actual player, `print` won't do, because it doesn't know _who_ to send to. Try this:
> py me.msg("Hello world!")
Hello world!
This looks the same as the `print` result, but we are now actually messaging a specific *object*,
`me`. The `me` is something uniquely available in the `py` command (we could also use `self`, it's
an alias). It represents "us", the ones calling the `py` command. The `me` is an example of an
*Object instance*. Objects are fundamental in Python and Evennia. The `me` object not only
represents the character we play in the game, it also contains a lot of useful resources for doing
things with that Object. One such resource is `msg`. `msg` works like `print` except it sends the
text to the object it is attached to. So if we, for example, had an object `you`, doing
`you.msg(...)` would send a message to the object `you`.
`me`. The `me` is a shortcut to 'us', the one running the `py` command. It is not some special
Python thing, but something Evennia just makes available in the `py` command for convenience
(`self` is an alias).
You access an Object's resources by using the full-stop character `.`. So `self.msg` accesses the
`msg` resource and then we call it like we did print, with our "Hello World!" greeting in
parentheses.
The `me` is an example of an *Object instance*. Objects are fundamental in Python and Evennia.
The `me` object also contains a lot of useful resources for doing
things with that object. We access those resources with '`.`'.
> Important: something like `print(...)` we refer to as a *function*, while `msg(...)` which sits on
an object is called a *method*.
One such resource is `msg`, which works like `print` except it sends the text to the object it
is attached to. So if we, for example, had an object `you`, doing `you.msg(...)` would send a message
to the object `you`.
For now, `print` and `me.msg` behaves the same, just remember that you're going to mostly be using
the latter in the future. Try printing other things. Also try to include `|r` at the start of your
string to make the output red in-game. Use `color` to learn more color tags.
```sidebar:: Functions and Methods
### Importing modules
Function:
Stand-alone in a python module, like `print()`
Method:
Something that sits "on" an object, like `.msg()`
```
For now, `print` and `me.msg` behaves the same, just remember that `print` is mainly used for
debugging and `.msg()` will be more useful for you in the future.
For fun, try printing other things. Also try this:
> py self.msg("|rThis is red text!")
Adding that `|r` at the start will turn our output red. Enter the command `color ansi` or `color xterm`
to see which colors are available.
### Importing code from other modules
As we saw in the previous section, we could use `me.msg` to access the `msg` method on `me`. This
use of the full-stop character is used to access all sorts of resources, including that in other
Python modules. If you've been following along, this is what we've referred to as the "Python path".
Keep your game running, then open a text editor of your choice. If your game folder is called
`mygame`, create a new text file `test.py` in the subfolder `mygame/world`. This is how the file
@ -88,22 +103,29 @@ For now, only add one line to `test.py`:
print("Hello World!")
```
Don't forget to save the file. A file with the ending `.py` is referred to as a Python *module*. To
use this in-game we have to *import* it. Try this:
```sidebar:: Python module
This is a text file with the `.py` file ending. A module
contains Python source code and from within Python one can
access its contents by importing it via its python-path.
```python
> @py import world.test
Hello World
```
If you make some error (we'll cover how to handle errors below) you may need to run the `@reload`
command for your changes to take effect.
Don't forget to _save_ the file. We just created our first Python _module_!
To use this in-game we have to *import* it. Try this:
> py import world.test
Hello World
If you make some error (we'll cover how to handle errors below), fix the error in the module and
run the `reload` command in-game for your changes to take effect.
So importing `world.test` actually means importing `world/test.py`. Think of the period `.` as
replacing `/` (or `\` for Windows) in your path. The `.py` ending of `test.py` is also never
included in this "Python-path", but _only_ files with that ending can be imported this way. Where is
`mygame` in that Python-path? The answer is that Evennia has already told Python that your `mygame`
folder is a good place to look for imports. So we don't include `mygame` in the path - Evennia
handles this for us.
included in this "Python-path", but _only_ files with that ending can be imported this way.
Where is `mygame` in that Python-path? The answer is that Evennia has already told Python that
your `mygame` folder is a good place to look for imports. So we don't include `mygame` in the
path - Evennia handles this for us.
When you import the module, the top "level" of it will execute. In this case, it will immediately
print "Hello World".
@ -114,32 +136,46 @@ those anyway.
Now try to run this a second time:
```python
> py import world.test
```
> py import world.test
You will *not* see any output this second time or any subsequent times! This is not a bug. Rather
it is because Python is being clever - it stores all imported modules and to be efficient it will
avoid importing them more than once. So your `print` will only run the first time, when the module
is first imported. To see it again you need to `@reload` first, so Python forgets about the module
and has to import it again.
is first imported.
We'll get back to importing code in the second part of this tutorial. For now, let's press on.
Try this:
> reload
And then
> py import world.test
Hello World!
Now we see it again. The `reload` wiped the server's memory of what was imported, so it had to
import it anew. You'd have to do this every time you wanted the print to show though, which is
not very useful.
> We'll get back to more advanced ways to import code in later tutorial sections - this is an
> important topic. But for now, let's press on and resolve this particular problem.
### Parsing Python errors
Next, erase the single `print` statement you had in `test.py` and replace it with this instead:
Running print only on import is not too helpful. We want to print whenever we like to!
Go back to your `test.py` file and erase the single `print` statement you had. Replace
it with this instead:
```python
me.msg("Hello World!")
```
As you recall we used this from `py` earlier - it echoed "Hello World!" in-game.
Save your file and `reload` your server - this makes sure Evennia sees the new version of your code.
Try to import it from `py` in the same way as earlier:
As you recall we used this with `py` earlier - it echoed "Hello World!" in-game.
Save your file and `reload` your server - this makes sure Evennia knows to re-import
it (with our new, fresh code this time).
```python
> py import world.test
```
To test it, import it using `py` as before
> py import world.test
No go - this time you get an error!
@ -149,33 +185,43 @@ File "./world/test.py", line 1, in <module>
NameError: name 'me' is not defined
```
This is called a *traceback*. Python's errors are very friendly and will most of the time tell you
exactly what and where things are wrong. It's important that you learn to parse tracebacks so you
can fix your code. Let's look at this one. A traceback is to be read from the _bottom up_. The last
line is the error Python balked at, while the two lines above it details exactly where that error
was encountered.
```sidebar:: Errors in the logs
1. An error of type `NameError` is the problem ...
2. ... more specifically it is due to the variable `me` not being defined.
3. This happened on the line `me.msg("Hello world!")` ...
4. ... which is on line `1` of the file `./world/test.py`.
In regular use, tracebacks will often appear in the log rather than
in the game. Use `evennia --log` to view the log in the terminal. Make
sure to scroll back if you expect an error and don't see it. Use
`Ctrl-C` (or `Cmd-C` on Mac) to exit the log-view.
```
This is called a *traceback*. Python's errors are very friendly and will most of the time tell you
exactly what and where things go wrong. It's important that you learn to parse tracebacks so you
know how to fix your code.
A traceback is to be read from the _bottom up_:
- (line 3) An error of type `NameError` is the problem ...
- (line 3) ... more specifically it is due to the variable `me` not being defined.
- (line 2) This happened on the line `me.msg("Hello world!")` ...
- (line 1) ... which is on line `1` of the file `./world/test.py`.
In our case the traceback is short. There may be many more lines above it, tracking just how
different modules called each other until it got to the faulty line. That can sometimes be useful
information, but reading from the bottom is always a good start.
different modules called each other until the program got to the faulty line. That can
sometimes be useful information, but reading from the bottom is always a good start.
The `NameError` we see here is due to a module being its own isolated thing. It knows nothing about
the environment into which it is imported. It knew what `print` is because that is a special
[reserved Python keyword](https://docs.python.org/2.5/ref/keywords.html). But `me` is *not* such a
reserved word. As far as the module is concerned `me` is just there out of nowhere. Hence the
`NameError`.
reserved word (as mentioned, it's just something Evennia came up with for convenience in the `py`
command). As far as the module is concerned `me` is an unfamiliar name, appearing out of nowhere.
Hence the `NameError`.
### Our first function
### Our first own function
Let's see if we can resolve that `NameError` from the previous section. We know that `me` is defined
at the time we use the `@py` command because if we do `py me.msg("Hello World!")` directly in-game
it works fine. What if we could *send* that `me` to the `test.py` module so it knows what it is? One
way to do this is with a *function*.
at the time we use the `py` command. We know this because if we do `py me.msg("Hello World!")`
directly in-game it works fine. What if we could *send* that `me` to the `test.py` module so it
knows what it is? One way to do this is with a *function*.
Change your `mygame/world/test.py` file to look like this:
@ -184,84 +230,78 @@ def hello_world(who):
who.msg("Hello World!")
```
Now that we are moving onto multi-line Python code, there are some important things to remember:
As we are moving to multi-line Python code, there are some important things to remember:
- Capitalization matters in Python. It must be `def` and not `DEF`, `who` is not the same as `Who`
etc.
- Capitalization matters in Python. It must be `def` and not `DEF`, `who` is not the same as `Who`.
- Indentation matters in Python. The second line must be indented or it's not valid code. You should
also use a consistent indentation length. We *strongly* recommend that you set up your editor to
always indent *4 spaces* (**not** a single tab-character) when you press the TAB key - it will make
your life a lot easier.
also use a consistent indentation length. We *strongly* recommend that you, for your own sanity's sake,
set up your editor to always indent *4 spaces* (**not** a single tab-character) when you press the TAB key.
So about that function. Line 1:
- `def` is short for "define" and defines a *function* (or a *method*, if sitting on an object).
This is a [reserved Python keyword](https://docs.python.org/2.5/ref/keywords.html); try not to use
these words anywhere else.
- A function name can not have spaces but otherwise we could have called it almost anything. We call
it `hello_world`. Evennia follows [Python's standard naming
style](https://github.com/evennia/evennia/blob/master/CODING_STYLE.md#a-quick-list-of-code-style-
points) with lowercase letters and underscores. Use this style for now.
- `who` is what we call the *argument* to our function. Arguments are variables we pass to the
it `hello_world`. Evennia follows [Python's standard naming style](https://github.com/evennia/evennia/blob/master/CODING_STYLE.md#a-quick-list-of-code-style-points)
with lowercase letters and underscores. We recommend you do the same.
- `who` is what we call the *argument* to our function. Arguments are variables _passed_ to the
function. We could have named it anything and we could also have multiple arguments separated by
commas. What `who` is depends on what we pass to this function when we *call* it later (hint: we'll
pass `me` to it).
- The colon (`:`) at the end of the first line indicates that the header of the function is
complete.
- The indentation marks the beginning of the actual operating code of the function (the function's
*body*). If we wanted more lines to belong to this function those lines would all have to have to
start at this indentation level.
- In the function body we take the `who` argument and treat it as we would have treated `me` earlier
- we expect it to have a `.msg` method we can use to send "Hello World" to.
- The colon (`:`) at the end of line 1 indicates that the header of the function is complete.
First, `reload` your game to make it aware of the updated Python module. Now we have defined our
first function, let's use it.
Line 2:
- The indentation marks the beginning of the actual operating code of the function (the function's
*body*). If we wanted more lines to belong to this function those lines would all have to
start at least at this indentation level.
- In the function body we take the `who` argument and treat it as we would have treated `me`
earlier- we expect it to have a `.msg` method we can use to send "Hello World" to.
Now let's try this out. First `reload` your game to have it pick up
our updated Python module when we reload.
> reload
> py import world.test
Nothing happened! That is because the function in our module won't do anything just by importing it.
It will only act when we *call* it. We will need to enter the module we just imported and do so.
It will only act when we *call* it. So we need to first import the module and then access the
function within:
> py import world.test ; world.test.hello_world(me)
Hello world!
There is our "Hello World"! The `;` is the way to put multiple Python-statements on one line.
There is our "Hello World"! Using `;` is the way to put multiple Python-statements on one line.
> Some MUD clients use `;` for their own purposes to separate client-inputs. If so you'll get a
`NameError` stating that `world` is not defined. Check so you understand why this is! Change the use
of `;` in your client or use the Evennia web client if this is a problem.
In the second statement we access the module path we imported (`world.test`) and reach for the
`hello_world` function within. We *call* the function with `me`, which becomes the `who` variable we
use inside the `hello_function`.
> As an exercise, try to pass something else into `hello_world`. Try for example to pass _who_ as
the number `5` or the simple string `"foo"`. You'll get errors that they don't have the attribute
`msg`. As we've seen, `me` *does* make `msg` available which is why it works (you'll learn more
about Objects like `me` in the next part of this tutorial). If you are familiar with other
programming languages you may be tempted to start *validating* `who` to make sure it works as
expected. This is usually not recommended in Python which suggests it's better to
[handle](https://docs.python.org/2/tutorial/errors.html) the error if it happens rather than to make
a lot of code to prevent it from happening. See also [duck
typing](https://en.wikipedia.org/wiki/Duck_typing).
# Looking at the log
As you start to explore Evennia, it's important that you know where to look when things go wrong.
While using the friendly `py` command you'll see errors directly in-game. But if something goes
wrong in your code while the game runs, you must know where to find the _log_.
Open a terminal (or go back to the terminal you started Evennia in), make sure your `virtualenv` is
active and that you are standing in your game directory (the one created with `evennia --init`
during installation). Enter
```warning:: MUD clients and semi-colon
A common issue is that some MUD clients use the semi-colon `;` for their own purposes,
namely to separate client-inputs. If so, you'll get a `NameError` above, stating that
`world` is not defined. Check so you understand why this is! Most clients allow you to
remap to use some other separator than `;`. You can use the Evennia web client if this
is problem remains.
```
evennia --log
```
(or `evennia -l`)
This will show the log. New entries will show up in real time. Whenever you want to leave the log,
enter `Ctrl-C` or `Cmd-C` depending on your system. As a game dev it is important to look at the
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.
So what happened there? First we imported `world.test` as usual. But this time we continued and
accessed the `hello_world` function _inside_ the newly imported module.
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.
We *call* the function with `me`, which becomes the `who` variable we use inside
the `hello_function` (they are be the same object). And since `me.msg` works, so does `who.msg`
inside the function.
> **Extra Credit:** As an exercise, try to pass something else into `hello_world`. Try for example
>to pass the number `5` or the string `"foo"`. You'll get errors telling you that they don't have
>the attribute `msg`. They don't care about `me` itself not being a string or a number. If you are
>familiar with other programming languages (especially C/Java) you may be tempted to start *validating*
>`who` to make sure it's of the right type before you send it. This is usually not recommended in Python.
>Python philosophy is to [handle](https://docs.python.org/2/tutorial/errors.html) the error if it happens
>rather than to add a lot of code to prevent it from happening. See [duck typing](https://en.wikipedia.org/wiki/Duck_typing)
>and the concept of _Leap before you Look_.
This gives you some initial feeling for how to run Python and import Python modules. We also
tried to put a module in `module/world/`. Now let's look at the rest of the stuff you've got
inside that `mygame/` folder ...
[prev lesson](Tutorial-World-Introduction) | [next lesson](Directory-Overview)

View file

@ -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
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
library [is covered by our directory overview](../../Coding/Directory-Overview#evennia-library-layout). You can
library [is covered by our directory overview](Directory-Overview#evennia-library-layout). You can
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.

View file

@ -44,6 +44,9 @@ from in-game, but you _will_ need to use the command-line to get anywhere. Here
- [Django-girls' Intro to the Command line for different OS:es](https://tutorial.djangogirls.org/en/intro_to_command_line/)
> Note that we only use forward-slashes `/` to show file system paths in this documentation. Windows users need
> to convert this to back-slashes `\` in their heads.
### A MUD client
You might already have a MUD-client you prefer. Check out the [grid of supported clients](../../Setup/Client-Support-Grid) for aid.

View file

@ -1,6 +1,6 @@
# The Tutorial World
[prev lesson](Building-Quickstart) | [next lesson]()
[prev lesson](Building-Quickstart) | [next lesson](Python-basic-introduction)
The *Tutorial World* is a small and functioning MUD-style game world shipped with Evennia.
It's a small showcase of what is possible. It can also be useful for those who have an easier
@ -115,5 +115,5 @@ should hopefully have given you a little taste of some of the possibilities of
move on with how to access this power through code.
[prev lesson](Building-Quickstart) | [next lesson]()
[prev lesson](Building-Quickstart) | [next lesson](Python-basic-introduction)