GMCP 数据规范与最佳实践

概述

GMCP (Generic MUD Communication Protocol) 是 MUD 客户端与服务器之间的标准化数据通信协议,基于 JSON 格式,用于提供丰富的客户端界面体验。也特别适合用于开发移动端游戏的数据交互。

GMCP(Generic MUD Communication Protocol)主要用于以下核心场景:

  1. 实时状态同步

    • 角色面板:HP、MP、内力、食物、潜能等实时数值
    • 战斗状态:当前目标、战斗计时、技能冷却
    • 装备信息:武器、防具、饰品的状态和耐久度
  2. 环境信息推送

    • 地图数据:当前房间坐标、相邻房间、区域信息
    • 天气系统:实时天气变化、时辰流转
    • NPC信息:周围NPC列表、商店物品、任务状态
  3. 客户端增强功能

    • 自动地图:根据GMCP数据绘制实时地图
    • 状态栏:显示角色关键属性,无需频繁输入score
    • 快捷栏:技能、物品的快速使用界面
    • 任务追踪:自动显示当前任务目标和进度
  4. 个性化客户端

    • 界面定制:字体、颜色、布局的个性化设置
    • 快捷键配置:玩家自定义的键盘映射
    • 数据持久化:客户端记住玩家的偏好设置

核心模块规范

1. Char.Vitals - 角色状态数据

{
  "hp": 1000,
  "max_hp": 1000,
  "mp": 500,
  "max_mp": 500,
  "jing": 400,
  "max_jing": 400,
  "neili": 800,
  "max_neili": 1000,
  "food": 200,
  "max_food": 300,
  "water": 180,
  "max_water": 300,
  "exp": 1250000,
  "pot": 50000,
  "level": 25,
  "combat_exp": 850000
}

2. Room.Info - 房间信息

{
  "name": "扬州城-客店",
  "short": "客店",
  "area": "扬州城",
  "zone": "江南",
  "exits": ["north", "south", "east", "west"],
  "coord": [120, 85, 0],
  "description": "这是一间整洁的客店...",
  "indoors": true,
  "light": 8,
  "terrain": "building"
}

3. Char.Status - 战斗状态

{
  "state": "peace|fighting|busy|unconscious",
  "target": "bandit",
  "combat_round": 3,
  "busy_timer": 2.5,
  "conditions": ["poisoned", "injured"]
}

4. Char.Skills - 技能信息

{
  "skills": {
    "force": {"level": 120, "exp": 8500, "max": 200},
    "sword": {"level": 95, "exp": 3200, "max": 150},
    "dodge": {"level": 110, "exp": 6800, "max": 180}
  }
}

5. Char.Equipment - 装备信息

{
  "weapon": {"id": "sword", "name": "青锋剑", "damage": 150, "durability": 85},
  "armor": {"id": "cloth", "name": "粗布衣服", "defense": 50, "durability": 100},
  "accessories": [
    {"slot": "neck", "name": "玉佩", "effects": ["+5 dex"]}
  ]
}

6. Comm.Channel - 频道信息

{
  "channels": ["chat", "rumor", "party", "guild"],
  "listening": ["chat", "party"]
}

扩展模块

7. Char.Inventory - 背包信息

{
  "items": [
    {"id": "potion", "name": "金创药", "quantity": 5, "type": "healing"},
    {"id": "book", "name": "九阳真经", "quantity": 1, "type": "skill_book"}
  ]
}

8. Quest.Info - 任务信息

{
  "active": [
    {
      "id": "kill_bandit",
      "title": "剿灭土匪",
      "desc": "杀死10名山贼",
      "progress": "7/10",
      "reward": "1000经验"
    }
  ]
}

数据格式规范

命名规范

  • 使用 snake_case(小写+下划线)
  • 模块名使用首字母大写的驼峰命名
  • 字段名使用小写字母

数据类型

  • 数值:整数(血量、等级)或浮点数(坐标)
  • 字符串:使用 UTF-8 编码
  • 布尔值:true/false
  • 数组:用于列表数据(出口、技能列表)

推送策略

推送时机

模块 触发时机 频率
Char.Vitals 状态变化时 实时
Room.Info 移动到新房间 事件
Char.Status 战斗状态变化 事件
Char.Skills 技能提升时 事件
Char.Equipment 装备更换时 事件

推送格式

服务端发送: send_gmcp("模块名 " + json_encode(数据))
客户端接收: {"module": "模块名", "data": {...}}

服务端实现规范

基础函数

// 检查客户端是否支持GMCP
int has_gmcp(object user)

// 发送GMCP数据
void send_gmcp(string message)

// 接收GMCP数据(apply函数)
void gmcp(string message)

实现示例

// 发送角色状态
void send_vitals() {
    mapping vitals = ([
        "hp": query("hp"),
        "max_hp": query("max_hp"),
        "mp": query("mp"),
        "max_mp": query("max_mp"),
        "exp": query("combat_exp"),
        "pot": query("potential")
    ]);

    if (has_gmcp(this_player())) {
        send_gmcp("Char.Vitals " + json_encode(vitals));
    }
}

// 发送房间信息
void send_room_info() {
    object env = environment(this_player());
    if (!env) return;

    mapping room = ([
        "name": env->query("short"),
        "area": env->query("area"),
        "exits": keys(env->query("exits")),
        "coord": env->query("coord") || ({0, 0, 0})
    ]);

    if (has_gmcp(this_player())) {
        send_gmcp("Room.Info " + json_encode(room));
    }
}

客户端处理规范

数据解析

// 解析GMCP数据
function handleGMCP(data) {
    try {
        const spaceIndex = data.indexOf(' ');
        const module = spaceIndex > -1 ? data.substring(0, spaceIndex) : data;
        const jsonData = spaceIndex > -1 ? data.substring(spaceIndex + 1) : '';

        if (jsonData) {
            const parsed = JSON.parse(jsonData);
            processGMCPModule(module, parsed);
        }
    } catch (e) {
        console.error('GMCP解析错误:', e);
    }
}

// 处理不同模块
function processGMCPModule(module, data) {
    switch(module) {
        case 'Char.Vitals': updateStatusBar(data); break;
        case 'Room.Info': updateRoomDisplay(data); break;
        case 'Char.Skills': updateSkillsPanel(data); break;
        // ... 其他模块
    }
}

向后兼容

版本控制

{
  "version": "1.0.0",
  "min_version": "0.9.0",
  "features": ["vitals", "room", "skills"]
}

字段扩展

  • 新增字段必须向后兼容
  • 旧字段不得删除或修改含义
  • 使用可选字段而非必填字段

性能优化

数据压缩

  • 使用短字段名(生产环境)
  • 批量推送相关数据
  • 避免频繁推送大数据

网络优化

  • 状态类数据:变化时推送
  • 信息类数据:请求时推送
  • 缓存静态数据

错误处理

服务端

// 错误处理
void send_gmcp_error(string module, string error) {
    send_gmcp("Error " + json_encode(([
        "module": module,
        "error": error,
        "timestamp": time()
    ])));
}

客户端

// 错误处理
try {
    const data = JSON.parse(jsonData);
} catch (e) {
    console.warn(`GMCP解析失败 [${module}]:`, e.message);
    // 静默失败,不影响正常游戏
}

测试建议

服务端测试

  1. 启用GMCP功能
  2. 测试数据推送时机
  3. 验证数据格式正确性
  4. 检查向后兼容性

客户端测试

  1. 验证数据解析
  2. 测试界面更新
  3. 检查错误处理
  4. 性能压力测试

相关文档

京ICP备13031296号-4