游戏性系统

引言

本章由马若遥老师介绍游戏玩法开发,他曾在动视暴雪开发使命召唤系列黑色行动3&4和手游,目前在腾讯NExT北京工作室。本章内容包括了解什么是游戏玩法开发,通过具体实例来介绍如何建立愿景、划定边界、迭代、抛光。

什么是游戏玩法开发 Gameplay Development

游戏玩法开发是与玩家交互行为相关的游戏功能与行为的开发。这个定义非常模糊,业界也没有一个准确的定义。

  • 中国的游戏团队传统上认为游戏玩法开发是 技术和设计的交叉点
    • 这是由MMORPG时代的工作习惯决定的,思维模式倾向于工业的流水线。
  • 西方的团队则认为是游戏玩法开发是 技术与设计的融合
    • 程序员与美术师去兼职设计,更倾向于一种创作者的思维。
  • 少数顶尖开发者可以做到游戏开发的终极形态: 技术、设计与艺术的统一
    • 从确定愿景开始作为核心参与原始设计,然后参与游戏整个开发周期,衔接众多生产环节。

实例 Example

  • 三消游戏
  • 开发周期
  • 轻代码
  • 展示决策过程

建立愿景 Vision

愿景

第一步也是所有游戏项目最重要的一步就是建立愿景。无论是单人的独立游戏还是成百上千人开发的大型项目,都要有它,没有它大家可能会各自干各自的。
愿景是描述游戏最核心最重要的部分,清晰的愿景是项目成功的保障,而且愿景会随着迭代和项目的进展而变化。

  • 愿景负责人 Vision Holder
  • 执行者是否清晰是标准

例如顽皮狗会有一个比较清晰的制作人,比如大家熟悉的小岛秀夫,著名的游戏制作人。但也有许多游戏说不出来具体的制作人,比如Call of Duty

子系统愿景

子系统也有愿景。不只是只作为整个一个大游戏,必须是Creative Director这样一个职务才在乎愿景,我们做一个很小的东西,它也有愿景,夸张极端一点每段代码都有愿景。

传达愿景

运用一切手段传达清晰:肢体表演列举参考等等,不仅仅是项目文档
国内团队很多情况下喜欢用一种excel或者word或者是网页这种几十几百页长篇大论的设计文档来传达它的设计,但是执行者是否清晰是标准。如果你写了一万字的长文但没有人看等于没有,因为执行者没有读。所以愿景最重要的是存在于执行者的心里。

结论与共识

由执行者作出描述。
共识可能发生传达者想的和执行者想的都不太一样,是一个中间点,具体情况具体落实。

三消愿景 Match-Three Vision

按照一个比较标准的三消游戏去描述它一下:

  • 下落的砖块
  • 玩家交换砖块的位置
  • 三个同色砖块连线消失

如果是一个从来没有玩过三消游戏的人,上面的描述非常模糊。所以我们看一个例子,看一下别的三消游戏作为参考:

图源网络

通过上面同类产品的参考,我们继续进行一些尝试性描述:

  • 一个 N*M 尺寸,布满砖块的板子
  • Match:三个或意义上同色砖块连成一线
  • 形成 Match 的砖块会消除并加分
  • 玩家操作:玩家交换相邻两砖块的位置来形成 Match
  • 消除后的空位由上方的砖块下落补充
分治策略 Divide And Conquer

将一个大的东西拆成几个比较小的东西:

  • 将愿景拆分成易于实现的模块,按照个人/团队的工作习惯
  • 可用于分析成品游戏
分析案例 Example:拆解马里奥的元素

《超级马里奥兄弟》
`关卡`、`地形`(静态碰撞 动态砖块)、`主角`、`敌人`、`水管`、`金币`、`得分` 新的游戏开发团队可能因为上面出现的各种问题而陷入争吵,但其实许多东西没必要去纠结,往下推进才是最重要的。
三消拆解 Match-Three Break Down

现在尝试拆解三消游戏:

  • 三消游戏的元素:世界板子砖块记分板菜单
  • 拆解思路:
    世界:整个游戏的容器
    板子:静态要素
    砖块:动态要素
  • 拿不定注意:
    • 砖块所占的格子
    • 板子世界是分是合?
    • 规则该由世界还是板子管理?
保持最简原则 Keep It Simple & Stupid

如果有多种方案,选择最简单的那个。

  • 不确定性体验在项目上,尤其是在玩法开发而不是算法开发上。玩法开发不是一个纯技术问题,很多情况下我们碰到这种不确定性的情况下的时候,如果我们争论会让团队有一种恐惧感,而这种恐惧感会影响决策和推进。
  • 而且很多时候我们不知道外部环境会怎么变化,现在所谓为未来作出的决策在将来是否真的有效。

所以我们保持灵活、保持简单,业界也有相关的概念:

YAGNI - You Ain’t Gonna Need It 忌引而不发
If it ain’t broke don’t fix it 忌未雨绸缪

KISS原则下的三消游戏拆解
  • 三消游戏元素:世界砖块
  • 拆解思路:
    世界:整个游戏的容器和静态要素
    砖块:动态要素
  • 拿不定的主意:砖块所占的格子? 先作为世界的一部分简单处理

划定边界 Scope

项目边界

Scope非常重要,它决定了我们到底需要多少资源,包括时间、金钱和其它一切需要付出的东西。

世界
  • 游戏的容器
  • 所有静态要素
  • 管理砖块
砖块
  • 动态要素
  • 玩家拖动交换
  • 从顶部下落
  • 三个连成线时消除

画点什么 Something On The Screen

  • 砖块的类?
  • 快速上屏:通过越少的工作越早的展示在屏幕上,项目就会推进得越顺利。代码只是一种文档。
enum BrickType
{
REGULAR_BLUE,
REGULAR_GREEN,
REGULAR_RED,
REGULAR_YELLOW,
REGULAR_PURPLE,

REGULAR_TYPE_COUNT,

BOMB_ROW,
BOMB_COLUMN,
BOMB_SQUARE
}
class World
{
Map BrickType_tp_Image;

Array[10,10] brickGrid;

Camera mainCamera;
float WorldPixelsPerUnit = 64;
}

DEMO完成 Hmm_it’s diffrernt from what I imagined


设计师:”呃…和我想的不太一样”。认真听取意见的合理之处,考虑如何改进(修改、不同方向)。

迭代 Iteration

迭代

设计的不确定性

对于各种问题,一个人犹豫不决,两个人僵持不下,一群人面红耳赤。
“想好就不要改了”的想法行不通的原因是现有信息不足,各种因素都在不断变化,需要与市场跟进。

快速试错

迭代的核心想法,也体现了时间上的分治策略。

迭代循环

降低单次循环成本。
设计 Design –> 实现 Implement –> 体验 Test –> 反馈 Feedback –> 设计 Design

输入和交换 Input And Swap

面向对象 Object-sriented

面向对象并非程序专属,而是一种思想。

  • 与对象相关的数据和逻辑打包
    比如假设现在我们有一个皮卡丘,我们可以用面向对象的方法把它包装起来:
    皮卡丘的属性有等级生命值,行为有攻击闪避进化。那么我们可以写出下面的伪代码:

    把相关的代码整合到一起集中管理,便于维护/重用。现代的商业引擎很多也是这样做的,比如UnityUnreal会看到里面这种叫ActorGameObject这样一个Instance的东西。它的概念就是把图像、模型、声音、代码等所有东西都放在一起组成一个”对象”。
  • 继承
  • 并非唯一的范式
    我们不是非得要做面向对象。实际上业界很多引擎比如像使命召唤的引擎现在还在产生最新的游戏,它不是C++,纯C不是一个面向对象的语言,它的编辑器也不是面向对象的,所以面向对象并不是唯一的范式。
    面向对象很多时候可能不一定是最好的解决办法,要把正确的工具用在正确的地方。
插值 Interpolation
  • 专业名词
    Lerp Interp MapRange Bezier/Hermite curve
  • 插值概念
    当 $x$ 从 $x_0$ 向 $x_1$ 变化时,$y$ 如何变化,简单来说就是当X这么变Y怎么变。
  • 解决大部分的”过渡”问题
    屏幕上炫酷的动画其实都可以用插值来完成。比如艺术师只做出关键帧,之后中间部分由插值完成,这样无论帧数多少都可以看起来很平滑。

玩家输入 Player Input

方案一:玩家点击选中砖块,选择相邻砖块,两者交换

  • 实现简单
  • 点击事件为系统级基础事件
  • 将复杂性留给了玩家:点错、点不中、手滑。

方案二:玩家向某方向拖拽砖块,砖块与该放下上邻居交换

  • 实现复杂
  • 手势判断设计多种模糊边界

方案二简化:

  • 使用系统基础事件:MouseDown MouseUp
  • 明确边界:按拖拽角度和下落区间选择邻居。

出生和销毁 Spawn And Destroy

砖块销毁 Destroy

销毁删除加一个简单的特效就可以完成
需要Match Three来触发

  • 先放着?
  • 临时测试逻辑
  • 经常验证
砖块下落 Brick Fall
  • 空位上方所有共同下落 – 复杂
  • 一个一个下落
  • 复用交换逻辑
生成新砖块 Spawn
  • 按照空位数量在顶端生成新砖块
  • 一个一个生成
检测三消 MatchThree
  • 触发砖块销毁
  • 仅在砖块移动后发生
  • 简单的算法
  • 第一屏?

测试和除错 Test and Debug

简单的测试代码
  • 在功能完整之前就测试现有逻辑,避免全部完成后整体测试的复杂
  • 刻意改写代码和逻辑线,帮助重现bug
  • 加快个人迭代速度
IDE断点Debugger
Log/屏幕消息
  • Log是非生产环境的唯一除错手段
  • 特别适用于追踪一个很深的逻辑树
辅助图形 Debug Draw
  • 辅助开发
断言Assert
  • 断言库
  • CallStack

抛光 Polish

从功能到艺术

游戏设计MDA模型

功能 Mechanics –> 动态 Dynamics –> 美 Aesthetics
举例来说,按下按键角色会走动,这是功能;如果这个角色身上带着火,那么他会把身边的树丛点着,玩家系统和另一个系统进行交互,这是动态;而玩家看到的就是
开发者与玩家视角不同。开发者会从功能往下去看,而玩家会从往上去看。

体现玩家直接看到的质量

如果玩家首先碰到不平衡、小bug、偶尔的卡顿、崩溃,开发者心知肚明,这些小bug不是特别重要,不是工作的主要部分。但玩家很在乎。
刺客信条:大革命,刚上线时头发系统出现了一些问题,脸没有画出来。不是什么大问题,但因此前期评分极低。

抛光最重要的点就是我们要留出时间,一定要留出充足的时间,功能做完不算做完。