style 表的结构化访问

我们游戏 UI 基于 RmlUI 的 fork,做了大量的改造。它实际上类似目前的 web 前端技术,使用 CSS 来表示 UI 的布局。所以,我们做的底层工作也都是围绕如何高效实现一套基于 CSS 的 UI 引擎来做的。 一年多前,我写过一篇 blog 介绍了一些优化的工作。 最近,在游戏开发的使用中,我们又发现了一些性能热点,最近在着手优化。这一篇 blog 记录一下其中的一个优化点。 按目前引擎的抽象,每个 style 其实是一组 attrib 的

避免帧间不变像素的重复渲染

上周五在公司内做了一个技术分享,介绍我们最近五年来自研的游戏引擎,以及最近一年用这个引擎开发的游戏。大约有一百多个同学参加了这次分享会,反响挺不错。因为这些年做的东西挺多,想分享的东西太多,很多细节都只是简单一提,没时间展开。 我谈到,我们的引擎主要专注于给移动设备使用,那么优化的重点并不在于提高单帧渲染的速度,而在于在固定帧率下,一个比较长的时间段内,怎样减少计算的总量,从而降低设备的能耗。当时我举了几个例子,其中有我们已经做了的工作,也有一些还没做但在计划中的工作。

游戏引擎中的可视化编辑器

提起游戏引擎,特别是商业通用游戏引擎,比如 Unreal 或是 Unity ,给人的第一印象会是它们的可视化编辑器。而在实际开发中,在不同引擎下做游戏开发,影响最大的是引擎层的 API 以及这些 API 带来的模式。 而对于使用自家专有引擎开发出来的游戏,却少见有特别的编辑器。比如以 Mod 丰富见长的 P 社游戏,新系列都使用一个名叫 Clausewitz 的引擎,玩家们在之上创造了大量的 Mod ,却不见有特别的编辑器。Mod 作者多在文本上工作,在游戏本身中调试。游戏

游戏数据包的补丁和更新

我们的游戏引擎是基于虚拟文件系统,可以通过网络把开发机上的目录映射到手机上。这对开发非常方便,开发者只需要在自己的开发机上修改资源,立刻就能反应到手机上。 但当游戏发行(也就是我们正在准备的工作),我们还是需要把所有资源打包,并当版本更新时,一次性的下载更新补丁更好。 之前一直没时间做这方面的工作,直到最近才考虑这个问题。我们到底应该设计一个怎样的补丁更新系统。 我不是第一次设计这玩意,早在 20 多年前我就为大话西游设计过一个。但我这次想重新思考这个问

Lua 的 C 模块之间如何传递内存块

Lua 的数据类型非常有限,用 C 编写的 Lua 模块也没有统一的生态。在不同模块间传递内存块就是件很头疼的事情。 简单通用的方法就是用 Lua 内建的 string 类型表示内存块。比如 Lua 原生的 IO 库就是这么干的。读取文件接口返回的就是字符串。但这样做有额外的内存复制开销。如果你用 Lua 编写一个处理文件的程序,即使你的处理函数也是 C 编写的模块,也会复制大量的临时字符串。 我们的游戏引擎是基于 Lua 开发的,在文件 IO 上就封装了自己的库,就是为

贴图管理模块及 UI 上的 3D 模型

我们游戏引擎的 UI 使用的是类似网页的技术,是将 RmlUI fork 出来的自行维护的版本 。目前游戏中大量遇到的一个需求是:把 3d 模型作为 UI 组件使用。这个需求在我经历过的历史项目中都曾遇到过,在不同的游戏引擎中我见过各种解决方案。 最典型的是 RPG 类游戏的人物属性面板。通常需要在面板上显示 3D 人物模型。通常还可以旋转这些模型,让玩家 360 度观看。我们目前的游戏类似 Factorio ,没有 Avatar ,但点开建筑的信息面板时,也需要把建筑的

虚拟文件系统的资源惰性编译

上篇谈了一下我们游戏引擎的虚拟文件系统(vfs)。我觉得这个系统中,游戏资产的管理部分还是个满有意思的设计,值得写一下。 VFS 的设计动机是方便把开发机磁盘上的数据同步到运行设备(通常是手机)中。传统游戏引擎的做法通常是建一个叫做资产仓库的东西,在开发期间不断添加维护这个仓库。需要把游戏部署在运行设备时,再打包上传过去。因为传统游戏引擎在开发期间一般直接在开发机上运行,所以打包上传(从开发机转移游戏资产)并不频繁。 而我们的游戏引擎特别为手机游戏开发而设计,我们不可能直

游戏引擎的虚拟文件系统

目前我们游戏用的引擎早在 2018 年就开始了。因为一开始,它就定位为一个主要用于手机平台的游戏引擎,要方便手机开发。因为我们不太可能直接在手机设备上编写代码、制作资源,所以开发机一定是和游戏运行环境分离的。从一开始,我们就设计了一个虚拟文件系统,它可以通过网络,把开发机上的文件系统映射到手机设备上,同时兼有版本管理的功能。这样,才可以做到在开发期间,开发机上所做的大多数修改,都能立刻反映到手机上。 我们的游戏引擎的大部分是用 Lua 开发的,这也意味着文件系统中不光有游戏

手机游戏交互的两点改进

最近在手机上玩我们正在开发的游戏时间比较多(之前主要运行的是 Windows 版),发现有许多操作值得改进。这里列举两个值得一提的交互优化。 第一,触摸屏上点击特别小的物件时很难精确。去年我提过一个解决方案 ,我们的游戏一直是这样处理的:连续 tap 屏幕同一个位置,会轮询这个位置附近的物件。这样,一次点不准的话,可以多点几次选到想要的焦点。这不仅可以解决小物件密集的时候,tap 不好区分的问题,还可以选到重叠的物件。这个方法其实在鼠标游戏中已有这么使用的了,比如 ri

一个任务调度算法引起的性能问题

这两天遇到一个任务调度算法引起的性能问题,花了颇多精力排查和解决。问题出在我写的 ltask 这个 lua 多任务库上。ltask 最初是对 skynet 的一些反思中开始的,最初只是想换一种思路实现 skynet :做一个库而不是框架、更少的锁竞争、避免服务因为消息队列堆积而过载…… 后来、我们游戏引擎开始尝试基于 ltask 利用手机设备上的多核,渐渐的便完善起来,也发展出和 skynet 不同的部分。它最近两年一直是围绕移动设备客户端程序优化,所以网络部分并非重点