游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

开发者回顾专注于游戏玩法设计的过程

发布时间:2011-10-26 17:58:41 Tags:,,,

作者:Ricardo J. Méndez

我之前提到了不专注于游戏玩法可能产生的影响。我发誓下次将首先从游戏玩法开始考虑,不先制作好系统就绝不写一行代码。

我坚持着这个决定。在我们放弃《Pirates》项目1个月左右之后,我开始对首版的《UnitySteer》进行润色。为了能够让努力转变成某些可供发布的产品,我会继续将这款游戏制作下去,完成后就转向游戏设计。

我的目标是创造出满足以下条件的东西:

1、玩起来有趣

2、具有可升级的复杂性,这样我就拥有了某些可供测试的模块规则

3、低保真度美术效果,可以避免逐步攀升的美术预算

4、可以使用纸张来复制,这样我就可以在不编程的情况下进行可靠的玩法测试

这意味着我需要避免使用即时系统,因为该系统的离线调整很麻烦。幸运的是,我很喜欢基于回合的系统,而桌游经常会使用这种系统。

我决定制作一款策略类战争游戏,游戏面板以六边形格子为基础,有着较少的游戏美术设计。这样,我既可以重新使用之前的六边形格子代码,也可以尽量少地使用动画模型,毕竟这只是个桌游。

我把最初的系统设计得很简单,基本包括如下几点:

1、每支军队都有数个部队,他们每回合只能移动数格(游戏邦注:当然,作者早期还未考虑到单位的平衡性问题)

2、单位要么近战要么远程,没有两者兼具的单位(游戏邦注:随后作者对此做了修改)

3、移动是确定的(游戏邦注:单位最对可以在Y地形移动N格),但是战斗的成功是随机的,由各单位的攻击力和防御力决定。

4、地形对移动会构成影响,比如狼比士兵更容易通过森林地形。

5、有基础士气,同时也有鼓舞和打击士气的规则。

我在纸上对我制定的规则进行测试,使用六边形格子、骰子和某些我从好友出借来的微型Reaper,测试后我开始制作军队(游戏邦注:共分成3个派系)和编程。就游戏的美工方面,我与某个美术工作室合作,他们负责向我提供基本的平面质感六边形以及树木、岩石和山脉等我可以用来构建风景的装饰。

随后,我犯了首个错误。

原来的灯塔美术设计效果(from arges-systems)

原来的灯塔美术设计效果(from arges-systems)

我之前的其他项目与他们合作过,因而我为这次获得的低质量资产感到甚为惊奇。

我决定,需要提出更为严格的要求。与他们的美术总监进行严肃的对话后,他们更换了接手任务的美工,我让这个新美工重新设计之前要求的灯塔装饰。质量的提升足以让人欣慰。

重新设计后的灯塔(from arges-systems)

重新设计后的灯塔(from arges-systems)

我给他们发送了更多所需图片的说明,很高兴看到一切处在他们的掌控之中,然后我便回到游戏编程中。我想要先期执行游戏的AI,即便它们看起来只是四处移动的立方体而已。我认为这会帮助我平衡游戏,因为我可以让AI在同种设计方案下相互战斗多次,看看是否有某一方胜利得过于频繁。

因为我制作的是非确定性桌游,expectiminimax算法似乎是最佳的方法。我简单地编写了一个此类算法,给它赋予了必要的评估功能(游戏邦注:这只是使用版本,用于测试目的)。

但是事实并非如此。

该方法并未取得显著的成效。我一开始就意识到了其中的缘由,但是因为我要同时注意艺术和系统创建两个方面,所以我忽视了对基本小细节的注意。

人类经常会忽略某些不相关的信息。如果有人将网球抛向你的脑袋,你不会专注于分析它的轨迹和速度,你只会进行躲避。同样,如果你需要处理很多单位,其中两个正在连续遭受攻击,你很可能会立即考虑防御这两个单位(游戏邦注:除非你因某些原因对这两个单位漠不关心)。

我所创建的分析器不会采取如上所述的做法,它会考虑更多的选择。

假设出现以下情况:你有12个单位,但是只能激活两个。你可以随意选择这两个单位,也可以按你自己的顺序激活他们。首先用近战攻击然后用弓箭手清场与首先使用弓箭手然后使用近战并不相同。

假设你的所有当前单位最多可以在棋盘上移动2格,如果你最后的位置邻近敌对单位时可以选择攻击(游戏邦注:指近战攻击单位)。

移动某个单位后可能到达的最终位置的总数是:

1、18,某个最多移动2格的单位最终可能到达的位置的数量

2、加上在回合结束后你可以攻击的敌人总数(游戏邦注:因为游戏使用的是六边形的格子,所以玩家有不止1种选择)

3、用之前的总数乘以可能的结果总数

4、将总数乘以12,得到的就是可能的单位数量

因为你可以移动两个单位,所以你需要考虑第二个单位最终位置的总数,而每种可能的单位移动组合都可能产生不同的结果(游戏邦注:“移动A,攻击,移动B”的结果与“移动B,攻击,移动A”不一定相同)。如果你的单位有更广阔的移动范围,结果会更加有趣,因为这样就可以有更多的点来计算你的潜在利益。

随后,你必须考虑对手在你行动之后可能的移动方式。

这样的树状结果不可能在任何合理的时间框架内进行评估。我做了些许调整,这使得情况得到了显著改善。主要的调整如下:

1、树中的叶子不再包含所有可能的行动结果,我仅仅通过最好和最差的结果两个方面来追踪可能性(游戏邦注:最差的结果是,玩家已用尽最大能量而敌人却毫发无损;最好的结果是,玩家以最低的代价给敌人带来最大的杀伤力)。

2、单位不再考虑每个可能移动到的六边形,只关注那些能够使队伍受益的可能地点。

首个改变很简单,但是第二个改变需要些许时间才能够实现,因为我必须决定吸引单位移动到某处的标准。我最终采用了简单的方法(游戏邦注:减少敌人的力量),然后让系统如此进行下去。

结果变得较好,但是仍然与理想的情况有很远的差距。产生出的大量分支使得AI必须考虑所有的单位和所有可能的移动组合。如果每方有12个单位,所计算的1回合便有134个分支。

当然,这些分支中有些极为相似,但是仍然让游戏充满复杂性。

回到画板上,我决定做个简单的改变,让决定的评估更为简单:每回合的行动不是主观地从大量单位中主观选择数个单位,每个单位将以主动比率为基础来激活,双方根据主动的顺序轮流激活单位。这意味着单位的激活更具确定性,与《英雄无敌》的做法类似,极大地降低了在任意时刻需要分析的选项的数量。

尽管在此过程中总是有人会说我正偏离主线,我需要专注于游戏玩法而不是AI。事实在于,因为这两种方法之间有显著的差异,我需要在决定之前先测试哪种方法更加可行。选择了某种方法之后,我再次在纸上进行测试。它确实有效,即便它比前一种方法需要更多的记录(游戏邦注:电脑很擅长记录信息),所以看来我是因祸得福了。

学到的经验:拥有某些能够在纸上测试良好的东西确实很棒,但是在你真正将其运转起来之前仍然是毫无用处的。

但是,在美术设计方面,事情进展得并不顺利。在我关注游戏玩法和AI之时,我任其自行发展,但是交期拖延和存在诸多问题的美术内容又使我不得不对其加以关注。

游戏邦注:本文发稿于2010年11月22日,所涉时间、事件和数据均以此为准。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

Postmortem: Focusing on gameplay design

Ricardo J. Méndez

Last week I mentioned the effects of not focusing on gameplay. I’d vowed to start with that the next time, and not write a single line of code until I had a system worked out.

I stuck with that decision. About a month later after we abandoned the Pirates project I was done polishing the first version of UnitySteer – which I’d continued working on in order to release something from that effort – and then put the keyboard down and turned to game design.

My goals were to create something that was:

Fun to play

Of scalable complexity, so that I could have some modular rules to playtest in a mix-and-match fashion

Aimed at a low-fi aesthetic, to avoid a ballooning art budget

Reproducible with cardboard and paper, so I could do a faithful playtest without programming it

This meant avoiding real-time systems, which would be a pain to fine-tune offline. Luckily I enjoy turn-based systems, and boardgames naturally lend themselves for that.

I decided to do a tactical wargame, on a hexagon-based board, following a miniature game aesthetic. That way I could both re-use my hex grid code and take the shortcut of having marginally animated models – it was, after all, a board game.

I kept the initial system simple enough. Basically:

Each army had a certain number of troops (I hadn’t done balancing on the units this early, of course) of which they could only move a few per turn.

Units were either melee or ranged, but not both (I changed my mind on this later).

Movement was deterministic (a unit can move a maximum of N hexes on Y terrain), but combat success was random, determined by attack and defense statistics.

Terrain tiles would have an effect on movement, such that moving across forest tiles would be easier for wolves than for soldiers.

There were some basic morale, support and shock rules, but you get the general idea.

The rules I created playtested like a charm on paper, using hexagon cutouts, dice and some Reaper minis I borrowed from a friend, so I set off to define the armies (three factions) and started programming. For the art, I contracted with an art shop (which shall remain nameless) to provide me with a base hex and variations on the surface textures, along with some decorations like trees, rocks and hills that I could use to pepper the landscape.

And hit my first production glitch.

I’d worked with them before in another project, so I was surprised at the terribly low quality of the assets I was getting back.

Above programmer art, sure, but not by far.

I got a couple do-overs (the one above was the best, actually) and decided that stricter measures were needed. A serious conversation with their art director/manager got the artist changed, and I asked the new guy to re-do the lighthouse decoration I had first requested. The improvement was reassuring.

I sent them specs for some more pieces, happy that things seemed on their way, and went back to programming. I wanted to have a quick implementation of the AI playing the game, even if they were only cubes moving around. I figured this would also help with balancing, as I could have the AI fight against itself on the same scenario multiple times and check if one side came up ahead too often.

Since I was dealing with a non-deterministic board game, an expectiminimax tree seemed like the best approach. I wrote one from scratch, gave it the necessary evaluation function (a trivial one initially, for testing purposes) and sent it off to the races.

Or not.

The approach crawled. The reason should have been obvious from the start, but since my focus was split between following up on the art and creating the system (on top of my regular client work) I had neglected to pay attention to a fundamental little detail.

We humans are very, very good at discarding irrelevant information. If someone throws a tennis ball at your head, you don’t stop to derive its trajectory and speed, you merely duck. In the same way, if you have a board full of units, two of which are getting pounded, you likely do not evaluate the options that do not immediately defend those units (unless you don’t care about them for some other reason).

The board analyzer I had created didn’t do anything like that and was considering way too many options.

Suppose the following scenario: You have 12 units, but can only activate two. They can be any two units, and you can activate them in any order that you wish – it’s not the same to attack with your berserker, then clean it up with archers if necessry, than to use the archers first and the berserker second.

Let’s say all your current units can move up to 2 hexes on the board, and you can choose to attack if you end up landing next to an enemy unit (for melee units).

The total number of possible end states for the board after moving one unit is:

18, which is the number of hexes which a single unit can reach by moving up to 2 positions

Adding the total number of enemies you could attack at the end of the turn (since there are hexes which could give you more than one choice)

Multiplying the previous total by the total possible outcomes (since it’s random)

Multiplying the total by 12, which is the number of possible units

Since you can move not one unit but two, you then need to take into account the total number of end states for your second unit, and do this across all possible unit pair permutations (“Move A, attack, Move B” does not necessarily yield the same result as “Move B, attack, Move A”). It gets even more fun if your units have a higher movement range, because now there are even more spots to calculate your potential profit for.

And then you have to consider your opponent’s possible moves after each of your actions.

Hello, Combinatorial Explosion. I see you’re still dating Brute Force.

Such a tree was impossible to evaluate in any reasonable timeframe. I did some adjustments, which trimmed it down significantly. Mainly:

The leaves of the tree no longer consisted of all possible action results, and I tracked the odds merely for two: the best and worst possible outcomes (zero damage to enemy with maximum backlash, and maximum damage to enemy with minimal backlash)

I also kept a potential field of areas of interest to each side, and the units no longer considered every possible hex to move to, focusing instead on those which were closer to its team’s interests

The first one was easy enough, but the latter took a bit of time to set up, as I had to determine the criteria of what made a spot attractive. I ended up settling on an simple approach (reduce enemy strength) and let it roll with that.

The results were better, but still far from ideal. A large amount of branches being spawned came from the fact that the AI had to consider all its units, twice, in all possible permutations of pairs. If each side has 12 units and we want to calculate just one turn ahead, that’s a total of 134 branches for the opposite side spawning from each of your 134 branches (leaving aside the probabilistic leaves).

These could probably be pruned, of course, as some of them are likely to be almost identical, but it added yet another level of complexity.

Going back to the drawing board, I decided on a simple change that made evaluating the decisions much simpler: instead of acting on each turn with an arbitrary selection of a few units from a large set, each unit would activate based on an initiative rating, and both sides would take turns activating the units in order of initiative. This meant that unit activation would now be deterministic, similarly to what happens in Heroes of Might and Magic, which massively narrowed down the number of options analyzed at any given moment.

While all through this there was a little voice telling me I was getting sidetracked, and I needed to focus on gameplay and not AI, the fact was that since both approaches played significantly different, I had to test what was easily doable before settling. Having picked an approach, I went back to playtest it on a few scenarios on paper. It worked, even if it required more bookkeeping than the first one (which was fine, as computers excel at bookkeeping), so I gave it my blessing.

Lesson learned: having something that plays well on paper is fine and dandy, but nothing’s final until you’ve actually got it running.

On the art side, however, things weren’t progressing as smoothly. I had left it on autopilot while I focused on the gameplay and AI, but delays and assets delivered with a variety of problems soon pulled my attention back to it. (Source: Arges Systems)


上一篇:

下一篇: