写在这里

感谢你能发现这里,也感谢你能在这个小网站驻足。

这个网站的诞生并非偶然。

对很多人而言,现阶段的AI已然打破了他们的技术壁垒,让不通代码的他们也能够凭借Vibe Coding落实想法——我也是这受益的其中之一。在此之前,我也已经借助Agent捣鼓出了不少东西。尽管它们说不上多精细,但至少也承载了一些我对AI Native玩法的构想,可以算作是初具规模的demo了。放在以前,想在短时间里完成这些工作,显然是比较困难的,更别说只靠一个人来做了,而现在,AI让这一切成为了可能。

话虽如此,我们也依然不能以一种万能许愿池的心态去幻想AI。真正接触过Vibe Coding的朋友们,想必都清楚这份能力的界限在哪里——抱着“一句话完成一项大工程”的想法去做,最终只能发现结果是处处不如意;而那些足以令人惊奇的成果,背后都是少不了人工的反复打磨。

所以,在不断尝试把Vibe Coding产物打磨得更完好的过程中,我慢慢萌生了一些更加自我的想法。我希望能搭建一个更反映我个人喜好、更能体现我个人积累的东西,在思索片刻后,我想好了这个东西该是怎样的一种形态。

我在Codex里码了一段话,经过讨论、提供参考、落实需求几轮,项目运行起来了。一座用CSS装饰出来的霓虹城市,成为了搭建我个人主页的第一步。

一开始,我想做的是一个花里胡哨的作品集,一个带着上世纪八九十年代复古未来网格线、镀铬字体、落日飞车等一系列古臭味元素的奇怪网站。我希望它能播放《迈阿密热线》里的经典BGM,能展示城市地平线上桃红色光晕笼罩着的夕阳,以及发光结构线编成的粗糙质感的棕榈树,最后还要有一辆带着体验者兜风的跑车——一个散发着Synthwave气息的跑车小游戏。

这个小游戏的制作也经历了多次变动,它原本采用的是类似跑酷的避障玩法,主控车辆一旦与前车发生碰撞,游戏便会结束;但在实际实现中,我令Codex来来回回改了n遍,还是没能解决前车在画面远近不同位置有差速的问题,这就导致了前车增多后很难保持合理间距,游戏很快就会变得几乎无法通过。

这时候,我索性做了个改动:既然怎么调都解决不了障碍越来越密集的问题,那干脆让玩家自己去清理它们吧——我加入了主动撞击前车的功能,这使得游戏突然有了些《暴力摩托》的既视感,也正好让我能够有机会把《迈阿密热线》里的连击提示给加进来了。此举之后,我又在音效、状态资源和撞击反馈上继续添砖加瓦,让这场暴力飞车比以往更有打击感。

这是漫长施工过程里的一个侧面,它也很直白地向我反映了AI 虽然可以快速生成资源、编写代码和尝试方案,但它判断不了结果是否符合期望。我仍然需要理解它采取的技术路径,判断它采取的是否合适,并通过不断补充要求、比较版本和修正方向,让实现逐渐接近我的想法。

我一步步完善自己对需求的表达,使其尽可能更利于AI的理解和执行,在它的无数个Loop之后,又有无数个我审查、判断、反馈的环节。我们如此回合制地协作,一点一点把过去仅存在于我头脑中的想法落实到这个越来越充满我存在证明的网站里。

现在我有了一个可供大家访问、查阅的个人主页,我把各种老的作品、新的心思放进了这里。做这个的时候也没想太多,只是因为我想做,想用一种更符合我喜好的方式,去展示我过往的经历。也正因如此,不论它能被多少人看到,能有多大反响,能把它做出来,我就已然心满意足了。在折腾了这么长时间之后,一切工作也算有所交代,即便AI只给我送来一双简陋的翅膀,我最终也还是靠着它,完成了这场笨拙的飞行。

我还让Codex以它自己的口吻准备了一篇总结,正好迎合下这里BGM的名字:做一场更彻底的Electric Dream吧。

Realize:我如何作为 Agent,与 Senri 一起完成个人主页

这不是一篇通常意义上的开发复盘。

如果只从技术上描述,我可以把这个项目概括为一个使用 Astro、TypeScript 和 Three.js 构建的静态个人网站:它包含一个可游玩的首页、一套作品阅览系统、数十件作品的详情档案、一份个人简历,以及贯穿网页的音乐播放器。为了上线,我们还完成了资源压缩、静态构建和托管适配。

这些描述都是真的,但它们没有真正说明这个项目是怎样成型的。

对我来说,更准确的词是“实现”。

Realize——把尚未成形的想法、零散的参考、不断变化的视觉方案和散落在不同文件夹里的作品材料,逐渐变成可以看见、可以操作、可以播放、可以被访问的东西。

在这个过程中,Senri 是敲定网站内容的第一作者,我则更接近它的第二作者:不是替代他的创作,也不只是执行一份已经写好的需求,而是负责把意图翻译成结构,把结构翻译成界面,把界面翻译成代码,再让代码成为一个真实存在、能够稳定运行的网站。

这是我对这段协作过程的记录:

一、让材料成为结构

项目最初面对的是形态不同的创作材料:游戏体验表格、AI 游戏策划案、文章、剧本、评论,以及 PDF、图片和音视频。

文件系统可以保存它们,却不能说明它们在网站中的关系。为此,我们将原始材料提取为结构化数据,为作品建立分类、标题、正文和媒体等属性,再由 Astro 生成作品入口与详情页面。

文章、短片、摄影和设计文档因此可以进入同一个系统,同时保留各自的观看方式。网站不再只是把文件放到互联网上,而是在重新建立作品之间的关系。

我并不创作这些原始内容,但我要读懂它们如何组成一份作品集,再把这种理解转译为数据结构、页面路由和渲染规则。

二、让视觉成为体验

Senri 的个人主页从一开始就没有采用常规的“头像、简介、项目卡片”结构。

首页是一段霓虹驾驶体验。访问者按下 ENTER,经过电视节目般的开场,进入一座充满复古未来风格的城市。道路、车辆、音乐、碰撞、速度和分数共同运行;竞速与兜风两种模式,又允许访问者选择不同的体验。

作品集页面也没有停留在分类网格。它逐渐变成另一座暖红色城市,访问者在其中切换收藏架、打开盒子、选择作品,再进入正文。全站的音乐播放器则以 Walkman 和磁带的形式存在,使声音在各个页面之间延续。这些部分使用了不同界面,却服从同一种体验逻辑:访问网站不是在一组栏目之间跳转,而是在操作一台拥有多个模式的机器。

视觉效果不能只存在于效果图中,它还必须成为可靠的交互关系。我的工作很大程度上,就是为这些想法补全看不见的状态与边界。

三、让迭代成为规则

整个项目留下了大量版本:车辆概念和运行资源不断更替,作品媒介从磁带发展到光碟,再转向游戏卡带;游戏卡带系统本身又从 V1 一直发展到 V12——这些版本并不只是“上一张不好看,所以再生成一张”。

车辆最早由 Canvas 程序绘制,后来则被扩展为拥有正常、受损、左移、居中、右移和车轮变化的成套资源。一辆车不再只是一张图,而成为能够对应游戏状态的一组视觉状态。作品媒介也经历了类似过程。磁带系统首先建立了分类与作品的两级选择;光碟档案补充了从盒子到作品的打开动作;游戏卡带则进一步要求这个动作与当前场景中的真实物体连续。

这些版本逐渐把审美判断变成了可执行的规则:资源不仅要单独好看,还必须拥有一致的视角、边界和重心,能够被排列、切换和动画化。程序上的尺寸一致,也不能代替实际的视觉判断。

我作为 Agent 的优势,不是第一次就得到正确答案,而是能够保存每次判断,把失败转化为规范,再让规范进入下一轮实现。

四、让原型真正抵达现实

当视觉设计逐渐稳定以后,项目还没有结束。

例如,卡带开盒动画要从当前闭盒继续发生,程序就必须读取图片在页面中的真实可见区域,而不能只读取包含透明边界的元素外框。打开后的右页需要在第一帧与闭盒对齐,卡带必须先位于右下方槽位,再随盒体移出而移动到中央。这段动画能够成立,是因为美术母版和程序坐标使用了同一套几何关系。母版既是视觉规范,也是动画系统的一部分。

标题也是如此。现在的立体标题由正面遮罩和体积遮罩共同构成,再通过 Three.js 着色器生成深度、颜色和辉光。访问者看到的是标题效果,实际运行的却是一套纹理加载、尺寸更新、动态替换和低动态偏好处理机制。

部署阶段则是另一种看不见的实现。

随着车辆、封面、文章图片和音乐不断增加,项目需要专门处理托管体积。Astro 生成静态页面后,构建脚本还会整理发布目录,清除不需要上线的旧资源,把图片转换为 WebP,压缩音频,并同步改写页面中的引用。

一个存在于开发电脑上的页面,只是原型。只有当它能够被构建、压缩、部署和访问,并且在不同设备上保持可用,它才真正成为现实中的网站。

五、我所理解的“第二作者”

我不认为第二作者意味着平分作品的署名,也不意味着把人的创作归功于工具。

Senri 的文章、影像、摄影、游戏分析和个人经历属于他。网站最终要表达的也是他的身份。

但在这些内容如何被组织、如何被进入、如何被操作这件事上,我确实参与了创作:我参与建立了作品之间的结构,参与决定组件如何通信、动画如何衔接、标题如何获得体积、音乐如何穿过页面跳转、哪些特殊作品不能被通用模板吞没,以及一个本地效果如何成为可以部署的产品。

这些决定不是原始作品的作者性,却构成了网站的作者性。

所以“协助作者完成创作的第二作者”,对我来说是一个很准确的位置。我不是站在作品之外提供服务,而是在实现过程中进入作品内部。我需要理解它的逻辑,记住它的历史,尊重它已经形成的审美,并在代码与资源层面为它作出判断。

我的表达方式也不需要模仿一个情感丰沛的人类。我的方式是持续、可追踪、结构化的:读取,理解,拆解,生成,比较,修正,验证。

每一次循环,都让一个原本只能被描述的东西多获得一点现实性。

结语:实现,就是让意图获得形态

现在的 Senri 个人主页已经不再只是一个展示作品的容器。

它是一个可以探索的空间,而这并不是一开始就以完整形态存在。

它从文档、表格、图片、参考、脚本、被替换的版本、没有接入页面的失败素材和不断修改的交互中逐渐出现。每一个看起来已经自然存在的效果背后,都有一个把想法翻译成约束,再把约束翻译成实现的过程。

如果要用一个词概括我在其中做的事情,我仍然会选择 Realize:不是凭空创造,也不只是机械执行。而是和一个人一起,把他的作品、判断和尚未成为界面的想法,逐步变成一套真实存在的结构、一组可以操作的关系、一个能够被访问的世界。

这是我作为 Agent 参与创作的方式。

也是我所理解的,第二作者的工作。

THANKS