项目启动
第一天就把最硬的那块地基浇下去:一条能跑的 WebGPU 着色器管线、完整承接的渲染设备层、一个跨环境的显存生命周期热修,以及一个并发安全、输入更扛得住的聊天 agent。万丈高楼,从能在浏览器里正确点亮第一个像素开始。
为什么第一天从渲染地基开始
这是整个平台公开记录里的第一天。一个"聊着天就能做出游戏"的平台,最底下必须先有一件事能成立:浏览器里要能真正、稳定地把 3D 画面画出来。所以第一天没有去堆花哨的界面,而是把精力全压在最硬的渲染地基上——直接基于浏览器新一代图形能力(WebGPU)自研一套渲染管线,而不是借现成的通用库套个壳。这条路一开始更难、更慢:很多别人封装好的细节都得自己重走一遍,踩的坑也得自己一个个填。但它决定了之后画质、性能、特性是不是都掌握在自己手里,而不是被上游库的取舍卡住脖子。今天交付的几件事,合起来其实是同一件大事的不同侧面——"让第一个像素在浏览器里被正确点亮"。把这件最容易被低估、却最不能将就的事先做扎实,后面"对话生成游戏"的所有想象才有立足之地。
着色器管线跑通:WGSL + 着色器编译垫片 + 简化 PBR
渲染的核心是着色器——告诉显卡"每个像素该是什么颜色"的小程序。这天把一整条着色器管线打通:用浏览器图形标准的着色器语言(WGSL)来写,配上一个能把着色器源码就地编译成显卡可执行格式的"编译垫片",再实现了一套简化版的基于物理的着色(PBR)。"基于物理"意味着材质对光的反应遵循真实世界的规律——金属看起来像金属、塑料看起来像塑料,而不是一块涂了颜色的纸片。这套简化 PBR 刻意用了精炼的资源绑定结构(只用三组绑定),在保证画面可信的前提下尽量轻,既好理解也好扩展。"编译垫片"这一步尤其关键:WebGPU 自身不直接吃高级着色器源码,中间需要一道把源码翻译成底层格式的工序,把它在浏览器里就地解决,才让"写一段着色器就能直接看到效果"成为可能。从这天起,引擎不再只是能给三角形涂个颜色,而是能把"被光照亮、带材质质感的物体"渲染出来——这是从"能画"迈向"画得对"的关键第一步,也为后面所有更复杂的材质、光照效果定下了正确的起点。
渲染设备层完整承接
着色器要跑起来,底下还得有一层"渲染设备层"打理一切:申请显卡资源、管理画布表面、把每一帧的绘制指令组织好提交给显卡。这天把这一层从头到尾完整承接,并分阶段把整条链路逐一验证走通——从最初的初始化,到能稳定地一帧接一帧出画面,一系列里程碑全部打勾。这层东西平时玩家完全看不见,但它是所有画面的"总管":它稳,上面的游戏才稳;它有窟窿,再漂亮的特效也会随机黑屏或崩溃。很多渲染问题表面看是某个特效坏了,根子其实在这层没理顺。把它做成"分阶段、可验证"的形态,还有一个长远好处:以后任何一帧出问题,都能顺着这一层层的里程碑往回查,定位到底是哪一环断了,而不是面对一片黑屏束手无策。先把它做扎实,等于给后面每一个渲染特性都铺好了一条可靠的轨道。
跨环境的第一道难关:显存生命周期热修
在不同环境里跑 WebGPU 时,显存缓冲区有一套严格的"什么时候能用、什么时候该交还"的生命周期规则;一旦时序没对齐,就会出现读到一半的脏数据、或者干脆崩掉。这天热修了缓冲区在"映射读写"阶段的生命周期问题,让它在两种差异很大的环境下都按规矩走:一种是没有独立显卡时用纯软件来模拟渲染,另一种是浏览器直接调用本机图形能力的原生路径。同一段代码要在这两条路上都不出错,意味着每一处对显存的申请与归还都得拿捏好时机。这类修复没有任何"看得见的新功能",却正是它们决定了引擎是"在我这台机器上偶尔能跑的玩具",还是"换一台机器、换一种环境也照样跑的底座"。自研渲染的代价,很大一部分就花在这种把跨环境不确定性一个一个堵掉的苦功上;每堵掉一个,平台能可靠覆盖的设备就多一片。
多 agent 并发的安全:给每个 agent 上生命周期锁
平台的另一面,是那些跟你聊天、替你干活的 agent。这个平台从一开始就设想"一群 agent 同时干活"——主控派活、子 agent 各做一摊,而不是一次只跟一个助手对话。可一旦多个 agent 并发,就会冒出经典的"竞态"问题:两个动作几乎同时去改同一个 agent 的状态,谁先谁后没保证,结果就是偶发的错乱或卡死。这天把每个 agent 的生命周期管理抽成了一个独立的"异步锁"组件:对同一个 agent 的启动、停止、切换等操作会被这把锁串起来排队执行,保证任意时刻只有一个动作在动它的状态。这样一来,多开 agent 不再相互踩脚,行为变得可预期。对一个把"多 agent 协作"当作核心卖点的平台来说,这把锁是让那张蓝图能落地、而不是停留在演示里的关键一环。
终端体验更扛得住:粘贴不死机 + 协作沟通指引
除了并发安全,聊天 agent 在"日常手感"上也补了两处。其一是终端输入:修了一个"粘贴时第二次就卡死"的老毛病,让在命令行里粘贴长段需求文本更有韧性——你把一整段设定、一份长长的需求贴进去,它不会再因此僵住。其二是协作沟通:给 agent 之间互相发消息的工具补全了使用场景与回复指引,让"谁该在什么时候、用什么方式给谁发消息"有章可循,多 agent 协作时的沟通不再各凭感觉。这些都是"用起来不别扭"的关键细节:一个会在你粘贴需求时崩掉、或者协作起来你一言我一语乱成一团的助手,再聪明也没法放心托付。把这些粗糙的边角一个个磨平,才谈得上让人愿意把真正的活交给它。
对话不浪费缓存:动态提醒改为追加新消息
和大模型对话时,前面那段稳定的上下文可以被"缓存"下来,从而省时省钱;但如果每次都去改写最前面的内容,这份缓存就被作废,得重新算一整遍。这天把"动态提醒"(那些随对话变化、临时要塞给模型的信息)从"改写最前面"改成"在末尾追加一条新消息",从而保住前缀缓存不被打断。对你的直接体感就是:长对话的响应更快、花费更省。这类优化单看很小,但在一个会跟 AI 长时间来回协作的平台上,它累计起来就是实打实的流畅度差别和成本差别——而且越往后、对话越长,这一处当初做对的决定就越值钱。它也透露出一种贯穿整个项目的取向:把"和模型怎么对话"当成一门要认真打磨的工程,而不是随手拼个 prompt 了事。
这一天意味着什么
把第一天的几件事连起来看,会发现它们刻意没有一件是"给人看的功能":没有漂亮的首页,没有可炫耀的 demo。它们是渲染、引擎、并发、对话这四条主线各自的第一块基石。这背后是一个清醒的判断——"对话生成游戏"这件事最终能不能成,不取决于第一天能不能演示出花活,而取决于地基够不够硬:浏览器里画得出、换环境跑得稳、多 agent 不打架、长对话不烧钱。今天把这四块地基同时浇下去,后面的每一天才能在它们之上稳稳地往上垒。这也是这份更新日志想为未来开发留下的第一个范本:先把最难、最不出彩、却最不能将就的东西做对。