Re: [问题] 单机游戏用seed生成的假乱数表好处是?

楼主: LiNcUtT (典)   2018-03-07 17:12:13
※ 引述《ZMTL (夜风/潇湘 VR板已经开板!)》之铭言:
: 嗯,虽然我是APP工程师,但大学不是唸本科毕业后才半路出家的,
: 对这点真乱数、假乱数以前耳闻过讨论却没什么概念,刚好跟游戏有关想到就问一下。
首先要有一个观念
目前没有所谓的真乱数
程式里用随机函式(后面用rand()代称)产生的乱数全都是假乱数
rand()有很多种,但不论哪种都是人写出来的
有自己写过的就会知道流程大概都如下
1.给一个seed > 2.算法做运算 > 3.得一个值 > 跳回2得3 loop
所以seed固定,后面产出的值也都会固定,连续取3的值建表就是所谓的随机表,这是正常的
不同的seed会有不同的表,更改seed可以视作"洗牌"
通常是用系统时间或tick做seed
: 首先举例使用假乱数表的游戏,以下有稍微简化过程:
: 1.魔物猎人:世界
: “炼金”功能是拿X个珠子生成三颗新的珠子,存盘读档结果不会变。
: 后来被发现有一张表,像这样
: A B C
: D E A
: A A C
: 如果你是这次炼金出来是ABC,下次炼金出来是DEA,下下次炼金出来是AAC
: 那你可以先不练金,去打两场任务出来就会变成AAC。
: (实际上打任务推进的序列是1、1、2轮回,按下不提)
: 细节:https://forum.gamer.com.tw/C.php?bsn=5786&snA=137873
: 2.神奇宝贝
: “生蛋”功能是公母方配种生出子代,特定变因固定下存盘读档结果遗传项不会变。
: 父母都有 A B C D E F六项能力,分别遗传父母的哪几项在变因固定下是不会变的,
: 但变因不包括父母是谁,所以可以确认会遗传哪一项后再更换父母取得特定遗传的子代,
: 进阶一点用法就是找到第XXXX次会生出色违后,
: 用低步数就生出来的神奇宝贝跳过中间不需要的部分,
: 在指定的位子再更会为要的神奇宝贝快速取得色违。
: 细节:https://home.gamer.com.tw/creationDetail.php?sn=3427102
: 那问题来了,
: 如果说是避免玩家用SL大法来硬洗出想要的成果,却反而造成未来成果会被预测,
: 难道单机游戏做不到真正在产出结果当下进行乱数,或者乱数表假乱数表有什么优点吗?
: 其实对这问题有疑问好久了w
: 很多人说MHW洗珠子无聊会消耗热情,但经过PM的洗礼我真的觉得还好XD
: 顺带一提,很多线上游戏/网络游戏的都市传说有时候我不会完全不信的原因也是这个。
老实说我觉得就是写程式的人问题
大多数都是直接call平台内建的rand()来用
而没有去了解该rand()的内部算法
所以容易被试出来更改seed的时间点(甚或进游戏后就没改过)
造成大量试错后会被发现规律性
要避免其实也很简单
就是在call rand()前更改seed就好了
但其实单机游戏被试出来也不是啥大问题就是
线上游戏或手游通常会比较注意这块
所以比较不会发生上面的问题
不过还是会有例外...
因为平台内建的rand()...改seed后产出的第1个值
不见得没有规律性喔~揪咪
有发现这点的人就会去找其他(或自写)rand()来用
Unity有发过这方面的文
有兴趣可以看看
https://blogs.unity3d.com/2015/01/07/a-primer-on-repeatable-random-numbers/
里面也有比较各rand()的优劣
以前自己实际跑的结果
https://i.imgur.com/JN9518o.png
seed固定
https://i.imgur.com/6kwkDsg.png
seed变动
看看那个精美的System.Random
作者: kamisun (水银灯的主人)   2018-03-07 17:13:00
Sega MD万兽之王,重读取后第一次攻击100%命中
作者: ckniening (☞罂粟小子☜)   2018-03-07 17:14:00
游戏公司顾一大群人来负责丢骰子
作者: kamisun (水银灯的主人)   2018-03-07 17:14:00
方便一直读取重打的人
作者: wuwuandy (呜呜安迪2016版)   2018-03-07 17:17:00
原PO想讨论的不是这个,他主要想说的是同样假乱数单纯用系统时间就可以做到每秒变化,为何MHW之类的游戏要用这种很死的SEED以MHW为例子,那不是"不足够乱"可以形容的,是一点都不乱...与其说开发人员没想到,不如说是刻意设计的吧
作者: FallenAngelX (跌倒)   2018-03-07 17:23:00
一般基础入门都会教你srand(time(NULL))你要用一个不会变化的数值丢到srand肯定刻意为之
作者: seaEPC (没看见,我没看见 >_<)   2018-03-07 17:24:00
"那不是bug,是feature!!"
作者: pinacolada (西洽的包皮馒头很猎奇)   2018-03-07 17:24:00
单机游戏的乐趣本来就取决于玩家
作者: FallenAngelX (跌倒)   2018-03-07 17:25:00
我是猜如果每次都会变 那就是S/L停原地一直刷但MHW这样的设计就是你就算S/L 还是要推进度才行S/L只是能省点资源 不会让你在原地得到大量东西
作者: linzero (【林】)   2018-03-07 17:28:00
时间用ms的值当seed,可以避免被使用固定seed看过一些修改主机时间的密技,应该大多可能用到分当seed的吧
作者: FallenAngelX (跌倒)   2018-03-07 17:29:00
用ms其实还是有风险 只是我很难想像会出现在游戏上我是遇过板子开机程序里面需要随机但因为那个东西开机就会跑 每次开机时间都差不多结果就是每次随机都几乎一样 偶尔才会变的状况但套在游戏上应该是足够安全 很难想像会有破解问题(虽然这是有点离题了)
作者: hom5473 (...)   2018-03-07 17:31:00
搞不好是工程师为了方便自己做测试抽卡好抽啊
作者: linzero (【林】)   2018-03-07 17:32:00
那个是没钟表时间功能的板子,时间是以开机后过的时间吧
作者: FallenAngelX (跌倒)   2018-03-07 17:33:00
是啊 所以才说很难想像套在游戏上会有问题
作者: zseineo (Zany)   2018-03-07 17:33:00
工程师自己开Debug模式之类的测试就好啊…
作者: linzero (【林】)   2018-03-07 17:35:00
搞不好欧非的乱数表不一样,是以创帐的生辰八字定生死 XD
作者: OochunoO (遥控器推广协会)   2018-03-07 17:38:00
我们后来解法是每片光盘里面塞一个工读生进去控SEED
作者: Cyjustin (justin)   2018-03-07 17:54:00
不论知不知道,能SL大法,去实作真随机意义就不大要我我也不会去费这个工,顶多不要太容易被破解就好近似啦…
作者: OochunoO (遥控器推广协会)   2018-03-07 18:03:00
我也曾觉得大IP的连线游戏对牵扯到平衡或金钱的系统不会犯低级失误 直到遇上kirara fantasy
作者: lbowlbow (沉睡的小猫)   2018-03-07 18:09:00
最简单的就是rand(nowtime)基本上没得刷…
作者: OochunoO (遥控器推广协会)   2018-03-07 18:17:00
如果是转蛋游戏的话 还会因为网络延迟的关系更加强随机性
作者: GKki2012 (chichi)   2018-03-07 18:32:00
好文推推
作者: elcnick (左手谢谢右手指教)   2018-03-07 19:46:00
xxHash提供的程式语言版本居然这么多种https://cyan4973.github.io/xxHash/

Links booklink

Contact Us: admin [ a t ] ucptt.com