feat(rbxl): XML-������ ������ .rbxl + Day/Night + Tool/Mouse/Backpack flow #38

Closed
min wants to merge 39 commits from feat/rbxl-xml-parser-import into main
4 changed files with 156 additions and 30 deletions
Showing only changes of commit b7a0b083b6 - Show all commits

124
RBXL_SOURCES.md Normal file
View File

@ -0,0 +1,124 @@
# Реестр источников .rbxl / .rbxlx для портирования в Рублокс
Цель: легально добыть Roblox Place-файлы (.rbxl бинарный / .rbxlx XML) по жанрам
для портирования и публикации на Рублоксе.
**Форматы:** `.rbxlx` (XML — предпочтителен, читаемый, легко парсить геометрию/CFrame)
· `.rbxl` (бинарный, конвертировать) · `.rbxm`/`.rbxmx` (модели, не целые места).
> ⚠️ **Главное про публикацию:** «uncopylocked» ≠ свободная лицензия. Для ПУБЛИКАЦИИ
> порта на Рублоксе безопасны только: репо с явной **MIT/Apache/MPL/CC0/CC-BY** +
> официальные ассеты Roblox с разрешением. Архивы чужих игр — только для
> обучения/прототипа парсера, НЕ для публикации. Lua-скрипты не портируются
> автоматом — логику переписываешь сам (это и снижает юр.риски).
---
## ИНСТРУМЕНТЫ (распаковка/парсинг)
| Инструмент | URL | Назначение | Лицензия |
|---|---|---|---|
| Rojo | https://github.com/rojo-rbx/rojo | place ↔ файлы | MPL-2.0 |
| rbxlx-to-rojo | https://github.com/rojo-rbx/rbxlx-to-rojo | .rbxl/.rbxlx → проект | MPL/MIT (проверить) |
| rbxfile (Go) | https://github.com/robloxapi/rbxfile | парсинг rbxl/rbxlx/rbxm | MIT (проверить) |
| remodel | https://github.com/rojo-rbx/remodel | скриптовая обработка | MPL-2.0 |
| RobloxAPI/spec | https://github.com/RobloxAPI/spec/blob/master/formats/rbxl.md | спека бинарного формата | docs |
---
## (А) ОФИЦИАЛЬНЫЕ — самые надёжные
### A1. Roblox/Old-Open-Source-Levels — классика от самой Roblox Corp ⭐
- https://github.com/Roblox/Old-Open-Source-Levels
- Каталог: https://github.com/Roblox/Old-Open-Source-Levels/blob/master/catalog.md
- ~30+ мест 2007-2013 (.rbxl). Жанры: Crossroads (арена/PvP), Castle Warfare,
ROBLOX Battle (бой), Sword Fight in the Dark (PvP), Haunted Mansion (хоррор),
Glass Houses, Pinball Wizards, Happy Home in Robloxia (песочница/мини).
- Лицензия: «free to manipulate however you wish» — **проверь файл LICENSE вручную** перед публикацией.
### A2. Встроенные шаблоны Roblox Studio
- Список: https://create.roblox.com/docs/resources/templates
- В Studio: открыть шаблон → File → Save to File → .rbxlx
- Baseplate, Castle, Suburban, Village, Racing, Classic Obby, Team Deathmatch/Combat,
Capture the Flag, Line Runner, Pirate Island, Modern City и др.
- Серая зона для публикации «как есть» — используй как базу/учёбу, геометрию делай своей.
### A3. creator-docs (документация Roblox, open)
- https://github.com/Roblox/creator-docs
### A4. Internet Archive — Crossroads (все версии 2007-2017)
- https://archive.org/details/roblox_crossroads
- https://archive.org/details/classic-crossroads_202408
---
## (Б) РЕПОЗИТОРИИ С КОДОМ/МЕСТАМИ (URL из поиска)
### С подтверждённой свободной лицензией (можно публиковать)
| Репо | URL | Лицензия | Жанр |
|---|---|---|---|
| Vigilant | https://github.com/IsoLogicGames/Vigilant | **MIT** ✅ | co-op horde-survival (шутер) |
| crossroads-rojo | https://github.com/Dekkonot/crossroads-rojo | наследует Crossroads | арена |
### Open-source игры (лицензию проверить у каждого — файл LICENSE)
| Репо | URL | Жанр |
|---|---|---|
| Miner's Haven | https://github.com/berezaa/minershaven | tycoon/симулятор |
| roblox-gym-tycoon | https://github.com/jason-lee88/roblox-gym-tycoon | tycoon |
| Racing-Kit-Roblox | https://github.com/Astrophsica/Racing-Kit-Roblox | гонки |
| RENTED_old_rbx | https://github.com/ReRand/RENTED_old_rbx | хоррор |
| roblox-rpg | https://github.com/mobyrblx/roblox-rpg | RPG/демо |
| RobloxGames (dwmk) | https://github.com/dwmk/RobloxGames | разное |
| recsObby | https://github.com/Nimblz/recsObby | obby |
| WavyRobloxObby | https://github.com/sammy0127/WavyRobloxObby | obby (.rbxlx) |
| Sight-Obby | https://github.com/TeoJJss/Sight-Obby | obby |
| fps (Anninzy) | https://github.com/Anninzy/fps | FPS |
| roblox-game-example | https://github.com/areshaistg/roblox-game-example | демо-каркас |
### Архивы чужих игр (ТОЛЬКО обучение/прототип, НЕ публикация — смешанные права)
| Репо | URL |
|---|---|
| uncopylocked-game-collection | https://github.com/Kitaske/uncopylocked-game-collection |
| robloxplacearchive | https://github.com/tropicalbananas/robloxplacearchive |
| RobloxRBXLArchive | https://github.com/LuaGunsX/RobloxRBXLArchive |
| Biggest Uncopylocked Library | https://github.com/KH0DIN/Biggest_Uncopylocked_Roblox_Games_Library |
| GitHub topics | https://github.com/topics/rbxlx · /rbxl · /rbxm · /rojo · /uncopylocked |
---
## (В) САЙТЫ ДЛЯ САМОСТОЯТЕЛЬНОГО СКАЧИВАНИЯ
### Прямое скачивание .rbxl/.rbxlx
- **GitHub code search** (вход обязателен): `extension:rbxlx`, `extension:rbxl`,
`filename:default.project.json` (корень Rojo-проекта рядом с местом)
https://github.com/search?q=extension%3Arbxlx&type=code
- **GitHub Topics:** https://github.com/topics/rbxlx · https://github.com/topics/rojo
- **Internet Archive:** https://archive.org/ — поиск «roblox place», «rbxl», «crossroads»
### CC0/CC-BY геометрия для воссоздания (юридически чистейший путь, не .rbxl но low-poly близко к Roblox)
- **Kenney** (CC0): https://kenney.nl/assets — Platformer/Nature/Car/Pirate/City/Prototype Kit, Blocky Characters
- **OpenGameArt** (CC0/CC-BY): https://opengameart.org/ — voxel/low-poly паки
- **itch.io** (фильтр assets+CC0): https://itch.io/game-assets/free/tag-low-poly
- **Poly Pizza** (CC0/CC-BY low-poly): https://poly.pizza/
- **Quaternius** (CC0 low-poly паки): https://quaternius.com/
### Сообщества с открытыми играми (часто прямые ссылки + лицензия)
- DevForum «free & open-sourced games»: https://devforum.roblox.com/t/lots-of-free-open-sourced-games/525670
- DevForum «Open Source Arena FPS»: https://devforum.roblox.com/t/open-source-arena-fps/1034576
- Uplift Games open source: https://www.uplift.games/open-source
---
## ЮРИДИЧЕСКИЕ ПРАВИЛА (коротко)
- ✅ Публиковать можно: **MIT / Apache-2.0 / MPL-2.0 / CC0 / CC-BY** (CC-BY — с атрибуцией).
- ❌ Нельзя: **GPL/AGPL** (заразные), **CC-BY-NC** (некоммерч.), **без лицензии** (= all rights reserved),
чужие игры через game-savers/декомпиляторы (нарушение DMCA/ToS).
- ⚠️ «Uncopylocked» = только разрешение копировать в Studio, НЕ передача прав.
- ⚠️ Официальные шаблоны Studio — учиться ОК, публиковать «как есть» — серая зона.
**Рекомендация для наполнения Рублокса легально:**
1. Геометрия под чистую публикацию → Kenney/OpenGameArt CC0.
2. Классика Roblox-стиля → Roblox/Old-Open-Source-Levels (проверить LICENSE) + Crossroads.
3. Полная игра с кодом → Vigilant (MIT).
4. Масса .rbxl для теста парсера → архивы из (Б) + GitHub topics.

View File

@ -3035,13 +3035,6 @@ export class BabylonScene {
// Без этого onTouch финиша/плитки не срабатывает (игрок встал).
const EPS = 0.25;
// Диагностика раз в секунду через time-based throttle
if (!this._touchDbgT0) this._touchDbgT0 = performance.now();
const _nowDbg = performance.now();
if (_nowDbg - this._touchDbgT0 > 1000) {
this._touchDbgT0 = _nowDbg;
console.warn(`[TouchDbg] pos=(${px.toFixed(2)},${py.toFixed(2)},${pz.toFixed(2)}) scripts=${scripts.length}`);
}
// 1) Касания объектов с target-скриптами (ключ touchState = 's:'+scriptId)
let _firedThisFrame = 0;
for (const s of scripts) {
@ -5537,7 +5530,7 @@ export class BabylonScene {
};
clip.scripts = (this._scripts || [])
.filter(s => matchTarget(s.target))
.map(s => ({ code: s.code, name: s.name || null }));
.map(s => ({ code: s.code, name: s.name || null, language: s.language || 'js' }));
} catch (e) { clip.scripts = []; }
try { localStorage.setItem('kubikon_clipboard', JSON.stringify(clip)); }
catch (e) { /* ignore — приватный режим / переполнение */ }
@ -7769,6 +7762,7 @@ export class BabylonScene {
code: s.code,
target: s.target || null,
name: s.name || null,
language: s.language === 'lua' ? 'lua' : 'js',
})),
},
editorCamera: this.camera ? {

View File

@ -21,7 +21,9 @@
* и вызывает Lua-side Fire по соответствующему signal'у
*/
let _wasmoon = null;
// Статический импорт — Vite корректно бандлит wasmoon в worker
import { LuaFactory } from 'wasmoon';
import { registerRobloxShim } from './RobloxShim.js';
// Главное состояние VM (на весь life-cycle Worker'а)
const state = {
@ -72,23 +74,21 @@ function logToMain(level, text) {
async function handleInit(payload) {
state.ipcId = payload?.ipcId || 0;
send('boot', { ipcId: state.ipcId });
// Загрузить wasmoon
_wasmoon = await import(/* @vite-ignore */ 'wasmoon');
const { LuaFactory } = _wasmoon;
try {
const factory = new LuaFactory();
state.vm = await factory.createEngine({ openStandardLibs: true });
// Регистрируем минимальный Roblox shim
const { registerRobloxShim } = await import('./RobloxShim.js');
state.api = registerRobloxShim(state.vm, {
send,
getSceneSnapshot: () => state.scenes,
getGuiTree: () => state.guiTree,
scheduleWait: (sec) => scheduleWait(sec),
});
state.isReady = true;
send('ready', {});
} catch (err) {
// Это самое важное — без этого юзер не видит почему ничего не работает
logToMain('error', `[LuaWorker init FATAL] ${err?.message || err}\nstack: ${err?.stack || '?'}`);
}
}
function handleAddScriptsBatch(payload) {

View File

@ -57,13 +57,21 @@ class RbxVector3 {
this.X = +x; this.Y = +y; this.Z = +z;
}
static new(x, y, z) { return new RbxVector3(x, y, z); }
Magnitude() { return Math.hypot(this.X, this.Y, this.Z); }
// В Roblox Magnitude/Unit это PROPERTY (без скобок), а не методы.
get Magnitude() { return Math.hypot(this.X, this.Y, this.Z); }
get magnitude() { return Math.hypot(this.X, this.Y, this.Z); }
Unit() {
const m = this.Magnitude() || 1;
get Unit() {
const m = Math.hypot(this.X, this.Y, this.Z) || 1;
return new RbxVector3(this.X / m, this.Y / m, this.Z / m);
}
get unit() {
const m = Math.hypot(this.X, this.Y, this.Z) || 1;
return new RbxVector3(this.X / m, this.Y / m, this.Z / m);
}
Normalize() {
const m = Math.hypot(this.X, this.Y, this.Z) || 1;
return new RbxVector3(this.X / m, this.Y / m, this.Z / m);
}
Normalize() { return this.Unit(); }
Dot(b) { return this.X * b.X + this.Y * b.Y + this.Z * b.Z; }
Cross(b) {
return new RbxVector3(