Messages varying per receiver¶
Sending messages to everyong in a location is handled by the msg_contents method on all Objects. It’s most commonly called on rooms.
room.msg_contents("Anna walks into the room.")
You can also embed references in the string:
room.msg_contents("{anna} walks into the room.",
from_obj=caller,
mapping={'anna': anna_object})
Use exclude=object_or_list_of_object
to skip sending the message one or more targets.
The advantage of this is that anna_object.get_display_name(looker)
will be called for every onlooker; this allows the {anna}
stanza to be different depending on who sees the strings. How this is to work depends on the stance of your game.
The stance indicates how your game echoes its messages to the player. Knowing how you want to handle the stance is important for a text game. There are two main stances that are usually considered, Actor stance and Director stance.
Stance |
You see |
Others in the same location see |
---|---|---|
Actor stance |
You pick up the stone |
Anna picks up the stone |
Director stance |
Anna picks up the stone |
Anna picks up the stone |
It’s not unheard of to mix the two stances - with commands from the game being told in Actor stance while Director stance is used for complex emoting and roleplaying. One should usually try to be consistent however.
Director Stance¶
While not as common as Actor stance, director stance has the advantage of simplicity, particularly in roleplaying MUDs where longer roleplaying emotes are used. It is also a pretty simple stance to implement technically since everyone sees the same text, regardless of viewpoint.
Here’s an example of a flavorful text to show the room:
Tom picks up the gun, whistling to himself.
Everyone will see this string, both Tom and others. Here’s how to send it to everyone in the room.
text = "Tom picks up the gun, whistling to himself."
room.msg_contents(text)
One may want to expand on it by making the name Tom
be seen differently by different people,
but the English grammar of the sentence does not change. Not only is this pretty easy to do
technically, it’s also easy to write for the player.
Actor Stance¶
This means that the game addresses “you” when it does things. In actor stance, whenever you perform an action, you should get a different message than those observing you doing that action.
Tom picks up the gun, whistling to himself.
This is what others should see. The player themselves should see this:
You pick up the gun, whistling to yourself.
Not only do you need to map “Tom” to “You” above, there are also grammatical differences - “Tom walks” vs “You walk” and “himself” vs “yourself”. This is a lot more complex to handle. For a developer making simple “You/Tom pick/picks up the stone” messages, you could in principle hand-craft the strings from every view point, but there’s a better way.
The msg_contents
method helps by parsing the ingoing string with a FuncParser functions with some very specific $inline-functions
. The inline funcs basically provides you with a mini-language for building one string that will change appropriately depending on who sees it.
text = "$You() $conj(pick) up the gun, whistling to $pron(yourself)."
room.msg_contents(text, from_obj=caller, mapping={"gun": gun_object})
These are the inline-functions available:
$You()/$you()
- this is a reference to ‘you’ in the text. It will be replaced with “You/you” for the one sending the text and with the return fromcaller.get_display_name(looker)
for everyone else.$conj(verb)
- this will conjugate the given verb depending on who sees the string (likepick
topicks
). Enter the root form of the verb.$pron(pronoun[,options])
- A pronoun is a word you want to use instead of a proper noun, like him, herself, its, me, I, their and so on. Theoptions
is a space- or comma-separated set of options to help the system map your pronoun from 1st/2nd person to 3rd person and vice versa. See next section.
More on $pron()¶
The $pron()
inline func maps between 1st/2nd person (I/you) to 3rd person (he/she etc). In short,
it translates between this table …
Subject Pronoun |
Object Pronoun |
Possessive Adjective |
Possessive Pronoun |
Reflexive Pronoun |
|
---|---|---|---|---|---|
1st person |
I |
me |
my |
mine |
myself |
1st person plural |
we |
us |
our |
ours |
ourselves |
2nd person |
you |
you |
your |
yours |
yourself |
2nd person plural |
you |
you |
your |
yours |
yourselves |
… to this table (in both directions):
Subject Pronoun |
Object Pronoun |
Possessive Adjective |
Possessive Pronoun |
Reflexive Pronoun |
|
---|---|---|---|---|---|
3rd person male |
he |
him |
his |
his |
himself |
3rd person female |
she |
her |
her |
hers |
herself |
3rd person neutral |
it |
it |
its |
theirs* |
itself |
3rd person plural |
they |
them |
their |
theirs |
themselves |
Some mappings are easy. For example, if you write $pron(yourselves)
then the 3rd-person form is always themselves
. But because English grammar is the way it is, not all mappings are 1:1. For example, if you write $pron(you)
, Evennia will not know which 3rd-persion equivalent this should map to - you need to provide more info to help out. This can either be provided as a second space-separated option to $pron
or the system will try to figure it out on its own.
pronoun_type
- this is one of the columns in the table and can be set as a$pron
option.subject pronoun
(aliasessubject
orsp
)object pronoun
(aliasesobject
orop
)possessive adjective
(aliasesadjective
orpa
)possessive pronoun
(aliasespronoun
orpp
).
(There is no need to specify reflexive pronouns since they are all uniquely mapped 1:1). Speciying the pronoun-type is mainly needed when using
you
, since the same ‘you’ is used to represent all sorts of things in English grammar. If not specified and the mapping is not clear, a ‘subject pronoun’ (he/she/it/they) is assumed.gender
- set in$pron
option asmale
, orm
female'
orf
neutral
, orn
plural
, orp
(yes plural is considered a ‘gender’ for this purpose).
If not set as an option the system will look for a callable or property
.gender
on the currentfrom_obj
. A callable will be called with no arguments and is expected to return a string ‘male/female/neutral/plural’. If none is found, a neutral gender is assumed.viewpoint
- set in$pron
option as1st person
(aliases1st
or1
)2nd person
(aliases2nd
or2
)
This is only needed if you want to have 1st person perspective - if not, 2nd person is assumed wherever the viewpoint is unclear.
$pron()
examples:
Input |
you see |
others see |
note |
---|---|---|---|
|
I |
he |
|
|
I |
she |
|
|
my |
its |
figures out it’s an possessive adjective, assumes neutral |
|
you |
it |
assumes neutral subject pronoun |
|
you |
she |
female specified, assumes subject pronoun |
|
you |
her |
|
|
you |
them |
|
|
you |
her |
specified female and objective pronoun |
|
yourself |
itself |
|
|
your |
its |
|
|
Your |
Its |
Using $Pron always capitalizes |
|
you |
her |
3rd person -> 2nd person |
|
I |
her |
3rd person -> 1st person |
|
my |
its |
3rd person -> 1st person |
Note the three last examples - instead of specifying the 2nd person form you can also specify the 3rd-person and do a ‘reverse’ lookup - you will still see the proper 1st/2nd text. So writing $pron(her)
instead of $pron(you, op f)
gives the same result.
Referencing other objects¶
There is one more inlinefunc understood by msg_contents
. This can be used natively to spruce up
your strings (for both director- and actor stance):
$Obj(name)/$obj(name)
references another entity, which must be supplied in themapping
keyword argument tomsg_contents
. The object’s.get_display_name(looker)
will be called and inserted instead. This is essentially the same as using the{anna}
marker we used in the first example at the top of this page, but using$Obj/$obj
allows you to easily control capitalization.
This is used like so:
# director stance
text = "Tom picks up the $obj(gun), whistling to himself"
# actor stance
text = "$You() $conj(pick) up the $obj(gun), whistling to $pron(yourself)"
room.msg_contents(text, from_obj=caller, mapping={"gun": gun_object})
Depending on your game, Tom may now see himself picking up A rusty old gun
, whereas an onlooker with a high gun smith skill may instead see him picking up A rare-make Smith & Wesson model 686 in poor condition" ...
Recog systems and roleplaying¶
The $funcparser
inline functions are very powerful for the game developer, but they may
be a bit too much to write for the regular player.
The rpsystem contrib implements a full dynamic emote/pose and recognition system with short-descriptions and disguises. It uses director stance with a custom markup language, like /me
/gun
and /tall man
to refer to players and objects in the location. It can be worth checking out for inspiration.