Skip to content

性能、静体与局部子系统

VVE 的成本近似由“活动物体数 × 每物体碰撞点数 × 每点介质候选查询 × 每 tick 子步数”决定。优化的第一原则是减少没有信息增益的工作,而不是把所有常量调小。

成本从哪里来

成本项典型放大因素
实例遍历活动物体数量
碰撞点换算每物体采样点数
方块/实体介质探测搜索范围、候选实体数、探测入口
子步global_rate
显示同步display 数量、乘客树、每 tick NBT 更新
调试绘图/输出粒子、tellraw、trace 事件数

降频不是简单跳过帧

对远处或低优先级对象,可以降低物理更新频率,但必须决定被跳过的时间如何表示:

  • 每 N tick 执行一次原步长:物理时间变慢;
  • 每 N tick 执行一次放大步长:可能穿透和数值不稳定;
  • 使用 slow key/mov:保持中间运动连续,但仍需模型支持;
  • 只降低显示同步:物理保持准确,画面更新变少。

因此“每 4 tick 跑一次 main_c”不是通用优化配方。它改变了模拟语义。

静体优化应放在业务层

当前 VVE 3.0.1 没有一个可对所有模型直接启用的完整 sleep/wake API。业务模块可以实现自己的静体状态:

text
连续 N 帧满足:
  |v| < v_threshold
  |ω| < w_threshold
  支撑接触稳定
  外部冲量队列为空
→ 标记 sleeping,停止完整 main_c

唤醒条件至少包括:

  • 收到外部冲量/力偶矩;
  • 支撑介质移动、销毁或材质变化;
  • 被玩家/脚本显式操纵;
  • 附近动态实体可能发生碰撞;
  • 模拟器常量或时间尺度发生不兼容变化。

只凭“速度恰好为零一帧”休眠会把碰撞顶点、抛物线顶点也错误冻结。使用连续帧滞回:进入休眠阈值小,唤醒阈值大,避免临界抖动。

局部子物理系统

“局部子系统”不是当前源码里一个现成模块,而是一种组合策略:按空间/玩法边界把对象分组,每组有自己的候选实体、模拟器状态和预算。

示例:

text
arena_a
  simulator_a
  tag=vve_region_a
  只查询 a 区域的实体介质

arena_b
  simulator_b
  tag=vve_region_b
  可使用不同重力/摩擦

设计约束:

  1. 一个活动实例同一时刻只属于一个模拟器;
  2. 跨区迁移要在完整帧边界执行;
  3. 两个区域若允许互撞,必须定义边界交互,不能双方都忽略对方;
  4. 各模拟器每轮先 vve:_consts,再覆盖自己的常量;
  5. 实体查询尽量使用区域 tag 与合理距离,而不是全世界扫描。

实用优化顺序

  1. 关闭正式环境中的 GELib 粒子与逐帧打印。
  2. 确认没有重复调度。
  3. 选择更轻模型:能用 point 就不使用刚体,能用 block 就不使用 cubox。
  4. 减少碰撞点,保留支撑和形状关键点。
  5. 缩小实体介质候选范围;普通物体不要无条件用 _detect_large
  6. 把 display 同步放到 sync_funcs,高速子步中只算物理。
  7. 对确实稳定的对象做业务 sleep/wake。
  8. 最后才考虑区域降频或多模拟器分区。

建立性能预算

为目标场景固定基准,例如:

text
版本:26.2
对象:64 block + 16 cublock
碰撞点:8/对象
子步:1
场景:平地 + 8 个实体介质
要求:20 TPS;单 tick 命令数 p95 < 预算;无积压

同时记录“活动/休眠对象数、探测调用数、候选实体数、命令数、tick 时长”。只有 FPS 不能区分 GPU 画面压力和数据包 tick 压力。

VVE 由小豆 8593 开发;本站是面向学习与查阅的增强文档。