[1486] in Coldmud discussion meeting

root meeting help first previous next last

Messaging system report

daemon@ATHENA.MIT.EDU (Sat Nov 20 21:03:49 1999 )

From: "Charles Lance Woodson" <AE-Wauric@aephirsden.com>
To: <coldstuff@cold.org>
Date: Sat, 20 Nov 1999 19:49:53 -0800
Reply-To: coldstuff@cold.org

This is a multi-part message in MIME format.

------=_NextPart_000_00AC_01BF3390.69C52C20
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Here is the report on the messaging system that I have written up for =
Aeternity.  I'm posting it here as it might be helpful documenting for =
others and to get feedback from you all concerning anything I might have =
missed or should correct.  Thanks!

Also, thanks to Levi for the help in this.

Lance

The Difference Between Ctext and CML
-------------------------------------------------------
Before I explain the messaging system, you need to know the difference
between CML and Ctext.  CML is the tag imbedded text that staffers will
enter messaging as.  It looks like:

You take [this].

Ctext is the compiled form of CML that cold C can work with.  It is a =
frob
datatype using the $ctext_frob object class.  It looks like:

<$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>

In general, a coder making use of any of these existing systems does not
have to work with Ctext directly.  They only need to call methods that
generate or retrieve the Ctext and send it to other methods.

Messaging system
--------------------------
Help definition of a message:  The message system is used to group =
several
different Ctext messages under a specific message type for single
evaluation. A message is composed of a base and any number of branches. =
The
branches defne each specific variation on the message, such as with =
teleport
messages--there is the actor's message, the source message and the
destination message. This message's base is "teleport" with the branches =
of
"actor", "source" and "dest". By default if no branch is specified, the
"general" branch is used instead (so referencing a message with no =
branch,
and with the "general" branch are equivalent).

What this means:  This is essentially a callback system to objects to =
return
uncompiled Ctext (CML) messages for use by other systems.  A message =
base
can be considered a single message case.  Branches can be considered =
facets
of a base.  For example, here is a look at the exit-close message base
defined on $path (as seen with @msg $path:)

  exit-close =3D [actor] closes [this].
  exit-close.actor =3D You close [this].

In this case, exit-close is the message base, and general and actor are =
the
branches.  When a person opens this particular path, the open command =
method
will make a call to the path to retrieve this messaging.  The "You close
[this]." actor branch will be displayed to the person invoking the =
command,
while the "[actor] closes [this]." general branch will be displayed to =
the
rest of the room.

Message bases and branches can easily be added or subtracted with the
@msg-define and @msg-undefine commands.  Further customization of =
messages
can be accomplished with the addition of new CML tags.

The strengths of this system are:
=B7 It lets a non-coder override default messaging for different =
object's
(people, places, things, paths, etc.) without ever having to code on the
object or know anything more than how to use the @msg command and CML.
=B7 It lets a coder derive unique messaging from an object for use by =
their
systems.
=B7 It gives a unique 'look' to different game systems while preserving =
how
their mechanics work.
=B7 Message's are inherited, enabling us to set default messaging for =
object's
on core object classes as opposed to each individual object, saving =
memory
space and making it unnecessary for GM's to set messaging on every =
object
they create.  For example, all default messaging for paths are defined =
on
the $path object.  When a GM creates a new path, say $path_22, anything =
that
makes use of messages on it will look first at $path_22 for the =
messaging
and then at $path for the default if nothing is found.
=B7 Message bases and branches can be added or subtracted from objects =
as
needed with in-game commands (@def-msg and @undef-msg).  No coding is
necessary.
=B7 The messaging system is further expandable with the addition of new =
CML
tags.

The drawbacks of the present system are:
=B7 It is not very "intelligent."  You have to write different messaging =
for
different viewpoints, even if all parts of the message are the same.  It =
is
possible to have a more intelligent messaging system that is able to
generate messaging for different viewpoints from one single message in =
these
instances.
=B7 Though the system is easy on coders, it could be made even more easy =
by
creating a standard method to call to objects to return the dictionary =
of
ctext variables for use with the .eval_message() method (see the =
Retrieving
& Displaying A Message Via Cold C Section).
=B7 The command parser itself could generate the ctext variable =
dictionary
based on those defined in the command invoking object.  It could then =
pass
this directly to the command method for use in the .eval_message() =
method
(see the Retrieving & Displaying A Message Via Cold C Section).

Viewing & Modifying Messages
--------------------------------------------
To view or modify messages on an object, you must use the @msg command.
Syntax:

@msg|@message [-clear] [<target>:][<msg>=3D<value>]

<target> is the target object
<msg> is the message branch and base in the format base.branch.
<value> is the new message.
<-clear> will clear the message.

Example:
 @msg $place_42:
 -- Messages on the place ($place):
  connect =3D [actor] wakes up.
  disconnect =3D [actor] falls asleep.
  housekeeper =3D The housekeeper arrives and takes [actor]'s body away.
---

@msg $place_42:connect =3D [actor] blinks his eyes confusedly, as if =
startled
out of a trance.
-- Message changed to:
  connect =3D [actor] blinks his eyes confusedly, as if startled out of =
a
trance.

Defining And Undefining Messages
-------------------------------------------------
To define a new message base on an object, you must use the @def-msg
command.  Syntax is:

@def-msg <target>:<msg> [options]
<target> is the object.
<msg> is the message base.
[options] are the options for the command, as follows:

      +b?ranches       Define the branches, in a comma delimited list =
(no
spaces).
      +c?ompiler       Define the CML compiler object. Defaults to
$compiler.
      +e?valuator      Define the CML evaluator object. Defaults to
$bs_eval.
      +g?etter            Define the getter. Defaults to =
'standard_get_msg

Example:
@def-msg me:test +b=3Dgeneral,actor
Message $user_wauric:test defined.
Message branches defined:
   $user_wauric:test.general
   $user_wauric:test.actor

In general, the compiler, evaluator and getter should remain the same,
though this does give us the ability to create new compilers, evaluaters =
and
getters. do have the ability to create new compilers, evaluators

To undefine a message base and all branches from an object, you must use =
the
@udef-msg command.  Syntax is:

@undef-msg <target>:<msg>
<target> is the object.
<msg> is the message base.

Example:
@undef-msg me:jump
Message $user_lance:jump undefined.


Retrieving & Displaying A Message From An Object Via Cold C
-------------------------------------------------------------------------=
---
------------
The messaging system is contained in the $foundation object, which makes =
it
definable on most object's in the core.  The message definitions are =
stored
in the object's defined_msgs variable, while the actual messages are =
found
in the msgs variable.  The method for retrieving these messages for =
display
is:

$foundation.eval_message(name, definer, vars)

This method will retrieve the ctext messaging for all branches of a =
message
base.  The name argument is a string of the message base.  The definer
argument should be the object name of the object that the message is =
defined
in.  The vars argument should be a dictionary containing the Ctext =
variables
for the message.  The keys to this vars dictionary should be strings, =
while
their associated values should be objnames for the $-variables and =
whatever
data types are appropriate for the others.  If the object receiving this
call does not have a message-definition or actual message stored on it =
for
the name specified, then this method will look at the definer object for
defaults.  Example call:

cvars =3D #[["actor", sender().name()], ["$actor", sender()], ["this",
this().name()], ["$this", this()]];
msg =3D $path.eval_message("exit-close", $path, vars);

The return value of a call to .eval_message is a message frob (class
$message_frob).  Its data part is a dictionary.  The dictionary keys are =
the
objnames of the message branch targets (except for the general branch, =
if it
exists, which remans string "general").  The associated values of those =
keys
are Ctext frobs that contain the text to be displayed to the targets.
Example return from the above call:

<$message_frob, #[["general", <$ctext_frob, [["Lance", " closes ", =
"Lance",
"."], #[["actor", "Lance"], ["$actor", $user_lance], ["this", "Lance"],
["$this", $user_lance], ['evaluator, $bs_eval], ['varkeys, 0], ['this,
$path], ['time, 'pre], ['sender, $message_frob]]]>], [$user_lance,
<$ctext_frob, [["You close ", "Lance", "."], #[["actor", "Lance"],
["$actor", $user_lance], ["this", "Lance"], ["$this", $user_lance],
['evaluator, $bs_eval], ['varkeys, 0], ['this, $path], ['time, pre],
['sender, $message_frob]]]>]]>

The coder does not need to be concerned with that value, however.  I =
list it
here only for reference.  To make it display the branches correctly to =
the
different parties, all the coder has to do is call .announce() in the
appropriate locations sending this message frob as the argument.  =
Continuing
the above example, this would be:

 sender().location().announce(msg);

In this case, this will display the actor branch to the actor and the
general branch to the rest of the room.

One of the ways the system could be improved is to create a standard =
method
for retrieving the ctext variables from an object.  On some objects =
there is
a method that returns this variable dictionary for you, such as
$path.path_msg_vars(), while on others you have to know the variable
dictionary to send it as an argument, such as when calling =
.eval_message()
to a descendant of $user.

Walkthrough Of Message System Use
-----------------------------------------------------
The following is a walkthrough for creating the jump verb on =
$user_wauric
that uses messaging defined on $user_wauric.  I also show how the =
messaging
can be changed easily in game with the @msg command, though the verb
mechanics remain the same.

@def-msg me:jump +b=3Dgeneral,actor
Message $user_wauric:jump defined.
Message branches defined:
  $user_wauric:jump.general
  $user_wauric:jump.actor

@msg me:jump=3D[actor] jumps up and down!
-- Message changed to:
  jump =3D [actor] jumps up and down!

@msg me:jump.actor=3DYou jump up and down!
-- Message changed to:
  jump.actor =3D You jump up and down!

@program .jump_cmd
-- Reprogramming public method $user_wauric.jump_cmd() --
arg cmdstr, cmd;
var vars, message;

vars =3D #[["actor", sender().name()], ["$actor", sender()]];
message =3D .eval_message("jump", $user_wauric, vars);
sender().location().announce(message);
.

@ac "jump" to $user_wauric.jump_cmd
Command "jump" added to $user_wauric.jump_cmd()

@rehash
Rehashing (raw) commands on Wauric ($user_wauric)...
Done.

jump
You jump up and down!

Rest of room sees:
Wauric jumps up and down!

@msg me:jump=3D[actor] hops around in circles.
-- Message changed to:
  jump =3D [actor] hops around in circles.

@msg me:jump.actor=3DYou hop around in a circle.
-- Message changed to:
  jump.actor =3D You hop around in a circle.

jump
You hop around in a circle.

Rest of room sees:
Wauric hops around in circles.

Improving The System With Ctext Variable Retrieval Methods
-------------------------------------------------------------------------=
---
--------
To give an example of how the current system can be made easier to use
through ctext variable retrieval methods, I created the following
.get_ctext_vars() method on $user_wauric:


arg @args;
var vars;

// Standard ctext variable initialization method.
//
// args argument is for a list of optional objects (if needed).
//
// args[1] =3D the target object
// args[2] =3D the destination place
//

vars =3D #[];
vars =3D dict_add(vars, "actor", .name());
vars =3D dict_add(vars, "$actor", this());
vars =3D dict_add(vars, "source", .location());
vars =3D dict_add(vars, "$source", .location());
(| vars =3D dict_add(vars, "target", args[1].name()) |);
(| vars =3D dict_add(vars, "$target", args[1]) |);
(| vars =3D dict_add(vars, "dest", args[2]) |);
(| vars =3D dict_add(vars, "$dest", args[2]) |);
return vars;

I then reprogrammed the $user_wauric.jump_cmd() method as
follows:

  arg cmdstr, cmd;
  var vars, message;

  vars =3D .get_ctext_vars();
  message =3D .eval_message("jump", $user_wauric, vars);
  sender().location().announce(message);

The benefit of creating these retrieval methods is that coders do not =
have to remember what Ctext variables exist on an object or what format =
to pass them as an  argument to .eval_message().  Needless to say, this =
would save coder time down the road.



------=_NextPart_000_00AC_01BF3390.69C52C20
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2314.1000" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT size=3D2>Here is the report on the messaging system that I =
have written=20
up for Aeternity.&nbsp; I'm posting it here as it might be helpful =
documenting=20
for others and to get&nbsp;feedback from you all concerning anything I =
might=20
have missed or should correct.&nbsp; Thanks!</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>Also, thanks to Levi for the help in =
this.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>Lance</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>The Difference Between Ctext and=20
CML<BR>-------------------------------------------------------<BR>Before =
I=20
explain the messaging system, you need to know the difference<BR>between =
CML and=20
Ctext.&nbsp; CML is the tag imbedded text that staffers will<BR>enter =
messaging=20
as.&nbsp; It looks like:<BR><BR>You take [this].<BR><BR>Ctext is the =
compiled=20
form of CML that cold C can work with.&nbsp; It is a frob<BR>datatype =
using the=20
$ctext_frob object class.&nbsp; It looks like:<BR><BR>&lt;$ctext_frob, =
[["You=20
take ", &lt;$generator, ["this", [], [], 'gen_this]&gt;<BR><BR>In =
general, a=20
coder making use of any of these existing systems does not<BR>have to =
work with=20
Ctext directly.&nbsp; They only need to call methods that<BR>generate or =

retrieve the Ctext and send it to other methods.<BR><BR>Messaging=20
system<BR>--------------------------<BR>Help definition of a =
message:&nbsp; The=20
message system is used to group several<BR>different Ctext messages =
under a=20
specific message type for single<BR>evaluation. A message is composed of =
a base=20
and any number of branches. The<BR>branches defne each specific =
variation on the=20
message, such as with teleport<BR>messages--there is the actor's =
message, the=20
source message and the<BR>destination message. This message's base is =
"teleport"=20
with the branches of<BR>"actor", "source" and "dest". By default if no =
branch is=20
specified, the<BR>"general" branch is used instead (so referencing a =
message=20
with no branch,<BR>and with the "general" branch are =
equivalent).<BR><BR>What=20
this means:&nbsp; This is essentially a callback system to objects to=20
return<BR>uncompiled Ctext (CML) messages for use by other =
systems.&nbsp; A=20
message base<BR>can be considered a single message case.&nbsp; Branches =
can be=20
considered facets<BR>of a base.&nbsp; For example, here is a look at the =

exit-close message base<BR>defined on $path (as seen with @msg=20
$path:)<BR><BR>&nbsp; exit-close =3D [actor] closes [this].<BR>&nbsp;=20
exit-close.actor =3D You close [this].<BR><BR>In this case, exit-close =
is the=20
message base, and general and actor are the<BR>branches.&nbsp; When a =
person=20
opens this particular path, the open command method<BR>will make a call =
to the=20
path to retrieve this messaging.&nbsp; The "You close<BR>[this]." actor =
branch=20
will be displayed to the person invoking the command,<BR>while the =
"[actor]=20
closes [this]." general branch will be displayed to the<BR>rest of the=20
room.<BR><BR>Message bases and branches can easily be added or =
subtracted with=20
the<BR>@msg-define and @msg-undefine commands.&nbsp; Further =
customization of=20
messages<BR>can be accomplished with the addition of new CML =
tags.<BR><BR>The=20
strengths of this system are:<BR>=B7 It lets a non-coder override =
default=20
messaging for different object's<BR>(people, places, things, paths, =
etc.)=20
without ever having to code on the<BR>object or know anything more than =
how to=20
use the @msg command and CML.<BR>=B7 It lets a coder derive unique =
messaging from=20
an object for use by their<BR>systems.<BR>=B7 It gives a unique 'look' =
to=20
different game systems while preserving how<BR>their mechanics =
work.<BR>=B7=20
Message's are inherited, enabling us to set default messaging for =
object's<BR>on=20
core object classes as opposed to each individual object, saving =
memory<BR>space=20
and making it unnecessary for GM's to set messaging on every =
object<BR>they=20
create.&nbsp; For example, all default messaging for paths are defined =
on<BR>the=20
$path object.&nbsp; When a GM creates a new path, say $path_22, anything =

that<BR>makes use of messages on it will look first at $path_22 for the=20
messaging<BR>and then at $path for the default if nothing is =
found.<BR>=B7 Message=20
bases and branches can be added or subtracted from objects as<BR>needed =
with=20
in-game commands (@def-msg and @undef-msg).&nbsp; No coding=20
is<BR>necessary.<BR>=B7 The messaging system is further expandable with =
the=20
addition of new CML<BR>tags.<BR><BR>The drawbacks of the present system=20
are:<BR>=B7 It is not very "intelligent."&nbsp; You have to write =
different=20
messaging for<BR>different viewpoints, even if all parts of the message =
are the=20
same.&nbsp; It is<BR>possible to have a more intelligent messaging =
system that=20
is able to<BR>generate messaging for different viewpoints from one =
single=20
message in these<BR>instances.<BR>=B7 Though the system is easy on =
coders, it=20
could be made even more easy by<BR>creating a standard method to call to =
objects=20
to return the dictionary of<BR>ctext variables for use with the =
.eval_message()=20
method (see the Retrieving<BR>&amp; Displaying A Message Via Cold C=20
Section).<BR>=B7 The command parser itself could generate the ctext =
variable=20
dictionary<BR>based on those defined in the command invoking =
object.&nbsp; It=20
could then pass<BR>this directly to the command method for use in the=20
.eval_message() method<BR>(see the Retrieving &amp; Displaying A Message =
Via=20
Cold C Section).<BR><BR>Viewing &amp; Modifying=20
Messages<BR>--------------------------------------------<BR>To view or =
modify=20
messages on an object, you must use the @msg=20
command.<BR>Syntax:<BR><BR>@msg|@message [-clear]=20
[&lt;target&gt;:][&lt;msg&gt;=3D&lt;value&gt;]<BR><BR>&lt;target&gt; is =
the target=20
object<BR>&lt;msg&gt; is the message branch and base in the format=20
base.branch.<BR>&lt;value&gt; is the new message.<BR>&lt;-clear&gt; will =
clear=20
the message.<BR><BR>Example:<BR>&nbsp;@msg $place_42:<BR>&nbsp;-- =
Messages on=20
the place ($place):<BR>&nbsp; connect =3D [actor] wakes up.<BR>&nbsp; =
disconnect =3D=20
[actor] falls asleep.<BR>&nbsp; housekeeper =3D The housekeeper arrives =
and takes=20
[actor]'s body away.<BR>---<BR><BR>@msg $place_42:connect =3D [actor] =
blinks his=20
eyes confusedly, as if startled<BR>out of a trance.<BR>-- Message =
changed=20
to:<BR>&nbsp; connect =3D [actor] blinks his eyes confusedly, as if =
startled out=20
of a<BR>trance.<BR><BR>Defining And Undefining=20
Messages<BR>-------------------------------------------------<BR>To =
define a new=20
message base on an object, you must use the @def-msg<BR>command.&nbsp; =
Syntax=20
is:<BR><BR>@def-msg &lt;target&gt;:&lt;msg&gt; =
[options]<BR>&lt;target&gt; is=20
the object.<BR>&lt;msg&gt; is the message base.<BR>[options] are the =
options for=20
the command, as follows:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
+b?ranches&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Define the branches, in a =
comma=20
delimited list (no<BR>spaces).<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
+c?ompiler&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Define the CML compiler =
object.=20
Defaults to<BR>$compiler.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
+e?valuator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Define the CML evaluator =
object.=20
Defaults to<BR>$bs_eval.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
+g?etter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;=20
Define the getter. Defaults to =
'standard_get_msg<BR><BR>Example:<BR>@def-msg=20
me:test +b=3Dgeneral,actor<BR>Message $user_wauric:test =
defined.<BR>Message=20
branches defined:<BR>&nbsp;&nbsp; =
$user_wauric:test.general<BR>&nbsp;&nbsp;=20
$user_wauric:test.actor<BR><BR>In general, the compiler, evaluator and =
getter=20
should remain the same,<BR>though this does give us the ability to =
create new=20
compilers, evaluaters and<BR>getters. do have the ability to create new=20
compilers, evaluators<BR><BR>To undefine a message base and all branches =
from an=20
object, you must use the<BR>@udef-msg command.&nbsp; Syntax=20
is:<BR><BR>@undef-msg &lt;target&gt;:&lt;msg&gt;<BR>&lt;target&gt; is =
the=20
object.<BR>&lt;msg&gt; is the message =
base.<BR><BR>Example:<BR>@undef-msg=20
me:jump<BR>Message $user_lance:jump undefined.<BR><BR><BR>Retrieving =
&amp;=20
Displaying A Message From An Object Via Cold=20
C<BR>--------------------------------------------------------------------=
--------<BR>------------<BR>The=20
messaging system is contained in the $foundation object, which makes=20
it<BR>definable on most object's in the core.&nbsp; The message =
definitions are=20
stored<BR>in the object's defined_msgs variable, while the actual =
messages are=20
found<BR>in the msgs variable.&nbsp; The method for retrieving these =
messages=20
for display<BR>is:<BR><BR>$foundation.eval_message(name, definer,=20
vars)<BR><BR>This method will retrieve the ctext messaging for all =
branches of a=20
message<BR>base.&nbsp; The name argument is a string of the message =
base.&nbsp;=20
The definer<BR>argument should be the object name of the object that the =
message=20
is defined<BR>in.&nbsp; The vars argument should be a dictionary =
containing the=20
Ctext variables<BR>for the message.&nbsp; The keys to this vars =
dictionary=20
should be strings, while<BR>their associated values should be objnames =
for the=20
$-variables and whatever<BR>data types are appropriate for the =
others.&nbsp; If=20
the object receiving this<BR>call does not have a message-definition or =
actual=20
message stored on it for<BR>the name specified, then this method will =
look at=20
the definer object for<BR>defaults.&nbsp; Example call:<BR><BR>cvars =3D =

#[["actor", sender().name()], ["$actor", sender()], =
["this",<BR>this().name()],=20
["$this", this()]];<BR>msg =3D $path.eval_message("exit-close", $path,=20
vars);<BR><BR>The return value of a call to .eval_message is a message =
frob=20
(class<BR>$message_frob).&nbsp; Its data part is a dictionary.&nbsp; The =

dictionary keys are the<BR>objnames of the message branch targets =
(except for=20
the general branch, if it<BR>exists, which remans string =
"general").&nbsp; The=20
associated values of those keys<BR>are Ctext frobs that contain the text =
to be=20
displayed to the targets.<BR>Example return from the above=20
call:<BR><BR>&lt;$message_frob, #[["general", &lt;$ctext_frob, =
[["Lance", "=20
closes ", "Lance",<BR>"."], #[["actor", "Lance"], ["$actor", =
$user_lance],=20
["this", "Lance"],<BR>["$this", $user_lance], ['evaluator, $bs_eval], =
['varkeys,=20
0], ['this,<BR>$path], ['time, 'pre], ['sender, $message_frob]]]&gt;],=20
[$user_lance,<BR>&lt;$ctext_frob, [["You close ", "Lance", "."], =
#[["actor",=20
"Lance"],<BR>["$actor", $user_lance], ["this", "Lance"], ["$this",=20
$user_lance],<BR>['evaluator, $bs_eval], ['varkeys, 0], ['this, $path], =
['time,=20
pre],<BR>['sender, $message_frob]]]&gt;]]&gt;<BR><BR>The coder does not =
need to=20
be concerned with that value, however.&nbsp; I list it<BR>here only for=20
reference.&nbsp; To make it display the branches correctly to =
the<BR>different=20
parties, all the coder has to do is call .announce() in =
the<BR>appropriate=20
locations sending this message frob as the argument.&nbsp; =
Continuing<BR>the=20
above example, this would=20
be:<BR><BR>&nbsp;sender().location().announce(msg);<BR><BR>In this case, =
this=20
will display the actor branch to the actor and the<BR>general branch to =
the rest=20
of the room.<BR><BR>One of the ways the system could be improved is to =
create a=20
standard method<BR>for retrieving the ctext variables from an =
object.&nbsp; On=20
some objects there is<BR>a method that returns this variable dictionary =
for you,=20
such as<BR>$path.path_msg_vars(), while on others you have to know the=20
variable<BR>dictionary to send it as an argument, such as when calling=20
.eval_message()<BR>to a descendant of $user.<BR><BR>Walkthrough Of =
Message=20
System =
Use<BR>-----------------------------------------------------<BR>The=20
following is a walkthrough for creating the jump verb on =
$user_wauric<BR>that=20
uses messaging defined on $user_wauric.&nbsp; I also show how the=20
messaging<BR>can be changed easily in game with the @msg command, though =
the=20
verb<BR>mechanics remain the same.<BR><BR>@def-msg me:jump=20
+b=3Dgeneral,actor<BR>Message $user_wauric:jump defined.<BR>Message =
branches=20
defined:<BR>&nbsp; $user_wauric:jump.general<BR>&nbsp;=20
$user_wauric:jump.actor<BR><BR>@msg me:jump=3D[actor] jumps up and =
down!<BR>--=20
Message changed to:<BR>&nbsp; jump =3D [actor] jumps up and =
down!<BR><BR>@msg=20
me:jump.actor=3DYou jump up and down!<BR>-- Message changed =
to:<BR>&nbsp;=20
jump.actor =3D You jump up and down!<BR><BR>@program .jump_cmd<BR>-- =
Reprogramming=20
public method $user_wauric.jump_cmd() --<BR>arg cmdstr, cmd;<BR>var =
vars,=20
message;<BR><BR>vars =3D #[["actor", sender().name()], ["$actor",=20
sender()]];<BR>message =3D .eval_message("jump", $user_wauric,=20
vars);<BR>sender().location().announce(message);<BR>.<BR><BR>@ac "jump" =
to=20
$user_wauric.jump_cmd<BR>Command "jump" added to=20
$user_wauric.jump_cmd()<BR><BR>@rehash<BR>Rehashing (raw) commands on =
Wauric=20
($user_wauric)...<BR>Done.<BR><BR>jump<BR>You jump up and =
down!<BR><BR>Rest of=20
room sees:<BR>Wauric jumps up and down!<BR><BR>@msg me:jump=3D[actor] =
hops around=20
in circles.<BR>-- Message changed to:<BR>&nbsp; jump =3D [actor] hops =
around in=20
circles.<BR><BR>@msg me:jump.actor=3DYou hop around in a circle.<BR>-- =
Message=20
changed to:<BR>&nbsp; jump.actor =3D You hop around in a=20
circle.<BR><BR>jump<BR>You hop around in a circle.<BR><BR>Rest of room=20
sees:<BR>Wauric hops around in circles.<BR><BR>Improving The System With =
Ctext=20
Variable Retrieval=20
Methods<BR>--------------------------------------------------------------=
--------------<BR>--------<BR>To=20
give an example of how the current system can be made easier to =
use<BR>through=20
ctext variable retrieval methods, I created the =
following<BR>.get_ctext_vars()=20
method on $user_wauric:<BR><BR><BR>arg @args;<BR>var vars;<BR><BR>// =
Standard=20
ctext variable initialization method.<BR>//<BR>// args argument is for a =
list of=20
optional objects (if needed).<BR>//<BR>// args[1] =3D the target =
object<BR>//=20
args[2] =3D the destination place<BR>//<BR><BR>vars =3D #[];<BR>vars =3D =

dict_add(vars, "actor", .name());<BR>vars =3D dict_add(vars, "$actor",=20
this());<BR>vars =3D dict_add(vars, "source", .location());<BR>vars =3D=20
dict_add(vars, "$source", .location());<BR>(| vars =3D dict_add(vars, =
"target",=20
args[1].name()) |);<BR>(| vars =3D dict_add(vars, "$target", args[1]) =
|);<BR>(|=20
vars =3D dict_add(vars, "dest", args[2]) |);<BR>(| vars =3D =
dict_add(vars, "$dest",=20
args[2]) |);<BR>return vars;<BR><BR>I then reprogrammed the=20
$user_wauric.jump_cmd() method as<BR>follows:<BR><BR>&nbsp; arg cmdstr,=20
cmd;<BR>&nbsp; var vars, message;<BR><BR>&nbsp; vars =3D=20
.get_ctext_vars();<BR>&nbsp; message =3D .eval_message("jump", =
$user_wauric,=20
vars);<BR>&nbsp; sender().location().announce(message);<BR><BR>The =
benefit of=20
creating these&nbsp;retrieval methods is that coders do not have to =
remember=20
what Ctext variables exist on an object or what format to pass them as =
an&nbsp;=20
argument to .eval_message().&nbsp; Needless to say, this would save =
coder time=20
down the road.</FONT><FONT size=3D2><BR><BR></DIV></FONT></BODY></HTML>

------=_NextPart_000_00AC_01BF3390.69C52C20--