Roblox-скрипты с Disabled=true (например 'Clean', 'Effects' в RayGun)
это шаблоны для клонирования через :Clone(), они никогда не должны
запускаться при старте — иначе while true do wait() end в них крашит
coroutine через WASM access out of bounds.
parseRobloxLuaMeta(code) парсит JSON-метадату из второй строки
packed-кода (формат '// {"roblox_class":..., "enabled":true}').
Скрипты с enabled=false идут в rbxlSkipped, не запускаются.
106 lines
6.0 KiB
Markdown
106 lines
6.0 KiB
Markdown
# Lua API — журнал изменений
|
||
|
||
Файл фиксирует **что было добавлено в Lua-runtime** при работе с реальными
|
||
Roblox-играми. Цель — потом продублировать тот же API для **JS-движка**
|
||
(на будущее, сейчас работаем только с Lua).
|
||
|
||
Формат: дата + что и почему + куда добавлено + надо ли портировать в JS.
|
||
|
||
---
|
||
|
||
## 2026-06-08 — Итерация 1: RayGun (проект 2792, 9 скриптов)
|
||
|
||
**Контекст:** Roblox-Tool пушка-стрелялка, использует Tool-API, Lighting,
|
||
Mouse, Welds, BodyForce, BrickColor, IntValue для leaderboard.
|
||
|
||
### Добавлено в `RobloxShim.js`
|
||
|
||
**Глобалы:**
|
||
- `BrickColor.new("Bright red")` + ~25 цветов (White, Black, Bright red/blue/green,
|
||
Pink, Brown, Reddish brown, Cyan, Magenta и др.). Возвращает `{Color, Name, R, G, B}`.
|
||
- `Ray.new(origin, direction)` — для raycast (заглушка структуры).
|
||
- `Region3.new(min, max)` — куб (заглушка).
|
||
- `TweenInfo.new(time, easingStyle, easingDirection, repeatCount, reverses, delayTime)`
|
||
- `NumberSequence`, `ColorSequence`, `NumberRange`, `Rect` — конструкторы-стабы.
|
||
|
||
**Enum расширения:** InfoType, SortOrder, FillDirection, Font,
|
||
TextXAlignment/TextYAlignment, ScaleType, AspectType, PartType, SurfaceType,
|
||
ContextActionResult, UserInputState, BorderMode, FormFactor.
|
||
|
||
**`game` методы:**
|
||
- `game:service(name)` (lowercase alias на GetService) — старый Roblox API.
|
||
- `game.GetServiceFromName` = alias.
|
||
- `game.JobId/PlaceId/GameId/CreatorId/CreatorType` — stub fields.
|
||
|
||
**Lighting:**
|
||
- `Brightness`, `ClockTime`, `TimeOfDay`, `OutdoorAmbient`, `FogStart/End/Color`.
|
||
- `GetMinutesAfterMidnight()`, `SetMinutesAfterMidnight(m)`.
|
||
- `GetMoonDirection()`, `GetSunDirection()`.
|
||
|
||
**Players:**
|
||
- `GetPlayers()`, `GetPlayerFromCharacter(char)`, `playerFromCharacter` alias.
|
||
- `PlayerAdded`, `PlayerRemoving`, `ChildAdded` signals.
|
||
|
||
**Instance.new новые типы:**
|
||
- `Tool` / `HopperBin` — Equipped/Unequipped/Activated/Deactivated signals,
|
||
GripForward/Right/Up/Pos, CanBeDropped, RequiresHandle, ToolTip.
|
||
- `IntValue` / `NumberValue` / `BoolValue` / `StringValue` / `ObjectValue` /
|
||
`CFrameValue` / `Vector3Value` / `Color3Value` / `BrickColorValue` / `RayValue`
|
||
— `.Value` + `.Changed` сигнал.
|
||
- `BodyForce` / `BodyVelocity` / `BodyPosition` / `BodyGyro` / `BodyAngularVelocity`
|
||
/ `BodyThrust` — `.force`, `.Velocity`, `.MaxForce`, `.P/.D`.
|
||
- `Weld` / `WeldConstraint` / `Motor6D` / `Snap` / `HingeConstraint` /
|
||
`BallSocketConstraint` / `RopeConstraint` / `SpringConstraint` — Part0/Part1/C0/C1/Enabled.
|
||
- `Sparkles` / `ParticleEmitter` / `Smoke` / `Fire` / `Trail` / `Beam` /
|
||
`PointLight` / `SurfaceLight` / `SpotLight` — Enabled/Color/Rate/Lifetime/Brightness/Range.
|
||
- `Mouse` — Button1Down/Up, Button2Down/Up, Move, KeyDown/Up, WheelForward/Backward,
|
||
Icon, Hit (Position), Target, TargetSurface, X/Y, ViewSizeX/Y.
|
||
|
||
### Исправлено
|
||
|
||
- `rbx_wait(sec)`: минимум 0.016с (1 кадр). `while true do wait() end` без
|
||
аргумента раньше делал tight loop без yield → WASM stack overflow
|
||
("memory access out of bounds").
|
||
|
||
- **Уважаем `enabled: false`** в Roblox-метадате. Roblox-скрипты с
|
||
`Disabled = true` — это шаблоны для клонирования (`script.Clean:Clone()`),
|
||
не должны запускаться при старте. `parseRobloxLuaMeta()` парсит JSON
|
||
из второй строки packed-кода, при `enabled=false` скрипт идёт в `rbxlSkipped`.
|
||
|
||
### Надо ли портировать в JS-движок?
|
||
|
||
✅ **Да, всё** — это базовый Roblox-совместимый API, который должен работать
|
||
независимо от языка скриптов.
|
||
|
||
**JS-эквивалент будет такой же структурой:**
|
||
- `BrickColor.new("Bright red")` → `new BrickColor("Bright red")`
|
||
- `Tool` Equipped/Unequipped → JS-EventEmitter методы
|
||
- BodyForce/Weld/Sparkles → JS-классы с теми же полями
|
||
- Mouse — глобальный объект `game.mouse` или через `player:GetMouse()`.
|
||
|
||
---
|
||
|
||
## Куда добавляется API
|
||
|
||
| Источник | Файл | Что туда идёт |
|
||
|----------|------|---------------|
|
||
| Глобалы (Vector3, Color3, BrickColor, Enum) | `RobloxShim.js` через `global.set` | Конструкторы, Enum-таблицы |
|
||
| Instance.new типы | `RobloxShim.js` в ветке `global.set('Instance', {new: ...})` | Tool, BodyForce, Weld, Sparkles и т.д. |
|
||
| Сервисы | `RobloxShim.js` через `makeService(name)` | Lighting, Players, RunService и т.д. |
|
||
| Wait/Task | `RobloxShim.js` в Lua-prelude (`lua.doStringSync`) | rbx_wait, task.wait |
|
||
| Setter Part-свойств | `newPart()` через `Object.defineProperty` | Position, Color, Anchored шлют partSet |
|
||
| Команды от Lua к Babylon | `rbxl-lua-integration.js` `handleLuaCommand` | partSet, sceneCreate, sceneDelete |
|
||
|
||
---
|
||
|
||
## Принципы расширения API
|
||
|
||
1. **No-op > Падение.** Лучше пустой stub-метод чем `nil error`.
|
||
2. **Сигналы (`Connect`/`Fire`) всегда есть на любом объекте.**
|
||
3. **Coloncall совместимость.** Если есть `Foo.Bar`, обычно делаем и `Foo:Bar`
|
||
(lowercase) как alias.
|
||
4. **При добавлении нового Instance-типа** — давай ему **все типичные поля**
|
||
сразу, не только те что нужны прямо сейчас (Equipped + Unequipped + Activated
|
||
вместе, даже если скрипт юзает только Equipped).
|
||
5. **Логировать сюда после каждой итерации** — что было добавлено и из какой игры.
|