feat: импорт Roblox .rbxl карт (тест-фича МИНа) #33
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/rbxl-import"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
См. rbxl-importer/CHANGELOG.md (в studio) или ветку feat/rbxl-import.
Тестовый импорт Easy Obby: project_id 2697 (2244 primitives + 742 lua-scripts).
Lua-runtime тесты: 36/36 passed.
Доступ только МИНу (user_id=1).
Сегодня доведены до играбельного состояния: - UI модалка импорта подключена в KubikonStudio (кнопка для МИНа в навигации) - Converter: SCALE 0.35 (карта пропорциональна R15-персонажу), playerModelType='skin_bacon-hair', Lua упакован в поле code с маркером // @roblox-lua (storys API сохраняет только {id,code,target,name}) - vite.config: api+статика через rublox.pro/minecraftia-school.ru - GameRuntime: распознаёт маркер, запускает через RobloxLuaSandbox + wasmoon Worker. Фильтрация: target!=null + lua<2500б + лимит 50 sandbox'ов (WASM OOM при >50 VM) - roblox-shim: nullStub (Proxy с no-op методами) вместо null для FindFirstChild/WaitForChild — цепочки не падают - require() заменён на nullStub - RobloxLuaSandbox: совместимость с интерфейсом ScriptSandbox (sendGlobalEvent/SceneSnapshot/etc — no-op заглушки) - RobloxLuaWorker: pcall обёртка над user-кодом - remoteDevlog.js + /devlog endpoint: автосбор browser-логов - PlayerController._loadSkinManifest: dev-fallback на studio.rublox.pro Тест на Easy Obby: - 8205 instances → 2245 primitives + 742 Lua-scripts - 50/742 Lua-VM запущены (KillBrick handlers и т.п.), 151 отфильтровано как admin/chat services, 541 пропущено по памяти - Скин bacon-hair виден, FPS 20-25 - Сцена играется, можно ходить, прыгать TODO (следующая итерация): - Single-VM mode для wasmoon (один Lua-state на 742 скрипта, убрать WASM OOM) - Реализовать select/focus в иерархии для импортированных карт - Touched events от Babylon impostor → Lua-shim сигналы - Поддержка GUI (ScreenGui/Frame/TextLabel) в конвертере Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Все 5 задач итерации: 1. Single-VM mode (RobloxLuaSharedWorker/Sandbox): - один Worker, одна wasmoon-VM на ВСЕ скрипты проекта - addScript() для каждого, общий tick/event broadcast - снимает WASM OOM (1 VM 16MB вместо 742 × 16MB) - убран per-script лимит 50, теперь все 742 загружаются 2. Touched events: - sendGlobalEvent в shared sandbox распознаёт playerTouch и пересылает в Worker как 'touched' с primId - Worker находит Part по __primId в workspace и Fire'ит его Touched сигнал — Lua-обработчики работают 3. Click в иерархии → scroll-to-selected: - useEffect в HierarchyPanel ловит изменение selection и scrollIntoView для нужного ItemRow - data-sel-id атрибут на primitive/model/block строках 4. GUI Roblox в конвертере: - ScreenGui/Frame/TextLabel/TextButton/ImageLabel/TextBox → scene.gui c полным набором свойств (UDim2→pixel, Color3→hex, BackgroundTransparency→bgOpacity, parentId) 5. Чистка: - удалены debug-console.warn из PlayerController._loadPlayerModel (убирает spam '[PlayerController.devlog]' в consoles) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Бага: при выделении объекта в 3D-сцене иерархия не скроллила к нему потому что: - workspaceOpen=false скрывал всю секцию Сцены - rootPrimsOpen/rootBlocksOpen/rootModelsOpen=false скрывали корневые группы - openFolders=пустой Set скрывал все папки с импортированной геометрией Фикс: effect раскрывает все секции содержащие выбранный объект перед скроллом. После раскрытия использует rAF×2 чтобы дать React дорендерить ItemRow'ы, потом scrollIntoView. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>ITERATION 6 (single-VM rewrite): - RobloxLuaSharedWorker: один wasmoon-state на 742 скрипта (не 742 VM) - Pre-populated Workspace + Player.PlayerGui перед addScripts - На каждом Part — Touched/TouchEnded сигналы; на каждом TextButton — MouseButton1Click/Activated/MouseEnter/Leave; Humanoid с Died/Health - Двухфазный init: addScriptsBatch ВСЕ скрипты → kickoff() с PlayerAdded - wait()/task.wait/task.spawn/task.delay через scheduler+coroutines - guiClick от Rublox-GUI → fireEvent → инстанс.MouseButton1Click.Fire() - playerTouch → part.Touched.Fire(HumanoidRootPart) + humanoid.Touched ITERATION 7 (nullStub compatibility): - debug.setmetatable(nil, ...) + debug.setmetatable(function() end, ...) с полным набором __index/__newindex/__call/__add/__sub/.../__len/__concat - Возврат undefined из FindFirstChild/WaitForChild (вместо JS proxy) - Lua-side __null_stub_singleton с Connect/connect/Wait/Fire (lowercase aliases) - __rbxl_lookup_part через __rbxl_parts_by_id table (не ipairs на JS array) - script.Parent гарантированно не nil (либо реальный Part либо null stub) - RbxSignal: Connect+connect, Wait+wait, Fire+fire, Disconnect+disconnect - SIGNAL_NAMES whitelist расширен: Tool (Selected/Equipped), Remote (OnInvoke), ChatMakeSystemMessage, etc. Converter: - GUI: UDim2 dataclass правильно резолвится (scale*100 + offset/viewport*100) - размеры в процентах (как Rublox-GuiOverlay ожидает) - ScreenGui.Enabled → пропагируется в детей - Эвристика скрыть HD Admin/Chat/CommandBar/TeleportTo модалки - rbxasset:// rbxassetid:// фильтруются на пустой URL Hierarchy: - scroll-to-selected раскрывает workspace+rootPrims+folders перед scroll - data-sel-id на всех ItemRow с rAF×2 timing Известные ограничения: - Synapse X obfuscated скрипты часто всё равно падают (требуют конкретный Roblox-VM) - но debug.setmetatable перехват не даёт скриптам валиться на indexing/arithmetic - реальные пользовательские KillBrick (Touched) теперь работают - GUI кнопки → MouseButton1Click работают Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>