前言
最近项目不忙,带薪摸鱼,出于对数值的兴趣,想玩些有趣的放置小游戏,顺便反推数值,用vba做个数值模拟器,练习vba使用技巧,以备日后使用。
正巧GooglePlay推送一个养鸡游戏《EggTycoon》,玩了段时间,对这款游戏的喜爱,始于画面陷于手感,看了近200个广告。
写这篇文章一是作总结,二是分享vba代码(希望能有点用),三是方便日后回顾这堆破代码【笑脸】。
有意见可以提出,会积极吸取的,多谢。
之后会陆续在简书里写数值策划学习之路上的总结,包括数值公式学习、vba代码编写和有趣的vba代码
文件链接:https://pan.baidu.com/s/1cBUA_skdtBUefiAvbkPnbQ(链接失效可联系,会更新)
游戏截图游戏循环介绍
玩家通过鸡场获得鸡蛋,鸡蛋通过车辆运输兑换成金钱。
鸡场需要解锁,解锁需要微乎其微的金币,靠玩家等级卡住进度。新鸡场金币产量比旧鸡场指数级上升。
运输车辆也有等级,升级后提升每秒运输的鸡蛋量。囤积的鸡蛋无法转换为金币。
玩家金币积累到一定数量后提升玩家等级,玩家等级升级需要手动点击按钮。
玩家提高金币产量的途径除了解锁鸡场,还有升级旧鸡场。而旧鸡场每隔30级可以看广告突破一次,突破后产量翻倍。
以上无限循环。
[系统结构]
详细的数值和系统循环如下图
系统循环图[循环图意义]
业余时间自己制作,这个图自然不用背负着应付上级,美化工作流程的重任。做循环图过程中,梳理对数值结构的认识,方便以后编写vba代码,不用反复的查看游戏。进一步说,如果有问题请教别人,有这个图也节省其了解游戏的时间。
重点内容如下:
[金币获得和消耗介绍]
玩家金币获得途径有三种:车辆把鸡蛋送到外界获得金币,在线奖励,玩家等级提升附送的金币,但最后者的量级过小。
玩家金币消耗途径也有三种:升级鸡场、升级车辆、解锁鸡场,实际体验中消耗量从前到后递减。升级鸡场虽然在图中只有一个按钮,但游戏中有许许多多按钮直接表现在界面上,造成一种金币消耗途径无处不在的假象。界面可以优化成,最高级鸡场之后的几个鸡场,升级按钮可以放到内部界面。
[广告点介绍]
游戏中广告点不多,比较重要的有以下几个:
(1)解锁的新鸡场需要花时间建设,看广告立刻跳过该时间
(2)离线收益翻倍的广告
(3)在线飘过来金蛋,点击后领取的奖励可以翻倍
(4)每个鸡场升30级后可以看广告reset突破一次,reset还能提高蛋的售价
[玩家操作,就是玩家点击的价值]
点击加速鸡的速度,间接提高产蛋量从而提高金币收益,最大的问题是反馈不即时。
点击车辆提高速度,当没有多余库存时,玩家点击收益实际是0,体验并不太好。
[数值体系评价]
以上介绍了游戏内较为重要的数值。游戏体积小,循环单一,从数值角度可以看出很少有做活动的空间。如果要做大规模的活动,可能参考《Idle Miner》的做法,单独的世界和活动界面。
玩家升级后获得金币和解锁鸡场的消耗金币,这两个数值没琢磨到设计意义。数值都很小,前者起不到补给作用,翻倍广告更毫无吸引力,后者微乎其微,起不到限制作用。
[反推数值经验]
经验尚浅,这是我第一款扒数值的游戏,走了些没必要和低效率的弯路,反思后觉得扒数值的思路应该如下:
(1)猜测这个数值设计目的。根据数值表现和游戏体验,猜测这个数值要满足什么需求。回答这个问题不会一蹴而就,进行下面几步时要反复思考这个问题。
(2)梳理数据结构和关系。先观察数值如何成长,是指数成长、对数成长或线性成长。和其他什么数值挂钩。
(3)确定具体的数值。太细小或者不重要的具体数值,就自己凭感觉填。
思路的重要性从上到下依次递减,可移植性从上到下递减。像素级扒数值是本末倒置的笨功夫,耗费时间多,可复用性差,如同用木镐敲金矿,苦力不少出还得不到金粒。
[困惑]
整理数值时,想明白的两个问题是:
问题1:玩家提升同一个鸡场的等级后,产蛋量是2的倍数上升,而下一个鸡场又是上一个鸡场10倍产蛋量。多出来的数值怎么消耗掉的?
问题2:鸡蛋的售价是随着鸡场reset的次数而上升,这部分增长的数值有处理吗?
[excel的模拟]
数值循环不复杂,但是架不住数学功底不行【微笑】为了回答这两个问题,就假设了部分条件,做出了原始版的玩家升级所需时间。假设的条件如下:
(1)玩家的鸡场解锁后立马达到生产最大值
(2)玩家只有1个鸡场,新解锁的鸡场产蛋量=10倍旧鸡场产蛋量
(3)解锁新鸡场不需要花金币
(4)取消运输车限制
(5)唯一变量:玩家每个鸡场reset的次数。鸡蛋的售价=鸡场id*鸡场reset次数*0.02+1
满足以上条件后,以玩家等级为坐标轴横轴,玩家等待时间为坐标轴竖轴建立坐标系。玩家每秒金币上升=每秒产蛋量*蛋的售价,玩家金币需求全用到升级,数值读表。
数据表 折线图尽管数值是基于部分假设做出来的,但也能对问题1和2做出解答。
问题1:鸡场产蛋量指数增长的数值,大致与玩家升级所需金币指数增长的数值相抵消,而两者的岔开增长给玩家造成了数值上“压抑-释放-压抑”的节奏感。
问题2:游戏没有处理增长的数值。造成的结果是,玩家升级等待时间不仅是个波动的曲线,还是个振幅不断缩小的波动曲线。Reset鸡场,提高蛋的产量,这个广告点长期收益很明显。
需求不高,粗糙且原始的模型已经够用,但还是想做一个vba模拟器更细致的看一下玩家行为。
VBA代码
[代码结构介绍]
个人编程水平浅薄,经验不足,依赖谨慎的前期规划避免出现太多问题。
代码有两个文件和三个类
两个文件:log和main,log模块负责输出数值log,看看哪里有问题,统一在一个文件方便修改;main模块负责编写玩家行为。
三个类:car、chicken和player。Car类是运输车,chicken是鸡场,player是玩家。一个player有多个chicken,有一个car。
写程序难免犯错,尤其是新手,再加上vba调试功能不完善,对测试的需求就比较高。测试分为两步:函数功能测试和程序运行输出LOG。前者不必多说,调用写完的函数,输入数据后检查输出是否符合预期。我从这次编程得到的经验是,不仅要简单的调用一两次,还要循环多次调用,把结果输出到工作表中检查。发生过很凑巧几次,我测试以为没问题的函数,如果输入数据多变化就有问题了,2333。最后是程序运行输出LOG,预想有哪些数据要输出成log,以便快速锁定问题。为了log确实多写了一小撮代码,但这总比运行断点划算。Log模块最好统一写在log文件,而不是分散写在别的各个类里。
把数据分为三个类型:读表数据、存储数据、临时数据。(1)读表数据是程序通过工作表读取,一般为类和程序初始化步骤读取,放到工作表里比写成常数项更容易修改,比如玩家初始金币、鸡场升级次数(2)存储数据,一些比较重要经常被调用的数据,比如玩家等级、玩家金币等,计算完保存以备下次调用(3)临时数据,大量用完即弃,随用随算的数据,比如鸡场产量中有个数据是单个鸡产蛋量,这个数据即使保存下次调用时也要从新计算,索性不存。
vba极不智能的编译环境,更改属性和函数名称需要自己手动全局替换,所以写代码前借助UML统一规划命名。属性和函数如下图:
UML图程序运行的流程为逐秒运算,假设玩家为一个完全理性的人,设定每秒内玩家决策,决策流程结束才进入下一秒。
流程图中间不涉及到复杂的算法问题,所以剩余的搬砖内容就不介绍了,码代码就完事了。
[模拟的前提]
处于编写代码的目的,把玩家设定为一个完全理性和循规蹈矩的人,只按照固定流程走,没有任何概率做其他事。实际上玩游戏主要是图开心放空自己,断然不会有如此精心计算周密安排的玩家。大脑的模糊逻辑更倾向于玩家有钱就只升级鸡场等级或者只提升运输车等级,造成产出远大于输出或相反。
游戏涉及数值比较大,用int和float存储会溢出,为了避免double溢出的情况,思考了几个方法,比如所有数值同比例缩小、以10为底换成其他数字、转换成指数、写一个大数值的类存储大数值。考虑到代码并非商业化系统,只是小型运行需要,选择了“转换成指数”这个方法。有些编程经验看到此处就会想到“double能存储的最大值为1.7*10^308,还满足不了需求吗?”bingo,说的没错,但是我当时忘了,凭空出现很多工作量,完全是与空气博弈。
[未完成部分]
先帝摸鱼未半而中道有活,遂有些未完成的部分。
(1)玩家离线和在线。模拟玩家在线离线,从而更为精准的计算游戏资源能支撑的生命周期,这个需求比较现实。实现应该也不难,就是多一个flag标签,每秒运行玩家策略时根据flag标签采取不同的策略。也可以能判断玩家等待多长时间自动下线,但这就需要优化下时间。
(2)时间计算优化。现在的时间优化是最笨的逐秒计算,完全真实的模拟每一秒。得益于总体运算量偏小,模拟10000秒不到3秒,但大可以不必这样。提前设定必须等待的时间,每秒运算的最后取等待时间的最小值,直接跳过即可。
(3)各数值价值,这项是最为真实的策划的需求,也是数值策划的职责之一。比如运输车的数量已经是方便调试的读表数据,但价值究竟如何,玩家3量运输车和2量运输车有何区别,能不能用数字表达出来。视频点的价值几何,哪些是高价值的视频点哪些又是低价值的。
网友评论