17 Commits

Author SHA1 Message Date
min
f77a741428 feat(player): не включать fullscreen в десктоп-приложении
All checks were successful
CI / Lint (pull_request) Successful in 57s
CI / Build (pull_request) Successful in 1m31s
CI / Secret scan (pull_request) Successful in 20s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
В Electron-обёртке (rublox-desktop) окно уже на весь экран без браузерной
панели и вкладок — fullscreen не нужен (раньше защищал от Ctrl+W/Ctrl+T,
в десктопе этого риска нет). По флагу window.__RUBLOX_DESKTOP__ (его ставит
preload Electron):
- handleGameStart/handleMobileStart не вызывают requestFullscreen;
- стартовый текст «Нажми чтобы играть» без упоминания FS (показывает
  управление WASD);
- пункт «Полноэкранный режим» в меню игры скрыт.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 20:17:27 +03:00
min
71139def77 fix(skin): валидация скина из БД — fallback на y-bot для legacy
All checks were successful
CI / Lint (pull_request) Successful in 57s
CI / Build (pull_request) Successful in 1m28s
CI / Secret scan (pull_request) Successful in 19s
CI / PR size check (pull_request) Successful in 5s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Бэкенд отдаёт skin_bacon-hair как дефолт (22+ юзеров в БД с legacy R15),
которого больше нет. Теперь если скин не в MIXAMO_SKINS (80 валидных) и
не customskin: → fallback на skin_y-bot. Персонаж всегда загружается.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 00:19:36 +03:00
min
eef7008416 feat(anim): 3-фазная анимация прыжка на месте (anticipate + air + land)
- jump_anticipate (0.375с): присед перед прыжком, физика заблокирована,
  Hips опускается визуально
- jump_air (0.975с): полёт без Hips.Y подъёма (физика управляет _modelRoot)
- jump_land (0.56с): амортизация при приземлении, Hips опускается
  относительно maxY (никогда не выше bind — иначе ноги повиснут в воздухе)
- Mixamo Jumping разрезан на 3 GLB через scripts/split_clip.js
- Blender pipeline для FBX→GLB через scripts/fbx2glb_blender.py + strip_anim_channels.js
- GameLoadingScreen убран при старте плеера (по умолчанию игра открывается сразу)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 20:25:30 +03:00
min
ca1ce23205 feat(player): crouch animation system + fullscreen + skin from DB
All checks were successful
CI / Lint (pull_request) Successful in 57s
CI / Build (pull_request) Successful in 1m33s
CI / Secret scan (pull_request) Successful in 44s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Этап 1 плана анимаций (ANIMATIONS_PLAN.md):

CROUCH (Ctrl):
- При зажатии Ctrl персонаж приседает, AABB → 0.45
- Скорость в crouch = 0.45×walk, crouch имеет приоритет над sprint
- Анимации: crouch_enter (one-shot) → crouch_idle / crouch_walk
- При вставании: crouch_to_stand (one-shot, если не движется)
- Y-drop для разных Mixamo-клипов (crouch_idle: -0.45, walk: -0.25)
- Anti-flicker debounce 120ms в MixamoAnimator

FULLSCREEN + СТАРТ-ЭКРАН:
- При запуске игры показывается оверлей "Нажми чтобы играть"
- Клик → requestFullscreen() → Chrome блокирует Ctrl+W/D/T/R/S и др.
- В fullscreen Esc отдаётся браузеру (выход), меню открывается на Tab
- Без fullscreen — Esc открывает меню как обычно
- BottomBar динамически показывает Esc/Tab в зависимости от режима

СКИН ЮЗЕРА:
- Приоритет: URL #skin=<id> → БД (rublox_equipped_skin) → localStorage → skin_y-bot
- В Esc-меню "Участники" Mixamo-скины грузят PNG с /character-assets/skins/

MIXAMO ANIMATOR:
- Полный класс с lazy-loading 35 состояний
- AnimationGroup loop=true через onAnimationGroupEnd safety-net
- crossFadeFrom для плавных переходов
- Жёсткий stop всех не-current групп → нет фантомных анимаций
2026-06-14 15:29:13 +03:00
min
dbdd61b4d6 feat(player): dev-skin через URL #skin= + убран beforeunload
All checks were successful
CI / Lint (pull_request) Successful in 55s
CI / Build (pull_request) Successful in 1m34s
CI / Secret scan (pull_request) Successful in 27s
CI / PR size check (pull_request) Successful in 10s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
LOCAL DEV: при запуске на localhost плеер берёт скин из:
1) hash-параметра #skin=<id> (сайт 3000 передаёт его при play-ticket
   через buildPlayerUrl(gameId, ticket, selectedSkin))
2) localStorage самого плеера (rublox_selected_skin)
3) дефолт skin_y-bot

Это нужно потому что:
- localStorage на :5173 (плеер) и :3000 (сайт) — РАЗНЫЕ хранилища
- В прод-БД пока legacy-скины (skin_sigma-labubu и др.), пока feature-flag
  RUBLOX_NEW_SKINS_AVAILABLE=false плеер не должен в неё лезть локально

PROD: только БД (rublox_equipped_skin) — поведение не меняется.

Также убран beforeunload-prompt: системное окно браузера невозможно
стилизовать (Chrome игнорирует кастомный текст с 2017), а уродливое
окно мешало. Случайное закрытие вкладки теперь без подтверждения.
2026-06-14 11:02:47 +03:00
min
8047cd366c Revert "Merge pull request 'revert: ����� Mixamo skin support' (#27) from revert/mixamo-skin-2026-06-13 into main"
This reverts commit 62ff0b01007684ed9ffdf6e550f7d257f58c3f9e, reversing
changes made to 830f4b8f4a2055e5e596a95b3268e30619c34724.
2026-06-14 11:02:25 +03:00
min
91870d7a09 Revert "feat(skin): Mixamo 80 + fallback �� legacy R15 (#26)"
All checks were successful
CI / Lint (pull_request) Successful in 55s
CI / Build (pull_request) Successful in 1m41s
CI / Secret scan (pull_request) Successful in 21s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
This reverts commit 830f4b8f4a2055e5e596a95b3268e30619c34724, reversing
changes made to 7d6e14a08fe2fcf0709a846f9a5efba536dd7184.
2026-06-13 12:50:26 +03:00
min
94da0e1409 feat(skin): Mixamo-палитра 80 скинов + fallback на legacy R15
All checks were successful
CI / Lint (pull_request) Successful in 56s
CI / Build (pull_request) Successful in 1m38s
CI / Secret scan (pull_request) Successful in 25s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Что:
- _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/ (отдельная инфра-задача)
2026-06-13 10:24:37 +03:00
min
ccf76d539b feat(player): графика/эффекты (фича-парность со студией) + realtime на game.rublox.pro
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>
2026-06-10 01:29:00 +03:00
min
f5a96fbec0 fix(player): задача 05 — красивый экран загрузки ИГРЫ при входе (а не в студии)
Главное по задаче 05: переделан React loading-оверлей в KubikonPlayer (тот,
что игрок видит после клика «Играть» пока грузится игра). Новый компонент
GameLoadingScreen: Ken Burns фон + карточка-витрина + название места + автор
+ verified-галочка + прогресс-бар (реальный 0→100%) + спиннер. Данные:
project_data.scene.loadingScreen (настройки автора из студии) → мета игры
(title/thumbnail/автор) → дефолт. 0 ошибок, проверено headless.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 19:46:20 +03:00
min
eb6430182b feat(14): Vehicle System V1+V2 — порт в плеер
All checks were successful
CI / Lint (pull_request) Successful in 57s
CI / Build (pull_request) Successful in 1m34s
CI / Secret scan (pull_request) Successful in 2m30s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Фича-парность со студией (задача 14):
- VehicleManager + VehicleHud (спидометр-стрелка) идентичны студийным.
- game.scene.spawn('vehicle:car'), onVehicleEnter/Exit, hold-F/E, камера follow/V.
- Звук мотора (рокот+LFO), оседание машины на землю (_settle+повторы),
  скрытие водителя, респавн при падении, shadow-caster фильтр (фикс FPS).
- incrementPlay(id, userId) — передаём user_id для cooldown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 02:25:15 +03:00
acb5b0b133 fix(player): меню ESC — toggle вместо открытия поверх + чинит orbit-камеру по ПКМ
All checks were successful
CI / Lint (pull_request) Successful in 58s
CI / Build (pull_request) Successful in 1m35s
CI / Secret scan (pull_request) Successful in 2m29s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Два бага меню в плеере:
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>
2026-05-31 09:55:58 +03:00
8f0524cbb3 feat: порт 3D-стрелки-указателя в плеер (фича-парность) + dev JWT-панель
- game.fx.pointer + расширенный game.fx.beam: BeamManager (текстуры/curved/
  градиент/quest-marker), ScriptSandboxWorker (_normFxPoint от DataCloneError),
  GameRuntime (fx.createPointer/pointerTarget/pointerUpdate/beamUpdate/
  beamVisible), BabylonScene._activatePointers. 1-в-1 со студией.
- Dev JWT-панель на экране «Нужен JWT» (только localhost): кнопка → инпут →
  localStorage.player_jwt + reload.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:46:24 +03:00
e26f854578 fix(player): меню больше не открывается на отпускание ПКМ (orbit)
React onLockChange в KubikonPlayer считал ЛЮБУЮ потерю pointer-lock за
нажатие ESC и открывал меню. В third отпускание ПКМ (orbit-камера) тоже
снимает lock → меню выскакивало на каждый поворот камеры.

Теперь меню открывается только если lock потерян в perma-режиме
(first/lockfirst/sideview/shiftLock) — там потеря lock = реальный ESC.
В third отпускание ПКМ игнорируется.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:15:09 +03:00
a46829c5f7 feat: синхронизация движка плеера со студией (задачи 01-07)
Some checks failed
CI / Lint (pull_request) Failing after 42s
CI / Build (pull_request) Successful in 1m30s
CI / Secret scan (pull_request) Successful in 2m28s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Плеер отстал на несколько задач — игры из студии не открывались с механиками.
Перенёс из 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>
2026-05-30 03:15:43 +03:00
6d86aa7c36 docs: переводы оставшихся английских комментариев на русский
- src/api/API.js — комменты, описание env
- vite.config.js — описание полей
- src/App.jsx — IndexRoute (текст «Плеер Рублокса»)
- src/KubikonPlayer/KubikonPlayer.jsx — exitPlayer
- src/engine/PlayerController.js — _storysApiUrl
- src/engine/GameRuntime.js — _resolveExternalUrl
- src/engine/devlog.js — убрал упоминания приватных путей разработчика
- src/fixtures/sample-game.json — title/description
2026-05-27 23:18:38 +03:00
87444ee2c8 Initial public release: Rublox Player v1.0
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)
2026-05-27 23:04:04 +03:00