From 655de3b654b0de39d5dfa7a8d192f26ae4275920 Mon Sep 17 00:00:00 2001
From: Griatch __unloggedin_look_command [l, look] (cmdset: UnloggedinCmdSet, help-category: General) about [version] (cmdset: CharacterCmdSet, help-category: System) access [hierarchy, groups] (cmdset: CharacterCmdSet, help-category: General) accounts [listaccounts, account] (cmdset: CharacterCmdSet, help-category: System) addcom [chanalias, aliaschan] (cmdset: AccountCmdSet, help-category: Comms) access [groups, hierarchy] (cmdset: CharacterCmdSet, help-category: General) accounts [account, listaccounts] (cmdset: CharacterCmdSet, help-category: System) addcom [aliaschan, chanalias] (cmdset: AccountCmdSet, help-category: Comms) alias [setobjalias] (cmdset: CharacterCmdSet, help-category: Building) allcom (cmdset: AccountCmdSet, help-category: Comms) batchcode [batchcodes] (cmdset: CharacterCmdSet, help-category: Building) batchcommands [batchcmd, batchcommand] (cmdset: CharacterCmdSet, help-category: Building) batchcommands [batchcommand, batchcmd] (cmdset: CharacterCmdSet, help-category: Building) cboot (cmdset: AccountCmdSet, help-category: Comms) ccreate [channelcreate] (cmdset: AccountCmdSet, help-category: Comms) cdesc (cmdset: AccountCmdSet, help-category: Comms) cdestroy (cmdset: AccountCmdSet, help-category: Comms) cemit [cmsg] (cmdset: AccountCmdSet, help-category: Comms) channels [comlist, clist, chanlist, channellist, all channels] (cmdset: AccountCmdSet, help-category: Comms) channels [all channels, chanlist, channellist, comlist, clist] (cmdset: AccountCmdSet, help-category: Comms) charcreate (cmdset: AccountCmdSet, help-category: General) chardelete (cmdset: AccountCmdSet, help-category: General) clock (cmdset: AccountCmdSet, help-category: Comms)
drop (cmdset: CharacterCmdSet, help-category: General)
encoding [encode] (cmdset: UnloggedinCmdSet, help-category: General)
examine [exam, ex] (cmdset: AccountCmdSet, help-category: Building)
find [locate, search] (cmdset: CharacterCmdSet, help-category: Building)
examine [ex, exam] (cmdset: AccountCmdSet, help-category: Building)
find [search, locate] (cmdset: CharacterCmdSet, help-category: Building)
get [grab] (cmdset: CharacterCmdSet, help-category: General)
give (cmdset: CharacterCmdSet, help-category: General)
grapevine2chan (cmdset: AccountCmdSet, help-category: Comms)
ic [puppet] (cmdset: AccountCmdSet, help-category: General)
info (cmdset: UnloggedinCmdSet, help-category: General)
inventory [inv, i] (cmdset: CharacterCmdSet, help-category: General)
inventory [i, inv] (cmdset: CharacterCmdSet, help-category: General)
irc2chan (cmdset: AccountCmdSet, help-category: Comms)
ircstatus (cmdset: AccountCmdSet, help-category: Comms)
link (cmdset: CharacterCmdSet, help-category: Building)
lock [locks] (cmdset: CharacterCmdSet, help-category: Building)
look [ls, l] (cmdset: AccountCmdSet, help-category: General)
look [ls, l] (cmdset: CharacterCmdSet, help-category: General)
look [l, ls] (cmdset: AccountCmdSet, help-category: General)
look [l, ls] (cmdset: CharacterCmdSet, help-category: General)
mvattr (cmdset: CharacterCmdSet, help-category: Building)
name [rename] (cmdset: CharacterCmdSet, help-category: Building)
nick [nicks, nickname] (cmdset: AccountCmdSet, help-category: General)
objects [listobjs, listobjects, db, stats] (cmdset: CharacterCmdSet, help-category: System)
objects [listobjects, db, stats, listobjs] (cmdset: CharacterCmdSet, help-category: System)
ooc [unpuppet] (cmdset: AccountCmdSet, help-category: General)
open (cmdset: CharacterCmdSet, help-category: Building)
option [options] (cmdset: AccountCmdSet, help-category: General)
page [tell] (cmdset: AccountCmdSet, help-category: Comms)
password (cmdset: AccountCmdSet, help-category: General)
pose [emote, :] (cmdset: CharacterCmdSet, help-category: General)
pose [:, emote] (cmdset: CharacterCmdSet, help-category: General)
py [!] (cmdset: AccountCmdSet, help-category: System)
quell [unquell] (cmdset: AccountCmdSet, help-category: General)
quit (cmdset: AccountCmdSet, help-category: General)
quit [q, qu] (cmdset: UnloggedinCmdSet, help-category: General)
quit [qu, q] (cmdset: UnloggedinCmdSet, help-category: General)
reload [restart] (cmdset: AccountCmdSet, help-category: System)
reset [reboot] (cmdset: AccountCmdSet, help-category: System)
rss2chan (cmdset: AccountCmdSet, help-category: Comms)
say [’, “] (cmdset: CharacterCmdSet, help-category: General)
say [”, ‘] (cmdset: CharacterCmdSet, help-category: General)
screenreader (cmdset: UnloggedinCmdSet, help-category: General)
script [addscript] (cmdset: CharacterCmdSet, help-category: Building)
scripts [globalscript, listscripts] (cmdset: CharacterCmdSet, help-category: System)
server [serverload, serverprocess] (cmdset: CharacterCmdSet, help-category: System)
scripts [listscripts, globalscript] (cmdset: CharacterCmdSet, help-category: System)
server [serverprocess, serverload] (cmdset: CharacterCmdSet, help-category: System)
service [services] (cmdset: CharacterCmdSet, help-category: System)
sessions (cmdset: SessionCmdSet, help-category: General)
set (cmdset: CharacterCmdSet, help-category: Building)
time [uptime] (cmdset: CharacterCmdSet, help-category: System)
tunnel [tun] (cmdset: CharacterCmdSet, help-category: Building)
typeclass [swap, update, parent, type] (cmdset: CharacterCmdSet, help-category: Building)
typeclass [swap, type, parent, update] (cmdset: CharacterCmdSet, help-category: Building)
unlink (cmdset: CharacterCmdSet, help-category: Building)
whisper (cmdset: CharacterCmdSet, help-category: General)
who [doing] (cmdset: AccountCmdSet, help-category: General)
aliases = ['ls', 'l']¶aliases = ['l', 'ls']¶
aliases = ['batchcmd', 'batchcommand']¶aliases = ['batchcommand', 'batchcmd']¶
aliases = ['swap', 'update', 'parent', 'type']¶aliases = ['swap', 'type', 'parent', 'update']¶
aliases = ['exam', 'ex']¶aliases = ['ex', 'exam']¶
aliases = ['locate', 'search']¶aliases = ['search', 'locate']¶
aliases = ['chanalias', 'aliaschan']¶aliases = ['aliaschan', 'chanalias']¶
aliases = ['comlist', 'clist', 'chanlist', 'channellist', 'all channels']¶aliases = ['all channels', 'chanlist', 'channellist', 'comlist', 'clist']¶
aliases = ['ls', 'l']¶aliases = ['l', 'ls']¶
aliases = ['inv', 'i']¶aliases = ['i', 'inv']¶
aliases = ["'", '"']¶aliases = ['"', "'"]¶
aliases = ['emote', ':']¶aliases = [':', 'emote']¶
aliases = ['hierarchy', 'groups']¶aliases = ['groups', 'hierarchy']¶
aliases = ['globalscript', 'listscripts']¶aliases = ['listscripts', 'globalscript']¶
aliases = ['listobjs', 'listobjects', 'db', 'stats']¶aliases = ['listobjects', 'db', 'stats', 'listobjs']¶
aliases = ['serverload', 'serverprocess']¶aliases = ['serverprocess', 'serverload']¶
aliases = ['listaccounts', 'account']¶aliases = ['account', 'listaccounts']¶
aliases = ['q', 'qu']¶aliases = ['qu', 'q']¶
aliases = ['ls', 'l']¶aliases = ['l', 'ls']¶
aliases = ['inv', 'i']¶aliases = ['i', 'inv']¶
aliases = ['q', 'qu']¶aliases = ['qu', 'q']¶
aliases = ['ls', 'l']¶aliases = ['l', 'ls']¶
aliases = ['@calls', '@callbacks', '@callback']¶aliases = ['@callback', '@calls', '@callbacks']¶
aliases = ["'", '"']¶aliases = ['"', "'"]¶
aliases = ['press', 'press button', 'push']¶
aliases = ['break lid', 'smash', 'smash lid']¶
aliases = ['listen', 'examine', 'get', 'ex', 'l', 'feel']¶
aliases = ['burn', 'light']¶aliases = ['light', 'burn']¶
aliases = ['shiftroot', 'pull', 'move', 'push']¶aliases = ['push', 'pull', 'move', 'shiftroot']¶
aliases = ['press button', 'button', 'push button']¶aliases = ['button', 'push button', 'press button']¶
aliases = ['slash', 'hit', 'stab', 'parry', 'defend', 'pierce', 'bash', 'kill', 'thrust', 'fight', 'chop']¶aliases = ['chop', 'hit', 'pierce', 'parry', 'kill', 'thrust', 'bash', 'stab', 'slash', 'defend', 'fight']¶
aliases = ['ls', 'l']¶aliases = ['l', 'ls']¶
aliases = ['feel', 'fiddle', 'search', 'feel around', 'l']¶aliases = ['search', 'fiddle', 'feel around', 'l', 'feel']¶
aliases = [':I', ':echo', ':y', ':x', ':q!', ':DD', ':u', ':fd', ':uu', '::', ':r', ':S', ':::', ':wq', ':q', ':=', ':dd', ':!', ':<', ':i', ':', ':A', ':f', ':>', ':UU', ':w', ':dw', ':s', ':h', ':fi', ':j', ':p']¶aliases = [':!', ':fd', ':::', ':i', ':', ':u', ':I', ':S', ':>', ':y', ':A', ':DD', ':fi', ':j', ':dd', ':h', ':echo', ':wq', '::', ':dw', ':q', ':r', ':q!', ':=', ':uu', ':p', ':w', ':UU', ':s', ':x', ':<', ':f']¶
aliases = ['n', 'next', 'end', 'a', 'quit', 't', 'e', 'q', 'top', 'back', 'abort', 'b']¶aliases = ['a', 'next', 'quit', 'end', 'back', 't', 'q', 'e', 'abort', 'top', 'b', 'n']¶
When performing actions in Evennia it is often important that you store data for later. If you write -a menu system, you have to keep track of the current location in the menu tree so that the player -can give correct subsequent commands. If you are writing a combat system, you might have a -combattant’s next roll get easier dependent on if their opponent failed. Your characters will -probably need to store roleplaying-attributes like strength and agility. And so on.
-Typeclassed game entities (Accounts, Objects,
-Scripts and Channels) always have Attributes associated with them.
-Attributes are used to store any type of data ‘on’ such entities. This is different from storing
-data in properties already defined on entities (such as key or location) - these have very
-specific names and require very specific types of data (for example you couldn’t assign a python
-list to the key property no matter how hard you tried). Attributes come into play when you
-want to assign arbitrary data to arbitrary names.
Attributes are not secure by default and any player may be able to change them unless you -prevent this behavior.
-To save persistent data on a Typeclassed object you normally use the db (DataBase) operator. Let’s
-try to save some data to a Rose (an Object):
# saving
- rose.db.has_thorns = True
- # getting it back
- is_ouch = rose.db.has_thorns
+# in-game
+> set obj/myattr = "test"
+# in code
+obj.db.foo = [1,2,3, "bar"]
+value = obj.db.foo
+
+obj.attributes.add("myattr", 1234, category="bar")
+value = attributes.get("myattr", category="bar")
-This looks like any normal Python assignment, but that db makes sure that an Attribute is
-created behind the scenes and is stored in the database. Your rose will continue to have thorns
-throughout the life of the server now, until you deliberately remove them.
-To be sure to save non-persistently, i.e. to make sure NOT to create a database entry, you use
-ndb (NonDataBase). It works in the same way:
- # saving
- rose.ndb.has_thorns = True
- # getting it back
- is_ouch = rose.ndb.has_thorns
-
-
-Technically, ndb has nothing to do with Attributes, despite how similar they look. No
-Attribute object is created behind the scenes when using ndb. In fact the database is not
-invoked at all since we are not interested in persistence. There is however an important reason to
-use ndb to store data rather than to just store variables direct on entities - ndb-stored data
-is tracked by the server and will not be purged in various cache-cleanup operations Evennia may do
-while it runs. Data stored on ndb (as well as db) will also be easily listed by example the
-@examine command.
-You can also del properties on db and ndb as normal. This will for example delete an
-Attribute:
- del rose.db.has_thorns
-
-
-Both db and ndb defaults to offering an all property on themselves. This returns all
-associated attributes or non-persistent properties.
- list_of_all_rose_attributes = rose.db.all
- list_of_all_rose_ndb_attrs = rose.ndb.all
-
-
-If you use all as the name of an attribute, this will be used instead. Later deleting your custom
-all will return the default behaviour.
-
-
-The AttributeHandler¶
-The .db and .ndb properties are very convenient but if you don’t know the name of the Attribute
-beforehand they cannot be used. Behind the scenes .db actually accesses the AttributeHandler
-which sits on typeclassed entities as the .attributes property. .ndb does the same for the
-.nattributes property.
-The handlers have normal access methods that allow you to manage and retrieve Attributes and
-NAttributes:
+Attributes allow you to to store arbitrary data on objects and make sure the data survives a
+server reboot. An Attribute can store pretty much any
+Python data structure and data type, like numbers, strings, lists, dicts etc. You can also
+store (references to) database objects like characters and rooms.
-has('attrname') - this checks if the object has an Attribute with this key. This is equivalent
-to doing obj.db.attrname.
-get(...) - this retrieves the given Attribute. Normally the value property of the Attribute is
-returned, but the method takes keywords for returning the Attribute object itself. By supplying an
+
What can be stored in an Attribute is a must-read
+also for experienced developers, to avoid getting surprised. Attributes can store almost everything
+but you need to know the quirks.
+NAttributes are the in-memory, non-persistent
+siblings of Attributes.
+Managing Attributes In-game for in-game builder commands.
+
+
+Managing Attributes in Code¶
+Attributes are usually handled in code. All Typeclassed entities
+(Accounts, Objects, Scripts and
+Channels) all can (and usually do) have Attributes associated with them. There
+are three ways to manage Attributes, all of which can be mixed.
+
+
+Using .db¶
+The simplest way to get/set Attributes is to use the .db shortcut:
+import evennia
+
+obj = evennia.create_object(key="Foo")
+
+obj.db.foo1 = 1234
+obj.db.foo2 = [1, 2, 3, 4]
+obj.db.weapon = "sword"
+obj.db.self_reference = obj # stores a reference to the obj
+
+# (let's assume a rose exists in-game)
+rose = evennia.search_object(key="rose")[0] # returns a list, grab 0th element
+rose.db.has_thorns = True
+
+# retrieving
+val1 = obj.db.foo1
+val2 = obj.db.foo2
+weap = obj.db.weapon
+myself = obj.db.self_reference # retrieve reference from db, get object back
+
+is_ouch = rose.db.has_thorns
+
+# this will return None, not AttributeError!
+not_found = obj.db.jiwjpowiwwerw
+
+# returns all Attributes on the object
+obj.db.all
+
+# delete an Attribute
+del obj.db.foo2
+
+
+Trying to access a non-existing Attribute will never lead to an AttributeError. Instead
+you will get None back. The special .db.all will return a list of all Attributes on
+the object. You can replace this with your own Attribute all if you want, it will replace the
+default all functionality until you delete it again.
+
+
+Using .attributes¶
+If you don’t know the name of the Attribute beforehand you can also use
+the AttributeHandler, available as .attributes. With no extra keywords this is identical
+to using the .db shortcut (.db is actually using the AttributeHandler internally):
+is_ouch = rose.attributes.get("has_thorns")
+
+obj.attributes.add("helmet", "Knight's helmet")
+helmet = obj.attributes.get("helmet")
+
+# you can give space-separated Attribute-names (can't do that with .db)
+obj.attributes.add("my game log", "long text about ...")
+
+
+With the AttributeHandler you can also give Attributes a category. By using a category you can
+separate same-named Attributes on the same object which can help organization:
+# store (let's say we have gold_necklace and ringmail_armor from before)
+obj.attributes.add("neck", gold_necklace, category="clothing")
+obj.attributes.add("neck", ringmail_armor, category="armor")
+
+# retrieve later - we'll get back gold_necklace and ringmail_armor
+neck_clothing = obj.attributes.get("neck", category="clothing")
+neck_armor = obj.attributes.get("neck", category="armor")
+
+
+If you don’t specify a category, the Attribute’s category will be None. Note that
+None is also considered a category of its own, so you won’t find None-category Attributes mixed
+with Attributes having categories.
+
+When using .db, you will always use the None category.
+
+Here are the methods of the AttributeHandler. See
+the AttributeHandler API for more details.
+
+has(...) - this checks if the object has an Attribute with this key. This is equivalent
+to doing obj.db.attrname except you can also check for a specific `category.
+get(...) - this retrieves the given Attribute. You can also provide a default value to return
+if the Attribute is not defined (instead of None). By supplying an
accessing_object to the call one can also make sure to check permissions before modifying
-anything.
+anything. The raise_exception kwarg allows you to raise an AttributeError instead of returning
+None when you access a non-existing Attribute. The strattr kwarg tells the system to store
+the Attribute as a raw string rather than to pickle it. While an optimization this should usually
+not be used unless the Attribute is used for some particular, limited purpose.
add(...) - this adds a new Attribute to the object. An optional lockstring can be
supplied here to restrict future access and also the call itself may be checked against locks.
remove(...) - Remove the given Attribute. This can optionally be made to check for permission
before performing the deletion. - clear(...) - removes all Attributes from object.
-all(...) - returns all Attributes (of the given category) attached to this object.
+all(category=None) - returns all Attributes (of the given category) attached to this object.
-See this section for more about locking down Attribute
-access and editing. The Nattribute offers no concept of access control.
-Some examples:
- import evennia
- obj = evennia.search_object("MyObject")
+Examples:
+try:
+ # raise error if Attribute foo does not exist
+ val = obj.attributes.get("foo", raise_exception=True):
+except AttributeError:
+ # ...
+
+# return default value if foo2 doesn't exist
+val2 = obj.attributes.get("foo2", default=[1, 2, 3, "bar"])
- obj.attributes.add("test", "testvalue")
- print(obj.db.test) # prints "testvalue"
- print(obj.attributes.get("test")) # "
- print(obj.attributes.all()) # prints [<AttributeObject>]
- obj.attributes.remove("test")
+# delete foo if it exists (will silently fail if unset, unless
+# raise_exception is set)
+obj.attributes.remove("foo")
+
+# view all clothes on obj
+all_clothes = obj.attributes.all(category="clothes")
-
-Properties of Attributes¶
-An Attribute object is stored in the database. It has the following properties:
+
+Using AttributeProperty¶
+There is a third way to set up an Attribute, and that is by setting up an AttributeProperty. This
+is done on the class level of your typeclass and allows you to treat Attributes a bit like Django
+database Fields.
+# mygame/typeclasses/characters.py
+
+from evennia import DefaultCharacter
+from evennia.typeclasses.attributes import AttributeProperty
+
+class Character(DefaultCharacter):
+
+ strength = AttributeProperty(default=10, category='stat', autocreate=True)
+ constitution = AttributeProperty(default=10, category='stat', autocreate=True)
+ agility = AttributeProperty(default=10, category='stat', autocreate=True)
+ magic = AttributeProperty(default=10, category='stat', autocreate=True)
+
+ sleepy = AttributeProperty(default=False)
+ poisoned = AttributeProperty(default=False)
+
+ def at_object_creation(self):
+ # ...
+
+
+These “Attribute-properties” will be made available to all instances of the class.
+
+Important
+If you change the default of an AttributeProperty (and reload), it will
+change the default for all instances of that class (it will not override
+explicitly changed values).
+
+char = evennia.search_object(Character, key="Bob")[0] # returns list, get 0th element
+
+# get defaults
+strength = char.strength # will get the default value 10
+
+# assign new values (this will create/update new Attributes)
+char.strength = 12
+char.constitution = 16
+char.agility = 8
+char.magic = 2
+
+# you can also do arithmetic etc
+char.magic += 2 # char.magic is now 4
+
+# check Attributes
+strength = char.strength # this is now 12
+is_sleepy = char.sleepy
+is_poisoned = char.poisoned
+
+del char.strength # wipes the Attribute
+strength = char.strengh # back to the default (10) again
+
+
+See the AttributeProperty docs for more
+details on arguments.
+An AttributeProperty will not create an Attribute by default. A new Attribute will be created
+(or an existing one retrieved/updated) will happen differently depending on how the autocreate
+keyword:
-key - the name of the Attribute. When doing e.g. obj.db.attrname = value, this property is set
-to attrname.
-value - this is the value of the Attribute. This value can be anything which can be pickled -
-objects, lists, numbers or what have you (see
-this section for more info). In the
-example
-obj.db.attrname = value, the value is stored here.
-category - this is an optional property that is set to None for most Attributes. Setting this
-allows to use Attributes for different functionality. This is usually not needed unless you want
-to use Attributes for very different functionality (Nicks is an example of using
-Attributes
-in this way). To modify this property you need to use the
-Attribute Handler.
-strvalue - this is a separate value field that only accepts strings. This severely limits the
-data possible to store, but allows for easier database lookups. This property is usually not used
-except when re-using Attributes for some other purpose (Nicks use it). It is only
-accessible via the Attribute Handler.
+If autocreate=False (default), an Attribute will be created only if the field is explicitly
+assigned a value (even if the value is the same as the default, such as char.strength = 10).
+If autocreate=True, an Attribute will be created as soon as the field is accessed in
+any way (So both strength = char.strength and char.strength = 10 will both make sure that
+an Attribute exists.
-There are also two special properties:
-
-attrtype - this is used internally by Evennia to separate Nicks, from Attributes (Nicks
-use Attributes behind the scenes).
-model - this is a natural-key describing the model this Attribute is attached to. This is on
-the form appname.modelclass, like objects.objectdb. It is used by the Attribute and
-NickHandler to quickly sort matches in the database. Neither this nor attrtype should normally
-need to be modified.
-
-Non-database attributes have no equivalence to category nor strvalue, attrtype or model.
+Example:
+# in mygame/typeclasses/objects.py
+
+from evennia import create_object
+from evennia import DefaultObject
+from evennia.typeclasses.attributes import AttributeProperty
+
+class Object(DefaultObject):
+
+ value_a = AttributeProperty(default="foo")
+ value_b = AttributeProperty(default="bar", autocreate=True)
+
+obj = evennia.create_object(key="Dummy")
+
+# these will find NO Attributes!
+obj.db.value_a
+obj.attributes.get("value_a")
+obj.db.value_b
+obj.attributes.get("value_b")
+
+# get data from attribute-properties
+vala = obj.value_a # returns "foo"
+valb = obj.value_b # return "bar" AND creates the Attribute (autocreate)
+
+# the autocreate property will now be found
+obj.db.value_a # still not found
+obj.attributes.get("value_a") # ''
+obj.db.value_b # now returns "bar"
+obj.attributes.get("value_b") # ''
+
+# assign new values
+obj.value_a = 10 # will now create a new Attribute
+obj.value_b = 12 # will update the existing Attribute
+
+# both are now found as Attributes
+obj.db.value_a # now returns 10
+obj.attributes.get("value_a") # ''
+obj.db.value_b # now returns 12
+obj.attributes.get("value_b") # ''
+
+
+If you always access your Attributes via the AttributeProperty this does not matter that much
+(it’s also a bit of an optimization to not create an actual database Attribute unless the value changed).
+But until an Attribute has been created, AttributeProperty fields will not show up with the
+examine command or by using the .db or .attributes handlers - so this is a bit inconsistent.
+If this is important, you need to ‘initialize’ them by accessing them at least once … something
+like this:
+# ...
+class Character(DefaultCharacter):
+
+ strength = AttributeProperty(12, autocreate=True)
+ agility = AttributeProperty(12, autocreate=True)
+
+
+ def at_object_creation(self):
+ # initializing
+ self.strength # by accessing it, the Attribute is auto-created
+ self.agility # ''
+
+
+
+Important
+If you created your AttributeProperty with a category, you must specify the
+category in .attributes.get() if you want to find it this way. Remember that
+.db always uses a category of None.
+
-
-Persistent vs non-persistent¶
-So persistent data means that your data will survive a server reboot, whereas with
-non-persistent data it will not …
-… So why would you ever want to use non-persistent data? The answer is, you don’t have to. Most of
-the time you really want to save as much as you possibly can. Non-persistent data is potentially
-useful in a few situations though.
+
+
+Managing Attributes in-game¶
+Attributes are mainly used by code. But one can also allow the builder to use Attributes to
+‘turn knobs’ in-game. For example a builder could want to manually tweak the “level” Attribute of an
+enemy NPC to lower its difficuly.
+When setting Attributes this way, you are severely limited in what can be stored - this is because
+giving players (even builders) the ability to store arbitrary Python would be a severe security
+problem.
+In game you can set an Attribute like this:
+set myobj/foo = "bar"
+
+
+To view, do
+set myobj/foo
+
+
+or see them together with all object-info with
+examine myobj
+
+
+The first set-example will store a new Attribute foo on the object myobj and give it the
+value “bar”.
+You can store numbers, booleans, strings, tuples, lists and dicts this way. But if
+you store a list/tuple/dict they must be proper Python structures and may only contain strings
+or numbers. If you try to insert an unsupported structure, the input will be converted to a
+string.
+set myobj/mybool = True
+set myobj/mybool = True
+set myobj/mytuple = (1, 2, 3, "foo")
+set myobj/mylist = ["foo", "bar", 2]
+set myobj/mydict = {"a": 1, "b": 2, 3: 4}
+set mypobj/mystring = [1, 2, foo] # foo is invalid Python (no quotes)
+
+
+For the last line you’ll get a warning and the value instead will be saved as a string "[1, 2, foo]".
+
+
+Locking and checking Attributes¶
+While the set command is limited to builders, individual Attributes are usually not
+locked down. You may want to lock certain sensitive Attributes, in particular for games
+where you allow player building. You can add such limitations by adding a lock string
+to your Attribute. A NAttribute have no locks.
+The relevant lock types are
-You are worried about database performance. Since Evennia caches Attributes very aggressively,
-this is not an issue unless you are reading and writing to your Attribute very often (like many
-times per second). Reading from an already cached Attribute is as fast as reading any Python
-property. But even then this is not likely something to worry about: Apart from Evennia’s own
-caching, modern database systems themselves also cache data very efficiently for speed. Our
-default
-database even runs completely in RAM if possible, alleviating much of the need to write to disk
-during heavy loads.
-A more valid reason for using non-persistent data is if you want to lose your state when logging
-off. Maybe you are storing throw-away data that are re-initialized at server startup. Maybe you
-are implementing some caching of your own. Or maybe you are testing a buggy Script that
-does potentially harmful stuff to your character object. With non-persistent storage you can be
-sure
-that whatever is messed up, it’s nothing a server reboot can’t clear up.
-NAttributes have no restrictions at all on what they can store (see next section), since they
-don’t need to worry about being saved to the database - they work very well for temporary storage.
-You want to implement a fully or partly non-persistent world. Who are we to argue with your
-grand vision!
+attrread - limits who may read the value of the Attribute
+attredit - limits who may set/change this Attribute
+You must use the AttributeHandler to assign the lockstring to the Attribute:
+lockstring = "attread:all();attredit:perm(Admins)"
+obj.attributes.add("myattr", "bar", lockstring=lockstring)"
+
+
+If you already have an Attribute and want to add a lock in-place you can do so
+by having the AttributeHandler return the Attribute object itself (rather than
+its value) and then assign the lock to it directly:
+ lockstring = "attread:all();attredit:perm(Admins)"
+ obj.attributes.get("myattr", return_obj=True).locks.add(lockstring)
+
+
+Note the return_obj keyword which makes sure to return the Attribute object so its LockHandler
+could be accessed.
+A lock is no good if nothing checks it – and by default Evennia does not check locks on Attributes.
+To check the lockstring you provided, make sure you include accessing_obj and set
+default_access=False as you make a get call.
+ # in some command code where we want to limit
+ # setting of a given attribute name on an object
+ attr = obj.attributes.get(attrname,
+ return_obj=True,
+ accessing_obj=caller,
+ default=None,
+ default_access=False)
+ if not attr:
+ caller.msg("You cannot edit that Attribute!")
+ return
+ # edit the Attribute here
+
+
+The same keywords are available to use with obj.attributes.set() and obj.attributes.remove(),
+those will check for the attredit lock type.
What types of data can I save in an Attribute?¶
-
-None of the following affects NAttributes, which does not invoke the database at all. There are no
-restrictions to what can be stored in a NAttribute.
-
The database doesn’t know anything about Python objects, so Evennia must serialize Attribute
-values into a string representation in order to store it to the database. This is done using the
-pickle module of Python (the only exception is if you use the strattr keyword of the
-AttributeHandler to save to the strvalue field of the Attribute. In that case you can only save
-strings which will not be pickled).
-It’s important to note that when you access the data in an Attribute you are always de-serializing
-it from the database representation every time. This is because we allow for storing
-database-entities in Attributes too. If we cached it as its Python form, we might end up with
-situations where the database entity was deleted since we last accessed the Attribute.
-De-serializing data with a database-entity in it means querying the database for that object and
-making sure it still exists (otherwise it will be set to None). Performance-wise this is usually
-not a big deal. But if you are accessing the Attribute as part of some big loop or doing a large
-amount of reads/writes you should first extract it to a temporary variable, operate on that and
-then save the result back to the Attribute. If you are storing a more complex structure like a
-dict or a list you should make sure to “disconnect” it from the database before looping over it,
-as mentioned in the Retrieving Mutable Objects section
-below.
+values into a string representation before storing it to the database. This is done using the
+pickle module of Python.
+
+The only exception is if you use the strattr keyword of the
+AttributeHandler to save to the strvalue field of the Attribute. In that case you can only save
+strings and those will not be pickled).
+
Storing single objects¶
With a single object, we mean anything that is not iterable, like numbers, strings or custom class
instances without the __iter__ method.
-You can generally store any non-iterable Python entity that can be
-pickled.
-Single database objects/typeclasses can be stored as any other in the Attribute. These can
-normally not be pickled, but Evennia will behind the scenes convert them to an internal
-representation using their classname, database-id and creation-date with a microsecond precision,
-guaranteeing you get the same object back when you access the Attribute later.
-If you hide a database object inside a non-iterable custom class (like stored as a variable
-inside it), Evennia will not know it’s there and won’t convert it safely. Storing classes with
-such hidden database objects is not supported and will lead to errors!
+You can generally store any non-iterable Python entity that can be pickled.
+Single database objects/typeclasses can be stored, despite them normally not being possible
+to pickle. Evennia wil convert them to an internal representation using their classname,
+database-id and creation-date with a microsecond precision. When retrieving, the object
+instance will be re-fetched from the database using this information.
+To convert the database object, Evennia must know it’s there. If you hide a database object
+inside a non-iterable class, you will run into errors - this is not supported!
+
+Valid assignments¶
# Examples of valid single-value attribute data:
obj.db.test1 = 23
obj.db.test1 = False
# a database object (will be stored as an internal representation)
obj.db.test2 = myobj
-
-# example of an invalid, "hidden" dbobject
-class Invalid(object):
- def __init__(self, dbobj):
- # no way for Evennia to know this is a dbobj
- self.dbobj = dbobj
-invalid = Invalid(myobj)
-obj.db.invalid = invalid # will cause error!
+
+
+Invalid, ‘hidden’ dbobject¶
+# example of an invalid, "hidden" dbobject
+class Container:
+ def __init__(self, mydbobj):
+ # no way for Evennia to know this is a database object!
+ self.mydbobj = mydbobj
+container = Container(myobj)
+obj.db.invalid = container # will cause error!
+
+
+
Storing multiple objects¶
@@ -258,11 +452,8 @@ entities you can loop over in a for-loop. Attribute-saving supports the followin
Lists, like [1,2,"test", <dbobj>].
Dicts, like {1:2, "test":<dbobj>].
Sets, like {1,2,"test",<dbobj>}.
-
-
-collections.OrderedDict,
-like OrderedDict((1,2), ("test", <dbobj>)).
-
+collections.OrderedDict,
+like OrderedDict((1,2), ("test", <dbobj>)).
collections.Deque, like
deque((1,2,"test",<dbobj>)).
Nestings of any combinations of the above, like lists in dicts or an OrderedDict of tuples, each
@@ -334,7 +525,6 @@ function evennia.ut
from evennia.utils.dbserialize import deserialize
decoupled_mutables = deserialize(nested_mutables)
-
The result of this operation will be a structure only consisting of normal Python mutables (list
@@ -354,52 +544,100 @@ already disconnected from the database from the onset.
# without affecting the database.
-
-Attributes will fetch data fresh from the database whenever you read them, so
-if you are performing big operations on a mutable Attribute property (such as looping over a list
-or dict) you should make sure to “disconnect” the Attribute’s value first and operate on this
-rather than on the Attribute. You can gain dramatic speed improvements to big loops this
-way.
-
-
-Locking and checking Attributes¶
-Attributes are normally not locked down by default, but you can easily change that for individual
-Attributes (like those that may be game-sensitive in games with user-level building).
-First you need to set a lock string on your Attribute. Lock strings are specified Locks.
-The relevant lock types are
+
+Properties of Attributes¶
+An Attribute object is stored in the database. It has the following properties:
-attrread - limits who may read the value of the Attribute
-attredit - limits who may set/change this Attribute
+key - the name of the Attribute. When doing e.g. obj.db.attrname = value, this property is set
+to attrname.
+value - this is the value of the Attribute. This value can be anything which can be pickled -
+objects, lists, numbers or what have you (see
+this section for more info). In the
+example
+obj.db.attrname = value, the value is stored here.
+category - this is an optional property that is set to None for most Attributes. Setting this
+allows to use Attributes for different functionality. This is usually not needed unless you want
+to use Attributes for very different functionality (Nicks is an example of using
+Attributes in this way). To modify this property you need to use the Attribute Handler
+strvalue - this is a separate value field that only accepts strings. This severely limits the
+data possible to store, but allows for easier database lookups. This property is usually not used
+except when re-using Attributes for some other purpose (Nicks use it). It is only
+accessible via the Attribute Handler.
-You cannot use the db handler to modify Attribute object (such as setting a lock on them) - The
-db handler will return the Attribute’s value, not the Attribute object itself. Instead you use
-the AttributeHandler and set it to return the object instead of the value:
- lockstring = "attread:all();attredit:perm(Admins)"
- obj.attributes.get("myattr", return_obj=True).locks.add(lockstring)
+There are also two special properties:
+
+attrtype - this is used internally by Evennia to separate Nicks, from Attributes (Nicks
+use Attributes behind the scenes).
+model - this is a natural-key describing the model this Attribute is attached to. This is on
+the form appname.modelclass, like objects.objectdb. It is used by the Attribute and
+NickHandler to quickly sort matches in the database. Neither this nor attrtype should normally
+need to be modified.
+
+Non-database attributes are not stored in the database and have no equivalence
+to category nor strvalue, attrtype or model.
+
+
+
+In-memory Attributes (NAttributes)¶
+NAttributes (short of Non-database Attributes) mimic Attributes in most things except they
+are non-persistent - they will not survive a server reload.
+
+Instead of .db use .ndb.
+Instead of .attributes use .nattributes
+Instead of AttributeProperty, use NAttributeProperty.
+
+ rose.ndb.has_thorns = True
+ is_ouch = rose.ndb.has_thorns
+
+ rose.nattributes.add("has_thorns", True)
+ is_ouch = rose.nattributes.get("has_thorns")
-Note the return_obj keyword which makes sure to return the Attribute object so its LockHandler
-could be accessed.
-A lock is no good if nothing checks it – and by default Evennia does not check locks on Attributes.
-You have to add a check to your commands/code wherever it fits (such as before setting an
-Attribute).
- # in some command code where we want to limit
- # setting of a given attribute name on an object
- attr = obj.attributes.get(attrname,
- return_obj=True,
- accessing_obj=caller,
- default=None,
- default_access=False)
- if not attr:
- caller.msg("You cannot edit that Attribute!")
- return
- # edit the Attribute here
-
-
-The same keywords are available to use with obj.attributes.set() and obj.attributes.remove(),
-those will check for the attredit lock type.
+Differences between Attributes and NAttributes:
+
+NAttributes are always wiped on a server reload.
+They only exist in memory and never involve the database at all, making them faster to
+access and edit than Attributes.
+NAttributes can store any Python structure (and database object) without limit.
+They can not be set with the standard set command (but they are visible with examine)
+
+There are some important reasons we recommend using ndb to store temporary data rather than
+the simple alternative of just storing a variable directly on an object:
+
+NAttributes are tracked by Evennia and will not be purged in various cache-cleanup operations
+the server may do. So using them guarantees that they’ll remain available at least as long as
+the server lives.
+It’s a consistent style - .db/.attributes and .ndb/.nattributes makes for clean-looking code
+where it’s clear how long-lived (or not) your data is to be.
+
+
+Persistent vs non-persistent¶
+So persistent data means that your data will survive a server reboot, whereas with
+non-persistent data it will not …
+… So why would you ever want to use non-persistent data? The answer is, you don’t have to. Most of
+the time you really want to save as much as you possibly can. Non-persistent data is potentially
+useful in a few situations though.
+
+You are worried about database performance. Since Evennia caches Attributes very aggressively,
+this is not an issue unless you are reading and writing to your Attribute very often (like many
+times per second). Reading from an already cached Attribute is as fast as reading any Python
+property. But even then this is not likely something to worry about: Apart from Evennia’s own
+caching, modern database systems themselves also cache data very efficiently for speed. Our
+default
+database even runs completely in RAM if possible, alleviating much of the need to write to disk
+during heavy loads.
+A more valid reason for using non-persistent data is if you want to lose your state when logging
+off. Maybe you are storing throw-away data that are re-initialized at server startup. Maybe you
+are implementing some caching of your own. Or maybe you are testing a buggy Script that
+does potentially harmful stuff to your character object. With non-persistent storage you can be
+sure that whatever is messed up, it’s nothing a server reboot can’t clear up.
+NAttributes have no restrictions at all on what they can store, since they
+don’t need to worry about being saved to the database - they work very well for temporary storage.
+You want to implement a fully or partly non-persistent world. Who are we to argue with your
+grand vision!
+
@@ -426,17 +664,25 @@ those will check for the Table of Contents
- Attributes
-- The .db and .ndb shortcuts
-- The AttributeHandler
-- Properties of Attributes
-- Persistent vs non-persistent
+- Managing Attributes in Code
+
+- Managing Attributes in-game
+- Locking and checking Attributes
- What types of data can I save in an Attribute?
-- Locking and checking Attributes
+- Properties of Attributes
+
+
+- In-memory Attributes (NAttributes)
diff --git a/docs/1.0-dev/Components/Default-Commands.html b/docs/1.0-dev/Components/Default-Commands.html
index 35bbfddcc2..b6c2235a69 100644
--- a/docs/1.0-dev/Components/Default-Commands.html
+++ b/docs/1.0-dev/Components/Default-Commands.html
@@ -62,39 +62,39 @@ with Batch-Processor’s interactive mode.
-__unloggedin_look_command [look, l] (cmdset: UnloggedinCmdSet, help-category: General)
+__unloggedin_look_command [l, look] (cmdset: UnloggedinCmdSet, help-category: General)
about [version] (cmdset: CharacterCmdSet, help-category: System)
-access [hierarchy, groups] (cmdset: CharacterCmdSet, help-category: General)
-accounts [listaccounts, account] (cmdset: CharacterCmdSet, help-category: System)
+access [groups, hierarchy] (cmdset: CharacterCmdSet, help-category: General)
+accounts [account, listaccounts] (cmdset: CharacterCmdSet, help-category: System)
addcom [chanalias, aliaschan] (cmdset: AccountCmdSet, help-category: Comms)
alias [setobjalias] (cmdset: CharacterCmdSet, help-category: Building)
allcom (cmdset: AccountCmdSet, help-category: Comms)
batchcode [batchcodes] (cmdset: CharacterCmdSet, help-category: Building)
-batchcommands [batchcommand, batchcmd] (cmdset: CharacterCmdSet, help-category: Building)
+batchcommands [batchcmd, batchcommand] (cmdset: CharacterCmdSet, help-category: Building)
cboot (cmdset: AccountCmdSet, help-category: Comms)
ccreate [channelcreate] (cmdset: AccountCmdSet, help-category: Comms)
cdesc (cmdset: AccountCmdSet, help-category: Comms)
cdestroy (cmdset: AccountCmdSet, help-category: Comms)
-channel [channels, chan] (cmdset: AccountCmdSet, help-category: Comms)
+channel [chan, channels] (cmdset: AccountCmdSet, help-category: Comms)
charcreate (cmdset: AccountCmdSet, help-category: General)
chardelete (cmdset: AccountCmdSet, help-category: General)
clock (cmdset: AccountCmdSet, help-category: Comms)
cmdsets [listcmsets] (cmdset: CharacterCmdSet, help-category: Building)
color (cmdset: AccountCmdSet, help-category: General)
-connect [con, conn, co] (cmdset: UnloggedinCmdSet, help-category: General)
+connect [con, co, conn] (cmdset: UnloggedinCmdSet, help-category: General)
copy (cmdset: CharacterCmdSet, help-category: Building)
cpattr (cmdset: CharacterCmdSet, help-category: Building)
create (cmdset: CharacterCmdSet, help-category: Building)
-create [cr, cre] (cmdset: UnloggedinCmdSet, help-category: General)
+create [cre, cr] (cmdset: UnloggedinCmdSet, help-category: General)
cwho (cmdset: AccountCmdSet, help-category: Comms)
delcom [delaliaschan, delchanalias] (cmdset: AccountCmdSet, help-category: Comms)
desc [describe] (cmdset: CharacterCmdSet, help-category: Building)
-destroy [delete, del] (cmdset: CharacterCmdSet, help-category: Building)
+destroy [del, delete] (cmdset: CharacterCmdSet, help-category: Building)
dig (cmdset: CharacterCmdSet, help-category: Building)
drop (cmdset: CharacterCmdSet, help-category: General)
encoding [encode] (cmdset: UnloggedinCmdSet, help-category: General)
-examine [ex, exam] (cmdset: AccountCmdSet, help-category: Building)
-find [search, locate] (cmdset: CharacterCmdSet, help-category: Building)
+examine [exam, ex] (cmdset: AccountCmdSet, help-category: Building)
+find [locate, search] (cmdset: CharacterCmdSet, help-category: Building)
get [grab] (cmdset: CharacterCmdSet, help-category: General)
give (cmdset: CharacterCmdSet, help-category: General)
grapevine2chan (cmdset: AccountCmdSet, help-category: Comms)
@@ -103,7 +103,7 @@ with home (cmdset: CharacterCmdSet, help-category: General)
ic [puppet] (cmdset: AccountCmdSet, help-category: General)
info (cmdset: UnloggedinCmdSet, help-category: General)
-inventory [i, inv] (cmdset: CharacterCmdSet, help-category: General)
+inventory [inv, i] (cmdset: CharacterCmdSet, help-category: General)
irc2chan (cmdset: AccountCmdSet, help-category: Comms)
ircstatus (cmdset: AccountCmdSet, help-category: Comms)
link (cmdset: CharacterCmdSet, help-category: Building)
@@ -113,13 +113,13 @@ with mvattr (cmdset: CharacterCmdSet, help-category: Building)
name [rename] (cmdset: CharacterCmdSet, help-category: Building)
nick [nicks, nickname] (cmdset: AccountCmdSet, help-category: General)
-objects [listobjects, stats, db, listobjs] (cmdset: CharacterCmdSet, help-category: System)
+objects [listobjects, db, listobjs, stats] (cmdset: CharacterCmdSet, help-category: System)
ooc [unpuppet] (cmdset: AccountCmdSet, help-category: General)
open (cmdset: CharacterCmdSet, help-category: Building)
option [options] (cmdset: AccountCmdSet, help-category: General)
page [tell] (cmdset: AccountCmdSet, help-category: Comms)
password (cmdset: AccountCmdSet, help-category: General)
-pose [emote, :] (cmdset: CharacterCmdSet, help-category: General)
+pose [:, emote] (cmdset: CharacterCmdSet, help-category: General)
py [!] (cmdset: AccountCmdSet, help-category: System)
quell [unquell] (cmdset: AccountCmdSet, help-category: General)
quit (cmdset: AccountCmdSet, help-category: General)
@@ -127,7 +127,7 @@ with reload [restart] (cmdset: AccountCmdSet, help-category: System)
reset [reboot] (cmdset: AccountCmdSet, help-category: System)
rss2chan (cmdset: AccountCmdSet, help-category: Comms)
-say [”, ‘] (cmdset: CharacterCmdSet, help-category: General)
+say [’, “] (cmdset: CharacterCmdSet, help-category: General)
screenreader (cmdset: UnloggedinCmdSet, help-category: General)
scripts [script] (cmdset: CharacterCmdSet, help-category: System)
server [serverload, serverprocess] (cmdset: CharacterCmdSet, help-category: System)
@@ -141,12 +141,12 @@ with spawn [olc] (cmdset: CharacterCmdSet, help-category: Building)
style (cmdset: AccountCmdSet, help-category: General)
tag [tags] (cmdset: CharacterCmdSet, help-category: Building)
-tasks [task, delays] (cmdset: CharacterCmdSet, help-category: System)
+tasks [delays, task] (cmdset: CharacterCmdSet, help-category: System)
tel [teleport] (cmdset: CharacterCmdSet, help-category: Building)
tickers (cmdset: CharacterCmdSet, help-category: System)
time [uptime] (cmdset: CharacterCmdSet, help-category: System)
tunnel [tun] (cmdset: CharacterCmdSet, help-category: Building)
-typeclass [swap, typeclasses, update, type, parent] (cmdset: CharacterCmdSet, help-category: Building)
+typeclass [swap, update, type, typeclasses, parent] (cmdset: CharacterCmdSet, help-category: Building)
unlink (cmdset: CharacterCmdSet, help-category: Building)
whisper (cmdset: CharacterCmdSet, help-category: General)
who [doing] (cmdset: AccountCmdSet, help-category: General)
diff --git a/docs/1.0-dev/Components/Objects.html b/docs/1.0-dev/Components/Objects.html
index 7ceaeb452a..04ee15431e 100644
--- a/docs/1.0-dev/Components/Objects.html
+++ b/docs/1.0-dev/Components/Objects.html
@@ -203,16 +203,16 @@ object).
In at_traverse, object.move_to(destination) is triggered. This triggers the following hooks,
in order:
-obj.at_before_move(destination) - if this returns False, move is aborted.
-origin.at_before_leave(obj, destination)
+obj.at_pre_move(destination) - if this returns False, move is aborted.
+origin.at_pre_leave(obj, destination)
obj.announce_move_from(destination)
Move is performed by changing obj.location from source location to destination.
obj.announce_move_to(source)
destination.at_object_receive(obj, source)
-obj.at_after_move(source)
+obj.at_post_move(source)
-On the Exit object, at_after_traverse(obj, source) is triggered.
+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
diff --git a/docs/1.0-dev/Howto/Coding-FAQ.html b/docs/1.0-dev/Howto/Coding-FAQ.html
index ef31f03e4c..6a39387b69 100644
--- a/docs/1.0-dev/Howto/Coding-FAQ.html
+++ b/docs/1.0-dev/Howto/Coding-FAQ.html
@@ -77,10 +77,10 @@ for more info.
Preventing character from moving based on a condition¶
Q: How does one keep a character from using any exit, if they meet a certain condition? (I.E. in
combat, immobilized, etc.)
-A: The at_before_move hook is called by Evennia just before performing any move. If it returns
+
A: The at_pre_move hook is called by Evennia just before performing any move. If it returns
False, the move is aborted. Let’s say we want to check for an Attribute cantmove.
Add the following code to the Character class:
-def at_before_move(self, destination):
+def at_pre_move(self, destination):
"Called just before trying to move"
if self.db.cantmove: # replace with condition you want to test
self.msg("Something is preventing you from moving!")
diff --git a/docs/1.0-dev/Howto/Gametime-Tutorial.html b/docs/1.0-dev/Howto/Gametime-Tutorial.html
index edf5430626..2c1d07a775 100644
--- a/docs/1.0-dev/Howto/Gametime-Tutorial.html
+++ b/docs/1.0-dev/Howto/Gametime-Tutorial.html
@@ -231,7 +231,11 @@ units. If you create “day”, it needs to be multiple of hours, for instance.
Notice we have set a time epoch of 0. Using a custom calendar, we will come up with a nice display
-of time on our own. In our case the game time starts at year 0, month 0, day 0, and at midnight.
+of time on our own. In our case the game time starts at year 0, month 1, day 1, and at midnight.
+
+Year, hour, minute and sec starts from 0, month, week and day starts from 1, this makes them
+behave consistently with the standard time.
+
Note that while we use “month”, “week” etc in the settings, your game may not use those terms in-
game, instead referring to them as “cycles”, “moons”, “sand falls” etc. This is just a matter of you
displaying them differently. See next section.
diff --git a/docs/1.0-dev/Howto/Starting/Part3/A-Sittable-Object.html b/docs/1.0-dev/Howto/Starting/Part3/A-Sittable-Object.html
index 46e75ea14e..12f17882ba 100644
--- a/docs/1.0-dev/Howto/Starting/Part3/A-Sittable-Object.html
+++ b/docs/1.0-dev/Howto/Starting/Part3/A-Sittable-Object.html
@@ -73,7 +73,7 @@ This requires a change to our Character typeclass. Open class Character(DefaultCharacter):
# ...
- def at_before_move(self, destination):
+ def at_pre_move(self, destination):
"""
Called by self.move_to when trying to move somewhere. If this returns
False, the move is immediately cancelled.
@@ -86,7 +86,7 @@ This requires a change to our Character typeclass. Open character.move_to is called. This in turn
-will call character.at_before_move. Here we look for an Attribute is_resting (which we will assign below)
+will call character.at_pre_move. Here we look for an Attribute is_resting (which we will assign below)
to determine if we are stuck on the chair or not.
diff --git a/docs/1.0-dev/Howto/Tutorial-Aggressive-NPCs.html b/docs/1.0-dev/Howto/Tutorial-Aggressive-NPCs.html
index 2013f3736e..6fba951ca0 100644
--- a/docs/1.0-dev/Howto/Tutorial-Aggressive-NPCs.html
+++ b/docs/1.0-dev/Howto/Tutorial-Aggressive-NPCs.html
@@ -113,12 +113,12 @@ hook in our customized room typeclass to suit our needs.
Characters, ignoring other NPCs or objects. When triggered the room will look through its
contents and inform any NPCs inside by calling their at_char_entered` method.
You’ll also see that we have added a ‘look’ into this code. This is because, by default, the
-at_object_receive is carried out before the character’s at_after_move which, we will now
+at_object_receive is carried out before the character’s at_post_move which, we will now
overload. This means that a character entering would see the NPC perform its actions before the
‘look’ command. Deactivate the look command in the default Character class within the
typeclasses.characters module:
# Add this hook in any blank area within your Character class.
- def at_after_move(self, source_location):
+ def at_post_move(self, source_location):
"""
Default is to look around after a move
Note: This has been moved to Room.at_object_receive
diff --git a/docs/1.0-dev/_modules/evennia/accounts/accounts.html b/docs/1.0-dev/_modules/evennia/accounts/accounts.html
index f9b8574d8a..df7d012edc 100644
--- a/docs/1.0-dev/_modules/evennia/accounts/accounts.html
+++ b/docs/1.0-dev/_modules/evennia/accounts/accounts.html
@@ -897,6 +897,12 @@
`*args` and `**kwargs` are passed on to the base delete
mechanism (these are usually not used).
+ Return:
+ bool: If deletion was successful. Only time it fails would be
+ if the Account was already deleted. Note that even on a failure,
+ connected resources (nicks/aliases etc) will still have been
+ deleted.
+
"""
for session in self.sessions.all():
# unpuppeting all objects and disconnecting the user, if any
@@ -912,7 +918,11 @@
self.attributes.clear()
self.nicks.clear()
self.aliases.clear()
- super().delete(*args, **kwargs)
+ if not self.pk:
+ return False
+ super().delete(*args, **kwargs)
+ return True
+
# methods inherited from database model
diff --git a/docs/1.0-dev/_modules/evennia/commands/default/admin.html b/docs/1.0-dev/_modules/evennia/commands/default/admin.html
index f548fe1868..1ea542f8c9 100644
--- a/docs/1.0-dev/_modules/evennia/commands/default/admin.html
+++ b/docs/1.0-dev/_modules/evennia/commands/default/admin.html
@@ -260,13 +260,18 @@
ipregex = ipregex.replace("*", "[0-9]{1,3}")
ipregex = re.compile(r"%s" % ipregex)
bantup = ("", ban, ipregex, now, reason)
+
+ ret = yield(f"Are you sure you want to {typ}-ban '|w{ban}|n' [Y]/N?")
+ if str(ret).lower() in ("no", "n"):
+ self.caller.msg("Aborted.")
+ return
+
# save updated banlist
banlist.append(bantup)
ServerConfig.objects.conf("server_bans", banlist)
- self.caller.msg("%s-Ban |w%s|n was added." % (typ, ban))
+ self.caller.msg(f"{typ}-ban '|w{ban}|n' was added. Use |wunban|n to reinstate.")
logger.log_sec(
- "Banned %s: %s (Caller: %s, IP: %s)."
- % (typ, ban.strip(), self.caller, self.session.address)
+ "Banned {typ}: {ban.strip()} (Caller: {self.caller}, IP: {self.session.address})."
)
@@ -308,15 +313,20 @@
elif not (0 < num < len(banlist) + 1):
self.caller.msg("Ban id |w%s|x was not found." % self.args)
else:
- # all is ok, clear ban
+ # all is ok, ask, then clear ban
ban = banlist[num - 1]
+ value = " ".join([s for s in ban[:2]])
+
+ ret = yield(f"Are you sure you want to unban {num}: '{value}' [Y]/N?")
+ if str(ret).lower() in ("n", "no"):
+ self.caller.msg("Aborted.")
+ return
+
del banlist[num - 1]
ServerConfig.objects.conf("server_bans", banlist)
- value = " ".join([s for s in ban[:2]])
- self.caller.msg("Cleared ban %s: %s" % (num, value))
+ self.caller.msg(f"Cleared ban {num}: '{value}'" % (num, value))
logger.log_sec(
- "Unbanned: %s (Caller: %s, IP: %s)."
- % (value.strip(), self.caller, self.session.address)
+ "Unbanned: {value.strip()} (Caller: {self.caller}, IP: {self.session.address})."
)
mechanism (these are usually not used).
bool –
+if the Account was already deleted. Note that even on a failure, +connected resources (nicks/aliases etc) will still have been +deleted.
+search_index_entry = {'aliases': 'batchcommand batchcmd', 'category': 'building', 'key': 'batchcommands', 'tags': '', 'text': '\n build from batch-command file\n\n Usage:\n batchcommands[/interactive] <python.path.to.file>\n\n Switch:\n interactive - this mode will offer more control when\n executing the batch file, like stepping,\n skipping, reloading etc.\n\n Runs batches of commands from a batch-cmd text file (*.ev).\n\n '}¶search_index_entry = {'aliases': 'batchcmd batchcommand', 'category': 'building', 'key': 'batchcommands', 'tags': '', 'text': '\n build from batch-command file\n\n Usage:\n batchcommands[/interactive] <python.path.to.file>\n\n Switch:\n interactive - this mode will offer more control when\n executing the batch file, like stepping,\n skipping, reloading etc.\n\n Runs batches of commands from a batch-cmd text file (*.ev).\n\n '}¶
search_index_entry = {'aliases': 'delete del', 'category': 'building', 'key': 'destroy', 'tags': '', 'text': '\n permanently delete objects\n\n Usage:\n destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]\n\n Switches:\n override - The destroy command will usually avoid accidentally\n destroying account objects. This switch overrides this safety.\n force - destroy without confirmation.\n Examples:\n destroy house, roof, door, 44-78\n destroy 5-10, flower, 45\n destroy/force north\n\n Destroys one or many objects. If dbrefs are used, a range to delete can be\n given, e.g. 4-10. Also the end points will be deleted. This command\n displays a confirmation before destroying, to make sure of your choice.\n You can specify the /force switch to bypass this confirmation.\n '}¶search_index_entry = {'aliases': 'del delete', 'category': 'building', 'key': 'destroy', 'tags': '', 'text': '\n permanently delete objects\n\n Usage:\n destroy[/switches] [obj, obj2, obj3, [dbref-dbref], ...]\n\n Switches:\n override - The destroy command will usually avoid accidentally\n destroying account objects. This switch overrides this safety.\n force - destroy without confirmation.\n Examples:\n destroy house, roof, door, 44-78\n destroy 5-10, flower, 45\n destroy/force north\n\n Destroys one or many objects. If dbrefs are used, a range to delete can be\n given, e.g. 4-10. Also the end points will be deleted. This command\n displays a confirmation before destroying, to make sure of your choice.\n You can specify the /force switch to bypass this confirmation.\n '}¶
aliases = ['swap', 'typeclasses', 'update', 'type', 'parent']¶aliases = ['swap', 'update', 'type', 'typeclasses', 'parent']¶
search_index_entry = {'aliases': 'swap typeclasses update type parent', 'category': 'building', 'key': 'typeclass', 'tags': '', 'text': "\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] <object> [= typeclass.path]\n typeclass/prototype <object> = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object.\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n "}¶search_index_entry = {'aliases': 'swap update type typeclasses parent', 'category': 'building', 'key': 'typeclass', 'tags': '', 'text': "\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] <object> [= typeclass.path]\n typeclass/prototype <object> = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object.\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n "}¶
search_index_entry = {'aliases': 'ex exam', 'category': 'building', 'key': 'examine', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [<object>[/attrname]]\n examine [*<account>[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}¶search_index_entry = {'aliases': 'exam ex', 'category': 'building', 'key': 'examine', 'tags': '', 'text': '\n get detailed information about an object\n\n Usage:\n examine [<object>[/attrname]]\n examine [*<account>[/attrname]]\n\n Switch:\n account - examine an Account (same as adding *)\n object - examine an Object (useful when OOC)\n\n The examine command shows detailed game info about an\n object and optionally a specific attribute on it.\n If object is not specified, the current location is examined.\n\n Append a * before the search string to examine an account.\n\n '}¶
search_index_entry = {'aliases': 'search locate', 'category': 'building', 'key': 'find', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}¶search_index_entry = {'aliases': 'locate search', 'category': 'building', 'key': 'find', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}¶
Teleports an object somewhere. If no object is given, you yourself are teleported to the target location.
+To lock an object from being teleported, set its teleport lock, it will be +checked with the caller. To block +a destination from being teleported to, set the destination’s teleport_here +lock - it will be checked with the thing being teleported. Admins and +higher permissions can always teleport.
key = 'tel'¶search_index_entry = {'aliases': 'teleport', 'category': 'building', 'key': 'tel', 'tags': '', 'text': "\n teleport object to another location\n\n Usage:\n tel/switch [<object> to||=] <target location>\n\n Examples:\n tel Limbo\n tel/quiet box = Limbo\n tel/tonone box\n\n Switches:\n quiet - don't echo leave/arrive messages to the source/target\n locations for the move.\n intoexit - if target is an exit, teleport INTO\n the exit object instead of to its destination\n tonone - if set, teleport the object to a None-location. If this\n switch is set, <target location> is ignored.\n Note that the only way to retrieve\n an object from a None location is by direct #dbref\n reference. A puppeted object cannot be moved to None.\n loc - teleport object to the target's location instead of its contents\n\n Teleports an object somewhere. If no object is given, you yourself are\n teleported to the target location.\n "}¶search_index_entry = {'aliases': 'teleport', 'category': 'building', 'key': 'tel', 'tags': '', 'text': "\n teleport object to another location\n\n Usage:\n tel/switch [<object> to||=] <target location>\n\n Examples:\n tel Limbo\n tel/quiet box = Limbo\n tel/tonone box\n\n Switches:\n quiet - don't echo leave/arrive messages to the source/target\n locations for the move.\n intoexit - if target is an exit, teleport INTO\n the exit object instead of to its destination\n tonone - if set, teleport the object to a None-location. If this\n switch is set, <target location> is ignored.\n Note that the only way to retrieve\n an object from a None location is by direct #dbref\n reference. A puppeted object cannot be moved to None.\n loc - teleport object to the target's location instead of its contents\n\n Teleports an object somewhere. If no object is given, you yourself are\n teleported to the target location.\n\n To lock an object from being teleported, set its `teleport` lock, it will be\n checked with the caller. To block\n a destination from being teleported to, set the destination's `teleport_here`\n lock - it will be checked with the thing being teleported. Admins and\n higher permissions can always teleport.\n\n "}¶
aliases = ['listobjects', 'stats', 'db', 'listobjs']¶aliases = ['listobjects', 'db', 'listobjs', 'stats']¶
search_index_entry = {'aliases': 'listobjects stats db listobjs', 'category': 'system', 'key': 'objects', 'tags': '', 'text': '\n statistics on objects in the database\n\n Usage:\n objects [<nr>]\n\n Gives statictics on objects in database as well as\n a list of <nr> latest objects in database. If not\n given, <nr> defaults to 10.\n '}¶search_index_entry = {'aliases': 'listobjects db listobjs stats', 'category': 'system', 'key': 'objects', 'tags': '', 'text': '\n statistics on objects in the database\n\n Usage:\n objects [<nr>]\n\n Gives statictics on objects in database as well as\n a list of <nr> latest objects in database. If not\n given, <nr> defaults to 10.\n '}¶
search_index_entry = {'aliases': 'channels chan', 'category': 'comms', 'key': 'channel', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶search_index_entry = {'aliases': 'chan channels', 'category': 'comms', 'key': 'channel', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
search_index_entry = {'aliases': 'channels chan', 'category': 'comms', 'key': 'channel', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶search_index_entry = {'aliases': 'chan channels', 'category': 'comms', 'key': 'channel', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
search_index_entry = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}¶search_index_entry = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}¶
locks = 'cmd:all()'¶
arg_regex = None¶func()[source]¶search_index_entry = {'aliases': '" \'', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say <message>\n\n Talk to those in your current location.\n '}¶search_index_entry = {'aliases': '\' "', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say <message>\n\n Talk to those in your current location.\n '}¶
locks = 'cmd:all()'¶
arg_regex = None¶parse()[source]¶search_index_entry = {'aliases': 'emote :', 'category': 'general', 'key': 'pose', 'tags': '', 'text': "\n strike a pose\n\n Usage:\n pose <pose text>\n pose's <pose text>\n\n Example:\n pose is standing by the wall, smiling.\n -> others will see:\n Tom is standing by the wall, smiling.\n\n Describe an action being taken. The pose text will\n automatically begin with your name.\n "}¶search_index_entry = {'aliases': ': emote', 'category': 'general', 'key': 'pose', 'tags': '', 'text': "\n strike a pose\n\n Usage:\n pose <pose text>\n pose's <pose text>\n\n Example:\n pose is standing by the wall, smiling.\n -> others will see:\n Tom is standing by the wall, smiling.\n\n Describe an action being taken. The pose text will\n automatically begin with your name.\n "}¶
search_index_entry = {'aliases': 'hierarchy groups', 'category': 'general', 'key': 'access', 'tags': '', 'text': '\n show your current game access\n\n Usage:\n access\n\n This command shows you the permission hierarchy and\n which permission groups you are a member of.\n '}¶search_index_entry = {'aliases': 'groups hierarchy', 'category': 'general', 'key': 'access', 'tags': '', 'text': '\n show your current game access\n\n Usage:\n access\n\n This command shows you the permission hierarchy and\n which permission groups you are a member of.\n '}¶
search_index_entry = {'aliases': 'listaccounts account', 'category': 'system', 'key': 'accounts', 'tags': '', 'text': '\n Manage registered accounts\n\n Usage:\n accounts [nr]\n accounts/delete <name or #id> [: reason]\n\n Switches:\n delete - delete an account from the server\n\n By default, lists statistics about the Accounts registered with the game.\n It will list the <nr> amount of latest registered accounts\n If not given, <nr> defaults to 10.\n '}¶search_index_entry = {'aliases': 'account listaccounts', 'category': 'system', 'key': 'accounts', 'tags': '', 'text': '\n Manage registered accounts\n\n Usage:\n accounts [nr]\n accounts/delete <name or #id> [: reason]\n\n Switches:\n delete - delete an account from the server\n\n By default, lists statistics about the Accounts registered with the game.\n It will list the <nr> amount of latest registered accounts\n If not given, <nr> defaults to 10.\n '}¶
help_category = 'system'¶
arg_regex = re.compile('', re.IGNORECASE)¶func()[source]¶search_index_entry = {'aliases': 'task delays', 'category': 'system', 'key': 'tasks', 'tags': '', 'text': "\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n "}¶search_index_entry = {'aliases': 'delays task', 'category': 'system', 'key': 'tasks', 'tags': '', 'text': "\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n "}¶
search_index_entry = {'aliases': 'con conn co', 'category': 'general', 'key': 'connect', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect "account name" "pass word"\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶search_index_entry = {'aliases': 'con co conn', 'category': 'general', 'key': 'connect', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect "account name" "pass word"\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
search_index_entry = {'aliases': 'cr cre', 'category': 'general', 'key': 'create', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create <accountname> <password>\n create "account name" "pass word"\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶search_index_entry = {'aliases': 'cre cr', 'category': 'general', 'key': 'create', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create <accountname> <password>\n create "account name" "pass word"\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
search_index_entry = {'aliases': 'look l', 'category': 'general', 'key': '__unloggedin_look_command', 'tags': '', 'text': '\n look when in unlogged-in state\n\n Usage:\n look\n\n This is an unconnected version of the look command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}¶search_index_entry = {'aliases': 'l look', 'category': 'general', 'key': '__unloggedin_look_command', 'tags': '', 'text': '\n look when in unlogged-in state\n\n Usage:\n look\n\n This is an unconnected version of the look command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}¶
delete()[source]¶Deletes channel.
+bool –
+if channel was already deleted. Even if it were to fail, all subscribers +will be disconnected.
+search_index_entry = {'aliases': 'deal offers', 'category': 'trading', 'key': 'status', 'tags': '', 'text': "\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n "}¶search_index_entry = {'aliases': 'offers deal', 'category': 'trading', 'key': 'status', 'tags': '', 'text': "\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n "}¶
search_index_entry = {'aliases': 'i inv', 'category': 'general', 'key': 'inventory', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}¶search_index_entry = {'aliases': 'inv i', 'category': 'general', 'key': 'inventory', 'tags': '', 'text': '\n view inventory\n\n Usage:\n inventory\n inv\n\n Shows your inventory.\n '}¶
evennia.contrib.custom_gametime.realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0, months=0, yrs=0, format=False)[source]¶evennia.contrib.custom_gametime.realtime_to_gametime(secs=0, mins=0, hrs=0, days=1, weeks=1, months=1, yrs=0, format=False)[source]¶
This method calculates how much in-game time a real-world time interval would correspond to. This is usually a lot less interesting than the other way around.
@@ -143,19 +143,27 @@ interesting than the other way around.time (float or tuple) –
---
-- The gametime difference or the same
- -
time split up into time units.
-
realtime_to_gametime(days=2) -> number of game-world seconds
+time split up into time units.
Note
+consistent with the real world datetime.
+ValueError – If trying to add a days/weeks/months of <=0.
+Example
+realtime_to_gametime(days=2) -> number of game-world seconds
The number of real seconds before the given game time is up.
Notes
+day/week/month start from 1, not from 0 (there is no month 0 for example)
search_index_entry = {'aliases': 'con conn co', 'category': 'general', 'key': 'connect', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect <email> <password>\n\n Use the create command to first create an account before logging in.\n '}¶search_index_entry = {'aliases': 'con co conn', 'category': 'general', 'key': 'connect', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect <email> <password>\n\n Use the create command to first create an account before logging in.\n '}¶
search_index_entry = {'aliases': 'cr cre', 'category': 'general', 'key': 'create', 'tags': '', 'text': '\n Create a new account.\n\n Usage (at login screen):\n create "accountname" <email> <password>\n\n This creates a new account account.\n\n '}¶search_index_entry = {'aliases': 'cre cr', 'category': 'general', 'key': 'create', 'tags': '', 'text': '\n Create a new account.\n\n Usage (at login screen):\n create "accountname" <email> <password>\n\n This creates a new account account.\n\n '}¶
search_index_entry = {'aliases': 'look l', 'category': 'general', 'key': '__unloggedin_look_command', 'tags': '', 'text': '\n This is an unconnected version of the `look` command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}¶search_index_entry = {'aliases': 'l look', 'category': 'general', 'key': '__unloggedin_look_command', 'tags': '', 'text': '\n This is an unconnected version of the `look` command for simplicity.\n\n This is called by the server and kicks everything in gear.\n All it does is display the connect screen.\n '}¶
search_index_entry = {'aliases': 'chicken out q abort quit', 'category': 'evscaperoom', 'key': 'give up', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}¶search_index_entry = {'aliases': 'chicken out abort q quit', 'category': 'evscaperoom', 'key': 'give up', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}¶
search_index_entry = {'aliases': 'shout whisper ;', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n Perform an communication action.\n\n Usage:\n say <text>\n whisper\n shout\n\n '}¶search_index_entry = {'aliases': '; whisper shout', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n Perform an communication action.\n\n Usage:\n say <text>\n whisper\n shout\n\n '}¶
search_index_entry = {'aliases': 'pose :', 'category': 'general', 'key': 'emote', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use "..." to enact speech.\n\n Usage:\n emote <emote>\n :<emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}¶search_index_entry = {'aliases': ': pose', 'category': 'general', 'key': 'emote', 'tags': '', 'text': '\n Perform a free-form emote. Use /me to\n include yourself in the emote and /name\n to include other objects or characters.\n Use "..." to enact speech.\n\n Usage:\n emote <emote>\n :<emote\n\n Example:\n emote /me smiles at /peter\n emote /me points to /box and /lever.\n\n '}¶
search_index_entry = {'aliases': 'e ex unfocus examine', 'category': 'evscaperoom', 'key': 'focus', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus <obj>\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}¶search_index_entry = {'aliases': 'examine e unfocus ex', 'category': 'evscaperoom', 'key': 'focus', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus <obj>\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}¶
search_index_entry = {'aliases': 'i give inventory inv', 'category': 'evscaperoom', 'key': 'get', 'tags': '', 'text': '\n Use focus / examine instead.\n\n '}¶search_index_entry = {'aliases': 'inv give i inventory', 'category': 'evscaperoom', 'key': 'get', 'tags': '', 'text': '\n Use focus / examine instead.\n\n '}¶
search_index_entry = {'aliases': '@calls @callback @callbacks', 'category': 'building', 'key': '@call', 'tags': '', 'text': '\n Command to edit callbacks.\n '}¶search_index_entry = {'aliases': '@callbacks @calls @callback', 'category': 'building', 'key': '@call', 'tags': '', 'text': '\n Command to edit callbacks.\n '}¶
locks = 'cmd:all()'¶
arg_regex = re.compile('', re.IGNORECASE)¶func()[source]¶locks = 'cmd:all()'¶
arg_regex = re.compile('', re.IGNORECASE)¶func()[source]¶search_index_entry = {'aliases': '" \'', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say <message>\n\n Talk to those in your current location.\n '}¶search_index_entry = {'aliases': '\' "', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say <message>\n\n Talk to those in your current location.\n '}¶
search_index_entry = {'aliases': 'forget recognize', 'category': 'general', 'key': 'recog', 'tags': '', 'text': '\n Recognize another person in the same room.\n\n Usage:\n recog\n recog sdesc as alias\n forget alias\n\n Example:\n recog tall man as Griatch\n forget griatch\n\n This will assign a personal alias for a person, or forget said alias.\n Using the command without arguments will list all current recogs.\n\n '}¶search_index_entry = {'aliases': 'recognize forget', 'category': 'general', 'key': 'recog', 'tags': '', 'text': '\n Recognize another person in the same room.\n\n Usage:\n recog\n recog sdesc as alias\n forget alias\n\n Example:\n recog tall man as Griatch\n forget griatch\n\n This will assign a personal alias for a person, or forget said alias.\n Using the command without arguments will list all current recogs.\n\n '}¶
at_before_say(message, **kwargs)[source]¶at_pre_say(message, **kwargs)[source]¶Called before the object says or whispers anything, return modified message.
at_before_move(destination)[source]¶at_pre_move(destination)[source]¶Called just before starting to move this object to destination.
at_before_give(giver, getter)[source]¶at_pre_give(giver, getter)[source]¶Can’t give away in combat.
at_before_move(destination)[source]¶at_pre_move(destination)[source]¶Called just before starting to move this object to destination.
at_before_move(destination)[source]¶at_pre_move(destination)[source]¶Called just before starting to move this object to destination.
at_before_move(destination)[source]¶at_pre_move(destination)[source]¶Called just before starting to move this object to destination.
at_before_move(destination)[source]¶at_pre_move(destination)[source]¶Called just before starting to move this object to destination.
at_before_drop(dropper)[source]¶at_pre_drop(dropper)[source]¶Called by the default drop command before this object has been dropped.
Notes
This hook cannot stop the drop from happening. Use -permissions or the at_before_drop() hook for that.
+permissions or the at_pre_drop() hook for that.at_before_get(getter)[source]¶at_pre_get(getter)[source]¶Called by the default get command before this object has been picked up.
Notes
This hook cannot stop the pickup from happening. Use -permissions or the at_before_get() hook for that.
+permissions or the at_pre_get() hook for that.at_before_give(giver, getter)[source]¶at_pre_give(giver, getter)[source]¶Called by the default give command before this object has been given.
Notes
This hook cannot stop the give from happening. Use -permissions or the at_before_give() hook for that.
+permissions or the at_pre_give() hook for that.aliases = ['press', 'push', 'press button']¶
search_index_entry = {'aliases': 'press push press button', 'category': 'general', 'key': 'push button', 'tags': '', 'text': '\n Push the red button (lid closed)\n\n Usage:\n push button\n\n '}¶
aliases = ['smash lid', 'smash', 'break lid']¶
search_index_entry = {'aliases': 'smash lid smash break lid', 'category': 'general', 'key': 'smash glass', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}¶
aliases = ['press', 'push', 'press button']¶
search_index_entry = {'aliases': 'press push press button', 'category': 'general', 'key': 'push button', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}¶
aliases = ['get', 'listen', 'l', 'ex', 'examine', 'feel']¶
search_index_entry = {'aliases': 'get listen l ex examine feel', 'category': 'general', 'key': 'look', 'tags': '', 'text': "\n Looking around in darkness\n\n Usage:\n look <obj>\n\n ... not that there's much to see in the dark.\n\n "}¶
search_index_entry = {'aliases': 'pull move push shiftroot', 'category': 'tutorialworld', 'key': 'shift', 'tags': '', 'text': '\n Shifts roots around.\n\n Usage:\n shift blue root left/right\n shift red root left/right\n shift yellow root up/down\n shift green root up/down\n\n '}¶search_index_entry = {'aliases': 'shiftroot pull push move', 'category': 'tutorialworld', 'key': 'shift', 'tags': '', 'text': '\n Shifts roots around.\n\n Usage:\n shift blue root left/right\n shift red root left/right\n shift yellow root up/down\n shift green root up/down\n\n '}¶
aliases = ['push button', 'press button', 'button']¶aliases = ['button', 'push button', 'press button']¶
search_index_entry = {'aliases': 'push button press button button', 'category': 'tutorialworld', 'key': 'press', 'tags': '', 'text': '\n Presses a button.\n '}¶search_index_entry = {'aliases': 'button push button press button', 'category': 'tutorialworld', 'key': 'press', 'tags': '', 'text': '\n Presses a button.\n '}¶
at_after_traverse(traverser, source_location)[source]¶at_post_traverse(traverser, source_location)[source]¶This is called after we traversed this exit. Cleans up and resets the puzzle.
aliases = ['slash', 'stab', 'bash', 'thrust', 'kill', 'pierce', 'chop', 'fight', 'defend', 'hit', 'parry']¶aliases = ['fight', 'stab', 'hit', 'thrust', 'parry', 'slash', 'defend', 'chop', 'bash', 'kill', 'pierce']¶
search_index_entry = {'aliases': 'slash stab bash thrust kill pierce chop fight defend hit parry', 'category': 'tutorialworld', 'key': 'attack', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab <enemy>\n slash <enemy>\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}¶search_index_entry = {'aliases': 'fight stab hit thrust parry slash defend chop bash kill pierce', 'category': 'tutorialworld', 'key': 'attack', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab <enemy>\n slash <enemy>\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}¶
aliases = ['feel around', 'l', 'search', 'fiddle', 'feel']¶aliases = ['fiddle', 'l', 'feel around', 'feel', 'search']¶
search_index_entry = {'aliases': 'feel around l search fiddle feel', 'category': 'tutorialworld', 'key': 'look', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}¶search_index_entry = {'aliases': 'fiddle l feel around feel search', 'category': 'tutorialworld', 'key': 'look', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}¶
at_after_object_leave(obj)[source]¶at_post_object_leave(obj)[source]¶Called after an object left this wilderness map. Used for cleaning up.
move_hooks (bool) – If False, turn off the calling of move-related hooks -(at_before/after_move etc) with quiet=True, this is as quiet a move +(at_pre/post_move etc) with quiet=True, this is as quiet a move as can be done.
The DefaultObject hooks called (if move_hooks=True) are, in order:
-
- +
self.at_before_move(destination) (if this returns False, move is aborted)
self.at_pre_move(destination) (if this returns False, move is aborted)
source_location.at_object_leave(self, destination)
self.announce_move_from(destination)
(move happens here)
self.announce_move_to(source_location)
- -
destination.at_object_receive(self, source_location)
- +
self.at_after_move(source_location)
self.at_post_move(source_location)
at_pre_move(destination, **kwargs)[source]¶Called just before starting to move this object to +destination.
+destination (Object) – The object we are moving to
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
shouldmove (bool) – If we should move or not.
+Notes
+If this method returns False/None, the move is cancelled +before it is even started.
+at_post_move(source_location, **kwargs)[source]¶Called after move has completed, regardless of quiet mode or +not. Allows changes to the object due to the location it is +now in.
+source_location (Object) – Wwhere we came from. This may be None.
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
at_after_move(source_location, **kwargs)[source]¶at_after_move(source_location, **kwargs)¶
Called after move has completed, regardless of quiet mode or not. Allows changes to the object due to the location it is now in.
@@ -1097,7 +1136,7 @@ overriding the call (unused by default). normally by calling traversing_object.move_to(target_location). It is normally only implemented by Exit objects. If it returns False (usually -because move_to returned False), at_after_traverse below +because move_to returned False), at_post_traverse below should not be called and instead at_failed_traverse should be called.at_post_traverse(traversing_object, source_location, **kwargs)[source]¶Called just after an object successfully used this object to +traverse to another object (i.e. this object is a type of +Exit)
+traversing_object (Object) – The object traversing us.
source_location (Object) – Where traversing_object came from.
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
Notes
+The target location should normally be available as self.destination.
+at_after_traverse(traversing_object, source_location, **kwargs)[source]¶at_after_traverse(traversing_object, source_location, **kwargs)¶
Called just after an object successfully used this object to traverse to another object (i.e. this object is a type of Exit)
@@ -1339,9 +1398,31 @@ overriding the call (unused by default).at_pre_get(getter, **kwargs)[source]¶Called by the default get command before this object has been +picked up.
+getter (Object) – The object about to get this object.
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
shouldget (bool) – If the object should be gotten or not.
+Notes
+If this method returns False/None, the getting is cancelled +before it is even started.
+at_before_get(getter, **kwargs)[source]¶at_before_get(getter, **kwargs)¶
Called by the default get command before this object has been picked up.
Notes
This hook cannot stop the pickup from happening. Use -permissions or the at_before_get() hook for that.
+permissions or the at_pre_get() hook for that. +at_pre_give(giver, getter, **kwargs)[source]¶Called by the default give command before this object has been +given.
+giver (Object) – The object about to give this object.
getter (Object) – The object about to get this object.
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
shouldgive (bool) – If the object should be given or not.
+Notes
+If this method returns False/None, the giving is cancelled +before it is even started.
at_before_give(giver, getter, **kwargs)[source]¶at_before_give(giver, getter, **kwargs)¶
Called by the default give command before this object has been given.
Notes
This hook cannot stop the give from happening. Use -permissions or the at_before_give() hook for that.
+permissions or the at_pre_give() hook for that. +at_pre_drop(dropper, **kwargs)[source]¶Called by the default drop command before this object has been +dropped.
+dropper (Object) – The object which will drop this object.
**kwargs (dict) – Arbitrary, optional arguments for users +overriding the call (unused by default).
shoulddrop (bool) – If the object should be dropped or not.
+Notes
+If this method returns False/None, the dropping is cancelled +before it is even started.
at_before_drop(dropper, **kwargs)[source]¶at_before_drop(dropper, **kwargs)¶
Called by the default drop command before this object has been dropped.
Notes
This hook cannot stop the drop from happening. Use -permissions or the at_before_drop() hook for that.
+permissions or the at_pre_drop() hook for that. +at_pre_say(message, **kwargs)[source]¶Before the object says something.
+This hook is by default used by the ‘say’ and ‘whisper’ +commands as used by this command it is called before the text +is said/whispered and can be used to customize the outgoing +text from the object. Returning None aborts the command.
+message (str) – The suggested say/whisper text spoken by self.
+whisper (bool) – If True, this is a whisper rather than +a say. This is sent by the whisper command by default. +Other verbal commands could use this hook in similar +ways.
receivers (Object or iterable) – If set, this is the target or targets for the +say/whisper.
message (str) – The (possibly modified) text to be spoken.
+at_before_say(message, **kwargs)[source]¶at_before_say(message, **kwargs)¶
Before the object says something.
This hook is by default used by the ‘say’ and ‘whisper’ commands as used by this command it is called before the text @@ -1652,9 +1806,15 @@ method (unless you want to fundamentally change how a Character object works).
at_after_move(source_location, **kwargs)[source]¶at_after_move(source_location, **kwargs)¶
We make sure to look around after a move.
at_script_delete()[source]¶Called when the Script is deleted, after at_stop().
+Called when the Script is deleted, before stopping the timer.
+bool – If False, the deletion is aborted.
+evennia.server.inputfuncs.external_discord_hello(session, *args, **kwargs)[source]¶Sent by Mudlet as a greeting; added here to avoid -logging a missing inputfunc for it.
+evennia.server.inputfuncs.external_discord_hello(session, *args, **kwargs)¶
+Dummy used to swallow missing-inputfunc errors for +common clients.
+evennia.server.inputfuncs.client_gui(session, *args, **kwargs)¶Dummy used to swallow missing-inputfunc errors for +common clients.
get_browserstr(request)[source]¶Get browser-string out of the request.
+request (Request) – Incoming request object.
+str – The browser name.
+at_login()[source]¶evennia.typeclasses.attributes.AttributeProperty(default=None, category=None, strattr=False, lockstring='', autocreate=False)[source]¶Bases: object
Attribute property descriptor. Allows for specifying Attributes as Django-like ‘fields’ +on the class level. Note that while one can set a lock on the Attribute, +there is no way to check said lock when accessing via the property - use +the full AttributeHandler if you need to do access checks.
+Example:
+class Character(DefaultCharacter):
+ foo = AttributeProperty(default="Bar")
+attrhandler_name = 'attributes'¶__init__(default=None, category=None, strattr=False, lockstring='', autocreate=False)[source]¶Initialize an Attribute as a property descriptor.
+default (any) – A default value if the attr is not set.
category (str) – The attribute’s category. If unset, use class default.
strattr (bool) – If set, this Attribute must be a simple string, and will be +stored more efficiently.
lockstring (str) – This is not itself useful with the property, but only if +using the full AttributeHandler.get(accessing_obj=…) to access the +Attribute.
autocreate (bool) – If an un-found Attr should lead to auto-creating the +Attribute (with the default value). If False, the property will +return the default value until it has been explicitly set. This means +less database accesses, but also means the property will have no +corresponding Attribute if wanting to access it directly via the +AttributeHandler (it will also not show up in examine).
evennia.typeclasses.attributes.NAttributeProperty(default=None, category=None, strattr=False, lockstring='', autocreate=False)[source]¶Bases: evennia.typeclasses.attributes.AttributeProperty
NAttribute property descriptor. Allows for specifying NAttributes as Django-like ‘fields’ +on the class level.
+Example:
+class Character(DefaultCharacter):
+ foo = NAttributeProperty(default="Bar")
+attrhandler_name = 'nattributes'¶evennia.typeclasses.attributes.Attribute(*args, **kwargs)[source]¶key (str or list, optional) – the attribute identifier or multiple attributes to get. if a list of keys, the method will return a list.
category (str, optional) – the category within which to -retrieve attribute(s).
default (any, optional) – The value to return if an Attribute was not defined. If set, it will be returned in a one-item list.
category (str, optional) – the category within which to +retrieve attribute(s).
return_obj (bool, optional) – If set, the return is not the value of the Attribute but the Attribute object itself.
strattr (bool, optional) – Return the strvalue field of diff --git a/docs/1.0-dev/api/evennia.typeclasses.tags.html b/docs/1.0-dev/api/evennia.typeclasses.tags.html index ca9583d8d6..3cbbef98f5 100644 --- a/docs/1.0-dev/api/evennia.typeclasses.tags.html +++ b/docs/1.0-dev/api/evennia.typeclasses.tags.html @@ -253,12 +253,12 @@ stored on and with a tagtype given by self.handlertype
add(key=None, category=None, data=None)[source]¶
Add a new tag to the handler.
tag (str or list) – The name of the tag to add. If a list, +
key (str or list) – The name of the tag to add. If a list, add several Tags.
category (str, optional) – Category of Tag. None is the default category.
data (str, optional) – Info text about the tag(s) added. @@ -275,12 +275,12 @@ will be created.
has(key=None, category=None, return_list=False)[source]¶
Checks if the given Tag (or list of Tags) exists on the object.
tag (str or iterable) – The Tag key or tags to check for. +
key (str or iterable) – The Tag key or tags to check for. If None, search by category.
category (str, optional) – Limit the check to Tags with this category (note, that None is the default category).
evennia.utils.ansi.strip_mxp(string, parser=<evennia.utils.ansi.ANSIParser object>)[source]¶Strip MXP markup.
+evennia.utils.ansi.raw(string)[source]¶aliases = [':dd', ':h', ':echo', ':f', ':', ':fi', ':q', ':s', ':fd', ':i', ':::', ':=', ':j', ':x', ':q!', ':wq', ':!', ':r', ':w', ':A', ':p', ':dw', ':uu', ':UU', ':<', ':I', '::', ':S', ':>', ':u', ':DD', ':y']¶aliases = [':uu', ':echo', ':u', ':r', '::', ':w', ':j', ':>', ':q!', ':A', ':=', ':p', ':', ':S', ':x', ':!', ':f', ':y', ':i', ':wq', ':UU', ':h', ':dw', ':::', ':I', ':fd', ':s', ':dd', ':fi', ':q', ':<', ':DD']¶
search_index_entry = {'aliases': ':dd :h :echo :f : :fi :q :s :fd :i ::: := :j :x :q! :wq :! :r :w :A :p :dw :uu :UU :< :I :: :S :> :u :DD :y', 'category': 'general', 'key': ':editor_command_group', 'tags': '', 'text': '\n Commands for the editor\n '}¶search_index_entry = {'aliases': ':uu :echo :u :r :: :w :j :> :q! :A := :p : :S :x :! :f :y :i :wq :UU :h :dw ::: :I :fd :s :dd :fi :q :< :DD', 'category': 'general', 'key': ':editor_command_group', 'tags': '', 'text': '\n Commands for the editor\n '}¶
aliases = ['yes', 'abort', 'a', 'n', '__nomatch_command', 'y', 'no']¶
search_index_entry = {'aliases': 'yes abort a n __nomatch_command y no', 'category': 'general', 'key': '__noinput_command', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}¶
aliases = ['quit', 't', 'abort', 'previous', 'end', 'n', 'p', 'a', 'e', 'next', 'q', 'top']¶aliases = ['previous', 'abort', 'top', 'quit', 't', 'e', 'next', 'n', 'end', 'a', 'q', 'p']¶
search_index_entry = {'aliases': 'quit t abort previous end n p a e next q top', 'category': 'general', 'key': '__noinput_command', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}¶search_index_entry = {'aliases': 'previous abort top quit t e next n end a q p', 'category': 'general', 'key': '__noinput_command', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}¶
For this to work, this file is included in the settings file, in the TEMPLATES[“OPTIONS”][“context_processors”] list.
evennia.web.utils.general_context.set_game_name_and_slogan()[source]¶Sets global variables GAME_NAME and GAME_SLOGAN which are used by -general_context.
-Notes
-This function is used for unit testing the values of the globals.
-evennia.web.utils.general_context.set_webclient_settings()[source]¶As with set_game_name_and_slogan above, this sets global variables pertaining -to webclient settings.
-Notes
-Used for unit testing.
+evennia.web.utils.general_context.load_game_settings()[source]¶Load and cache game settings.
UMZv(ASLMvMeDk8wNwoygD!H^ZXR_i|Fv
zLIPsx^0F606L;TsCIq1VdD~hKS$9gbrTDTr@1ynZJ_&;V%>R7<1?afjDFi7lT(_l_
zx(JzU&@;rYQz{^AM(5<4M{U<{1t+M*e)Q}H%<>vGBVg?YILgB8sR$3k?&S=(sfPY(
zY6J~sV@zswLxRO*A^W01+Vi8*`##n|-d~9IY%QzR@o00Y)q6d@4|v#!G>WYBrhLgx
zH*C$Nn`raIg6|JHC}yskv|LsQlyrb6*D9`Lo*-%5D$j2&xgMsyYt38mZ?*a4nGJUU
zH2S1q6|TXU8r
5K#GZLYSg3W+Mrin76aeuSf-v~%8Bb+
z=zA~kz7K*NrXI1P`0Ko~1E?|OJ8-(B4?k&gex|~B!kh0)-ZX$$&>Tr$V99sirRKje
zg5=+!T>a-qgW>Ck0n4xWO5^WHYcWgF