feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39

Merged
min merged 215 commits from feat/lua-50-games-bundle into main 2026-06-09 21:59:25 +00:00
4 changed files with 356 additions and 28 deletions
Showing only changes of commit eedac4379d - Show all commits

View File

@ -10,7 +10,7 @@ export const USER_addres = BASE + '/api-user';
export const ACHIVES_addres = BASE + '/api-achievs';
export const COMMENTS_addres = BASE + '/api-comments';
export const STORYS_addres = BASE + '/api-storys';
// rbxl-importer: только для МИНа (тест-фича импорта .rbxl карт Roblox)
// rbxl-importer: импорт .rbxl карт Roblox (см. вики «Импорт из Roblox»)
export const RBXL_addres = BASE + '/api-rbxl';
export const NOTICES_addres = BASE + '/api-notices';
export const HELP_addres = BASE + '/api-help';

View File

@ -390,18 +390,16 @@ const KubikonStudio = () => {
<span className={cl.navIcon}><Icon name="book-open" size={15} /></span>
<span>ВИКИ</span>
</button>
{/* Импорт Roblox .rbxl — только для МИНа (user_id=1) */}
{getCurrentUserId() === 1 && (
<button
className={cl.navItem}
onClick={() => setRbxlImportOpen(true)}
title="Импортировать игру из Roblox (.rbxl файл) — тест-фича"
style={{ marginTop: 8, borderTop: '1px solid #333', paddingTop: 12 }}
>
<span className={cl.navIcon}>📦</span>
<span>Импорт Roblox</span>
</button>
)}
{/* Импорт Roblox .rbxl — доступно всем */}
<button
className={cl.navItem}
onClick={() => setRbxlImportOpen(true)}
title="Импортировать игру из Roblox (.rbxl файл)"
style={{ marginTop: 8, borderTop: '1px solid #333', paddingTop: 12 }}
>
<span className={cl.navIcon}>📦</span>
<span>Импорт Roblox</span>
</button>
</nav>
<RbxlImportModal

View File

@ -5073,6 +5073,350 @@ end)`}</Code>}
],
},
//
// РАЗДЕЛ ИМПОРТ ИЗ ROBLOX (.rbxl)
//
{
id: 'rbxl-import',
icon: 'package',
title: 'Импорт из Roblox',
summary: 'Загрузи .rbxl-файл готовой Roblox-карты в Рублокс: геометрия, цвета и материалы переносятся хорошо, скрипты лучше отключить при первом импорте и включать постепенно.',
sections: [
{
id: 'rbxl-overview',
title: 'I1. Что это и зачем',
body: (
<>
<p>
<b>Импорт из Roblox</b> это возможность загрузить
в Рублокс <b>готовую карту из Roblox Studio</b> в формате
<b> .rbxl</b> или <b>.rbxlx</b>. Часть карты геометрия,
цвета, материалы, GUI переносится в Рублокс
автоматически. Импорт превращает её в обычный проект
Рублокса, который можно редактировать, как любой
свой проект.
</p>
<p>
Кнопка <b>«📦 Импорт Roblox»</b> находится в левой
панели студии внизу под кнопкой «ВИКИ». Откроется
модалка, куда можно перетащить .rbxl-файл.
</p>
<h3 className="lessonH">Зачем это нужно</h3>
<ul>
<li>Перенести свою старую Roblox-карту в Рублокс,
чтобы продолжить работу здесь;</li>
<li>Изучить, как устроены большие карты опытных
разработчиков (классические <i>Crossroads</i>,
<i> ROBLOX Battle</i> и др.);</li>
<li>Использовать готовую сцену как «костяк» для
своей игры добавить свои скрипты и механики.</li>
</ul>
<Note>
Импорт работает с файлами до <b>50 МБ</b>. Этого
хватает для большинства карт. Очень большие карты
с тысячами объектов могут импортироваться долго
(2060 секунд).
</Note>
</>
),
},
{
id: 'rbxl-how-to-use',
title: 'I2. Как импортировать карту',
body: (
<>
<h3 className="lessonH">Шаг 1. Получи .rbxl-файл</h3>
<p>
В Roblox Studio открой свою карту и сохрани её
через меню <b>File Save to File</b>. Получится файл
с расширением <b>.rbxl</b> (бинарный) или
<b> .rbxlx</b> (текстовый XML). Оба формата подходят.
</p>
<Note>
Если у тебя нет своей карты, можно скачать
любую <b>opensource Roblox-карту</b> с GitHub
их там много (поиск «roblox places .rbxl»).
Классика карта <i>Crossroads</i>.
</Note>
<h3 className="lessonH">Шаг 2. Загрузи в студию</h3>
<Step n="1">
Открой студию Рублокса и нажми кнопку
<b> «📦 Импорт Roblox»</b> в левой панели.
</Step>
<Step n="2">
Перетащи .rbxl-файл в окно модалки или нажми
<b> «Выбрать файл»</b>. Кликни <b>«Анализировать»</b>.
Это займёт 530 секунд: сервер читает структуру карты,
считает объекты, скрипты, ассеты и показывает отчёт.
</Step>
<Step n="3">
В отчёте увидишь, сколько в карте Part-ов, моделей,
скриптов, текстур и какие будут <b>предупреждения</b>.
Например: «найдены неподдерживаемые сетки», «много
BillboardGui может тормозить» и т.п.
</Step>
<h3 className="lessonH">Шаг 3. Настрой режим импорта</h3>
<p>
Перед созданием проекта выбери, как обращаться
со скриптами и GUI карты:
</p>
<ul>
<li>
<b>Скрипты:</b>
<ul>
<li><b>Отключены</b> (рекомендуется) все
скрипты импортируются, но <b>не запускаются</b>.
Карта оживает как декорация: можно ходить
и смотреть, но без логики.</li>
<li><b>Включены</b> Lua-скрипты карты пытаются
запуститься. Часть API не поддерживается
(Roblox-only), некоторые карты могут зависать
или давать ошибки в консоли.</li>
<li><b>Удалить</b> скрипты вообще не сохраняются.
Останется только геометрия.</li>
</ul>
</li>
<li>
<b>GUI:</b>
<ul>
<li><b>Все</b> импортируется и HUD (ScreenGui),
и подписи над объектами (BillboardGui).</li>
<li><b>Только ScreenGui</b> переносится
только HUD. Хорошо если в карте было
200+ табличек-вывесок города.</li>
<li><b>Пропустить</b> не импортировать GUI.</li>
</ul>
</li>
</ul>
<h3 className="lessonH">Шаг 4. Создай проект</h3>
<Step n="1">
Введи название игры. Под этим именем карта появится
в твоих проектах.
</Step>
<Step n="2">
Нажми <b>«Создать игру»</b>. Сервер скачает текстуры
и сетки с Roblox CDN, соберёт проект и переведёт тебя
в редактор.
</Step>
<Step n="3">
Нажми <kbd className="kbd">Запустить</kbd> и осмотри
карту вживую.
</Step>
</>
),
},
{
id: 'rbxl-graphics-vs-scripts',
title: 'I3. Графика хорошо, скрипты — осторожно',
body: (
<>
<p>
Главное, что нужно знать про импорт: <b>графика
переносится хорошо, скрипты нет</b>. Это связано
с тем, что движок Рублокса (Babylon.js) и движок
Roblox разные. Геометрия и материалы это
«стандартный 3D», он одинаков везде. А скрипты
опираются на сотни Roblox-API, которые в Рублоксе
реализованы лишь частично.
</p>
<h3 className="lessonH">Что переносится хорошо</h3>
<ul>
<li><b>Все Part-ы</b> (Brick, Cube, Sphere, Cylinder,
Wedge, CornerWedge) позиция, размер, поворот,
цвет, материал, прозрачность;</li>
<li><b>Модели (Models)</b> собранные группы Part-ов,
включая <i>Welds</i> (склейки);</li>
<li><b>Текстуры</b> и <b>Decals</b> скачиваются
с Roblox CDN и применяются на Part-ы;</li>
<li><b>MeshPart-ы</b> пользовательские 3D-сетки;</li>
<li><b>SpawnLocation</b> точка появления игрока;</li>
<li><b>Lighting / Sky</b> время суток, цвет неба;</li>
<li><b>GUI</b> (ScreenGui, TextLabel, TextButton,
ImageLabel, Frame) простая разметка интерфейса
переносится верно.</li>
</ul>
<h3 className="lessonH">Что переносится так себе</h3>
<ul>
<li><b>Lua-скрипты</b> выполняются через нашу
реализацию Roblox API. <b>Базовые вещи работают</b>:
Touched, ClickDetector, TweenService, BindableEvent,
Vector3, CFrame, Workspace, Players. Но <b>десятки
специальных сервисов нет</b>: DataStoreService,
HttpService, MarketplaceService, MessagingService,
TeleportService и т.д.;</li>
<li><b>Анимации</b> простые работают, сложные
rig-анимации (R15, custom) могут вести себя
не так;</li>
<li><b>Физика</b> общая работает, но <i>Constraint-ы</i>,
<i> Motors</i>, <i>BodyMover-ы</i> (BodyVelocity,
BodyPosition и др.) имеют упрощённую реализацию;</li>
<li><b>Звуки</b> переносятся, но Roblox SoundId
(<i>rbxassetid://</i>) у нас не играет напрямую
лучше заменить на наши звуки (<i>'click'</i>,
<i> 'win'</i>, <i>'coin'</i> и т.д.).</li>
</ul>
<h3 className="lessonH">Что точно не переносится</h3>
<ul>
<li>Мультиплеерная логика на Roblox-Remote-Event-ах
у нас своя система мультиплеера;</li>
<li>Покупки, бонусы, премиум Roblox-only;</li>
<li>Облачное сохранение (DataStore) у нас другое;</li>
<li>Чат, аватары пользователей Roblox.</li>
</ul>
</>
),
},
{
id: 'rbxl-recommended-flow',
title: 'I4. Правильный порядок: сначала графика, потом скрипты',
body: (
<>
<p>
Импорт <b>хорошо работает в два прохода</b>. Не
пытайся всё запустить сразу карта может встать
колом из-за ошибок в чужих скриптах. Делай так:
</p>
<h3 className="lessonH">Проход 1. Импорт без скриптов</h3>
<Step n="1">
Перед созданием проекта выбери в режиме скриптов
<b> «Отключены»</b>.
</Step>
<Step n="2">
Создай проект. Запусти игру и пройдись по карте.
Смотри только на <b>графику</b>:
<ul>
<li>как лежат блоки и модели;</li>
<li>правильные ли материалы и цвета;</li>
<li>работают ли текстуры;</li>
<li>как выглядит освещение и небо;</li>
<li>нет ли провалов / летающих в воздухе кусков.</li>
</ul>
</Step>
<Step n="3">
Если что-то выглядит криво это <b>хорошо</b>:
твой проект не сломан скриптами, можно спокойно
поправить геометрию руками в редакторе.
</Step>
<h3 className="lessonH">Проход 2. Аккуратно включай скрипты</h3>
<p>
После того как графика тебя устраивает, можно
<b> по одному</b> включать скрипты карты. Это
делается уже в редакторе проекта, в панели
<b> «Скрипты»</b>:
</p>
<Step n="1">
Открой панель скриптов. У каждого скрипта рядом
с названием есть тумблер <b>«Включён»</b>.
По умолчанию после импорта все они выключены.
</Step>
<Step n="2">
Включай скрипты <b>по одному</b>, начиная с самых
простых те, что висят на Touched-частях
(кнопки, телепорты, ловушки). Запускай игру,
смотри, всё ли работает.
</Step>
<Step n="3">
Если включил скрипт и игра <b>зависла или замусорила
консоль ошибками</b> выключи его обратно. Это
нормально. У этого скрипта, скорее всего, есть
Roblox-API, которого у нас нет.
</Step>
<Step n="4">
Для важных скриптов, которые не работают, можно
либо <b>переписать</b> их под Рублокс (у нас простой
JS-API через <code>game.*</code>), либо
<b> заменить</b> на свой скрипт с похожей логикой.
</Step>
<Note>
Не расстраивайся, если из 200 скриптов сразу
заработает только 50. Это нормально большие
Roblox-карты опираются на сложные сервисы. Зато
графика уже на месте, и тебе остаётся написать
несколько коротких скриптов на привычном JS.
</Note>
</>
),
},
{
id: 'rbxl-tips-and-tricks',
title: 'I5. Советы и частые проблемы',
body: (
<>
<h3 className="lessonH">Частые ошибки</h3>
<ul>
<li>
<b>«Карта пустая после импорта»</b> спавн-точка
могла оказаться под полом или в стене. В редакторе
переставь её в Game-вкладке: <b>точка спавна</b>
{' '} кликни в нужное место.
</li>
<li>
<b>«Текстуры серые»</b> изредка Roblox CDN не
отдаёт текстуру (она удалена). Поставь свой цвет
или текстуру на этих Part-ах в редакторе.
</li>
<li>
<b>«Игра тормозит»</b> обычно дело в большом
числе BillboardGui (вывески города) или unanchored
Part-ов. Импортируй заново с режимом GUI
<i> «Только ScreenGui»</i>.
</li>
<li>
<b>«Скрипт даёт ошибку DataStoreService»</b>
это Roblox-only сервис. Выключи скрипт или
замени логику сохранения на нашу.
</li>
<li>
<b>«Игрок проваливается под пол»</b> иногда
у Part-а пола стоит <i>CanCollide=false</i>.
Выдели пол в редакторе и включи коллизию.
</li>
</ul>
<h3 className="lessonH">Что делать после импорта</h3>
<ul>
<li>Переименуй важные объекты на русский так
удобнее писать новые скрипты;</li>
<li>Сгруппируй похожие Part-ы в модели (можно через
инспектор);</li>
<li>Поставь свои точки спавна и финиша на местах,
которые тебе нужны;</li>
<li>Сохрани <b>копию проекта</b> до того, как начнёшь
включать скрипты на случай, если карта сломается.</li>
</ul>
<Note>
Импорт это <b>стартовая площадка</b>, а не готовый
продукт. Лучше всего он работает, когда ты берёшь
из Roblox-карты только <b>геометрию</b>, а механики
и интерактив пишешь сам на нашем JS-API
(через <code>game.*</code>). Так получится игра,
которая <b>стабильно работает</b> у тебя и у игроков.
</Note>
<h3 className="lessonH">Что почитать дальше</h3>
<p>
Если хочешь узнать, как переписать импортированный
Roblox-скрипт под наш движок посмотри раздел
<b> «Скрипты»</b> в вики (D-G) и сравни Roblox-API
с нашим <code>game.*</code>. Многое делается похоже,
только короче.
</p>
</>
),
},
],
},
//
// РАЗДЕЛ СОВМЕСТНОЕ РЕДАКТИРОВАНИЕ (Team Create)
//

View File

@ -1,7 +1,7 @@
/**
* RbxlImportModal модалка импорта .rbxl Roblox-карт в Rublox.
*
* Доступна ТОЛЬКО МИНу (user_id === 1) это тест-фича.
* Доступна всем пользователям (см. вики «Импорт из Roblox» о нюансах).
*
* Поток:
* 1. Юзер дропает или выбирает .rbxl файл.
@ -13,8 +13,6 @@
import React, { useState, useRef } from 'react';
import { analyzeRbxl, createRbxlProject } from '../api/rbxlImporterApi.js';
const ALLOWED_USER_ID = 1; // МИН
const MAX_SIZE = 50 * 1024 * 1024; // 50 MB
export default function RbxlImportModal({ open, onClose, currentUserId, onCreated }) {
@ -37,18 +35,6 @@ export default function RbxlImportModal({ open, onClose, currentUserId, onCreate
if (!open) return null;
if (currentUserId !== ALLOWED_USER_ID) {
return (
<div style={overlayStyle} onClick={onClose}>
<div style={dialogStyle} onClick={(e) => e.stopPropagation()}>
<h2 style={{ marginTop: 0 }}>Импорт из Roblox</h2>
<p>Эта тест-функция доступна только администратору.</p>
<button style={btnStyle} onClick={onClose}>Закрыть</button>
</div>
</div>
);
}
const reset = () => {
setFile(null); setReport(null); setPreviewHash(null);
setTitle(''); setError(null); setAnalyzing(false); setCreating(false);