Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

01navmesh寻路与漏斗算法

多边形寻路参考PolygonNavMesh 原理:

1. 将unity导出的数据生成凸多边形

2. 找出所有凸多边形共享的边

3. 使用A*算法找出起点到目标点所经过的多边形列表

4. 使用漏斗算法找出顶点坐标

02游戏服务端究竟解决了什么问题?

整理下这篇文章到目前为止做了什么事情:

在文章的一开始确定了游戏服务端要解决的核心两个问题:消息的pipeline与游戏世界状态维护。

通过回顾历史的形式提出游戏服务端中最常见的需求情景:多玩家场景同步,并梳理了场景同步最适合的消息pipeline。

结合切场景的扩展需求,提出Gate这种基础设施抽象(infrastructure abstraction,简称IA)。

尝试进行高内聚、低耦合的服务划分,并总结Gate无法兼顾的消息pipeline。

针对Gate无法处理的消息pipeline(service -> service),提出新的MQ-IA,可以大大简化服务间拓扑关系。基于不同的IA与相关协议,提出更高层次的RPC协议,定义了适合.Net2.0和.Net4.5的两种异步RPC调用规范。实现了不同IA到统一规范的Adaptor。

总结了游戏中RPC应用的pattern,不同pattern如何与不同IA结合使用。同样通过回顾历史的形式引入数据服务来取代传统MMO中的Db代理进程。

结合MQ与数据服务,提出无状态服务在游戏服务端中的应用情景,展开介绍数据服务对于无状态服务的意义所在。

基于构建全局数据服务的理念,尝试实现一种多实例的、每实例内向不同服务提供原子修改操作级别一致性的数据服务。

为数据服务增加了符合需求的高可用支持。引入了zookeeper,可以让普通的服务也可以复用同样的协调者组件。


总结下出现的几种概念:

IA。包括Gate、MQ、内存db、持久化强一致性db、分布式协调器等等。不同的IA各司其职,各自只负责解决分布式系统中的一小部分问题。

RPC与Pattern。面向应用层的统一服务调用方式与规范。

Adaptor。不同的IA与相关协议到统一RPC与Pattern的适配器。

03Recast & Detour 寻路引擎的基本流程

Recast & Detour是一个开源的寻路引擎,其遵循zlib协议,基本上你可以免费且无限制的将它用作个人和商业产品中。

从名字中我们可以看到,这个引擎分成两部分:

第一部分是Recast,主要功能是将场景网格模型生成用于寻路的网格模型(Navigation Mesh)。所生成的寻路网格模型当然要比原模型简单很多,这也提高了实时寻路算法的效率。

第二部分是Detour,主要功能是利用上一步所生成的Navigation Mesh进行寻路,其包含了多种寻路算法,根据不同的路径光滑程度与寻路时间效率的要求可做不同的选择。

04龙之谷服务器设计

9月23日,首届“梦想·匠心”腾讯游戏开发者大会于深圳举行,在技术分论坛上,盛大游戏《龙之谷》手游技术总监李阳分享了龙之谷的服务器设计。作为《龙之谷》的手游技术负责人,李阳从事多年游戏后端开发,参与多款上线项目研发。李阳于本次论坛上分享《龙之谷》手游服务器在架构设计、灾备处理、性能优化、压力测试等方面遇到的一些问题和经验总结。

05pbc的一个陈年老BUG

这里就得提到pbc的两个feature。第一个是,如果一个optional字段的数据不存在,那么你尝试去读的时候,会返回一个默认值。这个默认值的话如果协议里不定义,整数是0,字符串是空串,而table就会生成一个新table,里面的数据全是默认值。

第二个是,如果某个optional的字段的内容是默认值,那么打包的时候会忽略。也就是说pack的结果的二进制里什么也没有。

说它是两个feature是因为,原生的protobuf是没有这回事儿的。二进制里没有,unpack的结果里去读也不会有;有数据但是是默认值,打包的二进制里也会有key-value,只是value是默认值(0或者空串),默认值一般都很小。

然后既然要自己动手,就得去读代码了。对以上features的实现,特别是读取不存在的数据的实现,并且为了高效pbc采用了默认值table的方法。什么叫默认值table呢?就是每一个protubuf的message,在第一次解包的时候,pbc的lua-binding都会生成一个默认值的table。

假设某个要读取的数据不存在,pbc的lua-binding会返回这个默认值的table。举个例子:

local msg1 = pbc.unpack('abc', buffer1)

-- 假设这时候nodata这个数据不存在

print(msg1.nodata.int_type)

-- 假设0是默认值,这里会输出0

local msg2 = pbc.unpack('abc', buffer2)

-- 如果buffer1和buffer2里都没有nodata的数据,下面两行会输出同一个table

print(msg1.nodata)

print(msg2.nodata)

那么问题就来了,这种情况,如果对解包数据是只读还好,一旦进行了写入,假设执行了msg1.nodata.int_type = 100,那么msg2.nodata.int_type也变成了100,并且以后解包的这个message的空数据里的nodata.int_type都变成了100。这也是最开始提到的那个BUG的原因。

06Lua查找表元素过程(元表、__index方法是如何工作的)

举个栗子:)

father = {

house=1

}

son = {

car=1

}

setmetatable(son, father) --把son的metatable设置为father

print(son.house)

输出的结果是nil,但如果把代码改为

father = {

house=1

}

father.__index = father -- 把father的__index方法指向自己

son = {

car=1

}

setmetatable(son, father)

print(son.house)

输出的结果为1,符合预期

07检测Lua中临时对象造成的内存增长

创建临时对象,比如临时表、临时闭包,向table里加key value,都会使lua虚拟机内存增加,虽然可被gc掉但会造成更频繁的gc,gc速度没分配速度快的话进程容易挂。问题就是如何自动化的找到分配临时对象内存的lua代码,造成内存增长的情况很多怎么找呢

08Lua math string库

Lua math string 库 http://cloudwu.github.io/lua53doc/contents.html 《Lua5.3参考手册》

09pbc默认值问题

这里就得提到pbc的两个feature。第一个是,如果一个optional字段的数据不存在,那么你尝试去读的时候,会返回一个默认值。这个默认值的话如果协议里不定义,整数是0,字符串是空串,而table就会生成一个新table,里面的数据全是默认值。

第二个是,如果某个optional的字段的内容是默认值,那么打包的时候会忽略。也就是说pack的结果的二进制里什么也没有。

10浅析Lua中table的遍历和删除

在Lua中,最最核心的数据结构就是表.表不仅可用作数组,还可以用作字典.Lua面向对象的实现也是用表实现的.这里主要讨论表的遍历和删除操作

11Lua非常有用的工具——递归打印表数据

在Lua中,我认为最最核心的数据结构就是表。表不仅可用作数组,还可以用作字典。Lua面向对象的实现也是用表实现的

12quick3.3下集成云风pbc(windows版)

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件

我的名片

网名:丰果 | Ranger

职业:游戏开发

现居:上海市

Email:86668082@qq.com




站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流