Standards:GMCP Client Variables
GMCP Client Variables Sharing Standard
Overview and Rationale
The GMCP Client Variables Sharing extension standardizes how client-specific variables are exchanged between MUD clients and servers. This enables servers to dynamically adjust gameplay based on client data, enhancing the user experience.
Rationale
As MUDs become more complex, the need for customizable and dynamic interactions between clients and servers has grown. Sharing client-specific variables allows for personalized gameplay experiences, seamless UI adjustments, and improved accessibility features. By standardizing this exchange, the GMCP Client Variables Sharing extension ensures that all participants in the MUD ecosystem can benefit from enhanced communication and data sharing.
Consent Management Process
User consent is essential for sharing client-specific variables. Ensure users are informed about the data being shared and retain control over their personal information. This exchange of information is geared towards finding out what data is available in the client, receiving only what is needed from the server or script, and prompting the user for variables where consent is necessary and the variables are desired.
Specification for Client.Variables
Commands
Client.Variables.Default
Purpose: Sent by the server to confirm support for the Client.Variables
namespace. The client responds with a Client.Variables.List
message. The server’s acknowledgment is typically asynchronous, while the client’s response is synchronous.
Client.Variables.Default {}
Client.Variables.List
Purpose: Lists available client variables, their types, and attributes. The server may asynchronously request specific variables via Client.Variables.Request
.
Attribute | Description | Value | Required |
---|---|---|---|
name | Client variable identifier. | (text) | Yes |
type | The data type of the variable. | see Supported Types table | Yes |
available | Indicates if the variable is available for use. Values that require consent default to false .
|
true or false
|
Yes |
updatable | Indicates if the variable can be updated by the server. | true or false
|
Yes |
Type | Description |
---|---|
"string"
|
A sequence of characters. |
"number"
|
Any numeric value, including integers and floating-point numbers. |
"integer"
|
A numeric value without a fractional part (whole number). |
"boolean"
|
A value that can be either true or false. |
"array"
|
A list of values, where each value can be of any type. |
"object"
|
A set of key-value pairs, where the keys are strings and the values can be of any type. |
"null"
|
A value representing null .
|
In the following example, consent will be required for the four variables that are "available": false
.
Client.Variables.List [
{"name": "256_COLORS", "type": "boolean", "available": true, "updatable": false},
{"name": "ANSI", "type": "boolean", "available": true, "updatable": false},
{"name": "BOLD_IS_BRIGHT", "type": "integer", "available": true, "updatable": true},
{"name": "CHARSET", "type": "string", "available": true, "updatable": true},
{"name": "CLIENT_NAME", "type": "string", "available": true, "updatable": false},
{"name": "CLIENT_VERSION", "type": "string", "available": true, "updatable": false},
{"name": "LANGUAGE", "type": "string", "available": false, "updatable": false},
{"name": "MTTS", "type": "integer", "available": true, "updatable": false},
{"name": "OSC_COLOR_PALETTE", "type": "boolean", "available": true, "updatable": false},
{"name": "SCREEN_READER", "type": "boolean", "available": false, "updatable": false},
{"name": "SYSTEMTYPE", "type": "string", "available": false, "updatable": false},
{"name": "TERMINAL_TYPE", "type": "string", "available": true, "updatable": false},
{"name": "TLS", "type": "boolean", "available": true, "updatable": false},
{"name": "TRUECOLOR", "type": "boolean", "available": true, "updatable": false},
{"name": "USER", "type": "string", "available": false, "updatable": false},
{"name": "UTF-8", "type": "boolean", "available": true, "updatable": false},
{"name": "VT100", "type": "boolean", "available": true, "updatable": false},
{"name": "WORD_WRAP", "type": "integer", "available": true, "updatable": false}
]
Client.Variables.List
is a schema of all variables. It does not include the values of variables.
Client.Variables.Request
Purpose: The server requests specific client variables with Client.Variables.Request
. The client synchronously responds with a Client.Variables.Update
message.
The client tracks variables requested via Client.Variables.Request
throughout the current connection. For the client to process updates—whether initiated by the server or by changes within the client—the variable must be referenced here.
Attribute | Description | Value | Required |
---|---|---|---|
name | Client variable identifier. | (text) | Yes |
purpose | Reason for collecting the information. | (text) | No |
Encourage user consent by including a custom message in the purpose
attribute, explaining why the information is collected. Limit the length of the value for the purpose
attribute to 250 characters or less.
Client.Variables.Request [
{"name": "BOLD_IS_BRIGHT"},
{"name": "CHARSET"},
{"name": "LANGUAGE", "purpose": "Match client language to optimize game and UI content"},
{"name": "SCREEN_READER", "purpose": "Enable accessibility features for game and UI"},
{"name": "SYSTEMTYPE", "purpose": "Adjust game and UI elements based on operating system"},
{"name": "USER", "purpose": "Identify client account and character to the server"}
]
Client.Variables.Update
Purpose: Client sends updates for requested variables. The source
attribute indicates whether the update is due to a request
, client
action, or server
initiation. The requested
attribute should only be sent in response to Client.Variables.Request
.
Attribute | Description | Value | Required |
---|---|---|---|
name | Client variable identifier. | (text) | Yes |
available | Indicates if the variable is available for use. | true or false
|
Yes |
updatable | Indicates if the variable can be updated by the server. | true or false
|
Yes |
requested | Indicates if the variable was requested by the server. | true or false
|
Yes |
source | Indicates the source of the update. | request or client or server
|
Yes |
timestamp | Unix timestamp indicating when the update was made. | 10-digit (or less) number | Yes |
success | Indicates if an updatable variable changed. | true or false
|
Only sent in response to Client.Variables.Set messages. |
value | The value of the variable. | When available is true and a value exists.
|
Client.Variables.Update [
{"name": "BOLD_IS_BRIGHT", "available": true, "updatable": true, "requested": false, "source": "request", "timestamp": 1721495879, "value": 2},
{"name": "CHARSET", "available": true, "updatable": true, "requested": false, "source": "request", "timestamp": 1721495879, "value": "UTF-8"},
{"name": "LANGUAGE", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "SCREEN_READER", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "SYSTEMTYPE", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "USER", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879}
]
Client Prompting Example
Client.Variables.Set
Purpose: Server sets previously requested
, updatable
client variables. The client responds synchronously with Client.Variables.Update
, marking the source
as server
.
Attribute | Description | Value | Required |
---|---|---|---|
name | Client variable identifier. | (text) | Yes |
value | The value of the variable. | (varies) | Yes |
// Client request with a valid and invalid value
Client.Variables.Set [
{"name": "BOLD_IS_BRIGHT", "value": 1},
{"name": "CHARSET", "value": "DEEP-6"}
]
// Server response to a valid and invalid value
Client.Variables.Update [
{"name": "BOLD_IS_BRIGHT", "available": true, "updatable": true, "source": "server", "timestamp": 1721495900, "success": true, "value": 1},
{"name": "CHARSET", "available": true, "updatable": true, "source": "server", "timestamp": 1721495900, "success": false, "value": "DEEP-6"}
]
Implementation Considerations
- Client Support Advertisement: Clients should advertise their support for the Client.Variables namespace using
Core.Supports.Set
. - Server Acknowledgement: Servers acknowledge support with
Client.Variables.Default
. - Consent Management: Clients must handle user consent for sharing sensitive or personal data variables. Prompts should inform users of requested data and allow them to opt-in or block requests.
- Blocked Variables: Clients should not share a variable previously blocked by a user in
Client.Variables.List
messages, nor make the variable available to other protocols, such as NEW-ENVIRON, MNES, and MTTS. If a variable that was"available": true
is changed to"available": false
, the client should update other protocols accordingly (e.g., send an EMPTYVAL
with NEW-ENVIRON or update MTTS to a 0 bit for the variable). - Variable Naming Convention: Variables should be transferred in uppercase to maintain consistency and avoid issues with case sensitivity.
- Types: When defining client variables in
Client.Variables.List
, ensure that each variable includes the"type"
attribute. This attribute specifies the data type of the variable, ensuring proper handling and validation on both the client and server sides. - Legacy Support: Game drivers may not be able to send boolean values. Where boolean values are expected, clients will transform
"true"
or1
totrue
, and"false"
or0
tofalse
.
Example Flow
1. Client: Should advertise support.
Core.Supports.Set ["Client.Variables 1", ...]
2. Server: May acknowledge support.
Client.Variables.Default {}
3. Client: Must send available variables list. Variables previously blocked by the user should not be sent.
Client.Variables.List [
{"name": "256_COLORS", "available": true, "updatable": false},
{"name": "ANSI", "available": true, "updatable": false},
{"name": "BOLD_IS_BRIGHT", "available": true, "updatable": true},
{"name": "CHARSET", "available": true, "updatable": true},
{"name": "CLIENT_NAME", "available": true, "updatable": false},
{"name": "CLIENT_VERSION", "available": true, "updatable": false},
{"name": "LANGUAGE", "available": false, "updatable": false},
{"name": "MTTS", "available": true, "updatable": false},
{"name": "OSC_COLOR_PALETTE", "available": true, "updatable": false},
{"name": "SCREEN_READER", "available": false, "updatable": false},
{"name": "SYSTEMTYPE", "available": false, "updatable": false},
{"name": "TERMINAL_TYPE", "available": true, "updatable": false},
{"name": "TLS", "available": true, "updatable": false},
{"name": "TRUECOLOR", "available": true, "updatable": false},
{"name": "USER", "available": false, "updatable": false},
{"name": "UTF-8", "available": true, "updatable": false},
{"name": "VT100", "available": true, "updatable": false},
{"name": "WORD_WRAP", "available": true, "updatable": false}
]
4. Server: May requests specific variables. Once per connected session, the client may prompt the user with a request to share variables that are "available": false
from the Client.Variables.List
message.
Client.Variables.Request [
{"name": "BOLD_IS_BRIGHT"},
{"name": "CHARSET"},
{"name": "LANGUAGE", "purpose": "Match client language to optimize game and UI content"},
{"name": "SCREEN_READER", "purpose": "Enable accessibility features for game and UI"},
{"name": "SYSTEMTYPE", "purpose": "Adjust game and UI elements based on operating system"},
{"name": "USER", "purpose": "Identify client account and character to the server"}
]
5. Client: Updates requested variables.
Client.Variables.Update [
{"name": "BOLD_IS_BRIGHT", "available": true, "updatable": true, "requested": false, "source": "request", "timestamp": 1721495879, "value": 2},
{"name": "CHARSET", "available": true, "updatable": true, "requested": false, "source": "request", "timestamp": 1721495879, "value": "UTF-8"},
{"name": "LANGUAGE", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "SCREEN_READER", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "SYSTEMTYPE", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879},
{"name": "USER", "available": false, "updatable": false, "requested": true, "source": "request", "timestamp": 1721495879}
]
Flow Diagrams
Requesting and Receiving Variables
Receiving Variable Updates
Setting Updatable Variables
Client Examples
Prompting an end user to consent to share sensitive or personal variables from the game client
Handling response to client requests for sharing sensitive or personal variables
Conclusion
The GMCP Client Variables Sharing extension standardizes the exchange of client-specific variables, ensuring seamless integration and enhanced user experiences. Adopting this standard streamlines variable management, enhances client-server communication, and enables more personalized gaming experiences.
Versions
- Version 1.0: Initial specification.
Authors
- Mike Conley (Tamarindo, Administrator at StickMUD and Mudlet contributor) mike.conley[at]stickmud.com
Notes
- This specification is subject to updates and community input. Contributions and feedback are welcome to ensure it meets the needs of the MUD community in the #mudlet-development channel of the Mudlet Discord.
- Implementation should follow GMCP protocol specifications, and all messages must be well-formatted JSON objects.