posts - 14,  comments - 57,  trackbacks - 0

        2011已经谢幕了,现在都流行总结,要是让我总结2011,可以用2个词来概括,辛苦、刺激。
辛苦是因为2011基本上是加了一年班,从过完年开始,到2012年过年前最后一周,这一年来,是我感觉最辛苦的一年,好在最终
项目算是打了个翻身仗,心里总算有了些慰藉。

       2011年游戏经历从技术封测、内测、公测到整改、重新内测公测,一路走来,遇到无数稀奇古怪的Bug,
有时候压力大的时候,晚上都睡不着,脑子里回想着现场的一丝丝蛛丝马迹,希望能找到bug的原因,经历过无数次绝望到重生的喜悦,也有被猜忌不信任的痛苦,活脱脱就是一部部侦探剧情。
  没有从事过游戏开发或者游戏没上线的同学很难理解:bug有这么难找吗?的确,如果是简单的空指针宕机,当然是好找的,用我们的话,这类问题是个傻子都能解决(其实不然,很多时候直接原因是空指针,
真正的原因隐藏很深),但是更多的是隐藏很深的问题,需要反复的分析现场,假设剧情才能得到灵感,然后推演,才可能得到结果,当然,这个和游戏逻辑的复杂度是分不开的。
  具体的bug细节不便在此分析,但是大部分的问题,其实都是因为不正常的设计引起的,所以其实我一直在思考,在软件开发领域,其实也存在着"道",说通俗点叫客观规律,不按照道行事,迟早是要受到惩罚的。
但是在游戏后台开发中,很多时候存在不同技术方案的矛盾,难以让人取舍,这些矛盾都是真实在很多项目存在的。

动态内存还是静态内存

      很多开发者由于担心内存泄露,在项目中禁止使用动态内存(当然这实际上几乎是做不到的),使用对象池来避免动态内存,就是预先创建预计最大数量的对象,后续申请和归还的时候,都是操作对象池,
避免动态new和delete。这样的项目还不少,我见过的就好几个。对象池的好处是显而易见的,基本上可以避免内存泄露。但是实际上,这种方式是把双刃剑,个人觉得在游戏项目中,这种方式弊大于利。
主要弊端有下面几点:
1、开发不方便,导致需要添加很多的对象池管理类,即使有模板帮忙,也是非常繁琐的。实际开发中,几乎不可能对这些小对象类都搞一个对象池管理类。

2、由于采用预先生成对象,一般会预估一个对象可能存在的最大数量,然后按照最大数量来创建,浪费内存。
  的确,你没有内存泄露,但是你启动的时候就需要好几个G的内存,这个是内存浪费,好在现在server开发基本都是64位,没有地址空间的困扰了,但是,在大部分情况下浪费好几个G的内存,
光想想都有点心疼。

3、引入了新的风险,由于采用对象池,申请新对象的时候,只是简单的pop一个空闲对象就可以了,很容易漏掉对象初始化的工作,在回收对象的时候,大部分开发者也很容易漏掉清理工作,或者初始化和
清理工作过于简单,这样容易导致新对象被历史操作影响。曾经遇到过一个新FB所有传送点都打不开的问题,就是因为历史对象回收时数据没清理导致的。

    回头来看对象池的优点,很多开发者坚持是为了解决内存碎片和内存泄露。先说内存碎片,暂且不说内存碎片真的是否有这么严重,退一步,其实内存碎片已经有很多的成熟解决方案了,自己重载smallObject还是
采用标准的tcmalloc解决,都是非常轻松的。至于内存泄露,个人觉得这个问题其实是很好查的,也是c++程序员的基本要求。

分模块针对接口编程还是一锅粥

     这个问题单独提出来,几乎所有人都会说,当然是分模块针对接口开发了。和天下所有的事情一样,知易行难。由于游戏逻辑项目影响的地方非常多,比如死亡的时候,既需要判断死亡掉落,又需要处理任务状态,
如果在战场和竞技场中,还要判断基数和得分等等,这就导致很多开发者不假思索的把所有的东西都揉在一起,你中有我,我中有你,我改你的代码你改我的。
一个最简单的例子,我在项目中开发掉落功能,当把物品添加到玩家背包后,发现客户端没有更新背包,一查,居然还需要掉落的开发者自己构造数据包同步客户端,其实作为其他模块,根本不关心背包数据同步的细节。
这个其实在现实生活中很常见,我委托背包模块添加一个物品,具体的细节是被由被委托人来负责的。将过多的细节交给其他模块处理,会导致复杂度增加,容易出现问题,对其他人来说,也是一个精力浪费,如果是一个复杂
模块,你会发现需要了解太多的细节,修改太多自己不熟悉的代码,进而导致风险。还有一种观点,认为一锅粥的开发方式有助于了解游戏的各个业务模块,对这种观点,我是不以为然的,每天陷入到繁琐的细节,真的对熟悉业务有好处吗?或许闲下来玩玩游戏更有帮助,而且,这么乱的代码,看起来也是非常累的。分模块开发,具体的办法,游戏编程精粹5上有篇文章写得很好,这里不扩展了。

真的需要禁用STL吗

  不止一次在和其他项目交流的资料里看到对方很威严的宣称在项目里禁止使用STL。说实话,我还真没觉得STL有什么不好。见过太多这类项目自己重复实现一个个蹩脚的排序算法、容器等等。
大部分人一般都会根据经验选择使用自己熟悉的技术,这个无可厚非,但是像这样明着禁止使用STL,真不知道如何能理直气壮。其实大部分不用STL的理由,基本上都是不熟悉,完全没有足够的理由禁止使用。

游戏开发无技术含量?
 
    曾经多次听到行业内的兄弟有此感慨,确实,游戏逻辑复杂度非常高,架构上大部分都是类似的。但是这并不说明游戏后台开发复杂度不高,如何将游戏开发逻辑复杂剥离开来,做到稳定高效开发,其实还是有很多
东西可以探讨的,看看那些项目,大部分都是一锅粥,需要什么功能就蛮干,加上去,这样确实毫无技术含量,都是蛮干。所以,一件事情是否有技术含量,不光是看事情本身,还要看怎么干,蛮干和苦干,那是最没有技术
含量的方式了,程序员还是要有强烈的“偷懒”意识。

 

posted on 2012-02-16 21:00 feixuwu 阅读(719) 评论(4)  编辑 收藏 引用 所属分类: 游戏开发

FeedBack:
# re: 项目开发中的一些思考
2012-02-17 11:28 | 杨粼波
1.对于STL这样的态度的公司或团队,不乏少数。其实,不论从容器还是算法来说,STL提供的容器和算法足够大部分情况下的使用。boost也同样好。当然,主要还是要能够掌控他们,否则就如脱缰野马。好与不好,合适就好。

2.关于游戏开发的技术含量,还是有的。在我的定义里面,游戏开发其实还是一种应用。所以相对于那些高深的研究来说,还是相对要技术含量低,特别是在国内一把抄的前提下。就服务器而言,最基础的是要提供稳定的底层,而后随着人数的承载量增长,对于服务器的架构设计要求也是越来越高的。就管理而言,要保证几十号人工作如一人,项目管理能力同样重要。

3.关于内存管理,得就事论事,合适就好。先用最普通的内存分配方式实现,如果不合适了再行优化。Premature optimization is the root of all evil.

4.如果能够在设计最初就划分好模块,那再好不过,因为这样就可以把功能细分了,功能能细分了,这样就能够把任务更细的划分到每一个实现人身上。但若一开始无法划分,那就不要划分,这样反倒会束手束脚,那就先实现,完成后再重构。其实你说的情况不是一个模块划分,接口的问题,而是一个高耦合的情况。“高内聚,低耦合”这都没做到,自然的,就更不要谈什么模块和接口了。如果你们能够达到这点,就不会乱到一锅粥了。要坚持不断重构,其中的好处,你们越到后面,越能够体会到。  回复  更多评论
  
# re: 项目开发中的一些思考
2012-02-18 11:54 | feixuwu
同意部分观点,欢迎大家探讨。
1、其实按照模块划分,针对接口开发,组件式开发这类东西,在游戏项目中已经很成熟了,很多项目都是这样做的,不存在什么问题和难点。

2、至于先实现再重构,个人觉得很难,游戏项目大部分时间紧,越到后面压力越大,很难到后面来调动大家积极性来重构,也很难抽出时间来重构,风险也非常大。过多的重构还不如做之前多规划。

3、内存管理的优化,其实不需要代码做出优化修改,发布的时候链接下特定库就行,无需人工参与和修改代码,对开发者基本是透明的。

4、不过不是好的东西就容易推,要打破现有或者历史结构,在哪个项目都不是件容易的事情,大部分情况下,只能互相妥协。和生活中很多事情一样,做事情之前,首先要取得别人的信任,否则多半是做不成的。
  回复  更多评论
  
# re: 项目开发中的一些思考[未登录]
2012-02-19 10:27 | 杨粼波
模块啊,接口这些,技术肯定是成熟的。问题是你如何去实施。这些关键是你如何去划分功能,如何去设计接口,难度在这里,而不是说为了用而用。这需要很好的设计能力,掌控力。如果是掌控不了的东西,不如不用。其实对于游戏这种应用,很多时候,也不必要去做这样的设计,只要把低耦合做好了,一样好使。

重构对于大部分项目来说,是不可能的任务,如果开发者能力还可以,那倒是无所谓,如果不好,连正常跑都是个问题,那会死得很难看,就更不要说什么应对变更的需求了。如果项目的核心有很好的管理和技术上的掌控,就不会有太多的问题,即便是在很紧迫的开发时间下。

内存管理上,你是用内存池,还是用对象池,这需要开发者的选择的。服务器还需要考虑到多线程情况下的应用。有些特定情况下,加了反而会适得其反。

合适的就是最好的。  回复  更多评论
  
# re: 项目开发中的一些思考
2012-02-19 16:29 | feixuwu
在游戏开发领域,按照组件开发这种模式,在很多项目都实施过了,本人也参与过一些。不是理论上的泛泛而谈,实施上和设计上都不存在难点了。

游戏领域的需求变更是常事,基本上每几天一变都可能,甚至还没做完就在变了,这个和传统项目完全不同,对开发者是有一定要求的。

内存管理这块通用的内存优化方案确实是不需要开发者参与了(当然,也固定了优化模式,不可能是对象池),无论是多线程还是单线程,性能都会有很大的提升。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

文章转载请注明出处

常用链接

留言簿(11)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜