2018.6.7

 • 

我的签证果然没有在武汉飞旧金山的航班飞走前结束审查。我发了十几封催签邮件,给 DOS 打了几次电话,甚至想着如果 WWDC 开幕式前一天签证下来了我就直接定北京到圣何塞的机票还能赶得上发布会,结果也没发生。
所以这就是我大学的第一个 WWDC 奖学金,也是最后一个,也是压根就没去成的一个。有点无奈,但也没办法。去不成自然会错过很多机会,少面基很多人,但是这个世界又不是绕着我转的,而且我还有其他事情不得不忙。
五月份筹备 WWDC 的行程时发现和毕设答辩撞了车,结果导师人很好让我可以提前答辩,因此提前准备了很多东西,结果签证没有如期发下来,最后我还是跟着大家一起正常答辩,也就是昨天下午。对别人来说答辩完就是大学结束了,对于我来说还有三门要考的试。啊不管怎么样算是告一段落,等真正毕业后估计还要写四年的所见,暂先不表。


五月底又打了把 hackathon,湖南大学办的华中 HHHackathon。和李霖及李霖的女朋友组队,基于 CoreML 和 ARKit 弄了个简单的三维维基百科,最后拿了第二和京东单项奖。
作为一个好歹在国内 hackathon 组队拿过六七次前三名的半职业打手(误),我觉得还是有点资格评判下湖大这次的组织和流程的。总而言之,湖大是把 hackathon 当成校赛来办。
校赛意味着两件事:第一是学校牵扯其中,自然会有很多学校的特殊规定,如不让人擅自离场吃饭(只能吃会场内的盒饭),不让人回宿舍睡觉,当然这些是出于学校对安全的一些硬性要求,情理上也能理解,但如果外加场地条件很差就是个灾难了,本身第一次办 hackathon 的组织都会对网络估计不足,这次也一样,外加晚上强制让睡会场,还好我们队不管规则纪律晚上照样回自己家休息了(毕竟不是湖大的学生,也处分不到我们头上),不然估计要和其他人一样在会场喂蚊子。这第二呢,就是校赛自然有很多说不清道不明的东西,比如有的队伍提前一周就开始开发了,主持人还说既然题目有公布,这种事情自然是允许的;比如有的队伍自带湖大的带队老师;比如大部分队伍的实现程度都没有到代码的程度,然后看到了熟悉的墨刀流(做个原型说自己有成品之流);比如赛后的官方新闻稿全篇都在说第一和第三名两个湖大的项目,第二名反正不是湖大的一笔带过,这对于学校宣传来说自然是无可厚非的,但既然是 hackathon 基本的平台中立还是要有的,学校可以单独发新闻稿,但是把参赛的包括武汉和南京远道而来的大家都裹挟到一篇只提到湖大自己的文章里面一笔带过就有些让我不太爽了,不过考虑到这个比赛也许就是按照校内比赛来办的,倒也是能说得通。只是我不太喜欢吧,毕竟这次比赛可是套着 hackathon 的头衔,然而只学到了 24 小时现场编程这个规定,而没学到真正让 hackathon 成为 hackathon 的东西,总让我们这些人感觉是到贵校“万国来朝”的,仅此而已
写完觉得还是说的有点刻薄了,毕竟话说吃别人的嘴软,但事实也就我描述的这样,外加我的确很反感校赛,这个不满的情绪怕是从大一就开始积攒了。我讨厌各种华而不实的校赛,讨厌各种吹上天的 PPT 和 BP,讨厌拿墨刀原型当成品,讨厌校内带队老师和评委之间说不清的照顾,讨厌纯学生组队没有带队老师的无力感,就这样


我把 Cetacea 开源了。实在是没精力折腾下去了,之前选用的 Bundle Based NSDocument,正则做 MD 解析外加 iCloud 的方案现在看起来有点蠢,不如等后面从头写一个基于 CMark,不管文件同步而是纯编辑器的小项目,再慢慢拓展,不然对于这种较大的 macOS 项目我现在仍然没有足够的能力去理清头绪,更别提两年前开始这个项目的时候了。

然后 Lonely Planet 被出版社发邮件说商标侵权后我自己 take down 了相关的各种东西,包括上架了的软件和相关视频,这几天估计会以 Epoch Core 的名字重新上线,内容还是一年前的 Epoch Core,而最近在 Epoch 上取得的进展估计要到七月底才有时间往 Core 里面整理了。

接下来就是 Skyline。因为毕设和之前一个一言难进的外包,Skyline 推迟了很多次更新,最近会关注下了。基于 Unity 2018.1 轻量级渲染管道和 Marklight 实现 UI 的版本估计会在六月底发包,然后等 Unity 出纯 ECS 的超小引擎包(参见 Unity at GDC - ECS for Small Things)的时候我再迁移上去,但是 Mapbox 的 C# SDK 还不知道会什么时候迁移到基于 ECS 的架构上去(说到这个他们公司之前和我接触了下但是我貌似忘了回邮件了 -。-),因此要这么做的话我还要自己写一个基本的请求层实现,那么要做的工作和我基于 LibGDX 重写的 Skyline GO 已经差不多了。总而言之,一个因为一开始脑抽用了 Unity + Android 的混合架构所以我目前还是不太想碰的老 code base,和目前还是烂摊子的重写计划,哪一个都不是个容易的事情。但我总觉得不能赚了一笔就跑路,虽然我事实上估计已经是了(


买了个 iPod Classic 6th gen,塞了很多音乐进去。最近听了 Soulection Radio Tour - Live at the El Rey Soulection Radio Show #343Coral City | Vol. 1Road TripBack to Life,此外看了一个有趣的视频 Evolution Simulator

美签面试经过

 • 

(之前我的 MBP 15 被我打翻一杯奶茶泼上去了,因此陈叔陪着我先带 MBP 去了 Apple Store 修,然后吃了饭下午就去美签的地点。)

排了一会队,录了指纹,然后被分到一个女面试官前面。我前面的一位女性在面试的时候靠的离玻璃特别近,当时还纳闷为什么这么近,后来才明白 —— 这位面试官声音特别小,不靠近根本听不见。

面试官:你好
我:您好
面试官:请问您来美国是做什么
我:去参加苹果邀请的 WWDC 会议
面试官:文件出示一下
(面试官收下 visa letter 看了会,然后继续看终端屏幕 )
面试官:ZHANG PENG 是谁?
我:我的同行人
面试官:您准备呆几天?
(我没听清)
我:Pardon?
(面试官用英语重复了下)
我:About 7 or 8 days
面试官:您的行程单
(我只给了行程单,但是忘了给机票订单了。面试官看了下行程单,和 visa letter 一起收了起来)
面试官:您的费用有谁来负担?
我:机票是由我父亲提供的,门票和住宿由苹果公司提供。
面试官:你和 CENG JI SHAN 什么关系?
(我:??????)
我:抱歉,能再说一遍吗?
面试官:你和 CE JI SHAN 什么关系?
(如此总共反复了两次中文,一次英文,说英文的时候我才明白面试官说的是我父亲,但是我父亲明明姓 ZHENG,后面的名也读得差强人意)
我:(英文)他是我父亲
面试官:他住在美国吗?
我:不,他住在中国安徽省
面试官:好的,我需要临时离开下
(面试官离开工位差不多两分钟,然后带了一位白色制服男性过来,两个人在聊着我的材料,然后翻看我的护照(我是白本),大约有三分钟)
(面试官将我的行程单,visa letter,护照用橡皮筋捆在一起收在了她那边,然后拿了张黄色纸在上面画了个叉)
面试官:您好,这是您的结果,请稍等三到四天,谢谢!
然后我就拿到了一张 (g)221 行政审查单。
总觉得自己的表现有些窝囊,以及自己的说话习惯太简略了,这种情况下反而不利于自己。不过护照被收走了也没办法重新申请面签了,只能耐心等待。尚不知道能不能在 WWDC 开幕(和我的航班飞走前)前通过审查拿到护照。

2018.4.28

 • 

WWDC Scholarship

获得了 WWDC 奖学金,今年可以实地去看 Keynote 了。预约了五月初的面签,机票也定了,武汉飞旧金山。除了不确定的期末考试时间以外基本都有准备了。

今年的提交作品其实和去年一样,是一个使用 Noise Map 生成高尔夫球场的高尔夫游戏,至于有什么区别,估计最大的就是我在生成地形的某个步骤之间添加了一个 Thread.Sleep() 罢,如此在较新的 iPad 上获得的结果便是正确的。这看起来像是一个苹果的 bug,我也的确提交了 radar,结果是工程师判断和之前的 radar 重复,但是自去年至少一年过去,这个问题仍然没修,就有点迷了。
对这个 bug 好奇的同学可以去搜下 openradar 上的 #39027796,具体内容是:对于 SceneKit 内的一个 SCNPlane 来说,如果改变其 SegmentWidth/Height,其 vertex 数目是没有立刻更改的,这对于过程生成的计算真的是一个比较严重的问题了(

Lonely Planet

Lonely Planet 目前已经从 Google Play 和 App Store 下架,包括 Youtube 上的宣传视频也暂时私享。原因是 Lonely Planet 商标的注册公司(卖杂志的那个)说我的软件侵犯他们的商标,而我没有十足的把握怼回去也没有足够的经历准备材料,就先下架求个安宁。后面 Lonely Planet 会直接用 Epoch Core 的名字重新上架。至于 Epoch,目前我在基于 Epoch Core 做 Google Earth 为题的毕设,Epoch 本身完工只能说是遥遥无期。不过在做毕设的过程中倒是发现了一个很像 vuejs 的 Unity UI 库:MarkLight,最近在基于这个库封装一些组件。

2018.4.20

 • 

学校

体育分数被教务系统弄丢的事情之前写了校长信箱,回信也不尽人意。回学校后需要继续去找老师处理。

比赛

上海宜家 hackathon 第一名,1.5 万欧元孵化器奖金。和队友做的是 2015 年 fix++ 的宜家版。

毕设

因为一个一言难尽的学校相关事情,毕设进度拖了一些,不过技术上直接拿 Epoch 肯定能毕业了,主要是纸面上的内容(论文,报告),抓紧下应该也没问题

21

 • 

21 岁的第一天因为吃了不卫生的饭店,发烧又拉肚子。

想了想自己的 20 岁,大部分时间是在焦虑和压抑,以及因此而产生的要发泄的怒气中度过。也没有生产太多有价值的东西,大部分时间都在看,看人与人之间的冲突,利益各方暗自的角力,过于懈怠和过于热情的奇怪的人们,因为钱而撕破脸的冲突,团队的聚和散,意气风发的光景和陷入绝地的状况。
而我也足够幸运,做了一些比较正确的决定,虽然事情仍然缠身,但尚不至于没有出路。至于选择本身,有的时候没有选择比有选择看起来还更好些,会少却很多顾虑和念想。
很多时候不想说模棱两可的话,但一旦指名道姓说出去又会得罪人,因此各种平台上也不怎么活跃了。
秉承着一贯模棱两可的状态,总结下自己的 20 岁(或许还有前面几年)里学到的东西:

关于钱
我对钱一贯的看法就是,在没有足够的钱之前谈钱的虚无是很荒谬的。我还记得村上春树在哪部小说里写到“天生丽质的女生可以说自己今天不好看而不愿意出门,但资质平平的女生这么说就会被人笑掉大牙”。这句话描述出来或许有些政治不正确的意味,但事情就是这样,钱也同理。

关于价值
创造价值在很多时候约等于赚钱,因此从某种功利的角度说来说提供了一个支持创造价值的观点。理想的状态是一个人创造他所爱的价值,然后通过创造的价值兑换和消费其他人创造的事物。
提防拿着实现人生价值的口号却让他人从事批量生产的人。

关于学校
这里对学校的定义是:国内的国家认可的高等教育学府。
学校和企业其实并无二样,学校只会做对学校整体最好的事情,至于个体的发展并不是学校所关心的,公司会有的利益相关,僵化死板,学校也会有。
但在某些方面,学校相较于企业能造成的破坏更甚,因为学校曾经在道义上负担着某种高尚的责任,学校一般也乐意去接受这种高尚的赞美,即使在背地里这种高尚是被当着面砸碎给学生看的,称之为:进入社会前的准备。

2018.2.9

 • 

事情接连变多,感觉有点撑不住。七号喵喵生日,忙里偷闲跑去给喵喵庆祝了一下,过了开心的一天,结果回到家第二天自己又感冒了。不过总的来说这几个月能把这些事情做完的话,我的六七月份将会特别轻松,也算是值得的。

自己的壁纸软件从一月五号正式上架到现在收入为一万四千多美元,收入趋势就是典型的“爆红曲线”,在榜单前十留了一周以后迅速掉落,原因主要是关于性能和兼容性的,自己没有做好 Unity 部分的优化和 Android 众多版本的适配,现在事情一多也没办法迅速迭代了,更别提用 LibGDX 重写。不过我还是挺满意这一次的意外之财的,让我看到了在海外市场卖软件/游戏的可能性,不出意料 Epoch 应该就是下一个被发布的产品。

回到家的生活就会多很多无谓的时间被浪费,特别是临近春节更是如此。但既然是可见的三年内剩下的最后一个寒假了,也是想多陪一下家人,毕竟今年已经知道好几位老人走的消息了,谁也说不好后面的事情。

村上春树新小说的译文版开卖了。考虑回到学校以后买一本看看。

2018.1.25

 • 

凌晨四点,准备睡了,不过赶上电脑系统更新,索性在更新结束前更新一篇日记罢。
回家之前被学校的事情折腾得很绝望,然后临近回家的时候知道了肯定要延期毕业的事情,心情反而平静了些,想着就要回家了也暂时不再烦了。而且之前谈的有个报酬很丰厚的外包,就等着寒假开工。
回家之后事情的发展出乎我的预估,Skyline 直接冲到了 Google Play 总榜第二连续好几天,当时还和谦哥说赚了一千刀很开心,结果只当天晚上就突然增加了三千刀的销售额,以及被 The Verge,The Next Web,Life Hacker Feature 这种事情,也是可遇不可求,都算是独立开发者能遇到的大好事了。
当然随着销售额的增加问题也开始变多。Unity 这个平台对于动态壁纸还是太重了,因为 Unity 空场景就需要占用 150 MB 左右,这部分对于我来说是无法优化的,因此 Skyline 从一开始就有了一个 150 MB 的包袱,在此基础上内存管理再好也没有什么用,加上耗电和性能损耗,造成了很多用户体验上特别差。因此到后面有很多差评,很多邮件联系我要退款,一个个处理起来还是有些吃力的,毕竟我还没准备好做客服的事情。除此以外因为差评变多自己很急,因此匆忙推送新版本导致更大的 bug 出现了这种事情也出现了。受评分降低的影响,销售额增速放缓,现在已经没有爆炸式的增长了,我也松了一口气,这样每天发邮件的用户也能变少了。
这么一折腾,自己原本有些平静的心态反倒又翻腾上去,自己也开始变得太在意了。大规模差评的时候不太想看 Google Play 邮件推送的用户评分提醒,但是总是要看的,看到用户很失望自己也觉得要赶紧修 bug,但是 Unity 的大坑摆在这里其实又没啥可修的,修起来也是大部分时间都在验证性地尝试,要一劳永逸除非拿精简点的小图形引擎重新实现一遍,但那样的话乐趣就不在了,毕竟我做 Skyline 也没真正想拿它来挣钱,就是为了好玩而已。
不管怎么说,对于在 iOS / Mac 生态圈写了两年其间一个像样的前百排行榜都没上的人来说,自己的非原生 Android 软件能莫名其妙地在 Google Play 总榜前五连续一周,挺奇幻的。

2018.1.20

 • 

出乎意料的,两天之内在 Google Play 挣了 1000+ 刀。感谢 Android Authority 介绍了我的软件,很多顾客购买了 Skyline,也提了很多意见,瞬间 Skyline 的功能排期表多了很多功能。
现在 Skyline 在美国区 Play 的游戏+软件总付费榜排第 20,应用类总付费排行榜上排第 6,个性化排行榜排第 2,当然只是暂时的,哈哈 :-)。


根据用户反馈,下一步 Skyline 的 Roadmap:

  • Better Swiping Gesture
  • Skyline Presents (already in dev)
  • Toggle For Animations

学校的考试考完了,下学期还有一些要重修。
我经常想和我妈表达一个意思,我对学校的态度,实际上是一个博弈的过程,因为是博弈,所以这中间没有什么反悔的,也没有什么“早知道”一类的话。我通过了解学校往年对我这类翘课学生的态度,估量自己的手段,评估自己是否能在毕业的前提下最大化我自己的独立发展,这中间总会有突然的变化,评估的失误,因此也会导致不尽人意的后果,比如学校取消了清考,导致我不得不在大四下跟着完整的课程走而延期毕业。这中间还有很多隐晦的,学校和学生之间的惯例,就不一一列举了。总而言之,因为大环境变严,很多原本模糊的地界开始变得严厉分明,我的下学期不得不跟流程着走了。

上学期最迷的莫过于生产实习了,写了整个班唯一一个完整功能带 GUI 的测试工具,结果成绩只是及格,后来经过崇哥点拨才想起来:生产实习结束后要写实习报告,套路是“我遇到了什么问题-我请教老师/和同学攻坚克难-我学到了什么-感谢老师提供机会+很多字”,而我当时的思路还在在百度写周报的状态,上来就写“我做了什么项目/实现了哪些功能/我对自己比较满意+完”。而且批阅人并不是实习公司的 Leader,而是学校这边偶尔来一次的带队老师。


想起两个月前见吴总聊起了不起的盖茨比。我一直觉得盖茨比真正了不起的一点是,他知道这个世界的困难和不公,但是并没有失去动力和憎恨世界,而是积极地投入其中,接受和利用规则,爬到顶端,然后再去实现他自己的理想。某些层面上看,他是最单纯的人。
现在再想起来,再抱着这个想法去审视周围的人,会突然觉得:我之前觉得他人做法欠妥当,但我是没有这个权利的,毕竟我何尝不也是一个穷尽一切可能走上去的人呢。


延期毕业

 • 

延期毕业的事情基本确凿了。近代史这门课是大三下学期的,当时在北京,因为没怎么在学校上课所以平时分比较低被挂了,类似的还有数据库实验课,提议说检查自己的个人项目也是被拒,因此挂了。学校对大四学生没有清考,只能跟着下一届的人上下半学期的课到下学期 16 周结课,在那之前就已经要发毕业证书了,所以只能延期。
延期对我的影响大致就两个,一个是腾讯的入职会比较麻烦,少了说会延期一到两个月,这期间只能办理实习生入职,等到拿到证书后才是正式员工和正式工资,多了说估计要半年。另一个就是事务上的,要花一些额外的时间对付学校的流程和课程。

Unity WebGL Canvas 窗口自适应

 • 

Unity WebGL 一个很奇怪的事情就是默认的模板没有默认充满窗口的选项,这个问题貌似可以在 WebGL Templates 里面纯 css 解决,不过我还是更偏向于 js 一些。
以下代码 Unity 2017.3.0f3 测试可用。

// CanvasResizerPlugin.jslib
var CanvasResizerPlugin =
  {
    CanvasResizerCheckBegin: function () {
      
      function ResizeCanvas ()
      {
        try {
          document.getElementById("gameContainer").style.width =
            (window.innerWidth
              || document.documentElement.clientWidth
              || document.body.clientWidth) + "px";
          document.getElementById("#canvas").width = window.innerWidth
            || document.documentElement.clientWidth
            || document.body.clientWidth;
          document.getElementById("gameContainer").style.height =
            (window.innerHeight
              || document.documentElement.clientHeight
              || document.body.clientHeight) + "px";
          document.getElementById("#canvas").height = window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
        }
        catch (err) {
          console.log(err);
        }
      }
      document.body.style.margin = "0px";

      window.addEventListener('resize', function (event) 
      {
        ResizeCanvas();
      });
    }
  };
mergeInto(LibraryManager.library, CanvasResizerPlugin);
// WindowResizerManager.cs
public class WindowResizerManager : Singleton<WindowResizerManager> 
    {

        [DllImport("__Internal")]
        private static extern void CanvasResizerCheckBegin();
 
        private void BeginResizeUpdating () 
        {
#if UNITY_WEBGL && !UNITY_EDITOR
			CanvasResizerCheckBegin ();
			#endif
        }

        private void Start()
        {
            try
            {
                BeginResizeUpdating();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }

效果: