《抛投大乱斗!》EA分享06:满身污泥&技术选择与对赌&散人之道

作者:Rocktaoist
2023-05-11
4 0 2

前言

一个月一眨眼就过去了,再不写,这个系列日志马上就会长蘑菇。

迟迟未写日志的原因,是陷入了制作联网功能的泥潭。在学习过程中,不得不正视一些不断被我推迟的代码知识,正是这些阻碍了我深入学习的可能。

下面聊一聊让我陷入泥泞的技术方案、其产生的原因以及此过程中的思考和感受等;并以此延伸,简单谈谈我个人关于技术对赌的认知;最后顺道说几句额外的话:关于技术散修的一些看法及简要分析(胡说八道)。

满身污泥

SteamLobby

SteamLobby 是 Steam 提供给开发者的联网大厅,每一个 Steam 应用的 steam_appid 提供了一个专门的房间。这有点类似浩方平台提供的房间号,能够让玩家聚在一起玩局域网游戏。

而 Mirror 能够让 Unity 快速搭建局域网游戏——让其中一名玩家成为主机端,其他玩家则转变为客户端。

读取 steam 用户,和简易的大厅设计

Steam_appid:Steam 应用的识别 ID。

Mirror:Unity 的一个局域网插件,能够让开发者快速制作出局域网游戏。

插播一句,如果第一次开发联网游戏,可以用虚拟机测试。


跌落泥潭

去年的开发计划里,《抛投大乱斗!》(下称《抛投!》)没有联网功能,因为这会产生太多超出边界的学习成本和制作成本。

另外,在技术选型期间,曾看过一些 Photon 的教程(能够让 Unity 网络联机的一个技术方案),但存在两个问题:

  • 没有与之对应的,足够深入的教程;
  • 担心掌控得不够深,会出现技术崩塌。

这让我很果断地抛弃了联网的想法。

但今年,有朋友告诉我 Steam 提供了很便捷的联网功能,我顺着关键词看了看,竟然还有 Steamwork 的.net 文档适配(当时没认真看)。

在我当时的幻想中,可能调用几个 API 就能够搞定一切;接着顺手浏览了几个通过 SteamLobby 联网的教程,感觉可以尝试;再加上老朋友们直言不讳:你不做联网,死路一条。于是我咬咬牙,决定投身网络模块。

不过很快,就一头撞到了墙上:

  • 不具备通信知识,导致对这项工作的风险评估严重失调;
  • 不清楚程序中间发生了什么,致使敲代码的过程有一种失重感;
  • Steamwork 的.net 文档,实际上没有 C# 对应的 API 解释,需要参照官方的 C++ 进行理解;
  • 不懂 C++,无法评估投入到 C++ 语法的学习会产生多少风险;
  • 简中网络缺少关于 SteamLobby+Mirro 的、足够深入的资料;
  • Mirror 提供的 exsample 啃不动,文档有诸多对不上的地方。


Mirror

Mirror 提供了一个快速进行局域网联机的框架,通过使用组件和派生类,能够简便、快速地做出一个局域网联机游戏。但能够方便快捷的前提是,需要从一开始就按着它的路子来:

  • Mirror 提供了一个用来管理服务器的 NetworkManager 类,当玩家以客户端的身份加入游戏时,这个 NetworkManager 会生成一个与客户端对应的预制物;
  • 每一名玩家的输入输出都会与该预制物绑定。

这种设计与我的代码设计有冲突。我之前是通过控制器驱动与预制物、玩家进行绑定,已经有了 InputSystemManager,现在再来一个 NetWorkManager,可想而知,极有可能产生灾难(当然,如果有能力拆分 Mirror,这些便不是问题)。

除了上述一堆痛点外,还有一些让我喘不上气的问题:

  • 重连如何处理?
  • 网络适配如何优化?
  • 控制器怎么交换?
  • 如何才能够让联网数据松耦合?
  • 会不会因此影响本地模式?
  • 更高的 fixedUpdate 帧率,会不会产生变故?
  • 大厅怎么设计?怎么清理无效用户?
  • ……

当我把这一连串问题写出来以后,甚至产生了不想继续的念头(但还是打算继续投入两周学习通信知识,看看能不能挽回沉没成本)。

当然,以上尝试也不是全无收获:

  • 在拆分 Mirror 案例时,它对特性的应用引起了我极大的兴趣,我现在正掉头重新学习反射与特性,也是为了将来可能用到的 IOC 做准备;
  • 网络联机功能最好不要在开发中途加入,伤筋动骨;
  • 以后只看流行的技术,生僻技术不看。

技术选择与对赌

经过这次失败的联网尝试,我再次思考如何改良自己的学习路径——独立游戏开发者一个很重要的品质,是在决策时注重风险与收益的比较。

技术学习的过程,实际上需要投入非常多的精力去评估每一次学习的成本与收益:市面上的可选技术线实在太多,各个技术线的拥趸都在呐喊自家的技术线天下无敌,如果动手之前不仔细思考,那么幸幸苦苦获取的知识最终很可能被遗弃在脑海的某个角落。

那么,关于技术线怎么选取?

每个开发者自身的经历都不可复制,应对的需求场景又截然不同,想要使用某种万金油解法,必然不行。所以很多时候,都是在风险与回报之间取舍。

这让我想到德州扑克——独立游戏开发的技术抉择,很多时候像是在打德州扑克:

  • 手牌——个人的认知、技术优势;
  • 公共牌池——市面上公开的技术池。通过学习公开技术,与自身优势产生组合;
  • 对手的牌——未来的坑。对手的牌如果能与公共池组成更强势的结果,上了牌桌的开发者就会无路可退;
  • 筹码——开发者的时间与资金。

如果把独立游戏开发这件事的商业成分剥离出来,大概就是这么一回事。

那么说个题外话,诈唬对应独立游戏开发的什么行为?我认为是还未度过愚昧之峰的开发者们,疯狂渲染某些技术的难度。

把德州扑克的对赌思路映射到我的这段经历,则是:

  • 现存的代码知识就是我的手牌,而联网功能就是还未掀开的公共牌;
  • 当我自信满满地打开下一张公共牌,与手牌一合计,却发现不达理想,最终叫苦不迭。

但这种信息不对称本就是常态。如果没有一个优秀的先行者带路,在这个信息嘈杂的赛博垃圾场四处碰壁才是日常。

许多时候,在网上看到的成功后总结,大多都只是在射箭画靶(预言型选手除外)。而失败往往才值得借鉴,因为失败这件事本身是一个高密度的信号。

本次的一些反思:

  • 将来在自身一片空白的领域学习时,如果技术对应的流通度不够高,不会考虑,除非有值得这么做的高回报;
  • 什么时候最合适技术冒进主义路线?首先得自身专精这条技术线,此外还有大量空余时间;
  • 独立游戏开发过程中,很多时候,有效的学习时间是无法挤出来的,大部分工作都是在消化曾经堆积的知识;
  • 当坚定要学习已经流通于市面的知识时,学会实际是必然的,真正困难的点是如何提高学习效率。

散人之道

散修,即是指学习者不专精某个方向的技能。散人之道,则指开发者需要让自己成为多面手,最终演变为通才。这里尝试简要分析散人的特点与利弊。

首先说说散修的特质:1.散人需要在记忆与遗忘之间找平衡;2.散人各不相同,最好独具一格。

记忆与遗忘的平衡:

  • 如果开发者的遗忘能力太弱,难以忘记东西,那么脑海里无数的想法会不断干扰工作,导致效率下降;
  • 如果记忆力过低,那么学习的知识容易变为过眼烟云,每一次重拾旧的知识,会浪费大量时间;
  • 遗忘与记忆是对立的属性,散修需要在二者之间找到平衡;
  • 人的大脑容量以及思考检索是有限的,在此前提下,越简单有效的学习方式,能包罗的内容越广。

记忆与遗忘,是人的天然。若专精一路,解决特定问题的方法自然就会多一些。专精路线有大量时间研磨技术,技术线粘度极高,无形中在反复记忆。如此,对于记忆与遗忘的包容度就会很高。

但散人则不是那么容易——需要面对的知识量过于庞大,路线极易走歪。

散修的劣势

先提劣势,是因为劣势太明显,需摆正姿态。

  • 散修不能专精某一条技术线
    • 一个打螺丝的你,和一个散修的你,散修的你会比打螺丝的你更专精吗?
  • 散人难以甚至无法回到之前专精职位的高度
    • 一来,人的记忆会衰减
    • 二来,游戏技术具有时效性,怎么保证自己能稳固特定知识,且保证环境不会进步?
  • 不经意之间的鄙视链底层
    • 已经散了,就放下社会达尔文意识吧。
  • 每一次前置知识的启动,所耗费的时间与精力
    • 人会遗忘,散人需要时刻与遗忘进行对抗。要么需要投入大量复习时间,要么每一次都要打开文档或者教程重新回忆,要么整理成能够快速使用的工具。
  • 时间不够用
    • 回头是岸


散修的优势

  • 大部分时候能让项目落地,实现可能性最高的是身为程序员的制作人。但实际上散人才是。
  • 能够与对应职位的工作人员共情
  • 设计工作流的可能性更高
  • 对实用性更敏感
  • 低姿态

关于写日志的一些新理解

之前写的日志,现在再回顾就能够发现问题。原因大概是:写的时候,脑海里的热认知能够自动脑补内容,而现在认知冷却了,便能够发现有些事情描述得太抽象,又或者是内容转进太快。

写日志这件事情也从最开始的紧绷到随性,再到现在慢慢摸清楚该怎么风格化:

  • 不可以太紧绷,不可以太随性
  • 不能够混沌,不能够无用
  • 不要正经,不要无趣
  • 不扣细节,不丢逻辑

尾声

最近精神状态又开始紧绷。一个原因是制作联网功能时,心理上产生的不确定性;另一个是我认为《抛投!》占地玩法的核心有严重缺陷,但又没法设计出有效的视觉表达方式。将这个玩法彻底抛弃能解决问题,但这么做就完全背离设计起点。

这同时也是一件有趣的事,因为在最初设计这款游戏时就已出现伏笔。

在立项之初,我思考和分析过几款流行的微信游戏,它们大都被设计成快速反馈的机制。而我最初在脑海里构建《抛投!》的弹刀、压刀、占地机制时,也把它们定位为快速反馈的机制。但在实际设计中,我害怕玩家的负反馈太强烈,以及策略深度不够,于是让武器落地变成了一个时间队列的方式——根据武器落地先后决定它们的权重,先出手的武器被破坏后,下一个武器的权重上升。

在思考这部分的时候,浑然不知这个微小的设计即将带来的灾难:为了填一个坑,又营造了无数个坑(通过文字与语言,很难描述清楚这个“占地机制”,后续会专门拆分出这个失败的设计分享)。

这让我有了一个猜想:如果一个机制的表达无法在三步之内画上句号,那么就是个失败的设计。未来我会尝试验证这个猜想


如果能给我的日志风格提建议,那就最棒了。

近期点赞的会员

 分享这篇文章

Rocktaoist 

猛兽总是成群,牛羊只会独行。 

参与此文章的讨论

  1. 无有时代 2023-08-19

    日志写得很好呀!(比我的好多了233)期待下篇~

    • RockTaoist 2023-08-20

      @无有时代:感谢无有兄鼓励,最近在忙,下一篇九月初。

您需要登录或者注册后才能发表评论

登录/注册