diff --git a/docs/source/Coding/Changelog.md b/docs/source/Coding/Changelog.md index 50319103bc..6268fa57ec 100644 --- a/docs/source/Coding/Changelog.md +++ b/docs/source/Coding/Changelog.md @@ -153,6 +153,13 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10 decouple structures from database without needing separate import. - Add `run_in_main_thread` as a helper for those wanting to code server code from a web view. +- Update `evennia.utils.logger` to use Twisted's new logging API. No change in Evennia API + except more standard aliases logger.error/info/exception/debug etc can now be used. +- Have `type/force` default to `update`-mode rather than `reset`mode and add more verbose + warning when using reset mode. +- Attribute storage support defaultdics (Hendher) +- Add ObjectParent mixin to default game folder template as an easy, ready-made + way to override features on all ObjectDB-inheriting objects easily. ## Evennia 0.9.5 diff --git a/docs/source/Components/Objects.md b/docs/source/Components/Objects.md index d30c41738c..7fb6583ee2 100644 --- a/docs/source/Components/Objects.md +++ b/docs/source/Components/Objects.md @@ -5,12 +5,32 @@ All in-game objects in Evennia, be it characters, chairs, monsters, rooms or han 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.md) entities. +An Evennia Object is, by definition, a Python class that includes +[evennia.objects.objects.DefaultObject](evennia.objects.objects.DefaultObject) among its +parents. Evennia defines several subclasses of `DefaultObject`: + +- [evennia.objects.objects.DefaultCharacter](evennia.objects.objects.DefaultCharacter) - +the normal in-game Character, controlled by a player. +- [evennia.objects.objects.DefaultRoom](evennia.objects.objects.DefaultRoom) - a location in the game world. +- [evennia.objects.objects.DefaultExit](evennia.objects.objects.DefaultExit) - an entity that (usually) sits +in a room and represents a one-way connection to another location. + +You will usually not use the `Default*` parents themselves. In `mygame/typeclasses/` there are +convenient subclasses to use. They are empty, and thus identical to +the defaults. Tweaking them is one of the main ways to customize you game! + +- `mygame.typeclasses.objects.Object` (inherits from `DefaultObject`) +- `mygame.typeclasses.characters.Character` (inherits from `DefaultCharacter`) +- `mygame.typeclasses.rooms.Room` (inherits from `DefaultRoom`) +- `mygame.typeclasses.exits.Exit` (inherits from `DefaultExit`) + ## How to create your own object types -An Evennia Object is, per definition, a Python class that includes `evennia.DefaultObject` among its -parents. In `mygame/typeclasses/objects.py` there is already a class `Object` that inherits from -`DefaultObject` and that you can inherit from. You can put your new typeclass directly in that -module or you could organize your code in some other way. Here we assume we make a new module +You can easily add your own in-game behavior by either modifying one of the typeclasses in +your game dir or by inheriting from them. + +You can put your new typeclass directly in the relevant parent +module, or you could organize your code in some other way. Here we assume we make a new module `mygame/typeclasses/flowers.py`: ```python @@ -29,32 +49,66 @@ module or you could organize your code in some other way. Here we assume we make self.db.desc = "This is a pretty rose with thorns." ``` -You could save this in the `mygame/typeclasses/objects.py` (then you'd not need to import `Object`) -or you can put it in a new module. Let's say we do the latter, making a module -`typeclasses/flowers.py`. Now you just need to point to the class *Rose* with the `@create` command +Now you just need to point to the class *Rose* with the `create` command to make a new rose: @create/drop MyRose:flowers.Rose -What the `@create` command actually *does* is to use `evennia.create_object`. You can do the same -thing yourself in code: +What the `create` command actually *does* is to use the [evennia.create_object](evennia.utils.create.create_object) +function. You can do the same thing yourself in code: ```python from evennia import create_object new_rose = create_object("typeclasses.flowers.Rose", key="MyRose") ``` -(The `@create` command will auto-append the most likely path to your typeclass, if you enter the +(The `create` command will auto-append the most likely path to your typeclass, if you enter the 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.md)). +your own building commands). 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.md)). The `Object` typeclass offers many more hooks that is available -to use though - see next section. +will usually want to change this at build time (using the `desc` command or using the +[Spawner](./Prototypes.md)). + +## Adding common functionality + +`Object`, `Character`, `Room` and `Exit` also inherit from `mygame.typeclasses.objects.ObjectParent`. +This is an empty 'mixin' class. Optionally, you can modify this class if you want to easily add some _common_ functionality to all +your Objects, Characters, Rooms and Exits at once. You can still customize each subclass separately (see the Python +docs on [multiple inheritance](https://docs.python.org/3/tutorial/classes.html#multiple-inheritance) for details). + +For example: + +```python +# in mygame/typeclasses/objects.py +# ... + +from evennia.objects.objects import DefaultObject + +class ObjectParent: + def at_pre_get(self, getter, **kwargs): + # make all entities by default un-pickable + return False + +class Object(ObjectParent, DefaultObject): + # replaces at_pre_get with its own + def at_pre_get(self, getter, **kwargs): + return True + +# each in their respective modules ... + +class Character(ObjectParent, DefaultCharacter): + # will inherit at_pre_get from ObjectParent + pass + +class Exit(ObjectParent, DefaultExit): + # Overrides and uses the DefaultExit version of at_pre_get instead + def at_pre_get(self, getter, **kwargs): + return DefaultExit.at_pre_get(self, getter, **kwargs) + +``` ## Properties and functions on Objects diff --git a/docs/source/Contribs/Contrib-Cooldowns.md b/docs/source/Contribs/Contrib-Cooldowns.md index ada9765a46..7c00b51d64 100644 --- a/docs/source/Contribs/Contrib-Cooldowns.md +++ b/docs/source/Contribs/Contrib-Cooldowns.md @@ -30,7 +30,7 @@ customize this if desired by passing a different value for the `db_attribute` parameter. ```python -from evennia.contrib.game_systems.cooldowns import Cooldownhandler +from evennia.contrib.game_systems.cooldowns import CooldownHandler from evennia.utils.utils import lazy_property @lazy_property diff --git a/evennia/game_template/typeclasses/characters.py b/evennia/game_template/typeclasses/characters.py index dd91f04310..452cd8296d 100644 --- a/evennia/game_template/typeclasses/characters.py +++ b/evennia/game_template/typeclasses/characters.py @@ -11,7 +11,7 @@ from evennia.objects.objects import DefaultCharacter from .objects import ObjectParent -class Character(DefaultCharacter, ObjectParent): +class Character(ObjectParent, DefaultCharacter): """ The Character defaults to reimplementing some of base Object's hook methods with the following functionality: diff --git a/evennia/game_template/typeclasses/exits.py b/evennia/game_template/typeclasses/exits.py index d9ae63abd6..4f1450dd15 100644 --- a/evennia/game_template/typeclasses/exits.py +++ b/evennia/game_template/typeclasses/exits.py @@ -10,7 +10,7 @@ from evennia.objects.objects import DefaultExit from .objects import ObjectParent -class Exit(DefaultExit, ObjectParent): +class Exit(ObjectParent, DefaultExit): """ Exits are connectors between rooms. Exits are normal Objects except they defines the `destination` property. It also does work in the diff --git a/evennia/game_template/typeclasses/objects.py b/evennia/game_template/typeclasses/objects.py index f99104ae48..b8aab3eeb6 100644 --- a/evennia/game_template/typeclasses/objects.py +++ b/evennia/game_template/typeclasses/objects.py @@ -25,7 +25,7 @@ class ObjectParent: """ -class Object(DefaultObject, ObjectParent): +class Object(ObjectParent, DefaultObject): """ This is the root typeclass object, implementing an in-game Evennia game object, such as having a location, being able to be diff --git a/evennia/game_template/typeclasses/rooms.py b/evennia/game_template/typeclasses/rooms.py index 88fa249b0f..2954abb4d8 100644 --- a/evennia/game_template/typeclasses/rooms.py +++ b/evennia/game_template/typeclasses/rooms.py @@ -9,7 +9,7 @@ from evennia.objects.objects import DefaultRoom from .objects import ObjectParent -class Room(DefaultRoom, ObjectParent): +class Room(ObjectParent, DefaultRoom): """ Rooms are like any Object, except their location is None (which is default). They also use basetype_setup() to