??xml version="1.0" encoding="utf-8" standalone="yes"?>久久国产免费直播,久久男人中文字幕资源站,国产精品久久久久久福利漫画http://www.shnenglu.com/jack-wang/archive/2011/09/29/157115.htmlWed, 28 Sep 2011 18:34:00 GMThttp://www.shnenglu.com/jack-wang/archive/2011/09/29/157115.htmlhttp://www.shnenglu.com/jack-wang/comments/157115.htmlhttp://www.shnenglu.com/jack-wang/archive/2011/09/29/157115.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/157115.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/157115.html转:http://www.cnweblog.com/fly2700/archive/2010/02/09/282920.html

参?/span>http://blog.csdn.net/kun1234567/archive/2007/12/11/1929815.aspx
W?步:下蝲
从官方主?/span>www.lua.org下蝲Lua源代码,最新版本ؓ5.1.3。(jack-wang注:现在已经?.1.4了)
解压之后扑ֈ“[Lua]/src”文g夹,q里面就是Lua了,不过q不能直接用?/p>

W?步:~译lua
使用LANSI C~译器,在这里用VS2005~译LUA。具体步骤如下:
a.打开vs的命令行工具Q工?->visual studio 2005 command prompt
b.跌{到[Lua]目录Q例如:cd  D:/Program Files/Lua
c.执行Qetc\luavs.batQ?注意Q是 \ 不是 /,写错了不能执行编?)
d.然后lua51.dll, lua51.lib, lua.exe, and luac.exeq成在 src 路径下了
e.在windows环境变量中把[Lua]\srcd到系lPath中去,

W?步:创徏lua脚本
下蝲LuaEdit http://luaforge.net/frs/download.php/1037/LuaEdit_2_5.zip 他是Lua脚本的编辑工Pq可以对Lua脚本q行语法和调试?/span>你也可以其他的纯文本~辑工具写一个文件test.luaQ注意后面没?#8220;;”

function f ( x, y)
    
return x + y
end

W?步:在C++ 中调用Lua脚本
开启VC++6.0环境创徏一个新文gmain.cpp
// Win32Console.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"

extern "C"
{
#include 
"D:/Lib/Lua/lua.h"
#include 
"D:/Lib/Lua/lualib.h"
#include 
"D:/Lib/Lua/lauxlib.h"
}

#pragma comment( lib ,
"D:/Lib/Lua/lua51.lib")
lua_State 
*L;

//调用lua
double fun( double x, double y )
{
 
double ret;
 lua_getglobal( L, 
"add");        // 获取全局变量f
 lua_pushnumber( L,x);          // 操作数压?/span>
 lua_pushnumber( L,y);          // 操作数压?/span>
 lua_call( L, 21);            // 执行Q?个操作数Q?个返回?br /> //lua_pcall( L, 2, 1, 0);      // 保护模式的lua_call,0为错误处理码。具体应用暂时不明,在用手册中有粗略介l?/span>
 ret = lua_tonumber( L, -1);    // 栈元素{换成数字q赋值给ret
 lua_pop( L, 1);                // 从栈中弹Z个元?/span>
 return ret;
}


//被lua调用的方?/span>
static int average(lua_State *L2)
{
    
/* get number of arguments */
    
int n = lua_gettop(L2);
    
double sum = 0;
    
int i;
    
/* loop through each argument */
    
for (i = 1; i <= n; i++)
    
{
    
/* total the arguments */
    sum 
+= lua_tonumber(L2, i);
    }

    lua_pushnumber(L, sum 
/ n);
    
/* push the sum */
    lua_pushnumber(L, sum);
    
/* return the number of results */
    printf(
"average called. [ok]\n");
    
return 2;
}

//==============================================
// Main Functions
//==============================================
int main( void)
{
 
int error;
 L 
= lua_open();          // 创徏Lua接口指针Q借用DX的术语,本质是个堆栈指针Q?/span>
 luaopen_base(L);     // 加蝲Lua基本?/span>
 luaL_openlibs(L);     // 加蝲Lua通用扩展?/span>
/*
 可能有的文章会采用以下写法,手工控制加蝲哪些库:
 luaopen_table(L);     // 加蝲table?br /> luaopen_io(L);           // 加蝲IO?br /> luaopen_string(L);    // 加蝲string?br /> luaopen_math(L);     // 加蝲math?br /> l过试Qluaopen_io(L);该句执行异常Q可能跟Lua的IO库有关系。具体原因暂时没有追IӞ来如果有机会弄清楚Q再回头来阐q?br />
*/

 
 
/* load the script */
 lua_register(L, 
"average", average);
 error 
= luaL_dofile(L, "hellow.lua");    // dLua源文件到内存~译

 
double ret = fun( 103.4);                // 调用模版函数f
 printf( "ret = %f\n", ret);                // 输出l果QC语言的东西,跟Lua无关
 lua_close( L);
 
return 1;
}


创徏一个hellow.lua文g和main.cpp攑֜一?写入以下内容
function add ( x, y)    
    file 
= assert(io.open("data.txt""w"))
    file:write(
"abcde\n")
    file:write(
"ok!\n")
    file:close()

    
--DataDumper(1,2,3,4)
    file 
= assert(io.open("data.txt""r"))
    str 
= file:read("*a")
    io.write(str)
    io.write(
"\n")
    
    avg, sum 
= average(102003000)
    print(
"The average is ", avg)
    print(
"The sum is ", sum)
    
    
return x + y
end


2011-09-29 02:34 发表评论
]]>
一U高效的寻\法 - B*寻\法http://www.shnenglu.com/jack-wang/archive/2011/04/07/143569.htmlWed, 06 Apr 2011 16:07:00 GMThttp://www.shnenglu.com/jack-wang/archive/2011/04/07/143569.htmlhttp://www.shnenglu.com/jack-wang/comments/143569.htmlhttp://www.shnenglu.com/jack-wang/archive/2011/04/07/143569.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/143569.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/143569.html转:http://qinysong.iteye.com/blog/678941


在此把这个算法称作B* 寻\法QBranch Star 分支寻\法Q且与A*对应Q,本算法适用于游戏中怪物的自动寻路,其效率远q超qA*法Q经q测试,效率是普通A*法的几十上癑ր?

通过引入该算法,一定程度上解决了游戏服务器端无法进行常规寻路的效率问题Q除非服务器端有独立的AI处理U程Q否则在服务器端无法允许可能消耗大量时间的寻\搜烦Q即使是业界普遍公认的最佳的A*Q所以普遍的折中做法是服务器端只做近距离的寻路,或通过D站点~短A*的范围?

法原理
本算法启发于自然界中真实动物的寻路过E,q加以改善以解决各种L问题?
前置定义Q?
1、探索节点:
Z叙述方便Q我们定义在寻\q程中向前探索的节点Q地图格子)UCؓ探烦节点Qv始探索节点即为原炏V(探烦节点可以对应为A*中的开放节点)

2、自q探烦节点Q?
探烦节点朝着目标前进Q如果前方不是阻挡,探烦节点可以l箋向前q入下一个地图格子,q种探烦节点我们UCؓ自由探烦节点Q?

3、绕爬的探烦节点Q?
探烦节点朝着目标前进Q如果前ҎLQ探索节点将试图l过LQ绕行中的探索节Ҏ们成为绕爬的探烦节点Q?
法q程
1、v始,探烦节点p点,从原点出发,向目标前q;
2、自p点前q过E中判断前面是否为障,
     a、不是障,向目标前q一步,仍ؓ自由节点Q?
     b、是障碍Q以前方障碍为界Q分出左右两个分支,分别试图l过障碍Q这两个分支节点xZ个绕爬的探烦节点Q?
3、绕爬的探烦节点l过障碍后,又成p点,回到2Q;
4、探索节点前q后Q判断当前地图格子是否ؓ目标格子Q如果是则寻路成功,Ҏ寻\q程构造完整\径;
5、寻路过E中Q如果探索节Ҏ有了Q则寻\l束Q表明没有目标格子不可达Q?


演示如下Q?nbsp;
    
   



B*与A*法的性能比较

寻\ơ数比较Q?U钟寻\ơ数Q?nbsp;


 
B*与A*性能比较实例
1?无障情?
此种情况Q根据以上测试数据,B*法效率是普通A*?4倍(左ؓA*Q右为B*)

     
 

2、线形障?
此种情况Q根据以上测试数据,B*法效率是普通A*?8倍(左ؓA*Q右为B*)

   

  
3、环形障?
此种情况Q根据以上测试数据,B*法效率是普通A*?32倍(左ؓA*Q右为B*)

      


4、封闭障(目标不可达)
此种情况Q根据以上测试数据,B*法效率是普通A*?81倍(左ؓA*Q右为B*)
    

衍生法
通过以上闭障碍Q可以看出,q个Ҏ在判断地图上的两个点是否可达上,也是非常高效的,在不可达情况下,旉复杂度与闭障碍的周长相当,而不是整个地囄面积?/font>

2011-04-07 00:07 发表评论
]]>
兽世界U服trinitycore2的架构——世界对?/title><link>http://www.shnenglu.com/jack-wang/archive/2010/07/11/120057.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Sat, 10 Jul 2010 17:53:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2010/07/11/120057.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/120057.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2010/07/11/120057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/120057.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/120057.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt">转自Q?a >http://blog.csdn.net/romandion/archive/2009/10/27/4733596.aspx</a><br><br>假设世界H然静止Q你能够从中单独L的物体就是构成这个世界的对象Q包括玩家、怪物、武器、矿石等。魔兽世界是个大型的|游Q里面的U类十分丰富Q更不用说对象了。当我看着trinity-core2的源码中Qgame目录的时候,有种ȝ的感觉,实在太多了。ؓ了理解方便,我们抽丝剥茧Q分析出cȝl承关系?/p> <p style="FONT-SIZE: 10pt">在tc2中,所有的对象都被认ؓ是objectQ以object作ؓ基类Q以1.2.3格式表示l承关系Q如Q? --> object  Q?.2 --> worldobject?.2表示worldobjectl承?QobjectQ。下面列出完整的对象l承族谱?/p> <p style="FONT-SIZE: 10pt">1?nbsp;                Object</p> <p style="FONT-SIZE: 10pt">1.1                 Item               【物品,比如武器?/p> <p style="FONT-SIZE: 10pt">1.1.1              Bag                 【包裹,Ҏ的物品,可以容纳其他物品?/p> <p style="FONT-SIZE: 10pt">1.2                 WorldObject     【显C在地图上的物体?/p> <p style="FONT-SIZE: 10pt">1.2.1              Corpse            【尸体?/p> <p style="FONT-SIZE: 10pt">1.2.2              DynamicObject 【动态生成的对象Q比如魔法,生命周期比较短?/p> <p style="FONT-SIZE: 10pt">1.2.3              GameObject     【游戏物品,q个分类很难从字面上理解Q后面会比较详细的介l?/p> <p style="FONT-SIZE: 10pt">1.2.3.1           Transport         【传送点?/p> <p style="FONT-SIZE: 10pt">1.2.4              Unit                 【游戏中有生命的单位?/p> <p style="FONT-SIZE: 10pt">1.2.4.1           Creature          【生物,非玩家?/p> <p style="FONT-SIZE: 10pt">1.2.4.2           TempSummon   【时召唤物?/p> <p style="FONT-SIZE: 10pt">1.2.4.2.1         Minion              【宠物?/p> <p style="FONT-SIZE: 10pt">1.2.4.2.1.1      Guardian          【守卫?/p> <p style="FONT-SIZE: 10pt">1.2.4.2.1.1.1   Pet               【玩家的宠物Q比如猎人的宠物Q或者术士的恉Q除非主散,否则一直存在?/p> <p style="FONT-SIZE: 10pt">1.2.4.2.1.2      Puppet             【傀儡,有一定的存在旉。比如d鲁依的树人?/p> <p style="FONT-SIZE: 10pt">1.2.4.2.1.3      Totem              【图腾,萨满的图腾?/p> <p style="FONT-SIZE: 10pt">1.2.4.2            Player              【玩Ӟ׃用多解释了?/p> <p style="FONT-SIZE: 10pt">整个魔兽世界分解静态物体和静态物体的行ؓQ就比较好理解了。事实上Q现实世界也是如此。将世界划分为时间和I间2个维度,现实物体是I间的概念,行ؓ是I间物体在时间维度上的变化。象光或者其他不可见或者没有空间占位的物品也可以看作特D的I间物体。我在这里先空间维度将分离出来分析?/p> <p style="FONT-SIZE: 10pt">差点忘了介绍GameObjectq个另类。在GameObject.h中,有个struct GameObjectInfo定义Q里面有个union能大概看出GameObjectI竟指的是哪些东ѝ?/p> <p style="FONT-SIZE: 10pt">0、GAMEOBJECT_TYPE_DOORQ指的是?/p> <p style="FONT-SIZE: 10pt">1、GAMEOBJECT_TYPE_BUTTONQ应该是按钮Q锁之类的?/p> <p style="FONT-SIZE: 10pt">2、GAMEOBJECT_TYPE_QUESTGIVERd物品</p> <p style="FONT-SIZE: 10pt">3、GAMEOBJECT_TYPE_CHEST子</p> <p style="FONT-SIZE: 10pt">4、GAMEOBJECT_TYPE_BINDER没定义,估计没有用上?/p> <p style="FONT-SIZE: 10pt">5、GAMEOBJECT_TYPE_GENERIC通用的,跟Q务相关的东西</p> <p style="FONT-SIZE: 10pt">6、GAMEOBJECT_TYPE_TRAP陷阱</p> <p style="FONT-SIZE: 10pt">7、GAMEOBJECT_TYPE_CHAIR椅子</p> <p style="FONT-SIZE: 10pt">8、GAMEOBJECT_TYPE_SPELL_FOCUS没搞懂啥玩意ѝ?/p> <p style="FONT-SIZE: 10pt">9、GAMEOBJECT_TYPE_TEXT文本</p> <p style="FONT-SIZE: 10pt">10、GAMEOBJECT_TYPE_GOOBER应该是果实一cȝ吧?/p> <p style="FONT-SIZE: 10pt">11、GAMEOBJECT_TYPE_TRANSPORT传送点</p> <p style="FONT-SIZE: 10pt">12、GAMEOBJECT_TYPE_AREADAMAGE区域性伤宻I没搞懂啥玩意ѝ?/p> <p style="FONT-SIZE: 10pt">13、GAMEOBJECT_TYPE_CAMERA照相机,再研I下</p> <p style="FONT-SIZE: 10pt">14、GAMEOBJECT_TYPE_MAPOBJECT地图对象Q空着</p> <p style="FONT-SIZE: 10pt">15、GAMEOBJECT_TYPE_MO_TRANSPORT地图对象的传送,不知道啥玩意ѝ?/p> <p style="FONT-SIZE: 10pt">16、GAMEOBJECT_TYPE_DUELFLAGx标志Q估计就是PKQ插旗吧。空着没用</p> <p style="FONT-SIZE: 10pt">17、GAMEOBJECT_TYPE_FISHINGNODE钓鱼?/p> <p style="FONT-SIZE: 10pt">18、GAMEOBJECT_TYPE_SUMMONING_RITUAL仪式Q不知道q啥。估计跟术士拉h那东西有兟?/p> <p style="FONT-SIZE: 10pt">19、GAMEOBJECT_TYPE_MAILBOX邮箱</p> <p style="FONT-SIZE: 10pt">20、GAMEOBJECT_TYPE_DONOTUSE֐思义Q没?/p> <p style="FONT-SIZE: 10pt">21、GAMEOBJECT_TYPE_GUARDPOST岗哨Q是某种生物</p> <p style="FONT-SIZE: 10pt">22、GAMEOBJECT_TYPE_SPELLCASTER法施放?/p> <p style="FONT-SIZE: 10pt">23、GAMEOBJECT_TYPE_MEETINGSTONE集合?/p> <p style="FONT-SIZE: 10pt">24、GAMEOBJECT_TYPE_FLAGSTAND不知道啥玩意ѝ?/p> <p style="FONT-SIZE: 10pt">25、GAMEOBJECT_TYPE_FISHINGHOLE估计也是钓鱼?/p> <p style="FONT-SIZE: 10pt">26、GAMEOBJECT_TYPE_FLAGDROP掉落标记</p> <p style="FONT-SIZE: 10pt">27、GAMEOBJECT_TYPE_MINI_GAME也没懂是啥玩意儿?/p> <p style="FONT-SIZE: 10pt">28、GAMEOBJECT_TYPE_CAPTURE_POINT应该是部落和联盟争夺地区</p> <p style="FONT-SIZE: 10pt">29、GAMEOBJECT_TYPE_AURA_GENERATOR灉|</p> <p style="FONT-SIZE: 10pt">30、GAMEOBJECT_TYPE_DUNGEON_DIFFICULTYC城难?/p> <p style="FONT-SIZE: 10pt">31、GAMEOBJECT_TYPE_BARBER_CHAIR理发师的椅子Q唉Q都啥玩意儿啊?/p> <p style="FONT-SIZE: 10pt">32、GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING可摧毁的建筑</p> <p style="FONT-SIZE: 10pt">33、GAMEOBJECT_TYPE_GUILDBANK工会银行Q空Q不可见?/p> <p style="FONT-SIZE: 10pt">34、GAMEOBJECT_TYPE_TRAPDOOR陷阱的门?/p> <p style="FONT-SIZE: 10pt">应该_GameObject是描q游戏中Q除装备、生物、魔法外Q无法准归cȝ东西Q比较杂Q因此只能笼l归lؓ游戏对象</p> <p style="FONT-SIZE: 10pt"><br>本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/romandion/archive/2009/10/27/4733596.aspx</a></p> <img src ="http://www.shnenglu.com/jack-wang/aggbug/120057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2010-07-11 01:53 <a href="http://www.shnenglu.com/jack-wang/archive/2010/07/11/120057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏对象的实?/title><link>http://www.shnenglu.com/jack-wang/archive/2010/07/10/120049.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Sat, 10 Jul 2010 14:54:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2010/07/10/120049.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/120049.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2010/07/10/120049.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/120049.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/120049.html</trackback:ping><description><![CDATA[狭义的游戏对象是指游戏世界中所能看到及可交互的对象Q如玩家、怪物、物品等Q我们这里也主要讨论q类对象在服务器上的l织及实现? <p style="FONT-SIZE: 10pt"></p> <p style="FONT-SIZE: 10pt">  在大部分的MMOG中,游戏对象的类型都大同异Q主要有物品、生物、玩家等。比如在wow中,通过服务器发下来的GUID我们可以了解刎ͼ游戏中有9大类对象Q包括物?Item)、背?Container)、生?Unit)、玩?Player)、游戏对?GameObject)、动态对?DynamicObject)、尸?Corpse){?/p> <p style="FONT-SIZE: 10pt">  在mangos的实CQ对象用类l承的方式,由Object基类定义游戏对象的公有接口及属性,包括GUID的生成及理、构造及更新UpdateData数据的虚接口、设|及获取对象属性集的方法等。然后分Z两类z对象Q一是ItemQ另一是WorldObject。Item即物品对象,WorldObject֐思义Qؓ世界对象Q即可添加到游戏世界场景中的对象Q该对象cd定义了纯虚接口,也就是不可被实例化,主要是在Object对象的基上又d了坐标设|或获取的相x口?/p> <p style="FONT-SIZE: 10pt">  Itemcd又派兵出了一cBag对象Q这是一U特D的物品对象Q其本nh物品的所有属性及ҎQ但又可作ؓ新的容器cdQƈh自己Ҏ的属性和ҎQ所以实C采用了派生。mangos在实现时对Bag的类型定义做了点技巧,Item的类型ؓ2QBag的类型ؓ6Q这样在通过位的方式来表C类型时QBagcd也就同时属于Itemcd了。虽然只是很的一个技巧,但在很多地方却带来了极大的便利?/p> <p style="FONT-SIZE: 10pt">  从WorldObjectz出的cd有好几U了QUnit、GameObject、DynamicObject和Corpse?br>         <br>         Unit为所有生物类型的基类Q同WorldObject一P也不可被实例化。它定义了生物类型的公有属性,如种族、职业、性别、生命、魔法等Q另外还提供了相关的一些操作接口。游戏中实际的生物对象类型ؓCreatureQ从UnitzQ另外还有一cL生对象Player为玩家对象。Player与Creature在实C最大的区别是玩家的操作由客L发来的消息驱动,而Creature的控制是p己定义的AI对象来驱动,另外Player内部q包括了很多的逻辑pȝ实现?/p> <p style="FONT-SIZE: 10pt">  另外q有两类Ҏ的CreatureQPet和TotemQ其对象cd仍然q是生物c,只是实现上与会有些特D的东西需要处理,所以在mangos中将其作为独立的zc,只是实现上的一点处理。另外在GameObject中也实现有派生对象,最l的l承关系图比较简单,׃ȝ地去d了?/p> <p style="FONT-SIZE: 10pt">  从我所了解的早期游戏实现来看,大部分的游戏对象l构都是采用的类DU方式。可能与早期寚w向对象的理解有关Q当面向对象的概念刚出来Ӟ大家认ؓl承是面向对象的全部,所以处处皆对象Q处处皆l承?/p> <p style="FONT-SIZE: 10pt">  cd现的是一U封装,虽然从云风那里出来的弃C++而{投C的声韛_能会影响一部分人,但是Q用什么语a本n是个h喜好及团队整体情况决定的。我们所要的也是最l的实现l果Q至于中间的步骤Q完全看个h。还是用云风的话_q只是一U信仰问题,我依焉用我所熟悉的C++Q下面的描述也是如此?/p> <p style="FONT-SIZE: 10pt">  随着面向对象技术的深入Q以及泛型等概念的相l提出,软gE序l构斚w的趋势也有了很大改变。C++大师们常说的话中有一句是q样说的Q尽是采用组合而不是ѝ游戏对象的实现也有cM的{变,向于以l合的方式来实现游戏对象cdQ也是实现一个通用的entitycdQ然后以脚本定义的方式组合出不同的实际游戏对象类型?/p> <p style="FONT-SIZE: 10pt">  <br><br>         在游戏编E精_四有三文章讲C实体以及实体理的实现方案,其中一文章说C实体理pȝ的四大要素:定义实体怎样沟通的实体消息Q实C实体cM码和数据的实体代码,l护已经注册在案的实体类列表Q和用来创徏、管理、发送消息的实体理器?/p> <p style="FONT-SIZE: 10pt">  关于实体消息的内容之前讨Z件机制的时候做q一点说明,其实q也是按接口调用和按消息驱动的区别Q现在mangos的做法是完全的接口调用,所以引擎内部就没有M的实体消息。实体代码实现和实体理器是我们重点要讨论的内容?/p> <p style="FONT-SIZE: 10pt">  另有一文章也提到了用类l箋的方式实现游戏对象的两大问题Q一是它要求pȝ中的所有对象都必须从一个v点衍生而成Q也是说所有对象类在编译的时候已l确定,q可能是一个不受欢q的限制Q如果开发者决定添加新的对象类Q则必须要对基类有所了解Q方能支持新cR另一个问题在于所有的对象c都必须实现同样的一些底层函数?/p> <p style="FONT-SIZE: 10pt">  对于W二个问题,可以通过接口l承的方式来避免基类的方法太多。在mangos的实C采用了cM的方法,从Object虚基cL生的Unit和WorldObject仍然q是不可实例化的c,q两U对象定义了不同的属性和ҎQ分来实C同类型的对象。在游戏内部可以Ҏ对象的实际类型来Object指针向下转型为Unit或WorldObjectQ以调用需要的接口。方法虽然不够OOQ也q能解决问题。但是第一个问题是始终无法避免的?/p> <p style="FONT-SIZE: 10pt">  所以我们便有了通用实体q么一个概念,其主要方法是原来基cȝ接口q行分类Q分C个个不同的子cMQ然后以对象l合的方式来生成我们所需要的实际游戏对象cd。这个组合的q程可以通过脚本定义的方式,q样便可以在q行时生成ؓ同的对象cdQ也p决了上面提到的第一个问题?/p> <p style="FONT-SIZE: 10pt">  通用实体的实现方法在目前的游戏引擎及开源代码中也可以看到媄子。一个是BigWorldQ从提供的资料来看,其引擎只提供了一个entity游戏对象Q然后由游戏内容实现者通过xml和python脚本来自由定义不同类型的entitycdQ每U类型可有不同的property和不同的Ҏ。这样原来由基类定义的接口完全{Ud脚本定义Q具有非常强的灵zL?/p> <p style="FONT-SIZE: 10pt">  另外q有一个是CEL中的entity实现。按照CEL的描qͼentity可以是游戏中的Q意对象,包括玩家可交互的对象Q如钥匙、武器等Q也可以包括不能直接交互的对象,如游戏世界,甚至d链中的一部分{。entity本nq没有Q何特性,具体的功能实现需要靠附加property来完成。简单来_property才定义了entity可以做什么,至于该怎么做,那又是依靠behavior来定义。所以,最l在CEL中一个游戏对象其实是由entityl合了多个property及多个behavior而生成的?/p> <p style="FONT-SIZE: 10pt">  但是CEL中的property与BigWorld中的property意义不大一P在CEL中可定义的property其实是引擎内部要先提供的Q比如其CZ中所丄pcobject.mesh、pcmove.linear、pctools.inventory{,而BigWorld中的property是完全的自由定制。从q个角度来讲Q其实可以把CEL中的property看作是游戏的逻辑pȝQ也是我们上面所描述的,接口分类后所定义的子cR?/p> <p style="FONT-SIZE: 10pt">  由引擎内部提供可选择的property与BigWorld所采用的完全自由定制property其实本质上是相同的。在用BigWorld实现的游戏中Q也不可能ؓ每种游戏对象cd都完全从头定义propertyQ基于代码利用的原则Q也会先定义一些小c,然后在entitycd定义时以自定义property的方式来包含q些类。当Ӟ我没有用过BigWorldQ上面的描述也只是基于游戏实现的大原则所做出来的?/p> <p style="FONT-SIZE: 10pt">  描述的依然有些抽象,我们可以用wow及mangos代码来说明一下。mangos中ؓobject定义了一个属性集合,Ҏ对象cd的不同,q个属性集的大及保存数据也会有差异,另外游戏对象内部含有处理不同游戏逻辑的系l,如RestSystem、FloodFilterSystem、VariousSystem{等Q在player.h中以接口l的方式q行定义?/p> <p style="FONT-SIZE: 10pt">  如果要将q种l构改ؓ我们描述的通用entitypȝQ可以让object只提供property注册和删除的接口Q这里的property定义与CEL中的相同Q放在mangos中也是上面说的RestSystem、FloodFilterSystem、VariousSystemq些。然后也通过xml文g的方式定义我们所需要的游戏对象cdQ如player,creature,item{,不同的对象类型可以选择加蝲不同的propertyQ加载的原则是需要哪些功能就加蝲哪些property?/p> <p style="FONT-SIZE: 10pt">  对象的定义按上面的方法完成后Q对象的实现也需要做一些修攏V以前客L的消息是直接交由player来处理,AI也是直接调用creature的接口来完成一些功能,现在通用的entity内部已经没有M可用的方法,所有的实现都{Cproperty中,所以需要由各个property实现自己来注册感兴趣的事件及消息Qentity实现一个消息的转发Q{l对此感兴趣的property来处理。其余的实现没有什么不同了?/p> <p style="FONT-SIZE: 10pt">  当然Q我们再做一Ҏ展,让property不光由引擎来提供Q用脚本本n也能定义propertyQƈ且可以通过xml来注册这些propertyQ这样便实现了与BigWorld一L完全自由Ҏ。这其实也就是将很多用C++实现的功能{Ud了python中,q种做法可作为参考,但不一定对所有h合适,臛_在我看来Q这L实现也基本只能由E序员来做,所以让E序员选择自己最擅长的语a可能会更易于开发和调试?br><br><br><br><br>有关游戏对象实现的描qͼ前面两篇文章中说的不甚清楚,主要是一直都要引用网上能够找到的资料来进行描qͼ以避免与公司引v不必要的ȝ。所以语a有些拼凑的感觉,丄例子也很不恰当,今天正好看到了游戏编E精_五和六上的两篇文章Q内定w差不多,<<Zlg的对象管?gt;>?lt;<Zlg的游戏对象系l?gt;>Q说的也是我上两文章想要描q的内容Q所以再补一,引用其中的部分文字进行明的说明?<br></p> <p style="FONT-SIZE: 10pt" align=left>  传统的游戏对象管理系l采用承的方式来实玎ͼ例如Q所有的子类都从CObjectz。大多数情况下,直接z的也是抽象类Q其中带一些功能而另一些子cd不带q些功能Q比如可控制/不可控制Q可动画/不可动画{。mangos的实C基本是q种情况Q从Object直接z的Unit和WorldObject都是不可直接实例化的cR?/p> <p style="FONT-SIZE: 10pt"><br> </p> <p style="FONT-SIZE: 10pt" align=left>  传统Ҏ的问题在于无法应寚w求的变化Q如要求武器也有动画效果时就无法处理了。如果硬要是q样做,那随着需求的啬,很多的方法会被放到基cMQ最l的l果是承树变得来头重脚轻,q样的类会失它的内聚性,因ؓ它们试图为所有对象完成所有的事?/p> <p style="FONT-SIZE: 10pt"> </p> <p style="FONT-SIZE: 10pt" align=left>  是说到最后,基类会有一个很长的接口列表Q而很多的游戏对象cdҎ不需要实现其中的一些甚臛_部分接口Q但是按照这U结构却又必d实现。以至于于实C个非常庞大的对象Q而且惌修改一点功能会Dpȝ的大调整?/p> <p style="FONT-SIZE: 10pt"> </p> <p style="FONT-SIZE: 10pt" align=left>  我们希望的系l是可以现有的功能l合到新的对象中Qƈ且在新的功能添加到现有的对象中时不需要重构大量的代码和调整承树的结构?/p> <p style="FONT-SIZE: 10pt"> </p> <p style="FONT-SIZE: 10pt" align=left>  实现的方法就是从lg来创Z个对象。组件是一个包含所有相x据成员和Ҏ的类Q它完成某个特定的Q务。把几个lgl合在一起就可以创徏一个新的对象。如把Entitylg、Renderlg和Collectablelgl合在一L成了一个Spoon对象。Entitylg让我们可以把对象攑ֈ游戏世界中,Renderlg让我们可以ؓ对象指定一个模型进行渲染,而Collectablelg让我们可以拾取这个对象?/p> <p style="FONT-SIZE: 10pt"> </p> <p style="FONT-SIZE: 10pt" align=left>  关于lg的实玎ͼ所有的lg都从一个基lg接口zQ可U其为IComponent。每个组件也有自q接口定义Qƈ且这个接口也需要从IComponentzQ类gq样QIComponent -- ICmpRender -- CCmpRender M<br></p> <p style="FONT-SIZE: 10pt" align=left>  q里的每个组件也是我在上一中所说的由引擎提供的属性,或者说在BigWorld中自己实现然后定义的属性,或者用mangos中的定义Q就是一个个的SystemQ虽然mangosq没有将其完全做成组Ӟ但是通过其代码注释可以看刎ͼ接口也是按功能组q行了分c,如果要拆分成lg也是比较方便的?/p> <p style="FONT-SIZE: 10pt" align=left>  lg之间的通信有两U方法,一是用lgID查询到组件接口指针,然后调用接口ҎQ二是用消息的方式Q向对象中所有组件发消息。在初始化的时候,每一个组件类型都会告诉对象管理器应该接收什么样的消息?br></p> <p style="FONT-SIZE: 10pt" align=left>  查询接口的方法也是直接的方法调用,只不q接口不是全部在基类中,所以必d查询到指定的lg然后才能调用其接口。消息的使用前面已经说过多次Q其实现Ҏ也有q说明?br></p> <p style="FONT-SIZE: 10pt" align=left>  最后是关于游戏对象功能的扩展和游戏对象的定义。需要扩展功能也是需要实C个新的组Ӟ或者修改现在组件。在大多数情况下Q扩展都不会引vl构的很大调_受媄响的最多只是用到该组件的部分代码?br></p> <p style="FONT-SIZE: 10pt" align=left>  游戏对象定义可采用完全数据驱动的方式Q用xml或者脚本语a来定义对象类型,以及每个cd需要加载的lg。对象类型注册到对象理器后Q由理器提供创建指定类型的对象的方法。数据驱动的方式能够让策划自由定义游戏对象类型,q且随时可自由创建新的对象类型?/p> <img src ="http://www.shnenglu.com/jack-wang/aggbug/120049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2010-07-10 22:54 <a href="http://www.shnenglu.com/jack-wang/archive/2010/07/10/120049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>L是目标Y件的服务器架构(转蝲的,不关我事哦,囄׃发了Q懒Q?/title><link>http://www.shnenglu.com/jack-wang/archive/2010/01/16/105817.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Sat, 16 Jan 2010 07:38:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2010/01/16/105817.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/105817.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2010/01/16/105817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/105817.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/105817.html</trackback:ping><description><![CDATA[     摘要:                                              计算机研I生开攄I?nbsp;    ...  <a href='http://www.shnenglu.com/jack-wang/archive/2010/01/16/105817.html'>阅读全文</a><img src ="http://www.shnenglu.com/jack-wang/aggbug/105817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2010-01-16 15:38 <a href="http://www.shnenglu.com/jack-wang/archive/2010/01/16/105817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>|络游戏中的同步问题http://www.shnenglu.com/jack-wang/archive/2010/01/10/105312.htmlSat, 09 Jan 2010 17:22:00 GMThttp://www.shnenglu.com/jack-wang/archive/2010/01/10/105312.htmlhttp://www.shnenglu.com/jack-wang/comments/105312.htmlhttp://www.shnenglu.com/jack-wang/archive/2010/01/10/105312.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/105312.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/105312.html同步在网l游戏中是非帔R要的Q它保证了每个玩家在屏幕上看到的东西大体是一L。其实呢Q解军_步问题的最单的Ҏ是把每个玩家的动作都向其他玩家 q播一遍,q里其实存在两个问题:1Q向哪些玩家q播Q广播哪些消息?Q如果网lgq怎么办?/p>

事实上呢Q第一个问题是个非常简单的问题Q不q之所以我 提出q个问题来,是提醒大家在设计自己的消息结构的时候,需要把q个因素考虑q去。而对于第二个问题Q则是一个挺ȝ的问题,大家可以来看q么个例子: 比如有一个玩家A向服务器发了条指令,说我现在在P1点,要去P2炏V指令发出的旉是T0Q服务器收到指o的时间是T1Q然后向周围的玩?q播q条消息Q消息的内容?#8220;玩家A从P1到P2”有一个在A附近的玩家BQ收到服务器的这则广播的消息的时间是T2Q然后开始在客户端上dQA从P1 到P2炏V这个时候就存在一个不同步的问题,玩家A和玩家B的屏q上昄的画面相差了T2-T1的时间。这个时候怎么办呢Q?有个解决 ҎQ我l它取名?预测拉扯Q虽然有些怪异了点Q不q基本上大家也能从字面上来理解它的意思?/p>

要解册个问题,首先要定义一个值叫Q预误差。然后需要在服务器端每个玩家q?接的c里面加一属性,叫TimeModifiedQ然后在玩家登陆的时候,对客L的时间和服务器的旉q行比较Q得出来的差g存在 TimeModified里面。还是上面的那个例子Q服务器q播消息的时候,根据要q播对象的TimeModifiedQ计出一个客L?CurrentTimeQ然后在消息头里面包含这个CurrentTimeQ然后再q行q播。ƈ且同时在玩家A的客L本地建立一个队列,保存该条消息Q?只到获得服务器验证就从未被验证的消息队列里面该消息删除Q如果验证失败,则会被拉扯回P1炏V然后当玩家B收到了服务器发过来的消息“玩家A从P1?P2”q个时候就查消息里面服务器发出的时间和本地旉做比较,如果大于定义的预误差,q出在T2q个旉Q玩家A的屏q上走到的地点P3Q然后把 玩家B屏幕上的玩家A直接拉扯到P3Q再l箋C去,q样p保证同步?/p>

更进一步,Z保证客户端运行v来更加smoothQ我q不推荐直接把玩家拉扯过 去,而是出P3偏后的一点P4Q然后用(P4-P1)/T(P4-P3)来算Z个很快的速度SQ然后让玩家A用速度S快速移动到P4Q这L处理Ҏ 是比较合理的Q这U解x案的原Ş在国际上被称为(Full plesiochronousQ,当然Q该原Ş被我改了很多来适应|络游戏的同步,所以而变成所谓的Q预拉扯?另外一个解x 案,我给它取名叫 验证同步Q听名字也知道,大体的意思就是每条指令在l过服务器验证通过了以后再执行动作。具体的思\如下Q首先也需要在每个玩家q接cd里面定义一?TimeModifiedQ然后在客户端响应玩安标行走的同时Q客Lq不会先行走动,而是发一条走路的指ol服务器Q然后等待服务器的验证。服务器?受到q条消息以后Q进行逻辑层的验证Q然后计出需要广播的范围Q包括玩家A在内Q根据各个客L不同的TimeModified生成不同的消息头Q开?q播Q这个时候这个玩家的走\信息是完全同步的了?/p>

q个Ҏ的优Ҏ能保证各个客L之间l对的同步,~点是当|络延迟比较大的时候,玩家的客L的行 Z变得比较不流畅,l玩家带来很不爽的感觉。该U解x案的原Ş在国际上被称为(Hierarchical master-slave synchronizationQ,80q代以后被广泛应用于|络的各个领域?

最后一U解x案是一U理惛_的解x案,在国际上?UCؓMutual synchronizationQ是一U对未来|络的前景的良好预测出来的解x案。这里之所以要提这个方案,q不是说我们已经完全的实Cq种ҎQ?只是在网l游戏领域的某些斚w应用到这U方案的某些思想。我对该U方案取名ؓQ半服务器同步。大体的设计思\如下Q?首先客户端需要在 登陆世界的时候徏立很多张q播列表Q这些列表在客户端后台和服务器要q行不及时同步,之所以要建立多张列表Q是因ؓ要广播的cd是不止一U的Q比如说?local message,有remote message,q有global message {等Q这些列表都需要在客户端登陆的时候根据服务器发过来的消息建立好。在建立列表的同Ӟq需要获得每个列表中q播对象的TimeModifiedQƈ 且要l护一张完整的用户状态列表在后台Q也是不及时的和服务器进行同步,Ҏ本地的用L态表Q可以做C部分决策由客L自己来决定,当客L发送这?分决{的时候,则直接将最l决{发送到各个q播列表里面的客LQƈ对其旉q行校对Q保证每个客L在收到的消息的时间是和根据本地时间进行校对过的?那么再采用预拉扯中提到q的计算提前量,提高速度行走q去的方法,会使同步变得非常的smooth。该Ҏ的优Ҏ不通过服务器,客户端自׃间进?同步Q大大的降低了由于网lgq而带来的误差Qƈ且由于大部分决策都可以由客户端来做,也大大的降低了服务器的资源。由此带来的弊端是׃消息和决{权 都放在客L本地Q所以给外挂提供了很大的可乘之机?

l合以上三种关于|络同步z的优~点Q综合出一套关于网l游戏传输同步的较完整的解决ҎQ我U它为综合同步法Qcolligate synchronizationQ。大体设计思\如下Q?首先服务器需要同步的所有消息从划分一个优先等U,然后按照3/4的比例划分出重要消息和非重要消息Q对于非重要消息Q把决策权放在客LQ在客户端逻辑上徏立相关的决策机构和各U消息缓存区Q以及相关的消息~存区管理机构,如下图所C: 上图单说明了对于非重要消息,客户端的大体处理程Q其中有一个客L被动行ؓ值得大家注意Q其中包括对服务器发q来的某些验证代码做q回Q来保?息缓存中的消息和服务器端是一致的Q从而有效的防止外挂来篡Ҏ地消息缓存。其中的消息来源是包括本地的客户端响应玩家的消息以及q程服务器传递过来的?息?

对于重要消息Q比如说战斗或者是某些牉|到玩家一些比较敏感数据的操作Q则采用另外一套方案,该方案首先需要在服务器和客户端之 间徏立一套Ping SystemQ然后服务器保存和用L及时的ping|当ping比较的时候,响应玩家消息的同时先不进行动作,而是先把该消息反馈给服务器,q且?塞,服务器收到该消息Q进行逻辑验证之后向所有该详细q播的有效对象进行广播(包括消息发v者)Q然后客L收到该消息的验证Q才开始执行动作。而当 ping比较大的时候,客户端响应玩家消息的同时立刻q行动作Qƈ且同时把该消息反馈给服务器,值得注意的是q个时候还需要在本地建立一个无验证消息的队 列,把该消息入队Q执行动作的同时{待服务器的验证Q还需要保存当前状态。服务器收到客户端的h后,q行逻辑验证Qƈ把消息反馈到各个客户端,带上各个 客户端校对过的本地时间。如果验证通过不过Q则通知消息发v者,该消息验证失败,然后客户端自动把已经在进行中的动作取消,恢复原来状态。如果验证通过Q?则广播到的各个客LҎ从服务器获得校对旉q行对其q行拉扯Q保证在该行为完成之前完成同步?xQ一个比较成熟的|络游戏的同步机制已l初步徏立v来了Q接下来的逻辑代码根据各自不同的游戏风格以及侧重Ҏ写了?同步是网l游戏最重要的问题,如何同步也牵扯到各个斚w的问题,比如说游戏的规模Q游戏的cd以及各种各样的方面,对于规模比较大的游戏Q在同步斚w?以下很多的工夫,把消息分得十分的l腻Q对于不同的消息采用不同的同步机Ӟ而对于规模比较小的游戏,则可以采用大体上一L同步机制Q究竟怎么样同步, 没有个定式,是需要根据自q不同情况来做Z同的同步决策?|游同步法之导航推(Dead ReckoningQ算法: 在了解该法前,我们先来谈谈该算法的一些背景资料?/p>

大家都知道,在网l传输的时候,延迟现象是很普遍的,而在ZServer/Clientl构下的 |络游戏的同步也成了很头疼的问题,在保证客L响应用户本地指o畅的情况下Q没法有效的保证的同步的及时性。同P在军方也有类似的事情发生Q即?是同一LAN里面的机器,也会因ؓ传输的gq,D一些运的pQ介于此Q美国国防部投入了大量的资金用于研究一U比较的好的Ҏ来解军_布式pȝ中的 延迟问题Q特别是一个叫分布式模拟运动(Distributed Interactive SimulationQ的pȝQ这套系l呢Q其中就提出了一套号U是Latency Hiding & Bandwidth Reduction的方案,命名为Dead Reckoning。呵呵,来头很大吧,恩,那么我们下面来看看q套pȝ的一些观点,以及我们如何把它q用到我们的|络游戏的同步中?首先Q这套同步方案是Z我那《网l游戏的同步》一文中的Mutual Synchronization同步Ҏ的,也就是说Q它q不是Server/Clientl构的,而是Z客户端之间的同步的?/p>

下面我们先来说一些本文中用到的名词概念Q网状网l:客户端之间构成的|络节点Q网状网l中的每个客L极限误差Q进行同步的时候可能生的误差的极?恩,在探讨其原理的之前,我们先来看看我们需要一个什么样的环境。首先,需要一个网状网l,|状|络如何构成呢?当有新节点进入的时候,通知该网l里?的所有节点,各节点ؓ该客L在本地创Z个副本,d的时候,则通知所有节炚w毁本地关于该节点的副本。然后每个节点该保存一些什么数据呢Q首先有一?很重要的包需要保存,叫做协议数据包(PDU Protocol Data UnitQ,PDU包含节点的一些相关的q动信息Q比如当前位|,速度Q运动方向,或者还有加速度{一些信息。除PDU之外Q还有其他信息需要保存,比如 说节点客L人物的HPQMP之类的。然后,保证每个节点在最?U之内要向其它节点广播一ơPDU信息。最后,讄一个极限误差倹{到此,其环境就搭 建完成了。下面,我们来看看相关的具体算法: 假设在节点A有一个小人(路hԌQ开始跑路了Q这个时候,像所有的节点q播一ơ他 的PDU信息Q包括:速度QSQ,方向QOQ,加速度QAQ。那么所有的节点开始模拟\人甲的运动轨q和路线Q包括节点A本nQ这点很重要Q,同时Q\ 人甲在某某玩家的控制下,会不时的改变一下方向,让其跑\的\U变得不是那么正规。在跑\的过E中Q节点A有一个值在不停的记录着其真实坐标和在后台模?q动的坐标的差|当差值大于极限误差的时候,则计出当前的速度SQ方向O和速度AQ算法将在后面介l)Qƈq播l网l中其他所有节炏V其他节点在收到 q条消息之后呢,可以用一些很qx的移动把路h甲拉扯过去,然后重新调整模拟跑\的数据,让其l箋在后台模拟跑路?很显Ӟ如果?限误差定义得大了Q其他节点看到的偏差׃q大Q如果极限偏差定义得了Q网l带宽就会增大。如果定义这个极限误差,pҎ各种数据的重要性来设计了?如果是回合制的网l游戏,那么在走路上把极限误差定义得大些无所谓,可以减少带宽。但是如果是及时打斗的网l游戏,那么得把极限误差定义得一些,否则 会出现某人看到某远把自q砍死的情c?Dead Reckoning的主要算法有9U,但是只有两种是解决主要问题的Q其他的基本上只是针对不同的坐标pȝ一些不同的法Q这里就不一一介绍了。好Q那么我们下面来看传说中的最主要的两U算法:W一Q目标点 = 原点 + 速度 * 旉差第二:目标?= 原点 + 速度 * 旉?+ 1/2 * 加速度 * 旉差呵呵,传说中的法都是很经典的Q虽然我们早在初中物理的时候就学过?该算法的好处呢,正如它开始所说的QLatency Hiding & Bandwidth ReductionQ从原则上解决了|络延迟D的不同步的问题,q且有效的减了带宽Q不好的地方是该算法基本上只能使用于移动中的同步,当然Q移?的同步是|络游戏中同步的最大的问题?该方法结合我在《网l游戏的同步》一文中提出的综合同步法的构架可以基本上解决掉网l游戏中走\同步的问题。相关问题欢q大家一赯论?

有关D推测法QDead ReckoningQ中的^滑处理: Ҏ我上文章所介绍的,在节点A收到节点B新的PDU包时Q如果和A本地的关于B的模拟运动的坐标不一致时Q怎么样在A的屏q上把B拽到新的PDU?所描叙的点上面dQ上文中只提了用“很^滑的Ud”把B“拉扯”q去Q那么实际中应该怎么操作呢?q里介绍四种Ҏ?W一U方法,我取名叫直接拉扯法,大家听名字也知道Q就是直接把B生生的拽到新的PDU包所描叙的坐标上去,该方法的好处是:单。坏处是Q看了以下三U方法之后你׃会用q种Ҏ了?W二U方法,叫直U行赎ͼLinearQ,卌B从它的当前坐标走直线到新的PDU包所描叙的坐标,行走速度用上文中所介绍的经典算法:目标?= 原点 + 速度 * 旉?+ 1/2 * 加速度 * 旉差算出:首先出从当前坐标到PDU包中描叙的坐标所需要的旉Q?T = Dest( TargetB – OriginB ) / Speed 然后Ҏ新PDU包中所描叙的坐标信息模拟计出在时间T之后Q按照新的PDU包中的运动信息所应该辑ֈ的位|: _TargetB = NewPDU.Speed * T 然后Ҏ当前模拟行动中的B和_TargetB的距配合时间T出一个修正过的速度_SQ?_S = Dest( _TargetB – OriginB ) / T 然后在画面上让B以速度_S走直U到Target_BQƈ且在走到之后调整光度Q方向,加速度{信息ؓ新的PDU包中所描叙的?q种Ҏ呢,非常的土Q会让物体在画面上移动v来变得非常的不现实,l常会出现很生硬的拐角,而且对于l常要修改的速度_SQ在玩家A的画面上Q玩家B的行动会变得非常的诡异。其好处是:比第一U方法要好?W三U方法,叫二ơ方E行赎ͼQuadraticQ,该方法的原理呢,是在直U行走的q程中,加入二次方程来计一条曲U\径,让Dest( _TargetB – OriginB )的过E是一条曲U,而不是一条直U,恩,具体的实现方法,是在LinearҎ的计中Q设定一个二ơ方E,在Dest函数计算距离的时候根据设定的 二次方程来计,q样一来,可以使B在玩家A屏幕上的Ud变得比较的有人性化一些。但是该Ҏ的考虑也是不周全的Q仅仅只考虑了TargetB?_TargetB的方向,而没有考虑新的PDU包中的方向描叙,那么从_TargetB开始模拟行走的时候,仍然是会出现比较生硬的拐角,那么下面提出?最l解x案,彻底解册个问题?

最后一U方法叫Q立方体抖动QCubic SplinesQ,q个东东比较复杂Q它需要四个坐标信息作为它的参数来q行q算Q第一个参数Pos1是OriginBQ第二个参数Pos2?OriginB在模拟运行一U以后的位置Q第三个参数Pos3是到达_TargetB前一U的位置Q第四个参数pos4是_TargetB的位|?Struct pos { Coordinate X; Coordinate Y; } Pos1 = OriginB Pos2 = OriginB + V Pos3 = _TargetB – V Pos4 = _TargetB q动轨迹?x, y)的坐标?x = At^3 + Bt^2 + Ct + D y = Et^3 + Ft^2 + Gt + H Q其中时间t的取D围ؓ0-1Q在Pos1的时候ؓ0Q在Pos4的时候ؓ1Q?x(0-3)代表Pos1-Pos4中x的|y(0-3)代表Pos1-Pos4中y的?A = x3 – 3 * x2 +3 * x1 – x0 B = 3 * x2 – 6 * x1 + 3 * x0 C = 3 * x1 – 3 * x0 D = x0 E = y3 – 3 * y2 +3 * y1 – y0 F = 3 * y2 – 6 * y1 + 3 * y0 G = 3 * y1 – 3 * y0 H = y0 上面是公式,那么下面我们来看看如何获得Pos1-Pos4Q首先,Pos1?Pos2的取g比较Ҏ获得Q根据OriginB配合当前的速度和方向可以获得,然而Pos3和Pos4呢,怎么获得呢?如果在从Pos1到Pos4?q程中有新的PDU到达Q那么我们定义它为NewPackage?Pos3 = NewPackage.X + NewPackage.Y * t + 1/2 * NewPackage.a * t^2 Pos4 = Pos3 – (NewPackage.V + NewPackage.a * t) 如果没有NewPackage的情况下,则Pos3和Pos4按照开始所规定的方法获得?/p>


本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/wolfcoder/archive/2009/02/16/3897672.aspx



2010-01-10 01:22 发表评论
]]>
一U经典的服务器架构(和我的体会太接近了,不得不{Q?/title><link>http://www.shnenglu.com/jack-wang/archive/2010/01/10/105310.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Sat, 09 Jan 2010 17:07:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2010/01/10/105310.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/105310.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2010/01/10/105310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/105310.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/105310.html</trackback:ping><description><![CDATA[<a id=viewpost1_TitleUrl href="http://www.shnenglu.com/johndragon/archive/2008/04/10/46768.html"><font color=#000080>一U经典的|络游戏服务器架?/font></a> <br><a href="http://www.shnenglu.com/johndragon/archive/2009/06/19/46768.html">http://www.shnenglu.com/johndragon/archive/2009/06/19/46768.html</a><br><br>首先Q二话不_上图Q用Windowsdȝ。。。)<br><br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/johndragon/servergraph.jpg" width=988 height=768><br>q个图是一个区的架构图Q所有区的架构是一L。上面虚U框的ServerGroup和旁Ҏ框内的架构一栗图上的所有x N的服务器Q都是多CL。红U,l线Q和蓝线图上也有囄Q这里就不多介绍了。关于Agent Server大家也能看出来,其实是Gate?br>q里主要介绍下图上的标记了号码的位置的数据连接的内容和意义?br><br>1-   q是一条WebService的管道,在用hz该区帐P或者修改帐号密码的时候,通过q条通道来插入和更新用户的帐号信息?br>2-   q也是一条WebService道Q用来获取和控制用户该该l内的角色信息,以及q行付费商城代币之类的更新操作?br>3-   q是一条本地的TCP/IPq接Q这条连接主要用来进行服务器l在登陆服务器的注册Q以及登陆服务器验证帐户后,向用h务器注册帐户登陆信息Q以及进行对已经登陆的帐戯色信息进行操作(比如t掉当前登陆的角ԌQ还有服务器l的信息更新Q当前在U玩家数量等Q?br>4-   q也是一条本地TCP/IPq接Q这条连接用来对q接到GameServer的客Lq行验证Q以及获取角色数据信息,q有传回GameServer上角色的数据信息改变?br>5-   q条q接也是一条本地的TCP/IPq接Q它用来q行公共信息服务器和C游戏服务器间的交互,用来交换一些游戏世界的信息(比如公会信息Q跨服组队信息,跨服聊天频道{)?br>6-   q里的两条连接,惌辄意思是QUserServer和GameServer的Agent是可以互换用的Q也是玩家q入l内之后Q就不需要再切换Agent。如果不怕ؕ套,也可以把登陆服务器的Agent也算上,q样用户整个q程里就不需要再更换AgentQ减重复连接的ơ数Q也提高了稳定性。(毕竟q接ơ数了Q也降低了连不上服务器的出现几率Q?br><br>在这个架构里面,GameServer实际上是一个游戏逻辑的综合体Q里面可以再L展成几个不同的逻辑服务器,通过PublicServerq行公共数据交换?br>UserServer实际上扮演了一个ServerGroup的领头羊的角Ԍ它负责向LoginServer注册和更新服务器l的信息Q名字,当前人数Q,q且对Agentq行调度Q对选择了该l的玩家提供一个用户量最的Agent。同Ӟ它也g一个角色管理服务器的功能,发送给客户端当前的角色列表Q角色的创徏Q删除,选择{管理操作,都是在这里进行的。而且Q它q是一个用户信息的验证服务器,GameServer需要通过它来q行客户端的合法性验证,以及获取玩家选择的角色数据信息?br><br><br>采用q种架构的游戏,通常有以下表现?br>1- 用户必须ȀzM个大区,才能在大区内登陆自己的帐受?br>2- 用户启动客户端的时候,弹出一个登陆器Q选择大区?br>3- 用户启动真正的客L的时候,一开始就是输入帐号密码?br>4- 帐号验证完成之后Q进行区内的服务器选择?br>5- 服务器选择完成之后Q进入角色管理。同Ӟ角色在不同的服务器里不能׃n?br><br>市面上符合上面几个表现特征的游戏相当的多Q而且也不乏旷世巨作。这个架构不是一个新的架构,但是它够经典和完善Qƈ且逻辑单而清晎ͼ用来做MMORPGQ或者其它网l游戏的服务器架构,是一U不错的选择?br> <img src ="http://www.shnenglu.com/jack-wang/aggbug/105310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2010-01-10 01:07 <a href="http://www.shnenglu.com/jack-wang/archive/2010/01/10/105310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从腾讯QQgame高性能服务器集架构看“分而治之”与“自沠Z等分布式架构设计原?/title><link>http://www.shnenglu.com/jack-wang/archive/2010/01/05/104793.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Mon, 04 Jan 2010 18:37:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2010/01/05/104793.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/104793.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2010/01/05/104793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/104793.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/104793.html</trackback:ping><description><![CDATA[<h1>从腾讯QQgame高性能服务器集架构看“分而治?#8221;?#8220;自治”{分布式架构设计原则</h1> <p style="FONT-SIZE: 10pt"><a >http://space.itpub.net/17007506/viewspace-616852</a></p> <p style="FONT-SIZE: 10pt"><a href="http://www.shnenglu.com/batch.common.php?action=viewspace&op=up&itemid=616852&uid=17007506">上一?/a> / <a href="http://www.shnenglu.com/batch.common.php?action=viewspace&op=next&itemid=616852&uid=17007506">下一?/a>  2009-10-19 13:54:17 / 个h分类Q?a href="http://www.shnenglu.com/17007506/spacelist-blog-itemtypeid-79388">服务器构?/a> </p> <div style="FONT-SIZE: 10pt"><a href="#xspace-tracks">查看( 1313 )</a> / <a href="#xspace-itemreply">评论( 9 )</a> / <a href="#xspace-itemform">评分( 20 / 10 )</a> </div> <div style="FONT-SIZE: 10pt" id=xspace-showmessage> <p style="FONT-SIZE: 10pt">  <a target=_blank>【上:从腾讯QQ升游戏?#8220;快速加入游?#8221;功能的实现缺LC/S之间如何正确分配相关协作?/a></p>     腾讯QQGame游戏同时在线的玩家数量极其庞大,Z方便l织玩家l队游戏Q腾讯设|了大量游戏室(戉KQ,玩家可以选择q入属意的房_q在此房间内扑ֈ可以加入的游戏组Q牌桌、棋盘等Q。玩安择q入某个戉KӞ必须保此房间当前h数未满(通常上限?00Q,否则q入步骤会p|。玩家在dQQGame后,会从<a title=服务? target=_blank>服务?/a>端获取某cL戏下所有房间的当前人数数据Q玩家可以据此找到未满的戉K以便q入? <p style="FONT-SIZE: 10pt">    如上所q的原因Q如果待q入戉K的h数接q上限时Q玩家的q入h可能p|Q这是因?a title=服务? target=_blank>服务?/a>在收到此q入h之前可能有若q其他玩家也hq入q个戉KQ造成戉K人数辑ֈ上限。这一问题是无法通过上篇所q调整协作分配的Ҏ来解决的Q这是因为:要进入的戉K是由玩家来指定的Q无法在服务器端完成此项工作Q游?a title=软g target=_blank><a onclick="javascript:tagshow(event, '%C8%ED%BC%FE');" href="javascript:;" target=_self>软g</a></a>必须服务器端所l护的所有房间h数数据复制到玩家的客LQƈ让玩家在界面上看到这些数据,以便q行选择。这P上篇所q的客户端与服务器端协作分配原则Q谁掌握数据Q谁q活Q,q得加上一些限制条Ӟq让位于另一个所?用户<a title=驱动 target=_blank>驱动</a>客户端行?原则--如果某个功能的执行是qh推动的,则这个功能的实现应当攑֜客户端(或者至由客户端来控制整个协作Q,q且客户端必L有此功能所依赖相关数据的副本,q个副本应当量与服务器端的源保持同步?/p> <p style="FONT-SIZE: 10pt"><a target=_blank><img border=0 src="http://space.itpub.net/attachments/2009/10/17007506_200910191415261.jpg"></a><br>  图一"q入戉K"p|C意</p> <p style="FONT-SIZE: 10pt">    注意Q点d片可以放大观?/p> <p style="FONT-SIZE: 10pt">    QQGameq存在一个明昄不Q就是:玩家如果在游戏一D|间后Q离开了某个房_q且惌入其它房_q时QQGameq不会刷新所有房间的当前人数Q造成玩家据此信息所选的待进入房间往往实际上h数已满,使得q入步骤p|。笔者碰到的最p情形是重复3?ơ以上,才最后成功进入另外某个房间。此~陷其实质是完全攑ּ了客L数据副本与服务器端的源保持同步的原则?/p> <p style="FONT-SIZE: 10pt">    实际上,QQGame的开发者有非常充分的理由来为此~陷的存在进行辩护:QQGame同时在线的用h过百万甚至千万数量U,如果所有客L要实Ӟ所谓实Ӟq家的体验容忍度而言Q可以定Z过1U的延迟Q地从服务器端获取更新数据,那么最l只有一个结?-pȝd崩溃。设想一下每U千万次h的吞吐量Q以普通服务器每秒上百个请求的处理能力Q这个数据是Ҏ服务h处理q程可能涉及到I/O操作来估值的Q纯<a title=内存 target=_blank>内存</a>处理的情形可能提高若q数量Q,需要成千上万台服务器组成集方能承受(高可用性挑战)Q而随着玩家不断地进入或退出游戏房_相关数据一直在快速变化中Q正向来看,假设有一C心服务器持有q些数据Q那么需要让成千上万台服务器与中心保持这些动态数据的实时同步Q数据一致性挑战)Q相对应的,逆向来看Q玩家进入房间等h被分配给不同的服务器来处理,一旦玩家进入房间成功则对应服务器内的相x据被改变Q那么假定中的中心服务器需要实时汇集所有工作服务器内发生的数据变动Q数据完整性挑战)。同时处理上万台服务器的数据同步Q这需要什么样的中心服务器呢?即有这L服务器存在,那么Internet|较大的Q而且不稳定的Q?a title=|络 target=_blank>|络</a>通讯延迟又怎么解决呢?</p> <p style="FONT-SIZE: 10pt">    对于软g~陷而言Q可以在不同的层面来加以解决--从设计、到需求、甚x直接在业务层面来解决Q例如,08q北京奥q会|上购票pȝQؓ了解册请求拥塞而至pȝ崩溃的缺P最后放弃了原先"先到先得"的购业务流E,改ؓQ用户先向系l发订票甌Q系l只是记录下来而不q行处理Q而到了空闲时Q在后台随机抽选幸q者,Z们一一完成订票业务Q。当然解x案所处的层面高Q可能就让Z满意。就上述q入戉K可能遭遇p|的缺陯言Q最便的解决Ҏ是Q在需求层面调整系l的操作方式Q即增加一个类g所q?自动快速加入游?的功?-"自动q入戉K"功能。系l在服务器端为玩家找C个h数较多又未满的房_q尝试进入(注意QY仉求是qL操作目标所驱动的,玩家在此的目标就是尽快加入一个满意的游戏l,因此ql来替代玩家选择目标戉K同样W合相关目标Q。而ؓ了方便玩家手工选择要进入的戉KQ则应当增加一?h当前各房间h?的功能。另外,q可以调整房间的l织模式Q例如以地域为单位来划分戉KQ像深圳Q长城宽带)区房?、四川(电信Q房?、北区戉K1{,在深圳上|的玩家被pȝ引导而优先进入深圛_的房间?/p> <p style="FONT-SIZE: 10pt">    不管怎样Q解册Y件缺L王道q是在设计层面。要解决上述~陷Q架构设计师必d旉寚w可用、数据一致性、完整性等斚w的严L战?/p> <p style="FONT-SIZE: 10pt">    在思考相兌x案时Q我们将应用若干与高性能服务器集架构设计相关的一些重要原则。首先是"分而治?原则Q即大量客L发出的服务请求进行适当的划分(例如Q所有从深圳长城宽带上网的玩家所发出的服务请求分Zl)Q分别分配给不同的服务器Q例如,前q服务请求分l分配给攄于深?a onclick="javascript:tagshow(event, '%CA%FD%BE%DD%D6%D0%D0%C4');" href="javascript:;" target=_self>数据中心</a>的服务器Q来加以处理。对于QQGame千万U的q发服务h数而言Q采用Scale Up向上扩展Q即升单个服务器处理能力的方式基本上不予考虑Q没有常规的L能处理每U上千万的请求)。唯一可行的,只有Scale Out向外扩展Q即利用大量服务器集做<a title=负蝲均衡 target=_blank>负蝲均衡</a>的方式,q实质上是"分而治?原则的具体应用?/p> <p style="FONT-SIZE: 10pt"><a target=_blank><img border=0 src="http://space.itpub.net/attachments/2009/10/17007506_200910191415571.jpg"></a></p> <div style="FONT-SIZE: 10pt" id=div6078909><br>    图二 分而治?下的QQGame游戏服务集群部v</div> <p style="FONT-SIZE: 10pt">    然而,要应?分而治?原则q行Scale Out向外扩展Q还依赖于其它的条g。如果各服务器在处理被分配的服务hӞ其行Z其它服务器的行ؓl果产生交叉Q@环)依赖Q换句话讲就是共享了某些数据Q例如,服务器A处理客户端a发来的进入房?nhQ而同Ӟ服务器B也在处理客户端b发来的进入房?nhQ此时服务器A与B的行为存在@环依?-因ؓ两者要同时讉K戉K#n的数据,q一׃n数据会造成两者间的@环依赖)Q则各服务器之间必须保q些׃n数据的一致完整性,否则可能发生逻辑错误Q例如,假定戉K#n的h数差一个就满了Q服务器A与B在独自处理的情况下,同时让客户端a与b的进入请求成功,于是戉K#n的最lh数将出上限Q。而要做到此点Q各服务器的处理q程之间必M持同步(实际上就是排队按先后序讉K׃n数据Q例如服务器A先处理,让客Laq入戉K成功Q此时房?n满员Q此后服务器B更新到房?n满的数据Q于是客Lb的进入请求处理结果失败)Q这P原来v量请求做负蝲均衡的意囑ְdp|了,多台服务器的q发处理能力在此与一台实质上q没有区别。由此,我们导出了另外一个所?处理自治"Q或U?行ؓ独立"Q的原则Q即所有参与负载均衡的服务器,其处理对应服务请求的行ؓ应当不@环依赖于其它服务器,换句话讲Q就是各服务器的行ؓ相对独立Q注意,在这里,非@环依赖是允许的,下文中我们来分析Z么)?/p> <p style="FONT-SIZE: 10pt">    由此可见Q简单的负蝲均衡{略对于QQGame而言是解决不了问题的。我们必LCU途径Q得在使用大量服务器进?分而治?的同Ӟ同时有确保各个服务器"处理自治"。此间的关键在?分而治???字上。前q将某个地域|段内上|的玩家所发出的服务请求分Cl,q分配给同一服务器的做法Q其目的不外乎是可能地减少|络通讯延迟带来的负面媄响。但它不能满?处理自治"的要求,Z保自治Q应当让同一台服务器所处理的请求本w是"自治"Q准的说法?自闭?ClosureQ的。同一台服务器所处理的所有请求组成一个服务请求集合,q个集合如果与其它Q何与其无交集的(hQ集合(包含此集合的爉合除外)不@环依赖,则此服务h集合?自闭?的,而处理此h集合的服务器Q其"行ؓ独立"。我们可以将针对同一戉K的进入请求划分到同一服务h分组Q这些请求相互之间当然是存在循环依赖的,但与其它分组中的h却不存在循环依赖Q本戉K内h数的变化不会影响到其它房_Q而将它们都分配给同一服务器(不妨命名?戉K<a onclick="javascript:tagshow(event, '%B9%DC%C0%ED');" href="javascript:;" target=_self>理</a>服务?Q简U?戉K服务?Q后Q那个服务器是"处理自治"的?/p> <p style="FONT-SIZE: 10pt"><a target=_blank><img border=0 src="http://space.itpub.net/attachments/2009/10/17007506_200910191416231.jpg"></a></p> <div style="FONT-SIZE: 10pt" id=div8703545><br>    图三 满"处理自治"条g的QQ游戏区域"戉K理"服务部v</div> <p style="FONT-SIZE: 10pt">    那么接下来要解决的问题,是玩家所x的某个游戏区内,所有房间当前h数数据的实时更新问题。其解决途径与上q的ҎcMQ我们还是将所有获取同一区内戉K数据的服务请求归Zl,q交l同一服务器处理。与上文所q场景不同的是,q个服务器需要实时汇集本区内所有房间服务器的房间h数数据。我们可以让每个戉K服务器一旦发生数据变更时Q就向此服务器(不妨命名?游戏区域理服务?Q简U?区服务器"Q推送一个变更数据记录,而推送的数据只需包含戉KId和所有进入的玩家IdQ房间服务器q包含其它细节数据,例如牌桌占位数据Q便可?/p> <p style="FONT-SIZE: 10pt">    另外Q由于一个区内的玩家数可能是上十万数量Q一个服务器Ҏ承担不了此种负荷Q那么怎么解决q一矛盾呢?如果深入分析Q我们会发现Q更新区内房间数据的h是一U数据只ȝhQ它不会Ҏ务器状态造成变更影响Q因此这些请求相互间不存在依赖关p;q样Q我们可以将它们再Q意划分ؓ更小的分l,而同时这些分l仍然保?自闭?Ҏ,然后分配l不同的区服务器。多台区服务器来负责同一区的数据更新hQ负载瓶颈被解决。当Ӟ此前Q还需这些区服务器分?C区服务器和nC属区服务器;d服务器负责汇集本区内所有房间服务器的房间h数数据,从属区服务器则从d服务器实时同步区戉K数据副本。更好的做法Q则是如『图五』所C,由房间服务器来充当从属区服务器的角色Q玩家进入某个房间后Q在玩家q入另外一个房间之前,其客L都将从此戉K对应的房间服务器来更新区内房间数据。要注意的是Q图中房间服务器的数据更新利用了所谓的"分布式对象缓存服??/p> <p style="FONT-SIZE: 10pt">    玩家q入某个戉K后,q要加入某个游戏l才能玩游戏。上所q的ҎQ是让第一个加入某个牌桌的用户Q其L自动充当本牌桌的游戏服务器;而其它玩家要加入此牌桌,其加入请求应当发往W一个加入的用户LQ此后开始游戏,其对弈过E将q一个加入用LL来主导执行?/p> <p style="FONT-SIZE: 10pt">    那么此途径是否同样也符合上q的前两个设计原则呢Q游戏在执行的过E中Q根据输赢结果,玩家要加分或减分Q同时还要记录胜负场数。这些数据必被持久化(比如?a onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target=_self>数据?/a>中保存下来)Q因此游戏服务器Q『图六』中的设计,是由4个部|于QQ客户端的"升"游戏前台逻辑执行服务Q加??升"游戏后台逻辑执行服务Q共同组成一个牌桌的"升"游戏服务Q在处理相关游戏执行hӞ依赖于玩家游戏账户数据服务Q『图六』中的所?QQGame会话服务"Q;不过q种依赖是非循环的,即玩家游戏̎h据服务器的行为反q来q不依赖于游戏服务器。上文中曾提刎ͼ"处理自治"原则中非循环依赖是允许的。这里游戏服务器在处理游戏收盘请求时Q要调用玩家游戏账户数据服务器来更新相关数据Q因Z同玩家的游戏账户数据是相互独立的Q此游戏服务器在调用游戏账户数据服务器时Q逻辑上不受其它游戏服务器调用游戏账户数据服务器的影响Q不存在同步{待问题Q所以,游戏服务器在此能够达成负载均衡的意图?/p> <p style="FONT-SIZE: 10pt"> </p> <div style="FONT-SIZE: 10pt" id=div2960811><a target=_blank><img border=0 src="http://space.itpub.net/attachments/2009/10/17007506_200910191417001.jpg"></a><br>    囑֛ 存在"非@环依?的QQ游戏客户端P2P服务与交互逻辑部v</div> <p style="FONT-SIZE: 10pt">    不过Q在上述场景中,虽然不存在同步依赖,但是性能依赖q是存在的,游戏账户数据服务器的处理性能不够Ӟ会造成游戏服务器长旉{待。ؓ此,我们可以应用分布式数据库表水q_割的技术,QQ玩家用户以其登记的行政区来加以分l,q|于对应区域的数据库中(例如Q深圳的玩家数据都在深圳的游戏̎h据库中)?/p> <p style="FONT-SIZE: 10pt"><a target=_blank><img border=0 src="http://space.itpub.net/attachments/2009/10/17007506_200910191417311.jpg"></a></p> <div style="FONT-SIZE: 10pt" id=div6663285><br>    图五 满"自闭?条g的QQ分布式数据库Q集)部v</div> <p style="FONT-SIZE: 10pt">    实际上,我们由此q可以推论出一个数据库表水q_割的原则--M数据库表水^分割的方式,必须保同一数据库实例中的数据记录是"自闭?的,即不同数据库实例中的数据记录怺间不存在循环依赖?/p> <p style="FONT-SIZE: 10pt">    MQ初步满QQGame之苛L能要求的分布式架构现在已经是初具雏形了Q但仍然有很多涉及性能斚w的细节问题有待解冟뀂例如,Internet|络通讯延迟的问题、服务器之间协作产生的性能瓉问题{等。笔者将在下中l箋深入探讨q些话题?br></p> </div> <img src ="http://www.shnenglu.com/jack-wang/aggbug/104793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2010-01-05 02:37 <a href="http://www.shnenglu.com/jack-wang/archive/2010/01/05/104793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>无缝世界|游服务器架构的设计思\Q{Q?/title><link>http://www.shnenglu.com/jack-wang/archive/2009/11/18/101271.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Wed, 18 Nov 2009 00:20:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2009/11/18/101271.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/101271.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2009/11/18/101271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/101271.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/101271.html</trackback:ping><description><![CDATA[<h2 class=entry-title>无缝世界|游服务器架构的设计思\</h2> <div id="aa8mgss" class=entry-content> <p>原文Q?a >http://canremember.com/?p=8</a><br><br>q去一q中Q花了很多时间在考虑服务器架构设计方面的问题。看了大量文章、也研究了不开源项目,眼界倒是开阔了不少Q不q回q头来看Q对|游架构设计斚w的帮助却是不多。老外q是玩儿console game的多QMMO Games斚w涉及的还是不如国内广泛。看?<a title=http://www.charlesriver.com/Books/BookDetail.aspx?productID=62407 onclick="javascript:pageTracker._trackPageview('/outgoing/www.charlesriver.com/Books/BookDetail.aspx?productID=62407');" target=_blank><u><font color=#0000ff>Massively Multiplayer Games Development</font></u></a> 1 & 2 q两本书吧,质量说实话很一般,帮助自然也很有限。当然这也是好事Q对国内的研发公?团队来说Q在|游服务器技术方面当然就存在越老外的可能性,而且在这斚w技术超的Z更大Q当然前提是要有U篏、要舍得投入Q研发h员更要耐得住寂寞、经得v诱惑Q在q_每天收到过3个猎头电话的时候——依然不动心?/p> <p>上面有点儿扯q了Q下面聊聊无~世界架构(Seamless world server architectureQ设计方面的一点儿看法?/p> <p>先说架构设计的目标——我的看法,服务器组架构设计的目标就是确定各服务器拓补关pd主要的业务逻辑处理Ҏ。主要要解决的问题就是在满游戏内容设计需要的前提下,如何提高带负载能力的问题?br><span id=more-8></span><br>最单的架构是基本的C/S架构Q一台Server直接构成一个ClusterQ所有Client直接q接q个ServerQ这个Server完成所有逻辑和数据处理。这架构其实很好Q最大的好处是它架构上?Simplicity QCluster内部的跨q程交互完全被排除,复杂度立d降下来了Q而且——完全可以实C个无~(Seamless worldQ的游戏世界。但是即使我不说Q大家也知道q种单Server架构会有什么问题。不q我们不妨以另外一个角度来看这个Server——一个黑盒子。从pȝ外部的角度来看,什么样的系l都可以看成一个整体、一个黑盒,而不系l内部的拓补关系和实现复杂度斚w的问题。在不考虑q个pȝ的实现的前提下,理论上Cluster的处理能力就是由g的数量和能力军_的,也就是说一个Server Cluster内包含越多的服务器、服务器?#8216;?#8217;Q那么这个Cluster的处理能力越好、带负蝲能力好。那么我们要面对的带负蝲能力的问题,是如何高效的利用这些Server的问题,基本上也可以理解?strong>如何提高玩家h的ƈ发处理能?/strong>的问题?/p> <p>CPU厂商在很久以前就在考虑q方面的问题了,CPU其实也可以看成个黑盒。看看他们用q的技术—?a title=http://en.wikipedia.org/wiki/Pipeline_(computer) target=_blank><u><font color=#0000ff>水U(pipelineQ?/font></u></a>技术?a title=http://en.wikipedia.org/wiki/Multi-core_(computing) target=_blank><u><font color=#0000ff>多CPU/多核QmulticoreQ?/font></u></a>技术,以及q些技术的衍生技术。我想了很久?Server Cluster 内部处理q行的方法、ƈ且有了比较清晰的思\之后Q才发现其实早就可以参照CPU厂商的方法。流水线的方法就是把一个指令处理拆分成很多个步骤,q样指o的处理被分解之后可以部分重叠(相当于变成ƈ发的了)执行。我们的Server Cluster一样可以用q种Ҏ来拆分,我想了个名字—?/p> <p><strong>Services-based Architecture</strong>——基于服务的架构。在q种架构内部Q我们根据处理数据、逻辑的相x来划分l内各个服务器的工作d。例如:位置服务提供物体可见性信息、物品服务处理所有物品相关的逻辑、社会关pL务提供行会家族等{方面的逻辑、战斗服务器只处理战斗相关的逻辑Q等{。这样划分的话、逻辑处理的ƈ发就有了可能性。D例来_A砍B一刀qg事情与C从奸商手里买C件武器这个事情是完全不相q的Q而且q?个请求本来就在不同的服务器上被处理,他们是被不同的Service Serverq发处理的。这是 Services-based Architecture 的ƈ发方法?/p> <p>基本上,把游戏逻辑的处理拆分成一个个的serviceQ就和设计cpu的时候把机器指o的具体处理拆分,然后设计Z个个水U单元是一个道理?/p> <p><strong>Cells-based Architecture</strong>——基于cell的架构。每个cell都在不同的物理server上面q行着完全一L应用E序服务器,但是他们负责承蝲不同的游戏场景区域的游戏逻辑。和 services-based arch. 明显不同的就是,每个cell都是?#8216;在逻辑上完整的’服务器。它得处理物品操作、h物移动、战斗计等{几乎所有的游戏逻辑。尽这么做会带来一些(可能是很复杂Q的问题Q但是它完全是可行的。D例来_在吴国A砍B一刀昄地和千里之外在越国的C砍D一刀不搭界,他们完全可以被不同的Cellq发地处理?/p> <p>基本上,q就相当于一个主板上面插多个CPU或者一个CPU但是有多个内核,每个CPU能做的事情都是一LQ而且能一起做?/p> <p>关于q两U?seamless world 架构的基本分析和需要解决的一些主要问题,下次再写?/p> <h4>Related posts</h4> <ul class=st-related-posts> <li><a title="技术主义者的|游观点 (2008.03?23)" ><u><font color=#0000ff>技术主义者的|游观点</font></u></a> (11)</li> <li><a title="无缝世界|游服务器架构的设计思\Q箋Q?(2008.02?15)" ><u><font color=#0000ff>无缝世界|游服务器架构的设计思\Q箋Q?/font></u></a> (3)</li> <li><a title="服务器组架构设计需要考虑的一些关键因?(2008.02?5)" ><u><font color=#0000ff>服务器组架构设计需要考虑的一些关键因?/font></u></a> (6)</li> <li><a title="关于?(2008.02?3)" ><u><font color=#0000ff>关于?/font></u></a> (0)</li> <li><a title="Trap of C++ (2008.02?18)" ><u><font color=#0000ff>Trap of C++</font></u></a> (0)</li> </ul> </div> <img src ="http://www.shnenglu.com/jack-wang/aggbug/101271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2009-11-18 08:20 <a href="http://www.shnenglu.com/jack-wang/archive/2009/11/18/101271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>|游服务器架构的设计http://www.shnenglu.com/jack-wang/archive/2009/06/18/88027.htmlThu, 18 Jun 2009 12:47:00 GMThttp://www.shnenglu.com/jack-wang/archive/2009/06/18/88027.htmlhttp://www.shnenglu.com/jack-wang/comments/88027.htmlhttp://www.shnenglu.com/jack-wang/archive/2009/06/18/88027.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/88027.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/88027.html1?常见的网游服务通信器架构概q?br>2?|游服务器设计的基本原则
3?|游服务器通信架构设计所需的基本技?br>4?|游服务器通信架构的测?br>5?|游服务器通信架构设计的常见问?br>
下面我们׃W一个问题说P

常见的网游服务器通信架构概述
  目前Q国内的|游市场中大体存在两U类型的|游游戏QMMORPGQ如Q魔兽世界)和休闲网游(如:QQ休闲游戏和联众游戏,而如泡堂一cȝ游戏与QQ休闲游戏有很多相同点Q因此也归ؓ此类Q。由于二者在游戏风格上的截然不同Q导致了他们在通信架构设计思\上的较大差别。下面笔者将分别描述q两U网游的通信架构?br>
1QMMORPGcȝ游的通信架构
  |游的通信架构Q通常是根据几个方面来定的:游戏的功能组成、游戏的预计上线人数以及游戏的可扩展性?br>  目前比较通用的MMORPG游戏程是这LQ?br>
a. 玩家到游戏官方网站注册用户名和密码?br>b. 注册完成后,玩家选择在某一个区ȀzL戏̎受?br>c. 玩家在游戏客L中登录进入已l被Ȁzȝ游戏分区Q徏立游戏角色进行游戏?br>
  通常Q在q样的模式下Q玩家的角色数据是不能跨Z用的Q即Q在A区徏立的游戏角色在B区是无法使用的,各区之间的数据保持各自独立性。我们将q样独立的A区或B区称Z个独立的服务器组Q一个独立的服务器组是一个相对完整的游戏世界。而网游服务器的通信架构设计Q则包括了基于服务器l之上的整个游戏世界的通信架构Q以及在一个服务器l之内的服务器通信架构?br>
  我们先来看看单独的服务器l内部的通信是如何设计的?br>  一个服务器l内的各服务器组成,要依据游戏功能进行划分。不同的游戏内容{划会对服务器的l成造成不同的媄响。一般地Q我们可以将一个组内的服务器简单地分成两类Q场景相关的Q如Q行走、战斗等Q以及场景不相关的(如:公会聊天、不受区域限制的贸易{)。ؓ了保证游戏的畅性,可以这两类不同的功能分别交׃同的服务器去各自完成。另外,对于那些在服务器q行中进行的比较耗时的计,一般也会将其单独提炼出来,交由单独的线E或单独的进E去完成?br>
  各个|游目会根据游戏特点的不同Q而灵z选择自己的服务器l成Ҏ。经常可以见到的一U方案是Q场景服务器、非场景服务器、服务器理器、AI服务器以及数据库代理服务器?br>  以上各服务器的主要功能是Q?br>
  场景服务器:它负责完成主要的游戏逻辑Q这些逻辑包括Q角色在游戏场景中的q入与退出、角色的行走与跑动、角色战斗(包括打怪)、Q务的认领{。场景服务器设计的好坏是整个游戏世界服务器性能差异的主要体玎ͼ它的设计隑ֺ不仅仅在于通信模型斚wQ更主要的是整个服务器的体系架构和同步机制的设计?br>
  非场景服务器Q它主要负责完成与游戏场景不相关的游戏逻辑Q这些逻辑不依靠游戏的地图pȝ也能正常q行Q比如公会聊天或世界聊天Q之所以把它从场景服务器中独立出来Q是Z节省场景服务器的CPU和带宽资源,让场景服务器能够可能快地处理那些对游戏畅性媄响较大的游戏逻辑?br>
  服务器管理器Qؓ了实C多的场景服务器之间以及场景服务器与非场景服务器之间的数据同步Q我们必d立一个统一的管理者,q个理者就是服务器l中的服务器理器。它的Q务主要是在各服务器之间作数据同步Q比如玩家上下线信息的同步。其最主要的功能还是完成场景切换时的数据同步。当玩家需要从一个场景A切换到另一个场景BӞ服务器管理器负责玩家的数据从场景A转移到场景BQƈ通过协议通知q两个场景数据同步的开始与l束。所以,Z实现q些内容J杂的数据同步Q务,服务器管理器通常会与所有的场景服务器和非场景服务器保持socketq接?br>
  AIQh工智能)服务器:׃怪物的h工智能计非常消耗系l资源,所以我们把它独立成单独的服务器。AI服务器的主要作用是负责计怪物的AIQƈ计结果返回给场景服务器,也就是说QAI服务器是单独为场景服务器服务的,它完成从场景服务器交q来的计Q务,q将计算l果q回l场景服务器。所以,从网l通信斚w来说QAI服务器只与众多场景服务器保持socketq接?br>
  数据库代理服务器Q在|游的数据库d斚wQ通常有两U作法,一U是在应用服务器中直接加q数据库讉K的代码进行数据库讉KQ还有一U方式是数据库d独立出来Q单独作成数据库代理Q由它统一q行数据库访问ƈq回讉Kl果?br>
  其中Q非场景服务器在不同的游戏项目中可能会被设计成不同的功能Q比如以l队、公会或全频道聊天ؓ特色的游戏,很可能ؓ了满玩家的聊天需求而设立单独的聊天服务器;而如果是以物品N易(如拍卖等Qؓ特色的游戏,很可能ؓ了满x卖的需求而单独设立拍卖服务器。到底是不是有必要将某一Ҏ戏功能独立处理成一个服务器Q要视该功能Ҏ戏的d景逻辑Q指行走、战斗等玩家日常游戏行ؓQ的影响E度而定。如果该功能对主场景逻辑的媄响比较大Q可能对d景逻辑的运行造成比较严重的性能和效率损失,那么应考虑其从主场景逻辑中剥,但能否剥还有另一个前提:此功能是否与游戏场景Q即地图坐标pȝQ相兟뀂如果此功能与场景相兛_实影响Cd景逻辑的执行效率,则可能需要在场景服务器上讄专门的线E来处理而不是将它独立成一个单独的服务器?br>
  以上是一个服务器l内的各服务器组成情况介l,那么Q各服务器之间是如何通信的呢Q它的基本通信构架有哪些呢Q?br>  MMORPG的单l服务器架构通常可以分ؓ两种Q第一U是带网关的服务器架构;W二U是不带|关的服务器架构。两U方案各有利弊?br>
  带|关的服务器架构而言Q由于它对外只向玩家提供唯一的一个通信端口Q所以在玩家一侧会有比较流畅的游戏体验Q这通常也是那些大规模无缝地图|游所采用的方案,但这U方案的~点是服务器l内的通信架构设计相对复杂、调试不方便、网关的通信压力q大、对|关的通信模型设计要求较高{。第二种Ҏ会同时向玩家开攑֤个游戏服务器端口Q除了游戏场景服务器的通信端口外,同时q可能提供诸如聊天服务器{的通信端口。这U方案的主要~点是在q行场景服务器的切换Ӟ玩家客户端的表现中通常会有一个诸如场景调入的界面出现Q媄响了游戏的流畅感。基于这U方案的游戏在客L的界面处理方面,比较典型的表现是Q当要进行场景切换时Q只能通过相应?#8220;传送功?#8221;传送到另外的场景去Q或者需要进入新的场景时Q客L会有比较长时间的{待q入新场景的{待界面(Loading界面)?br>
  从技术角度而言Q笔者更們֐于将独立的服务器l设计成带网关的模型Q虽然这加大了服务器的设计难度,但却增强了游戏的畅感和安全性,q种pq是值得的?br>  W者在下面附上了带|关的MMORPG通信架构图,希望能给业内的朋友们一Ҏ益的启_?

2009-06-18 20:47 发表评论
]]>
目前我们的游戏服务器逻辑层设计草案(转帖于:云风的BLOG)http://www.shnenglu.com/jack-wang/archive/2009/02/12/73515.htmlWed, 11 Feb 2009 18:50:00 GMThttp://www.shnenglu.com/jack-wang/archive/2009/02/12/73515.htmlhttp://www.shnenglu.com/jack-wang/comments/73515.htmlhttp://www.shnenglu.com/jack-wang/archive/2009/02/12/73515.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/73515.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/73515.html

我们一开始的游戏逻辑层是Z|络包驱动的Q也是?client 消息定义好结构打包发送出去,然后?server 解析q些数据包,做相应的处理?/p>

写了一D|间后Q觉得这U方案杂׃利于复杂的项目。跟同事商量以后Q改成了非阻塞的 RPC 模式?/p>

首先由处理逻辑?server 调用 client 的远E方法在 client 创徏出只用于昄表现的媄子对象;然后 server 寚w辑对象的需要client 做出相应表现的操作,变成调用 client 端媄子对象的q程Ҏ来实现?/p>

q得游戏逻辑~写变的清晰了很多,基本可以无视|络层的存在Q和单机游戏的编写一L单?/p>

本质上,q样一个系l跟|络包驱动的方式没有区别Q但是从~码表现形式上要自然很多。正?C 语言也可以实现面向对象,但却没有 C++ 实现的自然一栗在q个pȝ中,引擎装了对象管理的部分Q得逻辑~写的时候不再需要处理讨厌的对象数字 id Q还隐藏了消息发送或q播的问题?/p>

我把玩家控制的角Ԍ和服务器上你的角色分做两个东ѝ即Q你控制的你Q和服务器认为的你就分开了。服务器认ؓ的你Q你看见的服务器上的其他人是一cMѝ操作自q角色行动Ӟ你通过 client 上的控制器的q程Ҏ向服务器发送指令;而服务器通过q程调用每个角色的远E方法让 client 可以收到感兴的所有角色的行ؓ?/p>

q样Qclient 永远都是通过一个控制器调用其远E方法来告诉服务?我要q什?Q而服务器的逻辑层则通过调用其上所有逻辑对象的远E方法来改变每个对象的状态。而引擎就Ҏ每个链接的需要,q播q些消息Q得每?client 上对应的影子对象可以收到状态改变的消息?/p>

q些Q就是半个月来我跟同事一起做的工作。当Ӟ׃我们用脚本编写逻辑层,q样Q脚本接口可以比 C 接口实现的漂亮的多?/p>

首先是自定义格式的接口描q文Ӟ用自~写的工兯动编译成对应脚本代码。我们只需要在脚本中编写对应的c,可以自动响应远端调用的Ҏ了。而调用远E方法,也跟本地Ҏ保持同样的Ş式,写v来跟本地函数调用没有区别。这在以前用 C/C++ ~写逻辑的时候是很难做到的?/p>

其次Q引擎内部做好对象的理工作Q负责把通讯协议上的 id 转换成逻辑层中的对象传递给逻辑层用?/p>

再次Qenum q样的类型再也不需要用一些数字的常数了,也不需要在脚本额外的定义出来。可以在接口文g中定义好Q经q引擎的处理后,逻辑层可以直接用更ؓ友好的字W串代替Q而不失去效率?/p>

~写逻辑的程序员不再需要关心网l的问题后,可以把心思放在细节上?/p>

最后,对于实现行ؓ预测来补偿网lgq的Ҏ上。在先前的版本中Q我们ؓ了实现这个,׃不少的气力。主要是时间戳信息攑֜基础通讯协议中来辅助实现。具体的消息包收到后Q再计算延迟旉来推当前的状态。现在,可以把时间信息封装到 RPC 中,让每个远E方法自动带有gq时_方便计算。按模拟E序的实际效果上看,单单位置同步的预策略,可以让gq在 8 U之内的玩家可以忍受Q而gq小?1 U的时候,几乎不会受到滞后的媄响了?/p>

关于每个链接感兴的信息的问题,军_了每个逻辑对象的状态改变要通知哪些人。目前的x是独立到单独q程d理,我们在处理连接的服务器和处理逻辑的服务器之间讄单独的服务器来管理每个链接感兴趣的对象,q个d相对单一且责任重大,独立出来可以大大减轻逻辑服务器的复杂度?/p>



2009-02-12 02:50 发表评论
]]>
高性能的网l游戏服务器的设计。。。作者谈了QQGAME SERVER。。?Q{Q?/title><link>http://www.shnenglu.com/jack-wang/archive/2009/02/12/73514.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Wed, 11 Feb 2009 18:41:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2009/02/12/73514.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/73514.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2009/02/12/73514.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/73514.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/73514.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 10pt">高性能的网l游戏服务器的设计[转]<br minmax_bound="true">2007q?0?5?星期?18:08<br minmax_bound="true">    说v高性能的网l游戏,?个典范,1个是暴雪的WOWQ另外一个要数腾讯的QQGame了,因ؓ对于MMPRPG的体pL触不深,几乎属于文盲Q没有太多的发言权,而自己又是搞休闲游戏开发的所以本文就主要谈谈QQGame了?<br minmax_bound="true"><br minmax_bound="true">    前些天通过朋友得到了QQGame的一个系l分析的文档Q看完后很是震惊Q彻底被QQ的设计所折服了,到底是千万h在线pȝl验的拥有者,牛! <br minmax_bound="true"><br minmax_bound="true">    通过资料了解到QQGame目前有以下让我欣赏的Ҏ: <br minmax_bound="true"><br minmax_bound="true">1.单机最高容U?5,000人同时在U,Ҏ有看错是q么多,׃它适用了Linux下高性能的网l处理模型ePoll技术,q且一pd高超的优化技术轻杄万hQ当然ؓ了稳定性考虑单机保持?万h的容量,此时的带宽消耗ؓq?0MQ?<br minmax_bound="true">2.采用׃n内存方式高速完成进E间高速通讯Q?<br minmax_bound="true">3.服务器的扩充方式不是q面的方式,而是裂变式的扩充方式QŞ成负载均衡阵列树状结构; <br minmax_bound="true">4.所有的游戏服务器不是直接和数据库联p,而是和数据proxy(qq叫数据交换机和路由?q行联系Q由此带来的是游戏用户数据的分布存储,我分析着应该是proxy上记录着q个用户数据所在的实际的dbserver的信息,然后定时的将最新的用户信息写回到db中去Q这样就大大~解了数据库服务器的压力Q而且可以非常qx的将数据分裂开来,数据库服务器也就可以无限的扩充,当然我觉得肯定有个数据库信息索引了用Lid和对应的存储地点的关联关p,q点qggoogle的原理了Q所以对于数据库的硬件要求也׃是那么高了,qqgame的一l服务器通常?台服务器Q可以容U?万hQ其中就包含了数据库服务器,q点׃是棋牌游戏所怋用的数据集中存储了; <br minmax_bound="true">5.游戏服务器的|络和逻辑分开Q不仅仅是层ơ上的分开Q而是在进E上分开Q然后中间通过׃n通道q行理和协调,q且增加了辅助线E,在主U程处理大压力的异步的操作的时候直接交l辅助线E处理,保障了游戏服务器的高效性运转?<br minmax_bound="true">    作ؓ游戏服务器的l构斚w(以下只讨Z闲游戏部?MMORPG服务器不属于讨论范围)的设计已l相对于成熟q且l一,l构斚w?q前我所接触的中游系的那套^台没有太大的差异,无非是服务器采用星状的l构,?个中心节点作为核?然后向四周扩散出一些应用服务器,如负责登陆的LoginServer,负责具体游戏逻辑的GameServer{等,当然最_的结构是q样?q样的结构可以满?0万以下同时在U的定w,如果Z满更大的容?如QQGAMEq样的目前已l有200万以上同时在U的大定w的应用则需要额外的优化,从这个结构中分离Z些子应用独立开发出一些服务器端来处理,一斚w降低偶合?另外一斚w作ؓ高可用性系lؓ负蝲均衡提供条g. <br minmax_bound="true"><br minmax_bound="true">关于负蝲均衡,作ؓ整个游戏q_的所有服务器.我觉得除了具体的游戏逻辑服务器以外都是可以采用负载均?多点分担的方式来处理,惟独逻辑服务器不可以,因ؓ休闲游戏,都是分层ơ的,不管泡堂也?QQGAME也好q些游戏其实在客L的表现Ş式都是分层次?如QQGAME是LOBBY-HALL-ROOMq样的结?LOBBYq层是游戏q场?可以看到所有的游戏cd,游戏服务器和具体的游戏大?比如:牌类–斗地?#8211;新手?#8211;新手? q样的顺?传统的设计中新手?是属于一个独立的游戏逻辑服务器拥有一个独立的IP以及侦听端口,在服务器端通常也是一个独立的q程.一般的游戏服务器允许的q接数通常都是300-600Z间超q的提C服务器已满了,q样做的原因q不是因E的限制因ؓ一个进E完全可以做到同时让3000以上的玩家同时游戏,而是Zؓ设计的考虑Q因为在游戏逻辑服务器中有很多需要广播的消息Q如游戏玩家的聊天信息,某个戉K的开始信息,l束信息Q某出的信息{,而对于广播来_l?00个hq播和给3000个hq播所消耗的资源是绝Ҏ有可比性的。但是通过从进E上独立来处理这个传l的方式也有个缺P比如通过开10个进E来辑ֈ3000人和1个进E达?000人,如果不考虑q播的因素在内的话前者的资源是要高与后者的资源的,q且q程间的通讯也要比进E内的通讯要耗费资源和复杂度斚w要高很多Q比如说如果要实C个需求让玩家可以在同一cL戏中可以使用喇叭类或者跨游戏服务器找Zcȝ功能的话Q同一个进E的优势显C出来了Qؓ此QQGAME所使用的是Channel(频道)的概念,即一个游戏逻辑服务器的q程可以容纳5000人左叻I然后服务器端通过讄分割出很多的Channel如新?Q新?Q新?之类的传l意义上的游戏大厅,消息的分发范围q行隔离Q节U了资源。这一点可以通过查看q接属性看刎ͼq接QQGAME的同cd靠近的几个游戏大厅其实端口和IP都是一致的?<br minmax_bound="true"><br minmax_bound="true">我们目前的游戏服务器cd主要?c:CenterServerQ管理着所有的服务器连接,LoginServer 负责处理用户的登陆、注册,q且用来l用户传递游戏逻辑服务器列表等功能Q?GameServer具体逻辑服务器,Ҏ不同的逻辑来实C同的游戏需求?<br minmax_bound="true"><br minmax_bound="true">当然Q根据业务的发展需要,我们正准备把用户的状态在服务器端保存Qƈ且增加一个类似IM服务器的功能来满玩家跨服务器聊天和查询其他玩家状态的需要。以及GM服务器实现多功能的网室的需求,q些在以后慢慢写?<br minmax_bound="true"><br minmax_bound="true">今天开始写些技术的题材,一斚w记录一些自q本分工作的东?另外一斚w也是充实一下BLOG,工作太忙也没有什么太多的思A来一直写其他的题?所以就拿工作来填充?同时如果有h有幸看到了这些文?q且也有兴趣的话也希望多多探? <br minmax_bound="true"><br minmax_bound="true">先简单介l一?׃本h的工作就是游戏开发公司的,一直与游戏开发打交道,主要做休闲类的游?目前又以牌游戏Z,在这个行业中摸爬滚打了整3q了,从运营开始做?q营q当时国内一的游戏q_中游pd的?然后׃合作斚w的原因又自主开发过一套游戏^?然后׃发展方向上的分歧出来单独?目前在开发ƈq维一套全新的产品. <br minmax_bound="true"><br minmax_bound="true">q篇主要是对于游戏服务器的一些想?l合目前自n的品的一些问题g伸开来的. <br minmax_bound="true"><br minmax_bound="true">目前我们的服务器q是属于Windowsq_的架?暂时q没有考虑到跨q_,主要原因?:<br minmax_bound="true">1.成本:作ؓ公司来说首先得考虑的就是成本了,虽然说Linuxcȝq_存在着操作pȝ成本低廉,性能优异,E_性高q几个特?但是作ؓ全局考虑来说,一个Linux的系l管理员,以及开发h员的成本要比Windowsq_要高很多,q且作ؓ操作pȝ斚w是免费的,但是支持几乎是没有的只有一些不适合商业应用的开源社Z为支?要得到更加好的服务或者额外的支持q是得通过大厂商的高额的品或服务来实?而Windowsq_则不?虽然操作pȝ貌似h不扉,但是本n带了很多的模块,比如lg服务,日志服务{等,加上q_上各UY件的数量也和Linux下的不是同一量?可选择性要大的?而让Linuxer所诟病的Win32的安全性其实完全可以通过另外独立的安全模?如硬仉火墙{来完善,毕竟操作pȝ不是专门做安全防护的Linux也存在很多的漏洞,q且随着Linux发行版的日益增多,用户的逐渐了解,漏洞也日益的增多.<br minmax_bound="true">2.开发效?无疑Visual Studiopd开发套件是目前开发领域最方便最强大的IDE环境,q已是不争的事实,而如果用VI + GCC的模式去开发LINUX下面的服务器其效率和质量臛_从我目前的水q?可以部分代表国内目前中小游戏软g开发商实际现状)要彻底的领悟q{换需要一定的旉,q且q没有成熟的开发^CZ? JAVA好象?但是C++q没有听说有过VC++? </span><!-- google_ad_section_end --> <img src ="http://www.shnenglu.com/jack-wang/aggbug/73514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2009-02-12 02:41 <a href="http://www.shnenglu.com/jack-wang/archive/2009/02/12/73514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MMORPG开发入?/title><link>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72506.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Fri, 23 Jan 2009 05:36:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72506.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/72506.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72506.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/72506.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/72506.html</trackback:ping><description><![CDATA[<table class=t_table cellSpacing=0 width="98%" align=center> <tbody> <tr> <td width="80%"><font size=3>作者: Radu Privantu <br>译者:<a target=_blank><font color=#0000ff><u>pAnic</u></font></a> 2005q??1?br>原文链接Q?a target=_blank><font color=#0000ff><u>http://www.devmaster.net/articles/building-mmorpg/</u></font></a><br>译者序Q这是一讲解如何开发一ƾMMORPG的入门文章,作者本Z是一ƾ游戏的开发者,文中的内Ҏ于实践,有很高的参考h倹{很多h都想拥有自己的游戏,q篇文章寚w些想自己开发游戏的人来说可能是一U福韻I也可能是一盆冷水。无论如何,开发游戏都不是一件简单的事情?br>以下是翻译正文:<br></font></td> <td width="2%">[/td] <tr> <td>文章的中心是如何h开发你自己?大型多h在线角色扮演游戏( 原文QMassive Multiplayer Online Role Playing Games) (MMORPG)(译者注Q俗Uͼ|络游戏Q网??针对的读者是l验和资源有限的开发者?d文章之后Q你应该懂得如何hQ?q有一些关于什么是应该做的和不应该做的忠告。第一步是评估你的能力和资源。你必须对自p实,因ؓ做你力不从心的事情会费你的旉q让你心灰意冗?br><br>W一步:评估你的能力必须的技? <ul type=1> <li>懂至一U编E语a?q今为止Q?C++因ؓ性能和效率的优越性成为游戏开发者的首选?Visual Basic, Java 或?C# 可能也是不错的选择?br> <li>熟悉一U图形库。通常的选择是SDL, OpenGL, 或者DX/D3D?<font color=#ff0000>译者注Q网上也有很多免?付费引擎下蝲和出?/font>) <li>选择一U网l通讯库?你可以从WinSock, SDL_net, 或DirectPlay中选择?<font color=#ff0000>译者注Q很多h喜欢开发自q特的|络库,qƈ不复杂,gACE也是一U选择</font>)<br> <li>Ҏ戏开发有大体的经验?例如Q事件@环, 多线E, GUI 设计Q等{?/li> </ul> 强烈推荐的技? <ul type=1> <li>C/Sl构通讯? <li>多^台开发?你可能希望设计一个MMORPG, 其是服务器能运行在多种操作pȝ。ؓ此,我推荐用SDL, OpenGL 和SDL_net?br> <li>|站开发。如果你惌用户通过|站查看玩家l计Q服务器信息和其他信息,q是必须的?<font color=#ff0000>译者注Q其实网站可以交l其他h开发,如果有必要的?/font>)? <li>安全理?你当然不惛_为有人攻M的服务器而浪Ҏ_ <li>团队l织能力?你需要一个你能成功领导和理的团队?br></li> </ul> W二步:初步规划我注意到很多人在不同的论坛发帖子L团队开发MMORPG。他们中的大部分是这P“我们成立了一个公?游戏工作室,需?个美工,两个E序Q?个音乐制作,{等。ؓ了创斎ͼ不要参考过ȝMMORPGQ你有全部的自由用来创造你惌的世界,{等?我们会在目完成q赚到钱的时候付l你酬劳Q等{?#8221;?不幸的是Q以现有的技术和带宽Q你无法拥有一个动态的世界?朝向无法到达的目标前q只会导致失败。正的做法是拿Z些小规模的,功能性强的,可扩展的设计和构架?br>基本软g构架首先Q尝试创Z个简单的C/S模型Q有如下功能Q?br> <ul type=1> <li>创徏一个新角色 <li>保存那个角色(服务器端) <li>用那个角色登? <li>能够和其他h交谈 <li>能在3DI间游览</li> </ul> 保存角色看v来简单,其实不然?例如Q有两种方式保存角色Q用数据库服务或者用文件。两者有各自的优~点Q?<br><br> <table class=t_table cellSpacing=0 width="98%" align=center> <tbody> <tr> <td width="10%"></td> <td width="45%"><strong>数据?/strong></td> <td width="45%"><strong>文g</strong></td> </tr> <tr> <td><strong>优点</strong></td> <td> <ul> <li>d新域或者修改现有的都很单? <li>更新玩家l计数据非常?从游戏外)? <li>你可以通过SQL查询方便的获取不同种cȝl计l果? <li>无需自行完成I/O操作Q数据库会替你做好?<br> <li>易于更新/恢复?/li> </ul> </td> <td> <ul> <li>高速操???? <li>实现单? <li>无需额外的库? <li>不依赖数据库服务器。因此你不必担心数据库升U或安全问题?<br></li> </ul> </td> </tr> <tr> <td><strong>~点</strong></td> <td> <ul> <li>Ҏ出错?例如Q做一个更新查询的时候遗漏了'where'子句。会D惨痛的损失,其是你没有备䆾的时候? <li>数据库会比打开/写入一个玩家档案文件慢。你查询一些数据的时候会耗费几个毫秒Q尤其是大量玩家同时d/d的时候? <li>需要额外的代码q行游戏和数据库间的数据转换? <li>需要操作数据库和SQL的经验。ƈ且需要一个程序和数据库之间的接口库? <li>如果因ؓ某些原因数据库文件损坏,那算你倒霉Q你可能会丢失所有的玩家数据(其是短期内没有备䆾的时??/li> </ul> </td> <td> <ul> <li>很难d新的域,除非一开始就很小心的设计了文件的格式/l构? <li>没法做全体玩家的查询?q可以通过每天晚上用程序把重要字段dq一个数据库间接实现)? <li>如果你想更新/查玩家状态,你必额外写代码?<br> <li>更新和还原比较复杂?/li> </ul> </td> </tr> </tbody> </table> 现在你决定了如何存储角色Q你q得选择C/S通讯的网l协议:TCP q是 UDPQ?我们都知道TCP速度慢,但是更准,q且需要额外带宽。我实际使用TCPq没有遇C么问题?如果你有充的带宽,TCP是个好选择Q至对初学者是q样?nbsp; UDP 会很ȝQ尤其是Ҏ手?CQ游戏或引擎的初步测试会在你的局域网q行Q所有的包都会按序依次抵达。在Internet上无法保证这一炏V虽然包会按序到达Q但是有时候会丢包Q这通常是个ȝ事?当然Q你可以设计你的协议使得C/S能够从丢包中恢复。但q对初学者来说很痛苦Q不值得推荐?<br>W三步:选择数据传输协议又是看v来很单,其实不然。你不能只是发?\0'l尾的串。因Z需要一个通用的协议,能同旉用字符串和二进制数据。用0(或其他字W?做结束符是不明智的,因ؓ那个l束W可能是你要发送的数据的一部分。此外,如果你发?0字节Q然后再20字节Q服务器极有可能收不C?0字节的包。取而代之的是,它会一ơ性收?0字节Q这是ؓ了避免浪费带宽在不必要的头上?而且Q你可以发?KB的包Q但服务器会以两个小包的形式收到它。所以你必须知道哪里是一个包的开始,哪里是结束。在 “永恒大陆”(<font color=#ff0000>译者注Q原文: Eternal LandsQ本文的作者正在开发的一ƾMMORPG</font>)中,我们用如下的ҎQ?br> <ul> <li><strong>Offset 0</strong>: 1 字节 表示传输的命令? <li><strong>Offset 1</strong>: 2 字节Q传输的数据长度? <li><strong>Offset 3</strong>: 变长Q消息内宏V?/li> </ul> q种Ҏ有一致的优点Q所有的数据传输有统一的标准。缺Ҏ有些命o有固定已知的长度Q浪费了一些带宽。以后我们会Ҏ混合的方法?br>下一件事是决定服务器模型Q?“非阻塞soket,不用线E?#8221;Q或?#8220;dsoketQ用线E?#8221;。两U方?使用U程 vs 不用线E?各有优缺炏V?br><strong>U程:</strong><br> <ul type=1> <li>服务器响应会更加qxQ因为如果一个玩安要大量时?例如从数据库中读取数?Q这会在它自qU程中完成,不会影响其他人?<font color=#ff0000>译者注Q也怽者的意思是每个玩家都有独立的线E,但这对MMORPG不太现实</font>) <li>难以恰当的实现和调试Q你可能需要大量同步,q且一个小疏忽׃DN性的后果( 服务器瘫痪,物品复制Q等{?? <li>可以利用多处理器?/li> </ul> <strong>无线E?</strong> <ul type=1> <li>实现和调试更单? <li>响应速度慢?/li> </ul> 在我的公司,我们使用无线E的ҎQ因为我没有_的资源和人力处理U程模式?br>W四步:客户端你打算?Dq是3D游戏Q有些h认ؓ2D游戏做v来简单。我两者都做过Qƈ且我們֐?D游戏更简单。容我解释?br>2D下,你通常有一个~冲Q也是一个巨大的象素Ҏl。象素点的格式会因显卡的不同而不同?有些是RGB模式Q另一些是BGR模式Q等{。每U颜色的bitC会不同。只有在16bpp模式才有q个问题?-bit?4-bit模式单一些,但有他们各自的问?8-bit颜色数太?256)Q?4-bit速度更慢)。同Ӟ你需要制作你的精灵动ȝ序,不得不自己排序所有对象,以便他们以正的序l制?当然Q你可以用OpenGL或者D3D制作2D游戏Q但通常qƈ不值得。ƈ不是所有h都有3D加速卡Q所以?D库开?D游戏一般会带给你两者的~点Q不是所有h都能玩,你也不能旋{摄像机,拥有漂亮的阴影,?D游戏炫目的效果?<font color=#ff0000>译者注Q目前绝大部分显卡都支持565?6bpp格式Q这个也成ؓ目前16位色的业界通用格式Q有不少文章和代码都是讲q这一格式下图像处理的Q尤其是使用MMX技?/font>) <br>3D的途径Q正如我所_更简单。但是需要一些数?其是三?的知识。现代的囑Ş库很强大Q免Ҏ供了基本的操?你不需要从后到前排列对象,改变物体的色彩和/或帖N十分单,对象的光照会按照光源和它的位|计?只要你ؓ它们计算了法向量)Q还有更?。ƈ且?Dl了你的创作和运动更多的自由度,~点是不是所有h都能玩你的游?没有3D卡的人数可能会让你大吃一惊的)Qƈ且,预渲染的囄L比实时渲染的更漂亮?<font color=#ff0000>译者注Q市面上想买不支?D的显卡目前很困难Q只是高性能?D卡hg不低</font>)<br>W五步:安全昄Q不能相信用戗Q何时候都不能假设用户无法破解你精巧的加密法(如果你用了的话)或者协议,用户发送的M信息都要通过验证。极有可能,在你的服务器上,你有固定的缓冲区。例如,通常有一个小(可能?k)~冲区用来接收数?从soket)。恶意用户会发送超长数据。如果不查,q会D~冲区溢出,引v服务器瘫痪,或者更坏的Q这个用户可以hack你的服务器,执行非法代码。每个单独的消息都必L查:~冲区是否溢出,数据是否合法(例如用户发?#8220;q入那扇?#8221;Q即佉K在地囄另一端,或?#8220;使用ȝ药水”管用户没有那种药水Q等{??我再ơ强调,验证所有数据非帔R要。一旦有非法数据Q把它和用户名,IPQ时间和日期Q和非法的原因记录下来。偶检查一下那个记录。如果你发现量的非法数据,q且来自于大量用Pq通常是客L的bug或者网l问题。然而,如果你发C一个用h者IP发现大量非法数据Q这是明昄q象表明有h正在ƺ骗服务器,试图hack服务器,或者运行宏/脚本。同Ӟ决不要在客户端存储数据。客L应该从服务器接收数据。换句话_不能发送这L消息“OKQ这是我得物品列?#8221;或?#8220;我的力量?0Q魔法是200Q生命值是2000/2000”?而且Q客L不应收到它不需要的数据。例如:客户端不应该知道其他玩家的位|,除非他们在附q?q是常识Q给每个人发送所有玩家会占用大量带宽Qƈ且有些玩家会破解客户端从中获取不公^的利?像在地图上显C特定玩家的位置)(<font color=#ff0000>译者注Q就像传奇的免蜡烛外?/font>)。所有这些似乎都是常识,但,再次Q你会惊奇的发现有多h不知道这些我们认为的常识?<br>另一个要考虑的问题,当涉及到安全Q玩家走动的速度必须在服务器计算Q而不是客L?<font color=#ff0000>译者注Q这是重要的原则Q但是会耗费大量服务器资源。魔兽世界没有这样做Q它采用cM其他玩家揭发的Ş式掩盖这个事实,D加速外挂可以用Q但是在有其他玩家的时候会暴露</font>)。服务器应该跟踪旉(以ms为单?当客h后一ơ移动的时候,q且Q移动的h如果比通常的极限更快到来,q个h应该被抛弃。不要记录这c虚假请求,因ؓq可能是因ؓ|络延迟(也就是玩家gq,q去?0U内发送的数据同时到达??br>查距R如果一个玩家试囑֒100亿公里以外的玩家交易(或者甚臛_另一张地图上)Q记录下来。如果一个玩家试图查看,或者用一个遥q的地图对象Q记录它。小心假的ID。例如,正常情况下每个玩安会分配一个ID(ID在登陆的时候分配,可以是持久的(唯一ID)?如果ID在玩家登陆的时候赋?或怪物被创建的时?Q显然可以用玩家数组(保存玩家)的位|?索引)作ؓID?br>所以第一个登陆的玩家ID?Q第二个?Q依此类推。现在,通常你会有一个限Ӟ比如?000个烦引在玩家列表里。所以如果一个客L发送一条命令类|“查看ID200000的角?#8221;Q这会服务器当机,如果没有防备的话Q因为服务器会访问非法的内存区域。所以,一定要查,像q样Q?"if actor id<0 or if actor id> max players 然后记录非法操作q且断开玩家。如果你使用C或者C++Q注意或者定义烦引ؓ'unsigned int' q且查上限,或因为某些原因定义ؓint(int,默认是有W号?Q记得检?<0 and >max 。没有做q些会严重挫伤你和其他用戗类似的Q要查超出地囑֝标。如果你的服务器有某U寻路算法,q且客户端通过点击地面来移动,保他们不要点击在地囑֤部?<br>W六步:获得一个团队制作游戏需要大量的工作(除非是个Pong and Tetris游戏)。尤其是MMORPG。你无法单靠自己。理ZQ一个完整的团队l成是这P<br> <ul> <li>臛_<strong>3 个程序员Q?/strong> 1 个做服务器,两个客户?或者一个客LQ一个负责工P例如术插gQ世界编辑器Q等{?。有6个程序员是最好的Q更多就没必要了。这取决于你的领D力。最一个美工,2?个更合适。如果这是个3D游戏Q你需要一?D工Q一?D工(制作帖图Q界面,{等)Q一个动dQ和一个美术部负责人。美术部应该由有l验的hl织和安排,除非你就是个艺术家? <li><strong>数世界构徏?</strong>创徏所有地图是个O长的q程Q?q且直接关系到游戏的成|。再ơ,你需要一个世界构建部的负责h。你的世界需要协调一_所以不能只有一个意气用事的人? <li>一?<strong>|站理?/strong>是必ȝQ除非你_N网站设计,q且愿意花时间做|站。音效和音乐不是必须的,但是有音效和音乐的游戏比没有的会更吸引h? <li>一个游戏经系l?<strong>设计?/strong>.。你也许觉得那很单,可以自己来做Q但事实上那是最复杂的工作之一。如果经系l设计不?比如物品没有qQ资源在地图上随意放|,{等?玩家会觉得无聊ƈ且退出游戏。我们早期的q展存在很大的问题,其是因为经系l主要是由我(一个程序员)设计的,它没有被恰当的计划?于是Q我们花费了两个月来重新思考和建立一整个新的l济pȝ。这需要一ơ完全的物品清除。我告诉你,玩家会很不乐意你删除他们的物品。幸q的是,大部分玩家赞同这个想法,但是q么多小时的争论Q妥协,解释和时间的费q是让我们气。以后会更多?<br></li> </ul> 如前所_你需要一?0~15人的团队Q不包括协调员和理者。这10~15人必L有经验的。如果都是新手就不值得Q因Z需要花大量旉解释要做什么,怎样做,Z么他现在的做法不好,{等?br>一开始就凑齐10~15人几乎是不可能的。不你在不同的论坛发多帖Q你也无法找到合适的团队成员。毕竟,如果一个h在他/她的领域得心应手Qؓ什么在你无法拿ZQ何东西的时候他/她要加入你的团队Q很多h有远大的xQ但是实现它们需要大量时间和努力Q所以他们宁可从事自q工作也不会加入你。那如果你需?0~15人,但是无法让他们加入你的团队,你如何才能制作一ƾMMORPG呢? 好,事实上,你一开始不需要所有h都到位。你真正需要的是一个程序员和一个美工。如果你是个E序员,只要找个工可以了。请求懂术的朋友帮忙,花钱请大学生/朋友做一些美术或者其他工作?br>现在你有了一个美工,你期待的游戏的样子,现在可以开始实C。一旦你有了可以q行的C/S引擎Q一些用来展C的截图(或者更好,玩家可以登陆你的世界Q四处走动,聊天)Q更多的Z愿意加入你的团队。更恰当的是Q除非你使用独有的技术,否则你的客户端可以开源。许多程序员会加?作ؓ志愿?一个开源工E而不是非开源项目。而服务器不应该开?除非你打做一Ƒ֮全开源的MMORPG)?br>其他一些忠告:在有东西可展CZ前,不要夸大你的游戏。最惹h烦的事情之一是一个新手发一?#8220;需要帮?#8221;的请求,q且解释q个游戏到底有多P最后要求一个巨大的团队加入他的游戏制作。一旦你拥有了网站广?通常是在一个免费主?Q你会看C个吸引h的导航条Q包?#8220;下蝲”Q?#8220;截图”Q?#8220; 原画”(译者注Q原文:Concept artQ概念艺术,在游戏应该指工的原始设?Q?#8220;论坛”。你点击下蝲链接Q然后看到美妙的“?#8221;面(或者更p糕Q一?04错误)。然后你点击截图Q得到同Ll果。如果你没有东西lh下蝲Q就不要放下载链接。如果没有截囑ֱC,不要放截N接。然而更好的是,在工E进?0%(E序和美?之前Q不要浪Ҏ间在|站上?<br>W七步:打破某些话 <ul type=1> <li><strong>你无法制作MMORPG, 只有大公司才可以?/strong><br>我不同意。虽然制作一Ƒփ兽世界(World of Warcraft)Q无Q?(Ever Quest 2)Q亚瑟王的召?(Asheron's Call 2)Q血l?(Lineage 2)Q和其他一些游戏对一个小型的自发团队是不可能的,但是做一ƑփL游戏q是可以的,只要你有l验Q动机,和时间?你需?000时的编E来制作一个可q行的测试版Q大?0~15k时完成几乎完整的客L和服务器。但是作为团队领D,你不能只~程。保持团队团l,解决争执Q维护公共关p?PR)Q技术支持,架设服务器,惩罚捣ؕ分子Q自p论,{等都是你的职责。你可能会被非编E的dҎ。你很可能需要上?上学Q这减少了你p在项目上的时间。我们很q运Q没有成员离开团队Q但是如果这U事情发生,那的是大问题。假设你的美工半途离开。或者更p糕Q他/Ҏ有给你用他/她作品的许可。当然这可以通过和他们签订合同来解决Q但扑֏外一个美工仍然很ȝ。一个工E中有两U不同的术风格也是问题? <li><strong>需要大W金?通常 4-6 位数) 用来架设一?MMORPG 服务?<br></strong>当然Q这不是真的。我见过专业服务器,1000GB/月,不到100元/?2~300元的初装费)。除非你的数据传输协议设计非怸合理Q?000GB/月对一?000玩家在线(q_)的服务器来说_了。当Ӟ你还需要另一个服务器做网站和客户端下?客户端下载会占用大量量Q当游戏变得行的时?。我们的客户端有22MBQ有时候会?00GB/月的传输量。而我们还没有很流?仍然)。另一件事Q我们不需要另一C用服务器开启这个工E。ADSL/cable服务器可以胜任,直到你的同时在线人数辑ֈ20~30。然后要么找一个友好的L公司Q用q告交换免费LQ要么就只能自己掏腰包了?nbsp; <br> <li><strong>制作一个MMORPG很有?br></strong>q不是真的。你可能认ؓ每个人都会赏识你Q玩家会支持你,你标新立异,q且Q当Ӟ很多玩家都玩你的游戏。玩家可能让厌。即使是完全免费的游戏,他们也能扑ֈ理由抱怨。更p糕的是Zl常会抱怨矛盄事。战士会抱怨升U太难,商h会对战士掠夺大量p很失望。如果你减少怪物掉落物品Q有些玩家就会威胁说要退出游戏。如果你增加Q同L一h会不满新手能更简单赚q事实?真是左右为难。改革和改进是必ȝ。如果你军_改变某些东西Q例如给加工物品增加挑战性,有些Z说太难了。如果你不做Q他们又会说太简单无呟뀂你会发现满意的玩家通常不会说什么ƈ且感到满意,同时破坏者会怨声载道?br></li> </ul> MMORPG的经比单机版难以^衡的多。在单机游戏Q你可以逐渐改良武器Q只要玩家进展,?她可以用更好的装备Q丢?或者卖?旧的。另一斚wQ在多h游戏里,q种观点不成立,因ؓ每个人都试图得到最好的武器Q而蟩q低{武器。大部分玩家宁可I手省钱Q直C们能买游戏中最好的武器。经系l设计要参考相关的文章?br>q今为止我列丄所有事情,加上额外的工作和挑战Q以让你在军_涉q个工程之前三思而行。你必须知道你的军_意味着什么?br>ȝ希望q篇文章能给你够的知识。我的下一文章将介绍如何建立一个经系l?更明的Q要避免哪些错误)Q还有一些调试服务器和客L的信息?br>关于作者这文章作者是 Radu Privantu, 永恒大陆(Eternal Lands) <a target=_blank><font color=#0000ff><u>www.eternal-lands.com</u></font></a>的主E序和项目规? 永恒大陆是一Ƒօ费,客户端开源的MMORPG。作者可以通过 chaos_rift at yahoo dot com 联系?/td> </tr> </tbody> </table> <img src ="http://www.shnenglu.com/jack-wang/aggbug/72506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2009-01-23 13:36 <a href="http://www.shnenglu.com/jack-wang/archive/2009/01/23/72506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器宕?/title><link>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72505.html</link><dc:creator>王</dc:creator><author>王</author><pubDate>Fri, 23 Jan 2009 05:34:00 GMT</pubDate><guid>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72505.html</guid><wfw:comment>http://www.shnenglu.com/jack-wang/comments/72505.html</wfw:comment><comments>http://www.shnenglu.com/jack-wang/archive/2009/01/23/72505.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/jack-wang/comments/commentRss/72505.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jack-wang/services/trackbacks/72505.html</trackback:ping><description><![CDATA[<p>我不得不承认Q我的能力不以写出一?00%不会宕机的游戏服务器E序Q这也不能全怪我的能力太弱,谁让咱国内网游玩家数量庞大,哪个游戏刚上U时没有挤的爆满q?q有些或是猎奇,或是谋私的个人和l织Q在刉着千奇百怪,匪夷所思的数据包及操作程来试探你的服务器。这些都曾是我在服务器宕机后向老板开q理由?/p> <p> </p> <p>当WOWl于来到中国Ӟ我一Ҏ喜着l于可以在艾泽拉斯的大陆上自q,一边却咒骂着9C的破服务器,动不动就宕机。当Ӟwؓ游戏E序设计师的我明知道Q这大部分的错误都不应归|于代理?CQ但是,谁让blizzard是我心目中的,谁又让WOW成ؓ我游戏制作的教科书呢。好吧,我知道上面这D|力追捧blizzard跟WOW的话可能早已让你恶心q连Q不堪入目了Q对不vQ忘了这一节,让我们l?/p> <p> </p> <p> </p> <p><strong>服务器宕机后都发生了些什么?</strong></p> <p> </p> <p>昄的,宕机后玩家会骂,像我在玩WOW旉P骂游戏公司,骂老板Q骂GM。非常抱歉,我们可爱的玩家们gq不清楚Q这个时候最该骂的其实是我们q些E序员们。长久的遗忘被我们当成了包容Q以至于游戏E序员在公司里都L了趾高气扬,不可一世的坏毛病:看吧Q策划们Q你们做的太烂了Q数gqQ玩法没新意Q只会照抄WOW跟大菠萝Q能怪玩安你们吗?q营不得力,买服务器的钱不知道去了哪里,游戏里卡的要死,偶尔办个zdq没半点吸引力,能不被玩安你是无良q营商吗QGM们能不天天被骂家指着骂吗Q?#8230;…呃,又扯q了?/p> <p> </p> <p>赶紧先把服务器重启吧。老板正站在你的n后,一脸愁容,虽然暂时q没有发作,但看得出来:老板很生气,后果很严重!</p> <p>玩家们很快又回来了,不得不ؓ玩家们的毅力和执着_而感动,更ؓ自己的错误而愧疚,凌晨时分Q服务器启了又宕Q宕了又启,如此反复Q可热情的玩家们依然陪着我在折腾。哦Q当q安其拉开门的时候,我也曾这h腾过?/p> <p>q个时候不是你一个h在战斗。GM们在忙碌地处理着玩家不断打来的投诉电话:刚买的装备在宕机后消׃Q花光了w上所有材料合成的武器回档了,但材料却没有q给?#8230;…数据库维护组的同事们也在紧张的恢复着数据Q尽可能的将玩家的损失减到最?/p> <p> </p> <p>真是一件o人沮丧的事?/p> <p> </p> <p> </p> <p><strong>真的该试着做点什么了吧!</strong></p> <p> </p> <p>既然我们非常不愿意看到宕机的情况发生Q但又无?00%保证写出来的服务器程序一定不会出错,那我们就在当机发生后的抢救措施上q功夫Q让玩家的损׃至于太大Q也让我们的l护人员些压力吧?/p> <p> </p> <p>一个最单也最有效的做法是为每一台服务器都配备物理冗余,同步更新冗余服务器上的状态,当宕机发生时Q立卛_处理切换到后备服务器上。只是,物理冗余的代价太大,从成本方面考虑Q老板可能不大愿意点头?/p> <p> </p> <p>既然不能做硬冗余Q那再来考虑软的吧?/p> <p>如果只是单的启动冗余q程Q其实是换汤不换药的做法。原来能?000人的服务器,׃同时q行了两个相同的q程Q得CPU和内存开销都翻了倍,l果是只能跑500Z。还是要加服务器?/p> <p> </p> <p>看来只能更深一层,从架构设计上来动手了?/p> <p>假设我们的游戏世界是由多个独立场景构成的Q那么在实现上我们可以让q些场景在进E上也独立,q样做的好处是可以得一个场景的宕机不会影响到其他场景的正常q行。如果我们的游戏世界物理上没有分隔,是一个无~的大世界,我们也可以h为的其分成多个独立区域Q所需要做的额外工作是处理好那些站在区域边界附q的对象。事实上Q现在的无缝大世界也都是q样实现的?/p> <p> </p> <p>有了q样一个前提,我们再来看这个已宕掉的场景该如何处理?/p> <p>q是老办法,赶紧先把它拉h吧。一个具体可行的Ҏ是,由场景管理器Q或者你也有可能叫它世界服务器,来监视各个场景进E的q行状态,当某个场景异常失去联pLQ由理器来其重新启动。这里需要再q心思的是,如何让玩家数据正常地发送到新启动的场景q程中,而且q个q程对于客户端来说是透明的?/p> <p> </p> <p>q个Ҏ听v来似乎不错,只是Q如果宕掉的是场景管理器q程Q那该怎么办呢Q?/p> <p>按照前面的描qͼ场景理器可以看作是整个游戏世界的中心,它以一个指挥者的w䆾l护着游戏世界的有序运行,所以它的宕机对整个游戏世界的媄响也会是巨大的?/p> <p>有没有什么办法能够得场景管理器q程再次启动后能够恢复先前的状态呢Q?/p> <p>我们可以为管理器和场景进E定义一套协议,使得理器不仅能够创建ƈ恢复一个已有场景,而且场景理器还能通过现有的场景进E数据恢复出自己?/p> <p>一个理Z可行的方案是Q场景管理器与场景进E间保持TCP长连接,q以一定频率进行心跌p,L一方发现联pM断或长时间未收到心蟩包后都会立即做出处理?/p> <p>如果是管理器发现场景q程失去联系Q那启动新的场景,如前面所描述的那栗如果是场景q程发现理器失去联p,那就立即启动重连q程Q直接再ơ连接上理器,然后立即自己当前的状态和负责的场景ID报告l管理器。管理器通过q些上报的数据就能恢复出游戏世界内的场景对应关系表,也就是恢复出了自己原来的状态?/p> <p> </p> <p>q程是恢复出来了Q可我们忘了最重要的内容:数据。当场景q程宕机后,上面保存的玩家属性数据也随之丢失了,虽然我们能够再次这个场景创建出来,q把原来在这个场景内的客L数据重新定向q来Q但q些客户端对应的玩家对象的数据却没有了,游戏仍然无法l箋?/p> <p> </p> <p>也许我们可以再做一点修改,把场景内的玩家数据分d来,保存C个独立的q程上,比如Q我们可以把q个q程叫做数据服务器,或者数据中心之cȝ。一个隐含的要求是,数据服务器的逻辑实现非常单,单到你可以认为它是绝对安全的Q不会宕机。所以,保存在这里的玩家数据也就是绝对安全的?/p> <p> </p> <p>让我们在q个问题上稍微再深入一炏V?/p> <p>场景q程上每ơ执行玩家的游戏逻辑旉要异步地到数据服务器上来存取数据Q这个开销可能太大Q而且会得一些游戏逻辑的实现变的很复杂Q那么,把一些会频繁使用到的数据直接保存在场景进E中Q当数据发生改变时同步更新到数据服务器上Q这样可能会比较Ҏ接受?/p> <p> </p> <p> </p> <p><strong>老板全都满意了吗Q?/strong></p> <p> </p> <p>从理Z来说Q我们已l解决了场景q程宕机和管理器宕机后的状态恢复问题,q且在场景恢复后也不会因Z׃玩家数据而无法l进行游戏,而且Q只要处理得当,q个q程对客L来说可以是完全透明的,也就是玩家根本不知道服务器上有个q程意外l束Q我们做了这么多的工作来它恢复了?/p> <p> </p> <p>事实上,q个q程的透明也是必须的,我们q不需要嚷L告诉我们的用P也就是玩Ӟ我们做了多少多少事情来让你玩的更畅Q又׃多少多少_֊来解军_为服务器宕机而引LȝQ对于最l的用户来说Q他只需要n受最好的服务。闲话少_让我们l?/p> <p> </p> <p><strong>真的已经完全解决了所有问题吗Q?/strong></p> <p>惌q样一个场景:我带着几个刚刚降到艾泽拉斯大陆的伙伴冲向了艾文林Q去开荒霍|正在霍格只剩下一丝血的时候,服务器稍E卡了一下,{我~过来Q面前的霍格骤然消失Q地上也不见怽。找了一圈,它正在出生点摇头晃脑Q也在四处张望,但头上的血条分明是Q满血Q?/p> <p>怎么回事Q?/p> <p>处理q张地图的场景进E意外结束了Q服务器的宕机处理机制很快地恢复了这个场景进E,q且把我的客L数据重新定向C新场景。只是,事情q不是一切都完美。因个场景是完全重新创徏的,q意味着所有的怪物也是重新创徏q被摆放C初始位置Q所以,只剩下一丝血的霍格碰上了好运?#8230;…</p> <p> </p> <p>cM的还有,正在护送NPCq回营地Q在E微停顿了一会儿之后QNPC又重新回C原来的地方,{等?/p> <p> </p> <p>虽然q比h初的“客户端被q断开q接Q服务器端数据丢?#8221;要进步了许多Q但会给我工资的老板仍然可能不太满意Q他希望Q霍格应该还在我的面前,而且只有一丝血Q那个跟着我的NPC也应该还在我旁边……</p> <p> </p> <p>我要是不能说服老板Q这?#8220;Ҏ不可能完成的dQ?#8221;Q那也就只能坐下来再试一试?/p> <p>也许Q可以考虑所有对象的数据都保存到数据服务器上Q当Ӟq要求每个怪物都跟玩家一P有一个唯一IDQ这一点实现v来可能会有些ȝ?/p> <p>再不Ӟ为对象提供一个从已有的内存数据构造的ҎQ这样便可以使用׃n内存来保存现场数据,再从׃n内存中恢复出原来的对象。理Z来说Q这个方法是可行的,只是Q这三十多个字的文字描述要用C++来实C可能会是一Ҏ大的挑战Q所以,q也仅只是可供参考的一个尝试方案?/p> <p> </p> <p> </p> <p><strong>我想Q我们走的够q了</strong></p> <p> </p> <p>让我们先暂停一会儿Q回q头来看一看最初的目的。其实我们想要的只是可能的让服务器q程不要宕机Q如果实在是没有办法Q就可能的让宕机后的玩家损失比较小Q不需要我们做大量的工作去做善后处理?/p> <p>很简单的需求,g我们U缠的有些过头了?/p> <p> </p> <p>写出能够E_q行的程序是对程序员的最基本要求Q如果一个程序连E_性都不具备,那根本都不用再去考虑功能啊、扩展啊{其他标准了。但是,正如我最开始所说的Q没有一个h能够100%保证他写出来的服务器E序是绝对不会崩溃的。我们所能要求的只是可能的仔细Q尽可能的多一些必要的试Q离安全可能的更近一步?/p> <p> </p> <p>剩下的就是在宕机后如何降低损q问题了?/p> <p>对于一般的MMOG来说Q玩家在q入游戏时会从数据库中将该玩家的所有相x据读到内存,以便快速的q行游戏逻辑的处理,而在玩家下线时再数据的改动存回数据库?/p> <p>昄的,当服务器q程出现意外宕机Ӟ内存中所有的数据都丢׃Q这也就造成了玩家数据的回档Q而且玩家在游戏中呆的旉长Q回档的损失p大。所以,一个被q泛采用的做法是为玩家数据实CU定时存盘的机制Q就像现在大多数的单机游戏一PAutoSave。比如,?分钟自动为玩家存一ơ盘Q这样就可以使得回档的最大损失控制在5分钟以内?/p> <p>另外Q对于一些重要数据的变动Q比如玩家花大量游戏货币购买了一件贵重的武器装备Q这时可玩家数据立卛_一ơ存盘操作,q也有效的减少玩家的重大损失?/p> <p> </p> <p>听v来这是一不错的技术,在意外宕机的时候最多只回档5分钟Q而且q没有贵重物品的损失Q玩家应该是可以接受的吧?/p> <p> </p> <p> </p> <p><strong>我已l听C数据库维护员的咆?/strong></p> <p> </p> <p>“数据库已l快要崩溃了Q你׃能让每秒需要执行的SQL语句一点吗Q?#8221;</p> <p>“?#8230;……”</p> <p> </p> <p>我一直以为我们的数据库非常强大,可以处理M的数据,唯一的缺点就是查询速度比直接内存读取要慢很多。所以我使用了异步数据存取的ҎQƈ且开启了多个数据库操作线E来q行的执行我的请求,q行的效果看hq不错?/p> <p> </p> <p>也许Q我应该来算一,每秒U究竟丢了多条操作hl数据库?/p> <p> </p> <p>请允许我再自U一回,我已l很久没有提到WOW?#8230;…</p> <p>大概可信的数字是QWOW一l服务器的玩家数量在3000?000之间Q去掉最大的敎ͼ再去掉最的敎ͼ最后的q_值是Q?000吧,q4000?/p> <p>4000人在U,假设也是?分钟定时存盘一ơ,再假设所有玩家的存盘旉是^均分布的。这L下来Q每U种׃?7个玩家向数据库发出存盘请求操作?/p> <p> </p> <p>?7个,数据库维护组的同事就跟我说不堪重负了Q笑话,q数据库服务器是谁买的?</p> <p>先别急,67是玩家数Q但是每个玩家的存盘h不会只有一条SQL语句?/p> <p> </p> <p>虽然每个游戏的内定w各有差别Q但是一ƾMMOG需要存入数据库的数据少不了会有技能、物品、Q务、宠物、好友、公会这些东ѝ取决于游戏的类型差异,每个游戏都会有自q存盘方式Q比如我可能会把所有的技能ID作ؓ一条数据来存储Q但是我也有可能把每个技能作Z条单独的记录来存储,q样可以方便Ҏ能附加数据的扩展Q等{?/p> <p> </p> <p>但是Q游戏中的物品存储大概都是相同的Q只能是一?l?物品作ؓ一条记录来存储?/p> <p>而且Q可以说游戏中存储量最大的是物品数据。算一你的角色背包有多大Q?0| 100|q是200|不要忘了银行、摆摊位、装备拦、宠物背包和邮箱q些地方也能攄品。ƈ且,在游戏进行过E中Q玩家背包中物品数据的变动也是相当的频繁Q不断的有药品被用掉Q不断地又有些小玩意儿被捡v来,不久后,它们又被卖给了NPC?/p> <p> </p> <p>虽然你可以用一些y妙的比较法来过滤掉那些实际上没有发生变动的物品更新Q另外也不是所有的玩家物品数据变动都很频繁Q但在实际运营中Q尤其是当玩家的背包格数都很多的时候,物品数据的存盘的会成ؓ一个很大的问题?/p> <p> </p> <p>除了物品Q还有玩家的基本属性存盘,C会关系存盘{等Q再加上全局公共数据的存盘,如公会数据,拍卖行物品数据,如果老板也要我在游戏中开上一家拍卖行的话?/p> <p> </p> <p>q么一下来,g是有些多了?/p> <p> </p> <p> </p> <p><strong>再一ơ的挑战</strong></p> <p> </p> <p>具体的数字将取决于游戏的cd和设计的数据表结构?/p> <p>而数据库服务器能承担的每U查询数则取决于数据库服务器的Yg配置情况?/p> <p>但是一般来_数据库维护h员可能会告诉我,当每U执行的SQL语句数达?000条时Q数据库服务器将会感受到明显的压力,我可能也会看到数据库执行队列中的hC直在增长Q也可能会看到数据库服务器间歇性地拒绝响应Q等{?/p> <p> </p> <p>看v来我们又一ơ的面对C巨大的打h?/p> <p>q个问题的v因是什么?我们不希望服务器q程宕机时回档太久,所以我们增加了一个玩家数据定时存盘的机制Q结果却D了数据库h的骤然增多?/p> <p>那再退回到q个L处,定时存盘的旉间隔廉点,比如10分钟才存一ơ?数据库的压力会有~解Q但最初的问题却又会有所暴露。真是个两难的问题?/p> <p> </p> <p>既想要玩家数据存盘间隔时间短一点,又不想给数据库造成的压力太大?/p> <p>同样的需求似乎出现过很多回了Q在中间加一层代理做~冲。我们姑且称q一层代理ؓ数据库代理服务器Q它所要完成的工作是从场景q程攉玩家的定时存盘请求数据,再以一个低一点的频率写入到数据库?/p> <p> </p> <p>听v来这又像是一个换汤不换药的做法,写入数据库的旉间隔q是变长了。但实际上在前面我们曾l描q过Q如果服务器q程不会出现意外的宕机,玩家数据只需要在他上U时dQ在他下U时写入卛_Q中间添加的q些定时存盘q程完全只是Z防范宕机回档所造成的巨大损失?/p> <p> </p> <p>因ؓq个中间代理层的加入Q我们把场景q程宕机的隐患与数据丢失的后果隔d来了Q现在即使场景进E宕机,数据q在数据库代理服务器上,当然q里又隐含了一个条Ӟ数据库代理服务器需要够稳定,不会在场景进E之前先宕掉。事实上Q因个代理进E的工作是,我们完全有理q信,q个q程是非常稳定的Q那L话,多久旉才把~存的数据真正写入数据库Q就看你自己的喜好了?/p> <p> </p> <p> </p> <p><strong>该结束了?/strong></p> <p> </p> <p>是否有些似曾相识的感觉?</p> <p>没错Q前面我们曾l描q过一个数据服务器Q也是这栯的?/p> <p> </p> <p>所以,数据服务器,数据库代理服务器可以合ƈCP来共同保证数据的安全?/p> <p>再加上场景进E与理器进E的恢复协议Q让服务器的重启对玩家保持透明?/p> <p>看v来这个晚上可以睡个安E?/p> <img src ="http://www.shnenglu.com/jack-wang/aggbug/72505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jack-wang/" target="_blank">王</a> 2009-01-23 13:34 <a href="http://www.shnenglu.com/jack-wang/archive/2009/01/23/72505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大地图MMORPG的场景管? http://www.shnenglu.com/jack-wang/archive/2009/01/02/70969.htmlThu, 01 Jan 2009 20:09:00 GMThttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70969.htmlhttp://www.shnenglu.com/jack-wang/comments/70969.htmlhttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70969.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/70969.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/70969.html大地图MMORPG的场景管? - TagQ?大地图MMORPG的场景管?/font>                                          

目前在做一个超大地图MMORPG的场景管理部分,客户端通过动态预读解决了大N的动态加载,但是在做人物行走的时候遇C一些问题:
  一张地图上的PLAYER和NPC{是存放在一个list中的Q地图超大那么上面的PLAYER可能超多(预计大于Q0Q)Q这L话每个行走动作都要发送2Q0条以上的消息Q这对于服务器是一U很大的负担Q而且q种负担是呈U数增长Q?0个玩安C步服务器发?0*10=100条消息,?00个的话就?00*200=40000条消息!Q,可能M服务器都无法负担?br>  肯定有很多朋友都遇到了类似的问题Q很想知道大家是怎么解决的?
  

Ҏ一Q?br> ·服务器上每个场景用一个list来保存上面的player和NPC
 ·玩家行走、进入和d{事件发llist中的所有player
 ·客户端的list保有该场景上的所有player和npc
 优点Q处理v来简单直?br> ~点Q发送的消息会随玩家数量的增加而暴增、客L负担很重

Ҏ二:
 ·服务器上每个场景用一个list来保存上面的player和NPC
 ·玩家行走、进入和d{事件只发给该玩家一定范围内的Player
 ·客户端的list只保有本玩家附近的player和npc
 ·在服务器可以考虑使用hash表来优化查询速度
 优点Q减了服务器发送消息的数量、减M客户端的负担
 ~点Q实现相对复杂,服务器负担大大加重(因ؓ要不断判断玩安的位|关p)

Ҏ三:
 ·在服务器上把场景划分为小区域Q大于屏q大)。每个区域对应一个listQ场景中的所有对象按他们的位|加入到对应区域的list中,那么每次行走只需要把消息发送给最多4个相临区域的Player
 ·客户端的list只保有本玩家附近的player和npc
 优点Q大大减M服务器遍历list的负担、减了发送消息的数量、减M客户端的负担
 ~点Q实现非常复杂、而且在服务器需要不断判断玩家是否跨区?br>
Ҏ四:
 ·服务器上场景的每个TILE保存一个Object指针用来l定该格子上的player或NPC
 ·玩家行走、进入和d{事件发l玩家周围一定范围内的player
 ·客户端保有该player周围一定范围内的player和npc
 优点Q处理v来极为直接、避免了耗时链表遍历Q典型的以空间换旉Q?br> ~点Q地图每个TILE都要加入一个指针变量(理不善Ҏ出错Q、每ơ发送场景广播要遍历所有TILE

Ҏ五:
 ·服务器上每个场景用一个list来保存上面的player和NPC
 ·不用事仉知Q而用状态位|通知的方式通过定时发送状态来更新客户端的player和npc状?br> ·客户端保有该player周围一定范围内的player和npc
 优点Q处理比较简?br> ~点Q实时性太低,对于要求同步比较_的AQԌQ不太适合



2009-01-02 04:09 发表评论
]]>
MMORPG中游戏世界的构徏 http://www.shnenglu.com/jack-wang/archive/2009/01/02/70965.htmlThu, 01 Jan 2009 19:39:00 GMThttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70965.htmlhttp://www.shnenglu.com/jack-wang/comments/70965.htmlhttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70965.html#Feedback0http://www.shnenglu.com/jack-wang/comments/commentRss/70965.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/70965.htmlAuthor: Fox
原文地址Q?a href="http://www.shnenglu.com/Fox/archive/2007/12/16/game_world_architecture.html">http://www.shnenglu.com/Fox/archive/2007/12/16/game_world_architecture.html

一?/span>MMORPGQ?/span>Massively Multiplayer Online Role Playing GameQ的架构包含客户端和服务器两部分。客L主要涉及计算机图形学、物理学、多媒体技术等Q服务器主要涉及|络通信技术、数据库技术,而h工智能、操作系l等计算机基学科知识的应用体现在MMORPG开发过E中的方斚w面?/span>

一、游戏世界的划分

理想状态的游戏世界仅由一个完整的场景l成Q在《魔兽争?/span> III 》、?/span> CS 》这L单机游戏中,所有玩家位于该场景中,在理ZQ位于该场景中的L玩家都可以看到游戏中所有玩家ƈ与之交互Q出于公qx和游戏性(而不是技术上Q的考虑Q游戏中q不会这样做?/span>

然而,目前?/span> MMORPG 中,几乎没有M一Ƒ֏以做到整个游戏世界只包含一个场景,因ؓ在一?/span> MMORPG 中,同时在线的玩家数量成百上千,甚至是数万h同时在一个游戏世界中交互。以现在的网l技术和计算机系l,q无法ؓq么多玩家的交互提供x处理。因此, MMORPG 的游戏世界被划分为大不{、数量众多的场景Q游戏服务器对于q些场景的处理分为分区和无缝两种?/span>

在分区式服务器中Q一个场景中的玩家无法看到另一个场景中的玩Ӟ当玩家从一个场景到另外一个场景跨时Q都有一个数据{Ud加蝲的过E(其是从一个分区服务器跨越到另外一个服务器ӞQ玩安有一个等待的旉Q在q段旉内,服务器的主要工作是实现跨玩家数据的转移和加载以及后一个场景中玩家?/span> NPC {数据的传输Q客L的主要工作是实现新场景资源的加蝲和服务器通信。主要时间的长短主要取决于后一个场景中资源数据的大。分区式服务器的优点主要是各分区服务器保持相对独立,~点是游戏空间不够大Q而且Q一旦某个分区服务器中止服务Q位于该服务器上的所有玩家将失去q接?/span>

所谓无~服务器Q玩家几乎察觉不到场景之间的q种切换Q在场景间没有物理上的屏障,对于玩家而言Q众多场景构成了一个巨大的游戏世界。场景之_甚至服务器之?#8220;没有?#8221;明确的界Uѝ因此,无缝服务器ؓ玩家提供了更大的游戏I间和更友好的交互,实现了动态边界的无缝服务器甚臛_以在某个服务器中止服务时Q按一定策略将负蝲动态分散到其他服务器。因此,无缝服务器在技术上要比分区服务器更加复杂?/span>

目前国内上市?/span> MMORPG Q大多采用分区式服务器,做到无缝世界的主要有《完世界》和《天下贰》等Q国外的 MMORPG 中,像《魔兽世界》、?/span> EVE 》等Q都实现了无~世界?/span>

无缝服务器与分区式服务器在技术上的主要区别是Q当位于场景 S1 中的玩家 P1 处于两个Q甚x多)场景 S1 ?/span> S2 的边界区域内Ӟ要保?/span> P1 能够看到场景 S2 中徏{、玩家?/span> NPC {可感知对象。而且边界区域的大要大于{于 P1 可感知的范围Q否则就可能发生 S2 中的可感知对象突焉现在 P1 视野中的异常?/span>

无疑Q无~世界ؓ玩家提供了更人性化和更具魅力的用户体验?/span>

二、无~世界游戏服务器的整体架?/span>

MMORPG 的服务器架构从功能上主要划分ZU:

1?/span> d服务器( Login Server Q?/span>

d服务器用于玩安证登录,q根据系l记录玩家信息得到其所在节Ҏ务器Qƈ通过世界服务器ؓd玩家和对应节Ҏ务器建立q接?/span>

2?/span> 世界服务器( World Server Q?/span>

世界服务器将整个游戏世界划分成不同场景,所有场景按一定策略分配给节点服务器,q对节点服务器进行管理。世界服务器的另一功能是与d服务器交互。因此,世界服务器是d服务器、节Ҏ务器的沟通桥梁,当然Q一旦玩家登录成功,世界服务器将主要处理节点服务器间的通信。因此,世界服务器对于玩家是透明的?/span>

3?/span> 节点服务器( Node Server Q?/span>

节点服务器负责管理位于该节点的所有玩家?/span> NPC 的所有交互,在无~世界游戏中Q由于边界区域的存在Q一个节Ҏ务器甚至要处理相邻节点上位于边界区域的玩家和 NPC 的信息?/span>

在具体实CQ不同的 MMORPG Z便于理Q可能还会具?/span> AI 服务器、日志服务器、数据库~存服务器、代理服务器{?/span>

三?/span> 无缝世界游戏服务器的主要技术需?/span>

1?/span> ~程语言Q?/span> C/C++ ?/span> SQL ?/span> Lua ?/span> Python Q?/span>

2?/span> 囑Ş库( Direct 3D ?/span> OpenGL Q?/span>

3?/span> |络通信Q?/span> WinSock ?/span> BSD Socket Q或?/span> ACE Q?/span>

4?/span> 消息、事件、多U程?/span> GUI

5?/span> OS

三、无~世界游戏服务器需要解决的主要问题

1?/span> 资源理

无论是服务器q是客户端,都涉及到大量资源Q玩家数据?/span> NPC 数据、战斗公式、模型资源、通信资源{。当q些资源辑ֈ一定规模,其管理的隑ֺ不可忽视。而且Q资源管理的好坏Q直接关pd游戏的安全和生命?/span>

2?/span> |络安全

安全永远是第一位的Q我们无法指望所有的玩家及其所持的客户端永q是友好的。事实上Q威胁到游戏的公qx和安全性的大多数问题,归根l底Q都是由于网l通信中存在的ƺ骗和攻击造成的,q些问题包含但不限于交易ƺ骗、物品复制?/span>

3?/span> 逻辑安全

逻辑安全按理说应该是游戏中最基本的考虑Q覆盖的范围也最q最杂。随机数pȝ是一个非常值得重视的问题,随机C仅仅用于玩家可见的一些Q务系l、战斗公式、h工智能、物品得qQ还可用于网l报文加密等。因此,随机数系l本w的安全不容忽视。另外一个常见的逻辑安全是玩家的UdQ最主要的就是防止加速轮这L变态操作?/span>

4?/span> 负蝲均衡

MMORPG 中的负蝲均衡包括客户端及服务器资源管理和逻辑处理的负载均衡,其中最N知的是网l通信的负载均衡,正常情况下的|络通信数量是可以在游戏设计时做估的Q但因恶意攻击造成的网l负载是无法预测的。因此,负蝲均衡所要处理的主要是实时动态负载均衡和N恢复。负载均衡需要解决的问题包括负蝲监控、负载分析、负载分发和N恢复?/span>

5?/span> 录像pȝ

录像pȝ的构建,主要用于重现关键数据的输入输出,如玩家交易、玩家充|或者当 bug 出现后,为逻辑服务器(泛指上文提到的所有类型服务器Q主要是节点服务器)相应部分启动录像pȝ。待攉到够数据后Q通过录像pȝ重现 bug 。ؓ了逻辑服务器不受自w时_如中断调试等Q的影响Q还可以专门设计心蟩服务器来控制数据传输?/span>

四、ȝ

?/span> MMORPG 中,真正?/span> bug 永远存在于将来。从q一点出发,关于 MMORPG 中游戏世界的构徏Q怎样苛刻的思考都不ؓq?br>
参考资料:

1?[] Kim Pallister~? 孟宪?{译. 游戏~程_a5, P467-474, P516. 人民邮电出版C? 2007q?? 北京.
2?[] Thor Alexander~? 史晓?? 大型多h在线游戏开? P174-185. 人民邮电出版C? 2006q?2? 北京.
3?[] Dante Treglia~? 张磊 ? 游戏~程_a3, P117-122. 人民邮电出版C? 2003q?? 北京.
4?[] Mark DeLoura~? 王淑C?{译. 游戏~程_a1, P90-93. 人民邮电出版C? 2004q?0? 北京.
5?[] Douglas {著, 於春?? C++|络~程 ?. 中国电力出版C? 2004q?1? 北京.
6?[] Stephen D. Huston {著, 马维?? ACEE序员指? 中国电力出版C? 2004q?1? 北京.
7?[] Erich Gamma{著, 李英?{译. 设计模式. 机械工业出版C? 2000q?? 北京.
8?游戏引擎全剖? http://bbs.gameres.com/showthread.asp?threadid=101293.
9?服务器结构探讨:d服的负蝲均衡. http://gamedev.csdn.net/page/351491d0-05ad-48a4-85e1-77870bc1eef3.
10、服务器l构探讨Q最l的l构. http://gamedev.csdn.net/page/28695655-974c-4291-8ac4-2589c4e770d3.



2009-01-02 03:39 发表评论
]]>
负蝲均衡Q-大型在线pȝ实现的关?下篇)http://www.shnenglu.com/jack-wang/archive/2009/01/02/70962.htmlThu, 01 Jan 2009 18:19:00 GMThttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70962.htmlhttp://www.shnenglu.com/jack-wang/comments/70962.htmlhttp://www.shnenglu.com/jack-wang/archive/2009/01/02/70962.html#Feedback1http://www.shnenglu.com/jack-wang/comments/commentRss/70962.htmlhttp://www.shnenglu.com/jack-wang/services/trackbacks/70962.html  一般而言Q只有在大型在线pȝ当中才有必要引入负蝲均衡Q那么,多大的系l才能被UCؓ大型pȝ呢?比如动辄同时在线数十万的|络游戏Q比如同时在U数?0万以上的WEB应用Q这些我们都可以理解为大型系l,q本w就是一个宽泛的概念?br> 
 设计再好的服务器E序Q其单个E序所能承载的同时讉K量也是有限的Q面对一个庞大且日益增长的网l用LQ如何让我们的架构能适应未来量用户讉KQ这
自然q涉到了负载均衡问题。支持百万以上的大型在U系l,它的架构核心是如何?#8220;百万”q么大的一个同时在UK分摊到每个单独的服务器程序上厅R真
正的逻辑处理应该是在q最l的底层的服务器E序Q如QQ游戏q_的游戏房间服务器Q上的,而在此之前所存在的那些服务器Q都可以被称?#8220;引\?#8221;Q它们的
作用是客L一步步引导到这最l的负责真正逻辑的底层服务器上去Q我们计?#8220;百万U在U?#8221;所需要的服务器数量,也是首先考虑q底层的逻辑服务器单个可
承蝲的客Lq接量?br>  比如Q按上篇我们所分析QQ游戏架构而言Q假设每个服务器E序最高支?W的用户在U(假设一台机子只q行一?br>服务器程序)Q那么实?50万的在线量至需要多台服务器呢Q如果算得简单一点的话,应该是Q?50/2=75台。当Ӟq样v来,可能q不能代
表真正的服务器数量,因ؓ除了q底层的服务器外Q还要包括登?账号服务器以及大厅服务器。但是,׃d/账号服务器和大厅服务器,它们与客L的连?br>都属于短q接Q即Q取得所需要信息后Q客L与服务器x开q接Q,所以,客户端给q两cL务器带来的压力相比于长连接(卻I客户端与服务器始l保持连
接)而言pd多,它们的压力主要在处理瞬间的ƈ发访问上?br>  “短连?#8221;Q是实现应用层负载均衡的基本手段Q!Q如果客L要始l与d/账号服务器以及大厅服务器保持q接Q那么这样作的分层架构将是无意义的,q也没有办法从根本上解决用户量不断增长与服务器数量有限之间的矛盾?br> 
 当然Q短q接之所以可以被使用q能l护正常的游戏逻辑Q是因ؓ在玩家看不到的地方,服务器与服务器之间进行了大量的数据同步操作。如果一个玩家没有登?br>到登录服务器上去而是直接q接q了游戏戉K服务器ƈ试图q行游戏Q那么,׃游戏戉K服务器与大厅服务器和d/账号服务器之间都会有针对于玩家登录的?br>辑维护,游戏戉K服务器会出来该玩家之前q没有到d服务器进行必要的账号验证工作Q它便会玩家踢下线。由此看来,各服务器之间的数据同步,又是?br>现负载均衡的又一必要条g了?br>  服务器之间的数据同步问题Q依据应用的不同Q也会呈C同的实现Ҏ。比如,我们在处理玩家登录这个问
题上。我们首先可以向玩家开放一些默认的d服务器(服务器的IP及PORT信息Q,当玩家连接到当前的登录服务器后,p服务器首先判断自己同时连接的
玩家是不是超q了自定义的上限Q如果是Q由向与该服务器q接着?#8220;d服务器管理?#8221;Q一般是一个内部的服务器,不直接向玩家开放)甌仲裁Q由“d?br>务器理?#8221;Ҏ当前各登录服务器的负载情况选择一个新的服务器IP和PORT信息传给客户端,客户端收到这个IP和PORT信息之后重定向连接到q个?br>的登录服务器上去Q完成后l的d验证q程?br>  q种Ҏ的一个特ҎQ在面向玩家的一侧,会提供一个外部访问接口,而在服务器集的内部Q会提供一?#8220;服务器管理?#8221;及时记录各登录服务器的负载情况以便客L需要重定向时根据策略选择一个新的登录接口给客户端?br> 
 采用分布式结构的好处是可以有效分摊整个系l的压力Q但是,不点就是对于全局信息的烦引将会变得比较困难,因ؓ每个单独的底层逻辑服务器上都只是存?br>了自p一个服务器上的用户数据Q它没有办法查找到其它服务器上的用户数据。解册个问题,单一点的作法Q就是在集群内部Q由一个中介者,提供一个全局
的玩家列表。这个全局列表Q根据需要,可以直接攑֜“服务器管理?#8221;上,也可以存攑֜数据库中?br>  对于逻辑相对独立的应用,全局列表?br>使用Z其实q不多,最主要的作用就是用来检玩家是不是重复d了。但如果有其它的某些应用Q要使用q样的全局列表Q就会数据同步昑־比较复杂。比
如,我们在超大无~地囄MMORPG里,如果允许跨服操作(如跨服战斗、跨服交易等)的话Q这时的数据同步会变得异常复杂Q也Ҏ使处理逻辑出现不可
预测性?br>  我认为,对于休闲q_而言QQQ游戏的架构已l是比较合理的,也可以称之ؓ休闲q_的标准架构了。那么,MMORPG一般的架构是什么样的呢Q?br> 
 MMORPG一般是把整个游戏分成若q个游戏世界l,每个l内其实是一个单独的游戏世界。而不同的l之_其数据皆是相互独立的Qƈ不象QQ休闲q_
一h有的用户都会有一个集中的数据存放点,MMORPG的游戏数据是按服务器l的不同而各自存攄。玩家在dQQ游戏ӞQQ游戏相关的服务器会自?br>为玩家的dq行负蝲均衡Q选择相对不忙的服务器为其执行用户验证q最l让用户选择q入哪一个游戏房间。但是,玩家在登录MMORPGӞ却没有这L?br>动负载均衡,一般是q家h为地去选择要进入哪一个服务器l,之所以这P是因为各服务器组之间的数据是不相通的。其实,l致xQMMORPG的服务器
架构思想与休闲^台的架构思想有异曲同工之妙,MMORPG的思想是:可以为玩家无限地开独立的游戏世界(x务器l)Q以满大型玩家在线Q而休闲^?br>的思想则是Q可以ؓ玩家无限地开游戏戉K以满_量玩家在Uѝ这两种应用Q可以无限开的都?#8220;h完整游戏性的游戏世界”Q对于MMORPG而言Q它的一
个完整的游戏地图是一个整体的“游戏世界”Q而对于休闲^収ͼ它的一个游戏房间就可以描述Z?#8220;游戏世界”。如果MMORPG作成了休闲^台那L?br>服皆通,也不是不可以Q但随之而来的,是要解决众多跨服问题,比如Q好友、组队、帮z{的问题Q所有在传统MMORPG里所定义的这些玩家组lŞ式的
规则可能都会因ؓ“全服皆?#8221;而改变?br>  架构的选择是多h的Q确实没有一U可以称得上是最好的所谓的架构Q适合于当前项目的Q不一定就适合于另一个项目。针对于特定的应用,会灵z选用不同的架构。但有一点,是可以说的:不管你如何架构,你所要作的就是-Q要以尽可能单的Ҏ实现可能的E_、高效!

2009-01-02 02:19 发表评论
]]>
þþùƷ| ھƷþþþӰԺһ| þóСƵ| 91龫Ʒ91þþþ| ҹƷþþþþþ| ۺϾþþƷɫ| þ޾Ʒһ| ɫۺϾþۺ| ҰĻþ| ƷۺϾþþþþ888ѿ| þþƷѹۿ| þҹ³˿Ƭϼ| þۺϾþۺ| ݺɫþۺ_| ޹þþþþþ| ޹Ʒ˾þ | ŷþ޾Ʒ| þþƷѹۿ97| ھƷþþþþĻ| ɫۺϾþۺۿ| þ99Ʒ鶹ѿ| þˬˬƬAV鶹| þ2019Ļ| ۺϾþþƷɫ| þѵľƷV| ݹ˾þ91| þþþ18| ɫþþۺ| þ99Ʒ鶹լլ| ŷ鶹þþþþ| һɫþ99һۺ| ձɫۺϾþӰԺ| ˾þۺӰԺ| 97Ʒ˾þô߽app| ˺ݺۺϾþ88| þAVĻ| Ʒþþþþù| 99REþþƷﶼǾƷ | ƷۺϾþ| ޹˾þþƷ99 | ޹˾ƷŮ˾þþ |