evennia.contrib.grid.extended_room.extended_room

Extended Room

Evennia Contribution - Griatch 2012, vincent-lg 2019, Griatch 2023

This is an extended Room typeclass for Evennia, supporting descriptions that vary by season, time-of-day or arbitrary states (like burning). It has details, embedded state tags, support for repeating random messages as well as a few extra commands.

  • The room description can be set to change depending on the season or time of day.

  • Parts of the room description can be set to change depending on arbitrary states (like burning).

  • Details can be added to the room, which can be looked at like objects.

  • Alternative text sections can be added to the room description, which will only show if the room is in a given state.

  • Random messages can be set to repeat at a given rate.

Installation/testing:

Adding the ExtendedRoomCmdset to the default character cmdset will add all new commands for use.

In more detail, in mygame/commands/default_cmdsets.py:

… from evennia.contrib import extended_room # <—

class CharacterCmdset(default_cmds.Character_CmdSet):

… def at_cmdset_creation(self):

… self.add(extended_room.ExtendedRoomCmdSet) # <—

Then reload to make the bew commands available. Note that they only work on rooms with the typeclass ExtendedRoom. Create new rooms with the right typeclass or use the typeclass command to swap existing rooms.

evennia.contrib.grid.extended_room.extended_room.func_state(roomstate, *args, looker=None, room=None, **kwargs)[source]

Usage: $state(roomstate, text)

Funcparser callable for ExtendedRoom. This is called by the FuncParser when it returns the description of the room. Use ‘default’ for a default text when no other states are set.

Parameters
  • roomstate (str) – A roomstate, like “morning”, “raining”. This is case insensitive.

  • *args – All these will be combined into one string separated by commas.

Keyword Arguments
  • looker (Object) – The object looking at the room. Unused by default.

  • room (ExtendedRoom) – The room being looked at.

Example

$state(morning, It is a beautiful morning!)

Notes

We try to merge all args into one text, since this function doesn’t require more than one argument. That way, one may be able to get away without using quotes.

class evennia.contrib.grid.extended_room.extended_room.ExtendedRoom(*args, **kwargs)[source]

Bases: evennia.objects.objects.DefaultRoom

An Extended Room

Room states:

A room state is set as a Tag with category “roomstate” and tagkey “on_fire” or “flooded” etc).

Alternative descriptions: - Add an Attribute desc_<roomstate> to the room, where <roomstate> is the name of the

roomstate to use this for, like desc_on_fire or desc_flooded. If not given, seasonal descriptions given in desc_spring/summer/autumn/winter will be used, and last the regular desc Attribute.

Alternative text sections - Used to add alternative text sections to the room description. These are embedded in the

description by adding $state(roomstate, txt). They will show only if the room is in the given roomstate. These are managed via the add/remove/get_alt_text methods.

Details: - This is set as an Attribute details (a dict) on the room, with the detail name as key.

When looking at this room, the detail name can be used as a target to look at without having to add an actual database object for it. The detail command is used to add/remove details.

Room messages - Set room_message_rate > 0 and add a list of room_messages. These will be randomly

echoed to the room at the given rate.

fallback_desc = 'You see nothing special.'
room_state_tag_category = 'room_state'
months_per_year = 12
hours_per_day = 24
seasons_per_year = {'autumn': (0.75, 1.0), 'spring': (0.25, 0.5), 'summer': (0.5, 0.75), 'winter': (1.0, 0.25)}
desc_spring

AttributeProperty.

desc_summer

AttributeProperty.

desc_autumn

AttributeProperty.

desc_winter

AttributeProperty.

times_of_day = {'afternoon': (0.5, 0.75), 'evening': (0.75, 0), 'morning': (0.25, 0.5), 'night': (0, 0.25)}
desc

AttributeProperty.

details

AttributeProperty.

room_message_rate = 0
room_messages

AttributeProperty.

at_init()[source]

Evennia hook. Start up repeating function whenever object loads into memory.

start_repeat_broadcast_messages()[source]

Start repeating the broadcast messages. Only needs to be called if adding messages and not having reloaded the server.

repeat_broadcast_message_to_room()[source]

Send a message to the room at room_message_rate. By default we will randomize which one to send.

get_time_of_day()[source]

Get the current time of day.

Override to customize.

Returns

str – The time of day, such as ‘morning’, ‘afternoon’, ‘evening’ or ‘night’.

get_season()[source]

Get the current season.

Override to customize.

Returns

str – The season, such as ‘spring’, ‘summer’, ‘autumn’ or ‘winter’.

property room_states

Get all room_states set on this room.

add_room_state(*room_states)[source]

Set a room-state or room-states to the room.

Parameters

*room_state (str) – A room state like ‘on_fire’ or ‘flooded’. This will affect what desc_* and roomstate_* descriptions/inlines are used. You can add more than one at a time.

Notes

You can also set time-based room_states this way, like ‘morning’ or ‘spring’. This can be useful to force a particular description, but while this state is set this way, that state will be unaffected by the passage of time. Remove the state to let the current game time determine this type of states.

remove_room_state(*room_states)[source]

Remove a roomstate from the room.

Parameters
  • *room_state (str) – A roomstate like ‘on_fire’ or ‘flooded’. If the

  • did not have this state (room) –

  • happens.You can remove more than one at a time. (nothing) –

clear_room_state()[source]

Clear all room states.

Note that fallback time-of-day and seasonal states are not affected by this, only custom states added with .add_room_state().

add_desc(desc, room_state=None)[source]

Add a custom description, matching a particular room state.

Parameters
  • desc (str) – The description to use when this roomstate is active.

  • roomstate (str, None) – The roomstate to match, like ‘on_fire’, ‘flooded’, or “spring”. If None, set the default desc fallback.

remove_desc(room_state)[source]

Remove a custom description.

Parameters

room_state (str) – The room-state description to remove.

all_desc()[source]

Get all available descriptions.

Returns

dict

A mapping of roomstate to description. The None key indicates the

base subscription (stored in the desc Attribute).

get_stateful_desc()[source]

Get the currently active room description based on the current roomstate.

Returns

str – The current description.

Note

Only one description can be active at a time. Priority order is as follows:

Priority order is as follows:

  1. Room-states set by add_roomstate() that are not seasons. If multiple room_states are set, the first one is used, sorted alphabetically.

  2. Seasons set by add_room_state(). This allows to ‘pin’ a season.

  3. Time-based seasons based on the current in-game time.

  4. None, if no seasons are defined in .seasons_per_year.

If either of the above is found, but doesn’t have a matching desc_<roomstate> description, we move on to the next priority. If no matches are found, the desc Attribute is used.

replace_legacy_time_of_day_markup(desc)[source]

Filter description by legacy markup like <morning>…</morning>. Filter out all such markings that does not match the current time. Supports ‘morning’, ‘afternoon’, ‘evening’ and ‘night’.

Parameters

desc (str) – The unmodified description.

Returns

str – A possibly modified description.

Notes

This is legacy. Use the $state markup for new rooms instead.

get_display_desc(looker, **kwargs)[source]

Evennia standard hook. Dynamically get the ‘desc’ component of the object description. This is called by the return_appearance method and in turn by the ‘look’ command.

Parameters
  • looker (Object) – Object doing the looking (unused by default).

  • **kwargs – Arbitrary data for use when overriding.

Returns

str – The desc display string.

add_detail(key, description)[source]

This sets a new detail, using an Attribute “details”.

Parameters
  • detailkey (str) – The detail identifier to add (for aliases you need to add multiple keys to the same description). Case-insensitive.

  • description (str) – The text to return when looking at the given detailkey. This can contain funcparser directives.

set_detail(key, description)

This sets a new detail, using an Attribute “details”.

Parameters
  • detailkey (str) – The detail identifier to add (for aliases you need to add multiple keys to the same description). Case-insensitive.

  • description (str) – The text to return when looking at the given detailkey. This can contain funcparser directives.

remove_detail(key, *args)[source]

Delete a detail.

Parameters
  • key (str) – the detail to remove (case-insensitive).

  • *args – Unused (backwards compatibility)

The description is only included for compliance but is completely ignored. Note that this method doesn’t raise any exception if the detail doesn’t exist in this room.

del_detail(key, *args)

Delete a detail.

Parameters
  • key (str) – the detail to remove (case-insensitive).

  • *args – Unused (backwards compatibility)

The description is only included for compliance but is completely ignored. Note that this method doesn’t raise any exception if the detail doesn’t exist in this room.

get_detail(key, looker=None)[source]

This will attempt to match a “detail” to look for in the room. This will do a lower-case match followed by a startsby match. This is called by the new look Command.

Parameters
  • key (str) – A detail identifier.

  • looker (Object, optional) – The one looking.

Returns

detail (str or None) – A detail matching the given key, or None if it was not found.

Notes

A detail is a way to offer more things to look at in a room without having to add new objects. For this to work, we require a custom look command that allows for look <detail> - the look command should defer to this method on the current location (if it exists) before giving up on finding the target.

return_detail(key, looker=None)

This will attempt to match a “detail” to look for in the room. This will do a lower-case match followed by a startsby match. This is called by the new look Command.

Parameters
  • key (str) – A detail identifier.

  • looker (Object, optional) – The one looking.

Returns

detail (str or None) – A detail matching the given key, or None if it was not found.

Notes

A detail is a way to offer more things to look at in a room without having to add new objects. For this to work, we require a custom look command that allows for look <detail> - the look command should defer to this method on the current location (if it exists) before giving up on finding the target.

exception DoesNotExist

Bases: evennia.objects.objects.DefaultRoom.DoesNotExist

exception MultipleObjectsReturned

Bases: evennia.objects.objects.DefaultRoom.MultipleObjectsReturned

path = 'evennia.contrib.grid.extended_room.extended_room.ExtendedRoom'
typename = 'ExtendedRoom'
class evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook(**kwargs)[source]

Bases: evennia.commands.default.general.CmdLook

look

Usage:

look look <obj> look <room detail> look *<account>

Observes your location, details at your location or objects in your vicinity.

look_detail()[source]

Look for detail on room.

func()[source]

Handle the looking.

aliases = ['ls', 'l']
help_category = 'general'
key = 'look'
lock_storage = 'cmd:all()'
search_index_entry = {'aliases': 'ls l', 'category': 'general', 'key': 'look', 'no_prefix': ' ls l', 'tags': '', 'text': '\n look\n\n Usage:\n look\n look <obj>\n look <room detail>\n look *<account>\n\n Observes your location, details at your location or objects in your vicinity.\n '}
class evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDesc(**kwargs)[source]

Bases: evennia.commands.default.building.CmdDesc

describe an object or the current room.

Usage:

@desc[/switch] [<obj> =] <description>

Switches:

edit - Open up a line editor for more advanced editing. del - Delete the description of an object. If another state is given, its description

will be deleted.

spring|summer|autumn|winter - room description to use in respective in-game season <other> - room description to use with an arbitrary room state.

Sets the description an object. If an object is not given, describe the current room, potentially showing any additional stateful descriptions. The room states only work with rooms.

Examples

@desc/winter A cold winter scene. @desc/edit/summer @desc/burning This room is burning! @desc A normal room with no state. @desc/del/burning

Rooms will automatically change season as the in-game time changes. You can set a specific room-state with the |wroomstate|n command.

key = '@desc'
switch_options = None
locks = 'cmd:perm(desc) or perm(Builder)'
help_category = 'building'
parse()[source]

This method is called by the cmdhandler once the command name has been identified. It creates a new set of member variables that can be later accessed from self.func() (see below)

The following variables are available for our use when entering this method (from the command definition, and assigned on the fly by the cmdhandler):

self.key - the name of this command (‘look’) self.aliases - the aliases of this cmd (‘l’) self.permissions - permission string for this command self.help_category - overall category of command

self.caller - the object calling this command self.cmdstring - the actual command name used to call this

(this allows you to know which alias was used,

for example)

self.args - the raw input; everything following self.cmdstring. self.cmdset - the cmdset from which this command was picked. Not

often used (useful for commands like ‘help’ or to list all available commands etc)

self.obj - the object on which this command was defined. It is often

the same as self.caller.

A MUX command has the following possible syntax:

name[ with several words][/switch[/switch..]] arg1[,arg2,…] [[=|,] arg[,..]]

The ‘name[ with several words]’ part is already dealt with by the cmdhandler at this point, and stored in self.cmdname (we don’t use it here). The rest of the command is stored in self.args, which can start with the switch indicator /.

Optional variables to aid in parsing, if set:
self.switch_options - (tuple of valid /switches expected by this

command (without the /))

self.rhs_split - Alternate string delimiter or tuple of strings

to separate left/right hand sides. tuple form gives priority split to first string delimiter.

This parser breaks self.args into its constituents and stores them in the following variables:

self.switches = [list of /switches (without the /)] self.raw = This is the raw argument input, including switches self.args = This is re-defined to be everything except the switches self.lhs = Everything to the left of = (lhs:’left-hand side’). If

no = is found, this is identical to self.args.

self.rhs: Everything to the right of = (rhs:’right-hand side’).

If no ‘=’ is found, this is None.

self.lhslist - [self.lhs split into a list by comma] self.rhslist - [list of self.rhs split into a list by comma] self.arglist = [list of space-separated args (stripped, including ‘=’ if it exists)]

All args and list members are stripped of excess whitespace around the strings, but case is preserved.

edit_handler()[source]
show_stateful_descriptions()[source]
func()[source]

Define command

aliases = []
lock_storage = 'cmd:perm(desc) or perm(Builder)'
search_index_entry = {'aliases': '', 'category': 'building', 'key': '@desc', 'no_prefix': 'desc ', 'tags': '', 'text': '\n describe an object or the current room.\n\n Usage:\n @desc[/switch] [<obj> =] <description>\n\n Switches:\n edit - Open up a line editor for more advanced editing.\n del - Delete the description of an object. If another state is given, its description\n will be deleted.\n spring|summer|autumn|winter - room description to use in respective in-game season\n <other> - room description to use with an arbitrary room state.\n\n Sets the description an object. If an object is not given,\n describe the current room, potentially showing any additional stateful descriptions. The room\n states only work with rooms.\n\n Examples:\n @desc/winter A cold winter scene.\n @desc/edit/summer\n @desc/burning This room is burning!\n @desc A normal room with no state.\n @desc/del/burning\n\n Rooms will automatically change season as the in-game time changes. You can\n set a specific room-state with the |wroomstate|n command.\n\n '}
class evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDetail(**kwargs)[source]

Bases: evennia.commands.default.muxcommand.MuxCommand

sets a detail on a room

Usage:

@detail[/del] <key> [= <description>] @detail <key>;<alias>;… = description

Example

@detail @detail walls = The walls are covered in … @detail castle;ruin;tower = The distant ruin … @detail/del wall @detail/del castle;ruin;tower

This command allows to show the current room details if you enter it without any argument. Otherwise, sets or deletes a detail on the current room, if this room supports details like an extended room. To add new detail, just use the @detail command, specifying the key, an equal sign and the description. You can assign the same description to several details using the alias syntax (replace key by alias1;alias2;alias3;…). To remove one or several details, use the @detail/del switch.

key = '@detail'
locks = 'cmd:perm(Builder)'
help_category = 'building'
func()[source]

This is the hook function that actually does all the work. It is called by the cmdhandler right after self.parser() finishes, and so has access to all the variables defined therein.

aliases = []
lock_storage = 'cmd:perm(Builder)'
search_index_entry = {'aliases': '', 'category': 'building', 'key': '@detail', 'no_prefix': 'detail ', 'tags': '', 'text': '\n sets a detail on a room\n\n Usage:\n @detail[/del] <key> [= <description>]\n @detail <key>;<alias>;... = description\n\n Example:\n @detail\n @detail walls = The walls are covered in ...\n @detail castle;ruin;tower = The distant ruin ...\n @detail/del wall\n @detail/del castle;ruin;tower\n\n This command allows to show the current room details if you enter it\n without any argument. Otherwise, sets or deletes a detail on the current\n room, if this room supports details like an extended room. To add new\n detail, just use the @detail command, specifying the key, an equal sign\n and the description. You can assign the same description to several\n details using the alias syntax (replace key by alias1;alias2;alias3;...).\n To remove one or several details, use the @detail/del switch.\n\n '}
class evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomState(**kwargs)[source]

Bases: evennia.commands.default.muxcommand.MuxCommand

Toggle and view room state for the current room.

Usage:

@roomstate [<roomstate>]

Examples

@roomstate spring @roomstate burning @roomstate burning (a second time toggles it off)

If the roomstate was already set, it will be disabled. Use without arguments to see the roomstates on the current room.

key = '@roomstate'
locks = 'cmd:perm(Builder)'
help_category = 'building'
parse()[source]

This method is called by the cmdhandler once the command name has been identified. It creates a new set of member variables that can be later accessed from self.func() (see below)

The following variables are available for our use when entering this method (from the command definition, and assigned on the fly by the cmdhandler):

self.key - the name of this command (‘look’) self.aliases - the aliases of this cmd (‘l’) self.permissions - permission string for this command self.help_category - overall category of command

self.caller - the object calling this command self.cmdstring - the actual command name used to call this

(this allows you to know which alias was used,

for example)

self.args - the raw input; everything following self.cmdstring. self.cmdset - the cmdset from which this command was picked. Not

often used (useful for commands like ‘help’ or to list all available commands etc)

self.obj - the object on which this command was defined. It is often

the same as self.caller.

A MUX command has the following possible syntax:

name[ with several words][/switch[/switch..]] arg1[,arg2,…] [[=|,] arg[,..]]

The ‘name[ with several words]’ part is already dealt with by the cmdhandler at this point, and stored in self.cmdname (we don’t use it here). The rest of the command is stored in self.args, which can start with the switch indicator /.

Optional variables to aid in parsing, if set:
self.switch_options - (tuple of valid /switches expected by this

command (without the /))

self.rhs_split - Alternate string delimiter or tuple of strings

to separate left/right hand sides. tuple form gives priority split to first string delimiter.

This parser breaks self.args into its constituents and stores them in the following variables:

self.switches = [list of /switches (without the /)] self.raw = This is the raw argument input, including switches self.args = This is re-defined to be everything except the switches self.lhs = Everything to the left of = (lhs:’left-hand side’). If

no = is found, this is identical to self.args.

self.rhs: Everything to the right of = (rhs:’right-hand side’).

If no ‘=’ is found, this is None.

self.lhslist - [self.lhs split into a list by comma] self.rhslist - [list of self.rhs split into a list by comma] self.arglist = [list of space-separated args (stripped, including ‘=’ if it exists)]

All args and list members are stripped of excess whitespace around the strings, but case is preserved.

func()[source]

This is the hook function that actually does all the work. It is called by the cmdhandler right after self.parser() finishes, and so has access to all the variables defined therein.

aliases = []
lock_storage = 'cmd:perm(Builder)'
search_index_entry = {'aliases': '', 'category': 'building', 'key': '@roomstate', 'no_prefix': 'roomstate ', 'tags': '', 'text': '\n Toggle and view room state for the current room.\n\n Usage:\n @roomstate [<roomstate>]\n\n Examples:\n @roomstate spring\n @roomstate burning\n @roomstate burning (a second time toggles it off)\n\n If the roomstate was already set, it will be disabled. Use\n without arguments to see the roomstates on the current room.\n\n '}
class evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomGameTime(**kwargs)[source]

Bases: evennia.commands.default.muxcommand.MuxCommand

Check the game time.

Usage:

time

Shows the current in-game time and season.

key = 'time'
locks = 'cmd:all()'
help_category = 'general'
parse()[source]

This method is called by the cmdhandler once the command name has been identified. It creates a new set of member variables that can be later accessed from self.func() (see below)

The following variables are available for our use when entering this method (from the command definition, and assigned on the fly by the cmdhandler):

self.key - the name of this command (‘look’) self.aliases - the aliases of this cmd (‘l’) self.permissions - permission string for this command self.help_category - overall category of command

self.caller - the object calling this command self.cmdstring - the actual command name used to call this

(this allows you to know which alias was used,

for example)

self.args - the raw input; everything following self.cmdstring. self.cmdset - the cmdset from which this command was picked. Not

often used (useful for commands like ‘help’ or to list all available commands etc)

self.obj - the object on which this command was defined. It is often

the same as self.caller.

A MUX command has the following possible syntax:

name[ with several words][/switch[/switch..]] arg1[,arg2,…] [[=|,] arg[,..]]

The ‘name[ with several words]’ part is already dealt with by the cmdhandler at this point, and stored in self.cmdname (we don’t use it here). The rest of the command is stored in self.args, which can start with the switch indicator /.

Optional variables to aid in parsing, if set:
self.switch_options - (tuple of valid /switches expected by this

command (without the /))

self.rhs_split - Alternate string delimiter or tuple of strings

to separate left/right hand sides. tuple form gives priority split to first string delimiter.

This parser breaks self.args into its constituents and stores them in the following variables:

self.switches = [list of /switches (without the /)] self.raw = This is the raw argument input, including switches self.args = This is re-defined to be everything except the switches self.lhs = Everything to the left of = (lhs:’left-hand side’). If

no = is found, this is identical to self.args.

self.rhs: Everything to the right of = (rhs:’right-hand side’).

If no ‘=’ is found, this is None.

self.lhslist - [self.lhs split into a list by comma] self.rhslist - [list of self.rhs split into a list by comma] self.arglist = [list of space-separated args (stripped, including ‘=’ if it exists)]

All args and list members are stripped of excess whitespace around the strings, but case is preserved.

func()[source]

This is the hook function that actually does all the work. It is called by the cmdhandler right after self.parser() finishes, and so has access to all the variables defined therein.

aliases = []
lock_storage = 'cmd:all()'
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'time', 'no_prefix': ' ', 'tags': '', 'text': '\n Check the game time.\n\n Usage:\n time\n\n Shows the current in-game time and season.\n\n '}
class evennia.contrib.grid.extended_room.extended_room.ExtendedRoomCmdSet(cmdsetobj=None, key=None)[source]

Bases: evennia.commands.cmdset.CmdSet

Groups the extended-room commands.

at_cmdset_creation()[source]

Hook method - this should be overloaded in the inheriting class, and should take care of populating the cmdset by use of self.add().

path = 'evennia.contrib.grid.extended_room.extended_room.ExtendedRoomCmdSet'