class_name EffectPrewarm extends RefCounted static func run(game: Node) -> void: if DisplayServer.get_name() == "headless": return var overlay := CanvasLayer.new() overlay.layer = 120 var cover := TextureRect.new() cover.texture = load("res://assets/ui/boot_splash.png") cover.expand_mode = TextureRect.EXPAND_IGNORE_SIZE cover.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED cover.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) overlay.add_child(cover) game.add_child(overlay) var viewport := SubViewport.new() viewport.size = Vector2i(256,256) viewport.own_world_3d = true viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS viewport.msaa_3d = game.get_viewport().msaa_3d game.add_child(viewport) var scene := Node3D.new() viewport.add_child(scene) var camera := Camera3D.new() scene.add_child(camera) camera.position = Vector3(0,3,12) camera.look_at(Vector3(0,2,0)) camera.current = true # Render actual effect geometry in an isolated, undisplayed viewport. CombatVisuals.explosion(scene, Vector3.ZERO) CombatVisuals.impact(scene, Vector3(0,2,1)) CombatVisuals.flash(scene, Vector3(1,2,0)) for kind in ["flame", "embers", "smoke", "fireball", "flash"]: CombatVisuals.puff(scene, Vector3(0,2,2), 1.0, kind, 10, Vector3.ZERO) for frame in 4: await game.get_tree().process_frame await RenderingServer.frame_post_draw print("EFFECT PREWARM complete renderer=", RenderingServer.get_current_rendering_method()) viewport.queue_free() overlay.queue_free()