mirror of
https://github.com/evennia/evennia.git
synced 2026-03-25 17:26:32 +01:00
Copy doc tools from develop
This commit is contained in:
parent
bd65641755
commit
6af2fc6819
127 changed files with 2927 additions and 1427 deletions
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
*Typeclasses* form the core of Evennia data storage. It allows Evennia to represent any number of 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 varying distance, from `evennia.typeclasses.models.TypedObject`. In the documentation we refer to these objects as being "typeclassed" or even "being a typeclass".
|
||||
In Evennia the most important game entities, [Accounts](./Accounts), [Objects](./Objects), [Scripts](./Scripts) and [Channels](./Communications#Channels) 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".
|
||||
|
||||
This is how the inheritance looks for the typeclasses in Evennia:
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ to Evennia you must import that module from somewhere.
|
|||
|
||||
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).
|
||||
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).
|
||||
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 default library):
|
||||
|
||||
```python
|
||||
|
|
@ -96,7 +96,7 @@ chair = create_object(Furniture, key="Chair")
|
|||
chair = create_object("furniture.Furniture", key="Chair")
|
||||
```
|
||||
|
||||
The `create_object` (`create_account`, `create_script` etc) takes the typeclass as its first argument; this can both be the actual class or the python path to the typeclass as found under your 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 save the new instance to the database, so you don't need to call `save()` explicitly.
|
||||
The `create_object` (`create_account`, `create_script` etc) takes the typeclass as its first argument; this can both be the actual class or the python path to the typeclass as found under your 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 save the new instance to the database, so you don't need to call `save()` explicitly.
|
||||
|
||||
### About typeclass properties
|
||||
|
||||
|
|
@ -134,16 +134,16 @@ There is one special field that doesn't use the `db_` prefix (it's defined by Dj
|
|||
|
||||
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()`, `locks.get()` etc.
|
||||
- `attributes` - the [AttributeHandler](Attributes) that manages Attributes on the object. Use `attributes.add()`
|
||||
- `tags` - the [TagHandler](./Tags) that handles tagging. Use `tags.add()` , `tags.get()` etc.
|
||||
- `locks` - the [LockHandler](./Locks) that manages access restrictions. Use `locks.add()`, `locks.get()` etc.
|
||||
- `attributes` - the [AttributeHandler](./Attributes) 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 database.
|
||||
- `nattributes` - the [Non-persistent AttributeHandler](./Attributes) 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 available.
|
||||
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 available.
|
||||
|
||||
### Overloading hooks
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ The way to customize typeclasses is usually to overload *hook methods* on them.
|
|||
|
||||
### 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`.
|
||||
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`.
|
||||
|
||||
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 manager_ that sits on all typeclasses, named `objects`. This manager holds methods that allow database searches against that particular type of object (this is the way Django normally works too). When using Django queries, you need to use the full field names (like `db_key`) to search:
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ When querying from the database model parent you don't need to use `filter_famil
|
|||
|
||||
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 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:
|
||||
However, database-saved data, like `db_*` fields, [Attributes](./Attributes), [Tags](./Tags) 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:
|
||||
|
||||
```python
|
||||
# add a worth Attribute to all existing Furniture
|
||||
|
|
@ -235,7 +235,7 @@ The arguments to this method are described [in the API docs here](github:evennia
|
|||
|
||||
*This is considered an advanced section.*
|
||||
|
||||
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 subclasses of them are "proxies", extending them with Python code without actually modifying the database layout.
|
||||
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 subclasses of them are "proxies", extending them with Python code without actually modifying the database layout.
|
||||
|
||||
Evennia modifies Django's proxy model in various ways to allow them to work without any boiler plate (for example you don't need to set the Django "proxy" property in the model `Meta` subclass, Evennia 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.
|
||||
|
||||
|
|
@ -243,5 +243,5 @@ Evennia modifies Django's proxy model in various ways to allow them to work with
|
|||
|
||||
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 get lost as long as the server is running (they will only be cleared on a Server reload). Django does not work like this by default; by default every time you search for an object in the database you'll get a *different* instance of that object back and anything you stored on it that was not in the database would be lost. The bottom line is that Evennia's Typeclass instances subside in memory a lot longer than vanilla Django model instance do.
|
||||
|
||||
There is one caveat to consider with this, and that relates to [making your own models](New-Models): Foreign relationships to typeclasses are cached by Django and that means that if you were to change an object in a foreign relationship via some other means than via that relationship, the object seeing the relationship may not reliably update but will still see its old cached version. Due to typeclasses staying so long in memory, stale caches of such relationships could be more visible than common in Django. See the [closed issue #1098 and its comments](https://github.com/evennia/evennia/issues/1098) for examples and solutions.
|
||||
There is one caveat to consider with this, and that relates to [making your own models](./New-Models): Foreign relationships to typeclasses are cached by Django and that means that if you were to change an object in a foreign relationship via some other means than via that relationship, the object seeing the relationship may not reliably update but will still see its old cached version. Due to typeclasses staying so long in memory, stale caches of such relationships could be more visible than common in Django. See the [closed issue #1098 and its comments](https://github.com/evennia/evennia/issues/1098) for examples and solutions.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue