May 29, 2023

Apple watch 折腾记

云豆想要一块电话手表。我了解到现在的小孩大多用小天才儿童手表,但考虑到云豆其实没有什么社交需求,我自己也有一块 apple watch ,所以想试试给他买一块。最初的想法是,儿童手表过两年估计娃就不愿意带了,而 apple watch (系列)可以用到成年。而似乎 apple 似乎也愿意做儿童市场,现在 apple watch 有家人使用的模式,不妨试试。

周六,网上订购的 apple watch se 到了。我给他创建了一个苹果的儿童账号,很顺利的就设置好了手表。但简单适用了之后就被劝退。apple watch 的家人模式功能上大打折扣,手表其实还是挂在我账号下的,而表上多绑了一个儿童账号。这导致除了苹果官方默认 app 之外,几乎所有的 app 都不能安装。包括微信支付宝这些。除了打电话,能用的通讯就只剩下 iMessage ,对小孩几乎没什么用。我想在手表上装个交通卡也未能成功:因为年龄不够(苹果要求 14 周岁),不能在钱包里添加卡片。苹果官网查了一下,儿童账号的支付功能只在美国才能开。

阅读全文 "Apple watch 折腾记" »

May 15, 2023

带娃玩桌游的第二篇

今天有同学在老帖子 上留言,看到下面杨博去年问这方面有什么进展,想想应该补上这么一篇。

最近几年,因为疫情的缘故,在家的时间比较长。孩子也长大了不少,能开的桌游多了许多。我现在几乎很少在外面和朋友玩桌游了,而在家几乎每周都会开三到四次。

云豆马上九岁了,可可也已经六岁半。兄妹俩的喜好已经明显有区别,我们能一起玩的桌游不多,一般我都是分开带哥哥玩,或单独带妹妹玩。不过有一款游戏大家一起玩的很多,那就是 Splendor (宝石商人)。

这款游戏发行商标注的是 10 岁+ ,在 bgg 上用户投票以 8 岁+ 居多,我感觉也是。7,8 岁的年龄完全可以充分理解游戏规则,制定整局规划。可可不到 6 岁多点也能玩,但是年纪比较小,仅能理解规则,无法深度思考怎样赢得游戏。好在她的胜负心很弱,每次输掉都能自我开解:玩个游戏嘛,输赢无所谓的。

阅读全文 "带娃玩桌游的第二篇" »

May 01, 2023

记一次艰难的 debug 历程

五一前,我遇到了一个非常难缠的 bug ,前后花了两天时间才把它解决。其刁钻程度,可以列入我职业生涯的前三,非常值得记录一下。

问题发现在节前两天,很多同事都请了假,我也打算好好休息一下,陪孩子玩几天。就在我例行更新游戏项目的仓库后,突然发现程序崩溃了。一开始,我并不以为意。因为我们的游戏是用 Lua 为主开发的,并不需要在更新后重新编译。我大约一周才会构建一次项目。或许这只是因为我太久没有 build 了,所以我随手构建了一下。但问题依然存在,只不过发生的概率偏低,大约启动三次有一次会出问题。这不寻常,因为我已经很久没见过 Segmentation fault 了。

阅读全文 "记一次艰难的 debug 历程" »

April 17, 2023

今年玩的一些游戏

我们正在开发一款类似 Factorio 的游戏 ,以修建自动化工厂为主要玩点。其游戏背景接近火星殖民。所以,最近一年我玩了相当数量有类似点的游戏,希望能得到一些启发。

其中有三款以火星殖民为主题的新游戏我个人很喜欢,值得推荐一下:

其一是 Farlanders ,像素化的画风很复古,很对我的胃口。游戏是回合制的,节奏很快。从中可以找到许多桌游的元素。紧凑的四边形格子地图,地形改造,隧道、电线、水管,这些都需要玩家精心布局。

如果玩自由模式的话,后期会偏简单,有点无趣。但是它的故事模式的难度调的相当好。如果选困难(我觉得开发者是围绕这个难度制作的),到了第 6 关就很难一次过关了。

btw, 我在这个游戏中还学到了一个交互设计上的防呆处理手法。

菜单有一个按钮是不希望玩家误碰的(因为可能会删除档案),一般的做法是按了之后再弹出一个模式对话框二次确认;也有人做成这种按钮需要长按一段时间才能确认。

而这个游戏的做法是按了这个按钮后,在按钮的右侧再出现一个新的按钮,上面有画有一个勾勾。玩家需要移动鼠标去点击这个新的勾勾按钮才真的执行该操作。没有其它额外的说明文字。这个防呆设计让我觉得很舒服,而且非常适合在手机上实现。

阅读全文 "今年玩的一些游戏" »

April 12, 2023

SQL Server 向 MySQL 的迁移方案

昨天做内部晋升评审时听到候选人介绍他即将开始的一个项目。大致是我们公司从韩国买过来一个游戏(有全部源码)打算自己运营。该游戏服务器全部用 C++ 编写,使用 SQL Server 做数据库。我们这个项目,除了需要根据市场做二次开发外,还希望把 SQL Server 迁移到 MySQL 上。成本是最主要的原因,如果可以迁移成功,成本将减半甚至更多。该成本差异主要在 SQL Server 的使用执照费用,以及同等任务所需要的云成本。

我在反复确认了这项工作是否真的有做的价值(从 SQL Server 改为 MySQL)后,讨论了一下具体实施方案。

移植的难点在于该项目大量使用了 SQL Server 的存储过程。几乎所有的业务逻辑都是人肉写在 SQL Server 的存储过程中的,大约有 20 万行。虽然 SQL Server 的存储过程和 MySQL 的差异不是特别大,但再靠人一点点重写成本上也不划算。

阅读全文 "SQL Server 向 MySQL 的迁移方案" »

March 30, 2023

短 ID hash 映射的问题

今天解决了一个问题,觉得很有趣。本来想发到推特,发现一两句话说不清。所以写一篇 blog 记录一下。

我们正在开发的游戏中,会用一个 id 来表示一个游戏对象到底是什么。比如,“铁片” 是 1 ,“煤” 是 2 ,“采矿机” 是 3 …… 这样,在运行时,C 代码可以根据对象的类型方便的查询对象的属性。而对象的属性则是用 Lua 配置好,在运行期不变的。例如每燃烧一个单位的“煤”,可以产生 100KJ 的热量;一箱“铁片”有 100 个。

为了在 C 和 Lua 间快速共享这些配置数据,我还专门写了一个 cache 模块

问题出在 ID 的持久化上。因为游戏中的物品种类并不是特别多,出于时间以及空间性能的考量,我把 ID 设计为 16bits 。64K 种物品种类的上限看起来足够了。但 ID 的分配却比较麻烦。

最简单的做法是,在程序运行时,用一个自增 ID 分配给每个物品类型。但这会导致 ID 极不稳定,考虑到 ID 需要持久化,在开发过程中,持久化的存档也变得很不稳定。所以我选择了用物品的名称以及一些内在的参数(例如版本号)一起计算 hash 值当作 ID 使用。

阅读全文 "短 ID hash 映射的问题" »

March 23, 2023

继续学习神经网络

这段时间忙游戏项目之外,继续花了几天学习神经网络。

上一篇 blog 发布以后,收到了图灵的朋友的 email 。然后,我收到了一大堆(九本)图灵出版的关于人工智能的中文书。通常出版社的同学给我邮寄新书,或多或少是希望我能写点什么。我不想刻意帮人宣传新书,但倒是不介意推荐一些我自己读过的不少的东西。

这次收到的书太多,当然没有全部读完。但书的内容相关性都很强(差不多一个主题)。去年的时候,我读了《如何阅读一本书》,里面提到读书的四个层次。第四个层次就是就一个主题同时读多本书是非常有意义的。这次,我也颇有收获。

阅读全文 "继续学习神经网络" »

March 08, 2023

学习神经网络的一点笔记

最近 AI 很火。我从读书的时候就对 AI 有兴趣,90 年代的时候读过一本关于神经网络的书。但当时没有能力完全理解。2000 年初刚毕业那会儿想搞明白点,又研究过一段时间。了解了很多相关知识,感觉自己弄明白了,但却没有真正动手实践过。

现在,所有人都看得到,AI 已经变成了一个可以真正帮助我们提高生产力的工具了。我觉得有必要好好学习一下。我并不期望几篇文章就可以搞清楚,那样只会让自己好像懂了,和人聊天估计够用,想理解它还是得自己动手。真正写几段代码,才有触碰的感觉,明白别人到底在解决什么问题。

一开始,我是从维基百科的 Machine learning 开始读的。顺着看了一整天,了解了近年发展的脉络。好多词条,乱七八糟的笔记记了一大堆,感觉快消化不了了。疑问也积累了很多,觉得看下去效率会越来越低。不如换一条路。

然后我开始读 Neural Networks and Deep Learning 这本书。读了两章后,我想,手写数字识别看起来是一个非常好的实践手段,不如自己写一遍最快。有这么一个基础,后面可以继续修修补补,沿着前人的轨迹走一下,可以更好的理解为什么。

阅读全文 "学习神经网络的一点笔记" »

February 14, 2023

Aura 一个嵌入式小语言

上周看到了 Redis 作者的新玩具语言 Aocla ,感觉很有启发。它是 FORTH 和 Lisp 的杂合体,又增加了一些内嵌局部变量的支持。非常像我前两年给我们数学库做的一个小东西。最初的想法是为数学库设计一个 DSL 潜入 Lua ,在做复杂的数学计算过程时,可以把计算过程停留在 C Side ,减少 Lua 和 C 之间的边界成本。最初的版本是我模仿 FORTH 设计的基于栈的小语言。希望牺牲一些表达能力,换取一点性能。但实用起来过于别扭,后来又增加了一些特性却没有本质改进。最后终于决定把这个 DSL 彻底从数学库中剥离了

阅读全文 "Aura 一个嵌入式小语言" »

February 06, 2023

同一 Entity 包含多个同类 Component 的问题

ECS 中,同一个 Entity 是否可以由多个同类型的 Component 构成?在 Unity 中,答案是可以。我们的引擎在设计之初也是可以的。

当时有一个问题:在 Lua 中,如何访问同类型的 Component ?如果有多个同类 Component ,最自然的方式是把它们放在一个数组里。但是、绝大多数情况下我们用不上这个特性,每次访问 Component 都加一次 [1] 或 [0] 的数组索引显得画蛇添足。若单个 Component 不用数组,多个才用数组,写起来又有极大的心智负担。因为这样做,它们就成了两个不同的类型。

后来,我们干脆利用 Lua 的特性,把数组和 Component 本身放在一个 table 中。如果有多个 Component 就把这个数组直接放在第一个 Component 的 table 内。就这样用了一段时间后,最后还是受不了这个脏技巧。等到用 C 编写 luaecs 后,就砍掉了这个特性。

ECS 不是万能灵药。如果需要让相同的 Component 聚合在一起,那么就使用额外的数据结构,或是不只使用一个 world 。这是我们目前实践给出的答案。去年在 luaecs 的 issue 9 也讨论过类似问题。

阅读全文 "同一 Entity 包含多个同类 Component 的问题" »

January 20, 2023

最近开发中解决的一些性能问题

今天是年前最后一天工作,我想对最近做的一些事情做一些记录。

我们在使用自研引擎开发游戏时,遇到了不少和预期设计有距离的问题,针对问题再反思了原有的设计并做出改进。我认为、凭空设计一个通用游戏引擎是不可能的,必须结合实际项目,做许多针对性的实现。但同时应不断反思,避免过多的技术债。在最近一年,我参与的引擎具体编码工作很少,更多的是站在一个反思者位置,监督代码和设计的演变。

我们的引擎主体框架是基于 Lua 的,受益于 Lua 的动态性,可以很方便的把各个模块粘合在一起。但是、Lua 和 C/C++ 相比,又有两个数量级的性能差异,对于渲染代码而言,若将和 GPU 沟通的 API 完全放在 Lua 的 binding 层,对于对象数量巨大的场合,很容易出现性能问题。我估计、在手机环境这个“巨大” 差不多在 10K 这个数量级吧,而 PC 环境还能支撑到 100K 左右。

Lua 项目的优化无非两条路:使用 jit 技术、把热移到 C side 。正如 Roberto 所言,"Finally, keep in mind that those two options are somewhat incompatible" 这两条路需要的操作往往是互斥的。而我不喜欢 jit 带来的复杂度和不确定性,所以选择了后者。

为了解决大数量对象的批量操作问题,我在 2021 年进入了 luaecs 。这个库现在已经是引擎的核心,专门用来解决 Lua 处理大数据重复事务的性能问题。通过 luaecs ,我们可以把对象的初始化这个繁杂的过程使用 Lua 编写,而每帧都迭代的事务用 C 来实现。

一般来说,如果 10K 是场景可渲染对象的数目的话,那么对于很多游戏场景还是适用的。但如果Lua 调用的图形 API 放在太底层,手机上(以 Apple 的 A9 芯片为下线)一个流畅的场景却很难支撑到 10K 对象。这是因为,每个可渲染对象需要一系列参数传到图形 API 层,设置 VB/IB 渲染状态,尤其是大量的 uniform ,这些 API 差不多会在 10 个调用左右,它们会吃掉一个数量级,最终 Lua 层能流畅处理的数量大约只剩下 1K 左右了。

阅读全文 "最近开发中解决的一些性能问题" »

January 10, 2023

虚拟文件系统的 mod 机制

上次谈游戏引擎的虚拟文件系统是去年 10 月了。最近我们又做了一些修改。

我们的虚拟文件系统有两个工作模式。一种模式主要用于编辑器和开发环境,所有的文件名和路径都基于原生文件系统,我们叫它编辑器模式;另一种模式被称为运行时模式,主要用于运行时环境。文件均用类似 git 仓库的形式,用文件内容的 hash 值作文件名,储存在一颗 Merkle tree 上,并通过一个专门的 file server 为运行环境提供资源的更新服务。

在编辑器模式下,并不是直接映射原生文件系统的整棵目录树的,而是增加了一个 mount 配置,可以把很多不同的目录装配在一起。当初这么设计是希望提供一定的灵活度,方便游戏项目可以把引擎提供的基础功能和资源组装进来。

阅读全文 "虚拟文件系统的 mod 机制" »

December 20, 2022

covid-19 感染康复记录

月初还和同事调侃,这次谁也躲不掉,感染是迟早的事。最近全家都中招了,好在病毒这次还算轻柔,差不多都痊愈了。在此记录一下这次的历程。

起点是广州的全面开放。老婆在家已经被关了快一个月,憋得不行。开放第一个周末,就约了同事出去玩,周五晚上密室、周日下午(12 月 11 日)出去拍照。

我觉得广州已经放开,这次病毒的 R0 相当高,快速传播开无可避免,第一个周末外出有非常大的风险。所以取消了原本每个周末的攀岩活动,和两个孩子继续关在家中。儿子一直有点咳嗽,我有一些感冒,有流鼻涕的症状。

Day 0 (12 月 12 日周一)

老婆被通知一起玩的同事已经确诊,需要她居家办公,观察一天再考虑回办公室。

我当天正常上班了。这天我之前的感冒症状(流鼻涕)已经完全消失,精神状态非常好。

晚上她有一点低烧(38 度),自测抗原阴性,觉得是因为感冒。这一晚,女儿和妈妈睡觉。

阅读全文 "covid-19 感染康复记录" »

Misc

Categories

Archives

Recent Comments