我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。
0.《联机桌游合集: UNO+ 斗地主 + 五子棋》是什么?
这是我独立开发的 H5 小游戏,它是个桌游合集,每一款都能够联机,跟敌人一起玩。目前包含 3 款游戏:UNO、斗地主、五子棋,当前会继续开发新游戏。
地址:game.hullqin.cn
特点
反对联机
跟敌人进入同一个房间,即可联机玩游戏。
- 《UNO》反对 2 -10 人一起玩。
- 《斗地主》反对 2 - 4 人打牌。
- 《五子棋》反对 1 - 2 人下棋。
第一个进入房间的人会成为「房主」,能够批改游戏人数,人齐后房主可「开始游戏」。
游戏中断可随时重连
开始游戏后,如果你掉线,或者敞开了网页。不管过多久,只有房主没完结游戏,你从新回到这个房间,就能够持续对局。
哪怕所有人都敞开网页,只有游戏没完结。大家回来后,依然能够持续对战!
当然,如果游戏还没开始,或游戏曾经完结,那么你敞开网页,就退出房间了。
容许观战
当房间人数满时,之后进入的房间的人能够观战。
等到游戏完结,如果房间有空位了,访客点“刷新”,即可变成玩家,玩家位先到先得(晚了就还是访客噢)。
1. 我为什么要做《联机桌游合集》?
之前跟敌人团聚,但没带牌,很多桌玩耍不了。
我去搜公众号、小程序,但大都充斥着广告,或只反对线上匹配,或交互简单。
咱们迫切需要——没广告的、反对敌人联机的、简洁的工具。
因为我本人懂一点点前端和后端,就做了些尝试。
上个月,我开了个公众号“线下团聚游戏”,用来公布这些“工具”,目前做了五子棋、斗地主、UNO。
但因为它是联机游戏,所以线上的敌人也能够玩。
2. 技术选型?为什么?
通信
毫无疑问,这是须要 Client 和 Server 频繁交互的场景。用 HTTP 轮询、长轮询都不适合,会浪费资源。
所以我抉择了 WebSocket 作为通信协议。它跟 HTTP 一样也是基于 TCP 的,但差别在于,它 Client 和 Server 都能够被动发送数据,也随时可接收数据。
这样节约了带宽资源。
数据序列化协定
你可能会纳闷,这也须要决策?无脑 JSON 不就行了吗。
但我还真没用 JSON。因为 JSON 是基于字符串去序列化,它的体积必定会比基于二进制的序列化协定大一些。
因为波及到频繁的数据交互,且我服务器网络带宽不高,我不想一个收费的游戏给我带来太多老本。所以最后的技术选型尤其重要(如果当前再改,是很难的)。
我冀望有这样的协定:我定义好数据格式,比方五子棋游戏有 2 个字段,别离是“谁是黑棋”、“棋盘上棋子列表”。而我用第 1 位,0 示意房主是黑,1 示意房主是白。接下来 8 位,示意棋盘上有多少个棋子,假如为 K,那么接下来 K * 8 位,每 8 位就示意这 K 个棋子每个棋子的坐标。这样的数据序列化协定是最简短的。
然而我为什么要本人发明协定呢?这种货色,肯定有现有的协定实现了!必定不止我一个人想得到。
查了一下,还真有——Protocol Buffer。思路跟我心中的协定差不多,尽管空间比我心中的协定大了几位(能够疏忽),然而扩展性比我心中的协定好很多。
所以,数据序列化协定,我选了 Protocol Buffer。
这次技术选型,我又节约了带宽资源。
数据更新计划
这种桌游,肯定是数据驱动的。服务端存一份游戏数据,前端依据数据失去以后各个数据状态,依据数据状态渲染出游戏界面。
有 2 种数据更新计划:
长处 | 毛病 | |
---|---|---|
计划一:每次游戏数据更新,服务端同步全量数据给前端 | 能够有对立的版本控制 | 若游戏数据大,每次传输老本高 |
计划二:每次游戏数据更新,服务端增量更新数据给前端 | 每次传输成本低 | 可并发的增量更新,须要保障每个操作是原子操作;不可并发的增量更新,须要做好版本控制 |
如果是你,你会选计划几?你猜我选了计划几?
你可能认为我会故技重施,为了节约带宽而抉择计划二。
然而我选了计划一。为什么?
- 我的游戏是小游戏,只有保障总的游戏数据量足够小(甚至可能 1 个 TCP 包发完),那么你把 100b 压缩成 20b 其实是无意义的,他们可能只是 21ms 和 20ms 的差异。用户能感觉到 21ms 和 20ms 的差异吗?不能。
- 计划二增量更新的确迷人,尤其是针对《王者光荣》这种实时性强、数据量大的游戏。但我是个小游戏,实时性没那么强。而增量更新带来的前后端开发成本,是更高的,远高于收益。
后盾选型
这个其实只有反对 websocket 都能够。我用了本人善于的 python,用了 ASGI 协定,用了 Daphne 实现。
然而,python 解析 protobuf 是有老本的,好在 python 能够用 C ++ 实现。
最好的技术选型,其实是间接用 C ++ 改 Nginx 源码,以 Nginx 模块的模式实现小游戏后端。
然而开发成本比拟高,我为了疾速实现、落地、验证想法,就用了本人相熟的 python。前期有工夫的话,我会用 Nginx 模块开发的模式重构后端。
前端选型
既然曾经是数据驱动了,那么 React 再适宜不过。把游戏数据当作 State,收到后盾更新时,就setState
,那么 UI 就会自动更新。
当然 Vue 也能够,只是我对 React 更相熟。
用户认证计划
用户首次拜访,我会在后盾 Nginx 埋下随机数 cookie,无效工夫很长。之后都通过这个 cookie 来校验用户。
没 cookie 的,websocket 会回绝建设连贯。
之后用户能断网重连,也是因为他的 cookie 没变。如果用户删了 cookie,服务器就不意识他了。
监控计划
要做一个平台,你至多要晓得实时在线人数吧?这样能力晓得服务器负载如何,能提前去扩容。
我用了某云平台的日志工具做监控。通过后盾写日志,通过统计日志,展现服务监控。看个 pv uv 还是没问题的。
3. 技术实现亮点
UNO 是迄今为止,我做的复杂度最高的桌游,相熟我的敌人晓得,UNO 是我花了 7 天工夫做进去的。
为什么这么快?
大一统后端框架
首先,得益于大一统后端框架。所有游戏,他的后端其实是同一套,只是配置文件不同(例如可设置的最大人数、最小人数、游戏名称等等)。
相当于我把游戏开发复杂度全副转移到了前端,后端只负责数据直达。也就是说,其实每个人收到的数据,是同样的(如果你玩斗地主,你能解析数据,你会发现你晓得了其他人的牌。只是这个解析老本挺高的,你须要晓得二进制协定才行)
我这么做,也是为了晋升开发效率。
当然,可能有人会做外挂,然而我不会做在线匹配性能,只心愿提供给一群关系好的敌人去玩,敌人之间,你还开挂吗?(分分钟不跟你玩了 hhh)
前端脚手架和组件库
你拜访一下 3 款游戏,会发现,他们表面长得很像,只是换了个皮肤(色号)。
因为我做了一套游戏脚手架和组件库,把公共能力全副都抽成了组件,当前开发新游戏时,只须要写那个游戏独特的业务逻辑,其它货色,都被脚手架生成好了,组件库也拿来即用,所以开发效率特地高。这也是我能 7 天开发出 UNO 的真正起因。
其它特色
- 服务端实现简洁,无数据库依赖,数据临时都存于内存。
- 服务端如果须要更新重启,游戏数据保留!
- 有一套简略的 DevOps 体系,可帮忙我疾速开发、部署、上线。
4. 写在最初
我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。