原版视觉变体、同步随机流与父子姿态

本批结果

本批补两类实际实例输入所需的内核:

  • 622DF0视觉变体选择及676F60同步随机包装:3144组原生对照一致,同时比较选中值、完整lo/carry状态和getter不写回索引的行为。
  • Ogre Node::updateFromParentImpl姿态传播:1616组输入×三种精度=4848次原生对照逐位一致
  • F2RoomPieceCollision新增同一次选择的视觉/碰撞资源配对;不各自抽取索引。
  • 新增父节点先行的姿态解析器,对缺父节点/环报错,不改成世界根。
  • 1196条核心断言、126项相关Python检查通过;Godot C#零warning/error,coresimlint通过。

前批289个未解析场景变体仍不能直接标成关闭:选择内核已完成,但实际地图开始时的完整同步RNG状态、此前随机调用和原加载顺序仍未接入。全武器构造覆盖维持1053/1419。

原版变体选择

piece+0x170构造为0xFFFFFFFF,即随机/无效索引。622DF0:

  1. 有有效GUID、定义holder和定义指针时,用定义FILE数量;否则有效数量按1处理。
  2. 无符号比较判断storedIndex是否在范围内。
  3. 已在范围内:原样返回,不耗随机数。
  4. 有效数量为1:返回0,不耗随机数。
  5. 其余调用676F60(0, count-1)。

676F60直接使用g_seed_synced,地址361A8A0,内核为676B30的MWC。它先按有符号参数判断hi>lo,只有成立才推进状态。

因此数量为0时调用的是带钳位的(0,-1),返回0且不推进;不能替换为会推进的裸Range(0,-1)。

取证地址:622DF0、6234B0、676F60、676B30。 EXE SHA256: 186472c3057b38f4cdff4696959a943c396ae6166995f7418997b5ea853e8a5e

NativeRoomVisualVariation.Resolve复现getter,不修改存储索引。 Select另外复现6234B0在定义FIXEDVARIATION(+0x3D)为true时的写回:

情况当前选中值存储索引再次调用
有效指定索引原索引不变不耗随机数
随机且FIXEDVARIATION=true本次随机结果写回结果复用结果
随机且FIXEDVARIATION=false本次随机结果仍为随机哨兵会再抽取

原生oracle完整运行622DF0 → 676F60 → 676B30,关闭原可选调试日志,不替换随机函数。包括缺定义、0/1/多数量、无符号高位、0吸收态及随机lo/carry输入。 固定变体写回和资源选择外围以6234B0原始指令及核心测试验证;本批没有完整执行含模型装载的6234B0。

同一次视觉/碰撞选择

原6234B0在查看碰撞数量和MESH OVERRIDE之前就解析视觉变体:

  • 没有COLLISIONFILE也可能消耗一次视觉随机数。
  • MESH OVERRIDE存在也不能跳过该次抽取。
  • MESH OVERRIDE随后替代视觉文件,并令COLLISION ENABLED=false。
  • COLLISIONFILE数量等于FILE数量时,用同一个选中索引;数量不同时取碰撞第0项。
  • FIXEDVARIATION决定是否保存结果,不决定这次视觉和碰撞是否共享结果——这次总是共享。

F2RoomPieceCollision.SelectResources返回选择结果、StoredAfter、视觉路径、碰撞路径与最终碰撞启用位。它不自行加载模型、不重新生成场景RNG。 原LoadCollision接口保留严格模式:调用方未提供多变体结果时仍报缺输入,不暗中抽取。

实际skull_convex_01测试沿真实有序资源列表选择并加载对应碰撞几何,验证仅消耗一次随机数。

为什么转换器种子不能直接代替原版状态

同步MWC需要完整lo和carry。原设置低种子操作还可能保留旧carry;原seed=0入口涉及GetTickCount,而MWC裸(0,0)是吸收态。

当前转换器TL2_LAYOUT_SEED=0及其分组选择,不等于原g_seed_synced=(0,0),也不证明整个原地图加载到某个物件之前消耗了几次随机数。 不能把289个候选全部强行抽成0,再以“函数测试通过”宣称场景对齐。

Ogre父子姿态传播

读取原Ogre导出表,地址:

  • Node::updateFromParentImpl:10112DA0。
  • Quaternion乘Quaternion:1014D500。
  • Quaternion乘Vector3:1014D7D0。

原DLL SHA256: 974c1dc77ea2818276cc7eb94a8b95b2ccf8595e28fa3f14b2cd6d516fdb67a1

有父节点时:

text
derivedOrientation =
    inheritOrientation ? parentOrientation * localOrientation : localOrientation

derivedScale =
    inheritScale ? f32(localScale * parentScale) : localScale

scaledPosition = f32(localPosition * parentScale)
rotatedPosition = f32(parentOrientation * scaledPosition)
derivedPosition = f32(rotatedPosition + parentPosition)

关键:位置始终使用父旋转和父缩放,不受两个继承开关影响。继承开关只控制派生旋转/缩放字段。

无父节点时直接复制局部四元数、位置和缩放。四元数乘法按原指令顺序转写,不额外归一化。

本批将1014D500加入既有符号转写工具,生成数学叶子从5个增加到6个,原有矩阵/射线回归全部保留。 DeriveNodePose处理上述数值;ResolveNodePoses按依赖先解析父节点,缓存单次调用结果,对缺父节点、环或过深拓扑明确拒绝。

原生姿态对照范围

原生工具运行真实Node::updateFromParentImpl,以夹具vtable提供已解析的父姿态,分别测试全部继承开关组合、有/无父节点、非均匀/负/零缩放和随机姿态。

  • 4848次派生四元数、位置、缩放的float bits全部一致。
  • 756组输入会因PC24/53/64而产生不同输出。
  • 有父节点时原函数总按旋转→缩放→位置读取三个父getter,即使两个继承开关均关闭。
  • 工具也观察原parentDirty清零、transformDirty置位,但当前C#只移植数值及拓扑解析,没有宣称Ogre节点缓存/通知生命周期已搬完。
  • SceneNode额外的附属物件通知不在这个Base Node数学对照范围内。

纯姿态拓扑解析顺序不能当作原模型资源加载顺序:前者不消耗RNG,后者会消耗。也不能用返回字典顺序替代已验证的碰撞面遍历顺序。

Room Piece碰撞还必须使用piece自身缩放,不是把这里的derivedScale直接送入碰撞矩阵。derivedScale用于继续向子节点传播姿态;碰撞的自身scale规则在前批原622950取证中另行确认。

接线边界与下一步

后续:原局部姿态设置已补给定方向列到四元数/节点的精确链;二进制属性顺序、YAW及完整初始化仍未完成。

仍缺:

  1. 原版LAYOUT属性设置到局部四元数/节点关系的生产方,不能用Godot矩阵分解随便代替。
  2. 实际父节点继承开关、模型动画状态及加载后的双烘焙状态。
  3. 同步随机流起始lo/carry、完整调用与实例加载顺序。
  4. 条件分组分类、空间分区候选与完整世界LOS消费者。
  5. 原版实际运行线程浮点精度,以及异常/非有限姿态行为的完整验证。

NativeNodePose与NativeRoomVariation登记为Transient;没有新持久实例注册表或存档字段。以后接入实例所有者时必须保存FIXEDVARIATION写回结果及必要源状态,不得因为这里是临时结果而丢失持久信息。

验证与文件

text
python -m tools.build_native_room_variation_oracle
python -m tools.build_native_node_pose_oracle
dotnet run --project core_sim.tests
python -m unittest tests.test_native_room_instance_inputs
dotnet build torchlight-2-poc/TL2Poc.csproj
python -m tools.coresimlint
  • core_sim/NativeRoomVariation.cs。
  • core_sim/NativeNodePose.cs。
  • core_sim.io/F2RoomPieceCollision.cs。
  • build/native_room_instance_input_core.log:1196断言。
  • build/native_room_instance_input_python.log:126检查。

按godot-master的数据/表现分层,本批只补输入与数值,不改画面;main原地工作,未提交、未attach原游戏。 默认存档hash保持: 9840fe858b6e311c73f8c2d4ed49912d59d71365f6278392811730e012d32a7f