这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《游戏引擎实现原理》11.1 WGSL 组织与 include
WGSL 没有 #include,但引擎要把公共函数拆成多个文件复用:本节在 createShaderModule() 之前做一层文本级 include 展开,处理递归、去重与循环检测,并真跑一次编译与像素回读,验证拼接后的模块确实可编译可用。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
WGSL 没有 #include,但引擎要把公共函数拆成多个文件复用:本节在 createShaderModule() 之前做一层文本级 include 展开,处理递归、去重与循环检测,并真跑一次编译与像素回读,验证拼接后的模块确实可编译可用。
六个开关朴素地给出 2^6=64 个着色器变体,但特性之间有依赖,真实可达集只有 32 个。这一节按依赖枚举可达变体、用内容寻址(源码 + 开关集合的哈希)给编译结果去重,并在 headless Chromium 里把全部可达变体编译一遍,验证 0 error、非法组合会被拒。
WGSL 没有预处理器,材质却要在多种开关组合下生成不同程序。这一节实现一个只认 #ifdef / #ifndef / #else / #endif 的行级宏展开器,把一份模板裁剪成具体变体,并在 headless Chromium 里逐个编译验证 0 error。
把材质拆成「模型(参数声明)+ 实例(参数值)」两层,按 std140 算出每个参数的字节偏移并打包成 uniform buffer;再在 headless Chromium 里把它绑进管线、渲染一帧、回读中心像素,断言它就是 baseColor。
从 Tracer/Span 门面为什么存在讲起,用本机 jar 核实的签名拆解一次 span 的生命周期,说明 ObservationHandler 链如何让一次观察同时产出指标与 span,对比 Brave 与 OpenTelemetry 两种桥接、MDC 日志关联、概率与限速采样的组合,以及 W3C traceparent 与 B3 的报文差异。
把 18.1 的架构决策落成代码:分层骨架与关键接口、跨模块契约与统一错误码、借阅上限的乐观锁加唯一约束兜底、借书事件的可靠投递,并把单元、切片、Testcontainers 集成与契约测试串成四层测试,最后给出本地起依赖到联调前端的可复现步骤。
15.2 的校验只会说「过 / 不过」,但反作弊需要的是「可疑到什么程度」。本节给 aegis 写三个真跑的零件:令牌桶限速、指数衰减的嫌疑分、以及把分数映射成处置的阈值表。核心是一个处置梯度——限速、标记、断开、封禁,宁可分级也不一刀切,把误伤的代价压到最低。
移动和战斗是外挂最爱下手的两条路径。本节给 aegis 写一套真跑的校验:把「目的地」当提议、用位移与时间的比值判定超速、用单帧位移上限抓瞬移、用线段采样挡穿墙,再让服务端独占技能冷却与命中判定;并说明为什么校验函数要写成无时钟、无 I/O 的纯函数。每条规则都配了断言,跑得绿才贴进来。
外挂的根子不在客户端有漏洞,而在服务端信了不该信的话。本节把权威边界画清楚:哪些字段客户端只能提议、哪些必须由服务端裁决;再用一个真跑的信任契约表证明——客户端一旦发来服务端自有字段就是违规。最后说明为什么信任模型必须落到字段级,以及「把一切搬上服务端」并不是正确答案。
延迟补偿不能无限给:给得越多,被击中的玩家越觉得「明明躲开了」。本节给补偿套上上限——回退窗口取「绝对上限」与「最大补偿 RTT 的一半」的较小值,并用一个 RTT 追踪器识别「平时很快、开枪瞬间掉包」的延迟作弊,最后讨论被高延迟玩家击杀的体感如何用反馈层缓解。
「我屏幕上打中了,为什么没伤害」和「我躲进掩体了,为什么还被击中」是同一枚硬币的两面。本节实现延迟补偿裁决:为每个实体保存历史位置,按「服务端当前时间 − 半程 RTT − 插值延迟」把世界回退到射手当时看到的那一刻再做命中判定,并用确定性测试复现这两种不公。
「现在几点」这个问题在服务器上比想象中难:墙钟会被 NTP 校时、被 GC 暂停打断,客户端时钟和服务端更是各走各的。本节把逻辑时间与墙钟彻底分离,用单调钟搭一条只向前走的时间线,用 NTP 四时间戳估出客户端时钟偏移,并用确定性测试演示一次向后跳变是怎么被时间线吸收掉的。
逻辑层拿到权威状态了,渲染层还没完:远端玩家的位置是离散快照,直接画会一顿一顿地跳。本节给 aegis 的 predict 包补齐渲染侧的三件工具——用位置插值把快照之间补平、用速度外推兜住「快照还没到」的空档、用误差平滑把 13.2 的校正摊到多帧上,并给出各自的取舍与真跑测试。
预测让客户端先走一步,但权威永远在服务端:一旦服务端的答案和本地不一致,客户端必须回滚到权威状态、把未确认的输入重放一遍。本节把 13.1 的输入缓冲接到和解逻辑上,讲清裁剪-复位-重放三步、用一条测试给回滚的代价定上界(重放条数只跟 RTT 有关),并给出和解误差阈值的取法与「小误差平滑、大误差瞬移」的判据。
客户端先走一步能掩盖一个 RTT 的延迟,代价是服务端必须记住每个玩家「已经确认到哪一条输入」。本节给 aegis 的 predict 包写一个真实的输入缓冲:客户端给每次输入编号、本地立刻前进、把未确认的输入排进重放队列,服务端回一个确认号。最后用固定随机种子跑 500 步确定性回放,验证「服务端同意时客户端预测与权威状态逐字节相等」。
本节讲清审计日志与普通日志的区别:普通日志可丢可采样,审计日志必须完整、必须能证明没被改过。用追加式加哈希链实现审计日志,每条记录带前一条的哈希,改任何一条都会让链断掉。真跑:写 5 条记录、校验链完整、篡改中间一条再校验,打印「第 N 条校验失败」,并给出审计字段表与保留策略表。
本节给 ResearchCopilot 补上输出侧三道关:① 敏感信息用正则加结构化检测,命中就脱敏或拒答,并讨论误伤;② 越狱与不当内容靠独立于模型的检查层,不指望提示词;③ 幻觉引用校验把每条引用回语料核对(存在吗?支持吗?)。真跑三条答案,打印三道关各自的判定与最终处置,并给出校验项清单表。
本节给 ResearchCopilot 立起输入侧护栏:先讲清 Agent 特有的四个注入面,重点剖析检索文档里的间接注入为何最危险,再落分层防御——内容与指令分离、工具白名单与参数校验、危险动作人审、长度与频率限制。用一段自造的含注入指令假文档,真跑无防护版(删除真被执行)与有防护版(注入被当资料、危险工具被拦)两次轨迹。
讲解 .NET Aspire 的应用模型与资源编排,覆盖 AppHost 分布式应用构建、服务发现与依赖注入、OpenTelemetry 遥测与健康检查、Dashboard 本地开发体验,以及从本地到生产部署的资源供给差异与清单生成的落地实践。
调试信息把机器码映射回源码。本文讲解 DWARF 的 DIE 树与节区组织、行号状态机与行号表生成,分析优化导致的变量位置变化与 location list、内联调用点信息,再落到 JavaScript Source Map 的 VLQ 编码、分离调试信息与调试体验优化。