PS: 以原神作为参考
系统设计目的
抽卡系统旨在提供玩家良好的抽卡体验,无论是交互体验还是实际数据体验。
抽卡系统在大多数情况下与充值等服务强结合,所以需要严格保证安全性。
系统架构设计
为了保证安全性,抽卡系统的所有逻辑均应该放在服务端,只给客户端暴露最基本的调用接口。
服务端设计
首先,原神作为在线的游戏,我们需要在服务端对玩家数据进行存储,那么为了与抽卡系统进行搭配,我们需要在每个用户的数据内存下可能会有用处的数据,比如限定池的抽数、常驻池的抽数、保底情况等。
那么我们应该给客户端暴露什么接口呢,不考虑其他乱七八糟的功能的话,我认为主要的有且只有一个,就是进行一次单抽的接口,然后返回抽卡结果或者是资源不够的回退。
PS: 那么这里考虑到可能的实现,我们知道CE(cheat Engine)可以去通过注入实现数值更改,那么这里我们就可以做一个检测,如果客户端的资源审批通过了但是服务端没有,那么我们便可以初步检测作弊。
然后是服务端逻辑架构,我们希望这是一个独立的系统,并且要与别的系统进行解耦,那么首先我们按照用户ID进行基础数据的fetch,然后进行更改回调,这个主要使用了用户数据存储系统暴露的接口。
然后考虑卡池更换,在每一次热更新或者重启的时候从json里读取各种up或者卡池内容,这些不会涉及到用户差异,所以不用过多考虑。
客户端设计
我们在客户端主要应该考虑的是时序、演出、流畅的玩家体验等。
考虑用户点击抽卡按钮后的流程。
- 客户端进行资源检测,资源不够直接回调。
- 如果检测成功,那么发送请求给服务端。
- 服务端返回抽卡结果并且触发客户端数据更新(这样我们可以把结果与资源数据全部放在服务端更改,客户端只有一次原子操作,防作弊)
- 然后客户端按照服务端返回的结果加载所需的动画和素材资源(这里不需要异步操作,因为本来就是在等待进程)。
- 完成后播放抽卡动画,触发物品入库事件或动画。
算法逻辑设计
PS: 这里只考虑服务端流程
首先,我们知道每一个卡池在启动的时候已经实现了池子更新,那么我们只考虑随机算法实现即可。
为了保证稳定随机,我们采用分层随机的方式。
比如,数值策划给我们的数据是10%的四星概率,那么我们首先rand这一发是否是四星,然后我们再去rand实际的抽卡结果,这个分层随机保证了数值稳定。
向着星辰与深渊