http://www.nwn2toolset.dayjo.org/ToolsetTuts/conversations/writingconvos.html
https://twinery.org/
http://www.inklestudios.com/inklewriter/
http://www.nwn2toolset.dayjo.org/ToolsetTuts/conversations/writingconvos.html
https://twinery.org/
http://www.inklestudios.com/inklewriter/
手机上的聊天:有语音SDK,可以语音文本互转。也有语音SDK直接支持自建语音频道。
有文本翻译API,可以翻译为多国语种文字:https://www.microsoft.com/en-us/translator/home.aspx
各种翻译,目前已知的商业API有微软的,百度的,行云的,另外还它一些商业API提交翻译功能。
微软的 MicrosoftTranslatorAPI 可以检测出使用的语种。
自己之前写的在java服务器上使用导航网格寻路的库。
底层使用c++提供接口,java层通过jni调用c++接口。
https://github.com/zhukunqian/unity_navmesh_for_java
更多信息直接在github上交流吧。
安利一下云风写的公式计算器
http://blog.codingnow.com/2012/10/dev_note_27.html
方便简单,超级好用。
udp传输在手机网络环境下,比tcp可以获得更小的延迟。
以后游戏考虑引入udp。
推荐两个:
https://github.com/cloudwu/rudp
关于网络同步的一篇文章: http://www.skywind.me/blog/archives/1343#more-1343
另外还确定一件事情。
如果要获得最好的用户体验,客户端必须实现不会因为等待某个消息返回而处于停顿状态。
这里要求开发时要支持消息非顺序到达。
非顺序到达可以,可以先放入一个消息队列中,然后等待丢失的消息到达。但似乎逻辑处理起来,还是需要按消息顺序处理对开发人员更方便。
1、网络层消息可以非顺序到达。
2、业务逻辑按顺序处理消息。
上个项目使用的syslog,发现效果很不错,也希望在skynet中添加syslog模块,顺便也搜索一下使用c为lua编写独立模块。
参考了一下skynet原有crypt模块的代码和lua文档,写的lua-syslog.c如下:
#include <syslog.h> #include <lua.h> #include <lauxlib.h> static int lsyslog(lua_State *L) { size_t sz = 0; const char * text = (const char *)luaL_checklstring(L,1, &sz); syslog (LOG_INFO, text); return 0; } int luaopen_syslog(lua_State *L) { luaL_checkversion(L); luaL_Reg l[] = { { "log", lsyslog }, { NULL, NULL} }; luaL_newlib(L,l); return 1; }
代码量并不大,非常合适我这种已经N年不写C代码的人。
使用make编译出syslog.so模块,放出的Makefile只供参考,因为和项目目录存放关联密切,并不是直接COPY就可以使用。
PLATS = linux macosx .PHONY : $(PLATS) all clean skynet CC ?= gcc PLAT ?= linux linux : PLAT = linux macosx : PLAT = macosx GSHARED = -fPIC --shared CFLAGS = -g -O2 -Wall -I$(GLUA_INC) macosx : GSHARED := -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup linux macosx : $(MAKE) all PLAT=$@ GSHARED="$(GSHARED)" GLUA_INC ?= skynet/3rd/lua GLUA_CLIB = cjson syslog GLUA_CLIB_PATH ?= skynet/luaclib all : skynet \ $(foreach v, $(GLUA_CLIB), $(GLUA_CLIB_PATH)/$(v).so) $(GLUA_CLIB_PATH)/cjson.so : | $(GLUA_CLIB_PATH) cd 3rd/lua-cjson && $(MAKE) LUA_INCLUDE_DIR=../../$(GLUA_INC) CC=$(CC) CJSON_LDFLAGS="$(GSHARED)" && cd ../.. && cp 3rd/lua-cjson/cjson.so $@ $(GLUA_CLIB_PATH)/syslog.so : 3rd/lua-syslog/lua-syslog.c | $(GLUA_CLIB_PATH) $(CC) $(CFLAGS) $(GSHARED) $^ -o $@ skynet : cd skynet && $(MAKE) CC=$(CC) $(PLAT) clean : cd 3rd/lua-cjson && $(MAKE) clean cd skynet && $(MAKE) CC=$(CC) clean
测试代码:
package.cpath = "luaclib/?.so;" .. "../luaclib/?.so;" .. "../../luaclib/?.so;" .. "../../../luaclib/?.so;" .. "../../skynet/luaclib/?.so" local log = require "syslog" log.log("moon1 hello") log.log("") log.log("helloworld")
关于如何打开syslog及查看syslog,就不在这里多累述了,相信了解syslog的朋友已经对此很熟悉了。
如果使用mac os:
使用以下命令停止syslog launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist 使用以下命令启动syslog launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist
接收log的服务上的配置,仅供参考。
$EscapeControlCharactersOnReceive off $template TraditionalFormat1,"%msg:R,ERE,1,DFLT:[0-9a-zA-Z]+ (.*$)--end%\n" if re_match($syslogtag,'^game[0-9_a-zA-Z]+\\[[0-9]+\\]') then { $ActionFileDefaultTemplate TraditionalFormat1 $template DynFile1,"/opt/logs/skynet-log/%syslogtag:R,ERE,1,DFLT:([0-9a-zA-Z]*).*--end%/%timegenerated:1:10:date-rfc3339%/%syslogtag:R,ERE,1,DFLT:([0-9a-zA-Z]*).*--end%-%msg:R,ERE,1,DFLT:([0-9a-zA-Z]+)--end%_%timegenerated:1:10:date-rfc3339%.log" *.* -?DynFile1 stop }
后记:
最初想法是直接向本系统的syslog发送消息,然后使用syslog用udp转发至日志服。
进行压力测试时,发现在macos上syslogd有 -mps_limit
限制,默认是500/s, 用户进程默认是36000/小时。超出的消息直接丢弃掉了。
Mar 30 11:01:20 localhost game1[45275]: game moon1 2016-03-30 11:01:20 DEBUG hello world 36039 1459306880.61 Mar 30 11:01:20 localhost game1[45275]: game moon1 2016-03-30 11:01:20 DEBUG hello world 36040 1459306880.61 Mar 30 11:01:20 localhost game1[45275]: *** LOG MESSAGE QUOTA EXCEEDED - SOME MESSAGES FROM THIS PROCESS HAVE BEEN DISCARDED *** Mar 30 11:01:21 localhost game1[45275]: game moon1 2016-03-30 11:01:21 DEBUG hello world 56029 1459306880.99 Mar 30 11:01:21 localhost game1[45275]: game moon1 2016-03-30 11:01:21 DEBUG hello world 56030 1459306880.99
转至linux上测试,也有相同的限制,想想也是合理:
Mar 30 11:18:13 iZu1fh2yq8yZ game1: game moon1 2016-03-30 11:18:13 DEBUG hello world 999 1459307893.8 Mar 30 11:18:13 iZu1fh2yq8yZ game1: game moon1 2016-03-30 11:18:13 DEBUG hello world 1000 1459307893.8 Mar 30 11:18:13 iZu1fh2yq8yZ game1: game moon1 2016-03-30 11:18:13 DEBUG hello world 1001 1459307893.8 Mar 30 11:18:43 iZu1fh2yq8yZ journal: Suppressed 320255 messages from /user.slice/user-0.slice Mar 30 11:18:43 iZu1fh2yq8yZ game1: game moon1 2016-03-30 11:18:43 DEBUG hello world 321257 1459307923.32 Mar 30 11:18:43 iZu1fh2yq8yZ game1: game moon1 2016-03-30 11:18:43 DEBUG hello world 321258 1459307923.32
再测试一下直接使用udp发送至远程日志服务器:
1、查看了一下syslog中并没有提供函数可以直接udp远程进行发送,文档也说的很明白,如果要远程发送需要自己使用tcp或udp发送。
2、查看了一下syslog的udp协议,也很简单,正好skynet中支持udp,连c库都省的写了, http://tools.ietf.org/html/rfc5424
function test3() local c = socket.udp(function(str, from) print("client recv", str, socket.udp_address(from)) end) socket.udp_connect(c, "10.230.10.102", 514) for i=1,20 do socket.write(c, "<190>1 2003-10-11T22:14:15.003Z HOSTNAME skynet 11 MESSAGTEID A " .. i) -- write to the address by udp_connect binding end end
rsyslog中的系统属性列表:http://www.rsyslog.com/doc/v8-stable/configuration/properties.html
使用udp连续发送100万日志,发送砂时18秒左右。7万/s 日志,可以接受。但发现UDP有丢失包的现象。
内网也会丢包~~,为了确认使用:tcpdump udp port 514 > 1.log 将收到数据包记录下来,然后进行对比,发现,确实在网络一层丢失包。继续测试tcp ~~~
继续改为tcp测试一下。
tcp文献索引:http://tools.ietf.org/html/rfc3164
发送和udp有一点不同,需要在消息结尾附带 \r\n表示一条消息的结束。
测试发现,竟然达到了10万/s 日志的性能,-.-!! 而且没有丢包。
找到几篇文章,学习如何配置sublime开发unity。
1、http://blog.zephyr-ware.com/unity-and-sublime/
2、http://www.radjor.com/blog/p/65
实测OK,也挺好用。
1、关闭alpha通道:
convert source.png -alpha off dest.png
2、生成遮罩图:
convert moon.png -alpha extract alpha_extract.png
测试:
1、原始, 195.997M 2、一个png转为两个png,其中一个大图未选择压缩,max size4096。 198.270M 3、一个png转为两个png,选择压缩,max size4096。 194.509M 4、一个png转为两个png,选择压缩,max size修改为2048。 没有任何变化,连生成的大小都是相同的。 5、两个png使用pngquant压缩后再试。max size 2048。 194.522M 晕,竟然还变大了。 6、两个jpg。使用tinyjpg压缩。我CAAAAAAAAAAAAAO,竟然是201.184,竟然还变大了。(发现,自动选择的是true color,没有选择compress) 7、两个jpg。使用tinyjpg压缩。都选择上compress。194.798M。 最好的方式应该是不压缩的png选择compress。估计unity内部自己也有优化。 pngquant压缩后大小和tinypng压缩后大小差不多。 tinyjpg也很有用。压缩比也很高。
之前了解过,开发游戏项目,客户端使用svn,git管理并不合适,因为图形资源过多,而他们对二进制文件管理比较差,国外项目组用的比较多的是perforce,这里记录下创建perforce服务器的过程,以后如果有需要可以翻出来查看。
1、添加repo源:
安装pubkey:
sudo rpm --import http://package.perforce.com/perforce.pubkey
编辑: /etc/yum.repo.d/perforce.repo
[perforce] name=Perforce baseurl=http://package.perforce.com/yum/rhel/6/x86_64 enabled=1 gpgcheck=1
2、yum search perforce,可以看到所有相关的安装包。
安装服务端:
yum install perforce-server
3、运行p4d服务器端
p4d
如果不指定-r参数,则默认p4的根目录为执行命令的目录。
4、第一个连接的用户为superuser,我们修改默认用户的密码
1) 使用 p4 -p 127.0.0.1:1666 protect,第一次连进去后会默认生成一个权限配置文件。
2) 退出后,使用 p4 -p 127.0.0.1:1666 passwd 修改当前superuser的密码
5、p4默认用户在第一次连接时会自动创建,我们设置禁止自动创建用户
6、禁止自动创建用户后,使用以下方式创建用户及设置用户密码(别忘记了先使用p4 login进行登陆,因为上一步修改了当前用户的密码)
1) p4 -p 127.0.0.1:1666 user -f username
2) p4 -p 127.0.0.1:1666 passwd username
7、设置服务器的安全等级:
这里至少要修改为安全级别为2(或更高)
8、给用户分配权限。这里使用权限组进行管理。
使用命令:p4 -p 127.0.0.1:1666 protect,修改权限分配。
9、将用户添加至用户组:
使用命令:p4 -p 127.0.0.1:1666 group groupname,修改User那一行。
10、创建p4client,注:client与workspace是同一概念。
这里特别注意是创建的是view,指定了自己本地的工作目录与p4 server上目录的对应关系。如果写错误或权限不足,会有log提示。我在这里卡了半天时间。
2015年8月31日晚上8点整,GM反馈有海外玩家无法登陆游戏了。
最终排查后的结果:
域名被GWF给墙了 -.-!!
客户端中只使用了域名取一个配置文件,配置文件中存有各个服务器的真实IP之类的数据。
这个域名无法访问后,直接导致客户端在第一步直接卡掉进不去。
暂时的临时解决方法是使用dns智能解析,将海外用户dns解析至一台海外服务器上,暂时避免掉这个问题,但不保证100%解决所有海外用户的问题,因为dns智能解析也会误判一些用户。
这里想了一下以后的对策:
1、客户端首先应该使用ip进行获得,ip比域名少了解析的一步,要快。
2、如果IP读取失败,则使用域名再进行访问,这样可以避免掉如果IP出现问题后,玩家无法正常玩游戏。
3、如果有条件,在第一步时可以准备两个IP,基本一个IP备用。最多2个IP一个域名基本上能100%的解决掉所有问题。
后记:2015.09.02 突然想起来:可以直接使用一个主IP,一个备用IP,还有域名,三个连接同时去访问,最早返回的并且成功的数据取过来用。这样也可以实现起来更简单一些,而且比上面串行的被动等超时,要好很多。唯一需要确认的是:手机是否支持同时发出多条http请求。
近期评论