- 新增 script/playable_soak.sh:先做 soak 配置/资源校验,无 --allow-gameplay 只校验不启动客户端;N(>=10) 次独立正常退出运行 + 墙钟 soak,失败即停止后续 运行并记 BLOCKED;写本批次 release-manifest.json 后聚合 - run_client_gate.sh:确认的故障代理对所有 suite 启动(共享场景的退出运行也经代理); soak 超时下限只约束 soak 客户端(validate_soak 增加 soak_client 参数) - 新增本地 127.0.0.1 故障代理、RSS 采样/内存判定、窗口/指标/流程模块及其测试 - forest_mob_render_test 输出 PASS/FAIL 标记,供 rendering_batch_test.sh 识别 - 新增 docs/FIRST-MAC-PLAYABLE-STATUS.md:如实记录 PASS/BLOCKED、已知问题与环境需求 - .gitignore 排除本地场景配置、凭据文件与运行输出 离线回归:rendering_batch_test.sh failures=0,playable_gate_test.sh PASS, node 夹具测试 PASS。未联网运行,未重建候选包。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ft3kXpNdLbKEfg5uDLfqVF
44 lines
1.8 KiB
GDScript
44 lines
1.8 KiB
GDScript
extends SceneTree
|
|
const MobView = preload("res://ui/mob_view.gd")
|
|
var failures := 0
|
|
func _init() -> void:
|
|
call_deferred("run")
|
|
func run() -> void:
|
|
for mode in ["0", "1"]:
|
|
OS.set_environment("MTGODOT_GPUSKIN", mode)
|
|
# 101/110/20001 是原全怪物回归基线;2301-2315 是首测鬼木林树怪(MAP-01)。
|
|
for race in [101, 110, 20001, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2311, 2312, 2313, 2314, 2315]:
|
|
var view := MobView.new()
|
|
if not view.build(AssetRoot.path(), null, race):
|
|
failures += 1
|
|
view.free()
|
|
continue
|
|
root.add_child(view)
|
|
view.anim.set_process(false)
|
|
view.anim.set_time(0.3)
|
|
var signed_area := 0.0
|
|
var total_area := 0.0
|
|
for instance in view.model.find_children("*", "MeshInstance3D", true, false):
|
|
for surface in instance.mesh.get_surface_count():
|
|
var arrays: Array = instance.mesh.surface_get_arrays(surface)
|
|
var vertices: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX]
|
|
var normals: PackedVector3Array = arrays[Mesh.ARRAY_NORMAL]
|
|
var indices: PackedInt32Array = arrays[Mesh.ARRAY_INDEX]
|
|
for i in range(0, indices.size(), 3):
|
|
var a := indices[i]
|
|
var b := indices[i + 1]
|
|
var c := indices[i + 2]
|
|
var cross := (vertices[b] - vertices[a]).cross(vertices[c] - vertices[a])
|
|
signed_area += cross.dot((normals[a] + normals[b] + normals[c]).normalized())
|
|
total_area += cross.length()
|
|
var ratio := signed_area / maxf(total_area, 0.00001)
|
|
print("MOB winding race=%d GPU=%s normal_alignment=%f" % [race, mode, ratio])
|
|
# Godot's outward front face is clockwise; geometric cross is -normal.
|
|
if ratio >= -0.5:
|
|
failures += 1
|
|
printerr("FAIL: NPC/monster faces disagree with outward normals")
|
|
view.free()
|
|
await process_frame
|
|
print("mob_winding_test: failures=%d" % failures)
|
|
quit(1 if failures else 0)
|