MoreRSS

site iconKai Xia | 夏恺修改

工程师在澳大利亚墨尔本。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Kai Xia | 夏恺的 RSS 预览

Pensieve: 2411

2024-11-25 15:14:00

所读所观所玩

仍旧先说游戏, 这个月全成就了Astro Bot. 和免费的前作Astro Bot’s Playroom不一样的是, 这部作品我看到了满满的恶意. 每个大关卡里面的挑战关卡实在很是恶心人: 这些关卡容错率很低, 对操作反应要求也很高, 所以手残如我, 通关的策略只有”死-背板-到下一阶段-死”这样一个死循环. 当然, 最后那个挑战关卡更是集大成者. 其余来说, 我没觉得这个游戏相对于前作有大的突破. 玩完这个游戏后, 一直没怎么开PS5了, 手机上的原神仍在继续, 花了70抽终于把久岐忍的命座由1提升到了2. 现在手上攒了180颗球, 准备和之前说的那样等火神. 火神的技能机制爆料都看过了一些, 仍是很不满意在想是不是抽个零命保个底, 然后去抽让我还算满意的黑曜石奶奶. 1999里面环形水星没抽到, 作为零氪, 这个结果也不意外. 目前在努力提升Lucy和曲娘的共鸣, 顺便给天使娜娜攒兔子.

再说看过的影视作品, 大概认真看过的也就两个, 一个是月初时无聊在Netflix上看的黑暗骑士崛起, 记得不错的话该是第二遍看了, 仍没什么好感, 普通商业片而已. 另外一个是偶然下的网剧, 成何体统, 制作不够精良, 不过当泡面番看还是没问题的. 另外, 豆瓣上不知谁人写的这个番外真好.

终于说到这个月读过的书了. 首先是金庸的碧血剑. 隐藏双主角的设定很好, 但是很多转折仍是很生硬. 出场的人物对于这样篇幅的作品而言实在有点多, 走马灯似的串下来才使得主角能承上启下. 但是有没有可能摊子铺小一点点也能讲好故事, 并且成本更低? 读完了这本, 我找回高中时语文老师在上课时提到过的我看金庸我看鲁迅, 都觉得王朔说得很有道理. 王朔看金庸的那些评语就好比我对绝大多数网络小说的那些评语一样. 所以看起来这个比例尺下的鄙视链还是挺立得住的. 然后是莫言的奇奇怪怪故事集. 这应该是我第三本莫言了, 仍然不是那么喜欢他的风格, 乡土气息太重, 感觉一抬头就是有一坨牛粪堵在家门口. 对于我这个理科生而言, 莫言叙述故事的逻辑本身就是故意不太分明的, 奇奇怪怪的故事被奇奇怪怪的逻辑串到一起, 更是对我的阅读耐性提出了巨大的挑战. 人物形象的塑造也很成问题, 很像是戏台上飘过的野鬼, 乍看精彩, 但经不起推敲, 也没有太多生活基础. 再往后是一本蒋勋读唐诗, 这本书各个章节的水平比较不一, 有几个作者的作品是用心讲的, 比如张若虚, 李白和白居易讲得都还行, 其余几个作者总觉得差点意思. 最后一本是图书馆里的一大厚本The Making of Avatar, 讲的是詹姆斯卡梅隆拍阿凡达的事情. 读完这本后, 我很想去读读有关他的传记作品了, 因为这本书里的Jim实在是太厉害了, 什么事情都能高瞻远瞩地做出决策, 让我想起了乔布斯.

工具链更新

常用的工具链有一些更新, 首先是苹果上的输入法, 由默认的改成了鼠须管. 不是因为可配置性, 单纯是因为速度. 不过这么多年过去了, 鼠须管的配置还是那么一如既往地二, 总觉得有一个什么Rime For humans的工具包, 能把一个high-level的配置翻译成rime需要的配置, 然后自动部署就好了.

另外几个更新是在neovim里面. 首先是用blink.cmp换掉了nvim-cmp. 这样解决了我对cmp的两个不满之处, 一个是配置文件太过繁琐, 另外一个是补全速度实在是肉眼可见. 接下来是用conform换掉了之前一直使用的formatter, 优点是配置更容易了. 最后是开始用avante.

还有一个不太成功的尝试是使用Zed. 发现的一个主要问题是对于monorepo而言, 切分支的速度有点慢. 这也就算了, 而使用远程开发模式的时候, 切分支会直接失败. 简单查了下, 好像是我们的monorepo里面使用了一些libgit2还不能识别的特性. 我自己写的ps1之前也是会遇到问题, 现在zed仍然是有这样的问题. 后来也就没从neovim往zed切, 等它变得更成熟一些再说吧.

Pensieve: 2410

2024-10-28 08:07:00

所读所观所玩

先说游戏, 月初的时候完成了黑神话的全成就收集, 总共游戏时长是81个小时, 挺好. 要说感想的话, 种子的掉率实在是不太理想, 种子这个系统本身就只是在少部分玩家的路径上, 没必要用这么低的掉率来刻意延长游戏时间. 既重返未来1999后, 终于也在原神里双黄了一次. 这次是武器池, 十连出了up的两把武器. 而且抽西诺宁二命时一次都没歪. 运气真不错. 现在手上有190抽, 准备5.1下半抽久岐忍的二命(现在一命), 然后封箱等火神. 1999里面抽牙仙时歪了37, 也还算可以用.

这个月读书稍多一些了. 按阅读顺序来说, 首先是重读完了金庸的书剑恩仇录, 这本书是金庸成为金庸的第一步, 所以很多地方不太成熟, 比如机械降神太多, 芜杂的分支太多, 人物塑造不太鲜明, 人物脸谱化等等. 很多时候不太像是一个真正的人物在那个江湖里挣扎, 而是作者希望他/她在里面挣扎, 所以特意让剧情往挣扎的方向往下走. 这本书里有全金庸小说中最美的女主角, 也有全金庸小说里最不招人待见的男主角. 然后是村上春树的我的职业是小说家, 写得真诚恳, 满嘴大实话, 也很有启发意义. 各种工作要做好都需要持之以恒地努力, 而且理应为了完成这样的工作来调优自己的身体和生活习惯. 再往后是刘慈欣的一个短篇集, 信使. 我的感想是短篇科幻小说看不得, 因为科幻小说大都是在卖一个idea, 但是短篇由于篇幅所限, 能包裹这个idea的文字太少, 所以读完了之后总是让我感觉故事没说完. 尤其是像刘慈欣这样的文笔很一般的小说家, 除了idea就没什么其他可以回味的了. 再然后是余华的文城. 如果一本书能抓住我, 我在读书时是会进到故事里面去, 当能够看到不幸将要发生时, 我会停一下, 做一些其他的事情, 缓冲一下, 再回到书里面去. 读这本文城时我只怕驻足了几十次. 宁为太平狗, 莫作离乱人. 人类社会真的很脆弱, 能够生活在一个和平和平和的国家真的很幸福. 因为家里那只猫科动物有过敏症状, 在图书馆里看到了这本The allergic pet就借回来翻了翻. 总体评价是没价值, 可以不读, 属于招摇撞骗都不讲策略的书. 手机上比较快地读完了一个网文小阁老, 故事大量抄袭已有的材料/书籍, 本身乏善可陈. 但是作者的价值观真挺有趣的. 一方面是国内舆论控制所养出来的狭隘民族主义, 一方面是面向地读者群而经常走下三路. 作者一方面在里面妇女解放一方面三妻四妾, 一方面宣扬社会主义却又大搞土地财政, 一方面说不要家天下却又没有在机制上用民主来保证政权的更迭, 也是够分裂了. 我坚持读到最后主要就是想看作者理想中的政体是啥, 结果到最后也不敢明说. 算了, 对这种小说, 要求不要太高. 最后一本是意料外的好书, 东来的奇迹之年, 其他先不说, 就看看里面这两段:

买了门票, 进了公园, 到樱花树下找了一片平整空地, 铺开野餐毯子, 两个人躺下来, 仰视着这棵花树, 片片的团团的, 被阳光照透, 一树琉璃白火, 快要烧透了天. 她很快睡着了, 整个人卷起来, 脸被晒得发红, 分布得太过疏阔的五官, 此刻看起来更加破碎, 像毕加索的画, 零件拆开, 又粘回去, 不再真切. 来看花的人虽多, 却都是走马, 他们两个也被人一道观看.

他和她在公园里闲着没事, 租一条小船, 花小半时辰, 在河里流连, 小河曲折, 转弯困难, 时常撞在岸边花丛. 两岸的柳树释放着无穷无尽的柳絮, 大大小小在空气中漂浮, 造出春日艳阳里的雪, 迷住人眼, 掉在水面上, 渐渐铺满河道, 他们一边向前划桨, 一边扎到这场春天的雪里, 浆打在水面的声音轻微, 一下子将那些白絮卷到水里, 便宜了河鱼. 在浓密的白絮中穿行, 脸上身上却粘不到一点, 这场景连他都觉得似梦, 更别提她了, 划船前又喝了点酒, 幻想铺排过来.

前一段大都是短句, 像是先写诗, 再拼回成一段话, 尤其是里面那段写花, “片片的团团的, 被阳光照透, 一树琉璃白火, 快要烧透了天”, 放进任何诗集里都不逊色; 后一段长短句的排布更明显些, 朗读起来音韵感十足. 两段话用词造句都很讲究, 读起来真是享受. 这本的缺点是发挥不太稳定, 按责编的说法, 五个故事像是五个人写的. 期待作者后续的长篇作品.

新电脑

因工作需要, 这个月换了一台新电脑. 之前的旧机器是2021年的16寸MBP, 主要优点是配置很足(M1 Max/64G/1T), 缺点是太大太重了. 而且我现在的大部分开发工作都是在devbox上完成的, 对本地配置要求很不高, 所以找公司IT要求换电脑, 出乎意料地第二天就收到了新电脑, M3/24G/256G的MBA, 很是轻巧, 爱不释手. 我那实际工作场景中的bazel build对比了一下, 两者在伯仲之间, 而devbox的运行时间比两者都短得多. 另一个缺点是接口不太足, 只有两个USB C和一个电源口. 在单位办公时, 用的是显示器的USBC, 再加上一个Yubikey, 就完全可扩展性了. 另外, 机器上本身不带HDMI也是缺点. 不过瑕不掩瑜, 习惯了这把轻快的三德, 我现在是回不去那么重的斩骨了.

Pensieve: 2409

2024-09-29 11:48:00

所读所观所玩

这个月首先是完成了黑神话悟空的一周目, 花了59个小时. 目前在二周目第四关, 尝试了几次, 终于拿到了下毒手. PS5上没有手工存档的功能, 目前已知的办法只能是关闭自动存档到云后手工上传和下载存档. 而且二周目难度偏低, 所以后面是用了初始的柳木棒, 而且将加攻击的天赋点全取消才达成. 很享受这个游戏的过程, 后面准备拿了全成就后再开一周目, 专门拍照.

这个月读的书也不算少, 首先是重读完了西游记. 不得不说, 虽然小时候囫囵吞枣地读过几次, 电视剧也看过很多遍, 但是很多情节还是忘记了. 比如小雷音寺那段只记得这是一个假雷音寺, 最后是靠弥勒佛收服了妖怪, 但是吃瓜的这段我是完完全全地忘记了, 甚至玩游戏的时候都没想起来, 直到重读时才记起这段. 倒是这次重读时感觉很多地方能看出当时人吃人或人口买卖的记录. 比如通天河那段要献童男童女, 悟空顺口就提议去买一个童男来替代自己的孙子, 连报价都清清楚楚, 这大概能说明明朝时这种事情司空见惯吧? 另外读完了图书馆里的黎明之街, 不算太好, 更像是借着推理的外皮来讨论社会情感问题. 读完这本不算太纯洁的, 读阿来的三只虫草就感觉上到了淳朴的青藏高原一样. 这本很短, 充其量算是中篇. 这本是用一个孩子的视角来看这个纷乱的世界, 我们能看到的, 一方面是这种世俗对宗教和社会生活的入侵, 另一方面也是世俗对纯洁的个体的侵蚀. 接下来是在豆瓣上无法出现的Zodiac: A Graphic Memoir, 艾未未的这本我没觉得好看, 画得一般, 也没讲什么道理. 最后两本是葛亮的无岸之河谜鸦, 都不错, 不过看小短篇不过瘾(而且前一本有大概一半是文论), 不如燕食记.

原神到纳塔之后开放世界等级9, 继续没抽限定, 常驻又出了一把和璞鸢. 玩游戏一年多后终于到了60级, 而且终于深渊满星了一次, 没什么追求了. 后来又转回重返未来1999, 歪了葛天后拿到周年限定lucy和送的吸血鬼. 本来想补一个牙仙, 结果十连的时候抽错了, 出了双黄lucy. 现在努力再刷一个牙仙出来.

悉尼之旅

我这个月有一小半时间是在悉尼度过的. 有小半周是因为出差在悉尼开会, 后一周是趁着娃学校放假, 带着在悉尼玩. 相比于之前偶尔的走马观花, 这次能多一些了解悉尼的机会, 也发现了一些之前不了解的美妙之处.

首先是纪伊国屋的悉尼店, 这可能是我逛过的最好的书店之一了, 能和广州太古汇方所和台北诚品敦南店(为闭店哀悼一分钟)放到一起. 店里售卖的书籍种类有30万, 说是汗牛充栋一点都不为过. 除了英文书籍外, 还有大量来自台湾, 大陆和日本的书籍. 很多寻常大书店里不太会选的书籍, 在这家店里都能看到, 比如大量艺术设计类作品, 又比如铜版印刷的游戏原画等等. 书店里除了书籍外也还有文具, 文创和咖啡馆这样的周边. 带小姑娘去书店的时候, 她对里面的扭蛋机也很感兴趣. 限于行李额, 这次我没在里面买什么书, 准备下次去悉尼的时候补上. 另外, 我在书店里拍摄了很多书架上的书籍推荐, 后面也准备按图索骥, 找来给小姑娘读.

然后是观鲸, 回头来看, 这个活动不是那么有意思, 因为鲸鱼也算是我们熟知的动物, 但是真正出海去观鲸的体验仍然挺不错. 悉尼的码头上观鲸的航线有不少, 我们选的是这家, 本来选中了三个小时的行程, 看中的是大船, 不会那么颠簸. 但是出海前一两个小时收到邮件通知因机械故障航线取消了, 所以改订了两个小时的行程. 真正出海比较快, 大概20分钟左右就出了悉尼的海湾. 后面就是靠着声纳和其他观鲸船之间的互通信息来往有鲸鱼的地方行驶, 真正到鲸鱼附近也就停船, 由着甲板上的游客们欣赏. 网站上说最近有看到orca, 但是我们只看到了座头鲸. 甚至看到了鲸鱼跃出水面的情景, 也算是不虚此行.

最后, 我们这次是住在了Darlinghurst的一个小楼里. 楼下是客厅, 楼上是两个卧室, 不得不说住起来比较逼仄. 但是胜在交通方便, 而且闹中取静, 所以很满意.

Pensieve: 2408

2024-08-31 13:51:00

所读所观所玩

这个月同样是游戏挤占读书时间, 图书馆借了一堆书堆在书架上没怎么动, 只是翻完了一本Brilliant maps. 没什么特别的, 算是reddit上dataisbeautiful的水准而已. 另外有天晚上快进重读了棋魂的漫画, 很多这种漫画一开始的构思的确不太明确, 后面慢慢改好. 但是棋魂这本我觉得是从头到尾的构思都是乱的. 莫名其妙就把佐为给写没了. 这一个能文能武能卖萌能推剧情的机械降神是整个漫画塑造得最好的角色, 说没就没, 叹气.

剧的话, 拜买iPad赠送的Apple TV所赐, 看了Napoleon, 导演很有野心. 想在一部电影里塞下拿破仑的整个人生(我觉得这是不现实的, 因为拿破仑的一生的经历实在太丰富了). 但是力有不逮, 剧情太过纷乱. 小时候读过这本拿破仑传, 所以我大概的剧情都清楚, 所以还能过得去, 但是对于一个不了解拿破仑生平的人而言, 这部会比较难深入进去. 如果我来拍摄的话, 估计只会截取拿破仑历史中的一小段(意大利/埃及/奥斯特里茨/征俄)来拍. 批评归批评, 看到拿破仑单枪匹马收揽拦截他进入巴黎的军队那段, 看起来还是挺不错. 看过的另一部电影是Spy x Family Code: White, 地球人已经没办法拦截她妈妈了只好找了个机器人来? 要求不高休闲看看还是可以的.

这个月开头的时候还在继续玩宋上繁华的剧情模式, 不过面临最大的问题是过关的条件不明确, 而且不像文明系列游戏里各个阶段有不同的小目标可供完成, 在宋上繁华里这种刺激相对比较小, 建筑种类和升级不够丰富. 尤其是用剧情模式游玩时, 后期的反馈感和目标指向不够, 比如现在离完成剧情关卡还有哪些条件需要完成等等, 如果加上这些, 游戏的体验应该会好不少. 月中因为工作需要升级了macOS Sequoia, 升级完成后游戏就没法打开了.

接下来, 原神的纳塔终于开放, 不过目前对这个版本的人物/设定都不太满意. 首先是引入了夜魂, 旧角色得到的收益会明显比新角色少很多, 逼着玩家去跟进. 5.0目前已开放的主线剧情目前也许是为后面的剧情做铺垫, 我暂不评论. 现在的几个人物除了火神还比较成功外, 完全看不到之前原神人物的影子. 准备现在先凑合着玩着, 后面实在忍不下去再弃坑.

最后是已经花了四十个小时的黑神话悟空, 绝对是我的年度最佳游戏. 这是我目前在PS上玩过的最好看(超越了Horizon forbidden west), 也是游戏性最强的游戏(超越了Gran Turismo Sport). 发售前我对它的预期是一个高配版的Kena. 玩到后才觉得是自己要求太低了. 虽然没到荒野之息那种让我愿意买机器来玩游戏的程度, 但是$60的定价绝对是超值的. 目前进度在第四关, 开荒的时候还有不少攻略不够全面, 所以这一周目没法全收集了. 也好, 留着二周目.

iPad Air & pencil

自己手上的iPad已经很旧了, 甚至已经没法安装系统更新, 于是就买了一个新iPad, 具体购买方式参考了这篇帖子, 感谢pricebeat机制, 尝到甜头了. 拿到机器后又配了一个第三方的coverpencil. 目前使用很是顺畅. 买之前认为自己可能会大量使用pencil, 结果只是偶尔使用下. 后悔自己还是没想清楚使用场景就买了东西.

Pensieve: 2407

2024-07-28 14:47:00

所读所观所玩

这个月游戏玩得多, 书读得少, 只有两本. 一本是韩寒的光荣日, 挺没趣的, 满眼都是往下三路招呼, 恕我欣赏不来. 另一本是冯骥才的一百个人的十年, 这本已经没有豆瓣链接了. 里面的故事不少很难读下去, 故事都是鲜活的, 作者功底更不用说, 但是不少故事的细节实在让人太痛惜, 只好放下书缓一缓. 吹牛五千年文明, 谁给我解释一下文明古国怎么会有这么野蛮的事情发生?

借着出游的机会看完了Netflix上的Spy x Family, 标准泡面番, 杀时间可以看, 没大意思, 机械降神太多了. 另外看完了About Time这部电影, 这个更有意思一点, 人生如果可以这样回溯, 我也大有可能和男主的父亲一样, 靠反复看书来遣有涯之生了. 里面关于心态的tip也很厉害, 每天你遭遇到的事情都可能是一定的, 但是你的心态是自己可以控制的, 过得积极向上一点利人利己.

原神继续攒彩球, 看着4.8上半的武器池还行, 捞了几把西弗斯, 给万叶的武器加了一点精炼, 没出金. 现在限定的pity是50多, 限定武器有60, 常驻也有50多, 彩球有一百一. 4.8这个新版本的地图开得差不多了, 长期历练点的改进真不错, 可以放心游玩不用攒地图/宝箱了. 目前5.0的trailer没太吸引我, 几个人物都不像是原神世界里走出来的一样. 除了原神外还玩了回到未来1999宋上繁华. 前者我沉迷地玩了两周左右, 很有意思的是, 这个游戏有两个服务器, 国服比我玩的世界服要快大概半年左右, 所以有不少东西可以参考已有攻略. 这也让我看到数值膨胀比较严重, 所以零氪的我就主动退坑了. 退坑前拿到了曲娘/伊索尔德/兔毛手袋/远旅/温妮弗雷德这几个六星, 回合制战斗技巧要求也没那么高(计数和加减法就行), 没太多意思. 话说回来, 故事剧情, 配音和音乐都值得好评, 游戏的调性是在的. 后者是一个宋朝2D版的都市:天际线. 剧情模式目前卡在了卜算子这一关, 深恨乱折腾, 乱往下摊派的官家(皇上). 游戏数值系统设计不算太好, 很多建筑组合是简单粗暴地翻倍, 不过中国风的画面还是勉强让人能够继续玩下去.

Marysville

月初的时候, 我们一家从墨尔本开车去Marysville玩了几天. 这个小镇曾在2009年被山火摧毁, 但是我们这次去的时候已经完全看不到山火痕迹了. 这个小镇不大, 镇里最显眼的建筑可能就是我们这次住的Peppers酒店了. 我们这次去的主要目的是带着娃去附近的Lake Mountain Alpine Resort玩雪. 我们待的这几天运气不好, 气温略高于零度, 所以也没算见过雪花绽放的气候. 但是Resort里面提供了人造雪坡, 娃可以在里面玩平底雪橇, 也还行. 主要问题是住在镇上的时候, 实在没有合适的餐饮, 天天吃炸鱼薯条不是长久之计, 只能挖空心思地拼凑. 我们本来预备了一周左右的行程, 也就因为没有真雪和没有吃饭的地方而提前下山了. 倒是镇上没有吃饭的地方让我想着, 如果山上开一个中餐饺子馆, 生意应该不会太差.

kubectl cp

这个月工作中接到一个需求, 要给我们的一个内部传文件的工具加上进度条, 这样在传大文件的时候, 我们可以更好地估计时间. 这个工作看起来不算太难, 但是实际钻进去才发现是个坑. 我们这个文件的传输实际上是在调用kubectl cp, 而这个命令不支持提供进度条. 再往底层了说, 你在容器里怎么把文件传输出来的同时能够把文件的大小给出来? 现在kubectl cp的实现实际上是tar然后在本地解压, 这样处理的好处是容器里只需要有tar, 客户端可以不做任何要求, 传输就可以完成. 但是tar本身不支持进度条.

2010年刚毕业的我, 在翻译SCP原理这篇文章的时候, 不会想到, 我能够帮到十多年后的自己. 否则你在IT行业泡很多年, 也大概率不会碰到需要了解scp协议的场景, 或者即使读到了这个实现的原理, 转眼就可能忘了, 不会将kubectl和scp联系起来. 不卖关子了, 这个命令可能长这样:

kubectl exec pod-name -- sh -c 'file=/tmp/test1; name=$(basename $file) ; size=$(wc -c $file | cut -d " " -f 1); echo "C0644 $size $name"; dd if=$file bs=8192 2>/dev/null; printf "\0"' | scp -t /tmp

这个命令会在当前的kubectl context里面, 在pod-name这个pod内执行一个系统命令. 这个命令是一个shell脚本, 它会读/tmp/test1这个文件, 拿到文件名和大小后拼成一个SCP协议消息:

C0644 $filesize test1
$(file content)
$(EOF)

上面这个执行的结果会通过管道传递给本地的一个scp命令. 这个scp命令启动时使用了一个隐藏flag, -t, 表明它是一个文件的接收端. 收到上面的协议消息后, scp会创建这个文件, 并且把收到的$(file content)写进去. 另外, 那个单行shell脚本里使用了dd来分块文件而不是直接用cat, 这样可以避免一次将文件全部读入内存.

对容器来说, 上面这个hack要求容器里有coreutils, 而在客户端方面, 要求客户端有scp命令. 幸好, 对于我来说, 这两点都能成立.

Pensieve: 2406

2024-06-30 06:42:00

所读所玩所听

这个月游戏玩得多, 书读得少, 只有两本. 一本是孔庆东的金庸者谁, 挺水的可以不看. 另一本是在手机上碎片时间里读完的朱镕基答记者问, 这本值得重读, 因为有些话十年前读的时候没什么感觉, 过去也就过去了, 十年后失去了才知道可惜.

游戏除了单独成文的Diablo 4以外, 还有怪奇小店, 恶魔城晓月和Klei家的缺氧. 怪奇小店是AppStore里看到以前的已购游戏时下载下来玩的. 最大的感想是几年过去了, 当时很不少的游戏攻略已经基本绝迹了, 剩下的大都是内容农场里的作物. 无聊时随便玩玩时体验还好, 但是如果要去刷红名人物或刷挑战的话需要的反复读档实在太让人不爽. 单机游戏很多时候为了游戏时间只能这样通过随机数来控制, 我能理解, 就好比我偶尔会打开家里一台Windows电脑去刷几轮无尽模式的植物大战僵尸来刷植物种子(虽然n年前也已经完成过全收集了不过档没了不是吗). 恶魔城晓月是刷reddit时看到有不少人推荐iOS下的模拟器Delta, 于是下载下来, 然后下载了几个游戏过来测试(掩嘴笑). 大概十几个小时通关了, 魂收集大概有80-90%的样子, 反正之前实现过全魂收集, 这次就没强迫自己了. 手机上直接触屏玩的手感稍差, 有时候认为自己按到了但实际上没按到, 如果有物理按键肯定会好一些, 但是为了这个小游戏去拿手柄感觉又缺了点什么. 缺氧的设计和饥荒是一脉相承, 沙盒里通过各种系统和复杂度来留住玩家, 而且当一个管理者的感觉也挺好, 所以一直能够让玩家有正向反馈. 但是, 我还是觉得看视频才能学会玩游戏不算是一个好的体验. 哦对了当然也还在继续原神, 每天上线做日常, 然后在仆人的圣遗物本里坐牢. 这个月终于有了一个双爆的攻击沙, 而至今为止只见过两个双爆头也是挺让人无奈的.

这个月发现了一个古早的治愈系音乐家矢野显子, 日本对西方文化的吸收使得有很多人会喜欢用爵士乐去翻唱英文的名曲, 往往听起来有耳目一新的感觉. 另外一个发现是一个德国钢琴家Martin Stadtfeld的哥德堡变奏, 推荐9和30.

玩PTV的API

维洲的公共交通提供了API供爱好者查询使用. API的申请不是全自动的, 大概等了一两周才收到回信. 我针对我的需求, 写了一个脚本, 供下班时查询要乘坐的906/907线. 脚本和对应的注释在下面:

#!/usr/bin/env python3
from datetime import datetime
from datetime import timezone
import hmac
import http.client
import json
import math
from urllib.parse import urlencode

API_ID = "your-api-id-that-looks-like-a-number"
API_KEY = "your-api-key-that-looks-like-a-uuid"
API_HOST = "timetableapi.ptv.vic.gov.au"
# route_id available from /v3/routes, direction_id available from /v3/runs/route/route_id
ROUTES = {
    "907": {"route_id": 8591, "direction_id": 31},
    "906": {"route_id": 8596, "direction_id": 54},
}
MY_POSITION = {"longitude": 144.989958, "latitude": -37.809515}
# For weekdays around 5pm, it will take 8 minutes to travel 1.34KM according to the schedule.
BUS_SPEED = 1340 / (8 * 60)


def get_response(path, **kwargs):
    kwargs["devid"] = API_ID
    raw = f"{path}?{urlencode(kwargs)}"
    kwargs["signature"] = hmac.new(API_KEY.encode(), raw.encode(), "sha1").hexdigest()

    conn = http.client.HTTPSConnection(API_HOST)
    conn.request("GET", f"{path}?{urlencode(kwargs)}")
    return conn.getresponse()


def haversine(coord1, coord2):
    # radius of the earth in m
    R = 6371.0 * 1000

    lat1 = math.radians(coord1["latitude"])
    lon1 = math.radians(coord1["longitude"])
    lat2 = math.radians(coord2["latitude"])
    lon2 = math.radians(coord2["longitude"])

    dlat = lat2 - lat1
    dlon = lon2 - lon1

    a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return R * c


def main():
    print(f"Now it's {datetime.now().strftime('%H:%M')}")
    utc_now = datetime.now(timezone.utc)
    for route_name, route_info in ROUTES.items():
        response = get_response(f"/v3/runs/route/{route_info['route_id']}", expand="All")
        if response.getcode() != 200:
            raise RuntimeError(
                f"Bad response({response.getcode()}) from PTV API: {response.read().decode()}"
            )
        runs = json.load(response)["runs"]
        time_remaining = []
        for run in runs:
            if run["vehicle_position"] == None or run["direction_id"] != route_info["direction_id"]:
                continue
            if run["vehicle_position"]["longitude"] > MY_POSITION["longitude"]:
                continue
            distance = haversine(run["vehicle_position"], MY_POSITION)
            try:
                utc_time = datetime.strptime(
                    run["vehicle_position"]["datetime_utc"], "%Y-%m-%dT%H:%M:%SZ"
                ).replace(tzinfo=timezone.utc)
            except ValueError:
                utc_time = datetime.strptime(
                    run["vehicle_position"]["datetime_utc"], "%Y-%m-%dT%H:%M:%S.%fZ"
                ).replace(tzinfo=timezone.utc)
            distance -= (utc_now - utc_time).seconds * BUS_SPEED
            time_remaining.append(distance / BUS_SPEED / 60)
        time_remaining.sort()
        if len(time_remaining) == 0:
            print(f"[{route_name}] No bus info found.")
        elif time_remaining[0] > 10:
            print(f"[{route_name}] Closest bus is {min(time_remaining):.1f} mins away.")
        else:
            print(
                f"[{route_name}] Incoming buses: [{'/'.join(format(t, '.1f') for t in time_remaining[:2])}] mins."
            )


if __name__ == "__main__":
    main()

有一说一, 这个脚本没写得很好, 不少地方很粗糙. 不过在ChagGPT的帮助下两个小时就从零上手写完测完了, 开发体验还可以. 现在下班时就会打开Pythonista跑一遍这个脚本. 如果发现公交车还有不到三分钟到站的话就得小跑一段了.