Юзер указал что вся документация opensource-репо должна быть на русском. Также: - .env.example комменты на русском - package.json description на русском - Описания org и repo в Gitea обновлены через API
9.3 KiB
Архитектура плеера Рублокса
Как 3D-игра загружается, рендерится и синхронизируется. Чтение ~5 минут.
Общий поток
URL = /<gameId> например /265
│
▼
PlayerAuthProvider проверяет JWT в localStorage["player_jwt"]
│ ИЛИ обменивает URL #ticket=... на JWT
▼
useAuth().isAuthenticated
│
▼
KubikonPlayer.jsx главный контейнер, читает {projectId} из useParams
│
├── GET /api-storys/kubikon3d/projects/{id} → project_data (JSON)
│
▼
BabylonScene.create() создание движка Babylon, сцены, света, неба
│
▼
GameRuntime.loadProject() парсинг project_data, инстанциация всего:
│ - BlockManager.placeBlock() × N (Minecraft-блоки)
│ - ModelManager.spawnModel() × N (Kenney GLB)
│ - DecoManager.placeDeco() × N (декор ландшафта)
│ - PrimitiveManager.add() × N (кубы/сферы/цилиндры)
│ - PlayerController.spawn() (R15-персонаж + камера)
│
▼
ScriptSandboxWorker пользовательские JS-скрипты в Web Worker-песочнице.
│ Доступный API: game.player, scene, ui, broadcast.
│
▼
MultiplayerSync опционально. Колyseus-комната, синк позиций.
│
▼
ЦИКЛ РЕНДЕРА (60 fps) scene.render() каждый кадр
Ключевые модули
engine/BabylonScene.js
Обёртка над Engine + Scene из Babylon. Создаёт освещение (HemisphericLight + DirectionalLight + теневой генератор), скайбокс, туман. Единый источник правды для ссылки на scene.
engine/GameRuntime.js
Оркестратор. Читает project_data (JSON, сохранённый редактором студии) и направляет каждый элемент в соответствующий менеджер. Lifecycle-хуки: loadProject(), start(), pause(), dispose().
Также обрабатывает «external URL» резолвинг (_resolveExternalUrl) — скрипты игры могут вызвать game.openUrl('/kubikon/play/12'), и URL корректно резолвится в сам плеер или на главный сайт.
engine/PlayerController.js
R15-персонаж (15-костный Mixamo-rig). Камеры от первого и третьего лица. Управление WASD/тач. Прыжки, гравитация, столкновения с воксельным гридом + AABB-моделями. Спавн/респавн.
Спец-режимы для GD: setAutoRun(true), setShipMode(true) — используются гейммодами Geometry Dash (куб/корабль/волна/НЛО/мяч/паук).
engine/BlockManager.js / TerrainVoxelBuilder.js
Воксельный ландшафт. Блоки — uint16 type-id'ы в чанковых массивах. rebuildChunk(chunkId) делает greedy meshing → один меш на материал на чанк (~40-100× меньше draw call'ов чем наивно).
engine/ModelManager.js
Загрузка .glb-моделей Kenney (или загруженных дизайнерами GLB из /api-storys/assets/rublox-designer/models/...). Кеширует AssetContainer по modelTypeId, инстанциирует клоны при каждом спавне.
engine/DecoManager.js
Лёгкие декоративные пропсы (камни, растения, знаки). Использует ThinInstanceCount для огромного перфоманса (тысячи инстансов → один draw call на тип).
engine/scripts/ScriptSandboxWorker.js
Пользовательские JS-скрипты выполняются в отдельном Web Worker. Доступная API-поверхность (только чтение):
// В скрипте игрока:
game.onTick((dt) => { ... });
game.onKey('space', () => { player.jump(); });
game.broadcast('event', payload);
game.player.setHealth(100);
scene.findOne('Cube1').rotateY(0.1);
ui.set({ score: 42 });
Скрипты НЕ имеют доступа к window, document, fetch, localStorage, сети. Запускаются изолированно в Worker'е через строгий postMessage-мост.
engine/multiplayer/MultiplayerSync.js
Colyseus 0.16 клиент. Подключается к комнате per gameId если мультиплеер включён. Синхронизирует позиции/повороты/анимации игроков на 20 Hz. Сервер по VITE_REALTIME_WS.
engine/gd/* (модули Geometry Dash)
30+ классов реализующих GD-стиль 2D-автораннер-гейммоды в 3D-мире:
GdCube.js— обычный прыжокGdShip.js— гравитация-флип, полётGdWave.js— синусоида-дэшGdBall.js— флип-прыжок мячомGdUfo.js— мульти-тап прыжкиGdSpider.js— мгновенный телепорт-
- порталы, ускорители, шипы, финишные линии, трейлы, чекпойнт-музыка
Фабрики для каждого (GdSpikeFactory, GdPortalFactory, GdMusicFactory...) живут в AdminPreview/gd*/.
Поток данных (один кадр)
1. ВВОД клавиатура/тач/геймпад → PlayerController.onInput()
2. ФИЗИКА гравитация + скорость + столкновения с блоками/моделями
3. СКРИПТЫ onTick(dt) колбэки пользовательских скриптов (в Worker'е, асинхронно)
4. МУЛЬТИПЛЕЕР читаем удалённые позиции, lerp других игроков
5. РЕНДЕР Babylon scene.render() → WebGL2 draw calls
6. UI React ре-рендерится только если вызвали game.ui.set() (throttle 250мс)
Чего НЕТ в плеере
- Редактирование — это в Студии.
- Лента игр / поиск / публикация — это на главном сайте (
rublox.pro/app). - Авторизация-UI — игроки приходят с JWT/ticket. Плеер только читает их.
- Админка / модерация — вынесены в приватный репозиторий (
disaster-recovery/для мейнтейнера).
Узкие места по производительности (что смотреть первым делом если тормозит)
game.ui.set()вызывается каждый кадр — React setState 60Hz убивает FPS. Дросселируй до 250мс с diff-проверкой.scene.findOne()на старте —sceneSnapshotприходит через rAF; ссылка будет null. Перенеси вonTickилиsetTimeout(0).blockMaterialDirtyMechanism=trueв Babylon — НЕ включать. Ломает рендер новых мешей (debris, трейсеры).createOrUpdateSelectionOctree()— то же. Ломает превью-призраки редактора.- GLB-загрузка через
SceneLoaderвместоAssetContainer— течёт материалами. ИспользуйAssetContainer+instantiateModelsToScene().
С чего начать новую фичу
| Что хочешь добавить | Начни здесь |
|---|---|
| Новый тип блока | engine/CONST/blockTypes.js + текстура в public/kubikon-assets/blocks/ |
| Новое API для скриптов | engine/scripts/ScriptSandboxAPI.js (добавь в apiSurface) |
| Новый GD-гейммод | Скопируй engine/gd/GdBall.js, зарегистрируй в GdGameModeRegistry.js |
| Новый HUD-виджет | editor-shared/GameHud.jsx |
| Превью-роут для дизайнера | AdminPreview/ (например gdSkins/PreviewGdSkins.jsx) |
| Мультиплеер-событие | Colyseus-схема в engine/multiplayer/schemas/ + хендлер в MultiplayerSync.js |
Лицензионные заметки для контрибьюторов
Контрибьютя, ты соглашаешься лицензировать свои изменения под AGPL-3.0 И предоставляешь мейнтейнеру неисключительную безотзывную лицензию на сублицензирование (см. CLA.md). Это нужно чтобы проект мог продавать коммерческие лицензии корпорациям.