Expand prototype inheritance docs. Resolve #2220.

This commit is contained in:
Griatch 2022-01-19 22:58:08 +01:00
parent 5f7cbbcec0
commit f1b970d45a
2 changed files with 36 additions and 25 deletions

View file

@ -47,18 +47,18 @@ The dictionary defines all possible database-properties of an Object. It has a f
keys. When preparing to store the prototype in the database (or when using the OLC), some keys. When preparing to store the prototype in the database (or when using the OLC), some
of these keys are mandatory. When just passing a one-time prototype-dict to the spawner the system of these keys are mandatory. When just passing a one-time prototype-dict to the spawner the system
is is
more lenient and will use defaults for keys not explicitly provided. more lenient and will use defaults for keys not explicitly provided.
In dictionary form, a prototype can look something like this: In dictionary form, a prototype can look something like this:
```python ```python
{ {
"prototype_key": "house" "prototype_key": "house"
"key": "Large house" "key": "Large house"
"typeclass": "typeclasses.rooms.house.House" "typeclass": "typeclasses.rooms.house.House"
} }
``` ```
If you wanted to load it into the spawner in-game you could just put all on one line: If you wanted to load it into the spawner in-game you could just put all on one line:
@spawn {"prototype_key="house", "key": "Large house", ...} @spawn {"prototype_key="house", "key": "Large house", ...}
@ -74,15 +74,13 @@ before running.
All keys starting with `prototype_` are for book keeping. All keys starting with `prototype_` are for book keeping.
- `prototype_key` - the 'name' of the prototype. While this can sometimes be skipped (such as when - `prototype_key` - the 'name' of the prototype, used for referencing the prototype
defining a prototype in a module or feeding a prototype-dict manually to the spawner function), when spawning and inheritance. If defining a prototype in a module and this
it's good not set, it will be auto-set to the name of the prototype's variable in the module.
practice to try to include this. It is used for book-keeping and storing of the prototype so you
can find it later.
- `prototype_parent` - If given, this should be the `prototype_key` of another prototype stored in - `prototype_parent` - If given, this should be the `prototype_key` of another prototype stored in
the system or available in a module. This makes this prototype *inherit* the keys from the the system or available in a module. This makes this prototype *inherit* the keys from the
parent and only override what is needed. Give a tuple `(parent1, parent2, ...)` for multiple parent and only override what is needed. Give a tuple `(parent1, parent2, ...)` for multiple
left-right inheritance. If this is not given, a `typeclass` should usually be defined (below). left-right inheritance. If this is not given, a `typeclass` should usually be defined (below).
- `prototype_desc` - this is optional and used when listing the prototype in in-game listings. - `prototype_desc` - this is optional and used when listing the prototype in in-game listings.
- `protototype_tags` - this is optional and allows for tagging the prototype in order to find it - `protototype_tags` - this is optional and allows for tagging the prototype in order to find it
easier later. easier later.
@ -90,6 +88,7 @@ it's good
the copying and editing of the prototype when loaded through the OLC. The second determines who the copying and editing of the prototype when loaded through the OLC. The second determines who
may use the prototype to create new objects. may use the prototype to create new objects.
The remaining keys determine actual aspects of the objects to spawn from this prototype: The remaining keys determine actual aspects of the objects to spawn from this prototype:
- `key` - the main object identifier. Defaults to "Spawned Object *X*", where *X* is a random - `key` - the main object identifier. Defaults to "Spawned Object *X*", where *X* is a random
@ -111,15 +110,28 @@ exist.
- `attrs` - list of [Attributes](./Attributes.md). These are given as tuples `(attrname, value, - `attrs` - list of [Attributes](./Attributes.md). These are given as tuples `(attrname, value,
category, lockstring)` category, lockstring)`
- Any other keywords are interpreted as non-category [Attributes](./Attributes.md) and their values. - Any other keywords are interpreted as non-category [Attributes](./Attributes.md) and their values.
This is This is convenient for simple Attributes - use `attrs` for full control of Attributes.
convenient for simple Attributes - use `attrs` for full control of Attributes.
Deprecated as of Evennia 0.8: #### More on prototype inheritance
- `ndb_<name>` - sets the value of a non-persistent attribute (`"ndb_"` is stripped from the name). - A prototype can inherit by defining a `prototype_parent` pointing to the name
This is simply not useful in a prototype and is deprecated. (`prototype_key` of another prototype). If a list of `prototype_keys`, this
- `exec` - This accepts a code snippet or a list of code snippets to run. This should not be used - will be stepped through from left to right, giving priority to the first in
use callables or [$protfuncs](./Prototypes.md#protfuncs) instead (see below). the list over those appearing later. That is, if your inheritance is
`prototype_parent = ('A', 'B,' 'C')`, and all parents contain colliding keys,
then the one from `A` will apply.
- The prototype keys that start with `prototype_*` are all unique to each
prototype. They are _never_ inherited from parent to child.
- The prototype fields `'attr': [(key, value, category, lockstring),...]`
and `'tags': [(key, category, data), ...]` are inherited in a _complementary_
fashion. That means that only colliding key+category matches will be replaced, not the entire list.
Remember that the category `None` is also considered a valid category!
- Adding an Attribute as a simple `key:value` will under the hood be translated
into an Attribute tuple `(key, value, None, '')` and may replace an Attribute
in the parent if it the same key and a `None` category.
- All other keys (`permissions`, `destination`, `aliases` etc) are completely
_replaced_ by the child's value if given. For the parent's value to be
retained, the child must not define these keys at all.
### Prototype values ### Prototype values
@ -160,10 +172,10 @@ that you embed in strings and that has a `$` in front, like
"He has $randint(2,5) skulls in a chain around his neck."} "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 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 is a [FuncParser function](./FuncParser.md) run 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. every time the prototype is used to spawn a new object.
Here is how a protfunc is defined (same as an inlinefunc). Here is how a protfunc is defined (same as an inlinefunc).
```python ```python
# this is a silly example, you can just color the text red with |r directly! # this is a silly example, you can just color the text red with |r directly!
@ -198,17 +210,17 @@ with `_`.
The default protfuncs available out of the box are defined in `evennia/prototypes/profuncs.py`. To The default protfuncs available out of the box are defined in `evennia/prototypes/profuncs.py`. To
override the ones available, just add the same-named function in your own protfunc module. override the ones available, just add the same-named function in your own protfunc module.
| Protfunc | Description | | Protfunc | Description |
| `$random()` | Returns random value in range [0, 1) | | `$random()` | Returns random value in range [0, 1) |
| `$randint(start, end)` | Returns random value in range [start, end] | | `$randint(start, end)` | Returns random value in range [start, end] |
| `$left_justify(<text>)` | Left-justify text | | `$left_justify(<text>)` | Left-justify text |
| `$right_justify(<text>)` | Right-justify text to screen width | | `$right_justify(<text>)` | Right-justify text to screen width |
| `$center_justify(<text>)` | Center-justify text to screen width | | `$center_justify(<text>)` | Center-justify text to screen width |
| `$full_justify(<text>)` | Spread text across screen width by adding spaces | | `$full_justify(<text>)` | Spread text across screen width by adding spaces |
| `$protkey(<name>)` | Returns value of another key in this prototype (self-reference) | | `$protkey(<name>)` | Returns value of another key in this prototype (self-reference) |
| `$add(<value1>, <value2>)` | Returns value1 + value2. Can also be lists, dicts etc | | `$add(<value1>, <value2>)` | Returns value1 + value2. Can also be lists, dicts etc |
| `$sub(<value1>, <value2>)` | Returns value1 - value2 | | `$sub(<value1>, <value2>)` | Returns value1 - value2 |
| `$mult(<value1>, <value2>)` | Returns value1 * value2 | | `$mult(<value1>, <value2>)` | Returns value1 * value2 |
| `$div(<value1>, <value2>)` | Returns value2 / value1 | | `$div(<value1>, <value2>)` | Returns value2 / value1 |
| `$toint(<value>)` | Returns value converted to integer (or value if not possible) | | `$toint(<value>)` | Returns value converted to integer (or value if not possible) |
@ -256,7 +268,7 @@ PROTOTYPE_MODULES = += ["world.myownprototypes", "combat.prototypes"]
``` ```
Here is an example of a prototype defined in a module: Here is an example of a prototype defined in a module:
```python ```python
# in a module Evennia looks at for prototypes, # in a module Evennia looks at for prototypes,
@ -322,4 +334,4 @@ If the prototypes you supply are using `prototype_parent` keywords, the spawner
from modules from modules
in `settings.PROTOTYPE_MODULES` as well as those saved to the database to determine the body of in `settings.PROTOTYPE_MODULES` as well as those saved to the database to determine the body of
available parents. The `spawn` command takes many optional keywords, you can find its definition [in available parents. The `spawn` command takes many optional keywords, you can find its definition [in
the api docs](github:evennia.prototypes.spawner#spawn). the api docs](github:evennia.prototypes.spawner#spawn).

View file

@ -49,7 +49,6 @@ _PROTOTYPE_RESERVED_KEYS = _PROTOTYPE_META_NAMES + (
"destination", "destination",
"permissions", "permissions",
"locks", "locks",
"exec",
"tags", "tags",
"attrs", "attrs",
) )