November 07, 2018

判断点是否在三角形内的算法精度问题

今天一个同事反应,在使用 recastnavigation 库时,判断一个点是否在一个三角形内,遇到了精度问题,而且精度误差很大。

具体是 dtClosestHeightPointTriangle 这个函数。

他给出了一组测试参数,abc 三点为 {261.137939, 8.13000488} , {73.6379318, 8.13000488}, {76.9379349, 10.2300053} ,测试 p 为 {74.4069519 , 8.6193819 } 应该在这个三角形内,但是这个函数计算出来并不是。

阅读全文 "判断点是否在三角形内的算法精度问题" »

November 06, 2018

Skynet 1.2.0

今天我发布了 skynet 1.2.0。

距离上次发布 1.1.0 已经有一年了。虽然我觉得给 skynet github 仓库里某个特定版本起个有意义的名字并无太大意义,因为我也不会刻意去维护一个所谓稳定版。但在 issues 中还是发现有一些同学还在基于上个 1.1.0 的 release 版提问题,我认为还是保持一年一个版本号比较好。

其实,对于活跃项目,最好的方法还是始终跟进 github 上的 master 比较好。我也刻意在维持代码的向前兼容性。skynet 的 api 已经很稳定,不用太担心更新造成项目跑不起来。话说回来,即使某次更新打破了兼容性,每次一小步的跟进也比隔上一年才同步一次,或是永不升级来得好。

跟进及时可以减少更新带来的新问题。有麻烦可以马上反馈,我更容易帮助解决;不更新容易让 bug 滞留,原本已经解决的 bug 可能在未来再次困扰你。随着 skynet 的用户越来越多,隐藏在犄角旮旯的 bug 更容易被找出来。在 issues 板块,已经有很多问题其实是在 issue 提出时已经被解决了的,仅仅只是因为未更新代码。这种问题无疑浪费了大家的时间。

阅读全文 "Skynet 1.2.0" »

October 21, 2018

Lua 的多线程支持

单个 Lua 虚拟机只能工作在一个线程下,如果你需要在同一个进程中让 Lua 并行处理一些事务,必须为每个线程部署独立的 Lua 虚拟机。

ps. 在少量多线程应用环境,加锁也是可行的。你可以在编译时自定义 lua_lock(L)lua_unlock(L) 去调用操作系统的锁。

比较成熟的 lua 多线程库有 LanesEffil 。它们都试图隐藏多虚拟机的细节,让用户使用起来好像多线程在使用同一个虚拟机一样。比如 Effil 就用了 effil.table 去模拟 table 并让多个虚拟机可以共享数据;Lanes 则有 deep userdata 可以在不同线程间共享。

阅读全文 "Lua 的多线程支持" »

October 09, 2018

Lua GC 的工作原理

上次在 blog 上写 Lua GC 是 2011 年,lua 5.2 尚未发布时候的事情了。我认为仔细研读优秀开源代码是非常值得做的事情,但把研读过程写出来却意义不大。代人咀嚼这事吃力不讨好,每个人的技术背景不同,写得过细浪费阅读时间,写的粗糙又会使读者不得要领。一行行读代码本就只是件辛苦活,任何人沉下心来都能做到,想通过别人代读而节省时间,多半是做不到的。所以我那本 Lua 源码欣赏 也就一直搁置了。

沉在代码的逐行细节中往往一叶障目,反不如高屋建瓴的理解一下作者的思想。今年的 lua workshop ,Lua 的主要维护者 Roberto Ierusalimschy 做了题为 Garbage collection in Lua 的演讲,很好的讲述了 Lua 历史各个版本的 gc 算法实现。我没有听这个演讲,但阅读 Slide 结合源代码基本可以搞明白。这篇 Blog 分享一下我的理解。注意:我添加了许多自己的理解,很可能和演讲原意有极大的偏差。所以本篇仅代表我的个人立场。

阅读全文 "Lua GC 的工作原理" »

September 20, 2018

动作游戏中的击打判定

最近在玩怪物猎人世界,断断续续差不多 100 小时了,加上之前花在这个系列上的几百小时,不敢说是个老猎人,忠实粉丝还是算得上的。

因为职业原因,我又琢磨了一下这类游戏的实现方法。在网上搜不到太多直接资料,所以这篇 blog 更多的是对自己的想法的记录。这次主要还是想理解一下游戏中是如何处理武器和怪物之间的击打判定的。

我知道动作游戏和格斗游戏侧重点不同,但也有类似之处。格斗游戏尤其是 2D 格斗游戏资料比较全,制作方法成熟,从网上能找到不少资料介绍原理。浅谈格斗游戏的精髓——方块的战争 讲的非常清楚。为了性能,也为了简化及明确规则,2D 格斗游戏用了若干 AABB 轴对齐的矩形来做击打/碰撞判定。格斗游戏会精确到帧来做规则判定,在特定帧勾勒出 hurtbox (惯例上用红色框)作为攻击范围判定;如果击打判定帧的 hurtbox 覆盖了那一帧对手的受击盒 hitbox (惯例用蓝或绿色框)区域,就认为击打有效。另外,还会设定出碰撞盒 collisionbox 用来避免和对手重叠,或和障碍物做碰撞检测。

阅读全文 "动作游戏中的击打判定" »

September 12, 2018

给 skynet 增加网络统计

skynet 在这个阶段的工作,主要是增强运行时内部信息的透明性。多提供运行时的统计数据可以为运维工作提供方便,也能为性能调优给出指导方向。

最近,我给 debug console 增加了 netstat 指令,以及提供了配套的 socket.netstat api 来获取这些数据。

这个指令可以获取 skynet 创建的所有 socket 的列表。每个 socket 归属于哪个 service ,每个 socket 上读写的字节数,最后一次读和写发生的时间,未写入系统挂在代写链表上的字节数。当然还有每个 fd 对应的 ip 地址和端口(如果是 socket )。如果是 listen fd ,会纪录 accept 成功的次数,

阅读全文 "给 skynet 增加网络统计" »

August 27, 2018

lockstep 网络游戏同步方案

今天想写写这个话题是因为上周我们一个 MOBA 项目抱怨 skynet 的定时器精度只有 10ms (100Hz),无法满足他们项目 “帧同步” 的需求。他们表示他们的项目需要服务器精确的按 66ms 的周期向客户端推送数据,而 skynet 只能以 60ms 或 70ms 的周期触发事件,这影响了游戏的“手感” 。

讨论下来,我认为,这是对所谓“帧同步” 算法有什么误解。我们客户端运行时不应该依赖服务器的准时推送消息才能得到(手感)正确的结果。虽然在 skynet 下你可以写个服务代替底层提供的 timer 来更准确的按 15Hz 发出心跳消息,但我觉得服务器依赖时钟的精确是游戏设计上的错误,提供 “手感” 完全应该是客户端程序的责任。

这篇 blog 就来写写基于 lockstep 的网络游戏同步方案到底是怎么回事。

阅读全文 "lockstep 网络游戏同步方案" »

Misc

Categories

Archives

Recent Comments