86 Commits

Author SHA1 Message Date
min
e6cfcad2c0 fix(skin): валидация скина в Play-режиме редактора (legacy bacon → y-bot)
All checks were successful
CI / Lint (pull_request) Successful in 1m4s
CI / Build (pull_request) Successful in 1m57s
CI / Secret scan (pull_request) Successful in 23s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
KubikonEditor подмешивал skin_folder из БД в hash без проверки.
Для ~22 legacy-юзеров БД отдаёт skin_bacon-hair (модель удалена) →
в Play-режиме студии играл бекон. Теперь невалидный скин (не в
MIXAMO_SKINS и не customskin:) подменяется на skin_y-bot, как в
плеере (KubikonPlayer/GameMenu) и кабинете. Дефолты bacon → y-bot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:47:10 +03:00
min
1fb15eb87b feat(studio): вертикальная лестница ladder_vertical + лазание
All checks were successful
CI / Lint (pull_request) Successful in 1m5s
CI / Build (pull_request) Successful in 2m4s
CI / Secret scan (pull_request) Successful in 28s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
- новый примитив ladder_vertical с параметром stepCount (высота в ступенях)
- при смене stepCount лестница перестраивается (не растягивается модель)
- ladder-mode в PlayerController: W/S вверх-вниз, gravity off, Space отпрыг
- анимации climb_up/climb_down (лазание) + climb_to_top (вылезание наверх 4с)
- предзагрузка climb-анимаций (нет дёрга на 180° при входе)
- заморозка анимации на месте без исчезания скина (play/pause по moving)
- toolbox kit «Лестница (лазание)», иконка prim-ladder, Inspector-слайдер
- толщина лестницы defaultScale.z 0.12

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 23:46:53 +03:00
min
897dc08d3e feat(studio): 3-фазные прыжки в редакторе (перенос из плеера)
- MixamoAnimator обновлён: jump_anticipate/air/land, jump_fwd_*, jump_run_*
- PlayerController: _jumpKind (in_place/forward/run), anticipate-фаза с
  отложенным импульсом, coyote-фильтр спуска по лестнице (microAir)
- студия теперь анимирует прыжки 1-в-1 как плеер

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 22:18:24 +03:00
min
8f0266f8c2 fix(skin): cache-bust query ?v=20260614 for character-assets URLs
All checks were successful
CI / Lint (pull_request) Successful in 1m7s
CI / Build (pull_request) Successful in 2m2s
CI / Secret scan (pull_request) Successful in 24s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
After backend CORS rollout users had stale CORS-failure cached for
Mixamo GLB. Adding a query suffix forces browsers to re-fetch the URL
instead of replaying the cached failure.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 16:43:34 +03:00
min
1229bdad3f feat(studio): Mixamo skins + crouch + fullscreen + skin from DB
All checks were successful
CI / Lint (pull_request) Successful in 1m7s
CI / Build (pull_request) Successful in 2m0s
CI / Secret scan (pull_request) Successful in 23s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Синхронизация с rublox-player (Этап 1 ANIMATIONS_PLAN.md):

MIXAMO:
- Добавлен MixamoAnimator.js (полная копия из плеера)
- В PlayerController список MIXAMO_SKINS (78 шт)
- _resolveModelSource ветка для skin_* — грузит GLB с /character-assets/skins/
- _loadPlayerModel создаёт MixamoAnimator для Mixamo-скинов

CROUCH (Ctrl):
- AABB → 0.45, скорость 0.45×walk, приоритет над sprint
- Анимации: crouch_enter → crouch_idle / crouch_walk → crouch_to_stand
- Y-drop по 0.20-0.45м для разных Mixamo-клипов
- Анти-флик debounce + детект one-shot vs loopable

PREVIEW PLAYER:
- Skin приоритет: URL #skin= → БД → localStorage → дефолт
- Дефолт skin_bacon-hair → skin_y-bot

ENTERPLAYMODE:
- BabylonScene при Play читает hash/localStorage и подставляет user skin
  поверх projectModelType (тест-режим = играешь СВОИМ скином)

KUBIKONEDITOR:
- handlePlay async: предзагрузка скина из БД (если нет в URL) и инжект в hash
- При Play: requestFullscreen() — блокирует Ctrl+W/D/T/R/S/A/P/F и др.
- Во время Play: window keydown listener блокирует системные хоткеи,
  WASD проходят к PlayerController (для crouch+движение)
2026-06-14 15:50:19 +03:00
min
b03027e3d5 merge main (синхрон перед PR графики)
Some checks failed
CI / Lint (pull_request) Failing after 1m5s
CI / Build (pull_request) Successful in 1m58s
CI / Secret scan (pull_request) Successful in 27s
CI / PR size check (pull_request) Successful in 12s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
# Conflicts:
#	src/editor/engine/BabylonScene.js
2026-06-10 01:27:04 +03:00
min
8ccea76dc0 feat(studio): система графики/эффектов (шейдеры) + материалы + перенос Оформления
GraphicsManager: постобработка (bloom/FXAA/виньетка/цветокор/DoF) + тени/SSAO,
10 пресетов, mobile-safe, выкл по умолчанию. Новые материалы примитивов
(chrome/water/iridescent + улучшены glass/neon). API game.graphics.*. Графика +
Стартовый экран (Ken Burns) + Экран загрузки вынесены из Настроек в новый
GameDecorModal, открываются из вкладки «Игра» (группа «Оформление»). Вики-раздел
«Графика и эффекты» (GR1-GR4) + AI-контекст обновлён.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 01:24:30 +03:00
min
f7441b0bd6 feat: 50 ��� �� Lua + ������ Roblox ��� ���� + ������ ����
Some checks failed
CI / Lint (push) Failing after 1m8s
CI / Build (push) Successful in 1m58s
CI / Secret scan (push) Successful in 23s
CI / PR size check (push) Has been skipped
CI / Deploy to S1 + S2 (push) Successful in 3m28s
2026-06-09 21:59:19 +00:00
min
4757bf95a0 feat(studio): Team Create — синхрон GUI, папок и userModels
Дополнил коллаб-синхрон: GUI-элементы (guiManager create/update/remove),
папки (folderManager createFolder/renameFolder/removeFolder, id выравнивается
у соавторов через Map), пользовательские модели (userModelManager addInstance
с forceInstanceId / removeInstance). Списки в Hierarchy обновляются штатным
setInterval. Теперь синхронятся: примитивы, модели, блоки, скрипты, GUI,
папки, userModels.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 06:56:19 +03:00
min
73d7ae4765 merge main (синхрон перед PR синхрона скриптов)
All checks were successful
CI / Lint (pull_request) Successful in 1m6s
CI / Build (pull_request) Successful in 1m59s
CI / Secret scan (pull_request) Successful in 28s
CI / PR size check (pull_request) Successful in 10s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
2026-06-08 06:28:56 +03:00
min
58edaef2ab fix(studio): Team Create — синхрон скриптов (upsertScript/removeScript)
Раньше синхронизировались только примитивы/модели/блоки, а скрипты нет —
у соавтора было 0 скриптов. Перехватываем scene.upsertScript/removeScript,
шлём op scriptUpsert/scriptRemove; applyRemoteOp применяет их у соавтора
(список в Hierarchy обновляется штатным setInterval). Лимит соавторов 5
(MAX_COLLABORATORS в realtime StudioRoom, задеплоен на VM110).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 06:28:45 +03:00
min
2b98d8338b Merge remote-tracking branch 'origin/main' into feat/rbxl-import
All checks were successful
CI / Lint (pull_request) Successful in 1m8s
CI / Build (pull_request) Successful in 2m8s
CI / Secret scan (pull_request) Successful in 23s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
# Conflicts:
#	src/editor/HierarchyPanel.jsx
2026-06-08 06:24:27 +03:00
min
9caea93d32 feat(rbxl-import): single-VM Lua runtime + GUI tree + Touched/click events
All checks were successful
CI / Lint (pull_request) Successful in 1m6s
CI / Build (pull_request) Successful in 1m58s
CI / Secret scan (pull_request) Successful in 23s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
ITERATION 6 (single-VM rewrite):
  - RobloxLuaSharedWorker: один wasmoon-state на 742 скрипта (не 742 VM)
  - Pre-populated Workspace + Player.PlayerGui перед addScripts
  - На каждом Part — Touched/TouchEnded сигналы; на каждом TextButton —
    MouseButton1Click/Activated/MouseEnter/Leave; Humanoid с Died/Health
  - Двухфазный init: addScriptsBatch ВСЕ скрипты → kickoff() с PlayerAdded
  - wait()/task.wait/task.spawn/task.delay через scheduler+coroutines
  - guiClick от Rublox-GUI → fireEvent → инстанс.MouseButton1Click.Fire()
  - playerTouch → part.Touched.Fire(HumanoidRootPart) + humanoid.Touched

ITERATION 7 (nullStub compatibility):
  - debug.setmetatable(nil, ...) + debug.setmetatable(function() end, ...)
    с полным набором __index/__newindex/__call/__add/__sub/.../__len/__concat
  - Возврат undefined из FindFirstChild/WaitForChild (вместо JS proxy)
  - Lua-side __null_stub_singleton с Connect/connect/Wait/Fire (lowercase aliases)
  - __rbxl_lookup_part через __rbxl_parts_by_id table (не ipairs на JS array)
  - script.Parent гарантированно не nil (либо реальный Part либо null stub)
  - RbxSignal: Connect+connect, Wait+wait, Fire+fire, Disconnect+disconnect
  - SIGNAL_NAMES whitelist расширен: Tool (Selected/Equipped), Remote (OnInvoke),
    ChatMakeSystemMessage, etc.

Converter:
  - GUI: UDim2 dataclass правильно резолвится (scale*100 + offset/viewport*100)
  - размеры в процентах (как Rublox-GuiOverlay ожидает)
  - ScreenGui.Enabled → пропагируется в детей
  - Эвристика скрыть HD Admin/Chat/CommandBar/TeleportTo модалки
  - rbxasset:// rbxassetid:// фильтруются на пустой URL

Hierarchy:
  - scroll-to-selected раскрывает workspace+rootPrims+folders перед scroll
  - data-sel-id на всех ItemRow с rAF×2 timing

Известные ограничения:
  - Synapse X obfuscated скрипты часто всё равно падают (требуют конкретный Roblox-VM)
  - но debug.setmetatable перехват не даёт скриптам валиться на indexing/arithmetic
  - реальные пользовательские KillBrick (Touched) теперь работают
  - GUI кнопки → MouseButton1Click работают

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 06:18:55 +03:00
min
c0613853a2 fix(studio): Team Create — экран загрузки только в плеере, коллаб новой игры, вход по инвайту
1) Стартовый экран загрузки больше НЕ показывается в студии при тестовом
запуске (scene._editorMode), только в плеере на rublox.pro «Играть».
2) Новая игра: коллаб-сессия поднимается сразу после первого сохранения
(без перезагрузки) + кнопка «Пригласить» авто-сохраняет проект.
3) Незалогиненный по collab-ссылке → форма входа rublox.pro/login (origin без
/app, был 404) с ?return → возврат на инвайт-ссылку.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 05:57:55 +03:00
min
fbf7ef680b feat(studio): Team Create — совместное редактирование игры в реальном времени
StudioCollab (Colyseus studio-room): синхрон операций примитивов/моделей/блоков,
presence (курсоры/камера/выделение), soft-lock объектов, перехват менеджеров.
CollabOverlay: DOM-курсоры соавторов + онлайн-аватарки + тосты. Кнопки
«Скины»+«Пригласить» в TopRibbon вкладка «Игра». Гость-режим (скрыты
Настройки/Сохранить/Опубликовать). Autosave только host. Вход по ?collab-токену.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 03:27:38 +03:00
min
cc6447b851 fix(rbxl-import): UDim2 viewport-relative + rbxasset URL filter
All checks were successful
CI / Lint (pull_request) Successful in 1m5s
CI / Build (pull_request) Successful in 2m1s
CI / Secret scan (pull_request) Successful in 27s
CI / PR size check (pull_request) Successful in 11s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
- UDim2: scale теперь умножается на viewport reference (1280×720),
  раньше игнорировался — фреймы получали 0×0 и фейлились на дефолт 100×30
  или наоборот заполняли всё окно
- _udim2_pair(): пара (x,y) через _udim2_to_rublox(axis='x'|'y')
- Фильтр rbxasset:// rbxassetid:// rbxhttp:// rbxthumb:// URL'ов на пустую
  строку — браузер их не загружает, спам в console исчезает

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 01:49:20 +03:00
min
624bbc636b feat(rbxl-import): single-VM, Touched, scroll-to-selected, GUI
Some checks failed
CI / Lint (pull_request) Failing after 1m5s
CI / Build (pull_request) Failing after 49s
CI / Secret scan (pull_request) Successful in 25s
CI / PR size check (pull_request) Successful in 9s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Все 5 задач итерации:

1. Single-VM mode (RobloxLuaSharedWorker/Sandbox):
   - один Worker, одна wasmoon-VM на ВСЕ скрипты проекта
   - addScript() для каждого, общий tick/event broadcast
   - снимает WASM OOM (1 VM 16MB вместо 742 × 16MB)
   - убран per-script лимит 50, теперь все 742 загружаются

2. Touched events:
   - sendGlobalEvent в shared sandbox распознаёт playerTouch
     и пересылает в Worker как 'touched' с primId
   - Worker находит Part по __primId в workspace и Fire'ит
     его Touched сигнал — Lua-обработчики работают

3. Click в иерархии → scroll-to-selected:
   - useEffect в HierarchyPanel ловит изменение selection
     и scrollIntoView для нужного ItemRow
   - data-sel-id атрибут на primitive/model/block строках

4. GUI Roblox в конвертере:
   - ScreenGui/Frame/TextLabel/TextButton/ImageLabel/TextBox →
     scene.gui c полным набором свойств (UDim2→pixel, Color3→hex,
     BackgroundTransparency→bgOpacity, parentId)

5. Чистка:
   - удалены debug-console.warn из PlayerController._loadPlayerModel
     (убирает spam '[PlayerController.devlog]' в consoles)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 01:39:43 +03:00
min
412bb2fad9 feat(rbxl-import): студия исполняет импортированные Roblox-Lua скрипты
All checks were successful
CI / Lint (pull_request) Successful in 2m43s
CI / Build (pull_request) Successful in 1m57s
CI / Secret scan (pull_request) Successful in 1m21s
CI / PR size check (pull_request) Successful in 8s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
Сегодня доведены до играбельного состояния:
- UI модалка импорта подключена в KubikonStudio (кнопка для МИНа в навигации)
- Converter: SCALE 0.35 (карта пропорциональна R15-персонажу),
  playerModelType='skin_bacon-hair', Lua упакован в поле code с маркером
  // @roblox-lua (storys API сохраняет только {id,code,target,name})
- vite.config: api+статика через rublox.pro/minecraftia-school.ru
- GameRuntime: распознаёт маркер, запускает через RobloxLuaSandbox
  + wasmoon Worker. Фильтрация: target!=null + lua<2500б +
  лимит 50 sandbox'ов (WASM OOM при >50 VM)
- roblox-shim: nullStub (Proxy с no-op методами) вместо null
  для FindFirstChild/WaitForChild — цепочки не падают
- require() заменён на nullStub
- RobloxLuaSandbox: совместимость с интерфейсом ScriptSandbox
  (sendGlobalEvent/SceneSnapshot/etc — no-op заглушки)
- RobloxLuaWorker: pcall обёртка над user-кодом
- remoteDevlog.js + /devlog endpoint: автосбор browser-логов
- PlayerController._loadSkinManifest: dev-fallback на studio.rublox.pro

Тест на Easy Obby:
- 8205 instances → 2245 primitives + 742 Lua-scripts
- 50/742 Lua-VM запущены (KillBrick handlers и т.п.),
  151 отфильтровано как admin/chat services, 541 пропущено по памяти
- Скин bacon-hair виден, FPS 20-25
- Сцена играется, можно ходить, прыгать

TODO (следующая итерация):
- Single-VM mode для wasmoon (один Lua-state на 742 скрипта,
  убрать WASM OOM)
- Реализовать select/focus в иерархии для импортированных карт
- Touched events от Babylon impostor → Lua-shim сигналы
- Поддержка GUI (ScreenGui/Frame/TextLabel) в конвертере

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 21:13:16 +03:00
min
c31b1ed3d6 feat(studio): задача 05 — экран загрузки (Ken Burns + название места)
LoadingScreenOverlay: Ken-Burns фон (CSS pan+zoom) + 4 стиля (ken-burns/static/
parallax/particles) + карточка-композиция (cover/название места/автор/verified-SVG).
Стартовый экран при входе в Play (showStartupLoadingScreen из enterPlayMode +
поля проекта loadingScreen.* + serialize/deserialize). API game.loading.
setBackground/isVisible/onHide + расширенный show. UI редактора: секция
«Стартовый экран входа (Ken Burns)». Вики g5 #62 + статья. Тест-игра 2713.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 20:01:00 +03:00
min
f46e6f0102 fix(studio): убрал 2 eslint-ошибки в main (showToast no-undef + text self-assign) — CI был красным для всех PR
Some checks failed
CI / Lint (pull_request) Failing after 28s
CI / Build (pull_request) Failing after 31s
CI / Secret scan (pull_request) Failing after 34s
CI / PR size check (pull_request) Failing after 32s
CI / Deploy to S1 + S2 (pull_request) Has been skipped
2026-06-07 15:06:28 +03:00
min
e15dc56de3 fix(studio): self.delete снимает interact-подсказку (E больше не висит на пустоте)
_applySelfDelete удалял меш, но запись в _interactables оставалась → промпт
«E Собрать» висел на месте собранного предмета. Теперь запись чистится по ref.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:59:25 +03:00
min
661ff60bdf fix(studio): инвентарь — собранное идёт сначала в hotbar (виден), hotbar поднят над подсказкой
1) add() заполняет сначала hotbar, потом grid → собранные предметы сразу видны
   в постоянном хотбаре (раньше уходили в скрытую сетку — хотбар казался пустым).
2) Хотбар поднят bottom 14→64px, не перекрывает подсказку внизу экрана.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:51:27 +03:00
min
42f1334908 feat(studio): задача 44 — drag-drop инвентарь (сетка 8×5 + hotbar 9 + стаки + редкости)
InventoryUI.js: DOM-оверлей — окно инвентаря по I (сетка 8×5), постоянный
hotbar 9 (клавиши 1-9), drag-drop между слотами (HTML5), стаки с maxStack,
5 редкостей (цвет рамки), tooltip на hover, ПКМ-меню (использовать/разделить/
выбросить), сортировка по редкости. API: game.items.define([...]),
game.inventory.give/take/open/toggle/sort/setActiveHotbar. onUseEffect heal/speed.
Сериализация scene.inventory2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:45:24 +03:00
min
931d53b4d9 fix(studio): бластер от 3-го лица стреляет в точку клика, а не в центр камеры
При свободном курсоре (нет pointer-lock, 3-е лицо) выстрел шёл из getForwardRay
(фокус камеры). Теперь onDown берёт координаты клика → setAimScreenPoint → луч
через точку клика; onMove обновляет _holdAim для авто-огня при удержании. При
pointer-lock (1-е лицо, курсор в центре) — прежнее поведение (центр).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:01:14 +03:00
min
e4fdd91b12 fix(studio): оружие попадает по NPC (pickable+npcId) → авто-floater урона работает
Меши NPC ставились isPickable=false → raycast бластера/меча проходил сквозь
них, урон и авто-floater не срабатывали. Теперь меши NPC pickable + npcId в
metadata; damageByMesh находит NPC по metadata (быстро) или по rootMesh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:49:06 +03:00
min
854074bfa2 feat(studio): авто-floater над мобами + урон NPC от оружия (задача 40 доп)
game.fx.autoMobFloaters(true) — включает облачка урона над NPC при любой потере
HP (NpcManager.damage). NpcManager.damageByMesh — оружие (бластер/меч) наносит
урон скриптовым NPC (weapons.setOnHit → npcManager.damageByMesh). Связка:
выстрел бластера → урон NPC → авто-floater «-N» над целью.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:41:41 +03:00
min
458b6c3b59 feat(studio): задача 40 — damage floaters (game.fx.damageFloater)
FloaterManager.js: object pool (30 billboard-планов с DynamicTexture), tween
подъём+fade+покачивание, crit pop-scale, цвета damage/crit/heal/mana/miss,
стек одинаковых по stackKey (×N), комикс-стиль (BAM!/KAPOW!/POW! на звезде).
API game.fx.damageFloater(position, value, opts) — position {x,y,z} или ref/
'player'. Интеграция: tick в render-loop, resetRuntime при stop. Тест-игра
«Тренировочный полигон» id=2676.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 11:05:25 +03:00
min
f8f0d976ef fix(studio): Ctrl+шорткаты не двигают камеру (Ctrl+D больше не уводит вправо)
onKeyDown клал любую клавишу в _codes (набор для WASD-движения камеры),
включая D при зажатом Ctrl → камера летела вправо при копировании. Теперь
клавиши с ctrl/meta в _codes не попадают.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 10:44:14 +03:00
min
6c0c3dc26e fix(studio): Ctrl+D дублирует объект РОВНО на месте оригинала (не смещает +1 по X)
duplicateSelected для model/userModel/primitive ставил копию на sel.x+1 →
визуальное смещение. Теперь копия появляется в той же точке (как Roblox Studio).
Block остаётся с поиском свободной клетки (воксель нельзя в занятую).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 10:38:34 +03:00
min
e477d652f6 fix(studio): mainMenu.show подхватывает opts.onPlay/onShow/onHide (порт)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:17:43 +03:00
min
ba90bf5c7d feat(studio): кит «Таблица лидеров» в Toolbox → Готовые механики
Новый кит (категория ui): определяет лидерборд (Очки primary + Время),
время идёт само, очки растут от broadcast('score'|'coins'). Сохраняется в БД.
Работает вместе со счётчиком монет/очков. Всего 47 китов.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 10:11:18 +03:00
min
ce6e69a2e8 fix(studio): saveProgress/loadProgress с JWT-заголовком (был 401 при сохранении прогресса)
loadProgress/saveProgress (лидерстаты/достижения) слали fetch без Authorization
→ 401 UNAUTHORIZED. Используют _economyAuthHeaders() (JWT игрока из localStorage).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 10:01:38 +03:00
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
c9498b086e fix(studio): SkyboxManager.hexToRgb поддерживает короткий хекс #fff (был NaN в облаках)
skybox.clouds.color='#fff' → substring(4,6)='' → parseInt NaN → addColorStop
'rgba(255,15,NaN,0.9)' падал при load → прерывал загрузку проекта. hexToRgb
теперь расширяет #fff→#ffffff и подстраховывает NaN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 09:49:01 +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
cf34f9cdb6 fix(studio): враг бьёт с анимацией удара, ключ исчезает при подборе
1+2) Враг с HP / волна врагов: радиус удара 3.5 (NPC останавливался на
     followGap=2.5, урон-чек d<2.5 не срабатывал). Добавлена анимация атаки —
     R15Animator.attack (выпад рукой), npc.setAttacking, NpcManager.setAttacking.
3) Ключ исчезает при подборе: scene.setVisible теперь парсит ref ('primitive:N')
   — obj.visible=false слал {ref} без kind/id, поэтому ключ не пропадал.
4) Машина — остаётся рантайм vehicle:car (особенность транспорта).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 20:26:11 +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
26e6306f6e fix(studio): дверь-код подсказка E только при открытой, NPC=R15-скин (анимация рук/ног), торговец видимый
1) Дверь по коду: подсказка «E закрыть» теперь только когда дверь открыта
   и игрок рядом (через onKey+onTick, без постоянного interact-промпта).
2) NPC-киты используют R15-скин 'skin_roblox-noob' → процедурная анимация
   бега/покоя с руками и ногами (R15Animator), вместо безжизненного покачивания.
3) Торговец-кит: невидимый триггер (insertGameplayKit теперь уважает
   prim.visible=false, раньше хардкод visible:true) + NPC-персонаж рядом —
   синий куб больше не виден.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:54:38 +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
fe8b6b5b38 fix(studio): NPC-киты (robot→character-a), дверь по коду плавно распахивается
1) NPC-преследователь/торговец/волна: spawnNpc('robot') → 'character-a'
   (модели 'robot' не существует в ModelTypes → spawnNpc возвращал null → ошибка).
2) Дверь по коду: верный код → ПЛАВНОЕ открытие вокруг петли (как дверь по E),
   декор-панели вращаются вместе с полотном. Раньше полотно уезжало вниз,
   декор оставался.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:36:18 +03:00
min
3bf1e77230 fix(studio): self.setLabel, дверь по коду (красивая+радиус), счётчик механик, ссылка на скрипт в консоли
1) Дверь по коду: красивая составная дверь (полотно+рамка+кодовая панель),
   поле ввода появляется ТОЛЬКО когда игрок в радиусе 6м (onTick по дистанции).
2) game.self.setLabel/clearLabel добавлены (кит «Метка с именем» падал
   'setLabel is not a function').
3) Плитка «Готовые механики» в тулбоксе считает киты динамически
   (GAMEPLAY_KITS.length), а не хардкод «12».
4) Консоль: ошибки/логи скриптов привязаны к источнику — справа строки
   кликабельная ссылка «📄 имя скрипта», открывает скрипт в редакторе
   (_log прокидывает scriptId/scriptName).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:27:09 +03:00
min
045f892aaa fix(studio): светофор (obj.color по ref), грядка растёт+зреет (obj.scale), кит скрытия HP
1) scene.setColor теперь принимает {ref} (obj.color=hex), не только {id}.
   Светофор переключал цвета через obj.color, но ref игнорировался → не работал.
2) Грядка: добавлен obj.scale (scene.setScale → mesh.scaling). Урожай после
   сбора исчезает, растёт за 5с (scale 0→1) и зреет цветом красный→зелёный,
   при полном размере снова собирается.
3) Кит «HP-бар» теперь сам прячет стандартный HUD HP (setHpVisible false).
   Новый кит «Скрыть стандартный HUD HP» — отдельно прячет дефолтную полосу.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:13:02 +03:00
min
018fce474b fix(studio): объекты больше не вываливаются из папки после Play/Stop (folderId в serialize)
Корень: serialize примитивов/моделей/userModel НЕ сохранял folderId. При
Play→Stop сцена восстанавливалась из снапшота без группировки → все части
кита (светофор/шипы/дверь) вываливались из папки в общие «Примитивы».
Добавлен folderId в serialize всех 3 менеджеров + восстановление в loadFromArray
(model/userModel явно, primitive через opts.folderId).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:00:36 +03:00
min
6ece149924 fix(studio): камера 3-го лица не цепляется за проходимые зоны (canCollide в metadata)
Зона опасности / триггеры (canCollide:false) ловились camera-clamp, и камера
прыгала к игроку внутри зоны. Причина: metadata примитива НЕ содержал
canCollide, а PlayerController._clampCameraToWorld проверяет md.canCollide.
Добавлен canCollide в metadata меша (+ синк при updateInstance).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 18:49:17 +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
ed7310a532 feat(studio): +25 готовых механик из Вики (вся партия 3 — все остальные)
Добавлены все оставшиеся механики из TOOLBOX_KITS_FROM_WIKI.md:
Мир: зона опасности, шипы, светофор, грядка-урожай, падающие предметы.
Интерфейс: счётчик очков, HP-бар, дверь по коду (textbox), метка с именем,
  обратный отсчёт, 3D-стрелка-указатель.
Эффекты: костёр (particles fire), магнит монет.
NPC и бой (новая категория): преследователь, торговец (modal.dialog),
  мишень, враг с HP, волна врагов, диалог/кат-сцена, машина (vehicle:car).
Экономика (новая категория): магазин-кнопка, кликер, ключ+замок.

+2 категории китов (NPC и бой, Экономика). Всего ~37 китов.
Опущены «Главное меню» и «Экран загрузки» — требуют целой сцены, не «1 клик».
Все 45 скриптов прошли синтаксис-проверку, билд зелёный.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:55:32 +03:00
min
f270854795 feat(studio): +5 готовых механик (цветная плитка/лава/лифт/финиш/звук)
Партия 2 из TOOLBOX_KITS_FROM_WIKI.md:
- Цветная плитка — onTouch → смена цвета (self.setColor).
- Лава — onTouch/onUntouch → урон 15 HP/сек пока стоишь (player.damage).
- Лифт — onTick синусоида, ездит вверх-вниз 8 единиц.
- Финиш (победа) — onTouch → экран «ПОБЕДА!» + setInputBlocked.
- Звуковая плитка — onTouch → sound.play('coin') + подсветка.

game.self расширен: setColor(hex). Все 22 кита прошли синтаксис-проверку.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:31:49 +03:00
min
6938f83a3c fix(studio): декор двери поворачивается в ту же сторону (левосторонняя СК Babylon)
Ручка/филёнки уезжали на обратную сторону двери: формула поворота смещения
была правосторонняя, а Babylon mesh.rotation.y — левосторонняя. Единая rotY()
(wx=lx·c+lz·s, wz=-lx·s+lz·c) для полотна И декора → всё открывается синхронно
в одну сторону.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:23:35 +03:00