« July 2016 | Main | September 2016 »

August 28, 2016

Lua 稀疏数组

Lua 的 table 可以做数组用,但是前提是数组里不能有空洞。也就是不能在数组里保存 nil ,否则取长度和迭代的行为都是不确定的。

能不能用比较小的额外代价在 Lua 中实现一个支持空洞的数组呢?

首先,我们定义一下,带空洞的 array 的正确行为应该是怎样的:

  1. 数组只能用正整数做 key ,设置其它 key 会抛出 error 。

  2. 可以用 pairs 迭代数组,和普通的 table 一样,迭代器会跳过那些值为 nil 的键值对。但要求迭代器一定从 1 开始从小到大按次序迭代。

  3. 用取长度 (#) 操作符,可以正确的返回数组的大小,即最大一个正整数 key 。

  4. ipairs 的行为不变,会在第一个 nil 处停下来。


我想,可以依旧用 table 来充当数组,而只需要重定义这个数组对象的 __newindex __pairs__len 三个元方法就可以了。

我们可以认为,在触发 __newindex 时,如果 key 在 lua_rawlen 返回的范围内,那么新的值还是保存在 table 的 array part 的,不用特别干预。

而如果在 hash part, 可以额外把这个 key 记录下来,我想以负数为下标就可以了。

每当 pairs 迭代前,或是取 # 长度前,我们可以对稀疏部分,哪些负数下标记录的额外 key 做一次排序去重整理。之后的运算复杂度就可以控制在 log(n) 内。

实现的代码见 github 上的仓库

August 19, 2016

pvp 游戏如何解决玩家匹配等待时间过长的问题

按局打的纯 PVP 机制的游戏,面临最大的问题将是,在一个玩家想找人对战的时候,找不到对手匹配。

如果游戏的在线玩家达不到一定人数,那么这个问题会恶化:等不到人和你一起玩、放弃等待、新的玩家更找不到对手。

像皇室战争、王者荣耀、炉石传说这些火爆的 pvp 游戏都属于迈过了线的作品,玩家不太愁等不到人一起玩,提升了游戏体验,聚集了更多的玩家。而当玩家群有限时,同类产品就很难竞争,只要在线用户掉到一定限度以下,很可能导致(无非找到对手)体验下降,更多玩家流失。

那么,有没有办法解决初期玩家过少的问题呢?

直观的想法就是没人玩 AI 凑。可 AI 并不是真人,和 AI 在公平规则下对战乐趣会少很多,且高水品 AI 开发起来也非常困难。最关键的是,一旦玩家乐于和 AI 对战(无论是因为对战本身的乐趣,还是可以刷分刷掉落),你会进一步失去在线用户。

让我们来估算一下这个问题有多么严峻:

据说王者荣耀目前的日活跃用户有 3500 万,自然不愁找不到对手。

如果你玩过这个游戏,必然会有体会,每天为了玩这个游戏等待匹配的时间有多长呢?我没玩过,让我随便估算一下吧,如果一天打两盘,平均每盘等 10 秒钟。我的每天等待时间就是 20 秒。即一个用户每天有 20 秒在线时间可以供和同样的人一起匹配准备。

每天有 24 * 60 * 3 = 4320 个 20 秒,那么对于 3500 万日活跃用户来说,当你在等待其他玩家加入的时候,有大约 8102 个玩家是你的对手备选。

由于每天高峰和低估的在线人数差异比较大,按我的经验大约可以差到 4 倍左右。在低谷期,这个人数至少需要减半。

所以你看,即使这么大的用户规模(3500 万日活这个数字我有点怀疑,如果这个数字是真的,那么你随便找身边的游戏玩家,他们几乎都应该在最近玩过这个游戏了),全部玩家同服,不考虑天梯(尽量不让高水平玩家和低水平玩家对战),每时每刻,也只有几千用户备战。

所以,如果考虑运营这种纯 pvp 开房间按局比赛的游戏,必须考虑尽量简单而扩大目标用户群,且尽量减少单局游戏的时长。宏观上,每个玩家每天能分配在游戏上的总时间有限,单局时间越短,可以打的盘数就越多。每局游戏前的匹配时间以 10 到 20 秒为容忍上限的话,盘数越多,每天可以忍受在等待上的时间也就越长,这样就减少了匹配不到对手的尴尬。

如果玩家人数太少,也可以通过活动来把有限的玩家集中到每天的某个时间段,甚至让服务器不 24 小时开放。


出去运营策略,技术上我们可以做些什么呢?

我想了一个最容易实现的方案,就是增加运营人手陪玩,并在技术上做配合,提高陪玩的利用率。

假设我们一局 1 对 1 的游戏长度是 4 分钟,玩家可以容忍的等待时间上限是 20 秒,理论上,在工作时间内,只需要安排 12 个陪玩就可以解决问题。

规则如下:

系统对陪玩账号做上标记,匹配系统永远不撮合陪玩用户之间战斗。

玩家开始匹配时,如果没有其它玩家同时在等待匹配,那么他最长等待 20 秒,在此期间,一旦有新玩家加入,就尽量撮合他们;否则,在超过 20 秒后,从空闲的陪玩者中选出一个人和他游戏。

由于单局游戏长度是 240 秒,所以最坏情况下,我们需要安排 12 个人陪玩。


如果加入天梯系统,即尽量让积分/实力相近的玩家一起游戏。那么,就稍微修改一下规则,两个玩家都开始匹配时,并不立刻撮合他们,而是一定等待一定数量玩家进来(比如 5 个),然后为等待时间最长的玩家寻找一个和他积分最接近的玩家开始游戏。

只有等不到人数,才在等待上限(20 秒)时,匹配一个尽量积分接近的玩家或陪玩。


我现在正在设计的游戏正是一个 1 对 1 的 pvp 手机游戏(战斗过程完全不同于皇室战争)。记录一下想法,希望游戏做出来后可以熬过最初的用户积累期。

August 11, 2016

群星的汉化及其它

最近一个月,玩群星(Stellaris) 有点着魔。不同于 P 社之前我最喜欢的维多利亚2 ,这个上手更舒服。是我玩过的把大战略和 4X 结合的最好的游戏了。我很欣赏 P 社这种尽力降低玩家门槛的做法,让大战略和 4x 游戏不那么高冷,普通玩家也能很快领略其中的乐趣。

这里有我写了一篇评测。大致谈了群星是一个怎样的游戏,如何快速入门。小提示:即使是新手,也推荐用铁人/疯狂模式。第一次玩只需要把银河调小一点就好了。这样乐趣才能充分体现出来。

这次 P 社的引擎革新后,汉化变得很容易了。之前,大多数人和我一样使用的 3dm 版汉化 mod ;但这个 mod 翻译的时候,译者并没有怎么玩游戏,所以很多地方用词不当,还有一些仓促翻译导致的错别字。我实在受不了老式的闷头汉化的模式了,发现问题反馈到修正的周期太长,所以就自己维护了一个汉化 mod 。

需要的同学可以直接订阅。个人认为,利用 github 做合作创作,对于做汉化这件事特别合适。这个 mod 直接放在了 github 上

游戏文本的版本更新,可以直接体现在 diff 里。路人发现有错别字也可以顺手提个 pr 。而我自己一般是在玩游戏时瞟见翻译的不合理的地方,立刻打开文本编辑器校对一下。也正因为如此,游戏里出现的 event 都特别仔细的阅读;群星的开发者真是脑洞大开啊,游戏里的 event 涵盖了几乎我所有阅读过的科幻小说,看过的科幻电影的梗。光这一点就值回了票价。

在群星发布前,我还十分担心,如果没有了维多利亚里那种厚重的历史感,一个科幻题材的战略游戏该如何给玩家代入感;没想到它是通过这个手法来完美的解决了这个问题。


最后说两句别的。

看着现在大量重复又重复的移动平台游戏,包括我们公司正在制作的几款商业产品,我又一次感到失落。几年前 coc 给我的那种新鲜感慢慢褪去,皇室战争也只新鲜了几个月,感觉现有的手机游戏里又没有什么让自己感兴趣的东西了。

考虑了很久,终于酝酿出一点小想法。上个月开始制作游戏原型。不求被所有人接受,希望做出来后可以满足部分人的爱好吧。不求完全的原创点子,但是这次至少没有“借鉴”已有的游戏了(btw, 和群星一点关系都没有),但也让 demo 制作的特别困难。完全不知道做出来会不会好玩,开发过程中一直忐忑不安。花了一个多月后,第一个可运行版本居然玩起来感觉还成,在公司内部还发展了两三个粉丝。挺开心的。

不过接下来的工作更艰巨。加了两个同有兴趣的同事一起完善,计划在 3 个月内做出一个可以敢拿给几百个陌生人来尝试的完整版本。

如果能顺利走到商业化立项的阶段的话,或许是我们公司第一款完全原创玩法的手游了吧 :) 真正动手设计游戏并实现的感觉也很不错,即使过不了商业化的坎也认了。