Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUDs ➜ General ➜ Suggested protocol for server to client "out of band" messages

Suggested protocol for server to client "out of band" messages

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3  4  5  6  7  8  9  10  11  12 13  14  15  16  17  18  19  20  21  22  23  

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #165 on Fri 19 Feb 2010 05:01 AM (UTC)
Message
Ha! I wasn't aware that the term was so religiously loaded. I was using this definition, that Twisol cited: http://en.wikipedia.org/wiki/Ontology_(information_science)

This also gives a decent definition:
http://dictionary.reference.com/browse/ontology
(browse down to "Computing Dictionary")

In other words it means "simply" (for loose definitions of simplicity) to categorize the concepts, to define their spaces and to specify the interactions between the concepts.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #166 on Fri 19 Feb 2010 05:38 AM (UTC)
Message
Right.

Back to the demo screenshot, this was really a proof of concept, that it is possible to make a MUD game more user-friendly, along the lines of what you expect these days from a MMO game.

In particular, at a glance you can see:


  • Your status (health etc.)
  • The status of party members
  • Who is grouped with you
  • Who the group leader is
  • Where you are
  • Where you can go
  • Who else is nearby, and their levels
  • What NPCs are nearby, and their levels
  • What objects are nearby (eg. loot, fountains)
  • How far until you level
  • What your general demeanor is (eg. asleep)
  • What buffs or debuffs affect you and party members, so you can do something about them
  • Who you are fighting and how the fight is going


Previously you had to type in lots of commands, or carefully monitor text as it flies by. I think it is easier to get a "situation at a glance" update, particularly if you have been distracted by chat in the meantime.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #167 on Fri 19 Feb 2010 05:42 AM (UTC)
Message
Absolutely. It's looking really good! I think an easy way to build complex miniwindows would help immensely as well... now if only I could force myself back into the miniwidget framework. (I've been too caught up with the rest of my plugin stuff)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #168 on Sat 20 Feb 2010 01:32 AM (UTC)
Message
FWIW this is the current protocol I am using ...

Groups of players


The current player, and his/her group, are sent in one message. This message has the "group" table, so that any number of members can easily be represented (eg. as [1], [2] etc.).

To identify the player for whom the message is being sent, the "me = true" boolean is true (ie. this is me).

If you are the group leader the "leader" boolean is true.

If you follow someone the "follow" field shows who that is.

For each person the "stats" sub-table identifies statistics likely to be represented in a "stats bar" (in this case HP, Mana, Move). Buffs and debuffs are in their own tables - basically just string values which the client can display.



  group = {
    [1] = {
      me = false,
      combat = false,
      leader = true,
      debuffs = {
        },
      name = "Jerirath",
      position = "standing",
      buffs = {
        [1] = "armor",
        [2] = "bless",
        [3] = "bless",
        },
      level = 4,
      xp = {
        max = 42550,
        cur = 3944,
        },
      stats = {
        Mana = {
          max = 91,
          cur = 91,
          },
        HP = {
          max = 73,
          cur = 73,
          },
        Move = {
          max = 230,
          cur = 230,
          },
        },
      },
    [2] = {
      me = true,
      combat = false,
      follow = "Jerirath",
      leader = false,
      debuffs = {
        },
      name = "Nick",
      position = "standing",
      buffs = {
        [1] = "bless",
        [2] = "bless",
        [3] = "armor",
        },
      level = 4,
      xp = {
        max = 42550,
        cur = 489,
        },
      stats = {
        Mana = {
          max = 94,
          cur = 94,
          },
        HP = {
          max = 72,
          cur = 67,
          },
        Move = {
          max = 230,
          cur = 230,
          },
        },
      },
    },


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #169 on Sat 20 Feb 2010 01:38 AM (UTC)

Amended on Sat 20 Feb 2010 02:43 AM (UTC) by Nick Gammon

Message
Contents of room


The "inroom" table is used when the room contents change, eg. players or mobs enter or leave, or something is picked up or dropped.

Inside the "inroom" table are three subtables: objects, players, npcs.

This allows the client to group or colour each subgroup differently.

Objects have a "typ" field which is a string which identifies the object type. The client may sort by type, or perhaps colour things differently (eg. a fountain may be shown in blue).

Players have a level number, a name, and a flag indicating if they are in combat. If they are in combat, the unit name they are fighting is shown.

NPCs are similar to players, and also have an aggro flag to indicate if they attack unprovoked.


  inroom = {
    dark = false,
    blind = false,
    objects = {
      [1] = {
        typ = "fountain",
        dsc = "A large marble fountain gushes forth here.",
        },
      },
    players = {
      [1] = {
        fight = false,
        lvl = 4,
        dsc = "Jerirath",
        },
      },
    npcs = {
      [1] = {
        fight = false,
        lvl = 25,
        aggro = false,
        dsc = "A Lord of Healing stands here, overseeing your progress.\n\r",
        },
      },
    },


Example 2 (during fight):


inroom = {
    dark = false,
    blind = false,
    objects = {
      [1] = {
        typ = "corpse",
        dsc = "The corpse of the gnoll lies here.",
        },
      [2] = {
        typ = "blood",
        dsc = "A pool of spilled blood lies here.",
        },
      },
    players = {
      [1] = {
        fight = false,
        lvl = 4,
        dsc = "Jerirath",
        },
      },
    npcs = {
      [1] = {
        fight = true,
        lvl = 1,
        target = "YOU!",
        aggro = true,
        dsc = "A young gnoll is here ready to attack you.\n\r",
        },
      },
    },

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #170 on Sat 20 Feb 2010 01:40 AM (UTC)

Amended on Sat 20 Feb 2010 02:37 AM (UTC) by Nick Gammon

Message
Movement


When you move a "movement" transaction is generated. This shows the name of the current room, and its vnum. It also indicates the visible exits and their vnums.


 move = {
    room = 10340,
    blind = false,
    exits = {
      north = 10325,
      },
    name = "Warriors South Cage",
    dark = false,
    },


The actual code sent is more compact than the examples indicate, but is semantically the same. For example, the movement transaction above actually looks like the following (excluding the spaces after the semicolons):


move={blind=false; dark=false; room=10340; name="Warriors South Cage"; exits={north=10325; }; }


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #171 on Sat 20 Feb 2010 01:50 AM (UTC)
Message
Unicode support


To support MUDs that may use non-Latin characters (eg. German, Greek, Chinese, Japanese, Russian - in fact most languages) the strings are encoded in UTF-8. The plugins at the MUSHclient end can display UTF-8 strings, so a minimal amount of work is needed to display in virtually any character set.

The fixup_lua_strings function used in the server can optionally convert 1-byte latin sequences to UTF-8 (as shown below). This lets players use characters in the range 0x80 to 0xFF without causing problems. It also has the side-effect of fixing up the IAC character, since the UTF-8 encoding of any character never has 0xFF in it.

The conversion to UTF-8 is optional, in case your MUD already uses UTF-8 internally, in which case you don't want to convert it twice.


// Author: Nick Gammon; 2nd February 2010
// Fixup for sending Lua-style strings to client
// Convert: \r \n double-quote IAC and ESC
// Note that Lua expects 0x00 to be sent as \0 however since this is a
// null-terminated string, we won't ever get 0x00
// Also puts quotes around result to save you the trouble of doing it.
// A NULL string returns the string "nil".

// Handles conversion to UFF-8 if UTF8_ENCODE defined
// You would normally define this unless the MUD already uses UTF-8 internally.
// http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451

#define UTF8_ENCODE

char * fixup_lua_strings (const char * sce)
  {
  const char * p;
  char * dest;
  char * pd;
  int count = 3;  // allow for quotes and final 0x00 at end
  unsigned char c;
  
  if (sce == NULL)
    {
    dest = (char *) malloc (strlen ("nil") + 1);
    strcpy (dest, "nil");  
    return dest;
    }

  // first work out how much memory to allocate
  for (p = sce; *p; p++, count++)
    {
    c = (unsigned char) *p;
#ifdef UTF8_ENCODE
    if (c >= 0x80)
      count++;   // characters 0x80 to 0xFF require 110 000xx 10 xxxxxx
    else
#endif
      switch (c)
        {
        case '\r':   // carriage-return
        case '\n':   // newline
        case '"':    // double-quote
          count++;   // becomes \r \n and \"
          break;   
        
        // Note: will not apply if UTF-8 encoding present
        case '\xFF':  // IAC becomes \255
          count += 3;  
          break;
        
       } /* end of switch on character */

    }   /* end of counting */
  
  dest = (char *) malloc (count);
  pd = dest;
  *pd++ = '"';  // opening quote
  
  for (p = sce; *p; p++)
    {
    c = (unsigned char) *p;
#ifdef UTF8_ENCODE
    if (c >= 0x80)  // characters 0x80 to 0xFF require 110 000xx 10 xxxxxx
      {
      *pd++ = 0xC0 | (c >> 6);   // 110 000xx
      *pd++ = 0x80 | (c & 0x3F); // 10 xxxxxx
      }
    else
#endif
    switch (c)
      {
      case '\r':   // carriage-return
        memcpy (pd, "\\r", 2);
        pd += 2;
        break;
         
      case '\n':   // newline
        memcpy (pd, "\\n", 2);
        pd += 2;
        break;
        
      case '"':    // double-quote
        memcpy (pd, "\\\"", 2);
        pd += 2;
        break;
      
      // Note: will not apply if UTF-8 encoding present
      case '\xFF': // IAC
        memcpy (pd, "\\255", 4);
        pd += 4;
        break;
      
      default:
        *pd++ = c;
         break;  

      } /* end of switch on character */

     }   /* end of copying */
  
  *pd++ = '"';  // closing quote
  *pd = 0;      // terminating 0x00
  
  return dest;
}

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #172 on Sat 20 Feb 2010 02:54 AM (UTC)
Message
Just to elaborate a bit, I got rid of the idea of transaction types (which were possibly limiting anyway), and replaced them with high-level tables. The presence of a table indicates data relating to that. And by having multiple tables, fields like "name" are not confusing (ie. is name the name of a room, a player or a mob?).

So far we have:


  • inroom --> room contents
  • move --> room vnum, name, exits
  • group --> current player and his/her group
  • victim --> the unit being attacked by the current player
  • version --> simply the server version number
  • hint --> hints for displaying things like status bars

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #173 on Sat 20 Feb 2010 03:07 AM (UTC)
Message
Great! This is the kind of thing I was looking for when I suggested letting tt look like "package.message". At this point, I would also suggest allowing (even enforcing) transaction tables to be in package tables, to allow for a simple kind of namespacing.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #174 on Sat 20 Feb 2010 03:19 AM (UTC)
Message
Not sure what you mean by "transaction tables to be in package tables" but I agree the tables are a form of namespace.

For example, move.name is a different variable to victim.name.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #175 on Sat 20 Feb 2010 03:44 AM (UTC)
Message
I mean something like... well, lets assume something like ZMP's packages:

-- package table
subwindow = {}

subwindow.open = {
  name = "name",
  title = "title",
  width = 50,
  height = 50,
}


It's just a way to package related commands together so they don't clash, as long as the namespace/package name is unique.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #176 on Sat 20 Feb 2010 03:52 AM (UTC)
Message
Isn't that exactly what I did? And if not, in what way?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #177 on Sat 20 Feb 2010 03:57 AM (UTC)
Message
This all looks pretty nifty.

Is this an appropriate time to start hashing out small details? For example, the 'follows' thing should probably be based on a number of the group member, so that a group may contain NPCs with the same name. Or, the 'type' should be flag-based, not necessarily a simple type, as one could easily imagine things having several categories at once, e.g. "provides water" and "is movable".

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #178 on Sat 20 Feb 2010 04:02 AM (UTC)

Amended on Sat 20 Feb 2010 04:04 AM (UTC) by Twisol

Message
Nick Gammon said:

Isn't that exactly what I did? And if not, in what way?


*shake* Your transactions are all single, like "inroom" and "move" and "group". The example I gave, "subwindow.open", is a message (open) within a namespace (subwindow).

EDIT: This is entirely separate from the parameters themselves. You mentioned "victim.name" and "move.name", but name isn't a message. It's just a tagged piece of data that's important to a message.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #179 on Sat 20 Feb 2010 04:11 AM (UTC)
Message
Certainly we may as well get as many details solid as possible. :)

Can you group with NPCs? You can't in WoW. Or at least, you can't follow them, you get a message "you can't follow that unit".

As for the group number, I like the concept, but the problem is you can follow someone but not group with them (in Smaug and indeed in WoW too). Thus they wouldn't have a group number.

It would be nice if units had GUIDs but I doubt they have that, or do they?

As for item flags, I initially wanted to get away from sending "magic numbers" since that would tend to tie the resulting plugin to a particular MUD (eg. item type 15 is water). Thus I sent "water" instead. This allows for simple grouping (ie. you can put all the wet things together, and colour them blue).

I'm not sure what you would do, in a simple display (eg. room contents) that would require multiple flags (eg. is water, can be carried, and can be drunk). This sounds more like the level of detail you might want if you examine something.

Of course, this opens up a whole new can of worms - the idea you might mouse-over a unit and find out heaps of extra stuff (eg. class, race, alignment, reputation, level, email address etc.). This is hardly the sort of stuff you want to transmit to every client every moment someone enters a room.

The way WoW seems to do it, and the way I had an inventory plugin for Aardwolf working quite well a while back, was to only send a minimal amount of data, one of which was the GUID of the item (Global Unique ID). Then you might have a short inventory list that simply had a list of GUIDs.

When you mouse over an item the client sends back a message like "send me details on item 878989823423) and the server responds with a more detailed message, which the client then caches. This actually worked quite quickly and was pretty responsive - there was a slight delay the first time you looked at an item, and after that it was instant. Of course, nowadays you might use SQLite3 database to quickly store that sort of stuff.

It can all be made to work, and indeed I think is worth doing. However even without getting into that level of detail my initial tests indicate a quite responsive system. And I have to say it is F-U-N fun!

Being able to glance at the screen, and take in the basic information about who you are with, their status, if you are fighting or not, and if so, how the battle is going, gives the whole thing a sort of fun immediacy which gets you involved in it.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


928,612 views.

This is page 12, subject is 23 pages long:  [Previous page]  1  2  3  4  5  6  7  8  9  10  11  12 13  14  15  16  17  18  19  20  21  22  23  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.