There are a few extra flags one can set on CmdSets in order to modify
how they work. All are optional and will be set to defaults otherwise.
Since many of these relate to *merging* cmdsets you might want to read
up on [Commands#Adding\_and\_merging\_command\_sets next section] for
some of these to make sense.
-``key`` (string) - an identifier for the cmdset. This is optional but
should be unique; it is used for display in lists but also to
identify special merging behaviours using the
``key_mergetype' dictionary below. * ``\ mergetype\ `` (string) - one of "_Union_", "_Intersect_", "_Replace_" or "_Remove_". * ``\ priority\ `` (int) - Higher priority sets will take priority during merging. Evennia default sets have priorities between ``\ 0\ `` and ``\ 9\ ``, where ``\ 0\ `` are most commands and ``\ 8\ `` or ``\ 9\ `` are used for special things like channel-commands and exit-commands. *``\ key\_mergetype\ `` (dict) - a dict of ``\ key:mergetype\ `` pairs. This allows this cmdset to merge differently with certain named cmdsets. If the cmdset to merge with has a ``\ key\ `` matching an entry in ``\ key\_mergetype\ ``, it will not be merged according to the setting in ``\ mergetype\ `` but according to the mode in this dict. * ``\ duplicates\ `` (bool, default False) - when merging same-priority cmdsets containing same-key commands, the cmdset being merged "onto" the old one will take precedence. The result will be unique commands. If this flag is set the merged set can have multiple commands with the same key. This will usually lead to multi-match errors for the player. This is is useful e.g. for on-object cmdsets (example: There is a ``\ red
button\ `` and a ``\ green
button\ `` in the room. Both have a ``\ press
button\ `` command, in cmdsets with the same priority. This flag makes sure that just writing ``\ press
button\ `` will force the Player to define just which object's command was intended). * ``\ no\_objs\ `` this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from objects around the player (nor from rooms) when building the merged set. Exit commands will still be included. * ``\ no\_exits\ `` - this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from exits. *``\ is\_exit\ `` (bool) - this marks the cmdset as being used for an in-game exit. This allows the cmdhandler to easily disregard this cmdset when other cmdsets have their ``\ no\_exits\ `` flag set. It is set directly by the Exit object as part of initializing its cmdset. * ``\ no\_channels\ `` (bool) - this is a flag for the cmdhandler that builds the set of commands available at every moment. It tells the handler not to include cmdsets from available in-game channels. *``\ is\_channel\ `` (bool)- this marks the cmdset as being used for an in-game exit. It allows the cmdhandler to easily disregard this cmdset when other cmdsets have their ``\ no\_channels\ `` flag set. It is set directly by the Channel object as part of initializing its cmdset. == Default command sets == Evennia comes with four default cmdsets, used at different parts of the game. You can freely add more and/or expand on these as you see fit. * _DefaultUnloggedin_ (``\ src.commands.default.cmdset\_unloggedin.UnloggedinCmdSet\ ``) - this cmdset holds the commands used before you have authenticated to the server, such as the login screen, connect, create character and so on. * _DefaultSession_ (``\ src.commands.default.cmdset\_session.SessionCmdSet\ `` - this is stored on the [Session] once authenticated. This command set holds no commands by default. It is meant to hold session-specific OOC things, such as character-creation systems. * _DefaultPlayer_ (``\ src.commands.default.cmdset\_player.PlayerCmdSet\ ``) - this is stored on the [Player] and contains account-centric OOC commands, such as the commands for sending text to channels or admin commands for staff. * _DefaultCharacter_ (``\ src.commands.default.cmdset\_character.CharacterCmdSet\ ``) - this is finally stored on Character objects and holds all IC commands available to that Character. This is the biggest cmdset. For it to be available to the player, the Character must be puppeted. Except for the unloggedin cmdset, cmdsets stored on these various levels dre merged "downward" in the connection hierarchy. So when merging (with the same priority), Session cmdsets are merged first, followed by Player and finally Character (so Character command overrule Player commands which overrule Session commands as it were). See the next section for details about merge rules. ==Adding and merging command sets == _Note: This is an advanced topic. It's useful to know about, but you might want to skip it if this is your first time learning about commands._ !CmdSets have the special ability that they can be _merged_ together into new sets. This would happen if you, for example, did ``\ object.cmdset.add(MyCmdSet)\ `` on an object that already had a command set defined on it. The two sets will be evaluated and a temporary, _merged set_ will be created out of the commands in both sets. Only the commands in this merged set is from that point available to use. Which of the ingoing commands end up in the merged set is defined by the _merge rule_ and the relative _priorities_ of the two sets. Removing the latest added set will restore things back to the way it was before the addition. !CmdSets are non-destructively stored in a stack inside the cmdset handler on the object. This stack is parsed to create the "combined" cmdset active at the moment. The very first cmdset in this stack is called the _Default cmdset_ and is protected from accidental deletion. Running ``\ obj.cmdset.delete()\ `` will never delete the default set. Instead one should add new cmdsets on top of th
A2\ `` for set *A* and ``\ B1, B2, B3,
B4\ `` for *B*. So for that example both sets contain commands with the same keys 1 and 2, whereas commands 3 and 4 are unique to *B*. To describe a merge between these sets, we would write {{{A1,A2 + B1,B2,B3,B4 = ?}}} where ``?\ `` is a list of commands that depend on which merge type *A* has, and which relative priorities the two sets have. By convention, we read this statement as "New command set *A* is merged onto the old command set *B* to form *?*". Below are the available merge types and how they work. Names are partly borrowed from [http://en.wikipedia.org/wiki/Set_theory Set theory]. *Union* (default) - The two cmdsets are merged so that as many commands as possible from each cmdset ends up in the merged cmdset. Same-key commands are merged by priority. {{{ # Union A1,A2 + B1,B2,B3,B4 = A1,A2,B3,B4 }}} *Intersect* - Only commands found in _both_ cmdsets (i.e. which have the same keys) end up in the merged cmdset, with the higher-priority cmdset replacing the lower one's commands. {{{ # Intersect A1,A3,A5 + B1,B2,B4,B5 = A1,A5 }}} *Replace* - The commands of the higher-prio cmdset completely replaces the lower-priority cmdset's commands, regardless of if same-key commands exist or not. {{{ # Replace A1,A3 + B1,B2,B4,B5 = A1,A3 }}} *Remove* - The high-priority command sets removes same-key commands from the lower-priority cmdset. They are not replaced with anything, so this is a sort of filter that prunes the low-prio set using the high-prio one as a template. {{{ # Remove A1,A3 + B1,B2,B3,B4,B5 = B2,B4,B5 }}} Besides ``\ priority\ `` and ``\ mergetype\ ``, a command set also takes a few other variables to control how they merge: * _duplicates_ (bool) - determines what happens when two sets of equal priority merge. Default is that the new set in the merger (i.e. *A* above) automatically takes precedence. But if _duplicates_ is true, the result will be a merger with more than one of each name match. This will usually lead to the player receiving a multiple-match error higher up the road, but can be good for things like cmdsets on non-player objects in a room, to allow the system to warn that more than one 'ball' in the room has the same 'kick' command defined on it, so it may offer a chance to select which ball to kick ... Allowing duplicates only makes sense for _Union_ and _Intersect_, the setting is ignored for the other mergetypes. * _key_mergetypes_ (dict) - allows the cmdset to define a unique mergetype for particular cmdsets, identified by their cmdset-key. Format is ``\ {CmdSetkey:mergetype}``. Priorities still apply. Example: ``\ {'Myevilcmdset','Replace'}\ `` which would make sure for this set to always use 'Replace' on ``\ Myevilcmdset\ `` only, no matter what _mergetype_ is set to. More advanced cmdset example: {{{ class MyCmdSet(CmdSet): key = "MyCmdSet" priority = 4 mergetype = "Replace" key_mergetypes = {'MyOtherCmdSet':'Union'} def at_cmdset_creation(self): """ The only thing this method should need to do is to add commands to the set. """ self.add(mycommands.MyCommand1()) self.add(mycommands.MyCommand2()) self.add(mycommands.MyCommand3()) }}} == System commands == _Note: This is an advanced topic. Skip it if this is your first time learning about commands._ There are several command-situations that are exceptional in the eyes of the server. What happens if the player enters an empty string? What if the 'command' given is infact the name of a channel the user wants to send a message to? Or if there are multiple command possibilities? Such 'special cases' are handled by what's called _system commands_. A system command is defined in the same way as other commands, except that their name (key) mus
class variable can be used to implement state-persistent commands.
For example it can make a command operate on "it", where it is
determined by what the previous command operated on.**