Skip to content

多线程中的互锁操作

多线程中的互锁操作 published on 多线程中的互锁操作有116条评论

        在Win32平台下,为了让同一进程的多个线程访问某一相同变量时不冲突,我们可以使用互锁操作。它提供了一个简便实用的方式,它并不取代传统的同步对象,如临界区、信号量、互斥等,它是一个更加快速且有效的方式。

        互锁操作是一种基于硬件的同步技术,而不是基于操作系统本身的机制,它拥有普通同步对象不可比拟的性能。它可以以原子方式更新一个四字节或八字节的变量,例如 int、longlong、ptr 等。互锁的实现是基于硬件的,在某些情况下它可能转换为一个单一的CPU处理器指令,而任意一条CPU指令都可以看作是一个原子操作。

        什么是原子操作呢?一个原子操作是不可再分割的。简单来说假如在一个多线程程序中,对某个全局变量执行一个加法操作,在这个加法操作完成之前,不存在也不允许另一个线程来读取这个全局变量,那么这个加法操作就被称为一个原子写操作。但事实上并非如此简单,以Win32系统为例子,一个句普通的C/C++加法语句都有很大可能不是一个原子操作。在线程执行过程中,真正可以被称原子操作的只能是单条CPU指令,因为操作系统发生线程切换时不可能在某条指令的执行过程中,只可能在两条指令之间。如果能熟练掌握和运用互锁操作绝对有利于增加程序的健壮性和降低编写多线程程序的难度。

                相比传统的同步操作而言,互锁操作使用更简单而且效率更高,它是一种有针对性的、轻量级的同步操作。首先互锁操作直接支持一个或多个CPU(但不是跨进程),这是在硬件上完成的。通过各种编译器的支持,互锁操作直接提供了函数的形式的调用(WIN32下,见文章尾处的表)。这是一种非常友好的方式,它使C/C++程序员无需熟悉CPU指令或操作系统底层就可以直接使用它。当在多线程程序中,如果不使用同步操作来保证某一变量的在同一时间段(这个时间段可能非常短)的唯一性的话,那么非常容易引发竞争条件。竞争条件是指,两个或两个以上的线程在访问同一变量时执行顺序不可被预期,线程的控制权被强制转移了,这个不可预知性便照成了所谓的竞争条件。

        使用互锁操作,某一线程等待的状态将不复存在。如果在一个多线程程序中使用临界区或互斥对象锁定一个操作,那么将摆脱不了一个线程可能等待另一个线程的解锁的状况。而互锁操作则不会,它将立即完成。互锁的这种特性是多线程无锁编程的基础,多线程无锁编程是一种模式,它是在多线程下情况下不使用传统同步对象来控制数据同步的基础。互锁操作不会像互斥对象那样,在使用时存在从用户态到核心态的转换,这是互锁的一大优势。对大多数平台而言,从用户态转换到核心态的转换会消耗较多的CPU资源,简单说就是会使你的函数变慢!

        当然互锁操作并不是万能的,比如在多线程程序中操作某个对象的一批成员变量时,你无法避免使用传统的同步方法。它的另一个限制其实在本文的开头已经提到,它无法跨进程起作用,如果你要同步两个不同进程中的变量,仍然需要使用互斥对象或其他同步对象。

        这里想说明一下的就是和互锁相关的代码编写方面的一些建议:

  • 绝对不要将互锁操作与传统同步对象混用。
  • 绝对不要在同一volatile变量上混合使用多种互锁操作。
  • 如果你的程序正在执行与内存写入相关的互锁操作,请在互锁调用之前使用内存栅栏。
  • 如果你的程序正在执行与内存读取相关的互锁操作,请在互锁调用之后使用内存栅栏。

        这里我只给出了建议,未给出原理,因为涉及的东西实在太多太多……,希望以后有时间写一篇或几篇专门的文章来做补充说明。

        注意,在某些互锁函数中,MSDN备注栏有这样一句话:

This function is supported only on Itanium Processor Family (IPF).

        这就是说,这个互锁函数只支持安腾系列的CPU,其他架构的CPU是无法使用的,所以在编写代码的时候一定要预先确定CPU架构。

        我们来看看当前Windows平台下支持的一些互锁操作(下表来至MSDN): 

Interlocked function Description
InterlockedAdd Performs an atomic addition operation on the specified LONG values.
InterlockedAdd64 Performs an atomic addition operation on the specified LONGLONG values.
InterlockedAddAcquire Performs an atomic addition operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedAddAcquire64 Performs an atomic addition operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedAddRelease Performs an atomic addition operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedAddRelease64 Performs an atomic addition operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedAnd Performs an atomic AND operation on the specified LONG values.
InterlockedAndAcquire Performs an atomic AND operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedAndRelease Performs an atomic AND operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedAnd8 Performs an atomic AND operation on the specified char values.
InterlockedAnd8Acquire Performs an atomic AND operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedAnd8Release Performs an atomic AND operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedAnd16 Performs an atomic AND operation on the specified SHORT values.
InterlockedAnd16Acquire Performs an atomic AND operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedAnd16Release Performs an atomic AND operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedAnd64 Performs an atomic AND operation on the specified LONGLONG values.
InterlockedAnd64Acquire Performs an atomic AND operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedAnd64Release Performs an atomic AND operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedBitTestAndReset Tests the specified bit of the specified LONG value and sets it to 0.
InterlockedBitTestAndReset64 Tests the specified bit of the specified LONG64 value and sets it to 0.
InterlockedBitTestAndSet Tests the specified bit of the specified LONG value and sets it to 1.
InterlockedBitTestAndSet64 Tests the specified bit of the specified LONG64 value and sets it to 1.
InterlockedCompare64Exchange128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison.
InterlockedCompare64ExchangeAcquire128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompare64ExchangeRelease128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison. The operation is performed with release memory access semantics.
InterlockedCompareExchange Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison.
InterlockedCompareExchange64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison.
InterlockedCompareExchangeAcquire Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompareExchangeAcquire64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison. The exchange is performed with acquire memory access semantics.
InterlockedCompareExchangePointer Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison.
InterlockedCompareExchangePointerAcquire Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompareExchangePointerRelease Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison. The operation is performed with release memory access semantics.
InterlockedCompareExchangeRelease Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison. The exchange is performed with release memory access semantics.
InterlockedCompareExchangeRelease64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison. The exchange is performed with release memory access semantics.
InterlockedDecrement Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation.
InterlockedDecrement64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation.
InterlockedDecrementAcquire Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedDecrementAcquire64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedDecrementRelease Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed with release memory access semantics.
InterlockedDecrementRelease64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed with release memory access semantics.
InterlockedExchange Sets a 32-bit variable to the specified value as an atomic operation.
InterlockedExchange64 Sets a 64-bit variable to the specified value as an atomic operation.
InterlockedExchangeAcquire Sets a 32-bit variable to the specified value as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedExchangeAcquire64 Sets a 32-bit variable to the specified value as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedExchangeAdd Performs an atomic addition of two 32-bit values.
InterlockedExchangeAdd64 Performs an atomic addition of two 64-bit values.
InterlockedExchangeAddAcquire Performs an atomic addition of two 32-bit values. The operation is performed with acquire memory access semantics.
InterlockedExchangeAddAcquire64 Performs an atomic addition of two 64-bit values. The operation is performed with acquire memory access semantics.
InterlockedExchangeAddRelease Performs an atomic addition of two 32-bit values. The operation is performed with release memory access semantics.
InterlockedExchangeAddRelease64 Performs an atomic addition of two 64-bit values. The operation is performed with release memory access semantics.
InterlockedExchangePointer Atomically exchanges a pair of pointer values.
InterlockedExchangePointerAcquire Atomically exchanges a pair of pointer values. The operation is performed with acquire memory access semantics.
InterlockedIncrement Increments (increases by one) the value of the specified 32-bit variable as an atomic operation.
InterlockedIncrement64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation.
InterlockedIncrementAcquire Increments (increases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed using acquire memory access semantics.
InterlockedIncrementAcquire64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed using acquire memory access semantics.
InterlockedIncrementRelease Increments (increases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed using release memory access semantics.
InterlockedIncrementRelease64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed using release memory access semantics.
InterlockedOr Performs an atomic OR operation on the specified LONG values.
InterlockedOrAcquire Performs an atomic OR operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedOrRelease Performs an atomic OR operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedOr8 Performs an atomic OR operation on the specified char values.
InterlockedOr8Acquire Performs an atomic OR operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedOr8Release Performs an atomic OR operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedOr16 Performs an atomic OR operation on the specified SHORT values.
InterlockedOr16Acquire Performs an atomic OR operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedOr16Release Performs an atomic OR operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedOr64 Performs an atomic OR operation on the specified LONGLONG values.
InterlockedOr64Acquire Performs an atomic OR operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedOr64Release Performs an atomic OR operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedXor Performs an atomic XOR operation on the specified LONG values.
InterlockedXorAcquire Performs an atomic XOR operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedXorRelease Performs an atomic XOR operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedXor8 Performs an atomic XOR operation on the specified char values.
InterlockedXor8Acquire Performs an atomic XOR operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedXor8Release Performs an atomic XOR operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedXor16 Performs an atomic XOR operation on the specified SHORT values.
InterlockedXor16Acquire Performs an atomic XOR operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedXor16Release Performs an atomic XOR operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedXor64 Performs an atomic XOR operation on the specified LONGLONG values.
InterlockedXor64Acquire Performs an atomic XOR operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedXor64Release Performs an atomic XOR operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: 多线程中的互锁操作

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

商业游戏制作之风险认知

商业游戏制作之风险认知 published on 商业游戏制作之风险认知有103条评论

risk        任何一种类型的项目都存在风险。游戏项目也一样。想要一个游戏的制作过程相对顺利而最终有效,其中避免不了的就是风险管理,要谈管理首先要对风险有正确的理解和认知。

        在游戏项目中,项目经理或游戏制作人大多时候在做的事正是风险的评估和控制,游戏制作本身是一个非常复杂的过程,它需要管理者处理好各种人员、技术、交互和市场的各种问题,同时它是一个高风险尝试,其失败的可能性绝对大于成功,对任何一个风险的错误处理将有可能导致游戏制作的失败或使整个制作团队陷入困境。如何面对和降低风险,是在开始游戏制作前需要考虑的问题之一(其他的问题诸如商业理由、市场推广等也需要提前考虑,不过已超出本文的讨论范围)。

        我认为这是一个极具吸引力的话题。我们通过对风险的认知、分析并讨论对应的解决办法,可以不断的改变和完善现有过程管理中的不足,同时推动了游戏制作方法论的革新。这里我提出一些不同形式风险的描述并简要介绍一下降低某些风险的一些方式或手段。

目前游戏制作中的风险主要分以下三类:

  • 商业风险
  • 需求风险
  • 执行风险

商业风险:我们如何赚钱?

        这绝对是所有风险中最先需要解决的问题,如果商业理由不充分或分析不到位,其余一切的都是空谈。所有产品的开发和生产都不能违背一条定律,商业游戏也不例外:游戏必须能给用户提供某种程度上的价值,作为回报玩家付给我们钱。如果产品成功的变为一个商品,那么它会带来利润,这样我们就有更多的机会开发更多的游戏,以便扩大企业或资本组的利润增长速度。如果它在开发中就已经体现出失败了,那我们必须能够承受失败所照成的各种损失,其中包括时间、已经投入的资金和许多其他的东西,并且应该立即停止该游戏的制作,回收剩余的资金和各种资源或用他们来做一些其他的事情。从经济学的观点来看,这样做是绝对正确的。

        商业风险是无形的,并且可以给你带来最直接的资金损失。不过,简单想象和一个看似优秀的创意是绝对无法帮助您分析和控制这个风险的,这就要看您的制作人或游戏策划的商业素质了。(至于如何要求和培养游戏策划人员,可以参考这篇文章:策划的定义——关于游戏策划(零)

需求风险:我们要做什么?

        它是关于是否能够提供“正确的”产品给最终玩家的因素集合。它包含三个互相关联的部分,当然其中任何一个处理不得当都可以提升整体商业风险。

  • 策划风险 :它包括不正确或不能实现的功能,它是您的最终玩家(经济学的标准说法是:目标受众)的价值主张最强而力的风险。
  • 范围风险 :做得不够或做得太多也是一种风险。如果您做得不够的,您的策划风险将增加。如果您做太多,增加就是执行风险商业风险
  • 市场风险 :它的体现是:在市场上,产品的价值主张的变化,从有效变为无效。 市场风险是从外部影响项目的,它并不是制作过程中体现出来的。

        在这三个互相关联的风险中,策划风险是最重要的同时它与其他两个风险相互制约相互影响。想要降低需求风险,必须在一开始就归纳出游戏最低、最基本的需求或功能。并制定一个大概的、随着时间的推移、正确的需求功能演变或升级的计划,一般来说就是我们说的游戏资料片。同时需要分析产品上市时间,充分考虑外部事件可能带来的影响(比如:其他公司同类型的产品会和我们的产品在相近的时间上市么?)以及目标市场定位(开发完成需要2年,当然您就不能以当前时间点来选择目标玩家群)。

执行风险:我们怎么做?

        一旦我们清楚了“我们要做什么”那剩下要面临的就是执行面的风险。这个BOSS其实是由四只面目狰狞的精英怪组成~~~

  • 人员风险:最直接的表现就是执行人员没有正确的心态和工作方法。或根本没有选择合适的人来执行。
  • 技术风险:技术层面的主要依赖,简单且直接,技术不到位就会导致失败。
  • 计划风险:死板的计划,不根据当前情况和进度对计划作出修正和优化,完全按最原始的计划执行是该风险最直接的体现。
  • 质量风险:是关于错误或隐藏错误的一种风险。解决了所有其他因素,但产品还包含一系列的错误、漏洞或其他故障。

二次效应:一个难以避免的问题

        在游戏制作过程中,很多时候会造成一种被称为二次效应的东西。例如游戏过程中完善或扩展策划案所涉及范围、增加新的人员进入团队、加入一个新的功能或技术等等。如果这些这些变化没有被很好的管理或预计,那将会引发二次效应。

        增加新的人员进入团队时,团队内部其实正在发生急剧的变革。团队只有两人的时候,可以在一个小房间里讨论问题,并很容易达成一致。团队规模达到二十人时,必须要确定管理人员和规范交流方式。一个两百人的团队,常常会把时间花在维护团队整体的凝聚力和高成本并且复杂的沟通上。每个不同的事件的发生,需要进行一些列的转变取才可能取得最后的成功。

        为游戏添加新的特色或功能,有可能导致对新技术的需要。如果仅仅是机械增加这部分技术,有可能会对游戏性会照成最根本影响。新添加的特色或功能绝对有可能破坏整个产品的价值主张。更多的功能需要更多的规划时间和不确定性,还可能导致计划或时间表的重大变动。这些都是二次效应所带来的,同时也是游戏制作过程中风险变化的因。

        而当我们优化一个危险因素也就是风险时,同样会照成二次效应

不要吓坏了:存在问题就存在解决办法

        千万不要被上面列举的一系列风险和问题所吓到了,其实针对这些风险和问题早已存在解决方案。根据所针对问题的不同,解决方案也存在差异,目前游戏制造业中种最普遍的两种方式是:

  • 原型驱动:减少风险,拥抱变化和早期发现乐趣。这种技术的重点是降低了需求风险和执行风险。实施起来较为麻烦。
  • 数据驱动:减少风险,简化了游戏开发的过程。这种技术的重点是降低总的执行风险。实施起来相对简单。

(PS:到此本文也以告一段落,以后有时间的话,将会花一些篇幅来着重介绍原型驱动,毕竟我在这方面还算蛮精通的。)

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: 商业游戏制作之风险认知

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

游戏策划的定义

游戏策划的定义 published on 游戏策划的定义有81条评论

曾经的一次招聘让我印象深刻,职位是游戏执行策划,我记得面试者中有一位看似充满热情和决心的年轻人,他非常酷爱游戏,也非常希望能参与游戏的制作与开发,他认为他能胜任游戏执行策划这个职位。他一直强调他玩过非常非常多的游戏,而且他又不懂程序,不懂美术,所以他只能做策划。他述说他很多他对各种的看法,也提出很多的创意。当我提到他还不是很了解游戏执行策划时,他试图通过列举他的游戏经历和他自认为非常不错的创意来说服我。很久后的一天和一位业界内的朋友聊天谈及此事,我们一致认为,当前许多想涉足游戏策划的年轻人普遍都有这种想法,而这样的想法实在是太糟了!

这里我们先略过职位本身,我认为任何一个策划,无论是在职还是不在职、已经涉足或是打算涉足游戏业界的游戏策划者们,首先要清楚一件事:商业游戏的目的是什么?(如果对这个问题有任何疑惑可以参考这篇文章:商业团队存在的意义——关于团队建设(三))我一直一来都认为游戏策划绝不是游戏经历长或者是有绝妙的创意就可以胜任的,那只是热爱、爱好、热情、激情或是冲动,就算有10年以上游戏经历又如何?有个奇妙无比天下无敌的创意又怎样?如果不具备游戏策划最基本的认知,充其量是一个骨灰级玩家而已。我有一个朋友,出租车师傅,游戏经历超过15年,是游戏都玩,没有他打不爆的单机游戏,没有他玩不精的网络游戏,那又怎样,这样可以做策划?

gamedesigner

        我们策划的是商业游戏,它不绝是兴趣、也不是爱好、更不是创意。它是一种商品或是一种服务、需要面对广大的消费者、是能获取利润的产品。再说直白一点,所有的创意、功能、技术实现,最终的目的只有一个,让这个游戏成为商品,成为一种被用户认可的服务。不要因为一个技术很前沿而去实现一个功能,不要因为一个创意有多酷而去实现它,三思而后行。考虑一下吧,考虑一下这个创意、这个设计或这个功能到底能为这款游戏的最终价值带来多大的提升,到底值得吗?

做好一个游戏策划绝不容易,但也不是难如登天。首先,需要对这个职业有清楚的认知,同时一步一步不断拓展自己的知识面,尽可能的多学习和游戏制作相关的各种知识,不要只限于了解,尽可能的去熟悉、去精通。说实话我认为在游戏制作中最难做好的职业是游戏策划最富有挑战性的职业也是游戏策划,如果您正打算成为一名游戏策划或正打算为公司设计一款新的游戏,请永远在心底记得这两个字:利润

当然,这只是我自己对游戏策划这个职业的一个想法,可能是不完整的认知,甚至有误。不过这里我还是用我自己的方式给游戏策划做一个定义:

把握市场脉搏,以需求为导向,锁定特定目标用户群,以获取利润为目标,并用正确合理的方式来描述游戏需求的人。

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: 游戏策划的定义

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

游戏策划的本质

游戏策划的本质 published on 游戏策划的本质有96条评论

Game design pic2        游戏,集策划、美术、音乐和程序于一身,是一种特殊的软件。一款MMORPG类型的商业游戏,其制作周期约为一年半到三年左右,参与人员最高超过百人。由此可见其复杂程度和规模不是普通的商业软件可比拟的。

        游戏的制作过程其实就是软件工程的一次实施,各种游戏策划人员就是软件工程实施过程中的需求的提出者以及分析者,所以我认为游戏策划人员必须拥有基本的软件需求理念及对需求使用正确的分析方法,才能准确无误的将需求传达给团队中的其他人。

        现实生活中,对大多数的人来说,若要装修一间花费100万元购买的房子,他一定会与装修公司或装修人员详细讨论各种细节,是什么和为什么他们都明白不弄清楚这些问题后会造成的损失,以及事后再来解决这些问题的代价。然而,涉及到游戏制作,人们却变得“大大咧咧”起来。游戏项目开发过程中所遇到的问题排除美术和音乐的话,其中50%~60%问题都是由于策划部分准备不充分或传达有误(也就是需求阶段)埋下的“祸根”。可国内为数不少的游戏制作团队的策划们仍在项目上采用一些不合规范并且“危险”的方法,这样导致的后果便是一条鸿沟(期望差异)——游戏开发人员开发的成果与游戏策划人员所想得到的游戏存在着巨大期望差异

        这里我提出一个名词概念,游戏项目风险承担者(Game Project Stakeholder)。就是指直接参与项目或对项目感兴趣并做出贡献或即将做出贡献的一系列人员,他们关心的就是要做一个什么样的游戏。游戏项目风险承担者包括投资人、游戏策划人员、游戏美术人员、游戏开发人员、游戏测试人员、玩家文档编写者(目前游戏都有一些最基本的职业介绍、游戏内系统功能介绍)、项目管理者等,如果是自主运营那还包括维护人员、运营商。游戏策划阶段工作若处理好了,能开发出很出色的产品,同时会使玩家感到满意,开发者也倍感满足、充实。若处理不好,则会导致误解、挫折、障碍以及潜在质量和商业价值上的威胁。因为游戏策划阶段奠定了游戏制作过程中软件工程实施和项目管理的基础。

        其实国内游戏产业一直存在的一个这样的问题:缺乏统一定义的语言和方法来描述游戏制作过程中的各种名词以及希望被传达的想法。策划人员所定义的“策划案”对开发者似乎是一个较高层次的产品概念,很大部分是由未经雕琢的自然语言编写而成,其中充满了歧义和不容易被理解的元素(如果您不相信我的话,请翻阅一下贵公司之前或现在的策划文档)。而开发人员所说的“需求”对游戏策划人员来说又像是详细设计。实际上,我认为游戏策划案这个词语包含着多个层次,不同概念的内容(其实策划内容占整个软件需求的80%左右)需要从不同层次与不同方式来描述,最好是用一种标准的语言或方法,一个清晰、毫无二义性的“策划(需求)”术语来描述。我们需要确保所有的游戏项目风险承担者在阅读和理解游戏策划人员编写的策划案中的那些名词或示意图的时候务必达成共识。有朋友一定会问:有这种东西的存在么?答案是:有的。 

(PS:其实这是一个非常庞大的话题,一时间我无法将自己的看法、见解一古脑的列出来,so只有慢慢整理思绪了,同时希望借本文做一个引子,抛砖引玉。)

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: 游戏策划的本质

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。