在游戏开发过程中,经过遇到一些想要配置一些变量,但是又是比较零碎的。比如一个用户最多3次免费机会修改昵称,再之后需要花100钻石来修改。这中间就有两个值会可能需要调整,3次和100钻石,策划可以改成2次和50钻。

不太好的做法

最不好的做法

直接硬编码3和100,回头都不知道谁是谁。

前后端各自写常量

这种在不修改的情况下,其实都是顺顺利利的,一修改,忘了另外一端,就经常可以出问题。

比较合理做法

将它们配置到配置表去,两个字段key和value,然后一行一行组织下去。比如

1
2
3
4
5
6
7
8
9
key value comment
键,约定好,不得修改,前后端代码会使用到 值 注释
string int string
max_lv 100 最大等级
max_vigor 999 最大体力
init_vigor 200 初始体力
vigor_interval 360 体力恢复时间间隔,单位秒
init_gold 1000 初始金币
init_diamond 1000 初始体力

配置其实还是蛮容易理解的,但是怎么在Erlang来处理呢。

方法一,生成一堆define

我们开发定义常量也是这种方法,这种方法有个弊端,修改一个变量,所有include了这个hrl的erl都要重新编译,所以总觉得不舒服。因为这是通用的常量配置表,所有erl都会用到,一更改,就整个项目重新编译。

所以,不考虑这个办法。

方法二,生成get函数

1
2
3
4
5
6
7
get(max_lv) -> 100;
get(max_vigor) -> 999;
get(init_vigor) -> 200;
get(vigor_interval) -> 360;
get(init_gold) -> 1000;
get(init_diamond) -> 1000;
get(Val) -> lager:warning("get not find ~p", [Val]), [].

这种做法,更改了,只会编译它自己本身,不失为一种办法,但是唯一不足的地方,就是要匹配查找,比起define直接替换,可能会慢一点。

方法三,生成对应函数名

这是我在做饭的时候,无意联想到,其实早就用这种方式表示过常量,mochiglobal。但是只是一时间没有将它和配置表联系上。

1
2
3
4
5
6
7
8
9
10
11
max_lv() -> 100.
max_vigor() -> 999.
init_vigor() -> 200.
vigor_interval() -> 360.
init_gold() -> 1000.
init_diamond() -> 1000.

我们将配置表那些key弄成函数名,value弄成返回值。这样使用起来就避免了get的匹配查找了,而且可以用引用查找undef情况。

其实,怎么实现就看各家的工具,我们用的基于ast的表示,稍微修改就可以了。

题外话