Exits

Inheritance Tree:

┌─────────────┐
│DefaultObject│
└─────▲───────┘
      │
┌─────┴─────┐
│DefaultExit│
└─────▲─────┘
      │       ┌────────────┐
      │ ┌─────►ObjectParent│
      │ │     └────────────┘
    ┌─┴─┴┐
    │Exit│
    └────┘

Exits are in-game Objects connecting other objects (usually Rooms) together.

Note that Exits are one-way objects, so in order for two Rooms to be linked bi-directionally, there will need to be two exits.

An object named north or in might be exits, as well as door, portal or jump out the window.

An exit has two things that separate them from other objects.

  1. Their .destination property is set and points to a valid target location. This fact makes it easy and fast to locate exits in the database.

  2. Exits define a special Transit Command 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 default exit functionality is all defined on the DefaultExit typeclass. You could in principle completely change how exits work in your game by overriding this - it’s not recommended though, unless you really know what you are doing).

Exits are locked 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.

Exits are normally overridden on a case-by-case basis, but if you want to change the default exit created by rooms like dig, tunnel or open you can change it in settings:

BASE_EXIT_TYPECLASS = "typeclasses.exits.Exit"

In mygame/typeclasses/exits.py there is an empty Exit class for you to modify.

Exit details

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 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).

  2. The Exit command checks the traverse lock on the Exit object

  3. The Exit command triggers at_traverse(obj, destination) on the Exit object.

  4. In at_traverse, object.move_to(destination) is triggered. This triggers the following hooks, in order:

    1. obj.at_pre_move(destination) - if this returns False, move is aborted.

    2. origin.at_pre_leave(obj, destination)

    3. obj.announce_move_from(destination)

    4. Move is performed by changing obj.location from source location to destination.

    5. obj.announce_move_to(source)

    6. destination.at_object_receive(obj, source)

    7. obj.at_post_move(source)

  5. On the Exit object, at_post_traverse(obj, source) is triggered.

If the move fails for whatever reason, the Exit will look for an Attribute err_traverse on itself and display this as an error message. If this is not found, the Exit will instead call at_failed_traverse(obj) on itself.

Creating Exits in code

For an example of how to create Exits programatically please see this guide.