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>
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>
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>
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>
1) При выделении папки (клик по сцене / вставка кита) дерево авто-раскрывается:
workspace + цепочка родителей + scrollIntoView к строке папки. Раньше папка
выделялась на сцене, но в свёрнутом дереве её не было видно.
2) Delete на выделенной папке (type='folder') → removeFolder(id, true) удаляет
всю папку со ВСЕМ содержимым + _cleanupOrphanScripts чистит осиротевшие
скрипты привязанные к удалённым объектам.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
1) Длинная тень-полоса: csm.frustumEdgeFalloff=8 — тень персонажа больше не
тянется на весь пол.
2) Удаление примитива/модели/блока через ПКМ теперь обновляет дерево
(markDirty + hierarchyDirtyRef) — раньше объект удалялся, но не пропадал.
3) Клик по СЦЕНЕ по объекту в папке → выделяется ВСЯ папка (selectByMesh
проверяет folderId). Отдельную часть — через раскрытие папки в дереве.
4) Free-drag папки: зажал ЛКМ на группе и тянешь — двигается вся папка
(moveFolderBy по дельте центра).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Дельта пивота применялась только в dragEnd → объекты телепортировались в
конце. Теперь _onFolderGizmoDrag применяет инкрементальную дельту на каждом
тике (setOnDrag) — движение/вращение/масштаб группы видно в процессе, как
у одиночных объектов.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Клик по папке в дереве → выделяется вся группа (подсветка всех объектов
внутри, рекурсивно по подпапкам) + групповой 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>
- Киты «Сундук» и «Счётчик монет» связаны через 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>
- 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>
- F в редакторе теперь фокусирует камеру на ВЫДЕЛЕННОМ объекте (раньше всегда
летел в центр 0,0,0). Если выделения нет — центр сцены. Только в edit-режиме.
- focusOnSelection поддерживает userModel + запасной путь по позиции меша.
- Вставка кита из Тулбокса: объект выделяется И камера наводится на него
(видно, куда добавилось) + переключение на инструмент «Выделить».
- Кит «Двойной прыжок» чинён: был setJumpPower (высокий прыжок) →
game.player.setDoubleJump(true) (настоящий второй прыжок в воздухе по Space).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Процедурный 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>
- Дерево «Объекты сцены»: авто-раскрытие ветки + скролл к объекту при
выборе на сцене (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>
@
Живое 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>
Движок: 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>
При 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>
- Текстура 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>
Баг: стрелка-указатель 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>
Задача 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>
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>
Большой консолидирующий коммит после поднятия 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>