September 23, 2024

最近玩的几个游戏

这个月没有写什么程序。月初停下手头的开发工作,花了一周时间,作为 Indieplay 评委试玩了 200 多个参选游戏中的 100 多个。这个工作暂停之后,我就对前两个月对自己想做的游戏产生了许多疑惑。虽然写了不少代码,但仅限于基础玩法的外在功能:我实现了一整套类似边缘世界和缺氧里的工人系统,让小人可以在场景中活动起来,采集物资,建设建筑。让机器可以通上电运转起来,把原料加工为成品。但这些似乎只是一种模拟过程,而并非游戏。

我感觉自己对游戏到底想展现怎样的游戏体验没有清晰的认识。虽然在这篇采访中 也提到,(缺氧的最初设计是)“希望整个游戏运行在一个开放的(虽然简单的)模拟之上”。但我觉得模拟毕竟不是游戏,难以给玩家提供丰富的游戏体验。或者说,至少对于我这样的玩家,没有清晰的游戏目标和挑战是不行的。而且,实现一个丰富的游戏环境模拟面临的挑战我现在还无法评估,至少在当下,这不是我优先想做的东西。

我给游戏定下的基调是基地建设加生存挑战类型,或许应该有一些资源管理和 Roguelike 元素。工人管理或自动化元素是我比较喜欢的,但玩过几千小时类似游戏后,我感觉这些元素只是给予玩家体验的一种手段,并非目的。单独玩某个特定玩法,或许也能有趣,但体验却会大相径庭。

阅读全文 "最近玩的几个游戏" »

September 03, 2024

Ant 引擎的一些改进计划

我独自开发游戏已经有三个月了。这三个月里,我是 Ant Engine 唯一活跃用户,这是一个很好的机会来挖掘对于一个独立游戏开发者来说,引擎哪些地方有缺失。现阶段,我还是希望把精力放在游戏开发上多一些,所以引擎方面恰恰够用就好。虽然,完善引擎这件事做起来会更愉快,因为这些工作对于我比较顺畅,容易想清楚,游刃有余;而一个人开发游戏,更多的时候是手跟不上心而产生的烦闷。

我还是想挑战一下自己,把游戏设计好,实现好。引擎方面的事情,把想到的东西先记录一下。或许完成手头的游戏项目,沉淀更多,再回头做引擎,愉悦感更强一些。

首先,可视化编辑器 对我来说不重要。所以暂时就不维护了。我更需要的是一些快速验证眼下游戏设计中想法的功能,这些就在游戏 demo 中顺带实现就好,看起来没必要放在编辑器里。这和现阶段没有美术参与也有关系。因为对我自己做独立游戏来说,我不在乎开发进度,先做美术还是后做美术,区别不是很大。本来我自己就喜欢传统 roguelike ,几个 ascii 字符就能脑补所有的美术表现。我想,游戏原型阶段就不需要美术在编辑器里做创作了,用一些几何体就够用。这也是为什么我在三个月前最先完善的就是 Ant 引擎中预制几何体 这个功能的原因。

我在使用 Ant 引擎的时候,发现因为缺乏具体 API 文档而只能不断的阅读源代码(毕竟有很多模块不是我自己动手写的,无法全部了然于心)。而且并非每个模块的设计都满意,这让我经常有修改引擎的冲动。做了一段时间后,我找到一个方法来解决这个开发问题。我可以额外再做一个精简版的框架,按目前开发游戏的需求,从最基本的功能做起,逐步完善。这样就能隔绝引擎已经做好的部分:好用的模块直接做一些浅封装,有问题的部分可以多花些精力做不侵入(破坏老代码)的改进。

本来根据游戏类型的不同,使用引擎的方式就会有很大差异。我希望可以有不同的这样的框架针对具体类型游戏做二次封装。这样,在二次封装上写游戏的花,后面就可以更放心的裁剪底层实现。我更希望让 ECS 框架还原成更原始的设计:面向数据,避免添加太多的辅助模块。

阅读全文 "Ant 引擎的一些改进计划" »

August 24, 2024

一个简单的 C 模块管理器

我在用 C 构建项目,尤其是和 Lua 混合使用时,一直很头疼 C 没有一个统一的模块管理器。Lua 的模块管理虽然简单,但毕竟有且够用。一种方法是把 C 模块封装成一个个 Lua 模块,让 Lua 帮助管理,每个 C 模块是独立的,相互不可见。

但当 C 模块之间发生关系时,就比较麻烦。当然,简单的方法是通过链接器把它们都链接在一起,通过函数名前缀以区分。或是利用操作系统的动态库加载器来管理模块。

最近有了一点有趣的想法,觉得一个最简的模块管理器其实复杂度并不高。花了半天功夫实现了一下,感觉还不错。

https://github.com/cloudwu/cmod/

阅读全文 "一个简单的 C 模块管理器" »

August 18, 2024

32 位 handle 的一种生成方法

我倾向于在 C 程序里使用整数 handle ,而不是指针。尤其是需要做弱引用的时候。

我认为,一个好的 handle 生成算法,应该满足:

  1. 即使 handle 被销毁了,它这个数字也应该被保留,不应该被新的 handle 复用。posix api 里的文件 id 就不符合这一点。
  2. 提供一个 api 可以判断一个 handle 是否有效,其时间复杂度为 O(1) 。
  3. 从 handle 对应为对象的内存地址的时间复杂度应该为 O(1) ,不应该比指针有明显的性能问题。虽然 hash 表理论上可以满足 O(1) 的时间复杂度,但在糟糕的场景(hash 碰撞发生时)并不能保证这一点。
  4. 构造 handle 时间复杂度也为 O(1) 。
  5. handle 的数字位宽最好不要超过 32 bit 。

阅读全文 "32 位 handle 的一种生成方法" »

August 13, 2024

基地建设(工厂)类游戏的玩家体验

这两天思考了一下,基于工厂生产的基地建设类游戏给玩家提供的核心体验到底是什么?以及,我们去年被取消的游戏到底还差点什么。接下来我要制作的游戏的注重点应该在哪里。

我玩的时间比较长的两个基地建设类游戏:异星工厂和缺氧,它们的玩法其实差异很大,但却给人一些近似的体验。对于这个问题,我想过很多次,得出的结论是,它们的确有一些共通之处:

玩家在玩这两个游戏时的情感体验过程非常类似,大致是这样的:

阅读全文 "基地建设(工厂)类游戏的玩家体验" »

August 08, 2024

gameplay 框架设计总结

游戏行业从业 20 多年,一直在做底层开发,即使是帮助其他团队写上层游戏逻辑,也都是实现某些特定的功能模块。直到最近,我想单独开发游戏,才好好想想架子该怎么搭。

从最初的原始 demo 开始,由于缺乏经验,写着写着经常有失控的感觉。好在一个人做,重构的心理负担不大。想改的时候,停下来花上两三天全部重写也不太所谓。最近总算顺畅了一点,感觉需要整理一下思路,所以写一篇 blog 记录一下。

任何复杂的软件问题,都可以通过拆分为若干子问题减少复杂度。

我认为,游戏的上层逻辑,即 gameplay 部分,主要分为三块:数据模型、外在表现和人机交互。

“数据模型”是 gameplay 的核心部分,即把游戏的画面等外在表现以及图形界面、操作控制(鼠标键盘控制器等)等剥离后的东西。如何判断一个模块是否属于数据模型,是否有不属于它的部分没有拆分出去,最简单的方法是看它是否有直接调用游戏引擎的代码。拆分干净后,这块不应该包含任何与图形、界面、时钟、控制输入有关的接口。除了一些必要的文件 IO 接口(主要是用来读取 gameplay 相关的策划数据,写 log ,做数据持久化等),也不应该涉及任何 OS 的 API 。

这样,我们就可以方便的对它进行整体或局部的测试。必要时还可以更换游戏引擎,甚至从文本 roguelike 换到 3D 表现都不会受影响。

“外在表现”当然是指游戏的画面表现、声音声效等等,通常这由游戏引擎实现,但还会有大量的代码存在于 gameplay 的实现中。这一块代码也会维护大量的状态,但不会涉及数据持久化。简单的判断方法是:如果游戏保存进度时,所有这里的所有状态都可以舍弃,下次读取进度后,这些状态又能被重建,而玩家不会感觉丢失了任何数据。

“人机交互”是游戏软件必要的部分,如果没有“人”的存在,游戏也就没有意义了。这块分为两个部分:图形界面用于展示游戏的数据给人看,同时接收一些来至界面的间接输入;控制器(包括并不限于手柄鼠标键盘触摸屏等)对游戏的直接控制。

对于联网游戏,还应包括第四大块:“网络输入”。这篇 blog 仅讨论非联网游戏。

阅读全文 "gameplay 框架设计总结" »

July 25, 2024

工人任务分配系统

在矮人要塞 like 的游戏中,都有一套基于工人的任务分发系统。玩家通常不能像 RTS 中那样直接操作工人去工作,而是对要做的事情下达任务,等着工人自主去完成。

由于任务数量通常远多于工人数量,这个任务分发系统中大多配有优先级设置,可以让诸多任务有条不紊的进行。调整优先级变成玩家主动操控的渠道。初玩这类游戏,会有点不习惯:感觉难以在微观层面直接做自己像做的事情。像捡块石头放进指定仓库这件事,无法像玩 RTS 游戏那样,先点选工人,再针对石头发出拾取指令…… 但习惯之后,恐怕又回不去了。比如我在玩 Ratopia 时,就对操控鼠王直接干活烦躁不已。

这类游戏,我玩的时间比较长的有三个,按时长排序为:缺氧 (ONI) 、边缘世界 (Rimworld)、矮人要塞 (DF)。其它如 Songs of Syx 、Prison Architect 等很多也有所涉猎。其实,这些游戏在设计工人任务系统的细节上也有所不同。

以我游戏时长最长的缺氧和边缘世界相比较,同样是提供玩家主动操控的能力:Rimworld 可以给工人的任务队列直接下达指令(这更接近 RTS 的玩法),而 ONI 则是通过给单个任务本身排优先级实现的。ONI 设计了警报级任务,可以越过一切优先级设定,强制立刻完成。虽然 ONI 也保留了指挥单个小人移动到指定位置,但实际游戏中几乎没什么用。

对于拾取物品,Rimworld 可以封禁、解禁单个物品,而 ONI 没有这个设计。ONI 的工人几乎不会主动把地上的东西搬入仓库,除非下达清扫指令。

这些细节的不同,可能来源于作者设计时的思维轨迹,很大程度上也取决于游戏的其他玩法。例如 Rimworld 偏重手控成分很重的战斗,而 ONI 没有战斗成分。Rimworld 强调人物之间的情感联系,ONI 里的都是工具人。

我比较喜欢 ONI 的系统,打算用这个规则打底设计自己的游戏。下面是设计的草稿:

阅读全文 "工人任务分配系统" »

July 16, 2024

飞船建设部分的设计草案

像异星工厂、缺氧、边缘世界都有大量的 mod 。可以通过大改游戏机制,把本体游戏改造成完全体验不同的游戏。这些好玩的 mod 几乎都是一个人完成的。所以我觉得,固然游戏的外层玩法决定了整体体验,但其实开发的总工作量并不大。而且,一旦玩法不满意,也容易修改。

我的游戏开发计划是先完成一些底层基础系统,再考虑完整游戏的全貌。没有上层玩法支撑,光有底层系统玩起来一定寡淡无味,但我认为它们是设计和开发中最重要的一环。

在进一步实现 demo 之前,我设计了一下飞船的建造系统。

阅读全文 "飞船建设部分的设计草案" »

July 10, 2024

室内空气流动模拟

在设计飞船建造的游戏时,我想做一个空气流动的模拟系统。这里有一个初步的方案,不知道好不好,先记录一下:

  1. 空间是由二维的正方形格子构成的,有些格子如墙体会阻止空气流动。每个格子有温度属性及气体质量的记录。不同气体可以同时存在于同一个内,质量单独记录。温度传导系统另外设计。
  2. 每个游戏 tick 对每个格子做一次独立计算,根据温度值给出一个概率,这个概率决定了该格气体向周围扩展的比例。
  3. 温度越高,越可能将更大比例的气体平均扩散到最多邻接的 8 格空间。
  4. 当格子因为建墙而导致空间变化时,把该格内气体全部扩散到临接格,当极端情况下无法做到时,空气锁定在墙体内,不会消失,等待以后满足条件后再扩散出去。

阅读全文 "室内空气流动模拟" »

July 02, 2024

角色动画系统

Ant 引擎的角色动画系统还需要完善。

之前我们用 Ant 引擎开发的游戏以机械装置为主,所以并不需要人型角色动画。对于人物角色动作的动画控制,最好有更多的引擎支持。

通常,角色逻辑上的属性和动画表现存在一个映射关系。一个角色,它逻辑上的基本属性可能只有在空间中的坐标。我们编写代码控制它时,只关心它在哪里。但是,在做画面表现时,则需要根据空间坐标这组简单属性,转换为动画播放:如果角色静止不动,就播放 idle 动画,如果正在运动,就播放 walk 动画。

阅读全文 "角色动画系统" »

June 22, 2024

一些星舰或太空站建设类游戏

因为玩了一些星舰或太空站建造类的游戏,找找灵感。每个游戏都能给我一些启发,因为玩的都不多,所以就不评价了,只做个列表记录。有些还没有出,先加了个愿望单。

June 11, 2024

监视 Lua 对象的修改

我正在制作的游戏 demo 中,所有对象逻辑上都存在于二维空间,但在 Ant Engine 中通过 3d 渲染方式绘制出来。

我希望有一组简便的 API 方便我控制这些对象的渲染,只是控制它们的位置以及在 Y 轴上的旋转量。Ant Engine 是用场景组件来控制 entity 渲染时的空间状态,但场景节点使用的是 3d 空间的 SRT 即缩放、旋转、位移。而我只需要控制其中的两个坐标轴上的空间位置以及一个旋转轴上的旋转量,直接修改 SRT 太不方便了。而且,使用引擎时,还需要每帧标记被修改过的场景组件对应的 entity ,这也很麻烦。

在 ECS 结构下,最简单的方式是为这些 entity 创建一个额外的组件,里面有 x y r 三个值。通过一个 system 把它们转换到场景节点在 3d 空间下的 SRT 组件中。但如果每帧都全部转换一次显得多余,毕竟大部分 entity 不是每帧都会发生变化的。

我用了一个简单的 Lua 技巧来方便开发,下面便是代码:

阅读全文 "监视 Lua 对象的修改" »

June 07, 2024

一个游戏的点子

宅在家里一个月了。一直在想,如果不考虑迎合市场,不顾及销量,到底应该做一个怎样的游戏才能让自己在制作过程中得到满足。

过年前曾经参加过一次老同事聚餐。组织者说,这屋子坐的都是做游戏的老人了,程序、策划、美术全齐了,还都是不差钱的主。大家要不要凑个局,想想做个啥游戏出来?接下来是一阵沉默,直到有声音说,“我没什么想法”,饭桌上的人纷纷点头,转移了话题。

前段参加一个独立游戏活动,见了些老朋友。有位同学做游戏很多年了,说起这些年的经历,入行头几年是给老板打工,接下来开了家小公司自己做,没赔钱也没赚钱。但干下来感觉变成了给员工打工。为了可以持续发出工资,每次立项都很匆忙,结果还是在不喜欢的游戏项目上耗掉了太多时间。现在干脆把团队安顿好,一个人出来,好好想想到底要做什么。

可见,想清楚做什么很难。单独一人的状态也很难得,没有太多的外界干扰,不为了做事而做,可以慢慢来。

首先,我想做一款游戏,这毋庸置疑。玩游戏是我这些年最大的爱好。光在 steam 上这些年就花掉了上万小时,switch 上也有几千小时。我能在制作游戏的过程中获得我要的东西。

其次,做一款游戏的目的不是为了收入。我对物质生活要求极低,不需要花钱满足欲望。除非需要雇人一起做游戏,不然制作游戏的开销只是自己家庭的日常开销,而我这些年的积蓄已够过完余生。我喜欢的游戏都不需要太复杂的美术资产,这方面并不需要额外的投入。

另一方面,我也不需要用游戏讨好玩家来获得成就感,不需要用一个产品来证明自己,这些成就感的体验都已有过,不是我想追求的东西。

所以,我所需要的是制作过程带来的持续体验,让自己觉得自己在做一件有意义的事。我所喜欢和擅长的其实是:认清问题,解决它们。

阅读全文 "一个游戏的点子" »

Misc

Categories

Archives

Recent Comments