1. CFrame.to_euler_xyz переписан под Babylon YXZ convention:
rx = asin(-r12), ry = atan2(r02, r22), rz = atan2(r10, r11).
Раньше извлекал XYZ-Euler → Babylon применял как YXZ → клины,
мостики, наклонные постройки рендерились повёрнутые
(примеры из ROBLOX Battle: мостик торчал в стену).
Учтён gimbal-lock на X=±90°.
2. Lua watchdog в _startSingleScript и __rbxl_drain_handler:
debug.sethook(yield_50ms, '', 50000) — каждые 50k Lua-инструкций
принудительно yield 1 кадр. Защищает от:
while not workspace:FindFirstChild('X') do
workspace.ChildAdded:wait()
end
где наш stub :wait() возвращает -1 мгновенно — раньше скрипт
подвешивал вкладку (50k+ итераций в секунду). Сейчас yield'ит,
tickScheduler возобновляет.
3. Signal.Wait возвращает -1 как 'no-arg yield marker'. Сейчас
не используется в Lua, но если позже сделаем wrapper — будет.
ROBLOX Battle карта (arch1_ROBLOX_Battle_v2.rbxl, 1677 примитивов,
66 скриптов) — теперь не должна подвешивать.
Деплой rbxl_types.py на VM 130.