docs(lua): итерация 2 Crossroads в CHANGELOG
Зафиксированы все правки сделанные при работе с Crossroads:
- XML-парсер для старых .rbxl (~330 строк)
- BrickColor таблица расширена с 50 до 120 цветов
- Force-anchored для всех импортированных Part
- 4 новых слайдера в Свет и атмосфера (заливка теней,
экспозиция, контраст, насыщенность) через imageProcessingConfiguration
- Persistence настроек света в projectData.scene.lighting
- mat.ambientColor=(1,1,1) обязательно для scene.ambientColor работы
- Деплой rbxl-importer на VM 130 через прямой SSH (CI не настроен)
Известные баги Crossroads:
- 2 скрипта Regenerate* падают на model:clone() и Instance.new('Message')
— не критично, Anchored держит постройки.
This commit is contained in:
parent
e45a9968c4
commit
71d6396d8b
@ -8,6 +8,139 @@ Roblox-играми. Цель — потом продублировать тот
|
||||
|
||||
---
|
||||
|
||||
## 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)` — детект по `<roblox` без `!` (binary имеет magic `<roblox!`).
|
||||
- `parse_xml(blob) → RobloxModel` — то же что `parse()` из binary parser'а,
|
||||
совместимый формат, чтобы converter работал без изменений.
|
||||
- Поддержанные property-теги: `string`, `bool`, `int`, `int64`, `float`,
|
||||
`double`, `token`, `Vector3`, `Vector2`, `CoordinateFrame`, `Color3`,
|
||||
`Color3uint8`, `BrickColor`, `Ref`, `BinaryString`, `UDim`, `UDim2`,
|
||||
`Rect2D`, `OptionalCoordinateFrame`, `PhysicalProperties`, `NumberRange`,
|
||||
`ProtectedString`, `Content`.
|
||||
- Алиасы PascalCase: старые карты использовали `name/size/shape`
|
||||
с маленькой буквы — добавлены как PascalCase для converter'а.
|
||||
- `<int name="BrickColor">N</int>` — особый случай: в старом XML цвет
|
||||
лежит как int с именем `BrickColor`, заворачиваем в `BrickColor(code=N)`.
|
||||
|
||||
В `app.py` добавлен автодетект формата:
|
||||
```python
|
||||
is_binary = blob.lstrip().startswith(b'<roblox!')
|
||||
is_xml = blob.lstrip().startswith(b'<roblox') and not is_binary
|
||||
if is_xml:
|
||||
model = parse_xml(blob)
|
||||
else:
|
||||
model = parse(blob)
|
||||
```
|
||||
|
||||
### Расширенная BrickColor палитра (converter.py)
|
||||
|
||||
Старая палитра: ~50 цветов. Новая: ~120 цветов. Главные добавления:
|
||||
- **151 (Earth green)** — основная трава Crossroads (`#7c9b53`). Без неё
|
||||
пол получал дефолтный `#cccccc` и выглядел белым на 344 примитива.
|
||||
- 18, 26, 115-148, 168-301, 1021-1032 — заполнили дыры.
|
||||
|
||||
После: `#cccccc` дефолт упал с 344 → 68 на Crossroads (большинство цветов
|
||||
теперь правильные).
|
||||
|
||||
### Anchored = True для всех импортированных Part
|
||||
|
||||
В `_convert_part`/`_convert_wedge`/`_convert_cornerwedge`/`_convert_truss`/
|
||||
`_convert_meshpart`/`_convert_union` принудительно `'anchored': True`.
|
||||
|
||||
Причина: Roblox-карты держатся на **Welds** (склейки) или **BasePart-default
|
||||
Anchored=true** (Crossroads). У нас Welds — заглушки, физика 700+ unanchored
|
||||
Part'ов = карта рассыпается за 1 секунду (`Unanchored bodies: 767`).
|
||||
|
||||
После фикса: `Unanchored bodies: 0`, всё стоит на месте.
|
||||
|
||||
### Уважение поля `enabled` из метадаты
|
||||
|
||||
Уже было в Итерации 1, но напомню: скрипты с `Disabled=True` в Roblox
|
||||
не запускаются. Парсер метадаты `parseRobloxLuaMeta()` смотрит вторую
|
||||
строку packed-кода (JSON с `enabled`), если false — пропускаем.
|
||||
|
||||
### Визуальная настройка света
|
||||
|
||||
Главные находки:
|
||||
1. **mat.ambientColor=(1,1,1)** обязательно — иначе `scene.ambientColor`
|
||||
(«Заливка теней» слайдер) не влияет на материалы.
|
||||
2. **mat.ambientColor=(цвет_от_diffuse)** даёт пересвет — не делать.
|
||||
3. **scene.imageProcessingConfiguration** есть готовый в Babylon — даёт
|
||||
exposure/contrast/saturation бесплатно.
|
||||
|
||||
В `BabylonScene.setLightingProps(patch)` добавлено:
|
||||
- `patch.sceneAmbient` (0..1) → `scene.ambientColor` (заливка теней)
|
||||
- `patch.exposure` (0.3..2) → `ipc.exposure`
|
||||
- `patch.contrast` (0.5..2) → `ipc.contrast`
|
||||
- `patch.saturation` (0..2) → `ipc.colorCurves.globalSaturation`
|
||||
|
||||
В `SelectionManager.selectLighting()` добавлены поля для чтения текущих значений.
|
||||
|
||||
В `InspectorPanel.jsx` добавлены 4 новых слайдера в «Свет и атмосфера»:
|
||||
- Заливка теней (в блоке «Окружающий свет»)
|
||||
- Экспозиция / Контраст / Насыщенность (новый блок «Цветокоррекция»)
|
||||
|
||||
### Persistence настроек света
|
||||
|
||||
`BabylonScene.serialize()` теперь включает `scene.lighting`:
|
||||
```js
|
||||
lighting: {
|
||||
sunIntensity, hemiIntensity, sceneAmbient,
|
||||
exposure, contrast, saturation,
|
||||
}
|
||||
```
|
||||
|
||||
`BabylonScene.loadFromState()` применяет эти параметры через `setLightingProps()`.
|
||||
|
||||
### Деплой rbxl-importer
|
||||
|
||||
**ВАЖНО:** rbxl-importer на VM 130 деплоится **напрямую через SSH**, не через CI/CD:
|
||||
|
||||
```bash
|
||||
KEY="/c/Users/min/.ssh/id_ed25519"
|
||||
scp -P 2280 -i "$KEY" rbxl-importer/src/FILE.py root@85.175.7.40:/tmp/
|
||||
ssh -p 2280 -i "$KEY" root@85.175.7.40 \
|
||||
"scp -P 22 -i /root/.ssh/id_ed25519 /tmp/FILE.py min@192.168.1.130:/tmp/ && \
|
||||
ssh -p 22 -i /root/.ssh/id_ed25519 min@192.168.1.130 'sudo mv /tmp/FILE.py /opt/rbxl-importer/src/ && sudo systemctl restart rbxl-importer'"
|
||||
```
|
||||
|
||||
S1 PVE root доступен по SSH-ключу `~/.ssh/id_ed25519` (без пароля).
|
||||
См. [[vm130-direct-deploy]] в memory.
|
||||
|
||||
### Что НЕ доделано (известные баги Crossroads)
|
||||
|
||||
1. **2 скрипта падают `self2 is not a function`**:
|
||||
- `Regenerate Playground` и `Regenerate Castle`.
|
||||
- Используют `model:clone()` где `model = game.Workspace.Playground` —
|
||||
наш stub-Folder для Playground не имеет `:clone()` метода.
|
||||
- Также `Instance.new("Message")` — класс не реализован.
|
||||
- **Не критично**: Anchored=True держит постройки, регенерация не нужна.
|
||||
|
||||
2. **Цвета всё ещё чуть-чуть не такие как в Roblox**:
|
||||
- Юзер крутит слайдеры sun/hemi/ambient/saturation и подбирает
|
||||
baseline. Параметры сохраняются в проект через persistence.
|
||||
|
||||
### Надо ли в JS?
|
||||
|
||||
✅ **Все правки** — да:
|
||||
- BrickColor расширенная палитра — общая для обоих движков.
|
||||
- Anchored=True для импорта — это про converter, не движок.
|
||||
- Слайдеры света — UI студии, общий для обоих.
|
||||
- persistence — общий формат `projectData.scene.lighting`.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-08 — Итерация 1: RayGun (проект 2792, 9 скриптов)
|
||||
|
||||
**Контекст:** Roblox-Tool пушка-стрелялка, использует Tool-API, Lighting,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user