美文网首页
德洲扑克技术设计的思考过程

德洲扑克技术设计的思考过程

作者: 2016晓 | 来源:发表于2023-11-21 19:10 被阅读0次

    德洲扑克算得上部门已有游戏中最复杂的一款。流程设计难点包括以下几点:
    1、筹码购买、退回,保持钱包的扣币、发币一致;
    2、游戏中操作的来源不但有荷官、玩家的人为操作,还有超时、玩家的AUTO模式自动操作;
    3、多种操作同时进行时,避免并发下产生失败、数据覆盖。
    另外牌力算法也较为复杂,但与游戏流程是解耦的,不作为本文的论点。

    本次我比较满意的两点设计:
    1、超时逻辑的上下文更新,放在读取时幂等计算
    2、使用事件队列+回放

    以上难点都属于一致性问题,这种问题本质上,是处理数据的读写时序。
    客户端某个时刻获取到用于渲染游戏页面内容可以称作“帧”,后端维护的游戏完整状态内容可以称作“上下文”。游戏过程中,各种操作就是对上下文的修改,客户端获取的帧数据,由上下文进一步处理得到(主要是精简出端上需要的数据)。

    适当处理上下文读写成为关键。
    最无脑的方式,就是redis中直播存放上下文完整数据结构,每次读写时进行分布式加锁。但加锁失败的场景也后较多出现,后续若补偿重试也可能会再次加剧锁争抢。同时游戏逻辑中玩家操作超时对游戏进程影响较大,需要尽力保证及时处理,避免延时。另外兑换筹码又是一种分布式事务,一个玩家兑换过程中(涉及调用钱包服务),其他玩家无法兑换十分影响体验。

    玩家操作超时,可以单独进行一种优化:操作超时产生的对上下文的改动,不进行实际的上下文更新。而是在上下文读取后,使用上下文中的最后更新时间+当前时间,幂等计算出一份各种超时逻辑影响后的有效上下文。(增加了读取时的计算逻辑,省略了超时发生时的写入)

    难以避免锁的根本原因是将上下文更新实现为了全量写入,因而需要保证某个操作处理时,读取-变更字段-写入这个过程不存在并发。但如果上下文不进行完整存储,而且是将各种事件排为队列,进行增量计算得出,就能把上下文的更新操作转换为追加写入事件。代价是事件回放的逻辑会较为复杂(需要回放过程中拼出完整上下文;排除掉不满足前提下的事件)。

    事件队列我使用zset来存储的(score为事件时间),原因:
    1、避免使用lua脚本
    2、可以方便清除过期事件
    我自己能想到的不足:多个时间接近的事件同时产生,score更小的事件,在score更大的事件写入完,并回放完,才进行了写入,可能使得之前的回放结果不正确。实际很难发生,就没有避免。

    事件队列(单个主播)zset
    score:curMill
    value:{
    "type":"1、设置盲注&上限;2、正常关播;3、异常关播;4、复播;5、准备-兑换筹码&落座,6、成功-兑换筹码&落座,7、失败-兑换筹码&落座,8、准备-增加筹码,9、成功-增加筹码,10、失败-增加筹码,12、清算筹码&离座,11,开始游戏,21、更新上下文",
    。。。
    }

    相关文章

      网友评论

          本文标题:德洲扑克技术设计的思考过程

          本文链接:https://www.haomeiwen.com/subject/hzxiwdtx.html