游戏服务端架构发展史(上)

手游页游和端游,本质上没有区别,区别的是游戏类型:

《游戏服务端架构发展史》转载请著名出处:http://www.skywind.me/blog/archives/1265 

类型1:卡牌,跑酷等弱交互服务端

卡牌跑酷类因为交互弱,玩家和玩家之间不需要实时面对面PK,打一下对方的离线数据,计算下排行榜,买卖下道具即可,所以实现往往使用简单的 HTTP服务器:

image

登录时可以使用非对称加密(RSA, DH),服务器根据客户端uid,当前时间戳还有服务端私钥,计算哈希得到的加密 key 并发送给客户端。之后双方都用 HTTP通信,并用那个key进行RC4加密。客户端收到key和时间戳后保存在内存,用于之后通信,服务端不需要保存 key,因为每次都可以根据客户端传上来的 uid 和 时间戳 以及服务端自己的私钥计算得到。用模仿 TLS的行为,来保证多次 HTTP请求间的客户端身份,并通过时间戳保证同一人两次登录密钥不同。

Continue reading

Loading

Posted in 游戏开发, 网络编程 | 1 Comment

你为什么会离开游戏行业?

这个题目本来不想讨论,现实生活中我是一个尊重他人的人,而尊重他人最重要的是尊重他人的选择,尊重他人的价值观和梦想。但是身边太多惨痛的教训,让我有种不吐不快的想法,大家偶尔也该停下忙碌的脚步来想想自己要走的路,也是一件很有意义的事情,所以如果言语中我伤害了你的梦想,请你绕道而行:

下有地雷,玻璃们请小心绕路:

Continue reading

Loading

Posted in 大浪淘沙, 游戏开发 | 35 Comments

行为树的疑问

关于行为树的实现,我在网上看到几个实现版本都对节点规划了running状态,表示节点的动作未执行完毕,每次执行时从上次未执行完毕的节点开始执行而跳过之前已经执行完毕的节点。

问题在于,处于同一selector节点下的子节点,位置越靠前的节点优先级是越高的,如果因为running恢复机制而跳过了已经执行完毕的节点,岂不是无法实现“打断”现有逻辑的需求?

我想问,节点running状态的引入是为了解决什么问题?为什么不每次都top-down执行所有节点?

http://www.zhihu.com/question/29486474

1. 行为树肯定要有 RUNNING状态的,否则你长时间做一件事情很难描述呀,比如你先做“走过去”,再做“采矿”再做“返回”,一颗行为树就表达完了。每件事情都是持续的,如果没有RUNNING,那其实就更像一颗“决策树”而非“行为树”了。

2. 假设你有三层状态机,行为树也只会用在最后一层,头两层都是一些“确定的动作”,不需要行为树来弄,比如“跑过去”,“采矿”这些分解动作,本来变化也不多,如果这都要行为树来弄的话,你的开发反而会很累。

3. 行为树是“树形逻辑”,“树形状态变迁”,但是有些时候逻辑不是树形的,比如就是个纯粹的是有向图的,这种情况下非要用行为树的话,要打比较多Patch

4. 针对你说的“停止”,问题,状态机/行为树,肯定要可以随时打断安排新任务的,具体的做法可能是,update的时候传入一个事件(比如时钟,或者结束),就像tcp的状态机,时钟和网络包都是它的输入,如果不能处理输入,那你做出来的东西只会自顾自的在屏幕上动来动去罢了。

5. 针对实现停止,有三种做法,一种是节点前判断,一种是行为树跑完后,都要跑一个通用的状态机;第二种是增加RESET整棵树的操作;第三种是通用状态机来处理任务改变的消息,一旦改变就复位树,或者调用一颗新的树,比如你把“巡逻”,“逃避”,“进攻”,写成了三颗不同的行为树,相当于一个“高级状态”来用。

PS:由于国内单机游戏凋零,网游类型单一,早年国内说 AI 都在说寻路,而这两年说 AI 大家都在说行为树。行为树是好用的,但是最近两年有些滥用了。它不是银弹,不是什么问题都可以扔给行为树让它来解决的。

Loading

Posted in 人工智能 | Tagged | Leave a comment

二十年前是怎样开发游戏的?

知乎上有人问:“贴吧都是十五六岁就用引擎写游戏的天才,大家怎么看?”,感觉现在做游戏真实一件幸福的事情呀,不尽想起当年开发游戏的各种艰辛。

现在做游戏很简单,大把代码给你参考,大把框架给你使用,Windows帮你作完了大部分事情。我们那个年纪写游戏时,家里还没有Internet,什么资料都查不到,什么开源引擎都没有,95年左右你要写一个游戏,你起码面临:

  • 同显卡打交道,显卡著名的 ModeX显示模式,估计现在没几个人听过了吧,直接写显卡端口,N多trick才能初始化成功。
  • 直接访问显存,记得当年有个优化是,((char*)0xa0000L)[x + (y << 8) + (y << 6)]=c,把y两次左移相加代替y * 320。
  • 用调色板绘图,256色的调色板,建立若干索引表,来快速索引两个颜色混色的结果。
  • 保护模式编程,自己初始化GDT和LDT,后来找到 dos4gw,牛逼的 watcom c++。
  • 自己实现线程,编程8254时钟控制器,给CPU的IRQ0发中断,来调度不同最多32个任务,到时间靠一条IRET指令实现切换。
  • 自己控制声卡,通过220端口控制声卡(估计也没几个人用过吧),再用DMA传送音频,实现声音播放。
  • 自己实现混音,同时播放多个音源时,需要重采样成声卡格式,并且每次DMA中断时混音后给声卡。
  • 自己播放音乐,利用声卡338端口的 FM Synth合成器来播放MIDI音乐里面不同音轨的乐器音符,并用之前实现的线程系统,在后台线程运行。
  • 大量汇编代码,图形拷贝,图块缩放,RLE,显卡控制,多边形填充,键盘中断接管。
  • 自己绘制字体,HZK16,估计听过的人也没几个了。
  • 自己读取图片,GIF,PCX, BMP。
  • 自己播放视频,自己实现解码播放 animator, 3ds输出的 FLC视频格式的视频。
  • 自己实现脚本,没有LUA,没有PYTHON,但是你需要给你的游戏实现脚本来描述一些简单的剧情,没见过其他游戏是怎么做的,没有任何参考代码的情况下,意识到开发游戏需要靠脚本来提高效率,然后自己实现一套脚本系统。
  • 凭空实现游戏,从来没见过任何一款游戏代码的情况下,自己想想状态机应该怎么写,游戏对象应该怎么同时移动,图像前后遮挡该怎么做,游戏各种逻辑该如何写。
  • 学习美术设计,虽然没有美术功底,但得熟练应用当时常用的animator,3ds,等软件,自己制作一些简单的界面和角色,自己能对其他图片进行二次加工,画像素图,合并调色板。

Continue reading

Loading

Posted in 大浪淘沙, 游戏开发, 随笔 | 13 Comments

转换 Intel汇编格式到 AT&T汇编风格

常用 MSVC写内嵌汇编需要兼容 GCC是一件头疼的事情,不是说你不会写 GCC的 AT&T风格汇编,而是说同一份代码写两遍,还要调试两遍,是一件头疼的事情,特别是汇编写了上百行的时候。于是五年前写过一个小工具,可以方便的进行转换,能把 MSVC/MASM的汇编转成纯 AT&T风格汇编,或者 GCC Inline风格汇编,自动识别寄存器和变量,还有跳转地址,并且自动导出。今天把他放上来,或许有用到的人吧。

Continue reading

Loading

Posted in 编译原理 | Tagged , , | 1 Comment

游戏中AI常用工具分析

BehaviorTree:国内很多正式商用项目确实用了,不管RTS,还是RPG,而且用的还行,毕竟写AI一大半时间在调试上,有图形化的界面,调试起来更方便点,有的项目策划可以直接来写AI。值得花时间封装的东西,你做出一套来,以后其他项目都可以用,但是两个人一个多月的时间是最起码的,一个人写一个GUI编辑器,另一个人写 BehaviorTree的运行时,用你们熟悉的语言来写。包括若干基类,运行跟踪,状态单步,以及可以脱离游戏环境的调试方式。如果找到称手的AI框架,拿过来, 比如你可以评估下 U3D的 BehaviorTree的库和编辑器是否可以,能否集成到你的项目?我自己没有用过,我们用自己之前的一个实现。

NaviMesh:大部分情况最好不用,现在国内大部分游戏都是显示3D,但是内部数据还是2D的,比如地图,还是用的格子,在这种情况下,引入NaviMesh会逼迫你客户端使用全3D数据结构,并且逼迫你服务端从2D计算升级到3D计算,主要是 NaviMesh实现起来起码也要一个多月,然后要调试很久。确实很优秀,但是不要为了用它来增加整体项目复杂度,我同事之前实现过 NaviMesh,但是仅仅在试验项目里用了,正式线上产品开发时,我们还是选择用纯2D地图,上传统寻路。

Continue reading

Loading

Posted in 人工智能 | Tagged | Leave a comment

程序高手的境界

程序员也有三六九等:

初等程序员靠知识来挣钱,会别人会的东西,喜欢折腾架构和框架,以掌握更多新潮东西而沾沾自喜,以模仿各种奇技淫巧重新实现一遍而四处炫耀,常见台词:“为啥还在用png存图片?为啥不用webp这种高压缩比的格式?”,“我们使用 Erlang的高并发特性来实现同时支持5万人的效果”,“我们使用RTMFP来降低流量成本,又使用H265来给用户提供更高品质的视频画质”,这些人能够迅速的学会各种项目需要的架构套件,以自己的生产力来挣钱。

高等程序员靠智慧挣钱,会别人不会的东西,上能抉择技术方向,下能解决性能瓶颈;讨论方案时,腾讯怎么做的,阿里怎么做的,我们该怎么做,如数家珍;写完代码后,初读让人赏心悦目,再读让人恍然大悟,三读让人心悦诚服。常见台词:“webp压缩比不高,我改了一版新webp,用H265帧内预测来保存RGB,用lzma2来保存alpha比webp好多了”,“erlang大家不熟悉,我做了一个库,让大家可以象写erlang一样来写C++,照顾大家开发习惯,又可以象erlang一样写多线程”。“Micheal Abrash这几行代码还有很大优化空间,其实性能还可以更好!”她们都是以解决别人不能解决的问题来挣钱。

上等程序员靠创新来挣钱,能促进行业的发展,在这个充满咨询的年代,学习大家都掌握的东西只是一个基本过程,没什么值得称道的,当你baidu上找不到方案,google里没有参考,国内外没有任何人能给你启示的时候,任然能够充满创造的分析问题,抽象问题,并解决问题。找到别人完全没有走过的路,创造前人从来没有创造过的东西,这是他们的价值所在。他们的常见台词是:“别烦我!”,“忙着呢!”,“谷歌搜呀,这都问我?”,上等程序员是国宝,他们的时间不应该浪费在无意义的事情上。

Continue reading

Loading

Posted in 随笔 | 6 Comments

如何实现移动设备的通用手势识别?

移动设备多用手势进行输入,用户通过手指在屏幕上画出一个特定符号,计算机识别出来后给予响应的反应,要比让用户点击繁琐的按钮为直接和有趣,而如果为每种手势编写一段识别代码的话是件得不偿失的事情。如何设计一种通用的手势识别算法来完成上面的事情呢?

我们可以模仿笔记识别方法,实现一个简单的笔画识别模块,流程如下:

 

第一步:手势归一化

1. 手指按下时开始记录轨迹点,每划过一个新的点就记录到手势描述数组guesture中,直到手指离开屏幕。

2. 将gesture数组里每个点的x,y坐标最大值与最小值求出中上下左右的边缘,求出该手势路径点的覆盖面积。

3. 手势坐标归一化:以手势中心点为原点,将gesture里顶点归一化到-1<=x<=1, -1<=y<=1空间中。

4. 数组长度归一化:将手势路径按照长度均匀划分成32段,用共32个新顶点替换guestue里的老顶点。

 

第二步:手势相似度

1. 手势点乘:g1 * g2 = g1.x1*g2.x1 + g1.y1*g2.y1 + … + g1.x32*g2.x32 + g1.y32*g2.y32

2. 手势相似:相似度(g1, g2)=g1*g2/sqrt(g1*g1 + g2*g2)

 

由此我们可以根据两个手势的相似度算成一个分数score。用户输入了一个手势g,我们回合手势样本中的所有样本g1-gn打一次相似度分数,然后求出相似度最大的那个样本gm并且该分数大于某个特定阀值(比如0.8),即可以判断用户输入g相似于手势样本 gm !

Loading

Posted in 人工智能, 编程技术 | Tagged | 4 Comments