From 0ed6ff130d324fd54feed338e00c1c79607deb29 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Wed, 8 Jul 2026 09:02:01 -0400 Subject: [PATCH] feat(godot): Sleep blocks the VM thread so the compositor presents paced frames op 0xc8 -> Thread.Sleep(duration ms) on the VM background thread (capped 10s); main thread keeps compositing -> the sleep-paced opening burst gets frames to show. Unit = ms (RE-confirmed). Selftest OK (plumbing parity; synthetic scene has no sleep). Co-Authored-By: Claude Opus 4.8 --- godot/GodotAdvHost.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/godot/GodotAdvHost.cs b/godot/GodotAdvHost.cs index 6462850..7021e41 100644 --- a/godot/GodotAdvHost.cs +++ b/godot/GodotAdvHost.cs @@ -42,6 +42,17 @@ public sealed class GodotAdvHost : IHost // called from the main thread (click) or the selftest auto-clicker public void SignalInput() { if (_gate.CurrentCount == 0) _gate.Release(); } + // op 0xc8: block the VM background thread so the main-thread compositor (Main.Recomposite in _Process) + // presents the current retained GfxState — this is what makes the sleep-paced opening burst animate. + // Time-based sibling of WaitForInput's suspend. The native op arms a non-blocking main-loop-polled timer; + // blocking this throwaway task thread is behaviorally equivalent given our threading model. Operand is + // MILLISECONDS (docs/engine-re.md sleep section + opcodes.toml 0xc8). Headless CLI hosts no-op it (parity). + public void Sleep(long duration) + { + int ms = (int)System.Math.Clamp(duration, 0, 10_000); // cap so a pathological script can't hang the window + if (ms > 0) Thread.Sleep(ms); + } + // ---- texture ops (run on the VM thread; marshal Godot node work to the main thread) ---- public void CreateTexture(int slot, int width, int height) { _slotBmp[slot] = null; _slotDims[slot] = (width, height); }