GMCP is handlet a little bit differently in different clients. E.g. in CMUD it is considered an event, and is handled with event handlers. While in CMUD it is considered a special form of trigger. Also access to the properties are not always the same.
Both clients will "cache" previous values, so this is important when it comes to gmcp objects where the contents/properties change pr fire.
Below i will try to create examples for common use cases in Mudlet and CMUD.
While a super will fire if a sub event is sent, That does not mean that all the data on the super is updated, or indeed, available. Therefore, a set of best practices have been described below. |
It is recommended best practice to make the event handlers as small as possible, reacting to the "lowest possible" sub module because of this. Also that the handler only uses data from its own "node" and "downwards"
Example:
For the same reasons above, it is important that each handler only has awareness of the data "below it". Otherwize you will quickly encounter crashes or missing data due to the sparse nature of the protocol. If you need data from other parts of the tree, use Caching.
Example:
It is common that you want to access data from other parts of the gmcp tree in one of the handlers. E.g. you might want to access gmcp.Char.Status.name inside gmcp.Group.Party, or from within the gmcp.Action.Round.
As this can easily cause crashes and undeterministic behaviour due to the sparseness of the data, it is therefore recommended that for such use cases, you cache the inbound data to a global variable/hierarchy.
Note that this is primarily a challenge when communicating across trees, and less of a problem when navigating upwards in the same tree. However, the protocol does not enforce update of a super object when a child is sent, so consider this a general best practice!
Example:
As you don't have control over the frequency of the gmcp events, it is generally a bad practice to have the gmcp handler update gui objects like gauges, buttons or screens.
Example:
To prevent lagging your client, it is recommended that you handler "does as little as possible", generally store the data, then move on. Then do heavier tasks on the data in cyclic processes outside of the event itself.
You can use the "display" command to output the full, or parts of the gmcp tree, or print/echo to print out a single property.
Examples:
In Mudlet, a gmcp packet is considered an event. The events are named with dotted syntax. e.g. gmcp.Room or gmcp.Char.Vitals
Note that capitilization is important.
A "sub handler" will only fire on the specific event, while a "super" will fire on all sub events. E.g.
There are two main ways to setup handlers for events in Mudlet. I recommend reading the documentation for the Mudlet Event_Engine for details, but i will brifely describe the methods here:
handlerId = registerAnonymousEventHandler("gmcp.Char.Vitals", "processCharVitals")
Note! make sure to save the handlerid, and check for its existance before you register a handler when usign this method, otherwize you might get multiple fires pr event
Note! I do not recomment method 2 unless you are very experienced with Lua and event programming. This is because it is VERY easy to get into a state where the handler will fire multiple times. |
To use GMCP in CMUD, you use Triggers,