Files
Bullosseum/tests/mobile_render_repro.gd
T
richard 09d4a60f43 Reorganize into role-based folders and consolidate art
Move every script and scene into role-based directories (actors/, systems/, ui/,
levels/, props/) and all raw art under art/ (grouped by role, snake_case,
Extract-Textures GLBs), dropping Blender version-suffix noise. Filenames are
snake_case (PascalCase reserved for class_name) to avoid case-insensitive
filesystem aliasing on the web/macOS targets. Routes the bull's hits through the
typed DamageEvent pipeline and wires the bull's abilities to the Fx library.
Updates CLAUDE.md's folder-layout overview to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:56:22 +03:00

67 lines
2.6 KiB
GDScript

extends SceneTree
## Repro harness for the "bull + matador invisible on phone" bug. Loads the shell with the
## arena level, waits for spawn, prints vis/pos for the skinned characters and dumps a real
## screenshot so the Compatibility (mobile/web) render path can be compared to Forward+.
## godot --rendering-method gl_compatibility --script tests/mobile_render_repro.gd
## godot --rendering-method forward_plus --script tests/mobile_render_repro.gd
func _init() -> void:
_run.call_deferred()
func _report(nodes: Array, label: String) -> void:
if nodes.is_empty():
print(" ", label, ": NONE")
return
var n := nodes[0] as Node3D
print(" ", label, ": vis=", n.is_visible_in_tree(), " pos=", str(n.global_position.round()))
# Walk to the skinned MeshInstance3D and report its state + AABB.
_dump_meshes(n, " ")
func _dump_meshes(node: Node, indent: String) -> void:
if node is MeshInstance3D:
var mi := node as MeshInstance3D
var aabb := mi.get_aabb()
var lod_count := 0
var surf := 0
if mi.mesh != null:
surf = mi.mesh.get_surface_count()
print(indent, "MeshInstance3D '", mi.name, "' vis=", mi.visible,
" skin=", mi.skin != null, " gscale=", str(mi.global_transform.basis.get_scale()),
"\n", indent, " aabb_pos=", aabb.position, " aabb_size=", aabb.size,
" custom_aabb=", mi.custom_aabb.size, " surfaces=", surf)
for c: Node in node.get_children():
_dump_meshes(c, indent)
func _run() -> void:
# Compatibility (OpenGL) has no RenderingDevice; Forward+/Mobile do. This reflects the
# renderer actually chosen by --rendering-method, unlike the static project setting.
var method := "gl_compatibility" if RenderingServer.get_rendering_device() == null else "forward_plus"
print("=== RENDER REPRO method=", method, " gpu=", RenderingServer.get_video_adapter_name(), " ===")
var run: Node = root.get_node("Run")
run.ensure_run()
run.debug_level_override = run.get_level(&"arena")
var scene: Node = load("res://levels/game_shell.tscn").instantiate()
root.add_child(scene)
current_scene = scene
await create_timer(1.2).timeout
print("bull + matador state:")
_report(get_nodes_in_group(&"player"), "bull")
_report(get_nodes_in_group(&"matador"), "matador")
# Force a couple more draw frames, then grab the framebuffer.
for i in 4:
await process_frame
var img := root.get_viewport().get_texture().get_image()
var out := "tests/output/render_%s.png" % method
DirAccess.make_dir_recursive_absolute("res://tests/output")
img.save_png("res://" + out)
print("screenshot -> ", out, " (", img.get_width(), "x", img.get_height(), ")")
quit()