
做长期项目的人大概都有这种体会一个东西拖到第一百多期进度报告的时候你已经不太记得第一期是怎么动笔的了。我手上这个架空世界构建项目就是这样从最初一张手绘草图、一份两千字的设定草稿一路滚到现在文档库里有三百多个文件、两千多条条目、七十多个可复用的美术组件。这次的第 153 期进度报告主角是我这个架空世界里偏中亚风格的一个文明模块内部代号就叫“阿富汗王国”。它不是历史复刻也不是某个真实政权的模拟而是一套纯架空的文明设定干旱高原上的土坯城镇、蓝釉砖拼出来的穹顶、几何纹样的手工织毯、铜壶里煮出来的加香茶。整套东西服务于我自己的一个独立游戏原型和一批插画产出。写这一期进度报告我想把过去三周里从设定补全、美术资产落地到系统参数调平的全过程摊开讲一遍涉及 worldbuilding 的拆解方法、Blender 与 Substance 的资产管线、JSON 驱动的事件系统以及长期连载式项目日志的写法。不管你是做独立游戏、做概念设计、写小说设定还是单纯喜欢折腾这种偏门项目的人应该都能从里面捞到点能直接抄的东西。1. 从“进度报告 153”说起长期连载项目的骨架怎么搭1.1 为什么我坚持用“进度报告”而不是“开发日志”这两个词看着差不多实际差别挺大。“开发日志”天然带着一种面向外部的姿态写的时候人容易端着想着要给谁看、要显得专业最后写出来的东西像是给投资人看的汇报。而“进度报告”这四个字对我来说是内部用语是写给三个月后的自己看的备忘语气松信息密度反而高。具体差别体现在三个地方。第一是时间锚点不同开发日志习惯按“主题”组织今天讲美术、明天讲玩法时间线是断的进度报告按“这一期我实际动了哪些文件”组织时间线是连续的回头查某次改动到底发生在哪一期特别方便。第二是颗粒度不同开发日志容易写成结论进度报告必须写过程包括那些最后被推翻的方案这些废弃方案才是最有价值的部分。第三是容错率不同开发日志写砸了会被读者挑刺进度报告写砸了只有自己遭殃所以敢写真实数据比如“这次贴图返工了四遍”“这个参数调了两天还是不对”。我从第 1 期到第 153 期中间有好几次想改成“开发日志”试过两期就放弃了因为一旦换成对外口吻写东西的速度会掉一半。所以我现在定的规矩很简单进度报告只对自己负责如果某期内容恰好对别人有用那是附赠的。提示如果你的项目周期超过半年强烈建议把项目日志做成固定编号的连载编号本身就是一种承诺机制它会逼着你每周至少产出一点东西不然编号就断了。1.2 153 期背后的节奏周更、月更和里程碑怎么配我这 153 期不是均匀分布的。前期大概是每周一期做了六十多期以后改成两周一期最近一年多基本是“月更 里程碑加更”的混合模式。这个节奏是踩过坑之后调出来的早期周更的时候为了凑内容经常写一些没营养的流水账比如“今天调了一个颜色”这种东西存下来毫无意义只会让文档库变臃肿。现在我的节奏是这样切的每个月至少一期常规报告记录本月完成量、遇到的问题、下月计划每当完成一个可交付的里程碑比如“某个文明模块的建筑组件全部完成”就插入一期加更的专题报告专门讲这一块的技术细节。第 153 期属于后者是“阿富汗王国”模块的建筑资产阶段性收尾。这里有个我实测有效的做法给每期报告打三个标签分别是常规、专题、复盘。常规报告控制在 800 到 1500 字专题报告 3000 字以上复盘报告不设上限。这样一年下来文档库自然形成层次找东西的时候先按标签筛再从编号定位效率比全文搜索高得多。1.3 这一期要交付什么把“一个王国”拆成可交付件“阿富汗王国”这个模块如果笼统地说“我要做一个文明”那是永远做不完的。所以我在第 148 期的时候做了一次拆解把它分成四个可独立验收的交付件交付件内容范围验收标准当前状态A 设定文档地理、气候、材料、工艺、日常器物条目 ≥ 120 条无空缺字段已完成B 建筑组件库墙体、穹顶、门廊、塔楼、院墙可拼接出 ≥ 20 种不重复建筑本期完成C 纹样与材质库瓷砖、织物、木雕、金属无缝贴图 ≥ 30 张可平铺完成 26 张D 系统数据派系、资源、事件模板JSON 校验通过逻辑可跑通进行中这一期报告主要汇报 B 和 C 的进展D 只讲数据结构设计。之所以拆得这么细是因为前几年我吃过“大模块无法验收”的亏——一个模块做了半年说不清到底完成没完成最后心态崩了直接弃坑。拆成可验收的小件之后每完成一件就能在进度报告里划掉一个方块这种可视化反馈对长期项目来说比什么都重要。2. 架空王国的设定拆解从地理到日常生活的四层结构2.1 第一层地形与气候决定建筑形态的底层参数很多人的世界构建是从画地图开始的我以前也这么干后来发现顺序错了。地图是结果不是起点。真正决定一个文明长什么样的是气候和可获取的材料。所以我现在做任何新模块第一步都是写一份“环境参数表”把几个硬指标定死后面所有设计都要服从这张表。“阿富汗王国”这块区域我定的环境参数是年降水量 200 到 350 毫米昼夜温差常年维持在 15 摄氏度以上夏季极端高温冬季有霜冻地表以砾石和黄土为主天然石材稀缺木材更稀缺只有河谷地带能见到成材的树木。这几个参数一旦定下来建筑的形态几乎是被推导出来的。降水量低意味着不需要陡坡屋顶来排水所以平顶和浅穹顶成为主流。温差大意味着墙体必须有足够的热惰性白天吸热晚上放热于是土坯墙的厚度被推到 400 到 600 毫米。石材稀缺意味着承重结构只能靠土坯和夯土装饰面则依赖烧制的砖和灰泥。木材稀缺意味着梁柱跨度受限于是空间被切分成小开间用连续的拱券来过渡。这套推导逻辑听起来简单但它的价值在于一致性。以前我做设定喜欢“看到什么好看就加什么”结果一个区域里既有北欧式的坡屋顶又有沙漠式的平顶自己看着都出戏。现在有了环境参数表当约束每一个设计决定都能回答“为什么是这样”。提示环境参数表不用写得很长六到八个字段就够降水、温差、主导风向、地表材质、可用木材、可用石材、可用燃料、交通半径。这八个字段几乎能推导出 80% 的建筑与器物特征。2.2 第二层材料与工艺土坯、灰泥与琉璃砖的三件套材料层是我这个模块里花时间最多的地方因为它直接决定了后面贴图和建模怎么走。“阿富汗王国”的建筑表皮我定了三种主材土坯、灰泥、琉璃砖。这三种材料的视觉特征、施工逻辑和老化表现完全不同必须分开处理。土坯墙是主体也是占比最大的表面。它的特征是颜色不均、有细微的颗粒感、边角会磨损成圆角、底部常有返潮留下的深色带。我在做材质的时候专门做了一个“湿度梯度”的思路墙脚往上 300 毫米范围内基色往深里压 8% 到 12%粗糙度提高 0.1 左右模拟水汽上升留下的痕迹。这个细节很小但加上之后整面墙立刻从“塑料感”变成“有年代感”。灰泥多用在室内和门廊是石灰加砂加纤维的混合物表面比土坯细腻但会有手工抹平的痕迹。这种痕迹的方向性很关键一个工人从下往上抹和从左往右抹留下的纹理完全不一样。我在贴图里用了一层方向性的法线位移来模拟参数上取 0.3 毫米左右的起伏频率控制在每米 15 到 20 道。琉璃砖是这个模块的视觉亮点也是最费工的。它的工艺逻辑是先烧制素砖再在表面施釉二次烧成所以每一块砖的釉面颜色都会有细微差别拼接之后形成一种“不整齐的整齐”。我一开始想做完全一致的砖块然后复制做出来的效果非常假像贴了壁纸。后来改成准备 12 种色差变体随机拼接真实感一下就上来了。材料基色范围粗糙度主要老化特征贴图分辨率土坯浅土黄到灰褐0.75 到 0.9底部返潮带、边角磨损2048灰泥米白到浅灰0.6 到 0.75抹痕、细裂纹2048琉璃砖钴蓝、青绿、白0.15 到 0.3釉面开片、局部剥落2048木构件深褐0.5 到 0.7干裂、虫孔1024铜器红铜到暗褐0.25 到 0.45氧化层、磨损高光10242.3 第三层纹样系统几何骨架加自由填充纹样是这个模块最容易做过头的地方。我第一版做了四十多种纹样结果拼到墙上像杂货铺完全没有整体感。第二版我引入了一个约束所有纹样必须建立在同一套几何骨架上。这套骨架的基础是“八点圆”构图简单说就是在一个圆上取八个等分点用直线连接这些点形成星形或多边形再以这个星形为单元向外复制。这个构图方式的好处是无论怎么填充出来的纹样都有内在的比例关系放在一起不会打架。我在 Blender 里用了一个几何节点组来生成这套骨架参数只有三个半径、边数、旋转角度。骨架定好之后填充环节才允许自由发挥。我准备了四类填充元素直线条带、藤蔓曲线、几何实心块、类文字装饰带。这里要特别说一句我用的“类文字装饰带”是纯装饰性的抽象线条不承载任何实际语义就是为了在视觉上模拟那种书写感不做任何真实文字的挪用。四类元素按比例混合大概是直线 50%、藤蔓 20%、实心块 20%、装饰带 10%。这个比例是通过反复对比调出来的直线占比低了会显得花高了会显得呆。我在第 151 期的报告里记过一组对比数据把直线占比从 50% 提到 70%整体“秩序感”评分从 7.2 掉到 5.8因为少了变化。2.4 第四层生活器物让场景有“人味”的关键建筑做完了其实还是空的真正让场景活起来的是器物层。这一块我列了五类织毯、铜器、陶器、木器、茶饮器具。每类做三到五个变体总共二十来件小道具。织毯是最花心思的。它的难点不在图案而在“软”这个特性。硬表面建模的思路完全用不上我最后是用布料模拟加手工修形的方式做的。具体做法是先建一个低模平面网格密度控制在 60×40然后做一次布料模拟让它自然下垂再把模拟结果烘成静态网格最后手动调整边缘的褶皱让四个角有一点不规则的卷边。完全对称的织毯看起来像打印出来的加了卷边之后才有“铺在地上被人踩过”的感觉。茶饮器具这块我做得特别细因为它在叙事上有用。一个铜壶、几只小碗、一个托盘这三件套往地上一摆不用写任何文字看的人就知道这里有人在生活。铜壶的材质我用了三层结构底层红铜基色、中层氧化暗斑、顶层磨损高光。磨损的位置集中在壶嘴、把手和壶底边缘这三处是手最容易碰到的地方逻辑上也说得通。提示道具的磨损位置一定要符合使用逻辑。手碰不到的地方出现高光磨损是新手最常见的破绽比贴图精度低更致命。3. 美术资产落地从概念稿到可复用组件3.1 参考板管理别在素材收集上无限拖延做任何模块之前我都会建一个参考板但我给自己定了一个硬规矩参考板的收集时间不超过两小时超时就强制停止。这条规矩是吃过亏换来的早年我经常在素材网站上泡一整天收藏几百张图最后一张都没用上因为收藏太多反而没法做选择。我的做法是把参考板分三栏结构参考、材质参考、氛围参考。结构参考只看形体关系不看材质材质参考只看表面特征不看形体氛围参考只看光影和色调。三栏各不超过 20 张加起来不超过 60 张。超了就删删的时候问自己一句“这张图我会在建模时打开看吗”答案是“可能吧”的直接删。“阿富汗王国”这一期的参考板我最后留下的是 14 张结构、18 张材质、9 张氛围。这个数量刚好够用又不会让人分心。3.2 建模与贴图的参数化思路把变量抽出来这个模块的建筑资产之所以能在一个月内做完核心原因是参数化。我把所有可能的变量都抽出来做成可调参数而不是每次重新建模。拿穹顶举例。我做了一个基础穹顶模型然后暴露了四个参数底面半径、起拱高度、肋条数量、顶部开口直径。底面半径默认 3.5 米起拱高度 1.8 米肋条 8 根顶部开口 0.4 米。这四个参数一调就能生成从扁平穹顶到高耸穹顶的一整个系列我用它生成了 9 种变体实际建模工作量只有一套。墙体的参数化更简单就是宽度、高度、厚度三个量。默认高 3.2 米、厚 0.5 米、宽 2.4 米这个尺寸不是随便定的它对应的是建筑模数的基本单元。为什么是 2.4 米因为拱券的常见跨度大概在 2 到 3 米之间取 2.4 米作为模块宽度拼接时不会出现尴尬的零头两面墙加一根柱子正好凑成 5 米开间做室内布局的时候特别顺。贴图的参数化稍微麻烦一点我用的是“材质集合 随机偏移”的方案。做法是把同一材质的 4 到 6 张变体贴图打包成一个集合在引擎里通过顶点色或者 UV 随机偏移来选变体这样同一面墙拼出来的砖不会重复。实测下来只要变体数量达到 5 张以上眼睛基本看不出重复。3.3 组件化与模块拼接三套墙体加五种穹顶组件化的核心思想是不做“一栋建筑”只做“能拼出建筑的最小单元”。我这一期最终交付的组件清单是这样的墙体 3 套平直墙、带拱洞墙、带壁龛墙每套 4 种宽度变体穹顶 5 种大穹顶、小穹顶、肋条穹顶、平顶带气窗、角部小穹顶门廊 4 种单柱、双柱、三柱、无柱拱廊塔楼 3 种方塔、圆塔、多边形塔各带 3 级高度院墙 2 种实心墙、带装饰孔洞的花墙连接件 6 种直角转角、内凹转角、十字连接、丁字连接、拱券过渡、檐口过渡这 23 类组件按不同组合方式拼理论组合数超过两千实际视觉上不重复的组合我也拼出了 23 栋建筑。这里的关键是连接件很多人做组件化会忽略连接件结果墙体之间拼不严缝隙明显。我专门做了六个连接件每个都保证和墙体的接口尺寸完全一致误差控制在 1 厘米以内。拼接的时候有个经验想分享先用灰盒gray box拼一遍整体布局确认比例和动线没问题之后再替换成正式资产。我一开始图省事直接上成品资产结果发现整体比例不对全部推倒重来浪费了整整四天。灰盒阶段的成本极低改十遍都不心疼。3.4 命名规范与版本控制别让项目毁在乱命名上命名这件事讲起来无聊但它决定了你三个月后能不能找到东西。我现在的命名规则是这样的[AFA]_[类别]_[子类]_[变体]_[版本]比如AFA_WALL_ARCH_V03_A表示阿富汗模块的墙体资产带拱洞类型第三变体A 版本。类别代码固定用四五个WALL、DOME、PORT、TOWER、CONN、PROP、TEX。变体编号用两位数补零。版本字母在重大改动时递增。版本控制我用的是 Git 加 LFSLFS 的追踪阈值设在 5 MB超过这个大小的二进制文件自动走 LFS。为什么要设 5 MB因为普通 Git 仓库对超过 5 MB 的文件处理效率会明显下降而贴图和模型文件很容易超过这个数。我把.blend、.psd、.tif、.fbx全部加进了 LFS 追踪列表。还有个小技巧每次提交前跑一遍命名检查脚本把不符合规则的文件夹出来。这个脚本不长但省下的找文件时间非常可观。import os, re PATTERN re.compile(r^AFA_(WALL|DOME|PORT|TOWER|CONN|PROP|TEX)_[A-Z0-9]_V\d{2}_[A-Z]$) def check(root): bad [] for dirpath, _, files in os.walk(root): for f in files: name os.path.splitext(f)[0] if name.startswith(AFA_) and not PATTERN.match(name): bad.append(os.path.join(dirpath, f)) return bad if __name__ __main__: result check(./assets) print(f不符合命名的文件共 {len(result)} 个) for p in result[:50]: print(p)4. 系统层实现让“王国”真的能跑起来4.1 派系数据结构设计先把字段想清楚再写代码美术做得再漂亮如果系统层接不上那也只是个模型库。所以这一期我开始设计“阿富汗王国”作为游戏内一个文明派系的数据结构。设计数据结构这件事最容易犯的错是先写代码再想字段结果字段越加越多最后自己都记不清哪个字段是干嘛的。我的做法是先用自然语言把需要的字段列出来写在一张表里想清楚了再转成 JSON Schema。这一轮我列的字段分五组分组字段类型说明标识id, name, tagstring唯一标识与显示名环境climate, terrain, resource_biasenum/array关联环境参数表建筑building_set, style_weightarray/float可用的建筑组件集合文化pattern_set, prop_set, palettearray纹样、道具、配色逻辑growth_rate, trade_focusfloat/array数值参数这里面style_weight这个字段值得说一下。它是一个 0 到 1 的浮点数表示这个文明在视觉上的“风格强度”数值越高生成建筑时越倾向使用同一套组件视觉统一性越强数值越低混搭程度越高。这个字段的存在是为了让不同文明放在同一个场景里时能有层次有的看起来整齐有的看起来杂乱。4.2 资源循环与平衡参数数值是怎么算出来的数值这块我没打算一次做到位但基础循环得先跑通。目前设计的是一个三资源模型食物、材料、工艺品。食物是基础消耗材料用于建造工艺品用于交换。参数定的过程是这样的。我先假设一张地图上有 8 个聚落每个聚落基础人口 40食物消耗按每人每周期 0.1 单位算那么总消耗是 8 × 40 × 0.1 32 单位每周期。产出端一个农业生产单元每周期产 6 单位食物那么需要的农业单元数是 32 ÷ 6 ≈ 5.33取整 6 个。这就有 6 个单元被食物生产占用了。材料方面一栋中型建筑消耗 120 单位材料计划在 20 个周期内完成 3 栋那么每周期材料需求是 3 × 120 ÷ 20 18 单位。一个采掘单元每周期产 4 单位材料需要 4.5 个取 5 个。这样算下来8 个聚落里已经有 11 个生产单元被占用平均每个聚落不到 1.4 个。这个比例明显偏高会导致工艺品生产几乎没有空间。所以我把食物产出效率从 6 调到 8材料产出从 4 调到 5.5调整后需要的单元数分别降到 4 和 3.3总共 7.3 个留出了更多空间给工艺品。这个过程听起来很枯燥但它说明一个道理数值不是拍脑袋定的是把总量拆成单元再把单元数量凑成整数反复试出来的。我在进度报告里习惯把这个计算过程写下来因为过三个月我肯定会忘记当初为什么定 8 而不是 6。4.3 事件触发与文本模板让王国自己讲故事事件系统的设计我采用的是“条件 权重 模板”的三段式。条件决定事件能不能触发权重决定触发概率模板决定事件在界面上长什么样。条件部分用的是一个简单的表达式列表比如resource.food 20 AND turn 10。权重部分是一个浮点数基础权重 1.0根据玩家的行为浮动。模板部分用的是带占位符的字符串比如“{settlement} 的粮仓见底了当地人开始用 {material} 交换食物”。我发现模板这个东西有个隐藏价值它会反过来倒逼设定补全。写模板的时候你会突然发现某个占位符找不到合适的填充内容比如我需要一个“当地特产”的占位符但设定文档里根本没写特产那就得回去补。这一期我一共写了 46 条事件模板其中 11 条在写的过程中发现了设定空缺回过头补了 11 条设定条目。模板的变量命名也要统一我定的是{settlement}、{resource}、{material}、{prop}、{time}这几个全部小写下划线。不统一的变量名到最后就是灾难我自己踩过这个坑出现过{settlement}和{Settlement}同时存在的情况运行时直接报错。4.4 工具链与自动化脚本把重复劳动干掉我的工具链不复杂但每一环都有脚本兜底环节工具自动化程度建模Blender几何节点生成纹样骨架批处理导出贴图Substance Designer / Painter参数化材质集合批量烘焙文档纯文本 Markdown脚本校验字段完整性数据JSON 校验脚本Schema 校验重复 ID 检查版本Git LFS提交前命名检查其中我最常用的一个脚本是 JSON 校验加重复 ID 检查。数据量到几百条之后手工检查根本靠不住。脚本逻辑很简单读所有 JSON检查必填字段是否存在检查 id 是否有重复检查引用关系是否指向存在的对象。import json, glob, sys REQUIRED [id, name, tag, climate, terrain] def load_all(pattern): data {} for path in glob.glob(pattern): with open(path, r, encodingutf-8) as f: data[path] json.load(f) return data def validate(data): errors [] ids {} for path, items in data.items(): if not isinstance(items, list): items [items] for item in items: for key in REQUIRED: if key not in item: errors.append(f{path}: 缺少字段 {key}) i item.get(id) if i in ids: errors.append(f重复 ID: {i} 出现在 {path} 和 {ids[i]}) else: ids[i] path return errors if __name__ __main__: all_data load_all(./data/*.json) errs validate(all_data) print(f共检查 {len(all_data)} 个文件发现 {len(errs)} 个问题) for e in errs: print(e) sys.exit(1 if errs else 0)这个脚本挂到提交前的钩子里只花不到一秒但拦住的问题可能价值几个小时的排查时间。5. 进度报告本身怎么写才有人看5.1 固定模板与栏目设置把写作成本降到最低写 153 期报告这件事能坚持下来靠的不是自律是模板。我给自己设的模板只有五个栏目每期必须填完但不允许超过五个本期编号与日期范围本期完成项用勾选框关键决策与理由这是最有价值的部分遇到的问题与处理方式下期计划不超过三条为什么限制在五个栏目因为栏目一多写作成本就上去了成本一高人就会拖延一拖延就会断更。我试过用十二个栏目的模板最长坚持了三期。第 3 栏“关键决策与理由”是我认为最有价值的一栏它记录的不是“做了什么”而是“为什么这么做”。比如这一期我记的一条是“穹顶肋条数从 12 改为 8原因是 12 根肋条在小尺寸穹顶上显得拥挤视觉密度超过了墙体纹样主次关系颠倒。”这条记录三年后我再看仍然能立刻明白当时的判断依据。5.2 数据与截图的可视化别只写文字纯文字的进度报告回头翻的时候会很痛苦因为人脑对数字和图像的记忆远强于对段落。所以每期我都会塞至少三样东西一张进度对比图、一张数据表格、一张实际截图。进度对比图我用的是最简单的柱状图横轴是交付件纵轴是完成百分比涂个色就行不需要任何美化。数据表格用来记录参数变动比如这一期记录了穹顶参数的三次调整。实际截图必须是引擎里的实时截图不能是渲染图因为渲染图会掩盖真实效果看着漂亮但骗自己。这里有个小习惯值得借鉴我把所有截图按yyyy-mm-dd_主题命名放在一个固定文件夹里。一期报告里引用截图的时候用相对路径。这样几年下来截图库变成了一个可检索的视觉档案找“三年前那个穹顶长什么样”只要按日期筛就行。5.3 读者反馈的分流处理别被意见带着跑虽然进度报告主要是写给自己看的但我也会把它发在几个小圈子里。收到反馈的时候我会做一次分流把意见分成“事实类”和“偏好类”。事实类是那种客观信息比如“你这个砖缝对不齐”“这个拱券的受力逻辑有问题”这类意见直接采纳改了就是。偏好类是“我觉得蓝色不好看”“这个造型不够大气”这类意见我会记下来但不一定改因为审美是主观的改多了会导致风格漂移。我踩过的坑是把偏好类意见当事实类处理有一次有人说不喜欢我用的那种偏灰的色调我回去整体调亮了一档结果整个模块的“干旱感”没了跟设定完全不符后来又全部调回来。这件事让我养成一个习惯收到意见先放一天第二天再看还觉得有道理才动手。6. 常见问题与排查技巧实录6.1 问题速查表这一期遇到并解决的问题整理成了一张表都是实际发生过的不是假设的现象原因解决方法耗时贴图拼接处有明显色带变体贴图边缘像素不连续用偏移法重做无缝边缘 32 像素做重叠混合3 小时穹顶法线方向错误建模时翻转面后未重算法线全选面执行重算法线检查开放边20 分钟建筑拼接出现 3 厘米缝隙连接件基准点偏移统一定义基准点为墙角外侧顶点1.5 小时引擎里材质数量超限每种变体都建了独立材质合并为材质集合用顶点色选变体半天JSON 校验报字段缺失早期条目按旧 Schema 写的写脚本批量补默认值逐条人工确认2 小时纹样拼接后出现错位骨架旋转中心不一致所有骨架统一以单元中心为原点1 小时道具磨损位置不对手碰不到的边缘出现高光按使用逻辑重绘磨损蒙版2 小时这张表的价值不在于解决问题本身而在于它记录了“哪种问题会反复出现”。我翻了一下前面 152 期里“贴图拼接色带”这个问题至少出现过 9 次。所以现在我的流程里加了一步任何无缝贴图做完之后先做一次 4×4 平铺测试肉眼确认没问题才进引擎。这一步只花五分钟能省掉后面几小时的返工。6.2 踩坑之后总结的几条硬经验先说第一条也是最反直觉的一条资产做得越漂亮越容易拖垮项目。这个模块的琉璃砖我一开始想做到每一块都能单独看结果单块砖的贴图做到 4096一面墙拼下来显存直接爆了。后来把单砖降到 512用材质集合的方式组合整体效果反而更好因为人眼在正常距离下根本看不到单块砖的细节看到的是整体色调和纹样的节奏。第二条任何一个参数都不要在没有参照物的情况下调。我在调穹顶起拱高度的时候前两个小时完全是凭感觉拖滑块拖到最后自己都不知道哪个更好了。后来我建了三个参考建筑并排摆放有了参照物十五分钟就定下来了。做视觉判断的时候同时看到多个方案远比反复切换单个方案有效。第三条文档和资产必须同步更新不能欠账。我有过一次欠账经历连续做了两周资产没写文档想着最后一起补结果补的时候发现有一半的决策理由已经想不起来了只记得结果不记得原因。从那以后我定了个规矩每天收工前花五分钟写三条当天记录哪怕写得很潦草也比事后回忆强。第四条别在同一个模块上停留太久容易审美疲劳。这个模块从第 148 期做到第 153 期中间我插了两天的其他模块就是一个完全不相干的山地聚落回来之后发现问题看得特别清楚之前纠结半天的配色方案一眼就定了。长期盯一个东西会导致判断力下降这个是有生理基础的不是意志力问题。第五条所有随机都要可控。纹样拼接、砖块色差、道具摆放这些地方我都用了随机但随机必须可复现。我的做法是给每一次随机都设一个种子值记录在进度报告里。这样哪怕过半年我想重新生成一遍也能得到完全一样的结果。不可复现的随机本质上等于不可控。最后提醒一句关于组件库的事。组件库不是越多越好二十三套组件已经把组合空间撑得很大了如果继续加边际收益会迅速下降维护成本却直线上升。我现在给组件库设了一个上限单个模块不超过 30 套组件超了就必须先删再加。这个限制逼着我去复用已有的东西而不是一遇到新需求就新建一个。这个模块后面还会继续下一步是把系统数据层跑通然后做一组实景测试看看建筑组件在实际引擎里大规模铺开之后的性能表现。等那一轮做完我再写第 154 期报告把帧率、批次合并、LOD 切换这些实测数据一起记下来。