mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 14:07:16 +02:00
Updated HTML docs
This commit is contained in:
parent
66d0ad0bc9
commit
7900aad365
2073 changed files with 32986 additions and 41197 deletions
|
|
@ -1,45 +1,45 @@
|
|||
# Accounts
|
||||
|
||||
|
||||
All *users* (real people) that starts a game [Session](./Sessions) on Evennia are doing so through an
|
||||
All *users* (real people) that starts a game [Session](./Sessions.md) on Evennia are doing so through an
|
||||
object called *Account*. The Account object has no in-game representation, it represents a unique
|
||||
game account. In order to actually get on the game the Account must *puppet* an [Object](./Objects)
|
||||
(normally a [Character](./Objects#Character)).
|
||||
game account. In order to actually get on the game the Account must *puppet* an [Object](./Objects.md)
|
||||
(normally a [Character](./Objects.md#characters)).
|
||||
|
||||
Exactly how many Sessions can interact with an Account and its Puppets at once is determined by
|
||||
Evennia's [MULTISESSION_MODE](./Sessions#Multisession-mode) setting.
|
||||
Evennia's [MULTISESSION_MODE](./Sessions.md#multisession-mode) setting.
|
||||
|
||||
Apart from storing login information and other account-specific data, the Account object is what is
|
||||
chatting on [Channels](./Communications). It is also a good place to store [Permissions](./Locks) to be
|
||||
chatting on [Channels](./Communications.md). It is also a good place to store [Permissions](./Locks.md) to be
|
||||
consistent between different in-game characters as well as configuration options. The Account
|
||||
object also has its own [CmdSet](./Command-Sets), the `AccountCmdSet`.
|
||||
object also has its own [CmdSet](./Command-Sets.md), the `AccountCmdSet`.
|
||||
|
||||
Logged into default evennia, you can use the `ooc` command to leave your current
|
||||
[character](./Objects) and go into OOC mode. You are quite limited in this mode, basically it works
|
||||
[character](./Objects.md) and go into OOC mode. You are quite limited in this mode, basically it works
|
||||
like a simple chat program. It acts as a staging area for switching between Characters (if your
|
||||
game supports that) or as a safety mode if your Character gets deleted. Use `ic` to attempt to
|
||||
(re)puppet a Character.
|
||||
(re)puppet a Character.
|
||||
|
||||
Note that the Account object can have, and often does have, a different set of
|
||||
[Permissions](./Locks#Permissions) from the Character they control. Normally you should put your
|
||||
[Permissions](./Permissions.md) from the Character they control. Normally you should put your
|
||||
permissions on the Account level - this will overrule permissions set on the Character level. For
|
||||
the permissions of the Character to come into play the default `quell` command can be used. This
|
||||
allows for exploring the game using a different permission set (but you can't escalate your
|
||||
permissions this way - for hierarchical permissions like `Builder`, `Admin` etc, the *lower* of the
|
||||
permissions on the Character/Account will always be used).
|
||||
permissions on the Character/Account will always be used).
|
||||
|
||||
## How to create your own Account types
|
||||
|
||||
You will usually not want more than one Account typeclass for all new accounts (but you could in
|
||||
principle create a system that changes an account's typeclass dynamically).
|
||||
principle create a system that changes an account's typeclass dynamically).
|
||||
|
||||
An Evennia Account is, per definition, a Python class that includes `evennia.DefaultAccount` among
|
||||
its parents. In `mygame/typeclasses/accounts.py` there is an empty class ready for you to modify.
|
||||
Evennia defaults to using this (it inherits directly from `DefaultAccount`).
|
||||
Evennia defaults to using this (it inherits directly from `DefaultAccount`).
|
||||
|
||||
Here's an example of modifying the default Account class in code:
|
||||
Here's an example of modifying the default Account class in code:
|
||||
|
||||
```python
|
||||
```python
|
||||
# in mygame/typeclasses/accounts.py
|
||||
|
||||
from evennia import DefaultAccount
|
||||
|
|
@ -51,7 +51,7 @@ Here's an example of modifying the default Account class in code:
|
|||
self.db.config_1 = True # default config self.db.config_2 = False # "
|
||||
self.db.config_3 = 1 # "
|
||||
|
||||
# ... whatever else our game needs to know ``` Reload the server with `reload`.
|
||||
# ... whatever else our game needs to know ``` Reload the server with `reload`.
|
||||
|
||||
```
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ using `py`:
|
|||
|
||||
``` py [account.at_account_creation() for account in evennia.managers.accounts.all()] ```
|
||||
|
||||
You should now see the Attributes on yourself.
|
||||
You should now see the Attributes on yourself.
|
||||
|
||||
|
||||
> If you wanted Evennia to default to a completely *different* Account class located elsewhere, you
|
||||
|
|
@ -76,8 +76,8 @@ You should now see the Attributes on yourself.
|
|||
|
||||
## Properties on Accounts
|
||||
|
||||
Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses)), the
|
||||
Account also has the following custom properties:
|
||||
Beyond those properties assigned to all typeclassed objects (see [Typeclasses](./Typeclasses.md)), the
|
||||
Account also has the following custom properties:
|
||||
|
||||
- `user` - a unique link to a `User` Django object, representing the logged-in user.
|
||||
- `obj` - an alias for `character`.
|
||||
|
|
@ -91,12 +91,12 @@ as
|
|||
- `is_superuser` (bool: True/False) - if this account is a superuser.
|
||||
|
||||
Special handlers:
|
||||
- `cmdset` - This holds all the current [Commands](./Commands) of this Account. By default these are
|
||||
- `cmdset` - This holds all the current [Commands](./Commands.md) of this Account. By default these are
|
||||
the commands found in the cmdset defined by `settings.CMDSET_ACCOUNT`.
|
||||
- `nicks` - This stores and handles [Nicks](./Nicks), in the same way as nicks it works on Objects.
|
||||
- `nicks` - This stores and handles [Nicks](./Nicks.md), in the same way as nicks it works on Objects.
|
||||
For Accounts, nicks are primarily used to store custom aliases for
|
||||
[Channels](./Communications#Channels).
|
||||
|
||||
[Channels](./Channels.md).
|
||||
|
||||
Selection of special methods (see `evennia.DefaultAccount` for details):
|
||||
- `get_puppet` - get a currently puppeted object connected to the Account and a given session id, if
|
||||
any.
|
||||
|
|
@ -104,4 +104,4 @@ Selection of special methods (see `evennia.DefaultAccount` for details):
|
|||
- `unpuppet_object` - disconnect a session from a puppetable Object.
|
||||
- `msg` - send text to the Account
|
||||
- `execute_cmd` - runs a command as if this Account did it.
|
||||
- `search` - search for Accounts.
|
||||
- `search` - search for Accounts.
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ can give correct subsequent commands. If you are writing a combat system, you mi
|
|||
combattant's next roll get easier dependent on if their opponent failed. Your characters will
|
||||
probably need to store roleplaying-attributes like strength and agility. And so on.
|
||||
|
||||
[Typeclassed](./Typeclasses) game entities ([Accounts](./Accounts), [Objects](./Objects),
|
||||
[Scripts](./Scripts) and [Channels](./Communications)) always have *Attributes* associated with them.
|
||||
[Typeclassed](./Typeclasses.md) game entities ([Accounts](./Accounts.md), [Objects](./Objects.md),
|
||||
[Scripts](./Scripts.md) and [Channels](./Communications.md)) always have *Attributes* associated with them.
|
||||
Attributes are used to store any type of data 'on' such entities. This is different from storing
|
||||
data in properties already defined on entities (such as `key` or `location`) - these have very
|
||||
specific names and require very specific types of data (for example you couldn't assign a python
|
||||
|
|
@ -16,12 +16,12 @@ specific names and require very specific types of data (for example you couldn't
|
|||
want to assign arbitrary data to arbitrary names.
|
||||
|
||||
**Attributes are _not_ secure by default and any player may be able to change them unless you
|
||||
[prevent this behavior](./Attributes#locking-and-checking-attributes).**
|
||||
[prevent this behavior](./Attributes.md#locking-and-checking-attributes).**
|
||||
|
||||
## The .db and .ndb shortcuts
|
||||
|
||||
To save persistent data on a Typeclassed object you normally use the `db` (DataBase) operator. Let's
|
||||
try to save some data to a *Rose* (an [Object](./Objects)):
|
||||
try to save some data to a *Rose* (an [Object](./Objects.md)):
|
||||
|
||||
```python
|
||||
# saving
|
||||
|
|
@ -87,13 +87,13 @@ The handlers have normal access methods that allow you to manage and retrieve `A
|
|||
returned, but the method takes keywords for returning the Attribute object itself. By supplying an
|
||||
`accessing_object` to the call one can also make sure to check permissions before modifying
|
||||
anything.
|
||||
- `add(...)` - this adds a new Attribute to the object. An optional [lockstring](./Locks) can be
|
||||
- `add(...)` - this adds a new Attribute to the object. An optional [lockstring](./Locks.md) can be
|
||||
supplied here to restrict future access and also the call itself may be checked against locks.
|
||||
- `remove(...)` - Remove the given Attribute. This can optionally be made to check for permission
|
||||
before performing the deletion. - `clear(...)` - removes all Attributes from object.
|
||||
- `all(...)` - returns all Attributes (of the given category) attached to this object.
|
||||
|
||||
See [this section](./Attributes#locking-and-checking-attributes) for more about locking down Attribute
|
||||
See [this section](./Attributes.md#locking-and-checking-attributes) for more about locking down Attribute
|
||||
access and editing. The `Nattribute` offers no concept of access control.
|
||||
|
||||
Some examples:
|
||||
|
|
@ -118,23 +118,23 @@ An Attribute object is stored in the database. It has the following properties:
|
|||
to `attrname`.
|
||||
- `value` - this is the value of the Attribute. This value can be anything which can be pickled -
|
||||
objects, lists, numbers or what have you (see
|
||||
[this section](./Attributes#What_types_of_data_can_I_save_in_an_Attribute) for more info). In the
|
||||
[this section](./Attributes.md#what-types-of-data-can-i-save-in-an-attribute) for more info). In the
|
||||
example
|
||||
`obj.db.attrname = value`, the `value` is stored here.
|
||||
- `category` - this is an optional property that is set to None for most Attributes. Setting this
|
||||
allows to use Attributes for different functionality. This is usually not needed unless you want
|
||||
to use Attributes for very different functionality ([Nicks](./Nicks) is an example of using
|
||||
to use Attributes for very different functionality ([Nicks](./Nicks.md) is an example of using
|
||||
Attributes
|
||||
in this way). To modify this property you need to use the [Attribute
|
||||
Handler](Attributes#The_Attribute_Handler).
|
||||
in this way). To modify this property you need to use the
|
||||
[Attribute Handler](./Attributes.md#the-attributehandler).
|
||||
- `strvalue` - this is a separate value field that only accepts strings. This severely limits the
|
||||
data possible to store, but allows for easier database lookups. This property is usually not used
|
||||
except when re-using Attributes for some other purpose ([Nicks](./Nicks) use it). It is only
|
||||
accessible via the [Attribute Handler](./Attributes#The_Attribute_Handler).
|
||||
except when re-using Attributes for some other purpose ([Nicks](./Nicks.md) use it). It is only
|
||||
accessible via the [Attribute Handler](./Attributes.md#the-attributehandler).
|
||||
|
||||
There are also two special properties:
|
||||
|
||||
- `attrtype` - this is used internally by Evennia to separate [Nicks](./Nicks), from Attributes (Nicks
|
||||
- `attrtype` - this is used internally by Evennia to separate [Nicks](./Nicks.md), from Attributes (Nicks
|
||||
use Attributes behind the scenes).
|
||||
- `model` - this is a *natural-key* describing the model this Attribute is attached to. This is on
|
||||
the form *appname.modelclass*, like `objects.objectdb`. It is used by the Attribute and
|
||||
|
|
@ -162,7 +162,7 @@ default
|
|||
during heavy loads.
|
||||
- A more valid reason for using non-persistent data is if you *want* to lose your state when logging
|
||||
off. Maybe you are storing throw-away data that are re-initialized at server startup. Maybe you
|
||||
are implementing some caching of your own. Or maybe you are testing a buggy [Script](./Scripts) that
|
||||
are implementing some caching of your own. Or maybe you are testing a buggy [Script](./Scripts.md) that
|
||||
does potentially harmful stuff to your character object. With non-persistent storage you can be
|
||||
sure
|
||||
that whatever is messed up, it's nothing a server reboot can't clear up.
|
||||
|
|
@ -192,7 +192,7 @@ not a big deal. But if you are accessing the Attribute as part of some big loop
|
|||
amount of reads/writes you should first extract it to a temporary variable, operate on *that* and
|
||||
then save the result back to the Attribute. If you are storing a more complex structure like a
|
||||
`dict` or a `list` you should make sure to "disconnect" it from the database before looping over it,
|
||||
as mentioned in the [Retrieving Mutable Objects](./Attributes#retrieving-mutable-objects) section
|
||||
as mentioned in the [Retrieving Mutable Objects](./Attributes.md#retrieving-mutable-objects) section
|
||||
below.
|
||||
|
||||
### Storing single objects
|
||||
|
|
@ -248,7 +248,7 @@ containing dicts, etc.
|
|||
Since you can use any combination of the above iterables, this is generally not much of a
|
||||
limitation.
|
||||
|
||||
Any entity listed in the [Single object](./Attributes#Storing-Single-Objects) section above can be
|
||||
Any entity listed in the [Single object](./Attributes.md#storing-single-objects) section above can be
|
||||
stored in the iterable.
|
||||
|
||||
> As mentioned in the previous section, database entities (aka typeclasses) are not possible to
|
||||
|
|
@ -355,7 +355,7 @@ already disconnected from the database from the onset.
|
|||
Attributes are normally not locked down by default, but you can easily change that for individual
|
||||
Attributes (like those that may be game-sensitive in games with user-level building).
|
||||
|
||||
First you need to set a *lock string* on your Attribute. Lock strings are specified [Locks](./Locks).
|
||||
First you need to set a *lock string* on your Attribute. Lock strings are specified [Locks](./Locks.md).
|
||||
The relevant lock types are
|
||||
|
||||
- `attrread` - limits who may read the value of the Attribute
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Batch Code Processor
|
||||
|
||||
|
||||
For an introduction and motivation to using batch processors, see [here](./Batch-Processors). This
|
||||
For an introduction and motivation to using batch processors, see [here](./Batch-Processors.md). This
|
||||
page describes the Batch-*code* processor. The Batch-*command* one is covered [here](Batch-Command-
|
||||
Processor).
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ connect that room with a room you built in the current block. There are two ways
|
|||
|
||||
- Perform a database search for the name of the room you created (since you cannot know in advance
|
||||
which dbref it got assigned). The problem is that a name may not be unique (you may have a lot of "A
|
||||
dark forest" rooms). There is an easy way to handle this though - use [Tags](./Tags) or *Aliases*. You
|
||||
dark forest" rooms). There is an easy way to handle this though - use [Tags](./Tags.md) or *Aliases*. You
|
||||
can assign any number of tags and/or aliases to any object. Make sure that one of those tags or
|
||||
aliases is unique to the room (like "room56") and you will henceforth be able to always uniquely
|
||||
search and find it later.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Batch Command Processor
|
||||
|
||||
|
||||
For an introduction and motivation to using batch processors, see [here](./Batch-Processors). This
|
||||
For an introduction and motivation to using batch processors, see [here](./Batch-Processors.md). This
|
||||
page describes the Batch-*command* processor. The Batch-*code* one is covered [here](Batch-Code-
|
||||
Processor).
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ when creating the file, so that you can 'walk' (or teleport) to the right places
|
|||
This also means there are several pitfalls when designing and adding certain types of objects. Here
|
||||
are some examples:
|
||||
|
||||
- *Rooms that change your [Command Set](./Command-Sets)*: Imagine that you build a 'dark' room, which
|
||||
- *Rooms that change your [Command Set](./Command-Sets.md)*: Imagine that you build a 'dark' room, which
|
||||
severely limits the cmdsets of those entering it (maybe you have to find the light switch to
|
||||
proceed). In your batch script you would create this room, then teleport to it - and promptly be
|
||||
shifted into the dark state where none of your normal build commands work ...
|
||||
|
|
@ -172,7 +172,7 @@ The fact that you build as 'yourself' can also be considered an advantage howeve
|
|||
decide to change the default command to allow others than superusers to call the processor. Since
|
||||
normal access-checks are still performed, a malevolent builder with access to the processor should
|
||||
not be able to do all that much damage (this is the main drawback of the [Batch Code
|
||||
Processor](Batch-Code-Processor))
|
||||
Processor](./Batch-Code-Processor.md))
|
||||
|
||||
- [GNU Emacs](https://www.gnu.org/software/emacs/) users might find it interesting to use emacs'
|
||||
*evennia mode*. This is an Emacs major mode found in `evennia/utils/evennia-mode.el`. It offers
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ just list in-game commands in a text file. The code-processor on the other hand
|
|||
powerful but also more complex - it lets you use Evennia's API to code your world in full-fledged
|
||||
Python code.
|
||||
|
||||
- The [Batch Command Processor](./Batch-Command-Processor)
|
||||
- The [Batch Code Processor](./Batch-Code-Processor)
|
||||
- The [Batch Command Processor](./Batch-Command-Processor.md)
|
||||
- The [Batch Code Processor](./Batch-Code-Processor.md)
|
||||
|
||||
If you plan to use international characters in your batchfiles you are wise to read about *file
|
||||
encodings* below.
|
||||
|
|
@ -73,7 +73,7 @@ need to add the editor's encoding to Evennia's `ENCODINGS` list. If you are unsu
|
|||
file with lots of non-ASCII letters in the editor of your choice, then import to make sure it works
|
||||
as it should.
|
||||
|
||||
More help with encodings can be found in the entry [Text Encodings](../Concepts/Text-Encodings) and also in the
|
||||
More help with encodings can be found in the entry [Text Encodings](../Concepts/Text-Encodings.md) and also in the
|
||||
Wikipedia article [here](https://en.wikipedia.org/wiki/Text_encodings).
|
||||
|
||||
**A footnote for the batch-code processor**: Just because *Evennia* can parse your file and your
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
Bootstrap provides many utilities and components you can use when customizing Evennia's web
|
||||
presence. We'll go over a few examples here that you might find useful.
|
||||
> Please take a look at either [the basic web tutorial](../Howto/Starting/Part5/Add-a-simple-new-web-page) or
|
||||
>[the web character view tutorial](../Howto/Web-Character-View-Tutorial)
|
||||
> Please take a look at either [the basic web tutorial](../Howto/Starting/Part5/Add-a-simple-new-web-page.md) or
|
||||
>[the web character view tutorial](../Howto/Web-Character-View-Tutorial.md)
|
||||
> to get a feel for how to add pages to Evennia's website to test these examples.
|
||||
|
||||
## General Styling
|
||||
|
|
@ -77,4 +77,4 @@ width of the page - Evennia's base site uses the former.
|
|||
### Forms
|
||||
[Forms](https://getbootstrap.com/docs/4.0/components/forms/) are highly customizable with Bootstrap.
|
||||
For a more in-depth look at how to use forms and their styles in your own Evennia site, please read
|
||||
over [the web character gen tutorial.](../Howto/Web-Character-Generation)
|
||||
over [the web character gen tutorial.](../Howto/Web-Character-Generation.md)
|
||||
|
|
@ -7,8 +7,8 @@ _Channels_ allows Evennia's to act as a fancy chat program. When a player is
|
|||
connected to a channel, sending a message to it will automatically distribute
|
||||
it to every other subscriber.
|
||||
|
||||
Channels can be used both for chats between [Accounts](./Accounts) and between
|
||||
[Objects](./Objects) (usually Characters). Chats could be both OOC
|
||||
Channels can be used both for chats between [Accounts](./Accounts.md) and between
|
||||
[Objects](./Objects.md) (usually Characters). Chats could be both OOC
|
||||
(out-of-character) or IC (in-charcter) in nature. Some examples:
|
||||
|
||||
- A support channel for contacting staff (OOC)
|
||||
|
|
@ -20,7 +20,7 @@ Channels can be used both for chats between [Accounts](./Accounts) and between
|
|||
- Group telephathy (IC)
|
||||
- Walkie talkies (IC)
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
|
||||
Channel system changed to use a central 'channel' command and nicks instead of
|
||||
auto-generated channel-commands and -cmdset. ChannelHandler was removed.
|
||||
|
|
@ -30,7 +30,8 @@ Channels can be used both for chats between [Accounts](./Accounts) and between
|
|||
## Using channels in-game
|
||||
|
||||
In the default command set, channels are all handled via the mighty
|
||||
[channel command](api:evennia.commands.default.comms.CmdChannel), `channel` (or
|
||||
[channel
|
||||
command](evennia.commands.default.comms.CmdChannel), `channel` (or
|
||||
`chan`). By default, this command will assume all entities dealing with
|
||||
channels are `Accounts`.
|
||||
|
||||
|
|
@ -66,7 +67,7 @@ system automatically sets up an personal alias so you can do this instead:
|
|||
|
||||
public Hello world
|
||||
|
||||
```warning::
|
||||
```{warning}
|
||||
|
||||
This shortcut will not work if the channel-name has spaces in it.
|
||||
So channels with long names should make sure to provide a one-word alias as
|
||||
|
|
@ -91,7 +92,7 @@ But you can also use your alias with the `channel` command:
|
|||
|
||||
channel foo Hello world!
|
||||
|
||||
> What happens when aliasing is that a [nick](./Nicks) is created that maps your
|
||||
> What happens when aliasing is that a [nick](./Nicks.md) is created that maps your
|
||||
> alias + argument onto calling the `channel` command. So when you enter `foo hello`,
|
||||
> what the server sees is actually `channel foo = hello`. The system is also
|
||||
> clever enough to know that whenever you search for channels, your channel-nicks
|
||||
|
|
@ -140,10 +141,10 @@ Banning adds the user to the channels blacklist. This means they will not be
|
|||
able to _rejoin_ if you boot them. You will need to run `channel/boot` to
|
||||
actually kick them out.
|
||||
|
||||
See the [Channel command](api:evennia.commands.default.comms.CmdChannel) api
|
||||
See the [Channel command](evennia.commands.default.comms.CmdChannel) api
|
||||
docs (and in-game help) for more details.
|
||||
|
||||
Admin-level users can also modify channel's [locks](./Locks):
|
||||
Admin-level users can also modify channel's [locks](./Locks.md):
|
||||
|
||||
channel/lock buildchannel = listen:all();send:perm(Builders)
|
||||
|
||||
|
|
@ -158,7 +159,7 @@ Channels use three lock-types by default:
|
|||
|
||||
#### Restricting channel administration
|
||||
|
||||
By default everyone can use the channel command ([evennia.commands.default.comms.CmdChannel](api:evennia.commands.default.comms.CmdChannel))
|
||||
By default everyone can use the channel command ([evennia.commands.default.comms.CmdChannel](evennia.commands.default.comms.CmdChannel))
|
||||
to create channels and will then control the channels they created (to boot/ban
|
||||
people etc). If you as a developer does not want regular players to do this
|
||||
(perhaps you want only staff to be able to spawn new channels), you can
|
||||
|
|
@ -170,7 +171,7 @@ The default `help` command has the following `locks` property:
|
|||
locks = "cmd:not perm(channel_banned); admin:all(); manage:all(); changelocks: perm(Admin)"
|
||||
```
|
||||
|
||||
This is a regular [lockstring](./Locks).
|
||||
This is a regular [lockstring](./Locks.md).
|
||||
|
||||
- `cmd: pperm(channel_banned)` - The `cmd` locktype is the standard one used for all Commands.
|
||||
an accessing object failing this will not even know that the command exists. The `pperm()` lockfunc
|
||||
|
|
@ -204,14 +205,14 @@ access-denied error when trying to use use these switches.
|
|||
|
||||
## Allowing Characters to use Channels
|
||||
|
||||
The default `channel` command ([evennia.commands.default.comms.CmdChannel](api:evennia.commands.default.comms.CmdChannel))
|
||||
sits in the `Account` [command set](./Command-Sets). It is set up such that it will
|
||||
The default `channel` command ([evennia.commands.default.comms.CmdChannel](evennia.commands.default.comms.CmdChannel))
|
||||
sits in the `Account` [command set](./Command-Sets.md). It is set up such that it will
|
||||
always operate on `Accounts`, even if you were to add it to the
|
||||
`CharacterCmdSet`.
|
||||
|
||||
It's a one-line change to make this command accept non-account callers. But for
|
||||
convenience we provide a version for Characters/Objects. Just import
|
||||
[evennia.commands.default.comms.CmdObjectChannel](api:evennia.commands.default.comms.CmdObjectChannel)
|
||||
[evennia.commands.default.comms.CmdObjectChannel](evennia.commands.default.comms.CmdObjectChannel)
|
||||
and inherit from that instead.
|
||||
|
||||
## Customizing channel output and behavior
|
||||
|
|
@ -248,13 +249,13 @@ For most common changes, the default channel, the recipient hooks and possibly
|
|||
overriding the `channel` command will get you very far. But you can also tweak
|
||||
channels themselves.
|
||||
|
||||
Channels are [Typeclassed](./Typeclasses) entities. This means they are
|
||||
persistent in the database, can have [attributes](./Attributes) and [Tags](./Tags)
|
||||
Channels are [Typeclassed](./Typeclasses.md) entities. This means they are
|
||||
persistent in the database, can have [attributes](./Attributes.md) and [Tags](./Tags.md)
|
||||
and can be easily extended.
|
||||
|
||||
To change which channel typeclass Evennia uses for default commands, change
|
||||
`settings.BASE_CHANNEL_TYPECLASS`. The base command class is
|
||||
[`evennia.comms.comms.DefaultChannel`](api:evennia.comms.comms.DefaultChannel).
|
||||
[`evennia.comms.comms.DefaultChannel`](evennia.comms.comms.DefaultChannel).
|
||||
There is an empty child class in `mygame/typeclasses/channels.py`, same
|
||||
as for other typelass-bases.
|
||||
|
||||
|
|
@ -299,11 +300,11 @@ details.
|
|||
|
||||
## Channel logging
|
||||
|
||||
```versionchanged:: 0.7
|
||||
```{versionchanged} 0.7
|
||||
|
||||
Channels changed from using Msg to TmpMsg and optional log files.
|
||||
```
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
|
||||
Channels stopped supporting Msg and TmpMsg, using only log files.
|
||||
```
|
||||
|
|
@ -325,7 +326,7 @@ channel's `at_post_channel_msg` method.
|
|||
|
||||
Channels have all the standard properties of a Typeclassed entity (`key`,
|
||||
`aliases`, `attributes`, `tags`, `locks` etc). This is not an exhaustive list;
|
||||
see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details.
|
||||
see the [Channel api docs](evennia.comms.comms.DefaultChannel) for details.
|
||||
|
||||
- `send_to_online_only` - this class boolean defaults to `True` and is a
|
||||
sensible optimization since people offline people will not see the message anyway.
|
||||
|
|
@ -334,8 +335,8 @@ see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details.
|
|||
`mygame/server/logs/`). You should usually not change this.
|
||||
- `channel_prefix_string` - this property is a string to easily change how
|
||||
the channel is prefixed. It takes the `channelname` format key. Default is `"[{channelname}] "`
|
||||
and produces output like `[public] ...``.
|
||||
- `subscriptions` - this is the [SubscriptionHandler](api:evennia.comms.comms#SubscriptionHandler), which
|
||||
and produces output like `[public] ...`.
|
||||
- `subscriptions` - this is the [SubscriptionHandler](evennia.comms.models.SubscriptionHandler), which
|
||||
has methods `has`, `add`, `remove`, `all`, `clear` and also `online` (to get
|
||||
only actually online channel-members).
|
||||
- `wholist`, `mutelist`, `banlist` are properties that return a list of subscribers,
|
||||
|
|
@ -345,7 +346,7 @@ see the [Channel api docs](api:evennia.comms.comms.DefaultChannel) for details.
|
|||
This pattern accepts an `{alias}` formatting marker. Don't mess with this unless you really
|
||||
want to change how channels work.
|
||||
- `channel_msg_nick_replacement` - this is a string on the [nick replacement
|
||||
- form](Nicks). It accepts the `{channelname}` formatting tag. This is strongly tied to the
|
||||
- form](./Nicks.md). It accepts the `{channelname}` formatting tag. This is strongly tied to the
|
||||
`channel` command and is by default `channel {channelname} = $1`.
|
||||
|
||||
Notable `Channel` hooks:
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ If you need to search for objects in a code module you can use the functions in
|
|||
obj = search_object(objname)
|
||||
```
|
||||
|
||||
- [evennia.search_account](../wiki/evennia.accounts.manager#accountdbmanagersearch_account)
|
||||
- [evennia.search_object](../wiki/evennia.objects.manager#objectdbmanagersearch_object)
|
||||
- [evennia.search_object_by_tag](../wiki/evennia.utils.search#search_object_by_tag)
|
||||
- [evennia.search_script](../wiki/evennia.scripts.manager#scriptdbmanagersearch_script)
|
||||
- [evennia.search_channel](../wiki/evennia.comms.managers#channeldbmanagersearch_channel)
|
||||
- [evennia.search_message](../wiki/evennia.comms.managers#msgmanagersearch_message)
|
||||
- [evennia.search_help](../wiki/evennia.help.manager#helpentrymanagersearch_help)
|
||||
- [`evennia.search_account`](evennia.accounts.manager.AccountDBManager.search_account)
|
||||
- [`evennia.search_object`](evennia.objects.manager.ObjectDBManager.search_object)
|
||||
- [`evennia.search(object)_by_tag`](evennia.utils.search.search_tag)
|
||||
- [`evennia.search_script`](evennia.scripts.manager.ScriptDBManager.search_script)
|
||||
- [`evennia.search_channel`](evennia.comms.managers.ChannelDBManager.search_channel)
|
||||
- [`evennia.search_message`](evennia.comms.managers.MsgManager.search_message)
|
||||
- [`evennia.search_help`](evennia.help.manager.HelpEntryManager.search_help)
|
||||
|
||||
Note that these latter methods will always return a `list` of results, even if the list has one or
|
||||
zero entries.
|
||||
|
|
@ -50,12 +50,12 @@ entities directly in code (for example when defining new create commands).
|
|||
myobj = evennia.create_objects("game.gamesrc.objects.myobj.MyObj", key="MyObj")
|
||||
```
|
||||
|
||||
- [evennia.create_account](../wiki/evennia.utils.create#create_account)
|
||||
- [evennia.create_object](../wiki/evennia.utils.create#create_object)
|
||||
- [evennia.create_script](../wiki/evennia.utils.create#create_script)
|
||||
- [evennia.create_channel](../wiki/evennia.utils.create#create_channel)
|
||||
- [evennia.create_help_entry](../wiki/evennia.utils.create#create_help_entry)
|
||||
- [evennia.create_message](../wiki/evennia.utils.create#create_message)
|
||||
- [`evennia.create_account`](evennia.utils.create.create_account)
|
||||
- [`evennia.create_object`](evennia.utils.create.create_object)
|
||||
- [`evennia.create_script`](evennia.utils.create.create_script)
|
||||
- [`evennia.create_channel`](evennia.utils.create.create_channel)
|
||||
- [`evennia.create_help_entry`](evennia.utils.create.create_help_entry)
|
||||
- [`evennia.create_message`](evennia.utils.create.create_message)
|
||||
|
||||
Each of these create-functions have a host of arguments to further customize the created entity. See
|
||||
`evennia/utils/create.py` for more information.
|
||||
|
|
@ -137,7 +137,7 @@ setting `TIME_GAME_EPOCH` sets the starting game epoch (in seconds). The functio
|
|||
you desire for your game. You can use the `@time` command to view the server time info.
|
||||
|
||||
You can also *schedule* things to happen at specific in-game times using the
|
||||
[gametime.schedule](github:evennia.utils.gametime#schedule) function:
|
||||
[gametime.schedule](evennia.utils.gametime.schedule) function:
|
||||
|
||||
```python
|
||||
import evennia
|
||||
|
|
@ -181,13 +181,13 @@ number of seconds. This is a very light wrapper over a Twisted
|
|||
non-persistently, which means that if the server is `@reload`ed before the delay is over, the
|
||||
callback will never run (the server forgets it). If setting `persistent` to True, the delay will be
|
||||
stored in the database and survive a `@reload` - but for this to work it is susceptible to the same
|
||||
limitations incurred when saving to an [Attribute](./Attributes).
|
||||
limitations incurred when saving to an [Attribute](./Attributes.md).
|
||||
|
||||
The `deferred` return object can usually be ignored, but calling its `.cancel()` method will abort
|
||||
the delay prematurely.
|
||||
|
||||
`utils.delay` is the lightest form of delayed call in Evennia. For other way to create time-bound
|
||||
tasks, see the [TickerHandler](./TickerHandler) and [Scripts](./Scripts).
|
||||
tasks, see the [TickerHandler](./TickerHandler.md) and [Scripts](./Scripts.md).
|
||||
|
||||
> Note that many delayed effects can be achieved without any need for an active timer. For example
|
||||
if you have a trait that should recover a point every 5 seconds you might just need its value when
|
||||
|
|
@ -203,7 +203,7 @@ classes, instances or python-paths-to-classes.
|
|||
|
||||
Note that Python code should usually work with [duck
|
||||
typing](https://en.wikipedia.org/wiki/Duck_typing). But in Evennia's case it can sometimes be useful
|
||||
to check if an object inherits from a given [Typeclass](./Typeclasses) as a way of identification. Say
|
||||
to check if an object inherits from a given [Typeclass](./Typeclasses.md) as a way of identification. Say
|
||||
for example that we have a typeclass *Animal*. This has a subclass *Felines* which in turn has a
|
||||
subclass *HouseCat*. Maybe there are a bunch of other animal types too, like horses and dogs. Using
|
||||
`inherits_from` will allow you to check for all animals in one go:
|
||||
|
|
@ -274,17 +274,17 @@ need to send byte-data over the wire, `to_str` is the only one you'll need.
|
|||
The difference from Python's in-built `str()` and `bytes()` operators are that
|
||||
the Evennia ones makes use of the `ENCODINGS` setting and will try very hard to
|
||||
never raise a traceback but instead echo errors through logging. See
|
||||
[here](../Concepts/Text-Encodings) for more info.
|
||||
[here](../Concepts/Text-Encodings.md) for more info.
|
||||
|
||||
### Ansi Coloring Tools
|
||||
- [evennia.ansi](api:evennia.utils.ansi)
|
||||
- [evennia.utils.ansi](evennia.utils.ansi)
|
||||
|
||||
## Display utilities
|
||||
### Making ascii tables
|
||||
|
||||
The [EvTable](github:evennia.utils.evtable#evtable) class (`evennia/utils/evtable.py`) can be used
|
||||
The [EvTable](evennia.utils.evtable.EvTable) class (`evennia/utils/evtable.py`) can be used
|
||||
to create correctly formatted text tables. There is also
|
||||
[EvForm](github:evennia.utils.evform#evform) (`evennia/utils/evform.py`). This reads a fixed-format
|
||||
[EvForm](evennia.utils.evform.EvForm) (`evennia/utils/evform.py`). This reads a fixed-format
|
||||
text template from a file in order to create any level of sophisticated ascii layout. Both evtable
|
||||
and evform have lots of options and inputs so see the header of each module for help.
|
||||
|
||||
|
|
@ -294,4 +294,4 @@ ANSI colour. PrettyTable can be found in `evennia/utils/prettytable/`. See its
|
|||
instructions.
|
||||
|
||||
### Menus
|
||||
- [evennia.EvMenu](github:evennia.utils.evmenu#evmenu)
|
||||
- [evennia.EvMenu](evennia.utils.evmenu.EvMenu)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Command Sets
|
||||
|
||||
|
||||
Command Sets are intimately linked with [Commands](./Commands) and you should be familiar with
|
||||
Command Sets are intimately linked with [Commands](./Commands.md) and you should be familiar with
|
||||
Commands before reading this page. The two pages were split for ease of reading.
|
||||
|
||||
A *Command Set* (often referred to as a CmdSet or cmdset) is the basic unit for storing one or more
|
||||
|
|
@ -11,7 +11,7 @@ classes in a command set is the way to make commands available to use in your ga
|
|||
When storing a CmdSet on an object, you will make the commands in that command set available to the
|
||||
object. An example is the default command set stored on new Characters. This command set contains
|
||||
all the useful commands, from `look` and `inventory` to `@dig` and `@reload`
|
||||
([permissions](./Locks#Permissions) then limit which players may use them, but that's a separate
|
||||
([permissions](./Permissions.md) then limit which players may use them, but that's a separate
|
||||
topic).
|
||||
|
||||
When an account enters a command, cmdsets from the Account, Character, its location, and elsewhere
|
||||
|
|
@ -26,7 +26,7 @@ on. The tutorial world included with Evennia showcases a dark room that replaces
|
|||
commands with its own versions because the Character cannot see.
|
||||
|
||||
If you want a quick start into defining your first commands and using them with command sets, you
|
||||
can head over to the [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) which steps through things
|
||||
can head over to the [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) which steps through things
|
||||
without the explanations.
|
||||
|
||||
## Defining Command Sets
|
||||
|
|
@ -112,11 +112,11 @@ back even if all other cmdsets fail or are removed. It is always persistent and
|
|||
by `cmdset.delete()`. To remove a default cmdset you must explicitly call `cmdset.remove_default()`.
|
||||
|
||||
Command sets are often added to an object in its `at_object_creation` method. For more examples of
|
||||
adding commands, read the [Step by step tutorial](../Howto/Starting/Part1/Adding-Commands). Generally you can
|
||||
adding commands, read the [Step by step tutorial](../Howto/Starting/Part1/Adding-Commands.md). Generally you can
|
||||
customize which command sets are added to your objects by using `self.cmdset.add()` or
|
||||
`self.cmdset.add_default()`.
|
||||
|
||||
> Important: Commands are identified uniquely by key *or* alias (see [Commands](./Commands)). If any
|
||||
> Important: Commands are identified uniquely by key *or* alias (see [Commands](./Commands.md)). If any
|
||||
overlap exists, two commands are considered identical. Adding a Command to a command set that
|
||||
already has an identical command will *replace* the previous command. This is very important. You
|
||||
must take this behavior into account when attempting to overload any default Evennia commands with
|
||||
|
|
@ -127,7 +127,7 @@ new one that has a matching alias.
|
|||
|
||||
There are several extra flags that you can set on CmdSets in order to modify how they work. All are
|
||||
optional and will be set to defaults otherwise. Since many of these relate to *merging* cmdsets,
|
||||
you might want to read the [Adding and Merging Command Sets](./Command-Sets#adding-and-merging-
|
||||
you might want to read the [Adding and Merging Command Sets](./Command-Sets.md#adding-and-merging-
|
||||
command-sets) section for some of these to make sense.
|
||||
|
||||
- `key` (string) - an identifier for the cmdset. This is optional, but should be unique. It is used
|
||||
|
|
@ -138,7 +138,7 @@ dictionary below.
|
|||
- `priority` (int) - This defines the merge order of the merge stack - cmdsets will merge in rising
|
||||
order of priority with the highest priority set merging last. During a merger, the commands from the
|
||||
set with the higher priority will have precedence (just what happens depends on the [merge
|
||||
type](Command-Sets#adding-and-merging-command-sets)). If priority is identical, the order in the
|
||||
type](./Command-Sets.md#adding-and-merging-command-sets)). If priority is identical, the order in the
|
||||
merge stack determines preference. The priority value must be greater or equal to `-100`. Most in-
|
||||
game sets should usually have priorities between `0` and `100`. Evennia default sets have priorities
|
||||
as follows (these can be changed if you want a different distribution):
|
||||
|
|
@ -154,7 +154,7 @@ arguments, there is no collision between exits named the same as a channel even
|
|||
differently with certain named cmdsets. If the cmdset to merge with has a `key` matching an entry in
|
||||
`key_mergetype`, it will not be merged according to the setting in `mergetype` but according to the
|
||||
mode in this dict. Please note that this is more complex than it may seem due to the [merge
|
||||
order](Command-Sets#adding-and-merging-command-sets) of command sets. Please review that section
|
||||
order](./Command-Sets.md#adding-and-merging-command-sets) of command sets. Please review that section
|
||||
before using `key_mergetype`.
|
||||
- `duplicates` (bool/None default `None`) - this determines what happens when merging same-priority
|
||||
cmdsets containing same-key commands together. The`dupicate` option will *only* apply when merging
|
||||
|
|
@ -195,15 +195,15 @@ priority determines what is used.
|
|||
|
||||
## Command Sets Searched
|
||||
|
||||
When a user issues a command, it is matched against the [merged](./Command-Sets#adding-and-merging-
|
||||
When a user issues a command, it is matched against the [merged](./Command-Sets.md#adding-and-merging-
|
||||
command-sets) command sets available to the player at the moment. Which those are may change at any
|
||||
time (such as when the player walks into the room with the `Window` object described earlier).
|
||||
|
||||
The currently valid command sets are collected from the following sources:
|
||||
|
||||
- The cmdsets stored on the currently active [Session](./Sessions). Default is the empty
|
||||
- The cmdsets stored on the currently active [Session](./Sessions.md). Default is the empty
|
||||
`SessionCmdSet` with merge priority `-20`.
|
||||
- The cmdsets defined on the [Account](./Accounts). Default is the AccountCmdSet with merge priority
|
||||
- The cmdsets defined on the [Account](./Accounts.md). Default is the AccountCmdSet with merge priority
|
||||
`-10`.
|
||||
- All cmdsets on the Character/Object (assuming the Account is currently puppeting such a
|
||||
Character/Object). Merge priority `0`.
|
||||
|
|
@ -215,14 +215,14 @@ included if `no_objs` option is active in the merge stack.
|
|||
`no_objs` option is active in the merge stack.
|
||||
- The cmdsets of Exits in the location. Merge priority `+101`. Will not be included if `no_exits`
|
||||
*or* `no_objs` option is active in the merge stack.
|
||||
- The [channel](./Communications) cmdset containing commands for posting to all channels the account
|
||||
- The [channel](./Communications.md) cmdset containing commands for posting to all channels the account
|
||||
or character is currently connected to. Merge priority `+101`. Will not be included if `no_channels`
|
||||
option is active in the merge stack.
|
||||
|
||||
Note that an object does not *have* to share its commands with its surroundings. A Character's
|
||||
cmdsets should not be shared for example, or all other Characters would get multi-match errors just
|
||||
by being in the same room. The ability of an object to share its cmdsets is managed by its `call`
|
||||
[lock](./Locks). For example, [Character objects](./Objects) defaults to `call:false()` so that any
|
||||
[lock](./Locks.md). For example, [Character objects](./Objects.md) defaults to `call:false()` so that any
|
||||
cmdsets on them can only be accessed by themselves, not by other objects around them. Another
|
||||
example might be to lock an object with `call:inside()` to only make their commands available to
|
||||
objects inside them, or `cmd:holds()` to make their commands available only if they are held.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Command System
|
||||
|
||||
- [Commands](./Commands)
|
||||
- [Command Sets](./Command-Sets)
|
||||
- [Command Auto-help](./Help-System#command-auto-help-system)
|
||||
- [Commands](./Commands.md)
|
||||
- [Command Sets](./Command-Sets.md)
|
||||
- [Command Auto-help](./Help-System.md#command-auto-help-system)
|
||||
|
||||
See also:
|
||||
- [Default Command Help](api:evennia.commands.default#modules)
|
||||
- [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands)
|
||||
- [Default Commands](./Default-Commands.md)
|
||||
- [Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
# Commands
|
||||
|
||||
|
||||
Commands are intimately linked to [Command Sets](./Command-Sets) and you need to read that page too to
|
||||
Commands are intimately linked to [Command Sets](./Command-Sets.md) and you need to read that page too to
|
||||
be familiar with how the command system works. The two pages were split for easy reading.
|
||||
|
||||
The basic way for users to communicate with the game is through *Commands*. These can be commands
|
||||
directly related to the game world such as *look*, *get*, *drop* and so on, or administrative
|
||||
commands such as *examine* or *@dig*.
|
||||
|
||||
The [default commands](api:evennia.commands.default#modules) coming with Evennia are 'MUX-like' in that they use @
|
||||
The [default commands](./Default-Commands.md) coming with Evennia are 'MUX-like' in that they use @
|
||||
for admin commands, support things like switches, syntax with the '=' symbol etc, but there is
|
||||
nothing that prevents you from implementing a completely different command scheme for your game. You
|
||||
can find the default commands in `evennia/commands/default`. You should not edit these directly -
|
||||
they will be updated by the Evennia team as new features are added. Rather you should look to them
|
||||
for inspiration and inherit your own designs from them.
|
||||
|
||||
There are two components to having a command running - the *Command* class and the
|
||||
[Command Set](./Command-Sets) (command sets were split into a separate wiki page for ease of reading).
|
||||
There are two components to having a command running - the *Command* class and the
|
||||
[Command Set](./Command-Sets.md) (command sets were split into a separate wiki page for ease of reading).
|
||||
|
||||
1. A *Command* is a python class containing all the functioning code for what a command does - for
|
||||
example, a *get* command would contain code for picking up objects.
|
||||
|
|
@ -28,8 +28,8 @@ object in various ways. Consider a "Tree" object with a cmdset defining the comm
|
|||
*chop down*. Or a "Clock" with a cmdset containing the single command *check time*.
|
||||
|
||||
This page goes into full detail about how to use Commands. To fully use them you must also read the
|
||||
page detailing [Command Sets](./Command-Sets). There is also a step-by-step
|
||||
[Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands) that will get you started quickly without the
|
||||
page detailing [Command Sets](./Command-Sets.md). There is also a step-by-step
|
||||
[Adding Command Tutorial](../Howto/Starting/Part1/Adding-Commands.md) that will get you started quickly without the
|
||||
extra explanations.
|
||||
|
||||
## Defining Commands
|
||||
|
|
@ -81,15 +81,15 @@ In Evennia there are three types of objects that may call the command. It is im
|
|||
of this since this will also assign appropriate `caller`, `session`, `sessid` and `account`
|
||||
properties on the command body at runtime. Most often the calling type is `Session`.
|
||||
|
||||
* A [Session](./Sessions). This is by far the most common case when a user is entering a command in
|
||||
* A [Session](./Sessions.md). This is by far the most common case when a user is entering a command in
|
||||
their client.
|
||||
* `caller` - this is set to the puppeted [Object](./Objects) if such an object exists. If no
|
||||
* `caller` - this is set to the puppeted [Object](./Objects.md) if such an object exists. If no
|
||||
puppet is found, `caller` is set equal to `account`. Only if an Account is not found either (such as
|
||||
before being logged in) will this be set to the Session object itself.
|
||||
* `session` - a reference to the [Session](./Sessions) object itself.
|
||||
* `session` - a reference to the [Session](./Sessions.md) object itself.
|
||||
* `sessid` - `sessid.id`, a unique integer identifier of the session.
|
||||
* `account` - the [Account](./Accounts) object connected to this Session. None if not logged in.
|
||||
* An [Account](./Accounts). This only happens if `account.execute_cmd()` was used. No Session
|
||||
* `account` - the [Account](./Accounts.md) object connected to this Session. None if not logged in.
|
||||
* An [Account](./Accounts.md). This only happens if `account.execute_cmd()` was used. No Session
|
||||
information can be obtained in this case.
|
||||
* `caller` - this is set to the puppeted Object if such an object can be determined (without
|
||||
Session info this can only be determined in `MULTISESSION_MODE=0` or `1`). If no puppet is found,
|
||||
|
|
@ -97,7 +97,7 @@ this is equal to `account`.
|
|||
* `session` - `None*`
|
||||
* `sessid` - `None*`
|
||||
* `account` - Set to the Account object.
|
||||
* An [Object](./Objects). This only happens if `object.execute_cmd()` was used (for example by an
|
||||
* An [Object](./Objects.md). This only happens if `object.execute_cmd()` was used (for example by an
|
||||
NPC).
|
||||
* `caller` - This is set to the calling Object in question.
|
||||
* `session` - `None*`
|
||||
|
|
@ -120,10 +120,10 @@ it the following properties:
|
|||
- `caller` - The character BigGuy, in this example. This is a reference to the object executing the
|
||||
command. The value of this depends on what type of object is calling the command; see the previous
|
||||
section.
|
||||
- `session` - the [Session](./Sessions) Bob uses to connect to the game and control BigGuy (see also
|
||||
- `session` - the [Session](./Sessions.md) Bob uses to connect to the game and control BigGuy (see also
|
||||
previous section).
|
||||
- `sessid` - the unique id of `self.session`, for quick lookup.
|
||||
- `account` - the [Account](./Accounts) Bob (see previous section).
|
||||
- `account` - the [Account](./Accounts.md) Bob (see previous section).
|
||||
- `cmdstring` - the matched key for the command. This would be *look* in our example.
|
||||
- `args` - this is the rest of the string, except the command name. So if the string entered was
|
||||
*look at sword*, `args` would be " *at sword*". Note the space kept - Evennia would correctly
|
||||
|
|
@ -131,7 +131,7 @@ interpret `lookat sword` too. This is useful for things like `/switches` that sh
|
|||
In the `MuxCommand` class used for default commands, this space is stripped. Also see the
|
||||
`arg_regex` property if you want to enforce a space to make `lookat sword` give a command-not-found
|
||||
error.
|
||||
- `obj` - the game [Object](./Objects) on which this command is defined. This need not be the caller,
|
||||
- `obj` - the game [Object](./Objects.md) on which this command is defined. This need not be the caller,
|
||||
but since `look` is a common (default) command, this is probably defined directly on *BigGuy* - so
|
||||
`obj` will point to BigGuy. Otherwise `obj` could be an Account or any interactive object with
|
||||
commands defined on it, like in the example of the "check time" command defined on a "Clock" object.
|
||||
|
|
@ -143,18 +143,18 @@ for example*).
|
|||
- `raw_string` - this is the raw input coming from the user, without stripping any surrounding
|
||||
whitespace. The only thing that is stripped is the ending newline marker.
|
||||
|
||||
#### Other useful utility methods:
|
||||
#### Other useful utility methods:
|
||||
|
||||
- `.get_help(caller, cmdset)` - Get the help entry for this command. By default the arguments are
|
||||
not
|
||||
used, but they could be used to implement alternate help-display systems.
|
||||
- `.client_width()` - Shortcut for getting the client's screen-width. Note that not all clients will
|
||||
truthfully report this value - that case the `settings.DEFAULT_SCREEN_WIDTH` will be returned.
|
||||
- `.styled_table(*args, **kwargs)` - This returns an [EvTable](api:evennia.utils#module-
|
||||
- `.styled_table(*args, **kwargs)` - This returns an [EvTable](module-
|
||||
evennia.utils.evtable) styled based on the
|
||||
session calling this command. The args/kwargs are the same as for EvTable, except styling defaults
|
||||
are set.
|
||||
- `.styled_header`, `_footer`, `separator` - These will produce styled decorations for
|
||||
- `.styled_header`, `_footer`, `separator` - These will produce styled decorations for
|
||||
display to the user. They are useful for creating listings and forms with colors adjustable per-
|
||||
user.
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ key can consist of more than one word, like "press button" or "pull left lever".
|
|||
either matches. This is important for merging cmdsets described below.
|
||||
- `aliases` (optional list) - a list of alternate names for the command (`["glance", "see", "l"]`).
|
||||
Same name rules as for `key` applies.
|
||||
- `locks` (string) - a [lock definition](./Locks), usually on the form `cmd:<lockfuncs>`. Locks is a
|
||||
- `locks` (string) - a [lock definition](./Locks.md), usually on the form `cmd:<lockfuncs>`. Locks is a
|
||||
rather big topic, so until you learn more about locks, stick to giving the lockstring `"cmd:all()"`
|
||||
to make the command available to everyone (if you don't provide a lock string, this will be assigned
|
||||
for you).
|
||||
|
|
@ -181,9 +181,9 @@ by the next command by retrieving `self.caller.ndb.last_cmd`. The next run comma
|
|||
or replace the storage.
|
||||
- `arg_regex` (optional raw string): Used to force the parser to limit itself and tell it when the
|
||||
command-name ends and arguments begin (such as requiring this to be a space or a /switch). This is
|
||||
done with a regular expression. [See the arg_regex section](./Commands#on-arg_regex) for the details.
|
||||
- `auto_help` (optional boolean). Defaults to `True`. This allows for turning off the
|
||||
[auto-help system](./Help-System#command-auto-help-system) on a per-command basis. This could be useful if you
|
||||
done with a regular expression. [See the arg_regex section](./Commands.md#on-arg_regex) for the details.
|
||||
- `auto_help` (optional boolean). Defaults to `True`. This allows for turning off the
|
||||
[auto-help system](./Help-System.md#command-auto-help-system) on a per-command basis. This could be useful if you
|
||||
either want to write your help entries manually or hide the existence of a command from `help`'s
|
||||
generated list.
|
||||
- `is_exit` (bool) - this marks the command as being used for an in-game exit. This is, by default,
|
||||
|
|
@ -219,7 +219,7 @@ from this method will be returned from the execution as a Twisted Deferred.
|
|||
|
||||
Finally, you should always make an informative [doc
|
||||
string](https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring) (`__doc__`) at the top of
|
||||
your class. This string is dynamically read by the [Help System](./Help-System) to create the help
|
||||
your class. This string is dynamically read by the [Help System](./Help-System.md) to create the help
|
||||
entry for this command. You should decide on a way to format your help and stick to that.
|
||||
|
||||
Below is how you define a simple alternative "`smile`" command:
|
||||
|
|
@ -260,8 +260,8 @@ class CmdSmile(Command):
|
|||
string = f"{caller.key} smiles"
|
||||
else:
|
||||
target = caller.search(self.target)
|
||||
if not target:
|
||||
return
|
||||
if not target:
|
||||
return
|
||||
string = f"{caller.key} smiles at {target.key}"
|
||||
|
||||
caller.location.msg_contents(string)
|
||||
|
|
@ -277,7 +277,7 @@ default commands thus need to implement `parse()` at all, but can assume the
|
|||
incoming string is already split up and parsed in suitable ways by its parent.
|
||||
|
||||
Before you can actually use the command in your game, you must now store it
|
||||
within a *command set*. See the [Command Sets](./Command-Sets) page.
|
||||
within a *command set*. See the [Command Sets](./Command-Sets.md) page.
|
||||
|
||||
### On arg_regex
|
||||
|
||||
|
|
@ -428,7 +428,7 @@ will show.
|
|||
|
||||
> Note again that the `yield` keyword does not store state. If the game reloads while waiting for
|
||||
the user to answer, the user will have to start over. It is not a good idea to use `yield` for
|
||||
important or complex choices, a persistent [EvMenu](./EvMenu) might be more appropriate in this case.
|
||||
important or complex choices, a persistent [EvMenu](./EvMenu.md) might be more appropriate in this case.
|
||||
|
||||
## System commands
|
||||
|
||||
|
|
@ -458,7 +458,7 @@ display the "Huh?" error message.
|
|||
matches.
|
||||
- User is not allowed to execute the command (`syscmdkeys.CMD_NOPERM`) - Default is to display the
|
||||
"Huh?" error message.
|
||||
- Channel (`syscmdkeys.CMD_CHANNEL`) - This is a [Channel](./Communications) name of a channel you are
|
||||
- Channel (`syscmdkeys.CMD_CHANNEL`) - This is a [Channel](./Communications.md) name of a channel you are
|
||||
subscribing to - Default is to relay the command's argument to that channel. Such commands are
|
||||
created by the Comm system on the fly depending on your subscriptions.
|
||||
- New session connection (`syscmdkeys.CMD_LOGINSTART`). This command name should be put in the
|
||||
|
|
@ -485,7 +485,7 @@ work.
|
|||
|
||||
Normally Commands are created as fixed classes and used without modification. There are however
|
||||
situations when the exact key, alias or other properties is not possible (or impractical) to pre-
|
||||
code ([Exits](./Commands#Exits) is an example of this).
|
||||
code ([Exits](./Commands.md#exits) is an example of this).
|
||||
|
||||
To create a command with a dynamic call signature, first define the command body normally in a class
|
||||
(set your `key`, `aliases` to default values), then use the following call (assuming the command
|
||||
|
|
@ -509,10 +509,10 @@ make your command completely customized at run-time.
|
|||
|
||||
*Note: This is an advanced topic.*
|
||||
|
||||
Exits are examples of the use of a [Dynamic Command](./Commands#Dynamic_Commands).
|
||||
Exits are examples of the use of a [Dynamic Command](./Commands.md#dynamic-commands).
|
||||
|
||||
The functionality of [Exit](./Objects) objects in Evennia is not hard-coded in the engine. Instead
|
||||
Exits are normal [typeclassed](./Typeclasses) objects that auto-create a [CmdSet](./Commands#CmdSets) on
|
||||
The functionality of [Exit](./Objects.md) objects in Evennia is not hard-coded in the engine. Instead
|
||||
Exits are normal [typeclassed](./Typeclasses.md) objects that auto-create a [CmdSet](./Command-Sets.md) on
|
||||
themselves when they load. This cmdset has a single dynamically created Command with the same
|
||||
properties (key, aliases and locks) as the Exit object itself. When entering the name of the exit,
|
||||
this dynamic exit-command is triggered and (after access checks) moves the Character to the exit's
|
||||
|
|
@ -610,9 +610,9 @@ cmdset, ignore.
|
|||
- CmdSets defined on the current account, if caller is a puppeted object.
|
||||
- CmdSets defined on the Session itself.
|
||||
- The active CmdSets of eventual objects in the same location (if any). This includes commands
|
||||
on [Exits](./Objects#Exits).
|
||||
on [Exits](./Objects.md#exits).
|
||||
- Sets of dynamically created *System commands* representing available
|
||||
[Communications](./Communications#Channels).
|
||||
[Communications](./Channels.md)
|
||||
7. All CmdSets *of the same priority* are merged together in groups. Grouping avoids order-
|
||||
dependent issues of merging multiple same-prio sets onto lower ones.
|
||||
8. All the grouped CmdSets are *merged* in reverse priority into one combined CmdSet according to
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
TODO: Remove this page?
|
||||
|
||||
- [Channels](./Channels) - are used for implementing in-game chat rooms.
|
||||
- [Msg](./Msg)-objects are used for storing messages in the database (email-like)
|
||||
- [Channels](./Channels.md) - are used for implementing in-game chat rooms.
|
||||
- [Msg](./Msg.md)-objects are used for storing messages in the database (email-like)
|
||||
and is a building block for implementing other game systems. It's used by the
|
||||
`page` command by default.
|
||||
|
|
|
|||
|
|
@ -1,54 +1,54 @@
|
|||
# Core Components
|
||||
|
||||
These are the 'building blocks' out of which Evennia is built. This documentation is complementary to, and often goes deeper
|
||||
than, the doc-strings of each component in the [API](../Evennia-API).
|
||||
than, the doc-strings of each component in the [API](../Evennia-API.md).
|
||||
|
||||
## Database entites
|
||||
## Database entites
|
||||
|
||||
- [Typeclasses](./Typeclasses)
|
||||
- [Sessions](./Sessions)
|
||||
- [Acccounts](./Accounts)
|
||||
- [Guests](../Concepts/Guest-Logins)
|
||||
- [Objects](./Objects)
|
||||
- [Scripts](./Scripts)
|
||||
- [Channels and Messages](./Communications)
|
||||
- [Attributes](./Attributes)
|
||||
- [Nicks](./Nicks)
|
||||
- [Tags](./Tags)
|
||||
- [Spawner and prototypes](./Prototypes)
|
||||
- [Help entries](./Help-System)
|
||||
- [Typeclasses](./Typeclasses.md)
|
||||
- [Sessions](./Sessions.md)
|
||||
- [Acccounts](./Accounts.md)
|
||||
- [Guests](../Concepts/Guest-Logins.md)
|
||||
- [Objects](./Objects.md)
|
||||
- [Scripts](./Scripts.md)
|
||||
- [Channels and Messages](./Communications.md)
|
||||
- [Attributes](./Attributes.md)
|
||||
- [Nicks](./Nicks.md)
|
||||
- [Tags](./Tags.md)
|
||||
- [Spawner and prototypes](./Prototypes.md)
|
||||
- [Help entries](./Help-System.md)
|
||||
|
||||
## Commands
|
||||
## Commands
|
||||
|
||||
- [Command system](./Command-System)
|
||||
- [Commands](./Commands)
|
||||
- [Command-Sets](./Command-Sets)
|
||||
- [The Connection Screen](./Connection-Screen)
|
||||
- [Available default Commands](api:evennia.commands.default#modules)
|
||||
- [Batch-Processors](./Batch-Processors)
|
||||
- [Batch-Code-Processor](./Batch-Code-Processor)
|
||||
- [Batch-Command-Processor](./Batch-Command-Processor)
|
||||
- [Available Default Commands](./Default-Commands.md)
|
||||
- [Command system](./Command-System.md)
|
||||
- [Commands](./Commands.md)
|
||||
- [Command-Sets](./Command-Sets.md)
|
||||
- [The Connection Screen](./Connection-Screen.md)
|
||||
- [Batch-Processors](./Batch-Processors.md)
|
||||
- [Batch-Code-Processor](./Batch-Code-Processor.md)
|
||||
- [Batch-Command-Processor](./Batch-Command-Processor.md)
|
||||
|
||||
## Utils and tools
|
||||
|
||||
- [Misc Utils](./Coding-Utils)
|
||||
- [EvEditor](./EvEditor)
|
||||
- [EvMenu](./EvMenu)
|
||||
- [EvMore](./EvMore)
|
||||
- [MonitorHandler](./MonitorHandler)
|
||||
- [TickerHandler](./TickerHandler)
|
||||
- [Lock system](./Locks)
|
||||
- [FuncParser](./FuncParser)
|
||||
- [Misc Utils](./Coding-Utils.md)
|
||||
- [EvEditor](./EvEditor.md)
|
||||
- [EvMenu](./EvMenu.md)
|
||||
- [EvMore](./EvMore.md)
|
||||
- [MonitorHandler](./MonitorHandler.md)
|
||||
- [TickerHandler](./TickerHandler.md)
|
||||
- [Lock system](./Locks.md)
|
||||
- [FuncParser](./FuncParser.md)
|
||||
|
||||
## Server and network
|
||||
|
||||
- [Portal](./Portal-And-Server)
|
||||
- [Inputfuncs](./Inputfuncs)
|
||||
- [Outputfuncs](./Outputfuncs)
|
||||
- [Protocols](../Concepts/Custom-Protocols)
|
||||
- [Server](./Server)
|
||||
- [Server conf object](./Server-Conf)
|
||||
- [Webserver](./Webserver)
|
||||
- [Webclient](./Webclient)
|
||||
- [Bootstrap](./Bootstrap-Components-and-Utilities)
|
||||
- [Signals](./Signals)
|
||||
- [Portal](./Portal-And-Server.md)
|
||||
- [Inputfuncs](./Inputfuncs.md)
|
||||
- [Outputfuncs](./Outputfuncs.md)
|
||||
- [Protocols](../Concepts/Custom-Protocols.md)
|
||||
- [Server](./Server.md)
|
||||
- [Server conf object](../Setup/Server-Conf.md)
|
||||
- [Webserver](./Webserver.md)
|
||||
- [Webclient](./Webclient.md)
|
||||
- [Bootstrap](./Bootstrap-Components-and-Utilities.md)
|
||||
- [Signals](./Signals.md)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
# Connection Screen
|
||||
|
||||
|
||||
When you first connect to your game you are greeted by Evennia's default connection screen.
|
||||
When you first connect to your game you are greeted by Evennia's default connection screen.
|
||||
|
||||
|
||||
|
||||
==============================================================
|
||||
Welcome to Evennia, version Beta-ra4d24e8a3cab+!
|
||||
|
||||
|
||||
If you have an existing account, connect to it by typing:
|
||||
connect <username> <password>
|
||||
If you need to create an account, type (without the <>'s):
|
||||
create <username> <password>
|
||||
|
||||
|
||||
If you have spaces in your username, enclose it in quotes.
|
||||
Enter help for more info. look will re-show this screen.
|
||||
==============================================================
|
||||
|
|
@ -20,17 +20,17 @@ Effective, but not very exciting. You will most likely want to change this to be
|
|||
your game. This is simple:
|
||||
|
||||
1. Edit `mygame/server/conf/connection_screens.py`.
|
||||
1. [Reload](../Setup/Start-Stop-Reload) Evennia.
|
||||
1. [Reload](../Setup/Start-Stop-Reload.md) Evennia.
|
||||
|
||||
Evennia will look into this module and locate all *globally defined strings* in it. These strings
|
||||
are used as the text in your connection screen and are shown to the user at startup. If more than
|
||||
one such string/screen is defined in the module, a *random* screen will be picked from among those
|
||||
available.
|
||||
|
||||
### Commands available at the Connection Screen
|
||||
## Commands available at the Connection Screen
|
||||
|
||||
You can also customize the [Commands](./Commands) available to use while the connection screen is
|
||||
You can also customize the [Commands](./Commands.md) available to use while the connection screen is
|
||||
shown (`connect`, `create` etc). These commands are a bit special since when the screen is running
|
||||
the account is not yet logged in. A command is made available at the login screen by adding them to
|
||||
`UnloggedinCmdSet` in `mygame/commands/default_cmdset.py`. See [Commands](./Commands) and the
|
||||
tutorial section on how to add new commands to a default command set.
|
||||
`UnloggedinCmdSet` in `mygame/commands/default_cmdset.py`. See [Commands](./Commands.md) and the
|
||||
tutorial section on how to add new commands to a default command set.
|
||||
|
|
|
|||
106
docs/1.0-dev/_sources/Components/Default-Commands.md.txt
Normal file
106
docs/1.0-dev/_sources/Components/Default-Commands.md.txt
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
|
||||
# Default Commands
|
||||
|
||||
The full set of default Evennia commands currently contains 97 commands in 9 source
|
||||
files. Our policy for adding default commands is outlined [here](../Concepts/Using-MUX-as-a-Standard.md). The
|
||||
[Commands](./Commands.md) documentation explains how Commands work as well as make new or customize
|
||||
existing ones. Note that this page is auto-generated. Report problems to the [issue
|
||||
tracker](github:issues).
|
||||
|
||||
```{note}
|
||||
Some game-states adds their own Commands which are not listed here. Examples include editing a text
|
||||
with [EvEditor](./EvEditor.md), flipping pages in [EvMore](./EvMore.md) or using the
|
||||
[Batch-Processor](./Batch-Processors.md)'s interactive mode.
|
||||
```
|
||||
|
||||
- [**__unloggedin_look_command** [l, look]](evennia.commands.default.unloggedin.CmdUnconnectedLook) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**about** [version]](evennia.commands.default.system.CmdAbout) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**access** [groups, hierarchy]](evennia.commands.default.general.CmdAccess) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**accounts** [listaccounts, account]](evennia.commands.default.system.CmdAccounts) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**addcom** [chanalias, aliaschan]](evennia.commands.default.comms.CmdAddCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**alias** [setobjalias]](evennia.commands.default.building.CmdSetObjAlias) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**allcom**](evennia.commands.default.comms.CmdAllCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**batchcode** [batchcodes]](evennia.commands.default.batchprocess.CmdBatchCode) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**batchcommands** [batchcmd, batchcommand]](evennia.commands.default.batchprocess.CmdBatchCommands) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**cboot**](evennia.commands.default.comms.CmdCBoot) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**ccreate** [channelcreate]](evennia.commands.default.comms.CmdChannelCreate) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**cdesc**](evennia.commands.default.comms.CmdCdesc) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**cdestroy**](evennia.commands.default.comms.CmdCdestroy) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**channel** [chan, channels]](evennia.commands.default.comms.CmdChannel) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**charcreate**](evennia.commands.default.account.CmdCharCreate) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**chardelete**](evennia.commands.default.account.CmdCharDelete) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**clock**](evennia.commands.default.comms.CmdClock) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**cmdsets** [listcmsets]](evennia.commands.default.building.CmdListCmdSets) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**color**](evennia.commands.default.account.CmdColorTest) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**connect** [conn, co, con]](evennia.commands.default.unloggedin.CmdUnconnectedConnect) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**copy**](evennia.commands.default.building.CmdCopy) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**cpattr**](evennia.commands.default.building.CmdCpAttr) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**create**](evennia.commands.default.building.CmdCreate) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**create** [cr, cre]](evennia.commands.default.unloggedin.CmdUnconnectedCreate) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**cwho**](evennia.commands.default.comms.CmdCWho) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**delcom** [delchanalias, delaliaschan]](evennia.commands.default.comms.CmdDelCom) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**desc** [describe]](evennia.commands.default.building.CmdDesc) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**destroy** [del, delete]](evennia.commands.default.building.CmdDestroy) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**dig**](evennia.commands.default.building.CmdDig) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**drop**](evennia.commands.default.general.CmdDrop) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**encoding** [encode]](evennia.commands.default.unloggedin.CmdUnconnectedEncoding) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**examine** [ex, exam]](evennia.commands.default.building.CmdExamine) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Building_)
|
||||
- [**find** [locate, search]](evennia.commands.default.building.CmdFind) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**get** [grab]](evennia.commands.default.general.CmdGet) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**give**](evennia.commands.default.general.CmdGive) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**grapevine2chan**](evennia.commands.default.comms.CmdGrapevine2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**help** [?]](evennia.commands.default.help.CmdHelp) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**help** [h, ?]](evennia.commands.default.unloggedin.CmdUnconnectedHelp) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**home**](evennia.commands.default.general.CmdHome) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**ic** [puppet]](evennia.commands.default.account.CmdIC) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**info**](evennia.commands.default.unloggedin.CmdUnconnectedInfo) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**inventory** [i, inv]](evennia.commands.default.general.CmdInventory) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**irc2chan**](evennia.commands.default.comms.CmdIRC2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**ircstatus**](evennia.commands.default.comms.CmdIRCStatus) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**link**](evennia.commands.default.building.CmdLink) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**lock** [locks]](evennia.commands.default.building.CmdLock) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**look** [ls, l]](evennia.commands.default.account.CmdOOCLook) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**look** [ls, l]](evennia.commands.default.general.CmdLook) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**mvattr**](evennia.commands.default.building.CmdMvAttr) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**name** [rename]](evennia.commands.default.building.CmdName) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**nick** [nickname, nicks]](evennia.commands.default.general.CmdNick) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**objects** [listobjs, listobjects, db, stats]](evennia.commands.default.building.CmdObjects) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**ooc** [unpuppet]](evennia.commands.default.account.CmdOOC) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**open**](evennia.commands.default.building.CmdOpen) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**option** [options]](evennia.commands.default.account.CmdOption) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**page** [tell]](evennia.commands.default.comms.CmdPage) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**password**](evennia.commands.default.account.CmdPassword) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**pose** [:, emote]](evennia.commands.default.general.CmdPose) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**py** [!]](evennia.commands.default.system.CmdPy) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_)
|
||||
- [**quell** [unquell]](evennia.commands.default.account.CmdQuell) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**quit**](evennia.commands.default.account.CmdQuit) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**quit** [qu, q]](evennia.commands.default.unloggedin.CmdUnconnectedQuit) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**reload** [restart]](evennia.commands.default.system.CmdReload) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_)
|
||||
- [**reset** [reboot]](evennia.commands.default.system.CmdReset) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_)
|
||||
- [**rss2chan**](evennia.commands.default.comms.CmdRSS2Chan) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _Comms_)
|
||||
- [**say** [", ']](evennia.commands.default.general.CmdSay) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**screenreader**](evennia.commands.default.unloggedin.CmdUnconnectedScreenreader) (cmdset: [UnloggedinCmdSet](evennia.commands.default.cmdset_unloggedin.UnloggedinCmdSet), help-category: _General_)
|
||||
- [**scripts** [script]](evennia.commands.default.building.CmdScripts) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**server** [serverload, serverprocess]](evennia.commands.default.system.CmdServerLoad) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**service** [services]](evennia.commands.default.system.CmdService) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**sessions**](evennia.commands.default.account.CmdSessions) (cmdset: [SessionCmdSet](evennia.commands.default.cmdset_session.SessionCmdSet), help-category: _General_)
|
||||
- [**set**](evennia.commands.default.building.CmdSetAttribute) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**setdesc**](evennia.commands.default.general.CmdSetDesc) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**sethelp**](evennia.commands.default.help.CmdSetHelp) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**sethome**](evennia.commands.default.building.CmdSetHome) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**shutdown**](evennia.commands.default.system.CmdShutdown) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _System_)
|
||||
- [**spawn** [olc]](evennia.commands.default.building.CmdSpawn) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**style**](evennia.commands.default.account.CmdStyle) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**tag** [tags]](evennia.commands.default.building.CmdTag) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**tasks** [task, delays]](evennia.commands.default.system.CmdTasks) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**tel** [teleport]](evennia.commands.default.building.CmdTeleport) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**tickers**](evennia.commands.default.system.CmdTickers) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**time** [uptime]](evennia.commands.default.system.CmdTime) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _System_)
|
||||
- [**tunnel** [tun]](evennia.commands.default.building.CmdTunnel) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**typeclass** [swap, type, update, typeclasses, parent]](evennia.commands.default.building.CmdTypeclass) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**unlink**](evennia.commands.default.building.CmdUnLink) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
- [**whisper**](evennia.commands.default.general.CmdWhisper) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _General_)
|
||||
- [**who** [doing]](evennia.commands.default.account.CmdWho) (cmdset: [AccountCmdSet](evennia.commands.default.cmdset_account.AccountCmdSet), help-category: _General_)
|
||||
- [**wipe**](evennia.commands.default.building.CmdWipe) (cmdset: [CharacterCmdSet](evennia.commands.default.cmdset_character.CharacterCmdSet), help-category: _Building_)
|
||||
|
||||
|
|
@ -5,15 +5,15 @@ Evennia offers a powerful in-game line editor in `evennia.utils.eveditor.EvEdito
|
|||
mimicking the well-known VI line editor. It offers line-by-line editing, undo/redo, line deletes,
|
||||
search/replace, fill, dedent and more.
|
||||
|
||||
### Launching the editor
|
||||
## Launching the editor
|
||||
|
||||
The editor is created as follows:
|
||||
The editor is created as follows:
|
||||
|
||||
```python
|
||||
from evennia.utils.eveditor import EvEditor
|
||||
|
||||
EvEditor(caller,
|
||||
loadfunc=None, savefunc=None, quitfunc=None,
|
||||
EvEditor(caller,
|
||||
loadfunc=None, savefunc=None, quitfunc=None,
|
||||
key="")
|
||||
```
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ cleanup and exit messages to the user must be handled by this function.
|
|||
It has no other mechanical function.
|
||||
- `persistent` (default `False`): if set to `True`, the editor will survive a reboot.
|
||||
|
||||
### Example of usage
|
||||
## Example of usage
|
||||
|
||||
This is an example command for setting a specific Attribute using the editor.
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ from evennia.utils import eveditor
|
|||
|
||||
class CmdSetTestAttr(Command):
|
||||
"""
|
||||
Set the "test" Attribute using
|
||||
Set the "test" Attribute using
|
||||
the line editor.
|
||||
|
||||
Usage:
|
||||
|
|
@ -60,12 +60,12 @@ class CmdSetTestAttr(Command):
|
|||
caller.msg("Editor exited")
|
||||
key = f"{self.caller}/test"
|
||||
# launch the editor
|
||||
eveditor.EvEditor(self.caller,
|
||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||
key=key)
|
||||
eveditor.EvEditor(self.caller,
|
||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||
key=key)
|
||||
```
|
||||
|
||||
### Persistent editor
|
||||
## Persistent editor
|
||||
|
||||
If you set the `persistent` keyword to `True` when creating the editor, it will remain open even
|
||||
when reloading the game. In order to be persistent, an editor needs to have its callback functions
|
||||
|
|
@ -90,7 +90,7 @@ def quit(caller):
|
|||
|
||||
class CmdSetTestAttr(Command):
|
||||
"""
|
||||
Set the "test" Attribute using
|
||||
Set the "test" Attribute using
|
||||
the line editor.
|
||||
|
||||
Usage:
|
||||
|
|
@ -102,12 +102,12 @@ class CmdSetTestAttr(Command):
|
|||
"Set up the callbacks and launch the editor"
|
||||
key = f"{self.caller}/test"
|
||||
# launch the editor
|
||||
eveditor.EvEditor(self.caller,
|
||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||
key=key, persistent=True)
|
||||
eveditor.EvEditor(self.caller,
|
||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||
key=key, persistent=True)
|
||||
```
|
||||
|
||||
### Line editor usage
|
||||
## Line editor usage
|
||||
|
||||
The editor mimics the `VIM` editor as best as possible. The below is an excerpt of the return from
|
||||
the in-editor help command (`:h`).
|
||||
|
|
@ -154,7 +154,7 @@ the in-editor help command (`:h`).
|
|||
<txt> - longer string, usually not needed to be enclosed in quotes.
|
||||
```
|
||||
|
||||
### The EvEditor to edit code
|
||||
## The EvEditor to edit code
|
||||
|
||||
The `EvEditor` is also used to edit some Python code in Evennia. The `@py` command supports an
|
||||
`/edit` switch that will open the EvEditor in code mode. This mode isn't significantly different
|
||||
|
|
@ -178,4 +178,4 @@ to paste several lines of code that are already correctly indented, for instance
|
|||
To see the EvEditor in code mode, you can use the `@py/edit` command. Type in your code (on one or
|
||||
several lines). You can then use the `:w` option (save without quitting) and the code you have
|
||||
typed will be executed. The `:!` will do the same thing. Executing code while not closing the
|
||||
editor can be useful if you want to test the code you have typed but add new lines after your test.
|
||||
editor can be useful if you want to test the code you have typed but add new lines after your test.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ said functions, like `{"nodename": <function>, ...}`
|
|||
## Launching the menu
|
||||
|
||||
Initializing the menu is done using a call to the `evennia.utils.evmenu.EvMenu` class. This is the
|
||||
most common way to do so - from inside a [Command](./Commands):
|
||||
most common way to do so - from inside a [Command](./Commands.md):
|
||||
|
||||
```python
|
||||
# in, for example gamedir/commands/command.py
|
||||
|
|
@ -70,7 +70,7 @@ EvMenu(caller, menu_data,
|
|||
```
|
||||
|
||||
- `caller` (Object or Account): is a reference to the object using the menu. This object will get a
|
||||
new [CmdSet](./Command-Sets) assigned to it, for handling the menu.
|
||||
new [CmdSet](./Command-Sets.md) assigned to it, for handling the menu.
|
||||
- `menu_data` (str, module or dict): is a module or python path to a module where the global-level
|
||||
functions will each be considered to be a menu node. Their names in the module will be the names
|
||||
by which they are referred to in the module. Importantly, function names starting with an
|
||||
|
|
@ -107,7 +107,7 @@ after
|
|||
- `startnode_input` (str or (str, dict) tuple): Pass an input text or a input text + kwargs to the
|
||||
start node as if it was entered on a fictional previous node. This can be very useful in order to
|
||||
start a menu differently depending on the Command's arguments in which it was initialized.
|
||||
- `session` (Session): Useful when calling the menu from an [Account](./Accounts) in
|
||||
- `session` (Session): Useful when calling the menu from an [Account](./Accounts.md) in
|
||||
`MULTISESSION_MODDE` higher than 2, to make sure only the right Session sees the menu output.
|
||||
- `debug` (bool): If set, the `menudebug` command will be made available in the menu. Use it to
|
||||
list the current state of the menu and use `menudebug <variable>` to inspect a specific state
|
||||
|
|
@ -428,16 +428,15 @@ See `evennia/utils/evmenu.py` for the details of their default implementations.
|
|||
|
||||
## Examples:
|
||||
|
||||
- **[Simple branching menu](./EvMenu#example-simple-branching-menu)** - choose from options
|
||||
- **[Dynamic goto](./EvMenu#example-dynamic-goto)** - jumping to different nodes based on response
|
||||
- **[Set caller properties](./EvMenu#example-set-caller-properties)** - a menu that changes things
|
||||
- **[Getting arbitrary input](./EvMenu#example-get-arbitrary-input)** - entering text
|
||||
- **[Storing data between nodes](./EvMenu#example-storing-data-between-nodes)** - keeping states and
|
||||
- **[Simple branching menu](./EvMenu.md#example-simple-branching-menu)** - choose from options
|
||||
- **[Dynamic goto](./EvMenu.md#example-dynamic-goto)** - jumping to different nodes based on response
|
||||
- **[Set caller properties](./EvMenu.md#example-set-caller-properties)** - a menu that changes things
|
||||
- **[Getting arbitrary input](./EvMenu.md#example-get-arbitrary-input)** - entering text
|
||||
- **[Storing data between nodes](./EvMenu.md#example-storing-data-between-nodes)** - keeping states and
|
||||
information while in the menu
|
||||
- **[Repeating the same node](./EvMenu#example-repeating-the-same-node)** - validating within the node
|
||||
- **[Repeating the same node](./EvMenu.md#example-repeating-the-same-node)** - validating within the node
|
||||
before moving to the next
|
||||
- **[Full Menu](./EvMenu#example-full-menu):** a complete example
|
||||
- **[Yes/No prompt](./EvMenu#example-yesno-prompt)** - entering text with limited possible responses
|
||||
- **[Yes/No prompt](#example-yesno-prompt)** - entering text with limited possible responses
|
||||
(this is *not* using EvMenu but the conceptually similar yet technically unrelated `get_input`
|
||||
helper function accessed as `evennia.utils.evmenu.get_input`).
|
||||
|
||||
|
|
@ -507,7 +506,7 @@ def enter_guild:
|
|||
|
||||
This simple callable goto will analyse what happens depending on who the `caller` is. The
|
||||
`enter_guild` node will give you a choice of what to say to the guard. If you try to enter, you will
|
||||
end up in different nodes depending on (in this example) if you have the right [Tag](./Tags) set on
|
||||
end up in different nodes depending on (in this example) if you have the right [Tag](./Tags.md) set on
|
||||
yourself or not. Note that since we don't include any 'key's in the option dictionary, you will just
|
||||
get to pick between numbers.
|
||||
|
||||
|
|
@ -805,7 +804,7 @@ function - for example you can't use other Python keywords like `if` inside the
|
|||
|
||||
Unless you are dealing with a relatively simple dynamic menu, defining menus with lambda's is
|
||||
probably more work than it's worth: You can create dynamic menus by instead making each node
|
||||
function more clever. See the [NPC shop tutorial](../Howto/NPC-shop-Tutorial) for an example of this.
|
||||
function more clever. See the [NPC shop tutorial](../Howto/NPC-shop-Tutorial.md) for an example of this.
|
||||
|
||||
|
||||
## Ask for simple input
|
||||
|
|
@ -906,7 +905,7 @@ return True from the callback to repeat the prompt until you pass whatever check
|
|||
|
||||
> Note: You *cannot* link consecutive questions by putting a new `get_input` call inside the
|
||||
> callback If you want that you should use an EvMenu instead (see the [Repeating the same
|
||||
> node](EvMenu#example-repeating-the-same-node) example above). Otherwise you can either peek at the
|
||||
> node](./EvMenu.md#example-repeating-the-same-node) example above). Otherwise you can either peek at the
|
||||
> implementation of `get_input` and implement your own mechanism (it's just using cmdset nesting) or
|
||||
> you can look at [this extension suggested on the mailing
|
||||
> list](https://groups.google.com/forum/#!category-topic/evennia/evennia-questions/16pi0SfMO5U).
|
||||
|
|
@ -993,9 +992,9 @@ auto-created by the `list_node` decorator.
|
|||
|
||||
## Assorted notes
|
||||
|
||||
The EvMenu is implemented using [Commands](./Commands). When you start a new EvMenu, the user of the
|
||||
menu will be assigned a [CmdSet](./Command-Sets) with the commands they need to navigate the menu.
|
||||
The EvMenu is implemented using [Commands](./Commands.md). When you start a new EvMenu, the user of the
|
||||
menu will be assigned a [CmdSet](./Command-Sets.md) with the commands they need to navigate the menu.
|
||||
This means that if you were to, from inside the menu, assign a new command set to the caller, *you
|
||||
may override the Menu Cmdset and kill the menu*. If you want to assign cmdsets to the caller as part
|
||||
of the menu, you should store the cmdset on `caller.ndb._menutree` and wait to actually assign it
|
||||
until the exit node.
|
||||
until the exit node.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ page of text at a time. It is usually used via its access function, `evmore.msg`
|
|||
|
||||
The name comes from the famous unix pager utility *more* which performs just this function.
|
||||
|
||||
### Using EvMore
|
||||
## Using EvMore
|
||||
|
||||
To use the pager, just pass the long text through it:
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ from evennia.utils import evmore
|
|||
|
||||
evmore.msg(receiver, long_text)
|
||||
```
|
||||
Where receiver is an [Object](./Objects) or a [Account](./Accounts). If the text is longer than the
|
||||
Where receiver is an [Object](./Objects.md) or a [Account](./Accounts.md). If the text is longer than the
|
||||
client's screen height (as determined by the NAWS handshake or by `settings.CLIENT_DEFAULT_HEIGHT`)
|
||||
the pager will show up, something like this:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
# The Inline Function Parser
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
The [FuncParser](api:evennia.utils.funcparser#evennia.utils.funcparser.FuncParser) extracts and executes
|
||||
The [FuncParser](evennia.utils.funcparser.FuncParser) extracts and executes
|
||||
'inline functions'
|
||||
embedded in a string on the form `$funcname(args, kwargs)`. Under the hood, this will
|
||||
lead to a call to a Python function you control. The inline function call will be replaced by
|
||||
embedded in a string on the form `$funcname(args, kwargs)`. Under the hood, this will
|
||||
lead to a call to a Python function you control. The inline function call will be replaced by
|
||||
the return from the function.
|
||||
|
||||
```python
|
||||
```python
|
||||
from evennia.utils.funcparser import FuncParser
|
||||
|
||||
def _power_callable(*args, **kwargs):
|
||||
|
|
@ -48,72 +44,72 @@ parser.parse("This is an escaped $$pow(4) and so is this \$pow(3)")
|
|||
The FuncParser can be applied to any string. Out of the box it's applied in a few situations:
|
||||
|
||||
- _Outgoing messages_. All messages sent from the server is processed through FuncParser and every
|
||||
callable is provided the [Session](./Sessions) of the object receiving the message. This potentially
|
||||
callable is provided the [Session](./Sessions.md) of the object receiving the message. This potentially
|
||||
allows a message to be modified on the fly to look different for different recipients.
|
||||
- _Prototype values_. A [Prototype](./Prototypes) dict's values are run through the parser such that every
|
||||
- _Prototype values_. A [Prototype](./Prototypes.md) dict's values are run through the parser such that every
|
||||
callable gets a reference to the rest of the prototype. In the Prototype ORM, this would allow builders
|
||||
to safely call functions to set non-string values to prototype values, get random values, reference
|
||||
other fields of the prototype, and more.
|
||||
- _Actor-stance in messages to others_. In the
|
||||
[Object.msg_contents](api:evennia.objects.objects#DefaultObject.msg_contents) method,
|
||||
[Object.msg_contents](evennia.objects.objects.DefaultObject.msg_contents) method,
|
||||
the outgoing string is parsed for special `$You()` and `$conj()` callables to decide if a given recipient
|
||||
should see "You" or the character's name.
|
||||
|
||||
```important::
|
||||
```{important}
|
||||
The inline-function parser is not intended as a 'softcode' programming language. It does not
|
||||
have things like loops and conditionals, for example. While you could in principle extend it to
|
||||
do very advanced things and allow builders a lot of power, all-out coding is something
|
||||
have things like loops and conditionals, for example. While you could in principle extend it to
|
||||
do very advanced things and allow builders a lot of power, all-out coding is something
|
||||
Evennia expects you to do in a proper text editor, outside of the game, not from inside it.
|
||||
```
|
||||
|
||||
## Using the FuncParser
|
||||
|
||||
You can apply inline function parsing to any string. The
|
||||
[FuncParser](api:evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`.
|
||||
## Using the FuncParser
|
||||
|
||||
You can apply inline function parsing to any string. The
|
||||
[FuncParser](evennia.utils.funcparser.FuncParser) is imported as `evennia.utils.funcparser`.
|
||||
|
||||
```python
|
||||
from evennia.utils import funcparser
|
||||
|
||||
parser = FuncParser(callables, **default_kwargs)
|
||||
parsed_string = parser.parser(input_string, raise_errors=False,
|
||||
escape=False, strip=False,
|
||||
parsed_string = parser.parser(input_string, raise_errors=False,
|
||||
escape=False, strip=False,
|
||||
return_str=True, **reserved_kwargs)
|
||||
|
||||
# callables can also be passed as paths to modules
|
||||
parser = FuncParser(["game.myfuncparser_callables", "game.more_funcparser_callables"])
|
||||
```
|
||||
|
||||
Here, `callables` points to a collection of normal Python functions (see next section) for you to make
|
||||
Here, `callables` points to a collection of normal Python functions (see next section) for you to make
|
||||
available to the parser as you parse strings with it. It can either be
|
||||
- A `dict` of `{"functionname": callable, ...}`. This allows you do pick and choose exactly which callables
|
||||
to include and how they should be named. Do you want a callable to be available under more than one name?
|
||||
Just add it multiple times to the dict, with a different key.
|
||||
- A `module` or (more commonly) a `python-path` to a module. This module can define a dict
|
||||
- A `module` or (more commonly) a `python-path` to a module. This module can define a dict
|
||||
`FUNCPARSER_CALLABLES = {"funcname": callable, ...}` - this will be imported and used like the `dict` above.
|
||||
If no such variable is defined, _every_ top-level function in the module (whose name doesn't start with
|
||||
an underscore `_`) will be considered a suitable callable. The name of the function will be the `$funcname`
|
||||
If no such variable is defined, _every_ top-level function in the module (whose name doesn't start with
|
||||
an underscore `_`) will be considered a suitable callable. The name of the function will be the `$funcname`
|
||||
by which it can be called.
|
||||
- A `list` of modules/paths. This allows you to pull in modules from many sources for your parsing.
|
||||
|
||||
|
||||
The other arguments to the parser:
|
||||
|
||||
- `raise_errors` - By default, any errors from a callable will be quietly ignored and the result
|
||||
will be that the failing function call will show verbatim. If `raise_errors` is set,
|
||||
then parsing will stop and whatever exception happened will be raised. It'd be up to you to handle
|
||||
- `raise_errors` - By default, any errors from a callable will be quietly ignored and the result
|
||||
will be that the failing function call will show verbatim. If `raise_errors` is set,
|
||||
then parsing will stop and whatever exception happened will be raised. It'd be up to you to handle
|
||||
this properly.
|
||||
- `escape` - Returns a string where every `$func(...)` has been escaped as `\$func()`.
|
||||
- `strip` - Remove all `$func(...)` calls from string (as if each returned `''`).
|
||||
- `return_str` - When `True` (default), `parser` always returns a string. If `False`, it may return
|
||||
the return value of a single function call in the string. This is the same as using the `.parse_to_any`
|
||||
- `return_str` - When `True` (default), `parser` always returns a string. If `False`, it may return
|
||||
the return value of a single function call in the string. This is the same as using the `.parse_to_any`
|
||||
method.
|
||||
- The `**default/reserved_keywords` are optional and allow you to pass custom data into _every_ function
|
||||
call. This is great for including things like the current session or config options. Defaults can be
|
||||
replaced if the user gives the same-named kwarg in the string's function call. Reserved kwargs are always passed,
|
||||
ignoring defaults or what the user passed. In addition, the `funcparser` and `raise_errors`
|
||||
ignoring defaults or what the user passed. In addition, the `funcparser` and `raise_errors`
|
||||
reserved kwargs are always passed - the first is a back-reference to the `FuncParser` instance and the second
|
||||
is the `raise_errors` boolean passed into `FuncParser.parse`.
|
||||
|
||||
Here's an example of using the default/reserved keywords:
|
||||
|
||||
Here's an example of using the default/reserved keywords:
|
||||
|
||||
```python
|
||||
def _test(*args, **kwargs):
|
||||
|
|
@ -123,15 +119,15 @@ def _test(*args, **kwargs):
|
|||
parser = funcparser.FuncParser({"test": _test}, mydefault=2)
|
||||
result = parser.parse("$test(foo, bar=4)", myreserved=[1, 2, 3])
|
||||
```
|
||||
Here the callable will be called as
|
||||
Here the callable will be called as
|
||||
|
||||
```python
|
||||
_test('foo', bar='4', mydefault=2, myreserved=[1, 2, 3],
|
||||
funcparser=<FuncParser>, raise_errors=False)
|
||||
_test('foo', bar='4', mydefault=2, myreserved=[1, 2, 3],
|
||||
funcparser=<FuncParser>, raise_errors=False)
|
||||
```
|
||||
|
||||
The `mydefault=2` kwarg could be overwritten if we made the call as `$test(mydefault=...)`
|
||||
but `myreserved=[1, 2, 3]` will _always_ be sent as-is and will override a call `$test(myreserved=...)`.
|
||||
The `mydefault=2` kwarg could be overwritten if we made the call as `$test(mydefault=...)`
|
||||
but `myreserved=[1, 2, 3]` will _always_ be sent as-is and will override a call `$test(myreserved=...)`.
|
||||
The `funcparser`/`raise_errors` kwargs are also always included as reserved kwargs.
|
||||
|
||||
## Defining custom callables
|
||||
|
|
@ -144,44 +140,44 @@ def funcname(*args, **kwargs):
|
|||
return something
|
||||
```
|
||||
|
||||
> The `*args` and `**kwargs` must always be included. If you are unsure how `*args` and `**kwargs` work in Python,
|
||||
> The `*args` and `**kwargs` must always be included. If you are unsure how `*args` and `**kwargs` work in Python,
|
||||
> [read about them here](https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3).
|
||||
|
||||
The input from the innermost `$funcname(...)` call in your callable will always be a `str`. Here's
|
||||
The input from the innermost `$funcname(...)` call in your callable will always be a `str`. Here's
|
||||
an example of an `$toint` function; it converts numbers to integers.
|
||||
|
||||
"There's a $toint(22.0)% chance of survival."
|
||||
|
||||
What will enter the `$toint` callable (as `args[0]`) is the _string_ `"22.0"`. The function is responsible
|
||||
for converting this to a number so that we can convert it to an integer. We must also properly handle invalid
|
||||
for converting this to a number so that we can convert it to an integer. We must also properly handle invalid
|
||||
inputs (like non-numbers).
|
||||
|
||||
If you want to mark an error, raise `evennia.utils.funcparser.ParsingError`. This stops the entire parsing
|
||||
of the string and may or may not raise the exception depending on what you set `raise_errors` to when you
|
||||
of the string and may or may not raise the exception depending on what you set `raise_errors` to when you
|
||||
created the parser.
|
||||
|
||||
However, if you _nest_ functions, the return of the innermost function may be something other than
|
||||
a string. Let's introduce the `$eval` function, which evaluates simple expressions using
|
||||
However, if you _nest_ functions, the return of the innermost function may be something other than
|
||||
a string. Let's introduce the `$eval` function, which evaluates simple expressions using
|
||||
Python's `literal_eval` and/or `simple_eval`.
|
||||
|
||||
"There's a $toint($eval(10 * 2.2))% chance of survival."
|
||||
"There's a $toint($eval(10 * 2.2))% chance of survival."
|
||||
|
||||
Since the `$eval` is the innermost call, it will get a string as input - the string `"10 * 2.2"`.
|
||||
It evaluates this and returns the `float` `22.0`. This time the outermost `$toint` will be called with
|
||||
this `float` instead of with a string.
|
||||
Since the `$eval` is the innermost call, it will get a string as input - the string `"10 * 2.2"`.
|
||||
It evaluates this and returns the `float` `22.0`. This time the outermost `$toint` will be called with
|
||||
this `float` instead of with a string.
|
||||
|
||||
> It's important to safely validate your inputs since users may end up nesting your callables in any order.
|
||||
> It's important to safely validate your inputs since users may end up nesting your callables in any order.
|
||||
> See the next section for useful tools to help with this.
|
||||
|
||||
In these examples, the result will be embedded in the larger string, so the result of the entire parsing
|
||||
will be a string:
|
||||
In these examples, the result will be embedded in the larger string, so the result of the entire parsing
|
||||
will be a string:
|
||||
|
||||
```python
|
||||
parser.parse(above_string)
|
||||
"There's a 22% chance of survival."
|
||||
```
|
||||
|
||||
However, if you use the `parse_to_any` (or `parse(..., return_str=True)`) and _don't add any extra string around the outermost function call_,
|
||||
However, if you use the `parse_to_any` (or `parse(..., return_str=True)`) and _don't add any extra string around the outermost function call_,
|
||||
you'll get the return type of the outermost callable back:
|
||||
|
||||
```python
|
||||
|
|
@ -194,13 +190,13 @@ parser.parse_to_any("$toint($eval(10 * 2.2)")
|
|||
### Safe convertion of inputs
|
||||
|
||||
Since you don't know in which order users may use your callables, they should always check the types
|
||||
of its inputs and convert to the type the callable needs. Note also that when converting from strings,
|
||||
there are limits what inputs you can support. This is because FunctionParser strings are often used by
|
||||
non-developer players/builders and some things (such as complex classes/callables etc) are just not
|
||||
of its inputs and convert to the type the callable needs. Note also that when converting from strings,
|
||||
there are limits what inputs you can support. This is because FunctionParser strings are often used by
|
||||
non-developer players/builders and some things (such as complex classes/callables etc) are just not
|
||||
safe/possible to convert from string representation.
|
||||
|
||||
In `evennia.utils.utils` is a helper called
|
||||
[safe_convert_to_types](api:evennia.utils.utils#evennia.utils.utils.safe_convert_to_types). This function
|
||||
In `evennia.utils.utils` is a helper called
|
||||
[safe_convert_to_types](evennia.utils.utils.safe_convert_to_types). This function
|
||||
automates the conversion of simple data types in a safe way:
|
||||
|
||||
```python
|
||||
|
|
@ -208,94 +204,94 @@ from evennia.utils.utils import safe_convert_to_types
|
|||
|
||||
def _process_callable(*args, **kwargs):
|
||||
"""
|
||||
A callable with a lot of custom options
|
||||
|
||||
$process(expression, local, extra=34, extra2=foo)
|
||||
|
||||
A callable with a lot of custom options
|
||||
|
||||
$process(expression, local, extra=34, extra2=foo)
|
||||
|
||||
"""
|
||||
args, kwargs = safe_convert_to_type(
|
||||
(('py', 'py'), {'extra1': int, 'extra2': str}),
|
||||
(('py', 'py'), {'extra1': int, 'extra2': str}),
|
||||
*args, **kwargs)
|
||||
|
||||
# args/kwargs should be correct types now
|
||||
|
||||
# args/kwargs should be correct types now
|
||||
|
||||
```
|
||||
|
||||
In other words,
|
||||
|
||||
```python
|
||||
```python
|
||||
args, kwargs = safe_convert_to_type(
|
||||
(tuple_of_arg_converters, dict_of_kwarg_converters), *args, **kwargs)
|
||||
```
|
||||
|
||||
Each converter should be a callable taking one argument - this will be the arg/kwarg-value to convert. The
|
||||
special converter `"py"` will try to convert a string argument to a Python structure with the help of the
|
||||
following tools (which you may also find useful to experiment with on your own):
|
||||
Each converter should be a callable taking one argument - this will be the arg/kwarg-value to convert. The
|
||||
special converter `"py"` will try to convert a string argument to a Python structure with the help of the
|
||||
following tools (which you may also find useful to experiment with on your own):
|
||||
|
||||
- [ast.literal_eval](https://docs.python.org/3.8/library/ast.html#ast.literal_eval) is an in-built Python
|
||||
function. It
|
||||
_only_ supports strings, bytes, numbers, tuples, lists, dicts, sets, booleans and `None`. That's
|
||||
it - no arithmetic or modifications of data is allowed. This is good for converting individual values and
|
||||
lists/dicts from the input line to real Python objects.
|
||||
- [simpleeval](https://pypi.org/project/simpleeval/) is a third-party tool included with Evennia. This
|
||||
allows for evaluation of simple (and thus safe) expressions. One can operate on numbers and strings
|
||||
with +-/* as well as do simple comparisons like `4 > 3` and more. It does _not_ accept more complex
|
||||
- [simpleeval](https://pypi.org/project/simpleeval/) is a third-party tool included with Evennia. This
|
||||
allows for evaluation of simple (and thus safe) expressions. One can operate on numbers and strings
|
||||
with `+-/*` as well as do simple comparisons like `4 > 3` and more. It does _not_ accept more complex
|
||||
containers like lists/dicts etc, so this and `literal_eval` are complementary to each other.
|
||||
|
||||
```warning::
|
||||
It may be tempting to run use Python's in-built ``eval()`` or ``exec()`` functions as converters since
|
||||
these are able to convert any valid Python source code to Python. NEVER DO THIS unless you really, really
|
||||
know that ONLY developers will ever modify the string going into the callable. The parser is intended
|
||||
for untrusted users (if you were trusted you'd have access to Python already). Letting untrusted users
|
||||
pass strings to ``eval``/``exec`` is a MAJOR security risk. It allows the caller to run arbitrary
|
||||
Python code on your server. This is the path to maliciously deleted hard drives. Just don't do it and
|
||||
```{warning}
|
||||
It may be tempting to run use Python's in-built ``eval()`` or ``exec()`` functions as converters since
|
||||
these are able to convert any valid Python source code to Python. NEVER DO THIS unless you really, really
|
||||
know that ONLY developers will ever modify the string going into the callable. The parser is intended
|
||||
for untrusted users (if you were trusted you'd have access to Python already). Letting untrusted users
|
||||
pass strings to ``eval``/``exec`` is a MAJOR security risk. It allows the caller to run arbitrary
|
||||
Python code on your server. This is the path to maliciously deleted hard drives. Just don't do it and
|
||||
sleep better at night.
|
||||
```
|
||||
|
||||
## Default callables
|
||||
|
||||
These are some example callables you can import and add your parser. They are divided into
|
||||
global-level dicts in `evennia.utils.funcparser`. Just import the dict(s) and merge/add one or
|
||||
These are some example callables you can import and add your parser. They are divided into
|
||||
global-level dicts in `evennia.utils.funcparser`. Just import the dict(s) and merge/add one or
|
||||
more to them when you create your `FuncParser` instance to have those callables be available.
|
||||
|
||||
### `evennia.utils.funcparser.FUNCPARSER_CALLABLES`
|
||||
|
||||
These are the 'base' callables.
|
||||
|
||||
- `$eval(expression)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_eval)) -
|
||||
this uses `literal_eval` and `simple_eval` (see previous section) attemt to convert a string expression
|
||||
- `$eval(expression)` ([code](evennia.utils.funcparser.funcparser_callable_eval)) -
|
||||
this uses `literal_eval` and `simple_eval` (see previous section) attemt to convert a string expression
|
||||
to a python object. This handles e.g. lists of literals `[1, 2, 3]` and simple expressions like `"1 + 2"`.
|
||||
- `$toint(number)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_toint)) -
|
||||
- `$toint(number)` ([code](evennia.utils.funcparser.funcparser_callable_toint)) -
|
||||
always converts an output to an integer, if possible.
|
||||
- `$add/sub/mult/div(obj1, obj2)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_add)) -
|
||||
this adds/subtracts/multiplies and divides to elements together. While simple addition could be done with
|
||||
`$eval`, this could for example be used also to add two lists together, which is not possible with `eval`;
|
||||
- `$add/sub/mult/div(obj1, obj2)` ([code](evennia.utils.funcparser.funcparser_callable_add)) -
|
||||
this adds/subtracts/multiplies and divides to elements together. While simple addition could be done with
|
||||
`$eval`, this could for example be used also to add two lists together, which is not possible with `eval`;
|
||||
for example `$add($eval([1,2,3]), $eval([4,5,6])) -> [1, 2, 3, 4, 5, 6]`.
|
||||
- `$round(float, significant)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_round)) -
|
||||
- `$round(float, significant)` ([code](evennia.utils.funcparser.funcparser_callable_round)) -
|
||||
rounds an input float into the number of provided significant digits. For example `$round(3.54343, 3) -> 3.543`.
|
||||
- `$random([start, [end]])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_random)) -
|
||||
this works like the Python `random()` function, but will randomize to an integer value if both start/end are
|
||||
- `$random([start, [end]])` ([code](evennia.utils.funcparser.funcparser_callable_random)) -
|
||||
this works like the Python `random()` function, but will randomize to an integer value if both start/end are
|
||||
integers. Without argument, will return a float between 0 and 1.
|
||||
- `$randint([start, [end]])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_randint)) -
|
||||
- `$randint([start, [end]])` ([code](evennia.utils.funcparser.funcparser_callable_randint)) -
|
||||
works like the `randint()` python function and always returns an integer.
|
||||
- `$choice(list)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_choice)) -
|
||||
the input will automatically be parsed the same way as `$eval` and is expected to be an iterable. A random
|
||||
- `$choice(list)` ([code](evennia.utils.funcparser.funcparser_callable_choice)) -
|
||||
the input will automatically be parsed the same way as `$eval` and is expected to be an iterable. A random
|
||||
element of this list will be returned.
|
||||
- `$pad(text[, width, align, fillchar])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_pad)) -
|
||||
- `$pad(text[, width, align, fillchar])` ([code](evennia.utils.funcparser.funcparser_callable_pad)) -
|
||||
this will pad content. `$pad("Hello", 30, c, -)` will lead to a text centered in a 30-wide block surrounded by `-`
|
||||
characters.
|
||||
- `$crop(text, width=78, suffix='[...]')` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_crop)) -
|
||||
- `$crop(text, width=78, suffix='[...]')` ([code](evennia.utils.funcparser.funcparser_callable_crop)) -
|
||||
this will crop a text longer than the width, by default ending it with a `[...]`-suffix that also fits within
|
||||
the width. If no width is given, the client width or `settings.DEFAULT_CLIENT_WIDTH` will be used.
|
||||
- `$space(num)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_space)) -
|
||||
- `$space(num)` ([code](evennia.utils.funcparser.funcparser_callable_space)) -
|
||||
this will insert `num` spaces.
|
||||
- `$just(string, width=40, align=c, indent=2)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_justify)) -
|
||||
- `$just(string, width=40, align=c, indent=2)` ([code](evennia.utils.funcparser.funcparser_callable_justify)) -
|
||||
justifies the text to a given width, aligning it left/right/center or 'f' for full (spread text across width).
|
||||
- `$ljust` - shortcut to justify-left. Takes all other kwarg of `$just`.
|
||||
- `$rjust` - shortcut to right justify.
|
||||
- `$cjust` - shortcut to center justify.
|
||||
- `$clr(startcolor, text[, endcolor])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_clr)) -
|
||||
color text. The color is given with one or two characters without the preceeding `|`. If no endcolor is
|
||||
- `$clr(startcolor, text[, endcolor])` ([code](evennia.utils.funcparser.funcparser_callable_clr)) -
|
||||
color text. The color is given with one or two characters without the preceeding `|`. If no endcolor is
|
||||
given, the string will go back to neutral, so `$clr(r, Hello)` is equivalent to `|rHello|n`.
|
||||
|
||||
### `evennia.utils.funcparser.SEARCHING_CALLABLES`
|
||||
|
|
@ -304,15 +300,16 @@ These are callables that requires access-checks in order to search for objects.
|
|||
extra reserved kwargs to be passed when running the parser:
|
||||
|
||||
```python
|
||||
parser.parse_to_any(string, caller=<object or account>, access="control", ...)`
|
||||
|
||||
parser.parse_to_any(string, caller=<object or account>, access="control", ...)
|
||||
|
||||
```
|
||||
The `caller` is required, it's the the object to do the access-check for. The `access` kwarg is the
|
||||
[lock type](./Locks) to check, default being `"control"`.
|
||||
The `caller` is required, it's the the object to do the access-check for. The `access` kwarg is the
|
||||
[lock type](./Locks.md) to check, default being `"control"`.
|
||||
|
||||
- `$search(query,type=account|script,return_list=False)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_search)) -
|
||||
this will look up and try to match an object by key or alias. Use the `type` kwarg to
|
||||
search for `account` or `script` instead. By default this will return nothing if there are more than one
|
||||
- `$search(query,type=account|script,return_list=False)` ([code](evennia.utils.funcparser.funcparser_callable_search)) -
|
||||
this will look up and try to match an object by key or alias. Use the `type` kwarg to
|
||||
search for `account` or `script` instead. By default this will return nothing if there are more than one
|
||||
match; if `return_list` is `True` a list of 0, 1 or more matches will be returned instead.
|
||||
- `$obj(query)`, `$dbref(query)` - legacy aliases for `$search`.
|
||||
- `$objlist(query)` - legacy alias for `$search`, always returning a list.
|
||||
|
|
@ -320,9 +317,9 @@ The `caller` is required, it's the the object to do the access-check for. The `a
|
|||
|
||||
### `evennia.utils.funcparser.ACTOR_STANCE_CALLABLES`
|
||||
|
||||
These are used to implement actor-stance emoting. They are used by the
|
||||
[DefaultObject.msg_contents](api:evennia.objects.objects#evennia.objects.objects.DefaultObject.msg_contents) method
|
||||
by default.
|
||||
These are used to implement actor-stance emoting. They are used by the
|
||||
[DefaultObject.msg_contents](evennia.objects.objects.DefaultObject.msg_contents) method
|
||||
by default.
|
||||
|
||||
These all require extra kwargs be passed into the parser:
|
||||
|
||||
|
|
@ -333,16 +330,16 @@ parser.parse(string, caller=<obj>, receiver=<obj>, mapping={'key': <obj>, ...})
|
|||
Here the `caller` is the one sending the message and `receiver` the one to see it. The `mapping` contains
|
||||
references to other objects accessible via these callables.
|
||||
|
||||
- `$you([key])` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_you)) -
|
||||
if no `key` is given, this represents the `caller`, otherwise an object from `mapping`
|
||||
will be used. As this message is sent to different recipients, the `receiver` will change and this will
|
||||
be replaced either with the string `you` (if you and the receiver is the same entity) or with the
|
||||
- `$you([key])` ([code](evennia.utils.funcparser.funcparser_callable_you)) -
|
||||
if no `key` is given, this represents the `caller`, otherwise an object from `mapping`
|
||||
will be used. As this message is sent to different recipients, the `receiver` will change and this will
|
||||
be replaced either with the string `you` (if you and the receiver is the same entity) or with the
|
||||
result of `you_obj.get_display_name(looker=receiver)`. This allows for a single string to echo differently
|
||||
depending on who sees it, and also to reference other people in the same way.
|
||||
- `$You([key])` - same as `$you` but always capitalized.
|
||||
- `$conj(verb)` ([code](api:evennia.utils.funcparser#evennia.utils.funcparser.funcparser_callable_conjugate)) -- conjugates a verb between 4nd person presens to 3rd person presence depending on who
|
||||
- `$conj(verb)` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) -- conjugates a verb between 4nd person presens to 3rd person presence depending on who
|
||||
sees the string. For example `"$You() $conj(smiles)".` will show as "You smile." and "Tom smiles." depending
|
||||
on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](api:evennia.utils.verb_conjugation)
|
||||
on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](evennia.utils.verb_conjugation)
|
||||
to do this, and only works for English verbs.
|
||||
|
||||
### Example
|
||||
|
|
@ -377,10 +374,10 @@ result = parser.parse(string)
|
|||
```
|
||||
|
||||
Above we define two callables `_dashline` and `_uptime` and map them to names `"dashline"` and `"uptime"`,
|
||||
which is what we then can call as `$header` and `$uptime` in the string. We also have access to
|
||||
which is what we then can call as `$header` and `$uptime` in the string. We also have access to
|
||||
all the defaults (like `$toint()`).
|
||||
|
||||
The parsed result of the above would be something like this:
|
||||
The parsed result of the above would be something like this:
|
||||
|
||||
This is the current uptime:
|
||||
------- 343 seconds -------
|
||||
------- 343 seconds -------
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ regular code editor, see below).
|
|||
Evennia collects help entries from three sources:
|
||||
|
||||
- _Auto-generated command help_ - this is literally the doc-strings of
|
||||
the [Command classes](./Commands). The idea is that the command docs are
|
||||
the [Command classes](./Commands.md). The idea is that the command docs are
|
||||
easier to maintain and keep up-to-date if the developer can change them at the
|
||||
same time as they do the code.
|
||||
- _Database-stored help entries_ - These are created in-game (using the
|
||||
|
|
@ -93,14 +93,14 @@ All help entries (no matter the source) have the following properties:
|
|||
extra space at beginning and end.
|
||||
|
||||
A `text` that scrolls off the screen will automatically be paginated by
|
||||
the [EvMore](./EvMore) pager (you can control this with
|
||||
the [EvMore](./EvMore.md) pager (you can control this with
|
||||
`settings.HELP_MORE_ENABLED=False`). If you use EvMore and want to control
|
||||
exactly where the pager should break the page, mark the break with the control
|
||||
character `\f`.
|
||||
|
||||
#### Subtopics
|
||||
|
||||
```versionadded:: 1.0
|
||||
```{versionadded} 1.0
|
||||
```
|
||||
|
||||
Rather than making a very long help entry, the `text` may also be broken up
|
||||
|
|
@ -199,7 +199,7 @@ The text at the very top of the command class definition is the class'
|
|||
consistent format - all default commands are using the structure shown above.
|
||||
|
||||
You can limit access to the help entry by the `view` and/or `read` locks on the
|
||||
Command. See [the section below](#Locking-help-entries) for details.
|
||||
Command. See [the section below](./Help-System.md#locking-help-entries) for details.
|
||||
|
||||
You should also supply the `help_category` class property if you can; this helps
|
||||
to group help entries together for people to more easily find them. See the
|
||||
|
|
@ -209,7 +209,7 @@ used.
|
|||
|
||||
If you don't want your command to be picked up by the auto-help system at all
|
||||
(like if you want to write its docs manually using the info in the next section
|
||||
or you use a [cmdset](./Command-Sets) that has its own help functionality) you
|
||||
or you use a [cmdset](./Command-Sets.md) that has its own help functionality) you
|
||||
can explicitly set `auto_help` class property to `False` in your command
|
||||
definition.
|
||||
|
||||
|
|
@ -233,8 +233,8 @@ entry = create_help_entry("emote",
|
|||
category="Roleplaying", locks="view:all()")
|
||||
```
|
||||
|
||||
The entity being created is a [evennia.help.models.HelpEntry](api:evennia.help.models.HelpEntry)
|
||||
object. This is _not_ a [Typeclassed](./Typeclasses) entity and is not meant to
|
||||
The entity being created is a [evennia.help.models.HelpEntry](evennia.help.models.HelpEntry)
|
||||
object. This is _not_ a [Typeclassed](./Typeclasses.md) entity and is not meant to
|
||||
be modified to any great degree. It holds the properties listed earlier. The
|
||||
text is stored in a field `entrytext`. It does not provide a `get_help` method
|
||||
like commands, stores and returns the `entrytext` directly.
|
||||
|
|
@ -244,7 +244,7 @@ this will not return the two other types of help entries.
|
|||
|
||||
### File-help entries
|
||||
|
||||
```versionadded:: 1.0
|
||||
```{versionadded} 1.0
|
||||
```
|
||||
|
||||
File-help entries are created by the game development team outside of the game. The
|
||||
|
|
@ -369,7 +369,7 @@ help_entry = {
|
|||
|
||||
```
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
Changed the old 'view' lock to control the help-index inclusion and added
|
||||
the new 'read' lock-type to control access to the entry itself.
|
||||
```
|
||||
|
|
@ -377,7 +377,7 @@ help_entry = {
|
|||
## Customizing the look of the help system
|
||||
|
||||
This is done almost exclusively by overriding the `help` command
|
||||
[evennia.commands.default.help.CmdHelp](api:evennia.commands.default.help#CmdHelp).
|
||||
[evennia.commands.default.help.CmdHelp](evennia.commands.default.help.CmdHelp).
|
||||
|
||||
Since the available commands may vary from moment to moment, `help` is
|
||||
responsible for collating the three sources of help-entries (commands/db/file)
|
||||
|
|
@ -401,7 +401,7 @@ Once the main entry has been found, subtopics are then searched with
|
|||
simple `==`, `startswith` and `in` matching (there are so relatively few of them
|
||||
at that point).
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
Replaced the old bag-of-words algorithm with lunr package.
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Inputfuncs
|
||||
|
||||
|
||||
An *inputfunc* is an Evennia function that handles a particular input (an [inputcommand](../Concepts/OOB)) from
|
||||
An *inputfunc* is an Evennia function that handles a particular input (an [inputcommand](../Concepts/OOB.md)) from
|
||||
the client. The inputfunc is the last destination for the inputcommand along the [ingoing message
|
||||
path](Messagepath#the-ingoing-message-path). The inputcommand always has the form `(commandname,
|
||||
path](../Concepts/Messagepath.md#the-ingoing-message-path). The inputcommand always has the form `(commandname,
|
||||
(args), {kwargs})` and Evennia will use this to try to find and call an inputfunc on the form
|
||||
|
||||
```python
|
||||
|
|
@ -42,7 +42,7 @@ Evennia defines a few default inputfuncs to handle the common cases. These are d
|
|||
|
||||
This is the most common of inputcommands, and the only one supported by every traditional mud. The
|
||||
argument is usually what the user sent from their command line. Since all text input from the user
|
||||
like this is considered a [Command](./Commands), this inputfunc will do things like nick-replacement
|
||||
like this is considered a [Command](./Commands.md), this inputfunc will do things like nick-replacement
|
||||
and then pass on the input to the central Commandhandler.
|
||||
|
||||
### echo
|
||||
|
|
@ -134,7 +134,7 @@ to expand. By default the following values can be retrieved:
|
|||
accepted names if given an unfamiliar callback name.
|
||||
|
||||
This will tell evennia to repeatedly call a named function at a given interval. Behind the scenes
|
||||
this will set up a [Ticker](./TickerHandler). Only previously acceptable functions are possible to
|
||||
this will set up a [Ticker](./TickerHandler.md). Only previously acceptable functions are possible to
|
||||
repeat-call in this way, you'll need to overload this inputfunc to add the ones you want to offer.
|
||||
By default only two example functions are allowed, "test1" and "test2", which will just echo a text
|
||||
back at the given interval. Stop the repeat by sending `"stop": True` (note that you must include
|
||||
|
|
@ -155,7 +155,7 @@ This is a convenience wrapper for sending "stop" to the `repeat` inputfunc.
|
|||
|
||||
This sets up on-object monitoring of Attributes or database fields. Whenever the field or Attribute
|
||||
changes in any way, the outputcommand will be sent. This is using the
|
||||
[MonitorHandler](./MonitorHandler) behind the scenes. Pass the "stop" key to stop monitoring. Note
|
||||
[MonitorHandler](./MonitorHandler.md) behind the scenes. Pass the "stop" key to stop monitoring. Note
|
||||
that you must supply the name also when stopping to let the system know which monitor should be
|
||||
cancelled.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
|
||||
For most games it is a good idea to restrict what people can do. In Evennia such restrictions are
|
||||
applied and checked by something called *locks*. All Evennia entities ([Commands](./Commands),
|
||||
[Objects](./Objects), [Scripts](./Scripts), [Accounts](./Accounts), [Help System](./Help-System),
|
||||
[messages](./Communications#Msg) and [channels](./Communications#Channels)) are accessed through locks.
|
||||
applied and checked by something called *locks*. All Evennia entities ([Commands](./Commands.md),
|
||||
[Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md), [Help System](./Help-System.md),
|
||||
[messages](./Msg.md) and [channels](./Channels.md)) are accessed through locks.
|
||||
|
||||
A lock can be thought of as an "access rule" restricting a particular use of an Evennia entity.
|
||||
Whenever another entity wants that kind of access the lock will analyze that entity in different
|
||||
|
|
@ -92,9 +92,9 @@ the default command set) actually checks for, as in the example of `delete` abov
|
|||
|
||||
Below are the access_types checked by the default commandset.
|
||||
|
||||
- [Commands](./Commands)
|
||||
- [Commands](./Commands.md)
|
||||
- `cmd` - this defines who may call this command at all.
|
||||
- [Objects](./Objects):
|
||||
- [Objects](./Objects.md):
|
||||
- `control` - who is the "owner" of the object. Can set locks, delete it etc. Defaults to the
|
||||
creator of the object.
|
||||
- `call` - who may call Object-commands stored on this Object except for the Object itself. By
|
||||
|
|
@ -109,26 +109,26 @@ something like `call:false()`.
|
|||
- `get`- who may pick up the object and carry it around.
|
||||
- `puppet` - who may "become" this object and control it as their "character".
|
||||
- `attrcreate` - who may create new attributes on the object (default True)
|
||||
- [Characters](./Objects#Characters):
|
||||
- [Characters](./Objects.md#characters):
|
||||
- Same as for Objects
|
||||
- [Exits](./Objects#Exits):
|
||||
- [Exits](./Objects.md#exits):
|
||||
- Same as for Objects
|
||||
- `traverse` - who may pass the exit.
|
||||
- [Accounts](./Accounts):
|
||||
- [Accounts](./Accounts.md):
|
||||
- `examine` - who may examine the account's properties.
|
||||
- `delete` - who may delete the account.
|
||||
- `edit` - who may edit the account's attributes and properties.
|
||||
- `msg` - who may send messages to the account.
|
||||
- `boot` - who may boot the account.
|
||||
- [Attributes](./Attributes): (only checked by `obj.secure_attr`)
|
||||
- [Attributes](./Attributes.md): (only checked by `obj.secure_attr`)
|
||||
- `attrread` - see/access attribute
|
||||
- `attredit` - change/delete attribute
|
||||
- [Channels](./Communications#Channels):
|
||||
- [Channels](./Channels.md):
|
||||
- `control` - who is administrating the channel. This means the ability to delete the channel,
|
||||
boot listeners etc.
|
||||
- `send` - who may send to the channel.
|
||||
- `listen` - who may subscribe and listen to the channel.
|
||||
- [HelpEntry](./Help-System):
|
||||
- [HelpEntry](./Help-System.md):
|
||||
- `examine` - who may view this help entry (usually everyone)
|
||||
- `edit` - who may edit this help entry.
|
||||
|
||||
|
|
@ -214,10 +214,10 @@ Some useful default lockfuncs (see `src/locks/lockfuncs.py` for more):
|
|||
- `false()/none()/superuser()` - give access to none. Superusers bypass the check entirely and are
|
||||
thus the only ones who will pass this check.
|
||||
- `perm(perm)` - this tries to match a given `permission` property, on an Account firsthand, on a
|
||||
Character second. See [below](./Locks#permissions).
|
||||
Character second. See [below](./Permissions.md).
|
||||
- `perm_above(perm)` - like `perm` but requires a "higher" permission level than the one given.
|
||||
- `id(num)/dbref(num)` - checks so the access_object has a certain dbref/id.
|
||||
- `attr(attrname)` - checks if a certain [Attribute](./Attributes) exists on accessing_object.
|
||||
- `attr(attrname)` - checks if a certain [Attribute](./Attributes.md) exists on accessing_object.
|
||||
- `attr(attrname, value)` - checks so an attribute exists on accessing_object *and* has the given
|
||||
value.
|
||||
- `attr_gt(attrname, value)` - checks so accessing_object has a value larger (`>`) than the given
|
||||
|
|
@ -250,7 +250,7 @@ a Lock lookup.
|
|||
## Default locks
|
||||
|
||||
Evennia sets up a few basic locks on all new objects and accounts (if we didn't, noone would have
|
||||
any access to anything from the start). This is all defined in the root [Typeclasses](./Typeclasses)
|
||||
any access to anything from the start). This is all defined in the root [Typeclasses](./Typeclasses.md)
|
||||
of the respective entity, in the hook method `basetype_setup()` (which you usually don't want to
|
||||
edit unless you want to change how basic stuff like rooms and exits store their internal variables).
|
||||
This is called once, before `at_object_creation`, so just put them in the latter method on your
|
||||
|
|
@ -300,7 +300,7 @@ whereas only Admins and the creator may delete it. Everyone can pick it up.
|
|||
|
||||
## A complete example of setting locks on an object
|
||||
|
||||
Assume we have two objects - one is ourselves (not superuser) and the other is an [Object](./Objects)
|
||||
Assume we have two objects - one is ourselves (not superuser) and the other is an [Object](./Objects.md)
|
||||
called `box`.
|
||||
|
||||
> create/drop box
|
||||
|
|
@ -326,7 +326,7 @@ This is defined in `evennia/commands/default/general.py`. In its code we find th
|
|||
```
|
||||
|
||||
So the `get` command looks for a lock with the type *get* (not so surprising). It also looks for an
|
||||
[Attribute](./Attributes) on the checked object called _get_err_msg_ in order to return a customized
|
||||
[Attribute](./Attributes.md) on the checked object called _get_err_msg_ in order to return a customized
|
||||
error message. Sounds good! Let's start by setting that on the box:
|
||||
|
||||
> set box/get_err_msg = You are not strong enough to lift this box.
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ MONITOR_HANDLER.add(obj, fieldname, callback,
|
|||
|
||||
```
|
||||
|
||||
- `obj` ([Typeclassed](./Typeclasses) entity) - the object to monitor. Since this must be
|
||||
typeclassed, it means you can't monitor changes on [Sessions](./Sessions) with the monitorhandler, for
|
||||
- `obj` ([Typeclassed](./Typeclasses.md) entity) - the object to monitor. Since this must be
|
||||
typeclassed, it means you can't monitor changes on [Sessions](./Sessions.md) with the monitorhandler, for
|
||||
example.
|
||||
- `fieldname` (str) - the name of a field or [Attribute](./Attributes) on `obj`. If you want to
|
||||
- `fieldname` (str) - the name of a field or [Attribute](./Attributes.md) on `obj`. If you want to
|
||||
monitor a database field you must specify its full name, including the starting `db_` (like
|
||||
`db_key`, `db_location` etc). Any names not starting with `db_` are instead assumed to be the names
|
||||
of Attributes. This difference matters, since the MonitorHandler will automatically know to watch
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Msg
|
||||
|
||||
The [Msg](api:evennia.comms.models.Msg) object represents a database-saved
|
||||
The [Msg](evennia.comms.models.Msg) object represents a database-saved
|
||||
piece of communication. Think of it as a discrete piece of email - it contains
|
||||
a message, some metadata and will always have a sender and one or more
|
||||
recipients.
|
||||
|
|
@ -14,7 +14,7 @@ good uses for `Msg` objects:
|
|||
- game-wide email stored in 'mailboxes'.
|
||||
|
||||
|
||||
```important::
|
||||
```{important}
|
||||
|
||||
A `Msg` does not have any in-game representation. So if you want to use them
|
||||
to represent in-game mail/letters, the physical letters would never be
|
||||
|
|
@ -25,15 +25,15 @@ good uses for `Msg` objects:
|
|||
|
||||
```
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
Channels dropped Msg-support. Now only used in `page` command by default.
|
||||
```
|
||||
|
||||
## Msg in code
|
||||
|
||||
The Msg is intended to be used exclusively in code, to build other game systems. It is _not_
|
||||
a [Typeclassed](./Typeclasses) entity, which means it cannot (easily) be overridden. It
|
||||
doesn't support Attributes (but it _does_ support [Tags](./Tags)). It tries to be lean
|
||||
a [Typeclassed](./Typeclasses.md) entity, which means it cannot (easily) be overridden. It
|
||||
doesn't support Attributes (but it _does_ support [Tags](./Tags.md)). It tries to be lean
|
||||
and small since a new one is created for every message.
|
||||
|
||||
You create a new message with `evennia.create_message`:
|
||||
|
|
@ -62,7 +62,7 @@ You can search for `Msg` objects in various ways:
|
|||
### Properties on Msg
|
||||
|
||||
- `senders` - there must always be at least one sender. This is a set of
|
||||
- [Account](./Accounts), [Object](./Objects), [Script](./Scripts)
|
||||
- [Account](./Accounts.md), [Object](./Objects.md), [Script](./Scripts.md)
|
||||
or `str` in any combination (but usually a message only targets one type).
|
||||
Using a `str` for a sender indicates it's an 'external' sender and
|
||||
and can be used to point to a sender that is not a typeclassed entity. This is not used by default
|
||||
|
|
@ -70,17 +70,17 @@ You can search for `Msg` objects in various ways:
|
|||
python-path, for example). While most systems expect a single sender, it's
|
||||
possible to have any number of them.
|
||||
- `receivers` - these are the ones to see the Msg. These are again any combination of
|
||||
[Account](./Accounts), [Object](./Objects) or [Script](./Scripts) or `str` (an 'external' receiver).
|
||||
[Account](./Accounts.md), [Object](./Objects.md) or [Script](./Scripts.md) or `str` (an 'external' receiver).
|
||||
It's in principle possible to have zero receivers but most usages of Msg expects one or more.
|
||||
- `header` - this is an optional text field that can contain meta-information about the message. For
|
||||
an email-like system it would be the subject line. This can be independently searched, making
|
||||
this a powerful place for quickly finding messages.
|
||||
- `message` - the actual text being sent.
|
||||
- `date_sent` - this is auto-set to the time the Msg was created (and thus presumably sent).
|
||||
- `locks` - the Evennia [lock handler](./Locks). Use with `locks.add()` etc and check locks with `msg.access()`
|
||||
- `locks` - the Evennia [lock handler](./Locks.md). Use with `locks.add()` etc and check locks with `msg.access()`
|
||||
like for all other lockable entities. This can be used to limit access to the contents
|
||||
of the Msg. The default lock-type to check is `'read'`.
|
||||
- `hide_from` - this is an optional list of [Accounts](./Accounts) or [Objects](./Objects) that
|
||||
- `hide_from` - this is an optional list of [Accounts](./Accounts.md) or [Objects](./Objects.md) that
|
||||
will not see this Msg. This relationship is available mainly for optimization
|
||||
reasons since it allows quick filtering of messages not intended for a given
|
||||
target.
|
||||
|
|
@ -88,7 +88,7 @@ You can search for `Msg` objects in various ways:
|
|||
|
||||
## TempMsg
|
||||
|
||||
[evennia.comms.models.TempMsg](api:evennia.comms.models.TempMsg) is an object
|
||||
[evennia.comms.models.TempMsg](evennia.comms.models.TempMsg) is an object
|
||||
that implements the same API as the regular `Msg`, but which has no database
|
||||
component (and thus cannot be searched). It's meant to plugged into systems
|
||||
expecting a `Msg` but where you just want to process the message without saving
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Nicks
|
||||
|
||||
|
||||
*Nicks*, short for *Nicknames* is a system allowing an object (usually a [Account](./Accounts)) to
|
||||
*Nicks*, short for *Nicknames* is a system allowing an object (usually a [Account](./Accounts.md)) to
|
||||
assign custom replacement names for other game entities.
|
||||
|
||||
Nicks are not to be confused with *Aliases*. Setting an Alias on a game entity actually changes an
|
||||
|
|
@ -75,7 +75,7 @@ You can also use [shell-type wildcards](http://www.linfo.org/wildcard.html):
|
|||
## Coding with nicks
|
||||
|
||||
Nicks are stored as the `Nick` database model and are referred from the normal Evennia
|
||||
[object](./Objects) through the `nicks` property - this is known as the *NickHandler*. The NickHandler
|
||||
[object](./Objects.md) through the `nicks` property - this is known as the *NickHandler*. The NickHandler
|
||||
offers effective error checking, searches and conversion.
|
||||
|
||||
```python
|
||||
|
|
@ -101,12 +101,12 @@ offers effective error checking, searches and conversion.
|
|||
In a command definition you can reach the nick handler through `self.caller.nicks`. See the `nick`
|
||||
command in `evennia/commands/default/general.py` for more examples.
|
||||
|
||||
As a last note, The Evennia [channel](./Communications) alias systems are using nicks with the
|
||||
As a last note, The Evennia [channel](./Communications.md) alias systems are using nicks with the
|
||||
`nick_type="channel"` in order to allow users to create their own custom aliases to channels.
|
||||
|
||||
# Advanced note
|
||||
|
||||
Internally, nicks are [Attributes](./Attributes) saved with the `db_attrype` set to "nick" (normal
|
||||
Internally, nicks are [Attributes](./Attributes.md) saved with the `db_attrype` set to "nick" (normal
|
||||
Attributes has this set to `None`).
|
||||
|
||||
The nick stores the replacement data in the Attribute.db_value field as a tuple with four fields
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
All in-game objects in Evennia, be it characters, chairs, monsters, rooms or hand grenades are
|
||||
represented by an Evennia *Object*. Objects form the core of Evennia and is probably what you'll
|
||||
spend most time working with. Objects are [Typeclassed](./Typeclasses) entities.
|
||||
spend most time working with. Objects are [Typeclassed](./Typeclasses.md) entities.
|
||||
|
||||
## How to create your own object types
|
||||
|
||||
|
|
@ -48,17 +48,17 @@ thing yourself in code:
|
|||
call manually you have to give the full path to the class. The `create.create_object` function is
|
||||
powerful and should be used for all coded object creating (so this is what you use when defining
|
||||
your own building commands). Check out the `ev.create_*` functions for how to build other entities
|
||||
like [Scripts](./Scripts)).
|
||||
like [Scripts](./Scripts.md)).
|
||||
|
||||
This particular Rose class doesn't really do much, all it does it make sure the attribute
|
||||
`desc`(which is what the `look` command looks for) is pre-set, which is pretty pointless since you
|
||||
will usually want to change this at build time (using the `@desc` command or using the
|
||||
[Spawner](./Prototypes)). The `Object` typeclass offers many more hooks that is available
|
||||
[Spawner](./Prototypes.md)). The `Object` typeclass offers many more hooks that is available
|
||||
to use though - see next section.
|
||||
|
||||
## Properties and functions on Objects
|
||||
|
||||
Beyond the properties assigned to all [typeclassed](./Typeclasses) objects (see that page for a list
|
||||
Beyond the properties assigned to all [typeclassed](./Typeclasses.md) objects (see that page for a list
|
||||
of those), the Object also has the following custom properties:
|
||||
|
||||
- `aliases` - a handler that allows you to add and remove aliases from this object. Use
|
||||
|
|
@ -67,12 +67,12 @@ of those), the Object also has the following custom properties:
|
|||
- `home` is a backup location. The main motivation is to have a safe place to move the object to if
|
||||
its `location` is destroyed. All objects should usually have a home location for safety.
|
||||
- `destination` - this holds a reference to another object this object links to in some way. Its
|
||||
main use is for [Exits](./Objects#Exits), it's otherwise usually unset.
|
||||
- `nicks` - as opposed to aliases, a [Nick](./Nicks) holds a convenient nickname replacement for a
|
||||
main use is for [Exits](./Objects.md#exits), it's otherwise usually unset.
|
||||
- `nicks` - as opposed to aliases, a [Nick](./Nicks.md) holds a convenient nickname replacement for a
|
||||
real name, word or sequence, only valid for this object. This mainly makes sense if the Object is
|
||||
used as a game character - it can then store briefer shorts, example so as to quickly reference game
|
||||
commands or other characters. Use nicks.add(alias, realname) to add a new one.
|
||||
- `account` - this holds a reference to a connected [Account](./Accounts) controlling this object (if
|
||||
- `account` - this holds a reference to a connected [Account](./Accounts.md) controlling this object (if
|
||||
any). Note that this is set also if the controlling account is *not* currently online - to test if
|
||||
an account is online, use the `has_account` property instead.
|
||||
- `sessions` - if `account` field is set *and the account is online*, this is a list of all active
|
||||
|
|
@ -87,9 +87,9 @@ object set as their `location`).
|
|||
|
||||
The last two properties are special:
|
||||
|
||||
- `cmdset` - this is a handler that stores all [command sets](./Commands#Command_Sets) defined on the
|
||||
- `cmdset` - this is a handler that stores all [command sets](./Command-Sets.md) defined on the
|
||||
object (if any).
|
||||
- `scripts` - this is a handler that manages [Scripts](./Scripts) attached to the object (if any).
|
||||
- `scripts` - this is a handler that manages [Scripts](./Scripts.md) attached to the object (if any).
|
||||
|
||||
The Object also has a host of useful utility functions. See the function headers in
|
||||
`src/objects/objects.py` for their arguments and more details.
|
||||
|
|
@ -104,7 +104,7 @@ on).
|
|||
- `execute_cmd()` - Lets the object execute the given string as if it was given on the command line.
|
||||
- `move_to` - perform a full move of this object to a new location. This is the main move method
|
||||
and will call all relevant hooks, do all checks etc.
|
||||
- `clear_exits()` - will delete all [Exits](./Objects#Exits) to *and* from this object.
|
||||
- `clear_exits()` - will delete all [Exits](./Objects.md#exits) to *and* from this object.
|
||||
- `clear_contents()` - this will not delete anything, but rather move all contents (except Exits) to
|
||||
their designated `Home` locations.
|
||||
- `delete()` - deletes this object, first calling `clear_exits()` and
|
||||
|
|
@ -113,8 +113,7 @@ their designated `Home` locations.
|
|||
The Object Typeclass defines many more *hook methods* beyond `at_object_creation`. Evennia calls
|
||||
these hooks at various points. When implementing your custom objects, you will inherit from the
|
||||
base parent and overload these hooks with your own custom code. See `evennia.objects.objects` for an
|
||||
updated list of all the available hooks or the [API for DefaultObject
|
||||
here](api:evennia.objects.objects#defaultobject).
|
||||
updated list of all the available hooks or the [API for DefaultObject here](evennia.objects.objects.DefaultObject).
|
||||
|
||||
## Subclasses of `Object`
|
||||
|
||||
|
|
@ -126,10 +125,10 @@ practice they are all pretty similar to the base Object.
|
|||
|
||||
### Characters
|
||||
|
||||
Characters are objects controlled by [Accounts](./Accounts). When a new Account
|
||||
Characters are objects controlled by [Accounts](./Accounts.md). When a new Account
|
||||
logs in to Evennia for the first time, a new `Character` object is created and
|
||||
the Account object is assigned to the `account` attribute. A `Character` object
|
||||
must have a [Default Commandset](./Commands#Command_Sets) set on itself at
|
||||
must have a [Default Commandset](./Command-Sets.md) set on itself at
|
||||
creation, or the account will not be able to issue any commands! If you just
|
||||
inherit your own class from `evennia.DefaultCharacter` and make sure to use
|
||||
`super()` to call the parent methods you should be fine. In
|
||||
|
|
@ -150,21 +149,21 @@ you to modify.
|
|||
*in* might be an exit, as well as *door*, *portal* or *jump out the window*. An exit has two things
|
||||
that separate them from other objects. Firstly, their *destination* property is set and points to a
|
||||
valid object. This fact makes it easy and fast to locate exits in the database. Secondly, exits
|
||||
define a special [Transit Command](./Commands) on themselves when they are created. This command is
|
||||
define a special [Transit Command](./Commands.md) on themselves when they are created. This command is
|
||||
named the same as the exit object and will, when called, handle the practicalities of moving the
|
||||
character to the Exits's *destination* - this allows you to just enter the name of the exit on its
|
||||
own to move around, just as you would expect.
|
||||
|
||||
The exit functionality is all defined on the Exit typeclass, so you could in principle completely
|
||||
change how exits work in your game (it's not recommended though, unless you really know what you are
|
||||
doing). Exits are [locked](./Locks) using an access_type called *traverse* and also make use of a few
|
||||
doing). Exits are [locked](./Locks.md) using an access_type called *traverse* and also make use of a few
|
||||
hook methods for giving feedback if the traversal fails. See `evennia.DefaultExit` for more info.
|
||||
In `mygame/typeclasses/exits.py` there is an empty `Exit` class for you to modify.
|
||||
|
||||
The process of traversing an exit is as follows:
|
||||
|
||||
1. The traversing `obj` sends a command that matches the Exit-command name on the Exit object. The
|
||||
[cmdhandler](./Commands) detects this and triggers the command defined on the Exit. Traversal always
|
||||
[cmdhandler](./Commands.md) detects this and triggers the command defined on the Exit. Traversal always
|
||||
involves the "source" (the current location) and the `destination` (this is stored on the Exit
|
||||
object).
|
||||
1. The Exit command checks the `traverse` lock on the Exit object
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# Outputfuncs
|
||||
|
||||
TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB).
|
||||
TODO. For now info about outputfuncs are found in [OOB](../Concepts/OOB.md).
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
# Permissions
|
||||
|
||||
A *permission* is simply a text string stored in the handler `permissions` on `Objects`
|
||||
and `Accounts`. Think of it as a specialized sort of [Tag](./Tags) - one specifically dedicated
|
||||
to access checking. They are thus often tightly coupled to [Locks](./Locks).
|
||||
and `Accounts`. Think of it as a specialized sort of [Tag](./Tags.md) - one specifically dedicated
|
||||
to access checking. They are thus often tightly coupled to [Locks](./Locks.md).
|
||||
Permission strings are not case-sensitive, so "Builder" is the same as "builder"
|
||||
etc.
|
||||
|
||||
Permissions are used as a convenient way to structure access levels and
|
||||
hierarchies. It is set by the `perm` command and checked by the
|
||||
`PermissionHandler.check` method as well as by the specially the `perm()` and
|
||||
`pperm()` [lock functions](./Locks).
|
||||
`pperm()` [lock functions](./Locks.md).
|
||||
|
||||
All new accounts are given a default set of permissions defined by
|
||||
`settings.PERMISSION_ACCOUNT_DEFAULT`.
|
||||
|
|
@ -22,7 +22,7 @@ In-game, you use the `perm` command to add and remove permissions
|
|||
perm/account/del Tommy = Builders
|
||||
|
||||
Note the use of the `/account` switch. It means you assign the permission to the
|
||||
[Accounts](./Accounts) Tommy instead of any [Character](./Objects) that also
|
||||
[Accounts](./Accounts.md) Tommy instead of any [Character](./Objects.md) that also
|
||||
happens to be named "Tommy".
|
||||
|
||||
There can be reasons for putting permissions on Objects (especially NPCS), but
|
||||
|
|
@ -32,7 +32,7 @@ of which Character they are currently puppeting. This is especially important to
|
|||
remember when assigning permissions from the *hierarchy tree* (see below), as an
|
||||
Account's permissions will overrule that of its character. So to be sure to
|
||||
avoid confusion you should generally put hierarchy permissions on the Account,
|
||||
not on their Characters (but see also [quelling](./Locks#Quelling)).
|
||||
not on their Characters (but see also [quelling](#quelling)).
|
||||
|
||||
In code, you add/remove Permissions via the `PermissionHandler`, which sits on all
|
||||
typeclassed entities as the property `.permissions`:
|
||||
|
|
@ -73,7 +73,7 @@ that permission to pass.
|
|||
## Checking permissions
|
||||
|
||||
It's important to note that you check for the permission of a *puppeted*
|
||||
[Object](./Objects) (like a Character), the check will always first use the
|
||||
[Object](./Objects.md) (like a Character), the check will always first use the
|
||||
permissions of any `Account` connected to that Object before checking for
|
||||
permissions on the Object. In the case of hierarchical permissions (Admins,
|
||||
Builders etc), the Account permission will always be used (this stops an Account
|
||||
|
|
@ -99,7 +99,7 @@ _PermissionHandler_, stored as `.permissions` on all typeclassed entities.
|
|||
Using the `.check` method is the way to go, it will take hierarchical
|
||||
permissions into account, check accounts/sessions etc.
|
||||
|
||||
```warning
|
||||
```{warning}
|
||||
|
||||
Don't confuse `.permissions.check()` with `.permissions.has()`. The .has()
|
||||
method checks if a string is defined specifically on that PermissionHandler.
|
||||
|
|
@ -111,7 +111,7 @@ permissions into account, check accounts/sessions etc.
|
|||
### Lock funcs
|
||||
|
||||
While the `PermissionHandler` offers a simple way to check perms, [Lock
|
||||
strings](Locks) offers a mini-language for describing how something is accessed.
|
||||
strings](./Locks.md) offers a mini-language for describing how something is accessed.
|
||||
The `perm()` _lock function_ is the main tool for using Permissions in locks.
|
||||
|
||||
Let's say we have a `red_key` object. We also have red chests that we want to
|
||||
|
|
@ -153,7 +153,6 @@ There are several variations to the default `perm` lockfunc:
|
|||
objects (regardless of hierarchical perm or not).
|
||||
- `pperm_above` - like `perm_above`, but for Accounts only.
|
||||
|
||||
|
||||
### Some examples
|
||||
|
||||
Adding permissions and checking with locks
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
Evennia consists of two processes, known as *Portal* and *Server*. They can be controlled from
|
||||
inside the game or from the command line as described [here](../Setup/Start-Stop-Reload).
|
||||
inside the game or from the command line as described [here](../Setup/Start-Stop-Reload.md).
|
||||
|
||||
If you are new to the concept, the main purpose of separating the two is to have accounts connect to
|
||||
the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
|
||||
The *spawner* is a system for defining and creating individual objects from a base template called a
|
||||
*prototype*. It is only designed for use with in-game [Objects](./Objects), not any other type of
|
||||
*prototype*. It is only designed for use with in-game [Objects](./Objects.md), not any other type of
|
||||
entity.
|
||||
|
||||
The normal way to create a custom object in Evennia is to make a [Typeclass](./Typeclasses). If you
|
||||
The normal way to create a custom object in Evennia is to make a [Typeclass](./Typeclasses.md). If you
|
||||
haven't read up on Typeclasses yet, think of them as normal Python classes that save to the database
|
||||
behind the scenes. Say you wanted to create a "Goblin" enemy. A common way to do this would be to
|
||||
first create a `Mobile` typeclass that holds everything common to mobiles in the game, like generic
|
||||
|
|
@ -105,12 +105,12 @@ instead.
|
|||
exist.
|
||||
- `destination` - a valid `#dbref`. Only used by exits.
|
||||
- `permissions` - list of permission strings, like `["Accounts", "may_use_red_door"]`
|
||||
- `locks` - a [lock-string](./Locks) like `"edit:all();control:perm(Builder)"`
|
||||
- `locks` - a [lock-string](./Locks.md) like `"edit:all();control:perm(Builder)"`
|
||||
- `aliases` - list of strings for use as aliases
|
||||
- `tags` - list [Tags](./Tags). These are given as tuples `(tag, category, data)`.
|
||||
- `attrs` - list of [Attributes](./Attributes). These are given as tuples `(attrname, value,
|
||||
- `tags` - list [Tags](./Tags.md). These are given as tuples `(tag, category, data)`.
|
||||
- `attrs` - list of [Attributes](./Attributes.md). These are given as tuples `(attrname, value,
|
||||
category, lockstring)`
|
||||
- Any other keywords are interpreted as non-category [Attributes](./Attributes) and their values.
|
||||
- Any other keywords are interpreted as non-category [Attributes](./Attributes.md) and their values.
|
||||
This is
|
||||
convenient for simple Attributes - use `attrs` for full control of Attributes.
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ Deprecated as of Evennia 0.8:
|
|||
- `ndb_<name>` - sets the value of a non-persistent attribute (`"ndb_"` is stripped from the name).
|
||||
This is simply not useful in a prototype and is deprecated.
|
||||
- `exec` - This accepts a code snippet or a list of code snippets to run. This should not be used -
|
||||
use callables or [$protfuncs](./Prototypes#protfuncs) instead (see below).
|
||||
use callables or [$protfuncs](./Prototypes.md#protfuncs) instead (see below).
|
||||
|
||||
### Prototype values
|
||||
|
||||
|
|
@ -160,10 +160,8 @@ that you embed in strings and that has a `$` in front, like
|
|||
"He has $randint(2,5) skulls in a chain around his neck."}
|
||||
```
|
||||
At execution time, the place of the protfunc will be replaced with the result of that protfunc being
|
||||
called (this is always a string). A protfunc works in much the same way as an
|
||||
[InlineFunc](../Concepts/TextTags#inline-functions) - they are actually
|
||||
parsed using the same parser - except protfuncs are run every time the prototype is used to spawn a
|
||||
new object (whereas an inlinefunc is called when a text is returned to the user).
|
||||
called (this is always a string). A protfunc is a [FuncParser function](./FuncParser.md) run
|
||||
every time the prototype is used to spawn a new object.
|
||||
|
||||
Here is how a protfunc is defined (same as an inlinefunc).
|
||||
|
||||
|
|
@ -233,7 +231,7 @@ A prototype can be defined and stored in two ways, either in the database or as
|
|||
|
||||
### Database prototypes
|
||||
|
||||
Stored as [Scripts](./Scripts) in the database. These are sometimes referred to as *database-
|
||||
Stored as [Scripts](./Scripts.md) in the database. These are sometimes referred to as *database-
|
||||
prototypes* This is the only way for in-game builders to modify and add prototypes. They have the
|
||||
advantage of being easily modifiable and sharable between builders but you need to work with them
|
||||
using in-game tools.
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
# Scripts
|
||||
|
||||
[Script API reference](api:evennia.scripts.scripts)
|
||||
[Script API reference](evennia.scripts.scripts)
|
||||
|
||||
*Scripts* are the out-of-character siblings to the in-character
|
||||
[Objects](./Objects). Scripts are so flexible that the name "Script" is a bit limiting
|
||||
[Objects](./Objects.md). Scripts are so flexible that the name "Script" is a bit limiting
|
||||
in itself - but we had to pick _something_ to name them. Other possible names
|
||||
(depending on what you'd use them for) would be `OOBObjects`, `StorageContainers` or `TimerObjects`.
|
||||
|
||||
If you ever consider creating an [Object](./Objects) with a `None`-location just to store some game data,
|
||||
If you ever consider creating an [Object](./Objects.md) with a `None`-location just to store some game data,
|
||||
you should really be using a Script instead.
|
||||
|
||||
- Scripts are full [Typeclassed](./Typeclasses) entities - they have [Attributes](./Attributes) and
|
||||
- Scripts are full [Typeclassed](./Typeclasses.md) entities - they have [Attributes](./Attributes.md) and
|
||||
can be modified in the same way. But they have _no in-game existence_, so no
|
||||
location or command-execution like [Objects](./Objects) and no connection to a particular
|
||||
player/session like [Accounts](./Accounts). This means they are perfectly suitable for acting
|
||||
location or command-execution like [Objects](./Objects.md) and no connection to a particular
|
||||
player/session like [Accounts](./Accounts.md). This means they are perfectly suitable for acting
|
||||
as database-storage backends for game _systems_: Storing the current state of the economy,
|
||||
who is involved in the current fight, tracking an ongoing barter and so on. They are great as
|
||||
persistent system handlers.
|
||||
|
|
@ -21,22 +21,22 @@ you should really be using a Script instead.
|
|||
to tick the `at_repeat` hook on the Script at a certain interval. The timer can be controlled
|
||||
independently of the rest of the script as needed. This component is optional
|
||||
and complementary to other timing functions in Evennia, like
|
||||
[evennia.utils.delay](api:evennia.utils.utils#evennia.utils.utils.delay) and
|
||||
[evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat).
|
||||
[evennia.utils.delay](evennia.utils.utils.delay) and
|
||||
[evennia.utils.repeat](evennia.utils.utils.repeat).
|
||||
- Scripts can _attach_ to Objects and Accounts via e.g. `obj.scripts.add/remove`. In the
|
||||
script you can then access the object/account as `self.obj` or `self.account`. This can be used to
|
||||
dynamically extend other typeclasses but also to use the timer component to affect the parent object
|
||||
in various ways. For historical reasons, a Script _not_ attached to an object is referred to as a
|
||||
_Global_ Script.
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
In previus Evennia versions, stopping the Script's timer also meant deleting the Script object.
|
||||
Starting with this version, the timer can be start/stopped separately and `.delete()` must be called
|
||||
on the Script explicitly to delete it.
|
||||
|
||||
```
|
||||
|
||||
### In-game command examples
|
||||
## In-game command examples
|
||||
|
||||
There are two main commands controlling scripts in the default cmdset:
|
||||
|
||||
|
|
@ -52,11 +52,11 @@ The `scripts` command is used to view all scripts and perform operations on them
|
|||
> scripts/pause #11
|
||||
> scripts/delete #566
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
The `addscript` command used to be only `script` which was easy to confuse with `scripts`.
|
||||
```
|
||||
|
||||
### Code examples
|
||||
## Code examples
|
||||
|
||||
Here are some examples of working with Scripts in-code (more details to follow in later
|
||||
sections).
|
||||
|
|
@ -111,13 +111,13 @@ new_script.delete()
|
|||
timed_script.delete()
|
||||
```
|
||||
|
||||
## Defining new Scripts
|
||||
# Defining new Scripts
|
||||
|
||||
A Script is defined as a class and is created in the same way as other
|
||||
[typeclassed](./Typeclasses) entities. The parent class is `evennia.DefaultScript`.
|
||||
[typeclassed](./Typeclasses.md) entities. The parent class is `evennia.DefaultScript`.
|
||||
|
||||
|
||||
### Simple storage script
|
||||
## Simple storage script
|
||||
|
||||
In `mygame/typeclasses/scripts.py` is an empty `Script` class already set up. You
|
||||
can use this as a base for your own scripts.
|
||||
|
|
@ -162,12 +162,12 @@ evennia.create_script('typeclasses.scripts.MyScript', key="another name",
|
|||
|
||||
```
|
||||
|
||||
See the [create_script](api:evennia.utils.create#evennia.utils.create.create_script) and
|
||||
[search_script](api:evennia.utils.search#evennia.utils.search.search_script) API documentation for more options
|
||||
See the [create_script](evennia.utils.create.create_script) and
|
||||
[search_script](evennia.utils.search.search_script) API documentation for more options
|
||||
on creating and finding Scripts.
|
||||
|
||||
|
||||
### Timed Scripts
|
||||
## Timed Scripts
|
||||
|
||||
There are several properties one can set on the Script to control its timer component.
|
||||
|
||||
|
|
@ -229,11 +229,11 @@ The timer component is controlled with methods on the Script class:
|
|||
- `.force_repeat()` - this prematurely forces `at_repeat` to be called right away. Doing so will reset the
|
||||
countdown so that next call will again happen after `interval` seconds.
|
||||
|
||||
#### Script timers vs delay/repeat
|
||||
### Script timers vs delay/repeat
|
||||
|
||||
If the _only_ goal is to get a repeat/delay effect, the
|
||||
[evennia.utils.delay](api:evennia.utils.utils#evennia.utils.utils.delay) and
|
||||
[evennia.utils.repeat](api:evennia.utils.utils#evennia.utils.utils.repeat) functions
|
||||
[evennia.utils.delay](evennia.utils.utils.delay) and
|
||||
[evennia.utils.repeat](evennia.utils.utils.repeat) functions
|
||||
should generally be considered first. A Script is a lot 'heavier' to create/delete on the fly.
|
||||
In fact, for making a single delayed call (`script.repeats==1`), the `utils.delay` call is
|
||||
probably always the better choice.
|
||||
|
|
@ -249,9 +249,9 @@ It's also worth noting that once the script object has _already been created_,
|
|||
starting/stopping/pausing/unpausing the timer has very little overhead. The pause/unpause and update
|
||||
methods of the script also offers a bit more fine-control than using `utils.delays/repeat`.
|
||||
|
||||
### Script attached to another object
|
||||
## Script attached to another object
|
||||
|
||||
Scripts can be attached to an [Account](./Accounts) or (more commonly) an [Object](./Objects).
|
||||
Scripts can be attached to an [Account](./Accounts.md) or (more commonly) an [Object](./Objects.md).
|
||||
If so, the 'parent object' will be available to the script as either `.obj` or `.account`.
|
||||
|
||||
|
||||
|
|
@ -303,10 +303,10 @@ You can also attach the script as part of creating it:
|
|||
create_script('typeclasses.weather.Weather', obj=myroom)
|
||||
```
|
||||
|
||||
## Other Script methods
|
||||
# Other Script methods
|
||||
|
||||
A Script has all the properties of a typeclassed object, such as `db` and `ndb`(see
|
||||
[Typeclasses](./Typeclasses)). Setting `key` is useful in order to manage scripts (delete them by name
|
||||
[Typeclasses](./Typeclasses.md)). Setting `key` is useful in order to manage scripts (delete them by name
|
||||
etc). These are usually set up in the Script's typeclass, but can also be assigned on the fly as
|
||||
keyword arguments to `evennia.create_script`.
|
||||
|
||||
|
|
@ -325,12 +325,12 @@ reload.
|
|||
- `delete()` - same as for other typeclassed entities, this will delete the Script. Of note is that
|
||||
it will also stop the timer (if it runs), leading to the `at_stop` hook being called.
|
||||
|
||||
In addition, Scripts support [Attributes](./Attributes), [Tags](./Tags) and [Locks](./Locks) etc like other
|
||||
In addition, Scripts support [Attributes](./Attributes.md), [Tags](./Tags.md) and [Locks](./Locks.md) etc like other
|
||||
Typeclassed entities.
|
||||
|
||||
See also the methods involved in controlling a [Timed Script](#Timed_Scripts) above.
|
||||
See also the methods involved in controlling a [Timed Script](#timed-scripts) above.
|
||||
|
||||
## The GLOBAL_SCRIPTS container
|
||||
# The GLOBAL_SCRIPTS container
|
||||
|
||||
A Script not attached to another entity is commonly referred to as a _Global_ script since it't available
|
||||
to access from anywhere. This means they need to be searched for in order to be used.
|
||||
|
|
@ -353,7 +353,7 @@ GLOBAL_SCRIPTS.weather.db.current_weather = "Cloudy"
|
|||
|
||||
```
|
||||
|
||||
```warning::
|
||||
```{warning}
|
||||
Note that global scripts appear as properties on `GLOBAL_SCRIPTS` based on their `key`.
|
||||
If you were to create two global scripts with the same `key` (even with different typeclasses),
|
||||
the `GLOBAL_SCRIPTS` container will only return one of them (which one depends on order in
|
||||
|
|
@ -389,10 +389,10 @@ GLOBAL_SCRIPTS = {
|
|||
Above we add two scripts with keys `myscript` and `storagescript`respectively. The following dict
|
||||
can be empty - the `settings.BASE_SCRIPT_TYPECLASS` will then be used. Under the hood, the provided
|
||||
dict (along with the `key`) will be passed into `create_script` automatically, so
|
||||
all the [same keyword arguments as for create_script](api:evennia.utils.create.create_script) are
|
||||
all the [same keyword arguments as for create_script](evennia.utils.create.create_script) are
|
||||
supported here.
|
||||
|
||||
```warning::
|
||||
```{warning}
|
||||
Before setting up Evennia to manage your script like this, make sure that your Script typeclass
|
||||
does not have any critical errors (test it separately). If there are, you'll see errors in your log
|
||||
and your Script will temporarily fall back to being a `DefaultScript` type.
|
||||
|
|
@ -413,7 +413,7 @@ That is, if the script is deleted, next time you get it from `GLOBAL_SCRIPTS`, E
|
|||
information in settings to recreate it for you on the fly.
|
||||
|
||||
|
||||
## Hints: Dealing with Script Errors
|
||||
# Hints: Dealing with Script Errors
|
||||
|
||||
Errors inside a timed, executing script can sometimes be rather terse or point to
|
||||
parts of the execution mechanism that is hard to interpret. One way to make it
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
# Server Conf
|
||||
|
||||
|
||||
Evennia runs out of the box without any changes to its settings. But there are several important
|
||||
ways to customize the server and expand it with your own plugins.
|
||||
|
||||
## Settings file
|
||||
|
||||
The "Settings" file referenced throughout the documentation is the file
|
||||
`mygame/server/conf/settings.py`. This is automatically created on the first run of `evennia --init`
|
||||
(see the [Setup Quickstart](../Setup/Setup-Quickstart) page).
|
||||
|
||||
Your new `settings.py` is relatively bare out of the box. Evennia's core settings file is actually
|
||||
[evennia/settings_default.py](https://github.com/evennia/evennia/blob/master/evennia/settings_default.py)
|
||||
and is considerably more extensive (it is also heavily documented so you should refer to this file
|
||||
directly for the available settings).
|
||||
|
||||
Since `mygame/server/conf/settings.py` is a normal Python module, it simply imports
|
||||
`evennia/settings_default.py` into itself at the top.
|
||||
|
||||
This means that if any setting you want to change were to depend on some *other* default setting,
|
||||
you might need to copy & paste both in order to change them and get the effect you want (for most
|
||||
commonly changed settings, this is not something you need to worry about).
|
||||
|
||||
You should never edit `evennia/settings_default.py`. Rather you should copy&paste the select
|
||||
variables you want to change into your `settings.py` and edit them there. This will overload the
|
||||
previously imported defaults.
|
||||
|
||||
> Warning: It may be tempting to copy everything from `settings_default.py` into your own settings
|
||||
file. There is a reason we don't do this out of the box though: it makes it directly clear what
|
||||
changes you did. Also, if you limit your copying to the things you really need you will directly be
|
||||
able to take advantage of upstream changes and additions to Evennia for anything you didn't
|
||||
customize.
|
||||
|
||||
In code, the settings is accessed through
|
||||
|
||||
```python
|
||||
from django.conf import settings
|
||||
# or (shorter):
|
||||
from evennia import settings
|
||||
# example:
|
||||
servername = settings.SERVER_NAME
|
||||
```
|
||||
|
||||
Each setting appears as a property on the imported `settings` object. You can also explore all
|
||||
possible options with `evennia.settings_full` (this also includes advanced Django defaults that are
|
||||
not touched in default Evennia).
|
||||
|
||||
> It should be pointed out that when importing `settings` into your code like this, it will be *read
|
||||
only*. You *cannot* edit your settings from your code! The only way to change an Evennia setting is
|
||||
to edit `mygame/server/conf/settings.py` directly. You also generally need to restart the server
|
||||
(possibly also the Portal) before a changed setting becomes available.
|
||||
|
||||
## Other files in the `server/conf` directory
|
||||
|
||||
Apart from the main `settings.py` file,
|
||||
|
||||
- `at_initial_setup.py` - this allows you to add a custom startup method to be called (only) the
|
||||
very first time Evennia starts (at the same time as user #1 and Limbo is created). It can be made to
|
||||
start your own global scripts or set up other system/world-related things your game needs to have
|
||||
running from the start.
|
||||
- `at_server_startstop.py` - this module contains two functions that Evennia will call every time
|
||||
the Server starts and stops respectively - this includes stopping due to reloading and resetting as
|
||||
well as shutting down completely. It's a useful place to put custom startup code for handlers and
|
||||
other things that must run in your game but which has no database persistence.
|
||||
- `connection_screens.py` - all global string variables in this module are interpreted by Evennia as
|
||||
a greeting screen to show when an Account first connects. If more than one string variable is
|
||||
present in the module a random one will be picked.
|
||||
- `inlinefuncs.py` - this is where you can define custom [Inline functions](../Concepts/TextTags#inlinefuncs).
|
||||
- `inputfuncs.py` - this is where you define custom [Input functions](./Inputfuncs) to handle data
|
||||
from the client.
|
||||
- `lockfuncs.py` - this is one of many possible modules to hold your own "safe" *lock functions* to
|
||||
make available to Evennia's [Locks](./Locks).
|
||||
- `mssp.py` - this holds meta information about your game. It is used by MUD search engines (which
|
||||
you often have to register with) in order to display what kind of game you are running along with
|
||||
statistics such as number of online accounts and online status.
|
||||
- `oobfuncs.py` - in here you can define custom [OOB functions](../Concepts/OOB).
|
||||
- `portal_services_plugin.py` - this allows for adding your own custom services/protocols to the
|
||||
Portal. It must define one particular function that will be called by Evennia at startup. There can
|
||||
be any number of service plugin modules, all will be imported and used if defined. More info can be
|
||||
found [here](https://code.google.com/p/evennia/wiki/SessionProtocols#Adding_custom_Protocols).
|
||||
- `server_services_plugin.py` - this is equivalent to the previous one, but used for adding new
|
||||
services to the Server instead. More info can be found
|
||||
[here](https://code.google.com/p/evennia/wiki/SessionProtocols#Adding_custom_Protocols).
|
||||
|
||||
Some other Evennia systems can be customized by plugin modules but has no explicit template in
|
||||
`conf/`:
|
||||
|
||||
- *cmdparser.py* - a custom module can be used to totally replace Evennia's default command parser.
|
||||
All this does is to split the incoming string into "command name" and "the rest". It also handles
|
||||
things like error messages for no-matches and multiple-matches among other things that makes this
|
||||
more complex than it sounds. The default parser is *very* generic, so you are most often best served
|
||||
by modifying things further down the line (on the command parse level) than here.
|
||||
- *at_search.py* - this allows for replacing the way Evennia handles search results. It allows to
|
||||
change how errors are echoed and how multi-matches are resolved and reported (like how the default
|
||||
understands that "2-ball" should match the second "ball" object if there are two of them in the
|
||||
room).
|
||||
|
||||
## ServerConf
|
||||
|
||||
There is a special database model called `ServerConf` that stores server internal data and settings
|
||||
such as current account count (for interfacing with the webserver), startup status and many other
|
||||
things. It's rarely of use outside the server core itself but may be good to
|
||||
know about if you are an Evennia developer.
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
# Server component
|
||||
|
||||
TODO: This is currently in [Portal-and-Server](./Portal-And-Server).
|
||||
TODO: This is currently in [Portal-and-Server](./Portal-And-Server.md).
|
||||
|
|
@ -5,14 +5,14 @@ An Evennia *Session* represents one single established connection to the server.
|
|||
Evennia session, it is possible for a person to connect multiple times, for example using different
|
||||
clients in multiple windows. Each such connection is represented by a session object.
|
||||
|
||||
A session object has its own [cmdset](./Command-Sets), usually the "unloggedin" cmdset. This is what
|
||||
A session object has its own [cmdset](./Command-Sets.md), usually the "unloggedin" cmdset. This is what
|
||||
is used to show the login screen and to handle commands to create a new account (or
|
||||
[Account](./Accounts) in evennia lingo) read initial help and to log into the game with an existing
|
||||
[Account](./Accounts.md) in evennia lingo) read initial help and to log into the game with an existing
|
||||
account. A session object can either be "logged in" or not. Logged in means that the user has
|
||||
authenticated. When this happens the session is associated with an Account object (which is what
|
||||
holds account-centric stuff). The account can then in turn puppet any number of objects/characters.
|
||||
|
||||
> Warning: A Session is not *persistent* - it is not a [Typeclass](./Typeclasses) and has no
|
||||
> Warning: A Session is not *persistent* - it is not a [Typeclass](./Typeclasses.md) and has no
|
||||
connection to the database. The Session will go away when a user disconnects and you will lose any
|
||||
custom data on it if the server reloads. The `.db` handler on Sessions is there to present a uniform
|
||||
API (so you can assume `.db` exists even if you don't know if you receive an Object or a Session),
|
||||
|
|
@ -26,13 +26,13 @@ Here are some important properties available on (Server-)Sessions
|
|||
- `sessid` - The unique session-id. This is an integer starting from 1.
|
||||
- `address` - The connected client's address. Different protocols give different information here.
|
||||
- `logged_in` - `True` if the user authenticated to this session.
|
||||
- `account` - The [Account](./Accounts) this Session is attached to. If not logged in yet, this is
|
||||
- `account` - The [Account](./Accounts.md) this Session is attached to. If not logged in yet, this is
|
||||
`None`.
|
||||
- `puppet` - The [Character/Object](./Objects) currently puppeted by this Account/Session combo. If
|
||||
- `puppet` - The [Character/Object](./Objects.md) currently puppeted by this Account/Session combo. If
|
||||
not logged in or in OOC mode, this is `None`.
|
||||
- `ndb` - The [Non-persistent Attribute](./Attributes) handler.
|
||||
- `ndb` - The [Non-persistent Attribute](./Attributes.md) handler.
|
||||
- `db` - As noted above, Sessions don't have regular Attributes. This is an alias to `ndb`.
|
||||
- `cmdset` - The Session's [CmdSetHandler](./Command-Sets)
|
||||
- `cmdset` - The Session's [CmdSetHandler](./Command-Sets.md)
|
||||
|
||||
Session statistics are mainly used internally by Evennia.
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ transparently detect which session was triggering the command (if any) and redir
|
|||
`command.msg()` is often the safest bet.
|
||||
|
||||
You can get the `session` in two main ways:
|
||||
* [Accounts](./Accounts) and [Objects](./Objects) (including Characters) have a `sessions` property.
|
||||
* [Accounts](./Accounts.md) and [Objects](./Objects.md) (including Characters) have a `sessions` property.
|
||||
This is a *handler* that tracks all Sessions attached to or puppeting them. Use e.g.
|
||||
`accounts.sessions.get()` to get a list of Sessions attached to that entity.
|
||||
* A Command instance has a `session` property that always points back to the Session that triggered
|
||||
|
|
@ -132,7 +132,7 @@ changes carefully.
|
|||
|
||||
*Note: This is considered an advanced topic. You don't need to know this on a first read-through.*
|
||||
|
||||
Evennia is split into two parts, the [Portal and the Server](./Portal-And-Server). Each side tracks
|
||||
Evennia is split into two parts, the [Portal and the Server](./Portal-And-Server.md). Each side tracks
|
||||
its own Sessions, syncing them to each other.
|
||||
|
||||
The "Session" we normally refer to is actually the `ServerSession`. Its counter-part on the Portal
|
||||
|
|
@ -172,7 +172,7 @@ server reboot (assuming the Portal is not stopped at the same time, obviously).
|
|||
Both the Portal and Server each have a *sessionhandler* to manage the connections. These handlers
|
||||
are global entities contain all methods for relaying data across the AMP bridge. All types of
|
||||
Sessions hold a reference to their respective Sessionhandler (the property is called
|
||||
`sessionhandler`) so they can relay data. See [protocols](../Concepts/Custom-Protocols) for more info
|
||||
`sessionhandler`) so they can relay data. See [protocols](../Concepts/Custom-Protocols.md) for more info
|
||||
on building new protocols.
|
||||
|
||||
To get all Sessions in the game (i.e. all currently connected clients), you access the server-side
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ be extracted from the `**kwargs` dict in the signal handler.
|
|||
used way for users to themselves create accounts during login. It passes and extra kwarg `ip` with
|
||||
the client IP of the connecting account.
|
||||
- `SIGNAL_ACCOUNT_POST_LOGIN` - this will always fire when the account has authenticated. Sends
|
||||
extra kwarg `session` with the new [Session](./Sessions) object involved.
|
||||
extra kwarg `session` with the new [Session](./Sessions.md) object involved.
|
||||
- `SIGNAL_ACCCOUNT_POST_FIRST_LOGIN` - this fires just before `SIGNAL_ACCOUNT_POST_LOGIN` but only
|
||||
if
|
||||
this is the *first* connection done (that is, if there are no previous sessions connected). Also
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ currently dead.
|
|||
*Tags* are short text labels that you attach to objects so as to easily be able to retrieve and
|
||||
group them. An Evennia entity can be tagged with any number of Tags. On the database side, Tag
|
||||
entities are *shared* between all objects with that tag. This makes them very efficient but also
|
||||
fundamentally different from [Attributes](./Attributes), each of which always belongs to one *single*
|
||||
fundamentally different from [Attributes](./Attributes.md), each of which always belongs to one *single*
|
||||
object.
|
||||
|
||||
In Evennia, Tags are technically also used to implement `Aliases` (alternative names for objects)
|
||||
and `Permissions` (simple strings for [Locks](./Locks) to check for).
|
||||
and `Permissions` (simple strings for [Locks](./Locks.md) to check for).
|
||||
|
||||
|
||||
## Properties of Tags (and Aliases and Permissions)
|
||||
|
|
@ -26,7 +26,7 @@ unique key + category combination.
|
|||
|
||||
When Tags are assigned to game entities, these entities are actually sharing the same Tag. This
|
||||
means that Tags are not suitable for storing information about a single object - use an
|
||||
[Attribute](./Attributes) for this instead. Tags are a lot more limited than Attributes but this also
|
||||
[Attribute](./Attributes.md) for this instead. Tags are a lot more limited than Attributes but this also
|
||||
makes them very quick to lookup in the database - this is the whole point.
|
||||
|
||||
Tags have the following properties, stored in the database:
|
||||
|
|
@ -52,8 +52,8 @@ free up the *category* property for any use you desire.
|
|||
|
||||
## Adding/Removing Tags
|
||||
|
||||
You can tag any *typeclassed* object, namely [Objects](./Objects), [Accounts](./Accounts),
|
||||
[Scripts](./Scripts) and [Channels](./Communications). General tags are added by the *Taghandler*. The
|
||||
You can tag any *typeclassed* object, namely [Objects](./Objects.md), [Accounts](./Accounts.md),
|
||||
[Scripts](./Scripts.md) and [Channels](./Communications.md). General tags are added by the *Taghandler*. The
|
||||
tag handler is accessed as a property `tags` on the relevant entity:
|
||||
|
||||
```python
|
||||
|
|
@ -135,7 +135,7 @@ objs = evennia.search_tag(category="bar")
|
|||
|
||||
|
||||
|
||||
There is also an in-game command that deals with assigning and using ([Object-](./Objects)) tags:
|
||||
There is also an in-game command that deals with assigning and using ([Object-](./Objects.md)) tags:
|
||||
|
||||
@tag/search furniture
|
||||
|
||||
|
|
@ -166,4 +166,4 @@ That said, tag categories can be useful if you build some game system that uses
|
|||
use tag categories to make sure to separate tags created with this system from any other tags
|
||||
created elsewhere. You can then supply custom search methods that *only* find objects tagged with
|
||||
tags of that category. An example of this
|
||||
is found in the [Zone tutorial](../Concepts/Zones).
|
||||
is found in the [Zone tutorial](../Concepts/Zones.md).
|
||||
|
|
@ -11,7 +11,7 @@ hard-coded to rely on the concept of the global 'tick'. Evennia has no such noti
|
|||
use tickers is very much up to the need of your game and which requirements you have. The "ticker
|
||||
recipe" is just one way of cranking the wheels.
|
||||
|
||||
The most fine-grained way to manage the flow of time is of course to use [Scripts](./Scripts). Many
|
||||
The most fine-grained way to manage the flow of time is of course to use [Scripts](./Scripts.md). Many
|
||||
types of operations (weather being the classic example) are however done on multiple objects in the
|
||||
same way at regular intervals, and for this, storing separate Scripts on each object is inefficient.
|
||||
The way to do this is to use a ticker with a "subscription model" - let objects sign up to be
|
||||
|
|
@ -98,13 +98,13 @@ The `callable` can be on any form as long as it accepts the arguments you give t
|
|||
|
||||
> Note that everything you supply to the TickerHandler will need to be pickled at some point to be
|
||||
saved into the database. Most of the time the handler will correctly store things like database
|
||||
objects, but the same restrictions as for [Attributes](./Attributes) apply to what the TickerHandler
|
||||
objects, but the same restrictions as for [Attributes](./Attributes.md) apply to what the TickerHandler
|
||||
may store.
|
||||
|
||||
When testing, you can stop all tickers in the entire game with `tickerhandler.clear()`. You can also
|
||||
view the currently subscribed objects with `tickerhandler.all()`.
|
||||
|
||||
See the [Weather Tutorial](../Howto/Weather-Tutorial) for an example of using the TickerHandler.
|
||||
See the [Weather Tutorial](../Howto/Weather-Tutorial.md) for an example of using the TickerHandler.
|
||||
|
||||
### When *not* to use TickerHandler
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
different game entities as Python classes, without having to modify the database schema for every
|
||||
new type.
|
||||
|
||||
In Evennia the most important game entities, [Accounts](./Accounts), [Objects](./Objects),
|
||||
[Scripts](./Scripts) and [Channels](./Communications#Channels) are all Python classes inheriting, at
|
||||
In Evennia the most important game entities, [Accounts](./Accounts.md), [Objects](./Objects.md),
|
||||
[Scripts](./Scripts.md) and [Channels](./Channels.md) are all Python classes inheriting, at
|
||||
varying distance, from `evennia.typeclasses.models.TypedObject`. In the documentation we refer to
|
||||
these objects as being "typeclassed" or even "being a typeclass".
|
||||
|
||||
|
|
@ -48,14 +48,14 @@ module from anywhere, the `typeclass/list` will not find it. To make it known
|
|||
to Evennia you must import that module from somewhere.
|
||||
|
||||
|
||||
### Difference between typeclasses and classes
|
||||
## Difference between typeclasses and classes
|
||||
|
||||
All Evennia classes inheriting from class in the table above share one important feature and two
|
||||
important limitations. This is why we don't simply call them "classes" but "typeclasses".
|
||||
|
||||
1. A typeclass can save itself to the database. This means that some properties (actually not that
|
||||
many) on the class actually represents database fields and can only hold very specific data types.
|
||||
This is detailed [below](./Typeclasses#about-typeclass-properties).
|
||||
This is detailed [below](./Typeclasses.md#about-typeclass-properties).
|
||||
1. Due to its connection to the database, the typeclass' name must be *unique* across the _entire_
|
||||
server namespace. That is, there must never be two same-named classes defined anywhere. So the below
|
||||
code would give an error (since `DefaultObject` is now globally found both in this module and in the
|
||||
|
|
@ -82,7 +82,7 @@ both accept arbitrary keyword arguments and use `super` to call its parent::
|
|||
```
|
||||
|
||||
Apart from this, a typeclass works like any normal Python class and you can
|
||||
treat it as such.
|
||||
treat it as such.
|
||||
|
||||
|
||||
## Creating a new typeclass
|
||||
|
|
@ -129,11 +129,11 @@ argument; this can both be the actual class or the python path to the typeclass
|
|||
game directory. So if your `Furniture` typeclass sits in `mygame/typeclasses/furniture.py`, you
|
||||
could point to it as `typeclasses.furniture.Furniture`. Since Evennia will itself look in
|
||||
`mygame/typeclasses`, you can shorten this even further to just `furniture.Furniture`. The create-
|
||||
functions take a lot of extra keywords allowing you to set things like [Attributes](./Attributes) and
|
||||
[Tags](./Tags) all in one go. These keywords don't use the `db_*` prefix. This will also automatically
|
||||
functions take a lot of extra keywords allowing you to set things like [Attributes](./Attributes.md) and
|
||||
[Tags](./Tags.md) all in one go. These keywords don't use the `db_*` prefix. This will also automatically
|
||||
save the new instance to the database, so you don't need to call `save()` explicitly.
|
||||
|
||||
### About typeclass properties
|
||||
## About typeclass properties
|
||||
|
||||
An example of a database field is `db_key`. This stores the "name" of the entity you are modifying
|
||||
and can thus only hold a string. This is one way of making sure to update the `db_key`:
|
||||
|
|
@ -178,36 +178,36 @@ returns the string form "#id".
|
|||
|
||||
The typeclassed entity has several common handlers:
|
||||
|
||||
- `tags` - the [TagHandler](./Tags) that handles tagging. Use `tags.add()` , `tags.get()` etc.
|
||||
- `locks` - the [LockHandler](./Locks) that manages access restrictions. Use `locks.add()`,
|
||||
- `tags` - the [TagHandler](./Tags.md) that handles tagging. Use `tags.add()` , `tags.get()` etc.
|
||||
- `locks` - the [LockHandler](./Locks.md) that manages access restrictions. Use `locks.add()`,
|
||||
`locks.get()` etc.
|
||||
- `attributes` - the [AttributeHandler](./Attributes) that manages Attributes on the object. Use
|
||||
- `attributes` - the [AttributeHandler](./Attributes.md) that manages Attributes on the object. Use
|
||||
`attributes.add()`
|
||||
etc.
|
||||
- `db` (DataBase) - a shortcut property to the AttributeHandler; allowing `obj.db.attrname = value`
|
||||
- `nattributes` - the [Non-persistent AttributeHandler](./Attributes) for attributes not saved in the
|
||||
- `nattributes` - the [Non-persistent AttributeHandler](./Attributes.md) for attributes not saved in the
|
||||
database.
|
||||
- `ndb` (NotDataBase) - a shortcut property to the Non-peristent AttributeHandler. Allows
|
||||
`obj.ndb.attrname = value`
|
||||
|
||||
|
||||
Each of the typeclassed entities then extend this list with their own properties. Go to the
|
||||
respective pages for [Objects](./Objects), [Scripts](./Scripts), [Accounts](./Accounts) and
|
||||
[Channels](./Communications) for more info. It's also recommended that you explore the available
|
||||
entities using [Evennia's flat API](../Evennia-API) to explore which properties and methods they have
|
||||
respective pages for [Objects](./Objects.md), [Scripts](./Scripts.md), [Accounts](./Accounts.md) and
|
||||
[Channels](./Communications.md) for more info. It's also recommended that you explore the available
|
||||
entities using [Evennia's flat API](../Evennia-API.md) to explore which properties and methods they have
|
||||
available.
|
||||
|
||||
### Overloading hooks
|
||||
## Overloading hooks
|
||||
|
||||
The way to customize typeclasses is usually to overload *hook methods* on them. Hooks are methods
|
||||
that Evennia call in various situations. An example is the `at_object_creation` hook on `Objects`,
|
||||
which is only called once, the very first time this object is saved to the database. Other examples
|
||||
are the `at_login` hook of Accounts and the `at_repeat` hook of Scripts.
|
||||
|
||||
### Querying for typeclasses
|
||||
## Querying for typeclasses
|
||||
|
||||
Most of the time you search for objects in the database by using convenience methods like the
|
||||
`caller.search()` of [Commands](./Commands) or the search functions like `evennia.search_objects`.
|
||||
`caller.search()` of [Commands](./Commands.md) or the search functions like `evennia.search_objects`.
|
||||
|
||||
You can however also query for them directly using [Django's query
|
||||
language](https://docs.djangoproject.com/en/1.7/topics/db/queries/). This makes use of a _database
|
||||
|
|
@ -245,13 +245,13 @@ matches = ScriptDB.objects.filter(db_key__contains="Combat")
|
|||
When querying from the database model parent you don't need to use `filter_family` or `get_family` -
|
||||
you will always query all children on the database model.
|
||||
|
||||
## Updating existing typeclass instances
|
||||
# Updating existing typeclass instances
|
||||
|
||||
If you already have created instances of Typeclasses, you can modify the *Python code* at any time -
|
||||
due to how Python inheritance works your changes will automatically be applied to all children once
|
||||
you have reloaded the server.
|
||||
|
||||
However, database-saved data, like `db_*` fields, [Attributes](./Attributes), [Tags](./Tags) etc, are
|
||||
However, database-saved data, like `db_*` fields, [Attributes](./Attributes.md), [Tags](./Tags.md) etc, are
|
||||
not themselves embedded into the class and will *not* be updated automatically. This you need to
|
||||
manage yourself, by searching for all relevant objects and updating or adding the data:
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ The arguments to this method are described [in the API docs
|
|||
here](github:evennia.typeclasses.models#typedobjectswap_typeclass).
|
||||
|
||||
|
||||
## How typeclasses actually work
|
||||
# How typeclasses actually work
|
||||
|
||||
*This is considered an advanced section.*
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ Technically, typeclasses are [Django proxy
|
|||
models](https://docs.djangoproject.com/en/1.7/topics/db/models/#proxy-models). The only database
|
||||
models that are "real" in the typeclass system (that is, are represented by actual tables in the
|
||||
database) are `AccountDB`, `ObjectDB`, `ScriptDB` and `ChannelDB` (there are also
|
||||
[Attributes](./Attributes) and [Tags](./Tags) but they are not typeclasses themselves). All the
|
||||
[Attributes](./Attributes.md) and [Tags](./Tags.md) but they are not typeclasses themselves). All the
|
||||
subclasses of them are "proxies", extending them with Python code without actually modifying the
|
||||
database layout.
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ Evennia modifies Django's proxy model in various ways to allow them to work with
|
|||
handles this for you using metaclasses). Evennia also makes sure you can query subclasses as well as
|
||||
patches django to allow multiple inheritance from the same base class.
|
||||
|
||||
### Caveats
|
||||
## Caveats
|
||||
|
||||
Evennia uses the *idmapper* to cache its typeclasses (Django proxy models) in memory. The idmapper
|
||||
allows things like on-object handlers and properties to be stored on typeclass instances and to not
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ meant to be accessed in code, by other programs.
|
|||
The API is using [Django Rest Framework][drf]. This automates the process
|
||||
of setting up _views_ (Python code) to process the result of web requests.
|
||||
The process of retrieving data is similar to that explained on the
|
||||
[Webserver](./Webserver) page, except the views will here return [JSON][json]
|
||||
[Webserver](./Webserver.md) page, except the views will here return [JSON][json]
|
||||
data for the resource you want. You can also _send_ such JSON data
|
||||
in order to update the database from the outside.
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ To activate the API, add this to your settings file.
|
|||
The main controlling setting is `REST_FRAMEWORK`, which is a dict. The keys
|
||||
`DEFAULT_LIST_PERMISSION` and `DEFAULT_CREATE_PERMISSIONS` control who may
|
||||
view and create new objects via the api respectively. By default, users with
|
||||
['Builder'-level permission](./Permissions) or higher may access both actions.
|
||||
['Builder'-level permission](./Permissions.md) or higher may access both actions.
|
||||
|
||||
While the api is meant to be expanded upon, Evennia supplies several operations
|
||||
out of the box. If you click the `Autodoc` button in the upper right of the `/api`
|
||||
|
|
@ -74,7 +74,7 @@ permissions:
|
|||
"results": [{"username": "bob",...}]
|
||||
}
|
||||
|
||||
Now suppose that you want to use the API to create an [Object](./Objects):
|
||||
Now suppose that you want to use the API to create an [Object](./Objects.md):
|
||||
|
||||
>>> data = {"db_key": "A shiny sword"}
|
||||
>>> response = requests.post("https://www.mygame.com/api/objects",
|
||||
|
|
@ -108,7 +108,7 @@ Overall, reading up on [Django Rest Framework ViewSets](https://www.django-rest-
|
|||
other parts of their documentation is required for expanding and
|
||||
customizing the API.
|
||||
|
||||
Check out the [Website](./Website) page for help on how to override code, templates
|
||||
Check out the [Website](./Website.md) page for help on how to override code, templates
|
||||
and static files.
|
||||
- API templates (for the web-display) is located in `evennia/web/api/templates/rest_framework/` (it must
|
||||
be named such to allow override of the original REST framework templates).
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ objects are actually stored as a `tuple` with object-unique data.
|
|||
you'll find the field _Serialized string_. This string shows a Python tuple like
|
||||
|
||||
('__packed_dbobj__', ('objects', 'objectdb'), '2021:05:15-08:59:30:624660', 358)
|
||||
|
||||
|
||||
Mark and copy this tuple-string to your clipboard exactly as it stands (parentheses and all).
|
||||
2. Go to the entity that should have the new Attribute and create the Attribute. In its `value`
|
||||
field, paste the tuple-string you copied before. Save!
|
||||
|
|
@ -86,21 +86,21 @@ Only Superusers can change the `Superuser status` flag, and grant new
|
|||
permissions to accounts. The superuser is the only permission level that is
|
||||
also relevant in-game. `User Permissions` and `Groups` found on the `Account`
|
||||
admin page _only_ affects the admin - they have no connection to the in-game
|
||||
[Permissions](./Permissions) (Player, Builder, Admin etc).
|
||||
[Permissions](./Permissions.md) (Player, Builder, Admin etc).
|
||||
|
||||
For a staffer with `Staff status` to be able to actually do anything, the
|
||||
superuser must grant at least some permissions for them on their Account. This
|
||||
can also be good in order to limit mistakes. It can be a good idea to not allow
|
||||
the `Can delete Account` permission, for example.
|
||||
|
||||
```important::
|
||||
```{important}
|
||||
|
||||
If you grant staff-status and permissions to an Account and they still cannot
|
||||
access the admin's content, try reloading the server.
|
||||
|
||||
```
|
||||
|
||||
```warning::
|
||||
```{warning}
|
||||
|
||||
If a staff member has access to the in-game ``py`` command, they can just as
|
||||
well have their admin ``Superuser status`` set too. The reason is that ``py``
|
||||
|
|
@ -112,25 +112,25 @@ the `Can delete Account` permission, for example.
|
|||
|
||||
## Customizing the web admin
|
||||
|
||||
Customizing the admin is a big topic and something beyond the scope of this
|
||||
Customizing the admin is a big topic and something beyond the scope of this
|
||||
documentation. See the [official Django docs](https://docs.djangoproject.com/en/3.2/ref/contrib/admin/) for
|
||||
the details. This is just a brief summary.
|
||||
the details. This is just a brief summary.
|
||||
|
||||
See the [Website](./Website) page for an overview of the components going into
|
||||
See the [Website](./Website.md) page for an overview of the components going into
|
||||
generating a web page. The Django admin uses the same principle except that
|
||||
Django provides a lot of tools to automate the admin-generation for us.
|
||||
|
||||
Admin templates are found in `evennia/web/templates/admin/` but you'll find
|
||||
this is relatively empty. This is because most of the templates are just
|
||||
inherited directly from their original location in the Django package
|
||||
(`django/contrib/admin/templates/`). So if you wanted to override one you'd have
|
||||
(`django/contrib/admin/templates/`). So if you wanted to override one you'd have
|
||||
to copy it from _there_ into your `mygame/templates/admin/` folder. Same is true
|
||||
for CSS files.
|
||||
|
||||
The admin site's backend code (the views) is found in `evennia/web/admin/`. It
|
||||
is organized into `admin`-classes, like `ObjectAdmin`, `AccountAdmin` etc.
|
||||
These automatically use the underlying database models to generate useful views
|
||||
for us without us havint go code the forms etc ourselves.
|
||||
for us without us havint go code the forms etc ourselves.
|
||||
|
||||
The top level `AdminSite` (the admin configuration referenced in django docs)
|
||||
is found in `evennia/web/utils/adminsite.py`.
|
||||
|
|
@ -138,7 +138,7 @@ is found in `evennia/web/utils/adminsite.py`.
|
|||
|
||||
### Change the title of the admin
|
||||
|
||||
By default the admin's title is `Evennia web admin`. To change this, add the
|
||||
By default the admin's title is `Evennia web admin`. To change this, add the
|
||||
following to your `mygame/web/urls.py`:
|
||||
|
||||
```python
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ When Evennia starts it also spins up its own Twisted-based web server. The
|
|||
webserver is responsible for serving the html pages of the game's website. It
|
||||
can also serve static resources like images and music.
|
||||
|
||||
The webclient runs as part of the [Server](./Portal-And-Server) process of
|
||||
The webclient runs as part of the [Server](./Portal-And-Server.md) process of
|
||||
Evennia. This means that it can directly access cached objects modified
|
||||
in-game, and there is no risk of working with objects that are temporarily
|
||||
out-of-sync in the database.
|
||||
|
|
@ -12,17 +12,17 @@ out-of-sync in the database.
|
|||
The webserver runs on Twisted and is meant to be used in a production
|
||||
environment. It leverages the Django web framework and provides:
|
||||
|
||||
- A [Game Website](./Website) - this is what you see when you go to
|
||||
- A [Game Website](./Website.md) - this is what you see when you go to
|
||||
`localhost:4001`. The look of the website is meant to be customized to your
|
||||
game. Users logged into the website will be auto-logged into the game if they
|
||||
do so with the webclient since they share the same login credentials (there
|
||||
is no way to safely do auto-login with telnet clients).
|
||||
- The [Web Admin](./Web-Admin) is based on the Django web admin and allows you to
|
||||
- The [Web Admin](./Web-Admin.md) is based on the Django web admin and allows you to
|
||||
edit the game database in a graphical interface.
|
||||
- The [Webclient](./Webclient) page is served by the webserver, but the actual
|
||||
- The [Webclient](./Webclient.md) page is served by the webserver, but the actual
|
||||
game communication (sending/receiving data) is done by the javascript client
|
||||
on the page opening a websocket connection directly to Evennia's Portal.
|
||||
- The [Evennia REST-API](./Web-API) allows for accessing the database from outside the game
|
||||
- The [Evennia REST-API](./Web-API.md) allows for accessing the database from outside the game
|
||||
(only if `REST_API_ENABLED=True).
|
||||
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ it operates independently from Evennia. Small snippets of javascript can be
|
|||
used on a page to have buttons react, make small animations etc that doesn't
|
||||
require the server.
|
||||
|
||||
In the case of the [Webclient](./Webclient), Evennia will load the Webclient page
|
||||
In the case of the [Webclient](./Webclient.md), Evennia will load the Webclient page
|
||||
as above, but the page then initiates Javascript code (a lot of it) responsible
|
||||
for actually displaying the client GUI, allows you to resize windows etc.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
# Game website
|
||||
|
||||
When Evennia starts it will also start a [Webserver](./Webserver) as part of the
|
||||
[Server](./Portal-And-Server) process. This uses [Django](https://docs.djangoproject.com)
|
||||
When Evennia starts it will also start a [Webserver](./Webserver.md) as part of the
|
||||
[Server](./Portal-And-Server.md) process. This uses [Django](https://docs.djangoproject.com)
|
||||
to present a simple but functional default game website. With the default setup,
|
||||
open your browser to [localhost:4001](http://localhost:4001) or [127.0.0.1:4001](http://127.0.0.1:4001)
|
||||
open your browser to [localhost:4001](http://localhost:4001) or [127.0.0.1:4001](http://127.0.0.1:4001)
|
||||
to see it.
|
||||
|
||||
The website allows existing players to log in using an account-name and
|
||||
password they previously used to register with the game. If a user logs in with
|
||||
the [Webclient](./Webclient) they will also log into the website and vice-versa.
|
||||
the [Webclient](./Webclient.md) they will also log into the website and vice-versa.
|
||||
So if you are logged into the website, opening the webclient will automatically
|
||||
log you into the game as that account.
|
||||
|
||||
|
|
@ -28,15 +28,15 @@ In the top menu you can find
|
|||
show a list of all channels available to you and allow you to view the latest
|
||||
discussions. Most channels require logging in, but the `Public` channel can
|
||||
also be viewed by non-loggedin users.
|
||||
- _Help_ - This ties the in-game [Help system](./Help-System) to the website. All
|
||||
- _Help_ - This ties the in-game [Help system](./Help-System.md) to the website. All
|
||||
database-based help entries that are publicly available or accessible to your
|
||||
account can be read. This is a good way to present a body of help for people
|
||||
to read outside of the game.
|
||||
- _Play Online_ - This opens the [Webclient](./Webclient) in the browser.
|
||||
- _Play Online_ - This opens the [Webclient](./Webclient.md) in the browser.
|
||||
- _Admin_ The [Web admin](Web admin) will only show if you are logged in.
|
||||
- _Log in/out_ - Allows you to authenticate using the same credentials you use
|
||||
in the game.
|
||||
- _Register_ - Allows you to register a new account. This is the same as
|
||||
- _Register_ - Allows you to register a new account. This is the same as
|
||||
creating a new account upon first logging into the game).
|
||||
|
||||
## Modifying the default Website
|
||||
|
|
@ -52,7 +52,7 @@ You'll mostly be doing so in your settings file
|
|||
> DEBUG mode leaks memory (for retaining debug info) and is *not* safe to use
|
||||
> for a production game!
|
||||
|
||||
As explained on the [Webserver](./Webserver) page, the process for getting a web
|
||||
As explained on the [Webserver](./Webserver.md) page, the process for getting a web
|
||||
page is
|
||||
|
||||
1. Web browser sends HTTP request to server with an URL
|
||||
|
|
@ -115,7 +115,7 @@ This is the layout of the `mygame/web/` folder relevant for the website:
|
|||
|
||||
```
|
||||
|
||||
```versionchanged:: 1.0
|
||||
```{versionchanged} 1.0
|
||||
|
||||
Game folders created with older versions of Evennia will lack most of this
|
||||
convenient `mygame/web/` layout. If you use a game dir from an older version,
|
||||
|
|
@ -139,7 +139,7 @@ version rather than it using the original.
|
|||
|
||||
## Examples of commom web changes
|
||||
|
||||
```important::
|
||||
```{important}
|
||||
|
||||
Django is a very mature web-design framework. There are endless
|
||||
internet-tutorials, courses and books available to explain how to use Django.
|
||||
|
|
@ -206,8 +206,8 @@ There's a lot more information to be found in the [Django template language docu
|
|||
|
||||
### Change webpage colors and styling
|
||||
|
||||
You can tweak the [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) of the entire
|
||||
website. If you investigate the `evennia/web/templates/website/base.html` file you'll see that we
|
||||
You can tweak the [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) of the entire
|
||||
website. If you investigate the `evennia/web/templates/website/base.html` file you'll see that we
|
||||
use the [Bootstrap
|
||||
4](https://getbootstrap.com/docs/4.6/getting-started/introduction/) toolkit.
|
||||
|
||||
|
|
@ -220,8 +220,8 @@ The website's custom CSS is found in
|
|||
empty) `custom.css` in the same location. You can override either, but it may
|
||||
be easier to revert your changes if you only add things to `custom.css`.
|
||||
|
||||
Copy the CSS file you want to modify to the corresponding location in `mygame/web`.
|
||||
Modify it and reload the server to see your changes.
|
||||
Copy the CSS file you want to modify to the corresponding location in `mygame/web`.
|
||||
Modify it and reload the server to see your changes.
|
||||
|
||||
You can also apply static files without reloading, but running this in the
|
||||
terminal:
|
||||
|
|
@ -233,8 +233,8 @@ terminal:
|
|||
> Note that before you see new CSS files applied you may need to refresh your
|
||||
> browser without cache (Ctrl-F5 in Firefox, for example).
|
||||
|
||||
As an example, add/copy `custom.css` to `mygame/web/static/website/css/` and
|
||||
add the following:
|
||||
As an example, add/copy `custom.css` to `mygame/web/static/website/css/` and
|
||||
add the following:
|
||||
|
||||
|
||||
```css
|
||||
|
|
@ -271,14 +271,14 @@ look in `evennia/web/website/urls.py`. Here we find the following line:
|
|||
|
||||
```
|
||||
|
||||
The first `""` is the empty url - root - what you get if you just enter `localhost:4001/`
|
||||
The first `""` is the empty url - root - what you get if you just enter `localhost:4001/`
|
||||
with no extra path. As expected, this leads to the index page. By looking at the imports
|
||||
we find the view is in in `evennia/web/website/views/index.py`.
|
||||
we find the view is in in `evennia/web/website/views/index.py`.
|
||||
|
||||
Copy this file to the corresponding location in `mygame/web`. Then tweak your `mygame/web/website/urls.py`
|
||||
Copy this file to the corresponding location in `mygame/web`. Then tweak your `mygame/web/website/urls.py`
|
||||
file to point to the new file:
|
||||
|
||||
```python
|
||||
```python
|
||||
# in mygame/web/website/urls.py
|
||||
|
||||
# ...
|
||||
|
|
@ -292,8 +292,8 @@ urlpatterns = [
|
|||
# ...
|
||||
|
||||
```
|
||||
|
||||
So we just import `index` from the new location and point to it. After a reload
|
||||
|
||||
So we just import `index` from the new location and point to it. After a reload
|
||||
the front page will now redirect to use your copy rather than the original.
|
||||
|
||||
The frontpage view is a class `EvenniaIndexView`. This is a [Django class-based view](https://docs.djangoproject.com/en/3.2/topics/class-based-views/).
|
||||
|
|
@ -321,7 +321,7 @@ your copy. Just remember to reload.
|
|||
### Using Flat Pages
|
||||
|
||||
The absolutely simplest way to add a new web page is to use the `Flat Pages`
|
||||
app available in the [Web Admin](./Web-Admin). The page will appear with the same
|
||||
app available in the [Web Admin](./Web-Admin.md). The page will appear with the same
|
||||
styling as the rest of the site.
|
||||
|
||||
For the `Flat pages` module to work you must first set up a _Site_ (or
|
||||
|
|
@ -337,7 +337,7 @@ experimentation, add the domain `localhost:4001`. Note the `id` of the domain
|
|||
Next you create new pages easily.
|
||||
|
||||
- Go the `Flat Pages` web admin and choose to add a new flat page.
|
||||
- Set the url. If you want the page to appear as e.g. `localhost:4001/test/`, then
|
||||
- Set the url. If you want the page to appear as e.g. `localhost:4001/test/`, then
|
||||
add `/test/` here. You need to add both leading and trailing slashes.
|
||||
- Set `Title` to the name of the page.
|
||||
- The `Content` is the HTML content of the body of the page. Go wild!
|
||||
|
|
@ -348,16 +348,16 @@ You can now go to `localhost:4001/test/` and see your new page!
|
|||
|
||||
### Add Custom new page
|
||||
|
||||
The `Flat Pages` page doesn't allow for (much) dynamic content and customization. For
|
||||
The `Flat Pages` page doesn't allow for (much) dynamic content and customization. For
|
||||
this you need to add the needed components yourself.
|
||||
|
||||
Let's see how to make a `/test/` page from scratch.
|
||||
|
||||
- Add a new `test.html` file under `mygame/web/templates/website/`. Easiest is to base
|
||||
this off an existing file. Make sure to `{% extend base.html %}` if you want to
|
||||
- Add a new `test.html` file under `mygame/web/templates/website/`. Easiest is to base
|
||||
this off an existing file. Make sure to `{% extend base.html %}` if you want to
|
||||
get the same styling as the rest of your site.
|
||||
- Add a new view `testview.py` under `mygame/web/website/views/` (don't name it `test.py` or
|
||||
Django/Evennia will think it contains unit tests). Add a view there to process
|
||||
- Add a new view `testview.py` under `mygame/web/website/views/` (don't name it `test.py` or
|
||||
Django/Evennia will think it contains unit tests). Add a view there to process
|
||||
your page. This is a minimal view to start from (read much more [in the Django docs](https://docs.djangoproject.com/en/3.2/topics/class-based-views/)):
|
||||
|
||||
```python
|
||||
|
|
@ -385,7 +385,7 @@ Let's see how to make a `/test/` page from scratch.
|
|||
path("test/", testview.MyTestView.as_view())
|
||||
]
|
||||
|
||||
```
|
||||
```
|
||||
- Reload the server and your new page is available. You can now continue to add
|
||||
all sorts of advanced dynamic content through your view and template!
|
||||
|
||||
|
|
@ -395,13 +395,13 @@ Let's see how to make a `/test/` page from scratch.
|
|||
All the pages created so far deal with _presenting_ information to the user.
|
||||
It's also possible for the user to _input_ data on the page through _forms_. An
|
||||
example would be a page of fields and sliders you fill in to create a
|
||||
character, with a big 'Submit' button at the bottom.
|
||||
character, with a big 'Submit' button at the bottom.
|
||||
|
||||
Firstly, this must be represented in HTML. The `<form> ... </form>` is a
|
||||
standard HTML element you need to add to your template. It also has some other
|
||||
requirements, such as `<input>` and often Javascript components as well (but
|
||||
usually Django will help with this). If you are unfamiliar with how HTML forms
|
||||
work, [read about them here](https://docs.djangoproject.com/en/3.2/topics/forms/#html-forms).
|
||||
work, [read about them here](https://docs.djangoproject.com/en/3.2/topics/forms/#html-forms).
|
||||
|
||||
The basic gist of it is that when you click to 'submit' the form, a POST HTML
|
||||
request will be sent to the server containing the data the user entered. It's
|
||||
|
|
@ -412,9 +412,9 @@ On the backend side, we need to specify the logic for validating and processing
|
|||
the form data. This is done by the `Form` [Django class](https://docs.djangoproject.com/en/3.2/topics/forms/#forms-in-django).
|
||||
This specifies _fields_ on itself that define how to validate that piece of data.
|
||||
|
||||
The form is then linked into the view-class by adding `form_class = MyFormClass` to
|
||||
The form is then linked into the view-class by adding `form_class = MyFormClass` to
|
||||
the view (next to `template_name`).
|
||||
|
||||
There are several example forms in `evennia/web/website/forms.py`. It's also a good
|
||||
There are several example forms in `evennia/web/website/forms.py`. It's also a good
|
||||
idea to read [Building a form in Django](https://docs.djangoproject.com/en/3.2/topics/forms/#building-a-form-in-django)
|
||||
on the Django website - it covers all you need.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue