空间与关卡:可信度的工程
空间与关卡:可信度的工程
目录
- 0 地基:玩家说的不是丑,是这东西在骗我
- 1 可信度五件套:挂进必经收口,而不是逐件手工调
- 2 灰盒纪律
- 3 道具可信度:先答因果,再摆物体
- 4 门的工艺清单
- 5 朝向与朝向缺失
- 6 反射面(镜 / 玻璃 / 窗)
- 7 尺度与比例只能靠截图
- 8 只在近处成立的东西要在真实触发点目检
- 9 风格化低多边形是一组耦合约束
- 10 反 backtracking
- 11 空间篇反例与边界情况速查
- 12 自查闸门清单
0 地基:玩家说的不是丑,是这东西在骗我
玩家吐槽空间时用的词是「太出戏」「没做完的作业玩具」「悬空的东西太出戏」。这些词共享同一个底层判断:宣称与呈现不符。
具体的违约形态:物件上出现了不该有的东西、锁着的门报出钥匙在哪、文件里写的楼层和你脚下的楼层矛盾、镜子另一侧透明、桌上没有积灰却积了灰的一半、柜子是实心的却要玩家伸手进去。
一次被骗,对整个世界的信任永久扣一格。 这条推导决定了本篇的全部做法:不要在「摆物件」这一层优化,要在收口处建立自动约束,让违约在物理上无法发生。逐件手工调的对象是场景里上千个物件,而收口只有几个。
第二条地基,与第一条同等重要:
细节的失败比粗糙更致命。
粗糙是玩家能接受的完成度,玩家会把它归入「这游戏就这样」。半成品是冒犯——玩家会判定「这游戏根本没做完」,而这个判定同样不可修复。推论:一件东西要么完整,要么隐藏,不要半露。
1 可信度五件套:挂进必经收口,而不是逐件手工调
这一节的五条,每条都给出:做法 / 为什么逐件处理必然漏 / 判据 / 边界情况。共同点是把约束挂进「所有物件都必须经过的那一个函数」或「所有玩家都必须跑的那一次检查」。
1.1 接触阴影 = 防悬空的设计模式
做法:不要逐件加阴影贴图。把「在脚下生成一片柔暗斑」写进家具注册的唯一入口函数。任何经由该函数注册的家具自动获得接触阴影。
推导:暗部环境里,物体是否「落在地上」几乎完全由接触处有没有暗斑决定,而不是由物体自身的明暗决定。玩家判断悬浮的依据就是那一小圈接触暗部。
为什么逐件处理必然漏:新家具是流程里最高频的产出物,逐件清单必然滞后于新增。手工清单的失败模式不是漏某一间房的墙,而是漏最新加的那把椅子——而它恰好是玩家最先看到的一件。
判据:新增任意家具不需要任何额外操作即拥有接触阴影;目检位列表必须包含每一件新家具的脚。
1.2 会打开的家具必须有真腔体
做法:柜、箱、抽屉必须是五块板围出的真实空腔——背板、左右侧板、顶板、底板,加一个前方开口。门板关上时是唯一的遮挡。禁止「实心箱 + 正面贴一块黑面片」假装内部。
推导:拾取射线只认最近命中。实心箱会让腔内物件在几何上不可达——玩家既看不见它,也点不中它。于是「开柜之后才可交互」这类门禁逻辑在实心箱上物理上不可能成立,它是逻辑正确但几何上不可玩。
判据:走完整条链——关着点不中 → 拉开 → 聚焦内部物 → 拿起 → 门解锁——并出一张能看到腔体内部的图做目检。
边界情况(重要):通用可达性探针拦不住这一类。可达性探针只测「未被门禁的交互物」,而被门禁住的恰好是它跳过的那些。所以这条要单独写一条断言:门禁后方物件在门打开后必须可达,且在门关闭时不可达。
1.3 一类表面只画一张画布,每片按世界坐标取贴图偏移
做法:一类表面(一种材质/一种砖)共用一张画布;每个实例用世界坐标计算贴图偏移与重复数。
为什么逐件处理必然漏:逐块各调一份(含随机斑驳)就是互不相干的多张画布,斑驳不连续;再加上每片都从自己的 UV 零点开始铺,格线与底色会在每一个门口跳一次——玩家把这读作「割裂感」,虽然他们说不出为什么。
天花更糟:重复数写死常数等于「每间房一格多大全看运气」。实测同图重复数从 0.33 m/格到 11 m/格,差 33 倍。
判据:一类表面一张画布 + 按世界坐标算重复与偏移(可断言:同类表面实例之间不存在各自独立的手调参数)。
唯一允许的例外:一块与别处无公共边的地面可以单独一套。这同时推出另一条约束:异质房间必须无公共边,否则缝隙处会露出生缝。
边界情况:贴图翻转方向要按表面朝向推算。面旋转 90° 会让其中一个轴翻转——同一个模块贴两次,两面的砖会跑错方向。
1.4 命中挡板一律设为不可见
做法:小物件需要不可见的挡板(球 / 面 / 盒)来扩大可命中角。但「不可见」必须用不参与渲染的方式实现,不要用透明材质。
推导:完全透明的体在掠射角、且与它穿过的表面相交时,会在轮廓上糊出一圈暗边。玩家看到的是「画外面一圈黑框」——一种极难自查的瑕疵。而拾取射线不检查渲染可见性,所以挡板设成不渲染照样点得中,两全其美。
判据:命中挡板不参与渲染;小物件的命中角在多个角度下均可达(多角度射线采样)。
例外清单(必须显式写出,不许一刀切):运行时驱动透明度的物体必须保持可见并正确参与渲染,例如门缝漏光、粉笔显影、镜中剪影。这类物件正是靠透明实现的演出。
1.5 装饰件一律标记为不参与射线
做法:纯装饰或平时隐藏的构件——灯座、灯杆、灯罩、托架、镜片、框——全部排除在射线命中之外。
推导:这类构件常贴在交互物表面或紧邻墙面。一个罩子就能让整面墙上的纸永远点不中。现象极难自查:玩家只会说「我明明看着它」,而排查时要先意识到「有东西挡在前面」,再意识到那个东西不该参与命中。
判据:全图可达性探针 + 一条专项回归——「最近命中是装饰件」这个分支存在即失败。
2 灰盒纪律
这一节的多数内容在公开资料里有成熟工艺可循(模块化 kit 工作流见 Greybox to Final、模块化道具 kit、Level Design Book 模数、模块化环境工作坊),此处按「对小团队独立项目的取舍」重组。
2.1 proxy 件
用尺寸与轴心与最终件完全一致的代理件做灰盒。美术 pass 变成「换 mesh」而不是重建,位置、网格、视线、玩法空间逐字节不变。
推导:独立项目尤其重要,因为你不打算做两次关卡。把「布局靠第二次重做来修正」写进计划,等于承认第一次布局是浪费。
判据:换 mesh 前后,同一组交互点的世界坐标一致(快照 diff)。
2.2 建模前定死三件事
网格模数、轴心约定、贴图密度。三件事定死之后再开始建模。
轴心约定:统一放在网格 footprint 的角落且落在地面平面上。建筑件通常取「底-后-左」。
推导:中心轴心会造成「每个角落 1cm 的缝」。原因是两件相邻时,缝隙分布在对角上,逐件看每一件都精确,只有拼起来才暴露——这是最难定位的一类误差。
判据:轴心规则写在 kit 文档第一行;导入检查断言轴心在 footprint 角落且 Z 在地面。
2.3 模数从玩法反推,不是从美观反推
角色胶囊高度、相机高度、下蹲高度、翻越高度共同决定最小门洞、走廊宽度、层高。
推导:两个人要错身 → 400cm 模数。选 200cm 会一直跟你作对:它不是选错一次,是每一个门洞、每一段走廊、每一处视线遮挡都要和它谈判一次。
判据:最小门洞、走廊、层高三个值都能从玩法数值表推导出来;推导链有书面记录。
2.4 先画连接矩阵
连接矩阵 = 每种件 × 每种它需要相遇的件 × 所需过渡几何。这张表能在纸上抓住「这套 kit 转不了弯」。
推导:它的价值在于发现时机。建了 20 个件之后才发现 kit 转不了弯,意味着 20 个件全部要返工;在纸上画矩阵的成本是一页纸。
判据:矩阵每一格都有结论(需要过渡件 / 不需要 / 明确禁止)。
2.5 先做基础件,不要先做变体
变体(贴图变化)是廉价的:加了变体之后不需要重新验证几何。先把基础件集合做对、做透,压力测试 kit 本身:
- 碰撞会不会把人卡住?
- 能不能搭多层?(地板必须有厚度,否则叠层时从侧面看是纸)
- 间隙够用吗?
2.6 误差累积
一件以 0.98×/1.02× 导出的模块单独看完全没问题。二十件接起来,误差累积到走廊对不齐——而关卡设计师只会报告「走廊接不上」,找不到源头。
做法:所有模块用同一套导入设置(缩放、朝向、枢轴);导入时做尺寸回归断言,偏差超容差直接报错,不允许「先这样」。
2.7 小团队的关键杠杆是 trim sheet
用 10–15 个模块做灰盒,同一张贴图集承载大量砖、线脚、装饰变化,把材质实例数压到很低。模块做双向(窗户内外同面)。接缝用装饰件遮挡——即 1.5 那条:装饰件不参与射线,所以遮挡不产生命中问题。
2.8 信任块的注意力预算
先投入建筑部分,用建筑的完成度把玩家的注意力从较少的小道具上引开。
推导:玩家在一个月里的注意力预算是有限的。全部投在小道具上,等于没有一处值得相信;建筑部分可信了,玩家的注意力标准会自动切换到建筑尺度的细节上。
3 道具可信度:先答因果,再摆物体
不要撒破坏。先逐条答因果问题,答案自然告诉你放什么:
- 这栋楼是怎么塌的?塌的方向是哪一边?
- 这里有没有水流过,能削弱某处结构?
- 这里的阳光够不够长出植物?
- 哪个表面适合让泥渗进去?
- 哪里是长期没人碰的位置,哪里是天天被碰的位置?
「用少量物体暗示复杂度」是被明确推荐的做法(见 环境叙事与道具可信度、Naughty Dog 场景构建访谈 与 顽皮狗的信任块构建法)。
3.1 互证:讲一个故事,不叠层
美术总监级的做法是:进入一个空间时讲一个故事,不叠太多层;所有资产都为强化那个故事而建;必须给玩家休息去处理细节。
配套提问法:先问原始意图是什么,再决定加细节。 例如一个商店很容易被堆满商品,但如果这个场景的目标是展示匮乏感,堆满商品就把目标反过来了。
3.2 灯光当注意力遮罩
在过于吸引视线的热点上压一层阴影,把注意力引回你希望玩家看的地方。这条在黑暗恐怖里尤其有效,因为黑暗本来就是遮罩,遮罩可以叠。
3.3 引导用「看上去就不通」的物理阻挡
给玩家的引导不是箭头,而是物理上走不通:植被、门、落差、堆放物。
推导:箭头要求玩家把画面外的知识带进画面里,而画面外的知识在恐怖游戏里通常不可信。物理阻挡把引导变成视觉事实,玩家自己读到。
判据:关卡里每一处「必须往这边走」都有对应的视觉阻挡物;不存在靠 HUD 箭头承担的引导。
4 门的工艺清单
门是关卡里出现频次最高、最容易做错、也最容易被玩家直接撞见的物件。按序检查:
- 门框填充贯通墙厚并带碰撞体。 薄框没有体积 = 玩家可以穿墙。
- 门板贴在扫掠侧的墙面上,铰链钉在洞口一端,绕铰链旋转,且旋转平面完全落在洞口带内。
- 关闭态门板填满洞口,缝隙只留铰链余量。
- 碰撞体跟门板走,不能留在洞口中心。否则玩家在离门板一米处撞上隐形墙——这是最常见的门 bug,且玩家只能描述为「这门很怪」。
- 通道方向与门板方向必须转置正确:「通道沿某轴穿过这扇门」意味着门板与碰撞体横跨该轴。写反就是门开进墙里。
- 每扇门显式声明扫进「能站人的那一侧」;两侧都能站人时,选开进房间那侧。
判据:逐扇三条断言——扫掠侧可通过 / 关闭时玩家被挡 / 打开后可通过。
边界情况:门洞格不参与墙体合并。历史上有过在这里出事的记录:合并之后所有房间被封死,游戏完全不可玩。这类缺陷的特征是「一整片区域全都不对」,不会只发生在一扇门上。
5 朝向与朝向缺失
做法:任何「写字板 / 挂牌 / 图纸」形态的物体必须显式给朝向,不许吃默认值。
推导:默认值会造出「侧着放、谁也不面向」的物证。玩家不会读它,也不知道它坏了——它只是安静地不提供任何东西。
朝向要对着会看它的人。已发生过的实例:接待台上的登记簿默认朝北,而桌子贴西墙、来客站东侧——谁也不面向。
平面件必须有倾角,否则命中角接近零。已发生过的实例:谱与琴面只差 1.5mm,而纯平纸的可命中角约 ±0.02 rad——玩家永远点不中,而且会认为那是背景装饰。
判据:
- 断言所有该形态物件的朝向显式给定,旋转值不等于默认角。
- 平面件对至少两个方向的观察者有可命中的倾角(多方向射线采样)。
6 反射面(镜 / 玻璃 / 窗)
必须有背板盒体,且两面都不透明、可被射线命中。 单面片会被背面剔除,玩家能绕到背后看穿。
反射面里的内容必须放在反射面之前一侧——按镜头在哪一侧算落点,不是按墙心算。
已发生过的实例:镜中剪影被放在自己的镜子背后 2cm。逻辑全对,布局合理,但永远看不见。这类 bug 的排查难点在于每一处单独看都对。
镜后留通道同样是 bug,除非那条通道被设计成可钻的伏笔。
反射面相交面在掠射角容易糊出暗边——见 1.4 的挡板纪律,挡板不参与渲染。
判据:反射面从背侧观察时不可透视;反射内容在真实触发距离上可见(有截图目检位)。
7 尺度与比例只能靠截图
做法:不要推理这类问题,看截图。
具体例子:自发光强度要避开后期量化的抖动带。过亮的自发光会变成规则的点阵,看起来像一块 LED 板。镜子应该是「比墙暗一点点,但能映出东西」——这个亮度关系只能看。
推导:量化抖动是屏幕空间的非线性过程,贴图通道上的非线性问题同理。两者都无法用「眼睛推演数学」得到答案,因为玩家看到的是量化后的结果而不是浮点结果。
判据:每一个涉及亮度/对比度/量化抖动的问题都有一条截图目检位,且目检图里有明确指认区域。
8 只在近处成立的东西要在真实触发点目检
做法:剪影、特效一类「只在近距离才成立」的演出,目检机位必须站在真实触发点上,不是一个方便的观察距离。
推导:距离会改变可读性。已发生过的实例:镜前剪影在 3.3m 外的截图里完全读不出来,而真实触发点是镜前 1.4m——在 1.4m 上它成立,在 3.3m 上它是一片糊。这一条决定了「用远处截图验收近处演出」是无效验收。
边界情况(会污染截图的隐藏逻辑):把演出计时钉在你想看的那一段。否则取景装置自己的清理逻辑会先把演出走完,你截到的不是要看的那一帧——已发生过一次「意外拍到结局卡」的截图,原因就是这个。
判据:每条近距演出有绑定到真实触发点坐标的目检机位;目检脚本里有显式的演出计时锚点。
9 风格化低多边形是一组耦合约束
做法:低分辨率 + 低模只是最表层。真正的效果来自一组互相耦合的约束,全部照做,不要只抄其中一条:
- 低分辨率帧缓冲
- 有限色深
- 按多边形条件启用的抖动
- 不做透视校正的仿射纹理
- 屏幕空间整数顶点吸附
- 顶点着色光照
- 深度提示雾
推导:这套效果依赖上述约束同时成立。只开低模而没有顶点吸附,得到的是「干净的低模」,玩家读作资产粗糙;同时开全部约束,得到的是「一个年代」,玩家读作有意选择。同一份网格在两种情况下评价完全相反。
边界情况:
- billboard(纸片)只在「转身即散」的余光剪影上成立。会被近距离直视、会被跟身后的实体必须是世界空间物体——纸片被靠近时会露馅(没有侧向体积、翻转不成立)。
- 低模角色在远处看起来像纸片很正常,这是风格的一部分,不要因此去加细节。
- 模型精度差不是加面数能解决的。那是权威数据不一致的问题——渲染网格与碰撞/导航用的形状对不上。加面数只会让不一致更难被发现。对应到机制篇:导航与碰撞必须共用同一个身体包络。
10 反 backtracking
做法:
- 单程控制在 60–90 秒。
- 返程时世界状态必须已经变了。
- 新信息只放在回程。
- 加长靠「同一空间逐层递进」(回环:同一条走廊每圈改一件事),不靠拉长走廊。
- 房间是线性消耗品,回环是同一批内容的二次使用。时长不够时优先加长回环的层数,而不是再盖房间。
推导:折返本身是恐怖资源,但只折返一次是纯消耗。回环的价值在于它把「熟悉」变成「被改动」——玩家对空间的记忆越强,改动的一处越有效。所以加时长的正确操作是把空间压窄加深,而不是把地图摊开。
判据:
- 每段返程路上至少有一处与去程不同的世界状态(可断言:状态差异点存在)。
- 每件关键物至少触发一处「已探索空间的状态变更」,且该变更有可断言的可见变化(巡逻区扩张、灯全灭、桌椅转向)。
进度化的「安全区塌陷」:拿到关键物之后要回头重扫已走过的空间,让旧空间因为你的进展而变形。这把 backtracking 从惩罚改成了进度反馈——玩家回头是因为世界变了,不是因为忘了路。
11 空间篇反例与边界情况速查
| # | 反例 | 为什么错 | 正确做法 |
|---|---|---|---|
| 1 | 逐件手工清单做接触阴影 | 新家具永远滞后于清单,而它是最先被看到的 | 挂进家具注册的唯一入口函数 |
| 2 | 实心箱 + 正面黑面片假装内部 | 腔内物件几何上不可达,「开门后可交互」物理上不成立 | 五块板围出真腔体,前开口 |
| 3 | 只跑通用可达性探针 | 它跳过被门禁的物件,恰好漏掉真腔体这类问题 | 门禁链单独一条断言 |
| 4 | 逐块各调一份画布(含随机斑驳) | 互不相干的多张画布,格线与底色在每个门口跳一次 | 一类表面一张画布 + 世界坐标偏移 |
| 5 | 每片从 UV 零点开始铺 | 同上,且玩家读作「割裂感」 | 偏移按世界坐标算 |
| 6 | 重复数写死常数 | 同图实测 0.33 m/格到 11 m/格,差 33 倍 | 重复按世界尺度算 |
| 7 | 异质房间有公共边 | 唯一允许的例外是有公共边的地面必须共用画布 | 异质房间必须无公共边 |
| 8 | 面旋转 90° 后贴图未推方向 | 一个轴翻转,同模块两面砖跑错 | 翻转方向按表面朝向算 |
| 9 | 用透明材质做命中挡板 | 掠射角糊出暗边,玩家看到「黑框」 | 挡板不参与渲染 |
| 10 | 把不渲染一刀切 | 门缝漏光、粉笔显影、镜中剪影会失效 | 例外清单显式写出 |
| 11 | 装饰件参与射线 | 灯罩/托架让整面墙的纸永远点不中,且极难自查 | 装饰件标记排除 + 专项回归 |
| 12 | 轴心放中心 | 每个角落 1cm 的缝,逐件看都对,拼起来才暴露 | 轴心在 footprint 角落、Z 在地面 |
| 13 | 从美观反推模数 | 每个门洞都要和它谈判一次 | 从角色/相机/下蹲/翻越高度反推 |
| 14 | 先做变体 | 变体廉价,但基础件未定型时做变体是双重返工 | 先基础件,变体最后批量加 |
| 15 | 地板零厚度 | 叠层时从侧面看是纸 | 地板有厚度 |
| 16 | 各模块用不同导入设置 | 0.98×/1.02× 误差累积成「走廊接不上」,找不到源头 | 统一设置 + 导入尺寸回归断言 |
| 17 | 门框无碰撞体 / 薄框 | 玩家穿墙 | 门框填充贯通墙厚并带碰撞 |
| 18 | 碰撞体留在洞口中心 | 玩家离门板一米处撞隐形墙 | 碰撞体跟门板走 |
| 19 | 通道轴与门板方向写反 | 门开进墙里 | 通道横跨门板,转置正确 |
| 20 | 门洞格参与墙体合并 | 已发生:所有房间被封死、游戏不可玩 | 门洞格豁免合并 |
| 21 | 物证吃默认朝向 | 「侧着放、谁也不面向」,玩家不读也不知道它坏了 | 该形态一律显式给朝向 |
| 22 | 朝向不朝向观众 | 已发生:登记簿朝北,桌子贴西墙、来客站东侧 | 朝向对着会看它的人 |
| 23 | 平面件零倾角 | 可命中角 ±0.02 rad,玩家永远点不中 | 给倾角,多方向采样断言 |
| 24 | 反射面是单面片 | 被背面剔除,玩家绕到背后看穿 | 背板盒体两面不透明可命中 |
| 25 | 反射内容放在反射面之后 | 已发生:剪影在镜子背后 2cm,逻辑对但永不可见 | 按镜头所在一侧算落点 |
| 26 | 镜后留通道 | 同上类 bug | 除非设计成可钻伏笔 |
| 27 | 用远处截图验收近距演出 | 3.3m 读不出、1.4m 成立 = 无效验收 | 机位钉在真实触发点 |
| 28 | 目检脚本不钉演出计时 | 取景装置的清理逻辑先把演出走完,截到别的帧 | 显式计时锚点 |
| 29 | 靠推理判断亮度/量化 | 玩家看到量化结果,看不到浮点值 | 看截图,每处留目检位 |
| 30 | 只开低模不做其余约束 | 读作资产粗糙而非有意风格 | 耦合约束整组照做 |
| 31 | 用纸片做会被近距直视/跟随的实体 | 无侧向体积、翻转不成立 | 只用于转身即散的余光剪影 |
| 32 | 用加面数解决「精度差」 | 那是权威数据不一致,加面数只会更糟 | 渲染与碰撞/导航共用身体包络 |
| 33 | 折返时世界不变 | 折返变成纯消耗 | 返程世界状态必须已变 |
| 34 | 时长不够就盖新房间 | 房间是线性消耗品 | 加长回环层数 |
| 35 | 引导靠 HUD 箭头 | 要求玩家引入画面外知识,而那知识不可信 | 用看上去就不通的物理阻挡 |
| 36 | 半露的装饰件 | 半成品是冒犯,比粗糙更致命 | 要么完整,要么隐藏 |
12 自查闸门清单
可信度收口
- 新家具不需额外操作就有接触阴影吗?
- 每个会打开的家具都有真腔体吗?门禁链四步(点不中 → 打开 → 聚焦 → 拿起)走通了吗?门禁链有独立断言(不靠通用探针)吗?
- 同类表面共用一张画布、按世界坐标取偏移吗?
- 命中挡板不参与渲染吗?例外清单里的东西仍然正确渲染吗?
- 装饰件全部排除在射线外吗?「最近命中是装饰件」这条分支不存在吗?
kit 与灰盒 6. 轴心规则写在 kit 文档第一行,且导入检查会拒绝违规件吗? 7. 三个模数尺寸都能从玩法数值表推导出来吗? 8. 连接矩阵每一格都有结论吗? 9. 地板有厚度吗?kit 碰撞不会卡人吗? 10. 全部模块用同一套导入设置吗?
门与朝向 11. 逐扇断言三条(扫掠侧可通过 / 关闭挡住 / 打开通过)都过了吗? 12. 门洞格不参与墙体合并吗? 13. 所有物证形态朝向显式给定、不等于默认角吗?朝向对着会看它的人吗? 14. 平面件有倾角且多方向可命中吗?
目检与截图 15. 每条近距演出有绑定真实触发点的目检机位吗?脚本里有计时锚点吗? 16. 每个亮度/量化问题有截图目检位吗? 17. 风格化渲染的七项约束是否全部开启?
结构与节奏 18. 每段返程至少一处世界状态变更吗? 19. 每件关键物至少触发一处已探索空间的变形,且有可见变化断言吗? 20. 关卡里每一处引导都有视觉阻挡物吗?没有 HUD 箭头在承重吗?
最后一遍扫一遍原则:找一个物件,问「它宣称了什么,它的呈现支持吗?」答案里出现「其实没做」的地方,就是玩家下一次退出游戏的地方。