Что:
- _resolveModelSource:
* Mixamo (skin_y-bot/x-bot/eve/...) → /character-assets/skins/<id>.glb
(с rublox-site, non-humanoid-rigged kind)
* Legacy R15 (skin_bacon-hair, skin_sigma-labubu и др.) — сохранена
старая ветка через manifest + /kubikon-assets/. Это нужно пока
бэк storys работает в legacy-режиме (RUBLOX_NEW_SKINS_AVAILABLE != true).
- skinFolderRef.current default: skin_bacon-hair → skin_y-bot
- BabylonScene._playerModelType default + миграция character-* → skin_y-bot
- PlayerController._modelTypeId default → skin_y-bot
- MultiplayerSync: все дефолты → skin_y-bot
LOCAL DEV:
- На localhost плеер сначала пробует localStorage('rublox_selected_skin')
(тот же ключ что в rublox-site), потом БД. Это позволяет тестить выбор
скина в сайте без записи в прод-БД.
Зависит от:
- PR storys (новый бэк-резолв + feature-flag)
- PR user (endpoint /<id>/gender)
- Заливки 80 GLB на rublox.pro/character-assets/skins/ (отдельная инфра-задача)
GraphicsManager (постобработка/материалы/API game.graphics) — паритет со студией,
применяется при загрузке игры если автор настроил. Новые материалы chrome/water/
iridescent. Realtime-эндпоинт переведён на game.rublox.pro (S1 NPM прямо, без
hop через S2 — чинит разрывы WebSocket). MultiplayerSync улучшен.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Порт LoadingScreenOverlay (Ken-Burns/4 стиля/карточка/verified) + старт-экран
при входе в Play + API game.loading.setBackground/isVisible/onHide. Идентично
студии. worker SOURCE синтаксис проверен. Проверено headless в плеере (0 ошибок).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LeaderstatsManager + AchievementsManager скопированы в плеер, интегрированы
в BabylonScene/worker/GameRuntime (те же точки, что в студии): HUD-таблица,
toast, кубок+страница, bindToStat, сохранение прогресса в БД (savegame, JWT),
мост onChange→worker. Прогон 2616 в плеере: таблица в DOM, 0 ошибок. Полная
фича-парность задачи 20.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фича-парность: Environment не рисует жёлтую сферу/луну (флаг _drawSkyBodies),
SkyboxManager — единый источник неба и света (lights в конструкторе). Порт
правок студии 1:1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фича-парность со студией: namespace game.mainMenu (show/hide/setCamera/
setPatchNotes/колбэки) + зацикливание облёта через onCutsceneDone +
game.player.setInputBlocked в worker + handler в runtime + passthrough
scene.mainMenu в load. Проверено: меню работает в плеере на игре 2434.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фича-парность со студией: LoadingScreenOverlay.js (DOM-оверлей),
namespace game.loading в worker (хэндл local→real + колбэки через
globalEvent), cmd loading.* + _ensureLoadingScreen в GameRuntime,
class-ref + tick + load конфига в BabylonScene. Проверено: экран
загрузки работает в плеере на тест-игре «Такси-босс» 2427.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PlacementManager + ShopInventoryUi + проводка game.placement.*/inventoryUi.*
в worker/GameRuntime/BabylonScene — опубликованные tycoon-игры с расстановкой
теперь работают в плеере. + TerrainManager backFaceCulling=false (воксели не
просвечивают), cleanup usermodel при Stop, Hotbar скрыт при пустом инвентаре.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Два бага меню в плеере:
1. Повторный ESC открывал меню ПОВЕРХ первого (не закрывал).
2. После открытия/закрытия меню переставала работать orbit-камера по
зажатой ПКМ (игры задачи 2 camera_mouse_controls).
Первопричина: ESC слушали ДВА обработчика — движок (setOnExitRequest →
_onEscMenu) и React (отдельный keydown при topMenuOpen). На одно нажатие
срабатывали оба → гонка: меню дублировалось, а _uiCursorMode застревал в
true, из-за чего onCanvasMouseDownGlobal (if _uiCursorMode return) игнорировал
ПКМ → orbit-камера не включалась.
Фикс — единый источник истины в движке:
- BabylonScene: флаг _playerMenuOpen + toggle в setOnExitRequest (открыто→
закрыть+setUiCursorMode(false), закрыто→открыть). _onEscMenu(open) передаёт
состояние в UI. setPlayerMenuOpen(open) — синхронизация при закрытии из UI
(кнопка «Продолжить»). Сброс флага в enterPlayMode.
- KubikonPlayer: setOnEscMenu((open)=>setTopMenuOpen(open)); УБРАН дублирующий
React ESC-обработчик; onClose меню → setPlayerMenuOpen(false); синхронизация
_playerMenuOpen=true в onLockChange (perma) и setOnPlayChange.
- PlayerController.setUiCursorMode(true): сброс _rmbHeld=false (иначе если меню
открыли при зажатой ПКМ, флаг застревал → orbit «думал» что ПКМ активна).
Проверено: ESC открыл→ESC закрыл (1 меню в DOM), ПКМ-orbit работает после меню.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Портирование фикса из studio (фича-парность движков). Баг: стрелка-указатель
game.fx.pointer не переключалась на следующую цель.
- find/findOne/all раньше возвращали голую строку-ref → .onTouch невозможен.
Приведены к студийному Instance-proxy (_getOrCreateInstance, coerces в строку
через Symbol.toPrimitive → обратно совместимо со старым кодом).
- Instance-proxy: + onTouch/onUntouch/onClick → inst.watchTouch{ref}.
Worker: _instTouchHandlers + маршрут instTouch/instUntouch/instClick;
_detectSnapshotDeltas для changed/destroying-событий.
- GameRuntime: inst.watchTouch/watchClick → _watchedTouchRefs; routeInstEvent.
- BabylonScene._detectTouchEvents: блок watched-объектов + _refToTarget;
_touchState.clear() в enterPlayMode.
- Первичный snapshot сцены в init (setInitialScene) → findOne на старте.
Проверено на проде player.rublox.pro/333: стрелка переключается
red-cube→blue-sphere→gold-chest, на финале удаляется.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_handlePlayClick пикал билборд из ЦЕНТРА экрана (w/2,h/2) — верно только при
pointer-lock. В third курсор свободен, юзер кликает мышью НЕ в центре →
pick промахивался, кнопки табличек не нажимались (Ферма 1981 и др).
Фикс: onMouseDown передаёт реальные canvas-координаты клика в
_handlePlayClick(clickX,clickY); при locked — центр, иначе — точка клика.
Добавлен console.log [billboard] для диагностики попадания.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Игры со студии (1995/2037/2046) звали game.hud.setHotbarVisible/setHpVisible —
в движке плеера были только hud.setVisible (весь HUD). Без них скрипт падал
на первой строке и игра не работала (нет монет, кнопки не жмутся).
Добавлено во все 3 слоя:
- ScriptSandboxWorker: методы hud.setHotbarVisible/setHpVisible → _send
- GameRuntime: обработчики cmd hud.setHotbarVisible/setHpVisible
- BabylonScene: _setHotbarVisible/_setHpVisible + колбэки видимости
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1. Стартовый скин не ставился: блок чтения scene.skins/playerModelType стоял
НИЖЕ предзагрузки модели и enterPlayMode. Перенёс ВЫШЕ — теперь
PlayerController при старте видит корректный _playerModelType.
2. Меню открывалось каждые ~4с: onPointerLockChange звал _onExitRequest при
любой потере lock. В third/front потеря lock = отпустили ПКМ (orbit), это
НЕ выход. Меню (Esc) только из perma-режимов (first/lockfirst/sideview/
shift-lock).
3. Управление 02: start() лочит только в perma-режимах; onCanvasClick не лочит
в third (курсор свободен для GUI/3D-табличек); ПКМ-orbit (onRmbDown/Up);
onWheel авто-переход third<->first; _isPermaLockMode/_applyCursorVisibility.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Задача 01 — billboard-клик не работал: _handlePlayClick не проверял кнопки
табличек. Добавил pick по billboard-мешу из центра экрана → pickButtonAt →
fireClick (BabylonScene._handlePlayClick).
Задача 02 — управление было старым (всегда pointer-lock, ПКМ не работал):
- start(): lock только в perma-режимах (first/lockfirst/sideview/shift-lock),
в third курсор виден свободно
- onCanvasClick: не лочит в third (курсор для GUI/3D-табличек)
- ПКМ-orbit: зажал ПКМ в third → lock+вращение, отпустил → курсор вернулся
- onWheel: авто-переход third↔first при зуме (порог 0.7), экспоненциальный шаг
- onPointerLockChange: отпускание ПКМ в third НЕ выходит из Play (раньше выходило)
- _applyCursorVisibility / _isPermaLockMode хелперы
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Плеер отстал на несколько задач — игры из студии не открывались с механиками.
Перенёс из rublox-studio в движок плеера:
Новые файлы движка:
- engine/ModalManager.js (задача 04 — модальные сцены)
- engine/BillboardUiManager.js (задача 01 — 3D-таблички)
Точечный перенос в существующие файлы:
- ScriptSandboxWorker.js: namespace game.modal/billboard/environment, скины в
game.player, game.gui.tween, _guiHandlerKeys(localId), события
modalOpened/modalClosed/skinChanged/billboardClick
- GameRuntime.js: команды modal.*/billboard.*/player.setSkin.*/gui.tween +
_broadcastSkinsSnapshot/_ensureSkinState + routeGlobalEvent с localId
- PlayerController.js: non-humanoid скины (loadNonHumanoid+reloadSkin+
процедурная анимация+pivot-центрирование), setInputBlocked/focusOnTarget,
камера задачи 02 (zoom/shift-lock), клавиша B (магазин)
- BabylonScene.js: init modalManager/billboardUiManager, методы магазина скинов,
чтение scene.skins, modalManager.tick, Esc-приоритет
- ScriptSandbox.js: sendSkinsSnapshot
- GuiManager.js: поля анимаций задачи 03 (синхронизирован со студией)
- PrimitiveTypes.js / PrimitiveManager.js: тип billboard + рендер
React-слой (editor-shared):
- ModalOverlay.jsx, SkinShopOverlay.jsx (новые) + подключены в KubikonPlayer
- GuiOverlay.jsx, GameHud.jsx синхронизированы со студией
eslint.config: послабления стилевых правил (no-empty off и т.п.).
Локальный build зелёный.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Open-source web player for Rublox games, dual-licensed under
AGPL-3.0 + Commercial.
Highlights:
- Babylon.js 7 + React 18 + Vite 5 stack
- Self-contained engine (~46k lines): BlockManager, ModelManager,
PlayerController, ScriptSandboxWorker, MultiplayerSync, 30+ GD
gamemodes
- Configurable backend via VITE_API_BASE and friends — works against
staging (dev-api.rublox.pro) out of the box
- Standalone mode (VITE_STANDALONE=true) loads a bundled sample game
for first-run without any backend
- Full docs: README, ARCHITECTURE, CONTRIBUTING, SECURITY, CHANGELOG
- Lint + format scaffolding (ESLint + Prettier + EditorConfig)
- Legal: LICENSE (AGPL-3.0), LICENSE-COMMERCIAL.md, CLA.md, COPYRIGHT.md
- Issue templates: bug_report, feature_request, security_disclosure
Removed before public release:
- frontend_deploy.py (contained production SSH credentials)
- ~27 admin endpoints (kept in private repo)
- Hard-coded internal URLs and IPs
- All previous git history (clean repo init)