# Lua API — журнал изменений Файл фиксирует **что было добавлено в Lua-runtime** при работе с реальными Roblox-играми. Цель — потом продублировать тот же API для **JS-движка** (на будущее, сейчас работаем только с Lua). Формат: дата + что и почему + куда добавлено + надо ли портировать в JS. --- ## 2026-06-08 — Итерация 3: ROBLOX Battle (arch1_ROBLOX_Battle_v2.rbxl, проект 2851) **Контекст:** PvP-арена 2009 в XML, 1677 примитивов, 66 скриптов, 4 команды (TeamBeacon), 5 оружий, 12 батутов, KillFeed, раунды. ### Реализовано 11 механик из 14 1. **Teams** — game.Teams сервис + Team-инстансы, эвристика TeamBeacon-Model в converter.py → автоматически создаёт 4 команды по имени. 2. **Leaderstats UI** — IntValue.Value реактивно через Object.defineProperty, при Parent=leaderstats шлёт leaderstatSet → существующий LeaderstatsManager. 3. **BindableFunction/RemoteFunction** + Message/Hint классы с реактивным Text. 4. **KillFeed UI** + creator-tag tracking в Humanoid.TakeDamage. DOM-overlay. 5. **SpawnLocation.TeamColor** → scene.team_spawns[]. 6. **Tool/Model:Clone()** + :MakeJoints/:BreakJoints/:Remove no-op. 7. **Creator-tag**: ObjectValue.Name='creator' проверяется на Health=0. 8. **RegenerationScript** — no-op skip по имени (Anchored=True держит). 9. **BattleArmor** — реактивный Humanoid.MaxHealth/Health/WalkSpeed/JumpPower. 10. **WinGui/FireButton** через GuiManager. 11. **AdminConsole** — no-op. 12. **Bouncer** — BodyVelocity.Y > 10 + Parent=Torso → playerSet jumpVelocity. 14. **Mouse.Icon** → CSS cursor через canvas.style.cursor. Также добавлены: **tick/time/delay/spawn/LoadLibrary** legacy globals, **SpecialMesh/BlockMesh/CylinderMesh/FileMesh** Instance.new стабы. ### Новый модуль RbxlHudOverlay.js DOM-оверлей поверх canvas с KillFeed (правый верх, fade 5с) + Message (центр верх) + WinGui (центр). Lazy-создаётся. ### Tight-loop защита (КРИТИЧНО) Roblox 2009 паттерн: ```lua while not parent:FindFirstChild(name) do parent.ChildAdded:wait() end ``` Наш Signal:wait() возвращает синхронно — цикл бесконечный, страница виснет. **Не можем yield** из JS-функции через wasmoon C-call boundary. Перепробовали: - debug.sethook(yield, 'i', N) — внутри C-call падает с `yield across C-call`. - pcall(coroutine.yield) — ошибка ловится, счётчик не сбрасывается, вис. **Финал**: regex-фильтр в GameRuntime.js пропускает скрипты с этими паттернами. Из 66 скриптов 37 пропущены, 29 работают. Жертвы: RoundScript, GameClock, Spawner, KillFeed, LeaderboardV3, оружие Launcher/Sword/Slingshot/Cannon. ### CFrame YXZ Euler Переписал `to_euler_xyz` в `rbxl_types.py` под Babylon YXZ convention: rx=asin(-r12), ry=atan2(r02,r22), rz=atan2(r10,r11) + gimbal-lock guard. Раньше извлекал XYZ-Euler, Babylon применял как YXZ — мостики поворачивались криво. ### Persistence настроек света BabylonScene.serialize/loadFromState сохраняют scene.lighting: sunIntensity, hemiIntensity, sceneAmbient, exposure, contrast, saturation. ### Известные баги - `memory access out of bounds` (1 раз) — WASM-crash одного скрипта. - `Cannot read properties of null ('then')` — wasmoon promise-detection, скрипт init крашится но не блокирует. - 0 teams при загрузке старого проекта — нужен переимпорт. ### В JS ✅ Всё: Teams формат общий, KillFeed/Message HUD общий для студии+плеера. --- ## 2026-06-08 — Итерация 2: Crossroads (arch1_Original_Crossroads.rbxl, проект 2827) **Контекст:** Классическая Roblox-карта 2009 года для PvP, **XML-формат** .rbxl (старее бинарного). 877 instances, 777 Part, 83 Model. Состоит из 4 зон: крепость (Castle), дом (House Platform), деревья, дорожки крест-накрест. 2 скрипта: «Regenerate Playground» и «Regenerate Castle» — периодически удаляют и восстанавливают постройки (для PvP). ### Главное: XML-парсер для .rbxl `rbxl-importer/src/rbxl_xml_parser.py` (новый файл, ~330 строк): - `is_xml_rbxl(blob)` — детект по `N` — особый случай: в старом XML цвет лежит как int с именем `BrickColor`, заворачиваем в `BrickColor(code=N)`. В `app.py` добавлен автодетект формата: ```python is_binary = blob.lstrip().startswith(b' Падение.** Лучше пустой stub-метод чем `nil error`. 2. **Сигналы (`Connect`/`Fire`) всегда есть на любом объекте.** 3. **Coloncall совместимость.** Если есть `Foo.Bar`, обычно делаем и `Foo:Bar` (lowercase) как alias. 4. **При добавлении нового Instance-типа** — давай ему **все типичные поля** сразу, не только те что нужны прямо сейчас (Equipped + Unequipped + Activated вместе, даже если скрипт юзает только Equipped). 5. **Логировать сюда после каждой итерации** — что было добавлено и из какой игры.