Adding Object Typeclass Tutorial¶
Evennia comes with a few very basic classes of in-game entities:
DefaultObject | DefaultCharacter DefaultRoom DefaultExit
When you create a new Evennia game (with for example
evennia --init mygame) Evennia will automatically create empty child
They are found
For your own game you will most likely want to expand on these very simple beginnings. It’s normal to want your Characters to have various attributes, for example. Maybe Rooms should hold extra information or even all Objects in your game should have properties not included in basic Evennia.
Change Default Rooms, Exits, Character Typeclass¶
This is the simplest case.
The default build commands of a new Evennia game is set up to use the
Character classes found in the same-named
mygame/typeclasses/. By default these are empty and
just implements the default parents from the Evennia library
DefaultRoometc). Just add the changes you want to these classes
@reload to add your new functionality.
Create a new type of object¶
Say you want to create a new “Heavy” object-type that characters should not have the ability to pick up.
mygame/typeclasses/objects.py(you could also create a new module there, named something like
heavy.py, that’s up to how you want to organize things).
Create a new class inheriting at any distance from
DefaultObject. It could look something like this:
# end of file mygame/typeclasses/objects.py from evennia import DefaultObject class Heavy(DefaultObject): "Heavy object" def at_object_creation(self): "Called whenever a new object is created" # lock the object down by default self.locks.add("get:false()") # the default "get" command looks for this Attribute in order # to return a customized error message (we just happen to know # this, you'd have to look at the code of the 'get' command to # find out). self.db.get_err_msg = "This is too heavy to pick up."
Once you are done, log into the game with a build-capable account and do
@create/drop rock:objects.Heavyto drop a new heavy “rock” object in your location. Next try to pick it up (
@quellyourself first if you are a superuser). If you get errors, look at your log files where you will find the traceback. The most common error is that you have some sort of syntax error in your class.
Storing data on initialization¶
at_object_creation is only called once, when the object is first
created. This makes it ideal for database-bound things like
Attributes. But sometimes you want to create temporary properties
(things that are not to be stored in the database but still always exist
every time the object is created). Such properties can be initialized in
at_init method on the object.
at_init is called every time
the object is loaded into memory.
Note: It’s usually pointless and wasteful to assign database data in
at_init, since this will hit the database with the same value over and over. Put those in
You are wise to use
ndb (non-database Attributes) to store
non-persistent these properties, since ndb-properties are protected
against being cached out in various ways and also allows you to list
them using various in-game tools:
def at_init(self): self.ndb.counter = 0 self.ndb.mylist =  Note: As mentioned in the `Typeclasses`_ documentation, ``at_init`` replaces the use of the standard ``__init__`` method of typeclasses due to how the latter may be called in situations other than you’d expect. So use ``at_init`` where you would normally use ``__init__``.
Updating existing objects¶
If you already have some
Heavy objects created and you add a new
at_object_creation, you will find that those
existing objects will not have this Attribute. This is not so strange,
at_object_creation is only called once, it will not be called
again just because you update it. You need to update existing objects
If the number of objects is limited, you can use
@typeclass/force/reload objectname to force a re-load of the
at_object_creation method (only) on the object. This case is common
enough that there is an alias
@update objectname you can use to get
the same effect. If there are multiple objects you can use
loop over the objects you need:
@py from typeclasses.objects import Heavy; [obj.at_object_creation() for obj in Heavy.objects.all()]