mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Fix pages
This commit is contained in:
parent
c4dc554179
commit
cfd70ea837
8 changed files with 305 additions and 219 deletions
111
docs/source/Howto/Starting/Directory-Overview.md
Normal file
111
docs/source/Howto/Starting/Directory-Overview.md
Normal 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]()
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue