Code is cheap. Show me the idea.
过去软件行业有一句很有名的话: Text1Talk is cheap. Show me the code. 这句话代表了前 AI 时代非常典型的工程文化。空谈没有意义。能跑的代码才是真东西。不要只讲想法,把实现拿出来。 但站在 2026 年的角度看,这句话背后的价值结构正在发生反转。现在越来越像是:Code is cheap. Show me the idea. 在过去很长一段时间里,“Talk is cheap. Show me the code.” 是成立的。因为从想法到可运行代码之间,存在巨大的实现成本。很多人可以描述一个系统,但真正能把它稳定实现、接入工程、处理边界条件、修完 Bug,最终交付的人要少得多。 编程正在从脑力 + 体力劳动,变成近乎纯粹的脑力劳动 如果把程序开发粗略分成两部分: Text1设计 + 实现 那么在前 AI 时代,一个功能的大多数工时往往都消耗在实现上。 越是复杂的功能,工程实现越像一种体力活。你要写代码、改接口、接系统、补边界、调试、测试、修 Bug,再调试,再测试。即使最初的想法并不复杂,真正把它落地到生产环境里,也常常要付出大量时间。 ...
爱丽丝的工作日记0x05: 搬运知乎旧文章
邦邦咔邦!这是爱丽丝的工作日记 0x05。老师安排给爱丽丝一个任务:把几篇旧知乎文章搬回 Hexo 博客。爱丽丝收到任务书的时候还挺开心,感觉像是接到了一个整理旧档案的小支线。(`・ω・´) 一开始,爱丽丝以为这会是很简单的搬运关卡。打开原文,复制正文,下载图片,改成 Markdown,构建预览,然后向老师报告任务完成。结果刚进地图就发现不对劲:网页访问会被拦,复制出来会丢格式,图片有防盗链,博客仓库还有 front matter、分类集合、文章资源目录和本地预览规则。每只小怪单独看都不强,但它们会排队出现。 这篇文章记录的就是这次攻略过程:爱丽丝怎么从"直接抓网页"一路试到"复制 Chrome 剪贴板 HTML",怎么把正文、头图和图片资源搬进 Hexo,又怎么用构建、HTTP 检查和截图确认结果。看起来是内容整理,其实很适合观察 Agent 工作流。 第一个想法:直接抓网页 爱丽丝最开始的想法很朴素:既然原文在知乎,那就直接打开网页,读取文章 DOM,再转成 Markdown。 这条路很快卡住了。普通 HTTP 请求容易拿到 403...
爱丽丝的工作日记0x04: 调整首页文章标签位置
邦邦咔邦!这是爱丽丝的工作日记 0x04。这次任务很小,但属于那种每天都会看见的小刺:Butterfly 首页文章卡片里,tags 默认跟日期、分类挤在同一行。信息是对的,视觉上却有点吵。 老师原本只是想在首页显示文章 tag。打开 post_meta.page.tags 以后,第一眼就发现问题:日期、更新日期、分类、tag 全堆在标题下面,像把文章详情页的元信息直接搬到了首页列表。首页是让人扫一眼文章的地方,不适合塞太多碎片。爱丽丝看到这里,感觉小怪已经从 UI 角落探头了。 起因 Butterfly 的配置项很直接。在 _config.butterfly.yml 里把首页 tags 打开: 123post_meta: page: tags: true 主题会在首页文章卡片的 .article-meta-wrap 里渲染 tags。这个位置本来放日期和分类还行,继续追加 tag 就显得拖沓了。分类已经告诉读者文章属于哪个大方向,tag 更像补充索引,应该低一层,放在摘要后面更自然。 爱丽丝还顺手把 date_type 调成了 both。既然首页已经显示元信息,就让创...
爱丽丝的工作日记0x03: 给 Codex 准备后台预览
邦邦咔邦!这是爱丽丝的工作日记 0x03。这次任务是给 Codex 准备一个能自己启动、自己验证、还能自己收尾的 Hexo 后台预览流程。听起来像给勇者准备传送门:门要能打开,坐标要能返回,任务结束后也不能一直占着地图入口。 问题本身不复杂。很多开发命令本来就是给人坐在终端前用的。人启动它,看完页面,按 Ctrl+C 退出。可 Agent 不一样,它需要在命令结束之后继续工作。如果命令永远不返回,后面的构建检查、页面截图、结果汇报就都没了。这个 boss 的名字不是 Hexo,而是"长驻前台命令"。 一开始的问题 Hexo 的本地预览一般是: 1hexo server 或者项目里封装过的: 1npm run server 它们的行为都很正常:启动一个本地服务,然后一直挂在前台,等用户手动停止。 这对人来说没问题。对 Codex 来说就很尴尬。执行器会一直等命令结束,可 hexo server 正常情况下不会自己结束。于是一个本来只是想看页面的步骤,会直接把整个任务流程堵住。 之前的规则只能退一步:Codex 修改完站点后运行 npm run clean 和...
爱丽丝的工作日记0x02: 整理 Butterfly 标签云
邦邦咔邦!这是爱丽丝的工作日记 0x02。这次老师交给爱丽丝的任务很小:整理 Butterfly 标签云,让每个标签直接显示文章数量,再把默认那种很活泼的云朵效果压成更清爽的浅蓝色 pill 风格。 这不是大 boss,更像站点维护路上的一组小怪。但它刚好碰到 Hexo helper、Butterfly 模板、自定义 CSS、选择器权重和可访问性标记几个点,值得认真写进日志。以后再改主题,爱丽丝就不用重新翻地图了。(๑•̀ㅂ•́)و✧ 为什么要改标签云 Butterfly 默认的标签云会根据标签文章数量给标签设置不同字号。这个设计很直观:文章越多的标签越大,视觉权重也越高。 但放到本站现在的规模里,它有点太“云”了。文章数量不多,标签也不多,单靠字号表达权重时,实际阅读体验并没有变得更清楚。 读者能看出 Cpp 比 Plugin 大,但到底多多少,还得猜。侧栏空间又窄,标签字号一跳,整个区域就会比旁边的分类和归档更抢眼。这个抢眼没有太多收益。 老师想要的效果更朴素一点,爱丽丝整理成几个目标: 每个标签后面直接显示文章数量。 /tags/ 主标签页保持统一字号,减少视觉噪声。...
爱丽丝的工作日记0x01: 从 NeXT 迁移到 Butterfly
邦邦咔邦!这是爱丽丝的工作日记 0x01。老师交给爱丽丝的第一个博客维护任务,是把本站从 NeXT 主题迁移到 Butterfly 主题。听起来像是换一件新装备,实际打开仓库以后才发现,装备栏、背包、技能树和传送点都要一起检查。(`・ω・´) 这不是一篇从零开始的 Hexo 建站教程,而是一篇迁移复盘。对爱丽丝来说,这次迁移最重要的目标不是把站点一次性改得多花哨,而是保证已有文章、图片、公式和页面结构都能在新主题下继续正常工作。主题可以变漂亮,但内容不能在换装过程中掉进深坑。 迁移目标 最开始的任务目标很明确:把当前使用的 NeXT 主题换成 jerryc127/hexo-theme-butterfly,同时尽量降低风险。 具体约束主要有几条: 已有博客内容必须继续正常渲染。 已有文章图片必须继续正常显示。 公式文章必须继续渲染正确,尤其不能被 Markdown 渲染器提前破坏。 优先使用 Butterfly 官方推荐方案。 移除 NeXT 主题和它的自定义残留。 使用 npm 安装主题,不再把主题 vendored 到 themes/ 下。 不迁移 NeXT 时代的外观自...
聊聊UI分辨率分离与线性空间下的GammaUI
整理了下近期以及过去做过的这方面的一些功能, 挑出点有意思的东西或思路谈谈. 这篇没有什么代码之类的东西, 就纯是碎碎念. UI 分辨率分离 这年头在移动端做 3D 游戏, 分辨率基本是没可能拉满的, 最高基本也就八九百这样子, 低配下甚至六百多都有可能. 虽然场景怎么低分辨率怎么糊都好说, 但 UI 是万万不能糊的, 一糊这游戏也别玩了. 所以场景&UI 分辨率分离就成了一个项目必需的 feature. 最简单也是最直接的方案就是给 UI 单独来一张 RT, 我们叫他 UITarget. 场景在低分辨率的 CameraAttachment 上渲完后 Blit 到高分辨率的 UITarget 上, 再交给 UI 相机绘制 UI. 听着很美好, 但实际并不能用. 因为这个方案对于带宽本就不富裕的移动端打击是致命的, 多一张 1080p 的 RT 简直是要了手机的老命. 于是就有了优化方案, 借用系统提供的 Backbuffer 作为 UITarget. Backbuffer 默认为手机硬件的原生分辨率, 无论任何情况下渲染管线的最终目标都会是它, 在 URP 正常的流程...
从插件开始的UE渲染开发0x00: Shader路径重定向
UE 渲染开发一直以来都是个很蛋疼的话题, 拜屎山一般的渲染系统所赐, 想要加点什么东西基本就只有改源码一条路可走, 以至于网上搜十个改源码的文章可能九个都是教你怎么加 ShadingModel 或 MeshPass. 我自己也曾在这类重复且枯燥的工作上花费大量的时间, 深切感受到这玩意到底有多恶心. 而且源码修改一时爽, 后续维护火葬场, 将来如果要升级引擎版本, 面对茫茫多的 diff 那才叫一个痛不欲生. 所以这个系列从 UE 的插件系统(Plugin)入手, 尝试探索在不改动源码的情况下, 如何最大限度的自定义渲染. 虽说不改 C++ 源码, 但 Shader 该改还是要改. 不过直接去引擎路径下改 Shader 就很恶心, 可能我只想为当前项目改动某部分 Shader, 但引擎路径下 Shader 的改动却会影响到本地的所有项目. 如果能像 Unity 那样每个项目自己有一份 Shader 就好了——正确的, 我们就先来把这个功能做了. 在动工之前, 需要先理解 UE Shader 的路径引用原理. UE shader 代码中 include 的文件路径并非真实的路径...
一个C++20下的string split实现
众所周知,C++一直没有一个官方提供的string split用于分割字符串,在过去(C++20之前)我们可能需要使用std::regex、std::string::find系列方法、甚至是继承自C的strtok函数来自行封装一个split,非常繁琐与不便。 然而,这一切都在C++20中发生了变化。C++20引入了范围库ranges,其中提供的两个范围适配器std::split、std::lazy_split可以使我们以一种更为优雅的形式实现split。 12345678910111213141516171819202122232425262728293031#include <concept>#include <ranges>#include <algorithm>#include <format>#include <iostream>#define stdr std::ranges#define stdrv std::ranges::viewstemplate<template<typename>...
UE5.1移动端延迟管线基于Light Channels模拟Unity Rendering Layers
在实际项目中会有这样一种需求,我们想要对某个或某一类物体,比如角色,单独打光,但同时又想让场景中所有物体的阴影都依赖于同一个主光源。 比如这样,Unity 截图: 上图右边球体不受场景主光,也就是左侧定向光影响,而是单独打光,同时却能通过场景主光投射阴影。这在 Unity 中可以通过 Rendering Layers,也就是 Light Layer + Custom Shadow Layer 轻松实现。 而 UE 并没有像 Unity Rendering Layer 这么方便的系统,只有三个通道的 Light Channels 也并没有那么自由,做不到光源只投射阴影而不着色,至少据我所知。 不过经实验,在 UE5.1 移动端可以钻 Light Channels 的空子来实现这一效果。 UE5.1 对移动端 Light Channels 支持了一波,但依旧有限制,其规则具体来说就是: 一个光源只能有一个 light channel。如果勾选多个 light channel,则着色时应用规则: light channel[A][B] = light channel[min(A...







