奖励Reward系统设计

介绍

一般来说系统前期,发放奖励,就简单的发放道具就可以,基本上是,遇到一个配置一个,不同的系统可能配置的方法不一样,每次活动更是加不同的配置。

经历里这些不同的需求,我们需要设计一个系统它可以统一的管理这些,满足各种奖励需求。

配置

Reward

|----------|----------|---|---|---|
| RewardId | GroupIds | | | |
| 奖励id | 组列表 | | | |
| | | | | |

可以在导表中将Item表中的数据直接放入这里,可以很方便的配置道具,这里每个组必定产出一个物品

RewardGroup

|---------|---------|------------------|---------|---|
| GroupId | ItemIds | GroupItemRuleIds | Weights | |
| 组id | 道具id列表 | 道具规则列表 | 权重列表 | |
| | | | | |

ItemIds:

GroupItemRuleIds:

两个列表一一对应,每个ItemId 对应一个RuleId,可以重复使用相同的RuleId

RewardGroupItemRule

|-----------------|----------|----------|---|---|
| GroupItemRuleId | MinCount | MaxCount | | |
| 道具规则id | 单次产出最小值 | 单次产出最大值 | | |
| | | | | |

每次产出的数量范围[MinCount, MaxCount], 具体结合业务,一般需要结合 ItemOutputCount, 才能推出实际可以产出的数量

ItemOutputCount

|--------|-----------------|-------------------|---|---|
| ItemId | UserGotMaxCount | GlobalGotMaxCount | | |
| 道具id | 玩家历史产出总计最大数量 | 全服历史产出总计最大数量 | | |
| | | | | |

控制一些道具的产出,实际情况下很少使用 ^ ^,但是如果在表里配置了相关的itemId, 并且设置一个很大的数量值,这个也可以作为道具的产出记录使用

功能点

全局产出控制

个人产出控制

每个Item 产出时,必须先检查 ItemOutputCount 表中的 全服历史产出总计最大数量 -> 玩家历史产出总计最大数量如果产出已经到达上限,则这个道具的产出为0

动态权重

根据配表 RewardGroup 中的 的 Weights 来计算, 具体算法如下,每个道具有个数字来表示它的权重,查看一些负载均衡算法的应该熟悉则这个,这个算是最简单的分配算法了

cs 复制代码
int GetIndexByWeights(List<int> weights)
{
    int sum = 0;
    for(int i = 0; i < weights.Count; ++i){
        sum += weights[i];
    }

    if(sum == 0) return -1;

    // [0.0, 1.0)
    int roundWeight = Random.Shared.Next(1, sum + 1);

    sum = 0;
    for(int i = 0; i < weights.Count; ++i){
        sum += weights[i];
        if(sum >= roundWeight) return i;
    }

    return -1;
}

// 根据规则修改权重
List<int> CheckRestictedItemAndModifyWeight(List<uint> itemIds, List<int> weights)
{
    // 检查全局 道具产出限制
    
    // 检查个人 道具产出限制

    // 这里可能存在费时的操作,根据具体业务处理
}

(uint itemId, int count) GetOuputItemIdAndCountByWeigths(List<uint> itemIds, List<int> weights)
{
    List<int> newWeights = CheckRestictedItemAndModifyWeight(itemIds, weights);

    var index = GetIndexByWeights(newWeights);

    var itemId = itemIds[index];
    
    // 1.先根据 RewardGroupItemRule 计算产出数量
    // 2.结合 全局、个人产出限制,计算产出数量
    return (itemId, count)
}

奖励流程

cs 复制代码
List<RewardData> GetReward(uint rewardId)
{
    // 根据配表获取产出道具

    // 解析产出道具,一般来说这里会处理一些 道具分解、替换的流程

    // 真正的创建道具,结合业务创建相关物品
    
    // 推送相关信息
}

总结

后期一般,如果做了这个功能,就会慢慢的替换直接添加Item的操作,保证添加Item只有一个入口就是在奖励处

相关推荐
软件资深者8 天前
植物大战僵尸1经典版(小游戏)+超强辅助工具 自动收取阳光
windows·游戏程序·windows11
孟无岐9 天前
【Laya】Socket 使用指南
websocket·typescript·游戏引擎·游戏程序·laya
Watermelo61710 天前
随机扣款实现赛博共产主义,《明日方舟:终末地》公测支付事故复盘
数据库·后端·游戏程序·技术美术·用户体验·游戏策划·游戏美术
晚霞的不甘10 天前
Flutter 方块迷阵游戏开发全解析:构建可扩展的关卡式益智游戏
前端·flutter·游戏·游戏引擎·游戏程序·harmonyos
孟无岐13 天前
【Laya】HttpRequest 网络请求
网络·typescript·游戏引擎·游戏程序·laya
孟无岐13 天前
【Laya】LocalStorage 本地存储
typescript·游戏引擎·游戏程序·laya
怣疯knight14 天前
外部类触发角色状态切换
游戏程序
孟无岐15 天前
【Laya】Byte 二进制数据处理
网络·typescript·游戏引擎·游戏程序·laya
孟无岐15 天前
【Laya】ClassUtils 类反射工具
typescript·游戏引擎·游戏程序·laya
孟无岐16 天前
【Laya】Ease 缓动函数
typescript·游戏引擎·游戏程序·laya