Phase 1 mid-review + stress harness
- docs/MIDREVIEW.md: what M0'-M2.5 proved, bridge-layer LOC (~1100), key technical conclusions (4x4 transpose, animation method B, no handedness flip needed), remaining risks, recommendation = enter Phase 2 with a 3-item wrap-up (compare.py, dump_materials oracle, refocused perf). - harness MTGODOT_STRESS=N: grid of N animated warriors, vsync off, dumps test/godot-macos-stress.json. Frame times are throttle-capped in a background window (~30fps to 50 chars, 52ms at 100); the reliable signals are build cost ~165ms/char and the 100-char breakout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WaHYEY9rwLWt21PULiYjeJ
This commit is contained in:
@@ -31,6 +31,12 @@ func _ready() -> void:
|
||||
_build_environment()
|
||||
_build_sun()
|
||||
_build_camera()
|
||||
|
||||
var stress := OS.get_environment("MTGODOT_STRESS")
|
||||
if stress != "":
|
||||
await _run_stress(int(stress))
|
||||
return
|
||||
|
||||
_load_content()
|
||||
_frame_model()
|
||||
print("[mtgodot] harness ready")
|
||||
@@ -197,6 +203,80 @@ func _on_key(kc: int) -> void:
|
||||
_anim.call("set_time", _anim.call("get_time") + 0.05)
|
||||
|
||||
|
||||
## MTGODOT_STRESS=N : spawn N animated warriors in a grid, measure frame time
|
||||
## over ~180 frames, write test/godot-macos-stress.json, quit.
|
||||
## Feeds the Phase-2 animation A/B (per-frame set_bone_global_pose vs baked).
|
||||
func _run_stress(n: int) -> void:
|
||||
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
|
||||
Engine.max_fps = 0
|
||||
var model_path := _assets_root.path_join("PC/ymir work/pc/warrior/warrior_cheongrin.gr2")
|
||||
var tex_dir := _assets_root.path_join("PC/ymir work/pc/warrior")
|
||||
var anim_path := _assets_root.path_join("PC/ymir work/pc/warrior/action/dance_1.gr2")
|
||||
var cols := int(ceil(sqrt(float(n))))
|
||||
var t_build_start := Time.get_ticks_usec()
|
||||
for i in n:
|
||||
var m: Node3D = ClassDB.instantiate("Metin2Model")
|
||||
m.name = "M%d" % i
|
||||
m.set("texture_dir", tex_dir)
|
||||
m.set("gr2_path", model_path)
|
||||
m.position = Vector3((i % cols) * 1.2 - cols * 0.6, 0, (i / cols) * 1.2)
|
||||
add_child(m)
|
||||
var a: Node3D = ClassDB.instantiate("Metin2AnimPlayer")
|
||||
a.set("model_path", NodePath("../M%d" % i))
|
||||
a.set("anim_path", anim_path)
|
||||
a.set("time_scale", 1.0 + 0.01 * i) # desync
|
||||
add_child(a)
|
||||
a.call("reload")
|
||||
a.call("set_time", 0.13 * i)
|
||||
var build_ms := (Time.get_ticks_usec() - t_build_start) / 1000.0
|
||||
|
||||
_target = Vector3(0, 1.0, cols * 0.6)
|
||||
_dist = cols * 2.2
|
||||
_pitch = 0.35
|
||||
_update_camera()
|
||||
|
||||
# warm-up
|
||||
for i in 40:
|
||||
await get_tree().process_frame
|
||||
var total: Array[float] = []
|
||||
var proc: Array[float] = []
|
||||
for i in 240:
|
||||
await get_tree().process_frame
|
||||
total.append(1000.0 / maxf(Engine.get_frames_per_second(), 1.0))
|
||||
proc.append(Performance.get_monitor(Performance.TIME_PROCESS) * 1000.0)
|
||||
total.sort()
|
||||
proc.sort()
|
||||
var tsum := 0.0
|
||||
for s in total:
|
||||
tsum += s
|
||||
var psum := 0.0
|
||||
for s in proc:
|
||||
psum += s
|
||||
var report := {
|
||||
"characters": n,
|
||||
"build_ms_total": build_ms,
|
||||
"build_ms_per_char": build_ms / n,
|
||||
"frames": total.size(),
|
||||
"frame_ms_avg": tsum / total.size(),
|
||||
"frame_ms_p95": total[int(total.size() * 0.95)],
|
||||
"frame_ms_max": total[-1],
|
||||
"fps_avg": 1000.0 / (tsum / total.size()),
|
||||
"cpu_process_ms_avg": psum / proc.size(),
|
||||
"cpu_process_ms_p95": proc[int(proc.size() * 0.95)],
|
||||
"renderer": RenderingServer.get_video_adapter_name(),
|
||||
"method": "per-frame set_bone_global_pose (B)",
|
||||
}
|
||||
var out := OS.get_environment("MTGODOT_STRESS_OUT")
|
||||
if out == "":
|
||||
out = ProjectSettings.globalize_path("res://../test/godot-macos-stress.json")
|
||||
var f := FileAccess.open(out, FileAccess.WRITE)
|
||||
if f:
|
||||
f.store_string(JSON.stringify(report, " "))
|
||||
f.close()
|
||||
print("[mtgodot] stress ", n, " -> ", report)
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
func _screenshot() -> void:
|
||||
var img := get_viewport().get_texture().get_image()
|
||||
var path := "user://shot_%d.png" % Time.get_ticks_msec()
|
||||
|
||||
Reference in New Issue
Block a user