游戏中的常见概率设计分析

前言

        游戏中的概率真的是让人又爱又恨,很多玩家因为自己的屌丝气质(白嫖)而弃坑玩不下去的,比如人尽皆知的某阴阳师,除了氪金,还肝,而且如果你的脸真的非常的黑,那也是打不过那些0氪金的欧洲人的。

        而在游戏中被吐槽的最多的就是概率问题,我们一遍一遍的刷副本,BOSS,就是为了凑齐一整套装备,因为BOSS掉落是随机的,我们也不知道什么时候能够凑齐;为了获得某个角色,连续的抽卡,期待欧皇的附身,但是结果是无法确定的。这就是游戏的魅力,有随机性,有变数,有期望,有运气。

游戏中常见的4种概率设计

1、常规做法,直接配置概率,程序直接判定

2、在1的基础上,加个保底次数,当连续不发生的次数高于保底时,强制发生

3、设置基础概率,事件不发生概率翻倍

4、设置数组,将事件发生概率变成数组元素

独立随机算法

        每个怪物都会携带一些游戏道具(装备,宝石,金币,道具,任务物品等),被击败后,会根据概率随机掉落。至于掉落的游戏道具是不是你想要的,就要看你的运气了。

在游戏中:如果某个BOSS掉落某件极品装备的概率是5%,那么就是每次BOSS被击杀后,由系统随机在1—100中生成一个数字,如果这个数字小于等于5,那么就会掉落该装备,否则就不会掉落。这是独立概率,每次的概率都是一样的,不会变化。

但是概率其实是不可靠的,同样的概率,有的人可能打1,2次就掉落了,有的人可能打30次才会掉落。这也是没办法的事情,真随机就是这样的。所以,在早期的网络游戏中,如果你想获得某个游戏道具,多花时间就好,打的次数多了,肯定就容易获得你想要的道具。

没钱的玩家可以多花时间,打装备卖给有钱的玩家,以换取点卡。大家各取所需。这是早期游戏设计所决定的。那个时代,除了点卡消费,在游戏中,大家都是公平的。

开箱子or大转盘

    当游戏进入免费时代,游戏设计者为了能够赚到钱,就开始卖属性。但是不能直接卖,要间接的卖,卖的巧妙,最好还能多赚钱。于是转盘这种设计就出来了,不是卖装备 ,是抽奖,能不能抽到看运气。每个方格里有不同的道具,有普通道具,也有中级道具,更有高级道具。

看起来每个格子(转盘)设计的大小,概率都一样,其实不是这样的,这只是看起来一样,具有视角欺骗性,最终还是按概率来。可能高级道具的概率连1%都不到,要不停的转才有可能得到,其实就是一个简单版的打怪掉落程序,只不过不需要打怪,花钱就直接按概率掉落。


不过这种把戏后来慢慢被看穿了。于是,开箱子的方式改进了一下,就是已经抽到的道具不再参与转盘。相当于每获得一个格子中的道具,就减少一个道具,所有剩下的道具概率重新计算,每个道具的获得概率提升了。
但是,你想获得高级道具,仍然是要花大量的钱。

抽卡保底算法

        当卡牌游戏开始流行后,抽卡这种模式就越来越受到大众欢迎。抽卡就成了免费游戏的主要收入来源。简单直接,而且隐秘。简单是因为,只要点击一次,就会从牌库中,随机获得一张卡牌。隐秘是因为,牌库是比转盘还要复杂隐秘的,里面有太多道具,除了基本抽取的概率,内部每个道具的概率也是不一样的。所以,需要不停的抽卡,因为牌库太大,抽卡完全是看脸。


如果概率无法控制,其实对玩家是不太友好的。于是大部分的抽卡游戏都增加了保底功能,抽10次必得。就是为了防止连续抽多次也抽不出来的情况。还有一部分,采用幸运值累积的方法,每次抽卡如果没中,就会累积幸运值,幸运值越高,就越容易获得想要的道具,其实也是变相的提高概率。
这种其实是伪随机。

那么什么是保底设计?保底设计准确来说是为运气不好的人提供的一种保障,能够获得自己想要的卡牌。

设计保底的方案有多种,这里说下三种方案:

1.固定或浮动数值保底。这种方案在于你需要预先给对应保底的卡牌进行定价,比如价值1000 RMB,那么当玩家抽卡次数达到一定值N时(这里假设每次十连抽价格为188 RMB,N约为60,注意:卡牌定价≈N*抽卡价格 就可以),如果依旧没有获得保底卡牌,则必然会获得一张,一旦玩家获得保底卡牌后,N重置为0,重新开始计数。

这种方案比较简单,N可以为固定数值也可以为一定的浮动值,这种方案主要为运气不好的人服务,挡不住欧皇。

2.不重置抽卡。这种方案在于每个玩家抽卡前先将卡池设计好,比如卡池生成了1000张卡牌,900张R卡,90张SR卡,10张SSR卡。玩家每次抽卡都是从这个卡池中取卡,取出的卡牌不再加入这个卡池,直到玩家将这1000张卡牌全部抽完。再重新生成1000张卡牌,再次进行这个循环。

理论上来说,这种方案是最公平,所有玩家在抽完卡池后,获得卡牌都是一样的。但是这种方案在于大多数玩家抽不空卡池,更大的弊端在于一旦增加新卡进入卡池,这个卡池就要变换,导致达不到保底的效果。

3.浮动概率。这种方案有点类似于PRD算法。这种抽卡的机制在于每次抽完卡后调整所有卡牌的比例,让单人整体抽卡的感觉更趋近与高斯分布,但是收敛的方式会更快,从而让最终的结果接近于期望。

这种方案相对来说比较复杂,目前也只见过极少数项目用过,需要大量的数学公式,个人对这块研究不深,就不展开了。

其实,我们看到在抽卡的概率上面设计者并没有做太多的隐藏设计,但是为什么玩家怎认为是设计有缺陷,甚至调侃到玄学上面去呢?

我认为是基于两方面,一方面是因为幸存者偏差,很多玩家更多将注意力放在抽到卡牌的玩家,而对于没有抽到玩家没有关注(全服通告也只会告知玩家谁抽到好卡,而不会告知多少玩家没有抽到)。另外一方面在于抽卡的概率在大量玩家的基数上是平均的,但是对于单个玩家的概率并非平均。

从个人体验设计来说,个人认为保底是必须,哪怕会打破真实概率,因为比起获得卡牌的成功体验,失败的体验设计对玩家来说是非常糟糕。甚至有些大R玩家直接会打电话给客服,宁愿花钱去购买卡牌,而不是让自己一次次体验失败。

洗牌算法

洗牌算法最典型的应用莫过于音乐播放器的随机播放。

在最早期的时候,播放器的随机播放就是采用的真随机,但是用户很快就发现,经常会遇到接连播放同一首歌,或者连续多次在几首歌之间来回切换,而另外某些歌曲几百次也放不到。为了解决这个问题,播放器就把真随机改为了洗牌算法。

所谓的洗牌算法就是:如果你的歌单有20首歌,就建立一个1到20的数组,再把这20个数字像洗牌一样洗成乱序。
在洗完之后,如果第一个数字是n,第一次就播放歌单里的第n首歌。以此类推。

组合随机算法

所谓的组合随机,典型的应用就是在抽奖的时候进行两次判断:

一次不随机:根据预设好的确定数组,给予玩家对应的chest。

这一次主要是用于确定奖品品质。

一次真随机:从选中的chest中随机抽取一件物品给玩家。

这一次就是从对应品质的奖品堆中随机获取一件物品。

最典型的例子就是《我叫MT》的手游。

在这个游戏里,你第几次抽奖能中紫卡是完全确定的,但是你具体抽到哪一张紫卡则是随机的。

在游戏中一般会用到真随机和伪随机两种方式。

可以说,真随机是一种自然的随机机制,用代码来实现也非常容易,只需要用一个随机数与一个常量进行比较,根据大于小于等于分别触发不同的结果就行了。

而伪随机则是人为创造出来的一种机制,他需要程序员写下更多的代码,也需要数值设计者做更多的计算。

那么,既然伪随机费时费力,还反自然,为什么在应用领域还要引入各种伪随机的算法呢?

其目的就在于——让用户得到更好的体验。
真随机,就是原始时代的怪物掉落,掉不掉全看运气。每次概率都是一模一样。

伪随机就是,如果该玩家第10次还未掉落该道具,则系统会强制必掉该道具。同时在获得该道具后,概率又恢复初始。还有一种做法,就是每次没有获得该道具,概率就增加,到第10次,概率是100%,必得。

概率是为了增加游戏的乐趣和期望,但是概率是不可控的。为了降低概率不可控所带来的挫败感,在游戏中,都增加了一些机制,来让概率的设计符合预期。

早期的游戏,概率只是游戏乐趣的一部分。而现在,概率成了游戏设计者赚钱的一种主要方式,说不上算好还是坏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个通用游戏后台的设计模式实践总结

搞业务开发的时候,发现有一些代码的开发会让人感觉非常简便舒服,有一些代码的开发却有时候会让人感觉心智负担比较大。逐步总结的过程中,发现让开发人员写起来感觉舒服的代码,大概率是因为当前模块与其他模块代码耦合度低&#xf…

leetcode103. 二叉树的锯齿形层次遍历

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 例如: 给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 …

大型游戏后台实践浅谈

国家新闻出版署8月30日下发切实防止未成年人沉迷网络游戏的通知,要求从今天(9月1日)起,所有网络游戏企业仅可在周五、周六、周日和法定节假日每日20时至21时向未成年人提供1小时服务,其他时间均不得以任何形式向未成年人提供网络游戏服务。通知发布后,各大游戏厂商火速回…

如何使用弱网环境来验证游戏中的一些延迟问题

关于弱网 在当今移动互联网盛行的时代,网络的形态除了有线连接,还2G/3G/Edge/4G/Wifi等多种手机网络连接方式。不同的协议、不同的制式、不同的速率,使移动应用运行的场景更加丰富。 从测试角度来说,需要额外关注的场景就远不止断网、网络故障等情况了。对于弱网的数据定义…

使用nginx分片功能提升缓存效率,支持可拖拽式播放视频

Nginx的slice模块可以将一个请求分解成多个子请求,每个子请求返回响应内容的一个片段,让大文件的缓存更有效率。 HTTP Range请求 HTTP客户端下载文件时,如果发生了网络中断,必须重新向服务器发起HTTP请求,这时客户端已经有了文件的一部分,只需要请求剩余的内容,而不需要…

Nginx 配置TCP和UDP负载均衡

前言 Nginx除了以前常用的HTTP负载均衡外,Nginx增加基于TCP协议实现的负载均衡方法。 HTTP负载均衡,也就是我们通常所有“七层负载均衡”,工作在第七层“应用层”。而TCP负载均衡,就是我们通常所说的“四层负载均衡”,工作在“网络层”和“传输层”。例如,…

leetcode116. 填充每个节点的下一个右侧节点指针

116. 填充每个节点的下一个右侧节点指针 难度中等128 给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下: struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&am…

你的代码是否按照高内聚、低耦合的原则来设计的?

我们一直强调软件开发中要按照高内聚、低耦合的设计原则来做代码结构设计。c语言和c++不同,c语言面向过程、c++面向对象。 真正的项目中,要对业务升级,原来的业务函数需要保留,要保证老的功能继续维持,不能直接删除,这时候c语言面向过程,通常使用回调的方法。c+…

leetcode117. 填充每个节点的下一个右侧节点指针 II

给定一个二叉树 struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。 初始状态下,所有 next 指针都被…

你担心大家会滥用的全局变量,大家(包括你自己)一定会滥用

前言 不要使用全局变量的道理大家都懂,基本上在大家学习编程过程中很早就会被教育到,但是有时候我们也会禁不住诱惑用到一些似非实是的全局变量,只不过这些全局变量会穿上马甲,让你不会一下看穿它的巨大危害,滥用全局变量会引申带来其它更为严重的结构性系统问题。…

Android Studio下载安装教程及开发环境搭建

Android Stuio是本次Google io的一大亮点啊,一大早起来就赶紧下载来玩玩了。。。 如果你不幸被墙了,可以去这个帖子下载,我已经上传到百度盘里面了。 [Android利器]Android Studio下载地址来啰 。。http://www.eoeandroid.com/thread-275380-…

leetcode124. 二叉树中的最大路径和

难度困难314 给定一个非空二叉树,返回其最大路径和。 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。 示例 1: 输入: [1,2,3]1/ \2 3输出: 6示例 2: 输入: …

深入剖析阻塞式socket的timeout

前言 网络编程中超时时间是一个重要但又容易被忽略的问题,对其的设置需要仔细斟酌。 本文讨论的是socket设置为阻塞模式,如果socket处于阻塞模式运行时,就需要考虑处理socket操作超时的问题。 所谓阻塞模式,是指其完成指定的操作之前阻塞当前的进程或线程,直到操作…

leetcode165. 比较版本号 超级重要的细节

比较两个版本号 version1 和 version2。 如果 version1 > version2 返回 1&#xff0c;如果 version1 < version2 返回 -1&#xff0c; 除此之外返回 0。 你可以假设版本字符串非空&#xff0c;并且只包含数字和 . 字符。 . 字符不代表小数点&#xff0c;而是用于分隔数…

游戏服务器缓存系统如何设计

前言 不管是在业界开源领域,还是内部分享中,很少会有专门针对游戏业务特征进行专门设计的组件、类库或者框架。我们从游戏的客户端方面来看,一款专业的游戏客户端引擎,已经是游戏开发的标配,flash,Cocos,Unity,Unreal等,但是服务器端,我们几乎找不到同样重量级的产品…

leetcode574. 当选者(SQL)

表: Candidate -------------- | id | Name | -------------- | 1 | A | | 2 | B | | 3 | C | | 4 | D | | 5 | E | -------------- 表: Vote ------------------- | id | CandidateId | ------------------- | 1 | 2…

使用KCP 加速游戏消息,让全球玩家流畅联网

定义 kcp协议是传输层的一个具有可靠性的传输层ARQ协议。 它的设计是为了解决在网络拥堵情况下tcp协议的网络速度慢的问题。 kcp力求在保证可靠性的情况下提高传输速度。 kcp协议的关注点主要在控制数据的可靠性和提高传输速度上面,因此kcp没有规定下层传输协议,一般用udp作为…

leetcode584. 寻找用户推荐人(SQL)

给定表 customer &#xff0c;里面保存了所有客户信息和他们的推荐人。 ----------------------- | id | name | referee_id| ----------------------- | 1 | Will | NULL | | 2 | Jane | NULL | | 3 | Alex | 2 | | 4 | Bill | NULL | …

剖析KCP以及KCP在游戏中是如何使用的

亲爱的各位读者你们好,由于前段时间忙于部分项目的重构和优化,未能及时更新文章,不少读者催更,哈哈,我还是很开心能抽出时间给大家再来分享下kcp的相关技术内幕,以及之前完善自己的网络库增加了KCP的客户端服务器收发支持(结尾会分享封装的客户端服务器C++源码)。 KCP概…

leetcode585. 2016年的投资(SQL)

写一个查询语句&#xff0c;将 2016 年 (TIV_2016) 所有成功投资的金额加起来&#xff0c;保留 2 位小数。 对于一个投保人&#xff0c;他在 2016 年成功投资的条件是&#xff1a; 他在 2015 年的投保额 (TIV_2015) 至少跟一个其他投保人在 2015 年的投保额相同。 他所在的城…