Understand and write action messages with automatic verb conjugation, pronoun handling, and perspective-based delivery. Covers all $-tokens ($N, $v, $t, $o, $p, $r, $b), all action functions, article handling, reflexives, and common pitfalls.
The action message system (derived from Lima MUD) composes messages that automatically adjust grammar based on who is reading them. A single template like "$N $vswing $p sword." produces "You swing your sword." for the actor and "Bob swings his sword." for everyone else.
Core files:
adm/daemons/action.c — message composition engine (ACTION_D)std/ext/action.c — module wrapper inherited by living objectsadm/simul_efun/english.c — pronoun functions (subjective, objective, possessive, reflexive)adm/simul_efun/grammar.c — pluralisation helpersAll are called on the actor object (via EXT_ACTION module). The actor is always previous_object().
| Function | Who Sees It | Use For |
|---|
simple_action(msg, obs...) | Actor + room | Standard actions visible to everyone |
my_action(msg, obs...) | Actor only | Private feedback, failure messages |
other_action(msg, obs...) | Room only (not actor) | Announcements excluding the doer |
targetted_action(msg, target, obs...) | Actor + target + room (3 perspectives) | Actions directed at someone |
target_action(msg, target, obs...) | Target only | Private message to target |
my_target_action(msg, target, obs...) | Actor only | Actor sees target-aware message |
All functions accept mixed msg — either a string template or an array of strings (one is chosen randomly via element_of()).
The doer of the action. Defaults to who[0].
| Token | Actor Sees | Others See (first mention) | Others See (subsequent) |
|---|---|---|---|
$N | "You" | "Bob" | "he"/"she"/"they" (subjective) |
$No | "you" | "Bob" | "him"/"her"/"them" (objective) |
$Nd | "Bob" | "Bob" | "Bob" (always display name) |
$Np | "Bob's" | "Bob's" | "Bob's" (possessive proper noun) |
$N capitalises the result; lowercase $n does notquery_gender(): returns "male", "female", "other"Conjugates a verb based on perspective.
| Token | Actor Sees | Others See |
|---|---|---|
$vswing | "swing" | "swings" |
$vgrab | "grab" | "grabs" |
$vtry | "try" | "tries" |
$vis | "are" | "is" |
$vare | "are" | "is" |
Rules:
pluralize(verb): "swings", "grabs" (third-person singular)$vis, $vam, $vare → "are" for actor, "is" for others"other" also gets "are" (plural agreement)$vdon't works — the system detects 't after the verb and appends itUppercase $V capitalises the conjugated result.
The target of the action. Defaults to who[1] with objective suffix.
| Token | Actor Sees | Target Sees | Others See |
|---|---|---|---|
$t | "Bob" | "you" | "Bob" / "him" |
Same pronoun logic as $N but defaults to participant 1 (the target) and objective case.
References objects from the obs... arguments.
| Token | Resolves To |
|---|---|
$o or $o0 | obs[0] |
$o1 | obs[1] |
$o2 | obs[2] |
Article handling: The system detects articles in the text before $o and adjusts:
| You Write | Result |
|---|---|
"a $o" | "a sword" (indefinite article from a_short()) |
"the $o" | "the sword" (definite article from the_short()) |
"$o" | "sword" (bare short description) |
simple_list()
"a $o" with 3 swords → "3 swords"| Token | Actor Sees | Others See (first mention) | Others See (subsequent) |
|---|---|---|---|
$p | "your" | "Bob's" | "his"/"her"/"their"/"its" |
| Token | Actor Sees | Others See |
|---|---|---|
$r | "yourself" | "himself"/"herself"/"themself"/"itself" |
Like $N but uses objective pronouns on subsequent mentions.
| Token | Actor Sees | Others See (first mention) | Others See (subsequent) |
|---|---|---|---|
$b | "you" | "Bob" | "him"/"her"/"them" |
Tokens can reference specific participants by number:
$n0 — who[0] (the actor, same as $n)$n1 — who[1] (the target in targetted actions)$v1swing — conjugate "swing" for who[1]'s perspective$p1 — possessive of who[1]The format is: $[TYPE][PARTICIPANT_NUMBER][SUFFIX]
For two-digit parsing: $[TYPE][SUBJECT_NUMBER][PARTICIPANT_NUMBER][SUFFIX] — subject determines reflexive detection, participant determines which person.
When the subject and participant are the same person and the subject has already been mentioned, reflexive pronouns are used automatically:
"$N $vkick $No"
// Actor: "You kick yourself." (not "You kick you.")
// Others: "Bob kicks himself." (not "Bob kicks Bob.")
This only triggers when both reference the same who[] entry and the subject has been previously mentioned in the message.
Actor ← compose_message(actor, msg, who, obs)
Actor's inventory ← compose_message(null, msg, who, obs)
Room (excluding actor) ← compose_message(null, msg, who, obs)
Actor ← compose_message(actor, msg, who, obs)
Target ← compose_message(target, msg, who, obs)
Actor's inventory ← compose_message(null, msg, who, obs)
Target's inventory ← compose_message(null, msg, who, obs)
Room (excluding actor and target) ← compose_message(null, msg, who, obs)
When forwhom is null (the "others" perspective), no participant matches, so all names are used with third-person conjugation.
tp->simple_action("$N $vdrop $p $o.", item);
// Actor: "You drop your sword."
// Others: "Bob drops his sword."
tp->my_action("$N $vcannot drop $p $o.", item);
// Actor: "You cannot drop your sword."
tp->targetted_action("$N $vgive $p $o to $t.", target, item);
// Actor: "You give your sword to Alice."
// Target: "Bob gives his sword to you."
// Others: "Bob gives his sword to Alice."
tp->simple_action("$N $vtake a $o from a $o1.", item, container);
// Actor: "You take a sword from a chest."
// Others: "Bob takes a sword from a chest."
tp->simple_action("$N $vis ready to fight.");
// Actor: "You are ready to fight."
// Others: "Bob is ready to fight."
tp->simple_action("$N $vdon't see that here.");
// Actor: "You don't see that here."
// Others: "Bob doesn't see that here."
tp->other_action("$N $venter from the north.");
// Actor: (nothing)
// Others: "Bob enters from the north."
tp->simple_action("$N $vhurt $No.");
// Actor: "You hurt yourself."
// Others: "Bob hurts himself."
tp->simple_action(({
"$N $vswing $p sword wildly.",
"$N $vslash at the air with $p sword.",
"$N $vbrandish $p sword menacingly.",
}), sword);
// Randomly picks one template each time
Problem: "Bob swing the sword" instead of "Bob swings the sword"
Cause: Missing $v prefix on the verb. Write $vswing not just swing.
Problem: Actor sees "you" but you wanted the name
Fix: Use $Nd (display name suffix) to force the name instead of pronoun.
Problem: "he drops his sword" on first mention instead of "Bob drops his sword"
Cause: The has tracking thinks the object was already mentioned. This can happen if the same living appears in multiple token positions. The system tracks mentions per-composition — each viewer gets fresh tracking.
Problem: "You is ready" or "Bob are ready"
Fix: Use $vis (not $vare or $vam). The system handles conjugation — all three forms (is/am/are) trigger the same "to be" logic.
Problem: First mention of an object shows "it" instead of the name
Cause: The object or its short description was already in the has tracking — possibly mentioned via a different token. Each $o use with the same object increments the tracking.
Problem: "Bob's" shows up where "your" should
Cause: Check which participant $p refers to. By default it's participant 0 (the actor). Use $p1 for the target's possessive.
Problem: "a a sword" or missing article
Cause: The system strips and re-applies articles when a or the precedes $o. If your object's query_short() already includes an article ("a sword"), the system will strip and reapply. Don't include articles in both the template and the short description.
Note: Gender "other" uses plural agreement — $vis → "are", $vswing → "swing" (not "swings"). This is intentional for they/them pronouns.
Available as simul_efuns for manual use:
| Function | Returns |
|---|---|
subjective(ob) | "he", "she", "they", "it" |
objective(ob) | "him", "her", "them", "it" |
possessive(ob) | "his", "her", "their", "its" |
possessive_proper_noun(ob) | "Bob's", "Alice's" |
reflexive(ob) | "himself", "herself", "themself", "itself" |
pluralize(str) | Third-person singular: "swing" → "swings" |
simple_list(arr) | "sword, shield, and mace" |
add_article(str, definite) | Add "a"/"an" or "the" |
remove_article(str) | Strip leading article |