February 21, 2017

绕过 c api 直接访问 lua 表

今天试了一下一个想法:绕过 lua 提供的 C API 直接去访问 lua 的表结构,提供在性能及其重要的环境高效访问数据结构的方法。

例如:我们需要在 lua 和 C 中共享一个 vector 3 结构,有两种实现方法:一、把 C struct 实现为 lua 中的 userdata ,然后给 userdata 加上 metatable 以供 lua 中访问内部数据;二、在 lua 中使用一个 table 实现这个 vector3 结构,类似 { x = 0.0 , y = 0.0, z = 0.0 } 这样;然后在 C 里通过 c api (lua_rawget/lua_gettable/lua_getfield) 来访问里面的数据。

前一种方法会导致在 Lua 中访问成本加大、而后一种方法增加的是 C 中访问数据的成本。如果我们只在少数性能敏感的地方通过 C 去操作数据结构,那么第二种方法看起来更简单灵活一些。这样,不需要 C 介入的地方,是没有额外开销的。毕竟、通过 metamethod 索引 userdata 的成本比直接索引一个普通的 table 要重的多。

阅读全文 "绕过 c api 直接访问 lua 表" »

February 17, 2017

为什么 Windows 的文件系统会有盘符,使用反斜杠分割路径

今天同事在公司群里贴了张屏幕截图,上面有30+ 个盘。从 C: 排到 Z: , 然后还有 CC: CD: ,调侃问 Windows 能管理多少个盘。

图应该是 P 出来搞笑的,除去 A B 盘保留给已经淘汰的软驱用外,windows 超过 Z 盘后就不在能增加了。如果有更多储存设备,则需要用把设备挂接在空目录上(ntfs 支持)。

为什么 Windows 会有盘符这个诡异的东西呢?

按如非必要、勿增实体的原则,只用路径就够了呀。物理分区完全可以隐藏在文件系统之后,在 Unix 系的操作系统中,分区是用挂接点的方式挂接在虚拟文件系统中的(ntfs 其实也支持)。如果是为了方便记忆和保持用户习惯,完全可以把分区顺着挂接到 /c /d /e /f 下。如果你在 windows 下安装 mingw/msys 它就是这样处理 C 盘、D 盘 …… 的。

答案要从历史中找。

阅读全文 "为什么 Windows 的文件系统会有盘符,使用反斜杠分割路径" »

February 14, 2017

跟踪数据结构的变更

这两个月,我的主要工作是跟进公司内一个 MMORPG 项目,做一些代码审查提出改进意见的工作。

在数月前,项目经理反应程序不太稳定,经常出一些错误,虽然马上就可以改好,但是随着开发工作推进,不断有新的 bug 产生。我在浏览了客户端的代码后,希望修改一下客户端的 UI 框架以及消息分发机制等,期望可以减少以后的 bug 出生概率。由于开发工作不可能停下来重构,所以这相当于给飞行中的飞机换引擎,做起来需要非常小心,逐步迭代。

工作做了不少,其中一个小东西我觉得值得拿出来写写。

我希望 UI 部分可以严格遵守 MVC 模式来实现。其实道理都明白,但实际操作的时候,大部分人又会把这块东西实现得不伦不类。撇开各种条条框框,纸上谈兵的各种模式,例如 MVC MVP MVVM 这些玩意,我认为核心问题不在于 M 和 V 大家分不清楚,而是 M 和 V 产生联系的时候,到底应该怎么办。联系它们的是 C 还是 P 或是 VM 都只为解决一个问题:把 M 和 V 解耦。

阅读全文 "跟踪数据结构的变更" »

January 23, 2017

一个简单的 lua 对象回收再利用方案

昨天在 review 我公司一个正在开发的项目客户端代码时,发现了一些坏味道。

客户端框架创建了一个简单的对象系统,用来组织客户端用到的对象。这些对象通常是有层级关系的,顶层对象放在一个全局集里,方便遍历。通常,每帧需要更新这些对象,处理事件等等。

顶层每个对象下,还拥有一些不同类别的子对象,最终成为一个森林结构,森林里每个根对象都是一颗树。对象间有时有一些引用关系,比如,一个对象可以跟随另一个对象移动,这个跟随就不是拥有关系。

这种设计方法或模式,是非常常见的。但是在实现手法上,我闻到了一丝坏味道。

阅读全文 "一个简单的 lua 对象回收再利用方案" »

January 16, 2017

10 连抽保底的概率模型

网游里有很多抽卡、开箱子之类的赌性玩法,在最开始,游戏设计者实现的时候,仅仅给这些抽取概率简单的设置了一个值。比如抽卡抽出橙卡的概率是 10% ,那么就是说,玩家每次抽一张卡,有 90% 的可能是白卡,10% 的可能是橙卡。

但大 R 玩家是大爷,需要小心伺候。如果感受不好,人跑了就亏大了。概率这个东西靠改进伪随机数发生器是解决不了体验问题的,大爷要是连抽 20 张都出不来橙卡,那是要怒删游戏的。

连抽 20 张 10% 概率橙卡一张都抽不到的机会多不?一张抽不中的概率是 0.9 ,20 张都抽不中的概率是 0.9 ^20 = 12.2% 。这可不算小数字啊。平均 8 个大 R 就会碰到一次,一下子赶跑了 1/8 的金主,这个责任小策划可担当不起。

所以、一般网游都会用各种规则来避免玩家出现连抽不中的尴尬。例如,我忘记是谁发明的 10 连抽规则:如果你购买一个大包连抽 10 次,我在规则上就保证里面一定至少有一张橙卡。实现它应该并不困难,按常规概率生成 10 张的卡包,如果里面没有橙卡,那么我加一张即可。

阅读全文 "10 连抽保底的概率模型" »

January 14, 2017

豆豆的日常

云豆两岁的日常:

奶奶:10 点了,豆豆该睡觉了。

豆豆:要听咕哩咕哩。

奶奶:ipad 没电了。

(ipad 电量 1%)

豆豆:ipad 真没电了。

奶奶:听小兔子好吗?

豆豆:(拧开开关)小兔子不好听。(关上)

豆豆:ipad 没电了、手机也没电了、奶奶唱歌。

奶奶:唱什么?

豆豆:门前大桥下……

奶奶:我不记得歌词了。

豆豆:(唱)门前大桥下,游过一群鸭…… 不记得歌词了。

豆豆:奶奶唱,(唱)小燕子、 穿花衣,年年春天来这里~

奶奶:你不是会唱吗?

豆豆: 奶奶唱小燕子, 豆豆睡觉。

奶奶:(唱)小燕子 穿花衣 年年春天来这里~ Zzz...

豆豆:奶奶睡着啦。

January 08, 2017

在 Unity3D 的 Mono 虚拟机中嵌入 Lua 的一个方案

很多使用 Unity3D 开发的项目,都不太喜欢 C# 这门开发语言,对于游戏开发很多人还是更喜欢 Lua 一些。而 Lua 作为一门嵌入式语言,嵌入别的宿主中正是它说擅长的事。这些年,我见过许多人都做过 U3D 的 Lua 嵌入方案。比如我公司的阿楠同学用纯 C# 实现了一个 Lua 5.2 (用于在 U3D web 控件中嵌入 Lua 语言的 UniLua );还有 ulua slua wlua plua xlua ... 数不胜数。我猜测,a-z 这 26 个字母早就用完了。

上面提到的项目的作者不少是我很熟悉的朋友,我们公司现在的 U3D 游戏也由同事自己实现了一套差不多的东西。所以我曾了解过这些方案。但我一直觉得这些方案要么做的过于繁琐,要么有些细节上不太完备,总是手痒想按自己的想法搞搞看。

Mono 和 C 通讯使用 P/Invoke ,用起来不算麻烦,但是要小心暗地里做的 Marshal 的代价,特别是对象传递时装箱拆箱的成本。Lua 和 C 通讯有一套完善的 C API ,但完全正确使用并不容易。核心难点是 Mono 和 Lua 各有一套自己的异常机制,让它们协调工作必须很小心的封装两个语言的边界,不要让异常漏出去。我在 2015 年写过一篇 Blog 做过相关讨论

我认为简单且完备的 Mono / Lua 交互方案是这样的:

阅读全文 "在 Unity3D 的 Mono 虚拟机中嵌入 Lua 的一个方案" »

Misc

Categories

Archives

Recent Comments