道具系统
创建:2025-04-24 22:27
更新:2025-04-27 22:50

在游戏系统中,资源、宝箱、功能道具、装备、抽卡角色、宠物等等都属于道具的一部分。换一句话来说一切可以奖励的内容都属于道具的一部分。在整个道具系统的id都需要唯一。也就是说需要按照功能进行id分段。例如道具(资源,宝箱,功能道具)id段时[100000~199999], 装备id段是[200000-299999]

在设计接口的时候需要考虑的是:

  1. 简洁的接口,不需要使用者理解道具内部的流程逻辑。特别是游戏系统中存在大量的奖励发放逻辑
  2. 需要注意一次可能加多个道具,分别属于不同系统(常见于抽奖10连)。此时需要考虑前后添加是否会导致累计失败。需要根据策划要求判断失败是导致操作失败,还是邮件补发
  3. 需要支持道具的自动打开. 因为蛋蛋 奖励->道具 对于很多内容是无法操作的。必须能够支持 奖励->道具->奖励.. 这样的自动嵌套逻辑
  4. 尽可能通过注册的方式让各个系统注册自己的逻辑,而不是都来道具系统写东西,导致代码混乱
  5. check和实际操作接口要分离。例如一个流程: 是否可以扣除金币+检查是否可以添加=>扣除道具+添加 如果接口不分离则会导致部分成功,数据出现错误。这也是所有的请求处理需要保证的一点,也就是 一旦开始修改数据,则不允许失败

表定义

# 道具表

id段位 10000+x

ID 定义 名称 使用功能 功能参数 自动打开 级别 背包显示 图标 每日获取上限 拥有上限 描述 获取渠道 时间限制
int string enum int[5] bool enum int path int int text int time
100001 k_gold 金币 稀有 99999999 99999999
100002 一个宝箱 奖励 1 true 稀有

# 装备表

id段位 20000+x

ID 名称 ...
int string ...
200001 测试装备 ...

# 奖励表(掉落表)

ID 定义 用途 名称 随机物品列表 随机物品数量(max=0表示固定取min) 权重 随机次数 可重复获得
int string ref>item[10] {min:int, max:int}[10] int[10] int bool
1 100001 100

实现

// 纯道具,例如:金币钻石等资源,未打开的宝箱等,功能道具等等
struct user_item {
    int res_id; 
    int num;     // 数量
    int expire_time; // 过期时间
    short solt; // 槽位(有些游戏不自动排序)
    short solable; // 可交易次数(有些游戏道具存在交易次数限制)
};
struct user_items {
    struct user_item items[k_item_max];
    int items_count_;
};

// 装备
struct user_equip {
    int64 gid; // 与道具id对应
    struct {
        int attr;
        int val
    } attrs[4]; // 装备属性
    int attrs_count_;
    char wear; // 是否穿戴
    ...
};
struct user_equips {
    struct user_equip equips[100];
    int equips_count_;
    int gid_seq;
};

一般游戏系统会要求所有发奖必须强制成功,超出部分走邮件。则道具系统设计如下:

void item_on_login(struct game_user* user); // 登录时清理过期道具等操作
int item_get_num(struct game_user* user, int item_id);
bool item_reduce_check(struct game_user* user, int item_id, int item_num);
bool item_reduce(struct game_user* user, int item_id, int item_num, int reason, const char* code_func_where);

struct item_list {
    int64 seed; // 统一使用这个种子去随机
    ... // 其他需要记录的固定值,例如等级,世界等级等等,方便邮件固定下来奖励
    // 这里记录失败的item_id, item_num
    struct {
        int id;
        int num;
    } items;
    int items_count_;
    // 下边记录成功后的结果
    struct user_item items;
    struct user_equip equips;
};
bool item_add(struct game_user* user, struct item_list* list, int item_id, int item_num); // 打开并且check,这里不进行实际的添加逻辑
bool item_add_finnal(struct game_user* user, struct item_list* list, int reason, const char* code_func_where);
bool reward_add(struct game_user* user, int reward_id);

void item_list_register(int type, func check, func add); // 各种道具系统(资源,装备,宠物,角色等等)注册对应的处理检查函数和添加函数

如果不需要强制添加成功,失败则操作失败,不走邮件,那么道具系统设计如下:

void item_on_login(struct game_user* user); // 登录时清理过期道具等操作
int item_get_num(struct game_user* user, int item_id);
bool item_reduce_check(struct game_user* user, int item_id, int item_num);
bool item_reduce(struct game_user* user, int item_id, int item_num, int reason, const char* code_func_where);

struct item_list {
    struct user_item items;
    struct user_equip equips;
};
bool item_list_add_check(struct game_user* user, struct item_list* list, int item_id, int item_num); // 打开并且check
bool item_list_add(struct game_user* user, struct item_list* list, int reason, const char* code_func_where);
bool reward_add_check(struct game_user* user, struct item_list* list, int reward_id); // 打开奖励且不进行实际的添加

void item_list_register(int type, func check, func add); // 各种道具系统(资源,装备,宠物,角色等等)注册对应的处理检查函数和添加函数