30 Commits

Author SHA1 Message Date
min
33cd435d06 feat(studio): прогресс лидербордов и достижений сохраняется в БД (между сессиями)
GameRuntime.saveProgress/loadProgress — helper к storys savegame endpoint
(/kubikon3d/savegame/<pid>/<uid>/<ns>) для движковых менеджеров.

- Достижения: при unlock сохраняются в БД (namespace _achievements) + localStorage
  как быстрый кэш; loadFromDB при Play восстанавливает разблокированные.
- Лидерстаты: статы текущего игрока сохраняются в БД (namespace _leaderstats,
  дебаунс 1с при set); loadFromDB при Play восстанавливает значения.
- Загрузка из БД через 250мс после старта скриптов (даём define зарегистрировать).

Теперь прогресс игрока подгружается при каждой сессии с любого устройства.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 09:59:11 +03:00
min
5d49cd9eeb feat(studio): задача 20 — лидерборды (leaderstats) + достижения (achievements)
Leaderstats: HUD-таблица top-right (blur, сортировка по primary, топ-10,
подсветка me, flash-инкремент). API game.leaderstats.define/set/add/get/
onChange + me.* (format number/time/short). LeaderstatsManager.js.

Достижения: toast справа (4 редкости + звук + очередь, slide-in/out), кнопка-
кубок слева-снизу → страница grid (locked grayscale+замок, hidden=?, прогресс-
бар). API game.achievements.define/unlock/has/bindToStat/setButtonVisible/
openPage. bindToStat(id, stat, {gte/lte/eq}) — авто-unlock по лидерстату.
Сохранение unlocked в localStorage по проекту. AchievementsManager.js.

Интеграция: оба менеджера в BabylonScene (tick leaderstats в Play, resetRuntime
при stop, serialize/load в project_data scene.leaderstats/achievements). worker-
API + GameRuntime cmd-обработчики + мост leaderstats.onChange→worker (globalEvent
leaderstatsChange) для bindToStat. Плеер пока НЕ портирован (по плану).

Тест-игра «Сбор монет с достижениями» id=2616 (is_test): поляна + 30 монет +
3 стата + 5 достижений (3 через bindToStat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 09:32:53 +03:00
min
c4d184257b fix(studio): враг=NPC+урон, волна бьёт, удалённые скрипты не исполняются, ключ+дверь красивые, тени-acne
1) Враг с HP → R15-NPC (зомби-скин), преследует и бьёт игрока при касании.
2) Волна врагов: враги наносят урон при касании (onTick дистанция → damage).
3) Удалённые скрипты больше не исполняются: _cleanupOrphanScripts при удалении
   объекта (primitive/model/userModel) + перед enterPlayMode чистим скрипты-сироты.
4) Ключ и замок: ключ из примитивов (стержень+кольцо-torus+бородка), дверь
   как дверь-по-E (плавный поворот вокруг петли, только с ключом).
6) Тени-полосы: normalBias 0.005→0.02 (убирает acne-полосы от соседних объектов).

Машина (vehicle:car) — остаётся рантайм-спавном (особенность транспорта).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 20:12:50 +03:00
min
9903719f9d fix(studio): дверь-код закрывается по E, NPC ходит с анимацией, торговец=NPC, тени короче
1) Дверь по коду: открытую можно закрыть по E (onInteract) → снова вводить код.
2) NPC: процедурная анимация ходьбы (покачивание по Y + наклон корпуса) для
   Kenney-моделей — раньше скользили без анимации.
3) Торговец переделан в NPC-персонажа (spawnNpc character-a) + невидимый
   триггер с диалогом по E (вместо примитивов).
4) Тени: убрана «полоса через всю карту» — autoCalcDepthBounds off,
   shadowMaxZ 90/60 (было 200/120), lambda 0.6, frustumEdgeFalloff 12.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:47:27 +03:00
min
2d669a3ff3 fix(studio): выделение папки раскрывает дерево + Delete удаляет всю папку с содержимым
1) При выделении папки (клик по сцене / вставка кита) дерево авто-раскрывается:
   workspace + цепочка родителей + scrollIntoView к строке папки. Раньше папка
   выделялась на сцене, но в свёрнутом дереве её не было видно.
2) Delete на выделенной папке (type='folder') → removeFolder(id, true) удаляет
   всю папку со ВСЕМ содержимым + _cleanupOrphanScripts чистит осиротевшие
   скрипты привязанные к удалённым объектам.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 18:36:55 +03:00
min
46414d874b fix(studio): кит спавнится на поверхности в фокусе + многочастный в папку + снятие выделения при Play
1) Предметы кита из тулбокса спавнятся на ТВЁРДОЙ поверхности под центром
   экрана (getPlacementPointAtCenter: raycast в пол/объект), а не под камерой.
2) Многочастный кит (дверь) теперь реально попадает в папку: insertGameplayKit
   ставил folderId, но дерево не пересобиралось (markDirty не трогает
   hierarchyDirtyRef) — добавлен hierarchyDirtyRef.current=true.
3) enterPlayMode снимает любое выделение редактора (объект/папка) + убирает
   пивот папки и gizmo — в Play больше нет подсветки выбранного.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 18:30:41 +03:00
min
bf93219266 fix(studio): клик по части папки выделяет всю папку + free-drag папки + удаление обновляет дерево + затухание длинной тени
1) Длинная тень-полоса: csm.frustumEdgeFalloff=8 — тень персонажа больше не
   тянется на весь пол.
2) Удаление примитива/модели/блока через ПКМ теперь обновляет дерево
   (markDirty + hierarchyDirtyRef) — раньше объект удалялся, но не пропадал.
3) Клик по СЦЕНЕ по объекту в папке → выделяется ВСЯ папка (selectByMesh
   проверяет folderId). Отдельную часть — через раскрытие папки в дереве.
4) Free-drag папки: зажал ЛКМ на группе и тянешь — двигается вся папка
   (moveFolderBy по дельте центра).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 18:19:02 +03:00
min
c7b5f3645d fix(studio): групповые манипуляции папки в реальном времени (не телепорт)
Дельта пивота применялась только в dragEnd → объекты телепортировались в
конце. Теперь _onFolderGizmoDrag применяет инкрементальную дельту на каждом
тике (setOnDrag) — движение/вращение/масштаб группы видно в процессе, как
у одиночных объектов.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 02:53:35 +03:00
min
4c8f8c99cb feat(studio): групповые манипуляции папки (выделение+move/rotate/scale всей группы)
Клик по папке в дереве → выделяется вся группа (подсветка всех объектов
внутри, рекурсивно по подпапкам) + групповой gizmo на пивоте в центре папки.
Манипуляторы двигают/вращают/масштабируют ВСЕ объекты папки сразу. Выбор
отдельной модели внутри — манипулирует только ей (как раньше).

- FolderManager: getFolderObjects (рекурсивный сбор + центр), moveFolderBy,
  scaleFolder (от центра, +размеры примитивов), rotateFolderY расширен на модели.
- SelectionManager.selectFolder → multi-подсветка + type:'folder' + пивот-gizmo.
- BabylonScene._attachFolderGizmo/_applyFolderGizmo: пивот-TransformNode,
  на dragEnd дельта (move/rotate/scale) применяется ко всей папке, пивот
  пересоздаётся в новом центре. Пивот убирается при смене выделения.
- Дерево: клик по строке папки = выделить группу; клик по шеврону = свернуть.

Многокомпонентные модели уже кладутся в авто-папку (ModelManager) — теперь
их можно двигать как единое целое.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 02:40:00 +03:00
min
471af1cdeb fix(studio): сундук→счётчик монет через broadcast, удаление точки спавна + фолбэк 0,0
- Киты «Сундук» и «Счётчик монет» связаны через game.broadcast('coins',{add})
  + game.onMessage('coins') — раньше каждый кит в своём worker, счётчик не
  обновлялся (был globalThis, не работает между воркерами).
- Точку спавна теперь МОЖНО удалить: Delete (SelectionManager.deleteSelected
  обрабатывает type==='spawn' → scene.deleteSpawn) + ПКМ в дереве → контекст-
  меню «Навести камеру / Удалить точку спавна».
- Если точка спавна удалена (_spawnEnabled=false) — игрок появляется в
  (0, поверхность+2, 0). Постановка новой точки (setSpawnAtCamera) возвращает.
- spawnEnabled сериализуется в project_data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 02:21:38 +03:00
min
df1647019d fix(studio): game.self.rotate + понятные имена скриптов китов
- game.self.rotate(ry)/rotateY(ry) добавлен в worker (слал scene.rotate с
  ref объекта-носителя). Кит «Вращающийся объект» падал 'game.self.rotate is
  not a function' каждый кадр в onTick — теперь крутится.
- upsertScript принимает name; вставка кита даёт скрипту имя = название кита
  (раньше в дереве был сырой id script_mq03...). Ручное создание скрипта тоже
  даёт «Скрипт N» / «Скрипт объекта N» вместо id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 02:05:17 +03:00
min
4284fef704 fix(studio): F-фокус на выделенном объекте, автофокус при вставке кита, двойной прыжок
- F в редакторе теперь фокусирует камеру на ВЫДЕЛЕННОМ объекте (раньше всегда
  летел в центр 0,0,0). Если выделения нет — центр сцены. Только в edit-режиме.
- focusOnSelection поддерживает userModel + запасной путь по позиции меша.
- Вставка кита из Тулбокса: объект выделяется И камера наводится на него
  (видно, куда добавилось) + переключение на инструмент «Выделить».
- Кит «Двойной прыжок» чинён: был setJumpPower (высокий прыжок) →
  game.player.setDoubleJump(true) (настоящий второй прыжок в воздухе по Space).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 01:45:40 +03:00
min
a4881ee5ce fix(studio): единая система неба — убрать второе (жёлтое) солнце
Environment больше НЕ рисует свою жёлтую сферу-солнце/луну/фон (флаг
_drawSkyBodies=false) — иначе на небе было два солнца. Единое небо рисует
SkyboxManager (купол + солнечный диск + облака + горы). SkyboxManager стал
единым источником освещения: каждый пресет выставляет direction/intensity/
color солнца и ambient (lights переданы в конструктор), fadeTo плавно ведёт
и свет. Environment оставлен только для day/night cycle совместимости.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:44:25 +03:00
min
71536668f2 feat(studio): задача 16 — кастомное небо (SkyboxManager)
Процедурный gradient-skybox без внешних текстур: купол-сфера с ShaderMaterial
(градиент верх→горизонт→низ + солнечный диск + дымка), low-poly горы на
горизонте, billboard-облака с дрейфом, атмосферный туман, звёзды.

Пресеты: clear-summer-day / lowpoly-roblox / cloudy / sunset / starry-night /
space. Плавный fadeTo между пресетами (анимация цветов купола в tick).

game-API (студия): game.scene.setSkybox/setClouds/setFog,
game.scene.skybox.fadeTo/setSunDirection. Сериализация неба в project_data.
Тик облаков/перехода работает и в редакторе (превью).

Плеер пока НЕ портирован (по указанию — сначала проверка в студии).
Тест-игра «Небесная демка» id=2541 (dev-режим is_test=true, не в ленте).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:17:23 +03:00
min
75e83a9f3b feat(studio): UX-правки редактора — выбор, копирование, userModels, free-drag
- Дерево «Объекты сцены»: авто-раскрытие ветки + скролл к объекту при
  выборе на сцене (HierarchyPanel useEffect на selection).
- Копирование/дублирование примитива сохраняет вращение rotationX/Y/Z
  (SelectionManager клал selection без rotation → копия теряла поворот).
- Копирование/дублирование переносит скрипты объекта на копию
  (_copyScriptsToNewObject + clip.scripts для Ctrl+C/V).
- userModels (воксельные модели) теперь видны в дереве в группе «Мои
  модели», можно выбрать/удалить/прикрепить скрипт (target kind userModel
  уже поддержан в GameRuntime).
- Free-drag: перетаскивание объекта ЛКМ как в Roblox Studio — скольжение
  по полу/поверх объектов с AABB-коллизией (скольжение вдоль преграды).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-06-04 23:54:30 +03:00
min
2fda576e11 feat(14): Vehicle System V1+V2 — машины, на которых можно ездить
All checks were successful
CI / Lint (pull_request) Successful in 1m9s
CI / Build (pull_request) Successful in 2m2s
CI / Secret scan (pull_request) Successful in 2m36s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Система транспорта для Рублокс-студии (задача 14 Недели 4):
- VehicleManager — аркадная физика (газ/руль/тормоз/реверс), коллизия
  через physics.moveAABB; GLB-кузов Kenney car-kit (колёса в модели).
- VehicleHud — графический спидометр-стрелка (SVG, 270° дуга) + передача D/R/N.
- Вход hold-F / выход E; камера follow/капот/кинематографичная (V циклит).
- game.scene.spawn(vehicle:car, opts) + onVehicleEnter/onVehicleExit.
- Звук мотора: низкочастотный рокот (бас-пила + шум + LFO-пульсация тактов),
  pitch/громкость ∝ скорости — не воющий тон.
- Авто оседает на землю при спавне (_settle + повторы при поздней готовности
  физики) — не висит/не тонет.
- Водитель скрывается за рулём; падение в бездну → выход + респавн.
- Производительность: addShadowCaster фильтрует мелкие/тонкие/огромный пол меши;
  InstancedMesh без receiveShadows (фикс тормозов 5→50 FPS).
- Вики: карточка #61 «Такси-симулятор» + статья + 2 скриншота.
- incrementPlay(id, userId) — передаём user_id для self/user-cooldown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-06-03 02:24:43 +03:00
min
f0e284878e feat(13): главное меню игры (game.mainMenu)
All checks were successful
CI / Lint (pull_request) Successful in 1m19s
CI / Build (pull_request) Successful in 2m6s
CI / Secret scan (pull_request) Successful in 2m36s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Живое 3D-меню как в топ-играх Roblox: cinematic-камера облетает витрину,
патч-ноуты, логотип, кнопка ИГРАТЬ, музыка, блок управления.
- game.mainMenu.show/hide/setCamera/setPatchNotes/onShow/onPlay/onHide
- 4 режима камеры: cinematic(waypoints)/orbit/static/preset-cuts поверх camera.cutscene
- зацикливание облёта через onCutsceneDone (камера не вылетает за сцену)
- game.player.setInputBlocked экспортирован в worker + handler в runtime
- passthrough scene.mainMenu в toJSON/load
- вики g5 #60 guide-garage, тест-игра «Гараж Босса» id 2434 (GLB-машина Kenney)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:07:33 +03:00
min
34060c90c3 feat(12): внутриигровой Loading Screen (game.loading)
All checks were successful
CI / Lint (pull_request) Successful in 1m13s
CI / Build (pull_request) Successful in 2m3s
CI / Secret scan (pull_request) Successful in 2m35s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Программный экран загрузки для перехода между мирами:
- game.loading.show(opts) → хэндл (setProgress/setText/setCover/close/onSkip/onComplete)
- game.loading.transition(opts) → Promise (фейковый прогресс за duration)
- cover sceneSnapshot, прогресс-бар+процент, спиннер, кнопка Пропустить, логотип
- blockInput + пауза симуляции, fadeIn/Out; tick независим от paused
- настройки проекта «Экран загрузки» (логотип/акцент/дефолты) + 3 сниппета
- LoadingScreenOverlay.js (новый DOM-оверлей), worker namespace loading,
  cmd loading.* + _ensureLoadingScreen, serialize/load конфига в scene
- вики g5 #59 guide-taxi (карточка + урок), тест-игра «Такси-босс» id 2427

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:00:26 +03:00
min
ee1b7352b7 feat(11): placement mode — расстановка предметов (tycoon)
Some checks failed
CI / Lint (pull_request) Successful in 1m15s
CI / Build (pull_request) Successful in 1m58s
CI / Secret scan (pull_request) Failing after 9s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Движок: PlacementManager (тень-превью формой воксельной модели за курсором,
снап к сетке, стопка, проверка зоны и баланса, поворот R/колесо, ПКМ/Esc),
ShopInventoryUi (магазин-слоты, авто-серые при нехватке валюты); проводка
game.placement.* и game.inventoryUi.* в worker/GameRuntime/BabylonScene.

Попутные фиксы:
- TerrainManager: backFaceCulling=false — воксели не просвечивают (видна была
  задняя грань сквозь переднюю);
- KubikonEditor: guard от потери userModels/scripts при частичной загрузке
  (terrain догрузился, модели/скрипт нет → автосейв затирал) — критичный
  фикс защиты данных для ВСЕХ игр;
- Hotbar: пустой инвентарь не показывает панель (глобальное правило);
- MinimapOverlay: миникарта только по флагу игры (не авто на больших картах);
- cleanup usermodel-инстансов при Stop.

Вики: карточка #58 + статья-урок «Мой завод» (g5 Разбор готовых игр),
openProjectId=2345, скриншоты залиты на прод.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 19:06:03 +03:00
76b2afd312 feat(10): живые 3D-надписи (attachFace) + витрина-лутбокс + вики
Some checks failed
CI / Lint (pull_request) Failing after 5s
CI / PR size check (pull_request) Successful in 12s
CI / Secret scan (pull_request) Failing after 14m51s
CI / Build (pull_request) Failing after 14m52s
CI / Deploy to S1 + S2 (pull_request) Has been cancelled
Движок: LabelManager attachFace (текст плоско на грань примитива, FRONTSIDE
без зеркала), tilt, 5 пресетов, richText; GameRuntime scene.move/scene.rotate
для моделей и примитивов; ScriptSandboxWorker obj.move/obj.rotate в Instance-
proxy; InspectorPanel настройки label. Вики: карточка #57 guide-dynamic-label
(Часовая башня) + полная статья-урок с разбором attachFace/obj.move/format.money.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 21:15:54 +03:00
7c95072e4f merge main into feat/studs-material-09
All checks were successful
CI / Lint (pull_request) Successful in 1m6s
CI / Build (pull_request) Successful in 1m56s
CI / Secret scan (pull_request) Successful in 2m33s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
2026-05-31 14:03:54 +03:00
ea80ec3aa6 fix(09): studs не растягиваются при scale-drag примитива
All checks were successful
CI / Lint (pull_request) Successful in 1m7s
CI / Build (pull_request) Successful in 1m58s
CI / Secret scan (pull_request) Successful in 2m31s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
При scale-гизмо mesh.scaling тянул faceUV → studs превращались в полосы.
Фикс: во время drag прячем studs-текстуру (плоский цвет), в dragEnd меш
пересоздаётся с правильным faceUV. _recreateMesh для studs пересоздаёт
материал заново (свежий тайлинг + восстановление текстуры).
GizmoController: + onDrag (live) колбэк для scale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 13:37:44 +03:00
7ab66fc4c5 feat(09): сочные круглые studs (v4) + color-пикер окрашиваемых блоков
- Текстура studs v4: круглые кружки с усиленным объёмом (normal strength 4.0,
  запечённый блик/тень) + контактная тень от каждого кружка. Фон 0.97 — цвет
  остаётся сочным. emissive 45% от цвета на примитивах (Roblox-look).
- Версионные имена файлов (studs_v4_*) — обход browser-кэша Babylon.
- Color-пикер блоков: в палитре при выборе окрашиваемого блока (studs-block)
  под категориями появляется ряд из 8 лего-цветов + input «свой цвет».
  BabylonScene.setActiveBlockColor → addBlock(...,color) при постановке.
- DEV-хук ?dev=<имя> (localhost): грузит /dev-<имя>.json в редактор для
  локального теста без БД (на проде неактивен).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 12:22:03 +03:00
7c928462fc fix(engine): findOne(x).onTouch работает + findOne на старте скрипта
All checks were successful
CI / Lint (pull_request) Successful in 1m8s
CI / Build (pull_request) Successful in 1m56s
CI / Secret scan (pull_request) Successful in 2m31s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Баг: стрелка-указатель game.fx.pointer не переключалась на следующую цель —
при касании цель не менялась, стрелка не выключалась.

Первопричина (две движковые проблемы):
1. findOne(x).onTouch(...) не существовал: Instance-proxy не имел методов
   касания, движок ловил touch только объектов со скриптом-target/триггеров.
2. Race: скрипт исполняется синхронно в init, а sceneSnapshot приходил позже
   (rAF) → findOne() на старте = null → подписки onTouch молча не вешались.

Фикс:
- Instance-proxy: + onTouch/onUntouch/onClick → шлёт inst.watchTouch{ref}.
  Worker: _instTouchHandlers + маршрут instTouch/instUntouch/instClick по ref.
- GameRuntime: handler inst.watchTouch/watchClick → _watchedTouchRefs;
  routeInstEvent(ref,type); сброс в teardown.
- BabylonScene._detectTouchEvents: блок watched-объектов (AABB по ref, rising/
  falling edge → routeInstEvent), _refToTarget(ref)→{kind,id},
  _touchState.clear() в enterPlayMode.
- Первичный snapshot сцены передаётся прямо в init
  (ScriptSandbox.setInitialScene → worker заполняет _sceneIndex до userFn) →
  findOne работает в синхронном теле скрипта на старте.

Проверено: телепорт игрока по 3 целям игры 333 — стрелка переключается
red-cube→blue-sphere→gold-chest, на финале удаляется.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 08:28:02 +03:00
e3e5960241 feat: 3D-стрелка-указатель (game.fx.pointer) + is_test + Ctrl+V в редакторе + вики-карточка
All checks were successful
CI / Lint (pull_request) Successful in 2m10s
CI / Build (pull_request) Successful in 1m58s
CI / Secret scan (pull_request) Successful in 2m33s
CI / PR size check (pull_request) Successful in 10s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
- game.fx.pointer: лента бегущих шевронов + парящий quest-marker над целью
  (конус остриём вниз, свечение, bob+вращение, обводка); presets guide/quest/
  danger/gift/custom; расширенный game.fx.beam (8 текстур, curved, градиент).
- Примитив pointer в палитре (Геймплей) + инспектор + _activatePointers при Play.
- is_test: переключатель «Тестовая игра» в GameSettingsModal (не течёт в каталог).
- Ctrl+V в Monaco-редакторе скриптов (guard на .monaco-editor + activeElement).
- Вики: карточка g5 «Туториал — собери монетки» (Разбор готовых игр).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:45:57 +03:00
42be04def9 feat(week4): модальные сцены, кастомные скины игрока и вики-гайды по 4 играм
Some checks failed
CI / Lint (pull_request) Failing after 1m10s
CI / Build (pull_request) Successful in 2m2s
CI / Secret scan (pull_request) Successful in 2m36s
CI / PR size check (pull_request) Successful in 6s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Задача 04 — модальные сцены (затемнение + GUI/3D-анимация + блок ввода):
- engine/ModalManager.js (state-машина, fade, spotlight-проекция, HighlightLayer)
- editor/ModalOverlay.jsx (CSS-overlay + mask-image для spotlight)
- PlayerController.setInputBlocked/setCameraFrozen/captureCameraState/focusOnTarget
- game.modal.open/close/update/isOpen/onClose + пресеты bossIntro/lootbox/dialog/confirmation
- Фиксы ядра: клик GUI-кнопок (realId↔localId), modalOpened через globalEvent,
  guard от двойного срабатывания колбэков, кнопка ✓ на последней строке диалога

Задача 07 — кастомные скины игрока + магазин:
- non-humanoid скины (любая 3D-модель): загрузчик, процедурная анимация,
  настраиваемый AABB, центрирование через pivot-node
- PlayerController.reloadSkin (смена скина в Play)
- game.player.setSkin/unlockSkin/getAvailableSkins/onSkinChange/openSkinShop + локальная валюта
- editor/SkinShopOverlay.jsx (встроенный магазин, клавиша B) + SkinManagerModal.jsx (вкладка «Скины»)
- сериализация scene.skins, кнопка «Скины» в тулбаре

Вики — категория «Разбор готовых игр»:
- docsGames.js: группа g5 + 4 карточки (Двор/Витрина GUI/Сундук/Парк)
- docsLessons.jsx: 4 подробные статьи-урока для детей
- «Открыть мою копию» создаёт копию проекта (оригинал не трогается)

Адаптивная ширина кнопки billboard под длинный текст.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 00:50:56 +03:00
c32914c819 feat: интерактивные 3D-таблички (BillboardGui/SurfaceGui)
Some checks failed
CI / PR size check (pull_request) Successful in 22s
CI / Lint (pull_request) Failing after 2m17s
CI / Secret scan (pull_request) Successful in 3m21s
CI / Build (pull_request) Successful in 3m31s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Задача 01 из 1 - Неделя 4/ЗАДАЧИ РУБЛОКС. P0-приоритет: без таблиц
с кнопками невозможны симуляторы, тайкуны, фермы.

Новое:
- engine/BillboardUiManager.js — 4 пресета (shop-item, shop-purchase,
  banner, sign), 18 иконок, DynamicTexture-рендер, UV-hit-test
- PrimitiveTypes: новый тип 'billboard' в категории 'gameplay'
- PrimitiveManager: case billboard в _createMeshForType (Plane), init
  через applyToMesh, billboardOpts в updateInstance
- BabylonScene: PointerEventTypes-handler для кликов с _isPlaying-чеком
  и pointer-lock поддержкой
- GameRuntime: команды billboard.set/update/onClick, callback через
  sandbox.sendEvent('billboardClick')
- ScriptSandboxWorker: пространство game.billboard.{set,update,onClick}
- BillboardEditorModal.jsx — модалка с живым canvas-превью, 8 готовых
  градиентов + кастомные пикеры, дропдаун из 18 иконок
- InspectorPanel: кнопка 'Редактировать табличку…' для billboard-примитива
- KubikonEditor: проброс модалки через onEditBillboard prop
- Icon.jsx: SVG prim-billboard

Два режима ориентации: 'camera' (BillboardGui-аналог, всегда смотрит
на игрока) и 'fixed' (SurfaceGui-аналог, прикреплён к поверхности).

Клик-детекция через ray-pick → UV → пиксели текстуры → поиск кнопки
по AABB; работает с пиксельной точностью даже при повороте камеры.

Документация: RUBLOX_STUDIO_FUNCTIONS.md раздел 1.25.

Тестовая игра 'Магазин апгрейдов' (4 таблички + банер + HUD) — МИН
соберёт в студии drag-n-drop'ом.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 11:58:06 +03:00
0bcbb89664 fix(scripts): пробел в Monaco-редакторе скриптов больше не блокируется
Some checks failed
CI / Lint (pull_request) Failing after 6s
CI / Build (pull_request) Failing after 9s
CI / PR size check (pull_request) Successful in 15s
CI / Secret scan (pull_request) Successful in 3m48s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
BabylonScene.onKeyDown глобально перехватывал Space (preventDefault для
прокрутки страницы при WASD-навигации камеры). isTypingTarget проверял
только input/textarea/contentEditable — но Monaco роутит keydown через
свой внутренний div, и e.target оказывается не textarea, а
.monaco-editor-container div.

Фикс: добавлена проверка target.closest('.monaco-editor') — если фокус
в Monaco, считаем что юзер печатает и не глотаем клавиши.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 11:50:09 +03:00
61fba4e174 fix: починка билда + studio.rublox.pro инфра
Some checks failed
CI / Lint + Format (push) Failing after 32s
CI / Build (push) Failing after 37s
CI / Secret scan (push) Failing after 37s
CI / PR size check (push) Has been skipped
Большой консолидирующий коммит после поднятия studio.rublox.pro (28 мая 2026).
Содержит изменения которые делались в процессе подготовки прод-окружения:

Фиксы импортов после выноса из minecraftia:
- Массовая замена путей ../../components → ../components (40+ файлов в src/community/, src/admin-preview/)
- Замена ../KubikonEditor/ → ../editor/, ../KubikonStudio/ → ../community/, ../AdminPreview/ → ../admin-preview/
- API.js скопирован из минки целиком (было 8 экспортов, стало 312)
- Добавлены PLAYER_URL, MyButton_1, недостающие компоненты
- Заменены require() на статические ES-imports в BabylonScene, PrimitiveManager, GameRuntime (Vite не поддерживает CJS require)

Структура ассетов:
- public/kubikon-templates/ → public/assets/kubikon-templates/
- public/kubikon-learn/ → public/assets/kubikon-learn/
- (код искал в /assets/, файлы лежали без /assets/)

Навигация роутов внутри студии:
- /kubikon-studio/docs → /docs (90+ навигационных вызовов sed-replaced)
- /kubikon-editor/X → /edit/X, /kubikon/play/X → /play/X, /kubikon/gd/X → /gd/X

UI:
- Новый компонент StudioHeader (61px, как в минке) + копия favicon
- WithHeader wrapper в App.jsx для всех страниц кроме fullscreen-редактора/плеера
- SSO ticket-flow в AuthContext (auto-redeem #ticket= при загрузке)
- Тёмная тема карточек игр в ВИКИ (фон #1c2231 вместо #fff, картинка впритык)

Документация:
- docs/ONBOARDING.md — путь нового контрибьютора от нуля до PR
- docs/TUTORIAL_ADD_SCRIPT_API.md — как добавить game.* API
- API_USAGE.md — список эндпоинтов backend
- README в подпапках engine/, engine/terrain/, engine/voxel/, engine/robloxterrain/, engine/types/

.gitignore:
- public/wiki/ исключён (73МБ PNG, будут на CDN отдельной задачей)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 05:01:13 +03:00
31adbf151b Initial public release: Студия Рублокса v1.0
Open-source веб-студия для создания игр Рублокса, двойная лицензия
AGPL-3.0 + Коммерческая.

Главное:
- Vite 5 + React 18 + Babylon 7.54.3 + Monaco Editor + Colyseus 0.16
- Самодостаточный движок ~28к строк (66 файлов): BlockManager,
  TerrainVoxelBuilder, ModelManager, DecoManager, PlayerController,
  ScriptSandboxWorker, MultiplayerSync, 30+ GD-гейммодов
- Главный редактор KubikonEditor (~37к строк) + панели, ScriptEditor (Monaco)
- Витрина игр (KubikonFeed, KubikonStudio, KubikonDocs, KubikonLearn)
- Geometry Dash sub-app (GdMenu, GdShop, GdRules, GdCoverArt)
- 10 admin-preview каталогов для дизайнеров (скины, музыка, порталы и т.д.)
- Конфигурируемый бэкенд через VITE_API_BASE — работает со staging
  (dev-api.rublox.pro) без настройки
- Standalone-режим (VITE_STANDALONE=true) — открыть пустой редактор без бэка
- Полная документация (на русском): README, ARCHITECTURE, CONTRIBUTING,
  SECURITY, CHANGELOG
- ESLint + Prettier + EditorConfig
- Legal: LICENSE (AGPL-3.0), LICENSE-COMMERCIAL.md, CLA.md, COPYRIGHT.md
- Issue templates: bug_report, feature_request, security_disclosure

Перед публикацией:
- Все импорты из minecraftia заменены на локальные
- Все хардкоды URL (minecraftia-school.ru) и внутренних IP убраны → env
- Admin-эндпоинты Kubikon3DService вырезаны (остаются в приватном репо)
- AdminKubikonModeration не публикуется (модерация — в team.rublox.pro)
- 93 МБ ассетов public/kubikon-assets вынесены в .gitignore
  (раздаются через release artifact)
2026-05-27 23:41:10 +03:00