盗賊の極意

Feed Rss

上一篇提到的“能编译通过这个 aseprite 软件(及格),能在IDE中下断点调试(良好),可能的话希望自己能修改软件的菜单,加入自定义功能(优秀)”。现在看来,我已经及格了(笑)。

附上 aseprite 的官方编译指南

aseprite_v1.2-dev

回过头来看我耗时十几小时的编译之战,真是教科书一般的犯下了几乎所有可以犯下的错误。幸好结果不错,让这些付出也显得有了很高的价值。

时间很晚了,我就不长篇大论了,直接上这次吸取的教训:

编译复杂度达到自己无法掌控的项目时,人家让你用什么版本的工具,你就一定要分毫不差的用那个版本,以免各个工具之间出现兼容性问题。

 

离月末还有些时间,工作上暂时还比较闲(很好!)。那么下一步,就是让这个项目能在IDE中下断点调试了。别看编译通过了,其实都是命令行调用visual studio的编译和链接工具直接生成exe的,至于能不能用IDE顺利编译运行这个程序,还真不好说呢 : )

 

---------- 2017/09/20 更新 ----------

八小时前,aseprite 的作者更新了他的编译指南,使用了更新版本的 skia ,现在用 vs2017 也可以编译了。我作为编译指南更新前一天刚踩了一圈雷的无辜群众,可能是这世上最后一个被 aseprite 和 vs2017 的兼容性问题坑了的人吧。

关于为什么更新前不能用 vs2017 编译,我的观察是,之前编译指南推荐的 skia 版本是 m55, 那个版本里的 gyp 代码比较老,对 msvs 的版本只能识别到 2015 。我记得 gyp 对 vs2017 的识别能力是2017年四月份才加入的,m55 最后的更新是 2016 年 10月,当然不能识别 vs 2017。更新后的编译指南推荐使用 skia 的 m62 版本,目前最近更新日期是2017年8月31号,解决了这个问题。

 

今天买了steam上的像素绘图软件aseprite,因为我们独立项目的美术素材都是用这个软件生产的。

因为我之前看过这个软件可以导出帧动画的json信息,所以希望它也能导出单幅图的图层信息,主要是各个图层的位置信息,以及使用的图在spritesheet上的位置。结果买来一用发现人家并不提供导出这些信息。

怎么办?我还指望靠这个能把美术做的大场景图自动导入unity呢!人少的小项目,各种自动化对项目推进速度影响很大的呀。于是我先看了看这个软件的文件格式,心想万一人家特别亲切,保存文件内是json呢?结果人家用的理所当然是2进制。慢慢扒这个文件格式对我们这种小项目来说投入产出肯定是巨亏无比,遂放弃。

第二步,我在asset store上搜了搜,看有没有人和我有同样的需求,而且已经写出了插件。结果还是没有,只有一个导出为动画的付费插件。唉,小众软件,不能期待过高。

最后我上github随便搜了搜,希望有人分析过这个软件的存档格式,最好是已经封装好的库或者软件。结果还是没有(想啥美事儿呢?)。。。但是,等等?!

aseprite-in-github

虽然没找到辅助程序,但是我找到本尊的源代码了啊!一个我花了1480日元买的软件竟然是开源的!

其实比起亏钱了,我更觉得是我赚到了。我可以深入了解甚至改造我们项目所使用的美术工具了,这是何等的牛B!

事不宜迟,赶紧找保存文件的格式吧。结果我在保存文件的逻辑中迷失了自我,原文件中的一切对我来说有如小天书一般,我甚至没信心只靠静态分析来找到关于保存文件内部格式的逻辑了。可下断点调试需要先搭建编译环境,看着我从来没用过的cmake,一时也是不知从何下手。那一瞬间,我感觉到自己离开C++阵营太久了。

其实cmake也不是最近几年才出现的新东西,把这份茫然归罪于太久没碰C++也是不妥。可能是,我在井里待太久,误以为自己C++已经十分了得,其实只是略懂编译链接运行,对C++11有了解,会写点有设计模式的业务逻辑的小爬虫而已。我以前总觉得底层这些都领悟到了,什么工具呀库啊框架之类的也就信手拈来了,然而见到人家用自己的框架写的代码逻辑时发现并拈不来呀并拈不来。

今年是我正式开始重视现有框架和库的一年,我恶补了一圈现役主流的网站前端后端和app开发常用框架和编程库,感觉受益颇多。接下来如果时间允许的话,我希望到这个月末为止,能补充一下C++方面的知识,至少做到能编译通过这个 aseprite 软件(及格),能在IDE中下断点调试(良好),可能的话希望自己能修改软件的菜单,加入自定义功能(优秀)。

经公司的天才美术推荐,这周末把《我的英雄学院》的动画补完(追到最新一集)了。之后改追漫画,发现动画现在连漫画的一半都还没画到,不错不错,存量这么充足,够我消化一个礼拜了,哈哈。

另外,很久没看新漫画,到现在才知道海外看热门漫画已经如此困难了。

我虽然国内有一台阿里云服务器,但上次搞坏了vpn服务器的配置,导致我现在没有很方便的方法翻墙回国内。平时因为有unblock youku这个大神器,我几乎没有翻墙回国的需求,所以修复vpn服务器总是提不起兴趣。这次也是,找到一个小漫画网站能凑合着看漫画了,就懒的弄阿里云了。

 

评论一下这部漫画,如果到贪婪之岛结束为止的《猎人》是5星,《一拳超人》是4.5星的话,这部漫画大概是3.5星的样子。

虽然有点对不住推荐这部漫画的天才美术(按他的说法这是部媲美《猎人》的神作),但至少这部作品我不会看第二遍,而《猎人》是让我重看了六七遍,《一拳超人》是让我重看了两三遍的作品,它们就是有那种“虽然知道每一处剧情,但还是愿意再看一遍”的独特魅力。《我的英雄学院》能让我一天追36集动画,外加等会儿可能会继续看一晚上的漫画,已经是一部很吸引人的好作品了。但这是一种“好想快点知道后面的剧情!”的新鲜感,就像很多游戏大作,我通一遍剧情之后就不会再碰了,但我依然认为它们是好作品。

当然我对“有重看价值”的评定是很独断专横的,和大众价值观恐怕有很大出入。一个明显的例子是,我玩《口袋妖怪》(《精灵宝可梦》)也只会通一遍剧情,之后就愉快的拿着卡去商店换别的卡玩了,而主流观点似乎更倾向于通关后继续刷精灵更有趣= =

本来觉得太短的感想不适合博客,想发微博的,但突然要我手机号实在是让人不爽。到我心情平复到能忍辱交出私人联系方式为止,短文章还是暂时发博客好了。
气死我了!不让人说话还行?

-- 本来想发微博的感慨 --

withings被nokia收购之后网站和app的图表界面就变得可用性超级差!本以为忍忍就习惯了,结果越用越窝火!真不知道该喷nokia health的产品经理无能还是设计师是废物,好端端一个withings品牌活生生被你做成垃圾。如果nokia这套界面还没有任何改进,等产品更新换代时我不会再考虑任何withings和nokia品牌的商品了!

具体碰的什么壁我只会在私聊里说,这里主要是记录一下这件事对我的影响。

现在我写程序的心态很功利了,感觉没有前途容易被淘汰的知识就不想碰。后来甚至有点成了不想做作品时的万能借口。毕竟不会被淘汰的多是超级底层的知识,而用底层知识是很难做出作品的。

我以前读过一个故事,讲的好像是一个程序课,老师让学生们自己做一个喜欢的动画效果。
作者本身程序写的不错,就用算法写了一些简单的图形的规则运动动画交了上去。
作品发表的时候,作者看到一个程序完全写不来的同学做了一个超级酷炫的动画,骷髅眼窝中滴出血泪,落在地上溅起血花。
他当时完全被震撼了!怎么做到的?!
事后他去看了那位同学的代码,里面是无数的颜色数组。原来是那位同学用像素数组把动画一帧一帧画出来的。
那位同学没有可以方便他开发动画的技术,但有一颗无论如何也要把这个酷炫动画做出来的决心。

且不说与android文档的天壤之别,就是nodejs这种小语言的文档也比ios这说了等于没说的文档强百倍了。

要么给源码,要么给文档,只给函数签名,我以为我在搞逆向工程呢!

记录一下最近的工作收获

1. 去年用chrome devtool extension给公司的页游做了一个辅助开发工具,结果一年来除了我都没人用= =。直到最近被engineer leader重新挖了出来,组内推广了一波,用的人多了一些,给发了个月度最佳工程师提名奖励(没入选T_T),感觉很棒。
其实这东西本身超级方便我调试bug(我在组内主要任务就是追踪各种难以解决的bug),所以我一个人用我也挺满足的。但有别人也开始用我做的东西而且非常满意,这种感觉还是挺爽的,漫画家收到鼓励的读者来信时大概也就是这种心情了吧。

2. 我开发了大半年的一个 ios / android 照相机应用核心库上个月实际投入使用了。首次上线应用的晚上我负责去公司参与值守。虽然这种事主要是靠服务器端,我客户端开发在场也没法当场修补程序,但当晚还是有一些收获的。因为这个功能是在动画播放的时候让用户用app开摄像头拍摄动画,然后app判断你现在是不是在看动画首播直播,是的话就发个奖品,所以动画开始时twitter上有爆发式的关于本功能的留言。负责算法设计的顾问在里面挑了几个称赞我们黑科技的留言,我看了有点感动。这也是一种类似于收到读者来信时的心情吧。
从第一个hello world到现在,我写程序已经10多年了,但至今为止都是在享受一个人解题的乐趣。在第一家游戏公司,因为做的游戏比较小众,我自己也不玩,所以没有在意过玩家反馈。在现在这家公司,总算参与到了日本顶级手游项目,但这次是因为我一直在做的是偏底层的开发和疑难bug追踪,没做过什么大部分玩家能感受到我的存在的工作,所以也没有什么我的作品有读者(用户)的感觉。因为底层代码和bug追踪本身都是对我来说比较有趣的工作,所以我一度以为我是不在乎用户鼓励的冷面工程师。但经历过最近的几件事以后,我还是不得不承认,有人在使用、在期待着我的程序的感觉,真的很美好,令人沉迷。

3. 亲人离开研究机构独立创业,期间我除了帮忙写程序老本行以外,还有申请域名邮箱、关联主机、做简单的首页,上周又帮忙给他们买来放在家里的服务器设计内网拓扑结构(其实就是把这台服务器和家里自用的局域网分割开来,防止主机被黑导致家庭局域网沦陷),开机启动sshd,开端口,创建账号给合作创业者使用等等。虽然都是简单的基础设置,但对不懂这些的家人来说真的是帮助非常大。

4. 为了确认编译好的release版apk内的各种api网址用的是production而不是develop环境的,领导让我反编译了自家的apk看看里面。我说每次出新版apk都要找gui工具手动反编译apk然后搜索这些网址字符串是否存在,这种重复工作咱们还是写个脚本自动化吧(潜台词是不要让我们enginner做这种无聊的重复性体力劳动),于是我花了两天读了一下 zip 格式android 的 dex 文件的格式以后,用nodejs的zlib解压apk,找出classes.dex,再解析classes.dex ,找出所有的字符串,最后在这些字符串中查看给定的 production 环境的 api 的 url 字符串是否存在。要自己用 zlib 解压 apk的原因是如果想使用其他开源的解压zip的库的话要向上层层申请,非常麻烦,最后跟领导合计一下反正也就1天的工作量,干脆都自己实现好了。
这个工作中我最满意的是自己用第一手资料解决了问题。之前自己读HTTP的rfc徒手写 http proxy server 时也是,读文档能力是最重要的。不过当时我看的rfc是别人翻译的中文版... 毕竟原版300多页英文,考虑到开发效率,还是偷懒看中文了 =w=

太久没欲望,就容易懈怠

能激起我奋发向上热情的事不多,其中,身边人的成功算是比较有效的一个。

image from http://sc-pj.com/shitto-seiko/

今天去老朋友笃志的博客看了看他的近况,依然是每日工作在技术挑战中,依然是注重着身体健康,变化的,是那不断攀升的薪水。

我从大学时代就对笃志提及的游戏行业薪水充满向往,这算是坚定我入行信念最大的几个原因之一。

之后我求职不利进入小公司打拼,虽然学到很多,但对低薪和没有加薪可能的不安让我在学到能入手的几乎所有知识之后迅速下定决心跳槽,最终误打误撞来到现在的某日本本土手游大厂。

回过头来评价当初那段时间,我对自己及时果断的跳槽决定感到满意甚至感激。毕竟对我这样一个不喜欢冒险,安于平静稳定的技术工作的人来说,下定决心切换身边的生活环境并不是一件简单的事。

如今,我已经在现在这家大厂工作两年了。我很庆幸获得上司的赏识,帮我推掉重复性的体力劳动,让我专门负责各种技术密集的工作。可手游,尤其是页游方面能涉及到的技术密集型工作实在是非常有限。有些周期性出现的技术性工作做久了对我来说也变成重复性的体力劳动了,可对其他人来说依旧是无法接手的困难,结果就是我的工作中重复性工作也渐渐增多,只有在被外借出去帮别的项目开发核心功能时才有机会重新接触一些新知识。这样无法提升自我的工作内容,如果放在原来的小公司,我一定是会以跳槽来避开的。可在这家公司,为什么我却没产生跳槽的冲动呢?

我说服自己接受这样清闲的“退休生活”,把技术追求留在回家以后。可没有跳槽的压力,我连回到家的学习动力都没有了,回家以后也是一事无成。

 

除去害怕改变环境等可以被克服的心理压力外,落入这样被动的窘境主要是因为,欲望被满足了

 

今天看过笃志博客后重新燃起的欲望之火,我要好好培养

最近被一个android大量数据计算过程的提速问题困扰了一个星期,在尝试了各种办法之后,最终拜倒在了GPU的强大运算力面前。

 

我尝试过的实现一共有三种。

1. 平铺直叙的单线程java实现

这个主要是为了快速实现逻辑,用来检验代码正确性的,效率不是他需要考虑的问题,所以慢一点我也没什么意见。

 

2. jni调用C++,越过JVM,在native层实现运算逻辑

一开始实现完发现比java版快了10倍,顿时对native的效率赞叹不已。但之后总感觉哪里不对头,因为我记得java比C++只慢一点点,差距绝不会是一个数量级那么多。

后来检查发现是实现有误,纠正后整个运算竟然比java版还稍微慢了一点点。原因可能是java版里使用了android自己的jni版RGBtoHSV函数,而我无法从NDK平台直接调用android内置的实现,所以找了一个native版的实现,这个实现比java版慢了。

不管怎么说jni比java慢还是太反直觉了,可是用android-ndk-profiler测了一圈也没看出什么异常来,似乎纯粹的数字运算就是要耗费这么多时间。

这里需要强调的是,我的整个运算过程只调用了一次jni函数,慢不是因为频繁的跨语言通信导致的。

 

3. 借用GPU的力量进行运算。android平台强大的renderscript

实在不行就试试GPGPU这招我一开始就想到了,但是没想到实现起来会这么方便。这里真的要给android平台点个赞。

说来惭愧,游戏行业从业三年,我的3D编程能力还仅停留在对照教材实现示例的程度。本来这次都做好了3天入门OpenGL的打算了,没想到android自己内置了直接使用GPU的能力。启动运算传递数据的过程都可以直接从java中做到,我只需要额外学一个用来在GPU中执行的renderscript文件的写法就可以了。而这个renderscript语法类似C语言,比swift还好学啊。

renderscript最大的坑在于从出现到现在写法有变动。本来指导教程就少,里面还有很多已经变成了错误示范,无形坑人,最为致命。在跨过了这些教程坑以后路就平坦多了,业务逻辑的移植和结果验证一天搞定。

需要注意的是,renderscript本身并不保证一定会使用GPU,老版本的android好像只会用多线程CPU实现代替。不过我们项目的目标平台API LEVEL够高,不用太在意这个问题。

还有一点要说的是,renderscript目前只能做互不相干的大量运算,而像累加求和啊求最大值最小值之类各个运算结果之间会互相影响的密集计算要等android 7.0(API LEVEL24)以后才能支持,而且直觉上来说也不会有纯粹无关的运算那么快,不能过高估计他的效率。

 

以上,android版的优化总算是有惊无险的完成了。之后要研究iOS平台的同类问题,可能还会再写一篇总结。

其实我已经稍微调查了一下,遗憾的是iOS上似乎并没有android的renderscript这么方便的GPGPU支持,那到头来我还是要去入门一下OpenGL了,唉。(咦?我怎么还有点小高兴?!)