Наша история. Делаем игры с 2018 года: OkuuGame → UpBilim (2023) → PROlab Group. UpBilim Studio — редактор игр на нашем движке: 3D, физика, ИИ-помощники, выпуск в UpBilim Player.
Плеер: трава, толпы и пачки предметов дешевле в 2 раза
Плеер (приложение, режим «Видеокарта»): копии одного предмета (InstancedMesh — трава, деревья, толпа, пачки движка) теперь передаются видеокарте одним набором, и только когда меняются, а не по одному объекту каждый кадр. Сцена из 4000 домов и 40 000 травинок тратит на кадр 4,5 мс процессора вместо 8,4 мс, кадров больше — 109 вместо 101, а без теней — 127 вместо 99.
Как выглядит игра, не меняется.
ферма: грядки растут по настоящему времени
Движокновая деталь UB.farm3d для игр-ферм, как Grow a Garden.
СтудияИИ знает UB.farm3d и может сделать игру-ферму по просьбе.
живой фон в ленте
Плеер (сайт и приложение): если игра в ленте грузится дольше 0,7 с, вместо неподвижной обложки идёт видео игры — первые 8 секунд, без звука, по кругу. Как только игра пошла, видео исчезает. Если игра стартует сразу (уже скачана), видео не качается, чтобы не мешать игре.
Автору: чтобы у игры был живой фон, загрузи видео в «Выпустить» → «Видео игры». Записать его можно кнопкой «Записать видео» в Студии.
«Подписаться» и «Ремикс» прямо в ленте
Плеер (сайт и приложение): на карточке ленты Плеера появились две кнопки.
В приложении Плеера кнопки появятся с новой версией.
«Целиком» в ленте больше не считается уходом
Кабинет авторов («Статистика» → «Лента»): «пролистнули за 3 с» и график «На какой секунде листают дальше» считают только свайпы к другой игре. «Целиком», «Об игре» и выход из ленты больше не считаются уходом: если человек открыл игру, значит она его зацепила.
Плеер (сайт и приложение): лента сообщает, как ушли с карточки. В приложении — с новой версии, старые версии считаются как раньше.
статистика игры теперь в кабинете авторов
Кабинет авторов (studio.upbilim.com/console → игра → «Статистика»): здесь вся статистика, что была в Студии. Это срок (7, 30 или 90 дней), путь игрока, возвраты, лента, «Сколько продолжают играть», «Где играют», «Где бросают», данные по версиям и ошибки у игроков. Есть и сравнение версий A/B с кнопками «Оставить новую» и «Вернуть старую» — их видят те, у кого есть право выпуска.
Студиякнопка «Статистика» открывает эту страницу в браузере, отдельного окна больше нет. Карта игроков остаётся в Студии, её рисуют прямо в мире игры.
на какой секунде пролистывают твою игру в ленте
Кабинет авторов (studio.upbilim.com/console → игра → «Статистика»): новый блок «Лента». В нём: сколько раз игру показали в ленте Плеера, сколько её смотрят в среднем, сколько пролистнули за 3 с и график «На какой секунде листают дальше» (до 1 с, 1–2 с … минута и дольше). Если уходят в первые секунды, начни игру сразу с действия. Секунды считаются с 2 ноября 2026.
в приложении Плеера игра тоже не ждёт музыку
Плеер (приложение): при первом запуске игры скачиваются только модели и короткие звуки, музыка и длинные записи (больше 300 КБ) — следом, пока ты уже играешь. Пример: игра с 5,7 МБ музыки ждёт перед стартом 0,8 МБ вместо 6,2 МБ. Нет интернета посреди загрузки — игра идёт без музыки, а не стоит.
ремикс можно отключить
Студияв «Выпустить» — «Ремикс: Разрешён / Отключён». Отключён — другие не могут сделать копию твоей игры, на её странице написано «Ремикс отключён». По умолчанию — разрешён.
Плеер и сайт: на странице игры с отключённым ремиксом — отметка «Ремикс отключён» вместо кнопки. Игры детской Студии — ремикс всегда разрешён; у игр UpBilim — отключён.
игра стартует, не дожидаясь музыки
Плеер (сайт): игра запускается, как только скачаны модели и короткие звуки; музыка и длинные записи докачиваются следом и начинают играть, когда пришли. Пример: игра с 5,7 МБ музыки — старт за 3 с вместо 5 с (на медленном интернете разница больше).
Движоккороткий звук, который пришёл позже, чем на 1,5 с после вызова, не играет (чтобы не прозвучал невпопад); музыка и реплики героев — играют, когда пришли.
тяжёлые игры стартуют быстрее
Плеер (сайт): модели и звуки игры передаются в игру как есть, а не текстом base64 — телефону не надо перекодировать мегабайты. Пример: игра с 6 МБ моделей из кэша стартует за 0,4 с вместо 2,9 с. Авторам ничего менять не надо.
Движокфайлы игры могут прийти сразу после загрузки страницы — модели ждут, как обычно при разборе, UB.hasSound видит звук сразу, а UB.sound играет, когда он пришёл.
Студияпри выпуске — замечание, если игра тяжелее 3 МБ: в ленте Плеера первой карточкой идёт игра легче.
лента учится и открывает приложение на телефоне
Плеер (телефон): приложение открывается лентой — первая вкладка «Лента», свайп по полосе справа — следующая игра. «Назад» на Android возвращает в ленту.
статистика игры: путь игрока и возвраты
Студияв «Статистике» игры — путь игрока (сколько раз игру показали в Плеере, открыли, играли, больше минуты, доиграли) и возвраты: сколько игроков вернулись на следующий день и через неделю. Видно, где игра теряет людей.
лента игр: сразу в игру
Движокрежим ленты Плеера — игра открывается сразу в действии: первый экран (Илби и «Играть», меню UB.menu) сам нажимает главную кнопку, один раз. После игры меню — как обычно. Авторам ничего менять не надо.
Плеер (проба): лента игр /feed — игра на весь экран, свайп по полосе справа — следующая; следующая готовится заранее и стартует за долю секунды.
ролик из повтора на медленном компьютере
Студиямонтаж ролика из повтора больше не портит конец ролика на медленном компьютере: раньше посреди монтажа движок сам снижал качество (без теней, мельче), и последние кадры выходили другого размера.
двигающиеся предметы рисуются быстрее
Движокодинаковые предметы (кубики, шары, цилиндры, заготовки), которые двигаются, теперь рисуются пачкой сами — как неподвижные и юниты стратегий (e.crowd). 400 двигающихся предметов — 12 отрисовок вместо 786, кадров вдвое больше. Игре ничего менять не надо; картинка та же.
физика: герой снова ходит
Движокв играх с физикой (UB.physics()) герой UB.player3d почти не ходил — стоял на месте. Починено: земля и твёрдые предметы — неподвижные тела; то, что игра двигает (платформа), едет и везёт предметы.
готовые фразы в 2D, страница игрока на телефоне
ДвижокUB.phrases([...]) работает и в 2D: Y и 1–8 (или тап) — облачко над своим героем общего мира UB.world2d (с камерой UB.camera2d), друзья видят его над тобой; без общего мира — внизу посередине. Рисует движок.
Движокпортрет персонажа (UB.portrait, голова) — в одном масштабе у всех: кадр по кубику головы, причёска и шапка его не меняют.
клановые рекорды и турнир кланов
ДвижокUB.leaders — ещё и клановые рекорды (clans, mineClan): у клана — сумма лучших результатов пяти его игроков. UB.leaderboard(g, x, y, { by: 'clan' }) — готовая таблица «Лучшие кланы».
аватарка: персонаж, голова целиком
ДвижокUB.portrait(…, { head: true }) — кадр по самой голове (с причёской и шапкой) и чуть плеч; раньше считался по ширине всей фигуры, и с юбкой, плащом или крыльями голова обрезалась.
кланы в Плеере
Движокнад другом в комнате — «[ТЕГ] Имя», если он в клане.
Исправлено: игроки комнаты видели ведущего обычным человечком, а не его «Моим персонажем» — Плеер не передавал игре облик ведущего.
рагдолл
Движок (3D):UB.ragdoll(человечек, { dir, force, up, time }) — падение «тряпичной куклой»: опрокидывается по направлению удара, может подлететь и проскользить, руки-ноги-голова болтаются и ложатся на землю; через time с встаёт там, где лежал (time: 0 — лежит, пока не UB.ragdoll(e, false)). Свой герой — друзья видят то же падение. Без физической библиотеки: работает и в Плеере, и на телефоне.
ДвижокUB.melee({ ragdoll: true }) — третий удар серии сбивает с ног; w.health({ ragdoll: true }) — выбывшие падают куклой.
Исправлено: первая готовая фраза друга в комнате не показывалась.
игра без сети: прогресс не теряется
Движокбез сети таблица лидеров пишет «Нет связи — рекорды потом»; UB.leaders.state() — 'ok', 'asking', 'offline' или 'none'.
ходы по очереди, рыбалка и эмоции для ИИ
Движокw.turns({ time, onMove, bot, onTurn }) — ходы по очереди в общем мире, 3D (UB.world) и 2D (UB.world2d): настольные, карты, шашки, викторины. Чей ход и время решает ведущий; T.move({ … }) — мой ход (только в мою очередь), ведущий проверяет его в onMove (false — не принят, 'again' — ещё ход). Время вышло — ход следующему; ушедший пропускается, новый — в конец очереди; боты ходят через bot(). Сверху — «Твой ход · 25» / «Ходит Аня · 12».
Движок (2D): в UB.world2d — общие значения w.set / w.get (поле, карты на столе) и общие часы w.time().
ИИ: в подсказке — рыбалка (UB.fishing), эмоции (UB.emotes), достижения (UB.achieve), вода, в которой плавают (UB.water3d({ swim: true })), и ходы по очереди.
лидеры, награда дня, готовые фразы
ДвижокUB.leaders(fn) — рекорды игры: лучшие 10, мой рекорд и моё место после UB.finish; UB.leaderboard(g, x, y, { rows }) — готовая таблица «Лучшие игроки» для меню, итогов, лобби. Рекорды присылает Плеер; в Студии и без Плеера таблица скажет «Рекорды — в Плеере UpBilim».
ДвижокUB.daily({ rewards: [10, 20, …] }) — награда дня: новый день — окно с днями подряд (пропустил день — снова с первого), «Забрать» (Enter / тап), пока окно открыто — игра стоит. С UB.economy монеты кладутся сами, иначе — onClaim. Ответ — { day, streak, ready, away } (away — секунд с прошлого захода).
Движок (3D):UB.phrases(['Привет!', 'Помоги!', …]) — готовые фразы: Y и 1–8 (или тап) — облачко над героем; в общем мире его видят друзья. По сети ходит только номер фразы из списка игры, свободного текста нет.
Движокслужебные поля сохранения (__econ, __daily, __ach) больше не теряются, если игра сохраняет свой объект, взятый до них: раньше достижения и серия дней могли пропасть.
Shorts без сплющенных кадров
Студия, движок: ролик 9:16 («Смонтировать ролик», «Снять серию») больше не сплющивается: если во время монтажа менялся размер окна Студии, движок возвращал камере пропорцию окна (16:9), и часть кадров выходила как обычное видео, сжатое под Shorts. Теперь пока идёт монтаж, кадр держит свою пропорцию; а если кадр всё же пришёл другой пропорции — Студия кладёт его по центру с обрезкой, а не растягивает.
рисованный вид для мультиков
ДвижокUB.drawn3d('ink') — рисованный вид: мир остаётся 3D, а кадр выглядит как нарисованный от руки. Контур вокруг предметов и героев (силуэты, рёбра, черты лица) живой линией — она чуть дрожит, как в рисованном мультфильме; тени — плоскими ступенями; бумага. Стили: 'ink' — тушь, 'pencil' — карандаш (штриховка в тенях), 'paper' — аппликация (крупные плоские цвета, 12 кадров в секунду), 'comic' — комикс (точки в тенях); false — обычный 3D. Свой: UB.drawn3d({ style: 'ink', line: 2.5, color: '#3b2a1a', wobble: 1.2, twos: true }) или сразу UB.create3d({ …, drawn: 'pencil' }). Одинаково в браузере, в режиме «Видеокарта» и в смонтированном ролике.
Шаблон «Обучающий мультик»: по умолчанию — тушь (LOOK в stage.ts); перед мотором клавиша V меняет вид по кругу: тушь, карандаш, аппликация, комикс, обычный 3D.
окно Студии: пустое после закрытия проекта, не разворачивалось после нового
Студиянажали логотип (закрыть проект), когда нижняя панель была развёрнута, — окно оставалось пустым. Теперь виден экран с проектами; раскладка проекта (развёрнутая панель) вернётся, когда его откроют.
Студияпосле «Новый проект» окно иногда нельзя было развернуть на весь экран и потянуть за край — зелёная кнопка была серой, помогал только перезапуск. Теперь окно проекта всегда разворачивается.
мультик: рот под голос и три языка
ДвижокUB.sound('assets/voice/hi.mp3', { voice: герой }) — голос героя: рот шевелится под громкость звука — у человечков движка нарисованный рот «а» / «о» / закрыт, у модели со скелетом — челюсть или форма «рот открыт», без рта — кивает. Новая реплика того же героя обрывает прошлую. Рот пишется в повтор — в смонтированном ролике он тоже говорит. Шаг сценария { who, say, voice: 'assets/voice/hi.mp3' } ждёт, пока звучит голос.
Студиясерия мультика — сразу на трёх языках. «Голоса» → «Перевести реплики»: реплики, знаки и названия серий переводятся на английский и узбекский (сервер UpBilim) в таблицу «Перевод». «Озвучить новые» озвучивает каждый язык тем же голосом героя, узбекский — моделью ElevenLabs v3. «Смонтировать ролик» → языки EN · RU · UZ → «Снять серию»: по ролику на каждый язык, у каждого — своё название и концовка на этом языке, рядом — субтитры .srt для YouTube. Агенту: node .upbilim/game.mjs shoot 1 uz, gen.mjs speech … --lang uz.
Шаблон «Обучающий мультик»: реплики говорят голосом с ртом, языки и субтитры — в director.ts (BASE, tr), раздел «Три языка» в СЕРИИ.md.
«Снять серию»
Студияв «Смонтировать ролик» у мультика (шаблон «Обучающий мультик») — выбор серии и кнопка «Снять серию»: Студия сама играет серию с начала до конца и монтирует mp4 — кадр серии (9:16 или 16:9), её название титром, голоса и звуки. Раньше ролик брался из повтора и обрывался, если окно Студии сворачивали во время серии. Игра сообщает серии сама: UB.store.episodes, UB.store.shoot(i), UB.store.shootState(). Агенту: node .upbilim/game.mjs shoot 1.
панель «Голоса»
Студияпанель «Голоса» (значок микрофона над игрой) — озвучка мультиков мышкой, ключом ElevenLabs автора: новый голос по описанию — три пробы, послушать, «Выбрать»; реплики — из идущей игры («Найти в игре»), «Озвучить новые», переозвучить одну, ✎ — как произносить (ударение), сразу переозвучивает. Файлы — assets/voice/, длины — assets/voice/lines.json, произношение — sources/gen/voices/speak.json. Работает с шаблоном «Обучающий мультик» и любой игрой, которая сообщает реплики (UB.store.voiceLines).
шаблон «Обучающий мультик»
Студияновый шаблон проекта «Обучающий мультик» — серии по минуте для детей 3–6 лет, кадр 9:16 для Shorts / Reels / TikTok. В проекте: режиссёр (director.ts: сценарий шагами, реплики с голосом, камера сама берёт героев в кадр 9:16 и медленно наезжает, знаки в кадре — цифры, буквы, цвета, вопрос зрителю с паузой «тик-так»), детская комната (stage.ts), пример серии «Три яблока» с героями движка (девочка и котёнок), озвучка всех реплик одной командой (node tools/voice.mjs) и СЕРИИ.md — формула серии и правила для малышей. Герои — свои: человечки и звери движка или своя модель со скелетом.
голос персонажа и озвучка реплик
Студияагенту — голос и озвучка ключом ElevenLabs автора: node .upbilim/gen.mjs voice "<какой голос, по-английски>" --name hero — три пробы голоса (sources/gen/voices/hero-1…3.mp3), voice --name hero --pick 2 — выбранная проба в голоса аккаунта; speech "Привет! Я Илби!" --voice hero --name l01 — реплика этим голосом → assets/voice/l01.mp3 (русский, кыргызский, узбекский и другие языки; то же имя — переозвучить). В игре: UB.sound('assets/voice/l01.mp3').
свои движения для любого человека
ДвижокUB.model3d('assets/gen/knight.glb', { moves: 'human' }) — бесплатные движения для любой модели-человека со скелетом (Tripo, Mixamo, Blender…): библиотека Universal Animation Library (Quaternius, CC0) переносится на её кости сама. 37 движений: idle, walk, run, sprint, jump, dance, talk, sit, sittalk, sitdown, standup, punch, hit, fall, pickup, interact, cast, sword, shoot, aim, crouch, roll, push, swim, drive… — e.play('dance') или шаг сценария { do: 'dance' }; ходьба и бег — сами, пока говорит и стоит — «talk» сам. Свои клипы модели с тем же именем важнее.
Студия«Со скелетом и движениями» для человека теперь заказывает у Tripo только скелет — движения свои и бесплатные; движения Tripo — галочкой (по 10 кредитов). Агенту: gen-model … --rig (человек — сразу с moves: 'human' в коде), --tripo-moves — ещё 5 движений Tripo.
ролик в режиме «Видеокарта»
Студия«Смонтировать ролик» работает и когда игра идёт через видеокарту (ubrt): кадры рисуются в качестве Плеера — с тенями, свечением и затенением, ровно в размер ролика (не зависит от размера окна), со звуком игры. «Записать видео» в этом режиме подсказывает снимать через «Повтор» → «Смонтировать ролик».
Движок «Видеокарта» (ubrt): кадр без окна нужного размера в JPEG и запись звука для ролика — только в папку Студии во временной папке системы.
актёр — любая модель со скелетом
Студия«Создать по описанию» → модель → «Со скелетом и движениями»: Tripo ставит скелет и готовые движения. Человек — idle, walk, run, wave, cheer (и ещё 5 для фильмов: dance, clap, sit, laugh, bow), зверь — своя ходьба, остальные — только скелет. Модель сразу ходит в игре и играет в сценах. Tripo спишет кредиты за скелет и по 10 за движение. Агенту: node .upbilim/gen.mjs model "…" --rig [biped|quadruped|…] [--more].
Движокмодель со скелетом (UB.model3d) — полноценный актёр сцены: ходит своим клипом и не «уезжает» вперёд (увод корня у клипов движок убирает; rootMotion: true — как в файле), do — любой клип модели, mood — формы лица модели (Surprised, Smile, Angry…), пока над ней реплика — двигает ртом (кость челюсти или форма «рот открыт») или кивает. Наши кубические персонажи тоже кивают, когда говорят.
звуки игры в ролике
Студияв «Смонтировать ролик» — галочка «Звуки игры»: в ролик попадает всё, что звучало в игре, — эффекты, музыка, фон, звуки из файлов, звук в мире; в слоумо звук растягивается вместе с картинкой. Громкость — как принято на YouTube (около −16 LUFS, без хрипа); музыка из проекта рядом со звуком игры звучит тише. Агенту — film … nosound, чтобы без звука игры.
Шаблон «Мини-фильм»: заставка «Enter — мотор!» (с нажатием браузер включает звук), музыка и звуки на шагах сценария (sfx).
Движокповтор пишет и звук игры (UB.replay.start({ audio: true }); в Студии — всегда): последние минуты звука вместе с картинкой.
ИИ-агент монтирует ролик
Студияу агента (Claude Code и другие) новые команды моста: node .upbilim/game.mjs replay [game|free|orbit|shots|exit] — открыть повтор и выбрать камеру, node .upbilim/game.mjs film [wide|tall] [1080/60|1080/30|720/30] [music=<звук>] [заголовок] — смонтировать ролик из повтора (как кнопка «Смонтировать ролик»); ответ — путь к файлу. Попросите агента: «сыграй сцену и сделай Shorts с музыкой».
ДвижокUB.replay.camera() без названия только сообщает камеру повтора (раньше переключала на следующую).
сцена по сценарию и «Мини-фильм»
Студияновый шаблон проекта «Мини-фильм»: двое актёров, декорации и сценарий из 10 шагов в начале кода (SCRIPT). Сыграйте сцену → «Повтор» → «Смонтировать ролик» — получится мини-фильм для YouTube. Меняйте реплики сами или попросите ИИ: «напиши сцену, где Ильби находит в лесу дракона». В смонтированном ролике видны реплики-облачка.
ДвижокUB.cutscene([шаги], { actors, onEnd }) — сцена по сценарию: { who, to, run, say, mood, do, look, sound, cam, wait, with }; актёры идут, говорят облачками, меняют лицо и жесты, камера сама ставит планы (wide, close, two, over, follow, top). UB.say3d(e, 'текст') — облачко над любым персонажем в любой игре. Реплики и лица записываются в повтор. Ролики по ключам (UB.cutscene('intro')) — как были.
«Смонтировать ролик» из повтора
Студиякнопка «Смонтировать ролик» у игры (значок киноленты): ролик из повтора — mp4 для YouTube (16:9) или Shorts (9:16), 1080p 60 / 1080p 30 / 720p 30. Кадры рисуются по одному — ролик всегда плавный, даже если игра на компьютере подтормаживает. Камера — как выбрана в повторе; камера «точки» — от первой точки съёмки до последней, со слоумо. Титр в начале (можно пусто), музыка — любой звук из проекта (по кругу под длину ролика, плавно в начале и в конце), в углу знак «UpBilim Studio · studio.upbilim.com», в конце 2,5 секунды «Сделано в UpBilim Studio». Ролик — в «Фильмы / UpBilim Studio».
Движокэкспорт кадров повтора для Студии ({ ub: 2, type: 'rpx', op: 'begin' | 'frame' | 'end' }): мир рисуется ровно в размер ролика, потом экран как был.
режиссёрская камера в повторе
Студияв повторе — кнопка «Камера» (или C): «игра» — как было, «свободная» — лети сам (WASD, E/Q — вверх и вниз, Shift — быстрее, мышь с зажатой кнопкой — смотреть, колесо — зум), «облёт» — камера кружит вокруг героя (мышь — повернуть, колесо — ближе и дальше). K — точка съёмки: поза камеры, момент и скорость повтора; камера «точки» плавно пролетает через все точки, и скорость берётся у точки — поставь 0.25× у прыжка, и до следующей точки будет слоумо. X — убрать точку. P — фото без кнопок в «Изображения / UpBilim Studio».
ДвижокUB.camera3d({ mode: 'free' }) — свободный полёт для игр (зритель, дрон, режим фото). У повтора — UB.replay.camera('game' | 'free' | 'orbit' | 'shots'), UB.replay.shot(), UB.replay.photo() (кадр приходит сообщением ub:photo).
повтор игры
Студиякнопка «Повтор» у игры (значок часов рядом с записью видео) — последние 2 минуты 3D-игры: игра встаёт, мир и камера идут по записи. Пробел — пауза, ← → — 5 секунд, 0.25×–2× — скорость, H — спрятать кнопки, Esc или «Повтор» ещё раз — назад в игру, всё как было. Видео можно снимать прямо в повторе: «Записать видео» без интерфейса игры — без кнопок повтора.
ДвижокUB.replay — повтор для любых 3D-игр: UB.replay.start({ secs: 30 }) (держать последние 30 секунд), UB.replay.play({ back: 8, speed: 0.5, onEnd }) — гол, нокаут, рекорд ещё раз; exit(), pause(), speed(k), seek(s), playing(), length(). В повтор попадают место, поворот и видимость объектов, жесты (e.play) и камера; удалённые объекты видны до момента удаления. Пока не попадают частицы, вспышки и звуки. В комнате (UB.world) повтор не включается.
видео игры для YouTube и Shorts
Студиякнопка «Записать видео игры» спрашивает кадр: 16:9 для YouTube или 9:16 для Shorts (вырез по середине кадра). В 3D-игре можно убрать интерфейс игры и записать только мир (пункт «С интерфейсом игры» в том же меню). Качество — до 1080p, в углу знак «UpBilim Studio · studio.upbilim.com». Видео, как и раньше, в «Фильмы / UpBilim Studio».
Движокзапись ({ ub: 2, type: 'rec', on: true }) понимает frame: 'wide' | 'tall', hud: false (только 3D) и mark — ссылку для знака; без mark знака нет.
UpBilim Studio 0.2.2
Студиявыпуск 0.2.2 для Mac, Windows и Linux — всё, что появилось после 0.2.1 (записи ниже, с 24 октября): несколько окон и несколько проектов в окне вкладками, как в Chrome, сессия окон, автосохранение, команда studio, мини-карта, заготовки кода и задачи как в VS Code; картинки в «Создать по описанию», обложка от Bilimai в «Выпустить», матовый мир, комната со своими персонажами и другое. Установленные Студии обновятся сами.
кабинет авторов на сайте
Сайт Студии: studio.upbilim.com/console — кабинет авторов, как App Store Connect: все твои игры и игры, где ты в команде; страница игры на трёх языках (название, о чём игра, цель, управление, возраст) и скриншоты; выпуски — какая версия в Плеере, выпустить другую или снять с витрины; статистика за 30 дней; команда игры по почте с ролями — админ (всё, кроме передачи и удаления), менеджер (страница, статистика, выпуск — без кода), разработчик (код, без выпуска). Владелец может передать игру другому автору: тот принимает в своём кабинете, прежний владелец остаётся админом.
картинки качественнее по выбору
Студия«Картинка» → «Качественнее (FLUX dev)»: точнее слушается описания (≈ $0,025 вместо $0,005 у fal.ai). ИИ-агенту — gen.mjs image "…" --best. В описании картинки (sources/gen/<имя>.image.json) вид картинки — поле look.
картинки в «Создать по описанию»
Студиявкладка «Картинка» рядом с моделью, звуком и музыкой — своим ключом fal.ai (Связка ключей, как Tripo и ElevenLabs): FLUX рисует по описанию; «Предмет без фона» и «Иконка» — фон убирается (BiRefNet), пустые края обрезаются (512 / 256 px PNG), «Фон сцены» — 1280 px JPEG. «Взять» — в assets/images/. ИИ-агенту: node .upbilim/gen.mjs image "…" --kind sprite|icon|scene.
UB.models3d после смены сцены
ДвижокUB.clear3d отменяет и ещё не загруженные наборы UB.models3d. Раньше модель, догрузившаяся после смены сцены (меню → игра), появлялась в новой сцене «сиротой», которую не убрать remove(): например, облака над закрытой частью острова оставались после её открытия (особенно в веб-Плеере, где модели грузятся дольше).
проверка «Выпустить» знает ходьбу касанием
Студияпроверка на телефоне больше не останавливает выпуск игр, где ходят касанием (UB.player3d(hero, { stick: false }), как Family Island): раньше она требовала пульт или джойстик, раз игра читает стрелки. Движок: такой герой отмечает window.__UB_TAP3D — Тестер считает это управлением на телефоне.
обложка от Bilimai в «Выпустить»
Студияв окне «Выпустить», в разделе картинок — «Нарисовать обложку»: Bilimai рисует обложку по описанию игры, как в веб-Студии (тот же запрос сайта, 10 ответов Bilimai). В поле — сюжет обложки от сайта; поправь — нарисует по-твоему. Новая обложка сразу становится «Обложкой сейчас»; не хватает ответов или обложка не прошла проверку — сказано в окне.
матовый мир
ДвижокUB.create3d({ matte: true }) — всё матовое: детали движка (UB.prefab, UB.models3d('bush') …), коробки (UB.spawn, UB.boxes3d) и GLB-модели без бликов солнца и с ослабленным отражением неба; у машин лак остаётся. Мультяшный вид одинаков в браузере и в Плеере (через видеокарту), где раньше блестели заборы.
ключи сервисов после обновления Студии
Студияключ Tripo / ElevenLabs снова сохраняется после переустановки Студии. Раньше новая сборка не могла ни прочесть, ни перезаписать запись прежней сборки в Связке ключей («The specified item already exists in the keychain»), и ключ «не принимался». Теперь «Сохранить» удаляет старую запись и пишет ключ заново (macOS может спросить разрешение).
ДвижокUB.create3d({ starsAround: true }) — ночью звёзды и ниже горизонта (мир висит в небе, камера смотрит вниз); clouds: false — без плывущих облаков неба (высокая камера сверху пролетала сквозь них).
«Создать по описанию» для ИИ-агента
ДвижокUB.player3d(hero, { stick: false }) — без джойстика и кнопки прыжка на телефоне: игра, где герой ходит туда, куда коснулись (как Family Island): UB.groundAt3d(UB.pointer.x, UB.pointer.y) — точка, UB.pick3d — что коснулись, UB.goTo3d по путям UB.nav3d.
СтудияИИ-агент (Claude Code, Codex…) сам делает модели, звуки и музыку ключами автора: node .upbilim/gen.mjs model "wooden crate, low poly" --name crate, sound "…", music "…", keys. Идёт через мост Студии (команды gen-model, gen-sound, gen-music, gen-keys): ключи остаются в Связке ключей, агенту не видны. Модель (Tripo): исходник — в sources/gen/<имя>.glb с описанием, задачей и кредитами (<имя>.json), для игры — копия в assets/gen/<имя>.glb: сжата, упрощена до ~50 000 треугольников (--keep — не упрощать), стоит на земле по центру (--h 2 — высота 2 м); --image pic.png — по картинке. Звук — assets/sounds/, музыка — assets/music/ (без слов, --vocals — со словами), описание — в sources/gen/. Ответ — пути и строка кода.
Студияпапка sources/ проекта (исходники) не упаковывается в игру при запуске в Студии — раньше большие исходники моделей упирались в лимит 150 МБ, и игра не собиралась. В выпуск и так идёт только assets/.
Студиямодель для игры от gen.mjs model — матовая (металличность 0, без текстуры ORM): Tripo помечает все модели металлом, и движок Плеера (через видеокарту) рисовал их чёрными. --metal — оставить как есть.
Комната: один аккаунт — одно место
Сервер и Плеер: тот же аккаунт вошёл в комнату с другого устройства — место у нового, на старом «Ты зашёл в эту комнату с другого устройства», и он не переподключается (раньше два устройства выбивали друг друга по кругу).
Комната: друзья своими персонажами, пассажир без ошибки
Сервер: вошёл или вышел игрок — список игроков (имена, облики) рассылается всем, а не только ведущему: кто пришёл раньше, видит новеньких своими персонажами и с именами (раньше — «…» и стандартный облик).
Движокоблик друга пришёл позже, чем появилась его фигурка, или он его сменил — фигурка переодевается; пассажир — без ошибки «reading 'car'» (спидометр — только водителю).
Кататься вместе: пассажиры
Движокобщий мир — у машины, за рулём которой друг (машина города или его своя из гаража), «E — Сесть пассажиром»: сидишь на своём месте и едешь, куда он рулит; E — выйти рядом. Места по модели: карт и болид — одноместные, мото и спорткары — 1 пассажир, грузовики — 2, легковые — 3, автобус — 7; мест нет — «Мест нет». UB.passenger().
Движокдрузья больше не видят водителя и пассажиров стоящими посреди машины (метка «за рулём» в снимке героя).
Комната: мир города на сервере снова работает
Сервер / движок: город по плану в общем мире ведёт сервер (все экраны — игроки); сервер без экрана больше не строит дома районов — большой город падал «too many 3D objects», и игроки в комнате не видели друг друга.
Комната: свой персонаж и «С друзьями»
Движокв комнате свой герой — «Мой персонаж»: облик берётся из списка игроков комнаты (Плеер его не передаёт), уже стоящий герой переодевается.
Сайт: игра из UpBilim Studio с общим миром (UB.world) или своей связью (UB.net) — режим «один игрок», а «С друзьями» — комната (раньше становилась «командной»: общий экран + телефоны, и кнопки «С друзьями» не было); старые такие игры поправляются при следующей отправке версии.
Выпуск: проверка сайта больше не падает на городе
Движокбез света (проверка игры на сервере сайта) направление солнца — обычное дневное, а запекание теней района с неверным размером сетки пропускается, а не падает (RangeError: Array length… при «Выпустить»).
UpBilim Studio 0.2.1
Студиявыпуск 0.2.1 для Mac, Windows и Linux — всё, что появилось в движке и Студии после 0.2.0 (записи ниже, с 21 октября): города и острова с мостами, свои машины и гараж, «Мой персонаж», чит-коды для проверки игры, запекание района и другое. Установленные Студии обновятся сами.
Чит-коды только в Студии
ДвижокUB.cheats работает только в UpBilim Studio (автор проверяет игру): в выпущенной игре — на сайте, в Плеере — ~ ничего не открывает, чит-монет и открытых мостов нет.
Обход города: надписи, табличка дома, луч маяка
Движоквсплывающие надписи (UB.toast) — ниже строк HUD слева; надпись над табличкой дома выше подсказки «E — …»; изнутри своего дома табличка не висит перед камерой; луч маяка толще и ярче.
«Звёздный город» 2.0: баннер начала игры ниже, не наезжает на строки слева.
Мелкие недочёты
ДвижокUB.hud.banner и всплывающие надписи (UB.toast) — плашка по ширине текста посередине, а не полоса во весь экран (не закрывает HUD по краям); full: true — как раньше.
Движокбольшая карта — одинаковая подпись рядом (два «Мой гараж») рисуется один раз; озеро — тёмное дно под водой (не серое); сарай виноградника — маленький, в углу.
«Звёздный город» 2.0: подсказка «Свой дом — от 350 · карта M» короче и ярче; баннер начала игры не наезжает на строки слева.
Дым от машины — сзади и снизу
ДвижокUB.effect3d(…, { follow: e, local: { x, y, z } }) — эффект в точке на самом объекте, поворачивается вместе с ним.
Движокдым при заносе (UB.car3d) идёт сзади и низко — от задних колёс и выхлопа, а не с середины крыши; точка — по размеру этой машины (у автобуса дальше, у карта ближе).
Северный пригород: домов больше, чем игроков
«Звёздный город» 2.0: на севере Делового острова (Озёрная и Лесная) — 18 американских домов по 500–750 монет; всего домов 43 (в комнате до 30 игроков). Подсказка «Свой дом» ведёт на карту.
Свой характер у каждого острова
Движокновые места для UB.cityPlan3d: vineyard (ряды лоз с гроздьями, сарайчик), forest (густой лес, брёвна, грибы, тропинка), lake (озеро с песчаным берегом, камышом и мостками; в воду не зайти), lighthouse (полосатый маяк с фонарём; ночью луч светит и крутится).
«Звёздный город» 2.0: на Восточных холмах — 10 виноградников, на Лесном — лес и Лесное озеро, на Маячном — маяк на мысу.
Въезды на мосты и живые берега
Движокмост дугой (UB.cityPlan3d) — въезды как у настоящего моста: каменная опора под краем настила, перила продолжаются на сушу и кончаются столбом с фонарём (ночью светится); столбы твёрдые.
«Звёздный город» 2.0: берега островов извилистые (точка каждые ~8 м, мягкие волны), а не прямые отрезки; суша только расширилась — дома и улицы на своих местах.
«Моя машина» приезжает сама
Движокcity.callNear / «Моя машина» (B) — машина не появляется рядом, а приезжает по своей полосе ближайшей улицы (издалека, до 45 м): разгон, торможение, встаёт у тебя; сел раньше — дальше едешь сам.
Первый дом рядом и задание «Свой дом»
ДвижокUB.missions3d — шаг { when: (M) => bool, at, text }: засчитывается сам, когда условие сбылось (купил, набрал…); в плане города — { home: 'buy', go: 'lotId', text }: «купи свой дом», луч над домом.
«Звёздный город» 2.0: американский дом на Яблоневой в Садах — рядом с началом игры, 350 монет (всего домов 25); задание мэра «Свой дом» после «Звезды города» (купи дом — 50 монет) и задание соседки Норы на Холмах «Урожай с холмов» (отвези овощи повару Тимуру).
Где купить дом: метки на карте
Движокcity.forSale() — дома, которые можно купить сейчас (не заняты в комнате и ещё не твои): для карты и радара.
«Звёздный город» 2.0: дома «Продаётся · цена» — на большой карте (M) и зелёными точками на радаре; пока нет своего дома — подсказка под звёздами, где его купить.
Американские дома: купить навсегда, двор, огород, стоянка на 3 машины
ДвижокUB.cityPlan3d — участок дома со style: 'american': большой двор (лужайка, белый штакетник с боков и сзади, дорожка к двери, подъезд со стоянкой на 1–3 машины — parking, почтовый ящик, огород с грядками за домом, деревья) и дом в глубине с комнатами.
Движокдом с ценой (price, монеты города) покупается навсегда, как в GTA Online: E у таблички «Продаётся», список — на аккаунте (city.homes()). Купил — заселяешься сам в каждой игре; в комнате твой дом уже занят другим хозяином — тебе ближайший свободный, и он такой же твой: цвета, мебель и машины на стоянке хранятся у хозяина. E у своей таблички — окно «Мой дом»: запереть, какие машины гаража стоят на стоянке, мои дома (какой главный). city.buyHome, city.homeWindow; own: false — дом занять нельзя.
«Звёздный город» 2.0: пригород из 24 американских домов на Восточных холмах (12), Лесном (10) и Маячном (2, дорогие у маяка) островах, цены 400–1500 монет; мосты на Холмы и Лесной открыты сразу; остальные дома города занять нельзя.
Свои машины: у дома, по кнопке, и гараж в Студии
Студияигра в Студии теперь говорит с «Моим гаражом» на сервере, как Плеер и сайт: выбрать машину в окне гаража, купить, прокачать, монеты за игру, вещь персонажа. Раньше выбор не доходил до сервера — «Поехать» всегда давал первую машину. Гараж перечитывается раз в минуту (купил на сайте — видно в игре).
Движоквыбрал машину в гараже — она едет сразу, не дожидаясь сервера.
ДвижокUB.cityPlan3d — свои машины как в GTA Online: занял дом — у бордюра перед ним стоят твои машины из гаража (выбранная первой, сколько поместится перед участком, до двух — yardCars); B или city.carButton(g, x, y) — окно «Моя машина»: любая машина из гаража подъезжает к ближайшей улице (на улице одна твоя: новая заменяет старую). city.callNear, city.callMenu, city.yardCars.
ДвижокUB.modal3d() — какое окно открыто поверх игры.
«Звёздный город» 2.0: кнопка «Моя машина» под монетами, свои машины на радаре — белые.
Одни монеты на машины и на персонажа
Аккаунт: монеты «Моего гаража» теперь — монеты аккаунта: ими покупают и машины, и вещи «Моего персонажа». Вещь, закрытая по опыту, покупается за столько монет, сколько нужно опыта (корона — 1000); купленное открыто навсегда. На сайте в «Моём персонаже» — монеты и «Купить за N» у надетой закрытой вещи; в Плеере купленные вещи открыты.
ДвижокUB.garageDo('earn') можно звать сколько угодно часто: монеты копятся и уходят пачкой раз в 16 с (сервер берёт не чаще раза в 15 с и не больше 40 за раз) — раньше частые монеты (работа в городе) терялись.
Монеты города и «Мой гараж»
ДвижокUB.cityPlan3d платит в «Мой гараж» (общий кошелёк аккаунта для всех игр): 5 монет за оплаченный заказ на работе, 10 — за задание сюжета, 20 — за каждые 10 звёзд; над игроком — «+5 в гараж». garageCoins: { job, mission, stars } — свои суммы, false — не платить. Монеты города остаются в городе (одежда, дом, мебель), сервер ограничивает гаражные монеты за раз и за день.
Движокпосле любого чит-кода (UB.cheats.used) UB.garageDo('earn') ничего не начисляет — читами гараж не накрутить.
«Звёздный город» 2.0: работа, задания и звёзды теперь помогают прокачать свою машину в гараже.
Чит-коды и телепорт
ДвижокUB.cheats({ код: { text, run } }) — чит-коды для любой игры: ~ открывает консоль (напиши код и Enter или нажми на код в списке), ответ всплывает надписью; UB.cheats.used — были ли читы; UB.cheats.open() — открыть своей кнопкой (на телефоне нет ~).
ДвижокUB.teleport(x, z, y?) — перенести героя (или машину, в которой он едет) сразу, на пол; камера прыгает следом.
Движокcity.cheats() в UB.cityPlan3d — готовые коды города: stars (все звёзды — золотыми лучами), star (к ближайшей ненайденной), money (+1000 монет), open (все мосты открыты), day, night.
«Звёздный город» 2.0: чит-коды включены; после stars ненайденные звёзды видны и на мини-карте.
Мосты дугой и город из островов
ДвижокUB.cityPlan3d — прямая улица, которая пересекает воду между островами, становится мостом сама: дугой над проливом (у берегов ровно, посередине выше — до 10 м), с настилом, перилами, опорами в воду и красными башнями на длинном; по мосту ходят вверх и вниз, едут свои машины, машины-боты и прохожие. На воде улица не рисуется — только мост. arch: false — плоский мост.
ДвижокUB.ribbon3d — высота у точек пути ({ x, z, y }), бортики у полос: rise (перила вверх), drop (толщина вниз). UB.car3d едет по высоте рельефа (UB.__terrainH: мост дугой, горки).
«Звёздный город» 2.0: город — архипелаг из пяти островов, как в больших играх: Звёздный остров (центр, Набережная, Сады) посередине, Деловой остров на западе (стадион, больница, ТЦ, кинотеатр, библиотека, порт, Северная набережная), Восточные холмы (мост откроется за 5 звёзд), Лесной остров на севере (два моста — за 5 заданий), Маячный остров (за 3 задания). Шесть мостов дугой длиной 40–76 м.
Запекание района: тени один раз, меньше отрисовок, без рывков при езде
ДвижокUB.cityPlan3d с подгрузкой районов (chunk) — запекание (как в больших играх): неподвижный город не отбрасывает тени каждый кадр, тень от солнца считается один раз при постройке клетки и ложится на землю (UB.lightmap3d); настоящие тени — только у машин и людей. Закрытые дома — в общей сетке клетки (своя сетка — только у домов, в которые заходят). Ночью запечённые тени гаснут. plan.bake: false — по-старому. В Плеере (Mac): отрисовок за кадр 1263 → 572.
Движокклетка города строится не чаще 4 раз в секунду, модели новой клетки — сразу своей пачкой, общие пачки моделей собираются, когда подгрузка затихнет: при езде через новые районы рывков больше нет (худший кадр 19 мс, было до 50+).
Движокночью холмы на горизонте темнеют вместе с небом (были светло-зелёными на чёрном небе); фонари города мягче (свет 16 вместо 30, теплее).
ДвижокUB.sunDir3d() — направление на солнце; UB.lightmap3d — lift (высота над землёй), .visible(v).
Город достраивается за туманом, а не на глазах
Движок (меняет поведение): подгрузка районов UB.cityPlan3d (chunk) строит клетки дальше, чем видно (туман + 12 м), и с опережением по ходу движения (куда едешь — на 1,5 с вперёд), по 1–2 клетки за шаг — дома, деревья и мебель появляются за туманом, а не перед машиной. Раньше строилось в 96 м при тумане до 140 м — дома «вырастали» на глазах. Ближе туман — меньше клеток и быстрее; chunkView — свой предел. UB.viewFar3d() — докуда видно.
«Звёздный город» 2.0: туман 35–115 м: город строится до 127 м; Плеер, Mac — 77 кадров, худший кадр 20 мс.
Движок (починка): машины-боты города (life), уехавшие далеко, переставлялись в случайное место — без друзей не ближе 25 м, а в общем мире с друзьями даже рядом с героем (появлялись в 5 м). Теперь — только на краю тумана (от видимого предела до +15 м) и не перед носом ни у кого из игроков; уезжают дальше тумана + 30 м.
Кривые дороги, набережные и запертые мосты
ДвижокUB.ribbon3d({ path, strips, y, color }) — лента по плавной кривой через точки (дорога, тротуар, разметка, тропа, река) одной отрисовкой; .at(s) — точка и направление на длине s.
ДвижокUB.cityPlan3d — улица { curve: true, points: [[x, z], …] } — плавная кривая дорога (набережная вдоль берега, серпантин): асфальт, разметка, тротуары, бордюр, фонари, пальмы у моря (palms, sea); на карте и радаре — тоже. Машины-боты по ней не ездят.
Движокзапертый мост — lock: { missions: 3 } или { stars: 10 } у улицы-моста: ворота с красным огнём и надписью «Закрыто · задания 1/3», пройти и проехать нельзя, рядом — подсказка, что сделать; выполнил — огонь зелёный, «… открыт!», конфетти. У каждого игрока — по его успехам. city.gates, city.lockOpen(lock). UB.land3d — add({ …, when }): суша, пока when().
«Звёздный город» 2.0: Северная набережная с пальмами вдоль северного берега (берег стал извилистым); Звёздный мост на Маячный остров открывается после 3 заданий сюжета.
Движокконец кривой дороги у прямой улицы — настоящий T-перекрёсток: кривая начинается от края асфальта и первые 12 м идёт под прямым углом, в тротуаре улицы — разрыв, на улице — зебры (раньше ленты и тротуары налезали друг на друга).
Движокна радаре и большой карте кривая дорога доходит до середины улицы, с которой стыкуется (раньше обрывалась у её тротуара).
Острова, море и мосты
ДвижокUB.land3d({ islands: [{ name, points: [[x, z], …] }] }) — суша любой формы для любой 3D-игры: вокруг море ниже суши, берег-обрыв, песчаная кромка у воды; в воду не зайти (герой — сам), машинам — land.push в pushOut. land.onLand(x, z), land.islandAt(x, z), land.add({ x, z, w, d }) — ещё суша (мост, пирс). UB.walkArea(fn) — своё ограничение, где ходить.
ДвижокUB.cityPlan3d — islands в плане: город на островах; улица с bridge: true над водой — мост: настил, перила, опоры, у длинного — красные башни-ворота; по мосту ходят, ездят машины-боты и прохожие. На карте и радаре — море и острова. city.land, city.bridges.
«Звёздный город» 2.0: город — на острове среди моря, новый Маячный остров (кафе «Маяк», пляж, две виллы — можно занять, Маячный парк) и Звёздный мост к нему (130 м, с башнями).
Места в городе, звёзды для поиска, свой гараж через портал
ДвижокUB.cityPlan3d — места города (новые виды участков, у каждого свой вид, комнаты и дело): hospital (приёмная и палаты; работа «Врач» — пациент где-то в городе), fire (гараж с пожарной машиной; «Пожарный» — горит дом, доехать и потушить), police («Полицейский» — найти потерявшегося малыша), school (классы; у доски «E — Урок»), library («Библиотекарь» — потерянная книга), mall (магазин, примерочная и кафе внутри), cinema (зал с креслами и экраном; «E — Смотреть фильм»), stadium (поле, ворота, трибуны, мяч — пнуть, гол — монеты).
Движокчто искать — stars: 50 в плане: звёзды спрятаны за домами, в парках, на пляже, на горке; нашёл — монеты и достижения (на аккаунте); discover: true — первый раз в районе — монеты, неоткрытые районы на карте тёмные. city.stars, city.starsFound(), city.discovered(). Достижения: доктор, пожарный, первый гол, киноман, отличник, звёзды, знаток города.
ДвижокUB.lesson({ questions }) — урок в окне (вопросы по очереди, монеты за верные); UB.film({ scenes }) — короткий фильм кадрами с героями и подписями; UB.toast(text) — сообщение посреди экрана; у шага UB.job3d — effect: 'fire' (огонь на месте, пока шаг не сделан).
ДвижокUB.garageWindow({ onRide }) — «Мой гараж» окном поверх любой 3D-игры (машины, краска, диски, спойлер, неон, прокачка), игра стоит, камера возвращается; UB.window3d({ update, draw }) — своё окно поверх игры (герой и «E» замирают, HUD игры под окном не рисуется). В городе — участок с portal: 'garage': портал, E — гараж, «Поехать» — своя активная машина на улице у портала (city.callCar); изменения в гараже сразу видны на своих машинах.
Движоксвоя машина из гаража (UB.vehicle(car, { garage })) в общем мире — друзья видят её, где она стоит и как едет; друг за рулём — его фигурка в машине.
«Звёздный город» 2.0: городская больница, пожарная часть, полиция, школа «Звезда», библиотека, ТЦ «Звёздный», кинотеатр «Луна», стадион «Звезда»; 50 звёзд; районы открываются; портал «Мой гараж» на парковке в центре и у гаража на Набережной; места — на большой карте.
Большой город: подгрузка районов
ДвижокUB.cityPlan3d — chunk: 60 в плане: город делится на клетки по 60 м, дома, двери, мебель и украшения строятся только в клетках рядом с героем (за рулём — рядом с машиной), дальние убираются — вместо них простые коробки (одна отрисовка на клетку). Работа, задания, свой дом, гардеробы и карта работают по всему городу (данные считаются один раз для всех участков). Вернулся в клетку — дом построен заново: дверь, перекраска, мебель — как были. chunkView — как далеко строить (по умолчанию 1,6 клетки), city.chunks, city.chunkStats(). Модели (мебель, деревья) всех построенных клеток — одной пачкой на модель.
Движок (меняет поведение): у каждого участка города своё зерно случайности (цвета, деревья) — участок строится одинаково и при подгрузке; цвета домов в старых городах по плану могут поменяться.
Движокучасток с jobs: false — без работы (большой город: работа не в каждом магазине).
«Звёздный город» 2.0: город в 5 раз больше — 445 участков, 22 улицы, ~760 × 360 м: новые районы «Деловой квартал» (офисы до 8 этажей, магазины и кафе на бульваре, площадь Огней), «Порт» (склады и парковки у моря), «Новый квартал», «Лесной» (дома, парки, площадки), «Восточные холмы» (виллы). Плеер на Mac — 75–82 кадра. Нужна Студия с этим движком: в старой большой город не помещается в 900 объектов.
Куда идти в начале: луч над жителем с заданием, события для Тестера
ДвижокUB.missions3d — над жителем со следующим заданием (пока оно не взято) — луч в небо: издалека видно, куда идти. Задания, работа и покупки отмечают события для Тестера и «Карты игрока» (UB.mark: mission, mission-done, job, coin, buy) — плей-тест видит, что в игре что-то происходит.
«Звёздный город» 2.0: в начале игры герой стоит у площади лицом к мэру, первые 7 секунд — подсказка «Иди к розовому лучу — мэр ждёт тебя на площади».
Машины рисуются в 7 раз быстрее
Движокмашины-заготовки (UB.prefab('car' | 'taxi' | 'sportscar' | 'bus' | 'truck' | …)) были из 50–85 отдельных деталей — каждая отдельная отрисовка, и ещё одна в тени. Теперь детали машины склеиваются в 7–8 сеток: кузов (перекраска setColor работает), диски (цвет из гаража работает), фары по цвету свечения, остальное — по виду материала. Вид тот же. Геометрия одной модели общая у всех таких машин. Касается всех игр с машинами.
Замер (Плеер, Mac, «Звёздный город» из трёх районов): отрисовок за кадр 2846 → 1199, кадров 80 → 88, худший кадр 34,5 → 17,3 мс.
Движокчеловечки в браузере (сайт, веб-Плеер, Студия) рисуются скелетом: части тела — кости, детали — одна сетка, одежда в цвет — вторая, лицо — третья (было 14 отрисовок на человека). Анимации, переодевание, перекраска одежды, свой персонаж — как раньше. В Плеере (на телефоне и компьютере) — как было, из деталей: там скелет считается на процессоре и город шёл 7 кадров вместо 88. Толпа (e.crowd, юниты стратегии) — как была.
Движок (починка):UB.wear(...) без окна гардероба надевал вещь на облик по умолчанию — свой персонаж («Мой персонаж») пропадал. Теперь наряд — поверх своего персонажа.
Движокмебель в домах города по плану (модели набора) больше не отбрасывает тень от солнца — она под крышей, тень не видна, а рисовалась ещё раз в каждой карте теней: в Плеере отрисовок 1200 → 950.
Карта с улицами, деревья в Плеере не чёрные
Движок (починка): деревья, пальмы и другие модели, выгруженные как матовый металл без текстур (так у наборов Kenney), в Плеере были чёрными — такой «металл» окрашивает только отражение окружения. Теперь движок при загрузке модели считает его не металлом: цвет одинаковый в браузере и в Плеере. Гладкий металл (хром) не трогается.
ДвижокUB.mapPlan(() => ({ x0, z0, x1, z1, rects: [{ x, z, w, d, color }] })) — свой план для радара и большой карты (улицы, участки, вода); раньше план был только по твёрдым коробкам — дорог на карте не было. Город по плану (UB.cityPlan3d) рисует свой план сам: улицы с тротуарами, участки по видам, дома, пляж, море. На радаре такой план плотнее — сквозь него не видно столбов и деревьев сцены.
Движокподписи на большой карте (labels) — на подложке поверх точек и не налезают друг на друга (сдвигаются; не помещается — остаётся точка).
«Звёздный город» 2.0: на радаре и карте (M) — улицы и районы.
Детская площадка, неоновая площадь, сюжет в новых районах
ДвижокUB.cityPlan3d — участок kind: 'playground' — детская площадка: горка (по ступеням наверх, по скату вниз), качели, песочница, карусель (на неё можно встать), скамейки, деревья. Площадь kind: 'plaza', style: 'neon' — тёмная плитка, неоновая рамка и колонны, пальмы, скамейки, светящаяся башенка в середине (ночью горит).
«Звёздный город» 2.0: «Детская площадка» в «Садах», «Площадь Неона» на «Набережной»; сюжет продолжается — мороженщица Зоя, сёрфер Арман, садовник Ильяс, учительница Мира: «Мороженое тает», «Волна у маяка», «Яблоки для школы», «Праздник на площади Неона» (9 заданий).
Большой город из районов; машины и двери под рост героя
Движок (меняет поведение):UB.cityPlan3d — масштаб под героя (2 м): машины плана и машины-боты крупнее заготовок в 1,25 раза (plan.carScale), двери 2,5 м вместо 2,24, этаж 3,5 м вместо 3,2. Раньше легковая рядом с героем выглядела игрушечной. Игры подгонять не надо (планы городов те же, дома немного выше).
Движокневидимые стены каждого участка города — один составной объект (части), а не два десятка: центр «Звёздного города» — 112 объектов вместо 242, город из трёх районов (40 участков) — 256. Столкновения, видимость, камера и сетка проходимости работают как раньше.
Движокdistricts в плане с name (без ground) — именованные части большого города; city.districtAt(x, z) → { name } — где герой.
«Звёздный город» 2.0: два новых района в одной карте: «Набережная» (восток, у моря: «Мороженое», кафе «Пальма», сёрф-шоп, отель, вилла у моря, площадь Неона, парк, гараж, пляж «Маяк») и «Сады» (север, пригород: дома с садами — пять с входом, их можно занять, яблоневый сад, школа «Звезда», детская площадка). Улицы продлены, новые — Пальмовая, Маячная, Яблоневая, Вишнёвая, Дальняя; вверху — «Звёздный город · Набережная».
Задания с сюжетом
ДвижокUB.missions3d({ npcs, missions }) — задания с сюжетом, как в GTA, по-детски: у жителя, который даёт следующее задание, «!» над головой; E — разговор (реплики субтитрами внизу экрана: имя и слова, E — дальше; ушёл — разговор прервался). Шаги: дойти до места и E (at, text, carry — вещь в руках), доехать на машине (drive: true, без E), поговорить с другим жителем (talk, say); time — успеть за столько секунд (не успел — задание заново у того же жителя). Задания по порядку, выполненные хранятся на аккаунте (UB.economy), награда — монеты; вверху — плашка задания (последние 10 секунд — красная). M.cur, M.target(), M.next(), M.done(id), M.fail(), M.reset().
ДвижокUB.cityPlan3d — npcs и story в плане: житель стоит у своего участка снаружи, сбоку от двери; шаги по участкам — go (к двери), drive, talk. city.story. У домов — aside (где встать жителю).
«Звёздный город» 2.0: сюжет из пяти заданий — мэр, тётя Алия, повар Тимур, лихач Дима, стилист Лина: «Новенький в городе», «Свежий хлеб», «Обед для мэра» (на время), «Ночной заезд», «Звезда города»; цель — на радаре.
Радио в машине, город днём и ночью, неон, общие часы мира
ДвижокUB.vehicle(car, { radio: true }) — радио: сел за руль — играет станция («Неон FM», «Закат», «Турбо», «Ночной город», «Звезда» — стили UB.music со своей мелодией, и «выкл»), T или тап по плашке «Радио» вверху — следующая; вышел — снова музыка игры. UB.radio([{ name, style }]) — свои станции. Машины UB.cityPlan3d — с радио сами (plan.radio: false — без).
ДвижокUB.dayCycle3d(sec, { start, clock }) — с какой доли суток начать (0 — утро, 0,45 — перед закатом, 0,7 — ночь) и свои часы; UB.daylight — 1 днём, 0,55 на закате, 0 ночью. w.time() у UB.world — общие часы мира (секунды ведущего, у всех одинаковые).
ДвижокUB.cityPlan3d — dayNight: 240 в плане: город живёт днём и ночью — ночью горят окна, настоящий свет фонарей и неон, днём — обычные стёкла и плафоны; с друзьями — у всех одно время. У магазинов, кафе и одежды — неон по краю крыши.
«Звёздный город» 2.0: сутки — 4 минуты (начало перед закатом), ночью неон; радио в машинах.
Мебель в своём доме; прокрутка в окне магазина
ДвижокUB.cityPlan3d — у входа в свой дом «E — Обустроить» (вместо «Обои и пол»): окно с обоями и полом (бесплатно, следующие цвета) и мебелью за монеты — диван, телевизор, столик, ковёр, растение, стол со стульями, кровать, шкаф, стол с компьютером, книжная полка, тумбочка, игрушки. Купленное встаёт в 1,5 м перед героем лицом к нему (не в своём доме — монеты назад), у предмета — «E — Убрать» (монеты назад). В общем мире — у ведущего, видят все; до 24 предметов; новый хозяин — пустой дом. Из кода: city.furnish('sofa') (true — бесплатно, подарок), city.furniture(), city.paint('in' | 'out').
Движок (починка): окно магазина (E.shop) с длинным списком прокручивалось только стрелками клавиатуры — на телефоне до нижних строк было не добраться. Теперь внизу «↑» «↓» и «9–13 / 13».
«Звёздный город» 2.0: обустрой свой дом — мебель за монеты с работы.
Свой дом можно перекрасить
ДвижокUB.cityPlan3d — хозяин дома обустраивает его: ведро краски у дорожки — «E — Покрасить дом» (фасад и крыша, каждое нажатие — следующие цвета), внутри у входа — «E — Обои и пол». В общем мире решает ведущий, видят все; новый хозяин получает дом таким, каким он построен. Сетка дома пересобирается только при перекраске.
«Звёздный город» 2.0: занял дом — перекрась его.
Такси в городе, работа без E, «за рулём ли я»
ДвижокUB.driving() — машина (UB.vehicle), за рулём которой я сейчас, или null.
ДвижокUB.job3d — шаг без E: { auto: 4.5, need: () => !!UB.driving() } — доехал (дошёл) ближе 4,5 м — шаг засчитан (за рулём — считается от машины); person: true — на месте ждёт человек и садится, personOut: true — выходит и уходит; fn у шага; tip — подсказка к «Смена: …». Шаг без E не выполняется сам при начале смены.
ДвижокUB.cityPlan3d — есть такси на плане (cars: [{ prefab: 'taxi' }]) — работа «Такси»: портфель у машины, пассажир ждёт на тротуаре, отвезти на другую улицу (дальше 35 м) на любой машине; платят 8 + расстояние / 5. plan.jobs: { taxi: false } — без неё. У city.cars — prefab, x0, z0 (где стояла).
«Звёздный город» 2.0: работа таксистом — портфель у такси на парковке.
Свой дом в городе: занять, запереть, имя хозяина на табличке
ДвижокUB.cityPlan3d — у каждого дома, в который заходят, табличка во дворе: «Свободен» — E «Занять дом», ещё E — запереть или отпереть (в запертый чужой дом дверь не открывается, на двери — «Заперто»). У каждого игрока один дом. В общем мире решает ведущий (наш сервер): все видят имя хозяина на табличке; хозяин вышел из комнаты — дом снова свободен. city.myHouse() — мой дом (поставьте на радар), city.leaveHouse(), у дома owner, locked, mine; plan.homes: false или own: false у участка — без таблички.
«Звёздный город» 2.0: любой дом с входом можно занять — «Дом на Садовой» (был «Мой дом»), «Дом у бульвара», «Дом у моря»; свой дом — на радаре.
Одежда за монеты, наряд на аккаунте, магазин одежды в городе
ДвижокUB.wardrobe({ price: { hat: { crown: 150 } } }) — вещи за монеты: на плитке цена, тап — купить один раз (UB.economy или свой wallet), дальше вещь своя; owned: true — только бесплатное и купленное (шкаф дома); onBuy. В игре с UB.economy наряд и купленное хранятся на аккаунте и надеваются при следующем заходе (save: false — нет).
Движок (починка): в общем мире друзья видят твой наряд из гардероба всегда — раньше он надевался на их фигурки только во время конкурса мод (w.contest).
Движокгардероб в тесной комнате — герой поворачивается туда, где больше места, камера не уходит за стену. Названия вещей — по-русски, по-узбекски и по-английски («Корона», «Крылья»), а не crown, wings.
ДвижокUB.cityPlan3d — участок kind: 'clothes' — магазин одежды (вешалки, зеркало, касса): у зеркала «E — Примерочная» — шапки, очки, аксессуары за монеты, цвета и причёски бесплатно; в доме со спальней — «E — Гардероб» (что уже есть). plan.clothes: false — без одежды, { price } — свои цены; city.wardrobes — где они.
«Звёздный город» 2.0: магазин «Одежда «Стиль» за «Моим домом» (вместо офиса) — тратить монеты с работы; шкаф в спальне; магазин на радаре и большой карте.
Работа в городе за монеты: официант, продавец, курьер
ДвижокUB.job3d({ name, start: { x, z }, steps: [{ at, text, carry }], pay }) — работа сменами, как в Brookhaven: у места работы светящийся портфель (E — «Работать: …», первый шаг сразу), дальше к каждой цели — луч и светящийся кубик, у цели — «E — …»; carry — что герой несёт в руках до последнего шага; последний шаг платит монеты в UB.economy (или свой wallet). at — точка, список (каждый раз другая) или функция. Вверху — плашка смены (работа · заказов · заработано), Q или тап по ней — закончить; новая смена заканчивает старую; leave: 40 — ушёл дальше — смена кончилась. UB.job3d.current(), UB.jobs3d(). Работает и в общем мире: у каждого своя смена и свой кошелёк.
ДвижокUB.cityPlan3d — работа в городе сама: кафе — официант (заказ у стойки → столик), магазин — продавец (коробка у кассы → полка), магазин и дома — курьер (посылка у входа в магазин → дверь дома, дальше — дороже). city.jobs — работы (j.kind, j.at — куда идти, поставьте на радар); plan.jobs: false — без работы, { waiter: false, courier: { pay: 20 } } — выключить одну или своя плата. У домов — H.items: где стоит мебель и где перед ней встать (kind, x, z, front).
Движок (меняет поведение): в кафе города по плану — до трёх столиков вместо одного.
«Звёздный город» 2.0: работа за монеты — официант в «Кафе «Звезда», продавец в «Продуктах», курьер по домам центра; монеты в углу, работы — на радаре и большой карте. Ещё два дома, в которые заходят: «Дом у бульвара» и «Дом у моря».
«Сайт не принял код» видно до отправки; дорога и трава быстрее
Студия«Выпустить» → «Проверить» сначала гоняет тот же автотест, что сайт (пункт «Сайт (автотест)»): кадры меню → игра → итоги, нажатия, лимит 1,5 с на пачку кадров. «The game froze: a frame took too long», падение в сцене итогов и т. п. — теперь до отправки, с тем, какая пачка тяжёлая: «60 кадров, сцена «menu»: ≈ 1860 мс на сервере сайта при лимите 1500 мс». Близко к лимиту — замечание.
Студия«Телефон: игра не запустилась — не появилось ни одной сцены» больше не пишется, когда игра запустилась, а Тестер просто не успел: теперь это замечание «Тестер не закончил за 24 с — игра запустилась (сцена «…»), но на этом экране идёт очень медленно».
Студия«Выпустить» проверяет длину текста страницы на всех языках до отправки («О чём игра» (UZ): 311 символов — на сайте не больше 300, сократите); отказ сайта 400 validation — с полем: «Сайт не принял данные: i18n.uz.pitch — too_big ≤ 300», а не обрезанное «Нет связи с сайтом (…)».
Движокroad.dist(x, z) у UB.path3d — в ~5 раз быстрее (поиск кольцами от точки, не квадрат 40 м); road.dist(x, z, far) — не искать дальше far. avoid: road у UB.grass3d / UB.scatter спрашивает только нужный радиус: трава 200×200 у дороги — 0,39 → меньше 0,12 с. Свой avoid: { dist(x, z, far), width } получает far третьим аргументом.
Как подогнать свою игру: свой avoid.dist для тысяч травинок — ищите только рядом (третий аргумент far), а не точное расстояние на десятки метров: на сайте это «The game froze». Экран итогов (over) сайт открывает со своими данными { score, won, winner } — не рассчитывайте на свои поля в data.
Лестница без тряски
Движок (меняет поведение): камера от первого лица на ступенях больше не прыгает на каждую ступень — плавно догоняет высоту героя (за ~0,1 с). Прыжок, падение, стремянка и перенос героя — как раньше, сразу. Игры подгонять не надо.
Комната: неподтверждённые действия и короткие события
Движок (комната):UB.net.pending() у игрока → [{ kind, data }] — действия, которые ведущий ещё не подтвердил (показать деньги уже без покупки сразу). UB.net.emit(kind, data, { keep: 0.8 }) — частые события (выстрелы) повторяются в рассылках 0,8 с вместо 5 — меньше данных в бою.
Наблюдение и лобби для телефона и опоздавших
ДвижокUB.spectate3d на телефоне сам рисует кнопки «Следующий», «Свободная камера», «Играть за него»; S.next(), S.setFree(on) — для своих кнопок; canTake / onTake — «E — играть за него» (встать на место бота). Камера за напарником — без «рентгена»: стены не просвечивают (раньше сквозь них было видно врагов).
ДвижокUB.lobby({ locked: () => matchRunning }) — кто пришёл посреди матча, видит «Матч уже идёт — войдёшь со следующего раунда» вместо выбора команды; «Ждём: Аня — ещё загружает игру» — с правильным окончанием для одного.
«Сжать игру»: текстуры в атласы — карта рисуется в разы быстрее
Студияв «Сжать игру» (⌥⌘K) — галочка «Текстуры — в атласы» (включена): статичная модель с 16+ текстурами (карта, город, большой дом) собирается на несколько больших картинок-атласов — отрисовок за кадр столько, сколько атласов. Карта Dust2: 390 материалов → 6 за 4 с, треугольники те же, файл 12,6 → 11,2 МБ; в игре кадр рисуется примерно вдвое быстрее. Модели с анимацией, скелетом или морфингом не трогаются. Исходник — в .upbilim/originals/, «Вернуть исходники» возвращает его.
Готовое лобби с командами
Движок (комната):UB.lobby({ title, teams: [{ name, color }, …], max: 5, start: [{ label, go }] }) — лобби, где каждый на своём экране выбирает команду (не больше max на команду — лишние в другую), пустые места — «бот», у кого игра ещё качается — «загружается…» (у ведущего — «Ждём: …»), кнопки начала — только у ведущего. В draw — L.draw(g); L.rows() → [{ id, name, team, ready, me }] — составы для матча; L.stop(), когда матч начался.
Комната без потерь, строй команды, «ты со стороны», наблюдение после гибели, попадания по частям тела
Движок (комната):UB.net.act(kind, data) у игрока — действие дойдёт до ведущего ровно один раз (повторяется само, пока ведущий не подтвердит); у ведущего UB.net.acts() — каждое по одному разу, по порядку. UB.net.emit(kind, data) у ведущего — событие для всех (выстрел, взрыв, «раунд окончен»), у игрока UB.net.events() — ровно один раз. UB.net.glide(figure, { x, y, z, rotY }, dt) — плавно двигать других между рассылками.
ДвижокUB.lineup3d(people, { x, y, z }) — твоя команда в ряд на карте (меню, лобби, итоги): люди своими персонажами в куртке цвета команды, боты — роботы; камеру ставит сам, не за стену. UB.introCam3d(hero, { yaw }) — в начале раунда пару секунд камера показывает героя спереди, потом снова от первого лица. UB.spectate3d({ units, killer }) — после гибели: камера смерти на того, кто выбил, потом за спиной напарника (Пробел — следующий), Q — свободная камера.
ДвижокUB.gun3d — в onHit теперь hit.part: 'head' / 'chest' / 'stomach' / 'legs' (по высоте попадания); parts: { head: 4, legs: 0.75 } — множители урона.
Оружие со своим звуком и направлением, облик со shirt
ДвижокUB.gun3d({ sound: 'assets/ak.wav', volume, onAim }) — у каждого ствола свой звук выстрела (gun.set('rifle', { sound }) при смене, sound: false — тихо; без sound — общий, как раньше); onAim: (a) => a — поменять выстрел перед полётом ({ from, dir }: разброс на бегу, увод очереди вбок). Описан gun.hands.show(false) — спрятать руки от первого лица.
Движок (меняет поведение): облик «Мой персонаж» (UB.character3d({ look }), UB.dressAs) принимает цвет верха и как shirt, не только color — раньше shirt молча терялся и верх был цвета по умолчанию.
Что уже умеют Студия и движок
Игры из Студии со своей комнатой — «Играть» и «С друзьями»; кто ещё загружает игру
Плеер и сайт: игра из UpBilim Studio, которая сама играет в комнате через UB.net (своё лобби, ведущий, у каждого свой экран), теперь как наборы с комнатой: на странице игры — и «Играть» (одному), и «С друзьями», ярлык «1 и с друзьями»; её можно выбрать в любой комнате («Выбрать игру»). Раньше такая игра оставалась только одиночной, если её первый выпуск был без UB.net. Правило — только для версий из Студии; детские командные игры (общий экран + телефоны) не меняются.
ДвижокUB.net.players() у ведущего — [{ id, name, team, ready }]: человек в комнате появляется сразу, а игра у него ещё качается (большая — десятки МБ); ready: true — его игра уже запустилась. Покажите в лобби «загружается…» и начинайте, когда все ready. Сам ведущий — всегда ready.
Сайт (команда UpBilim): раздел «Студия» — игры на проверке с выбором возраста и «Утвердить» / «Отклонить», качество сборок, возраст и жанр; по «Сыграть» видно, сколько игры скачано.
Город с друзьями живёт на нашем сервере: до 30 игроков
Сервер (комнаты): игра с UB.cityPlan3d(plan, { world: w }) и UB.world в комнате с друзьями — город ведёт наш сервер, а не телефон ведущего: сервер берёт из игры только план (JSON, код игры на сервере не исполняется), строит тот же город и ведёт общие двери, общие машины, машины-боты и прохожих. Все телефоны — игроки; кто бы ни вышел, город идёт. В одном городе — до 30 игроков (было 8). Пока работает после выкладки сервера; экземпляры города («зайти к другу», новый город, когда полон) — следующий шаг.
Движок (меняет поведение): ведущий без экрана (сервер, свёрнутая вкладка ведущего) теперь шагает весь 3D-мир: общие объекты, машины игроков, жизнь на улицах, двери (UB.__hostStep). Раньше у свёрнутого ведущего общий 3D-мир стоял. Игры подгонять не надо.
Как подогнать свой город: план — JSON (import plan from './city.plan.json' или прямо в коде), город строится на верхнем уровне до UB.start, в UB.world({ players: 30, spawn }) — 30 мест появления.
«Звёздный город» 2.0: центр — город на 30 игроков на сервере.
Город с друзьями: до 8 игроков в одном городе
ДвижокUB.cityPlan3d(plan, { world: w }) — город в общем мире (UB.world({ hud: false }), без раунда и очков): друзья видят друг друга, двери общие (открыл друг — открыто у всех, и у того, кто пришёл позже), машины на парковке общие (сел любой — все видят, как он едет), машины-боты и прохожие у всех одни и те же — их ведёт ведущий. Город строится на верхнем уровне программы, до UB.start. Свои машины из гаража в общем городе пока не ставятся.
Движокв общей машине (UB.vehicle с shared: true) игрока через полторы секунды высаживало («место занято»), хотя ведущий уже записал его водителем: проверка иногда шла раньше снимка ведущего. Теперь высаживает, только если ведущий записал водителем другого; аркадная езда при этом убирает за собой камеру, мотор и пульт.
«Звёздный город» 2.0: центр — общий город на 8 игроков; «В городе: N» и друзья на радаре.
Город ожил: машины ездят по улицам, люди гуляют
ДвижокUB.cityPlan3d — life: { walkers: 10, cars: 6 } в плане (или city.life({ walkers, cars, kinds }) из кода): машины-боты ездят по улицам плана по своей полосе, поворачивают на перекрёстках, тормозят перед машинами, героем, твоей машиной и людьми на переходе, проезжают перекрёсток по очереди; твоя машина в них упирается. Люди гуляют по тротуарам — останавливаются, разворачиваются, переходят улицу по зебре, уступают дорогу герою. city.traffic, city.walkers — кто есть.
Движокпрохожие и машины-боты — без настоящей тени (пятно под ногами есть): так город с жизнью в Плеере почти не тяжелее пустого (на Mac 91 кадр против 94).
Пульт машины на телефоне в городе, радар без тормозов в Плеере
Движоксел в машину (UB.vehicle с drive: 'arcade') на телефоне — вместо джойстика героя пульт машины, как в мобильных гонках: руль ← → слева, справа задний ход «R», нитро, тормоз и газ; спидометр — над пультом. Вышел — снова джойстик героя и кнопки игры.
Плеер (движок):UB.hud.radar рисовал план карты с поворотом и круглой обрезкой прямо на экран каждый кадр — в Плеере это перерисовка и загрузка всего HUD на каждом шаге героя. Теперь радар — своя картинка, обновляется, только когда сдвинулся или повернулся (до 20 раз в секунду). «Звёздный город» в машине на Mac: 70 → 100 кадров, JS-кадр 5,2 → 0,95 мс. Касается всех игр с UB.hud.radar.
Езда как в гонках, свои машины из гаража, камера как в GTA, свой персонаж в Студии
ДвижокUB.vehicle(машина, { drive: 'arcade' }) — сел на E и едешь как в «Ночных улицах» (UB.car3d): газ ↑, тормоз и задний ход ↓ (и R), занос, нитро — пробел, 6 передач, звук мотора по оборотам, фары ночью, камера за машиной, спидометр; вышел (E или нажать плашку «E — выйти») — камера снова за героем. На телефоне — джойстиком героя (вбок — руль, вверх — газ, вниз — тормоз). Водитель в аркаде не виден (showDriver: true — виден). Машины UB.cityPlan3d едут так по умолчанию (drive: 'simple' — по-старому).
Движоксвои машины из «Моего гаража» в городе: у машины плана mine: 1 (активная), 2, 3… или 'all' (все купленные в ряд) — своя модель, краска, диски, спойлер, неон и прокачка (мотор — скорость, шины — сцепление, нитро, руль). Не вошёл в аккаунт — заготовка из плана. UB.myCars() — все купленные машины, UB.garageStats(машина) — её сила для UB.car3d.
ДвижокUB.camera3d({ mode: 'follow', target, chase: true }) — камера как в GTA: когда герой идёт, она плавно заходит ему за спину; мышью (тащить) или пальцем по правой половине — повернуть и поднять-опустить, секунду после этого не мешает. UB.car3d({ input }) — своё управление поверх клавиш.
Студияв игре, запущенной в Студии, герой — твой персонаж из «Мой персонаж», а машины — из «Моего гаража» (как в Плеере); нужен вход в аккаунт.
Город по плану из настоящих моделей: дома, мебель, деревья, пляж
ДвижокUB.cityPlan3d — kits в плане: furniture: 'assets/furniture-kit/' (набор мебели Kenney) — в домах настоящая мебель: диван, телевизор на тумбе, ковёр и столик, кухня с плитой и раковиной, холодильник, стол со стульями, кровать с тумбочкой, шкаф, ванна, раковина, унитаз, стол с компьютером, стеллажи и проходы в магазине, круглые столики в кафе; tree / palm — деревья и пальмы моделями. Копии одной модели рисуются одним объектом (не в счёт 400). Без kits — как раньше, из коробок.
Движокзакрытый дом или офис моделью — model: 'assets/city-kit-suburban/building-type-e.glb' у участка: модель вписывается в участок, а его стена подгоняется под настоящий размер модели, когда она загрузится (turn — довернуть модель). Участок beach — песок, пальмы, зонтики и лежаки; water в плане — море или пруд.
Движокмебель ищет место сама: занято (проём, другой предмет) — та же стена в другом месте, потом другие стены; кухня больше не остаётся пустой.
ДвижокUB.model3d(…, { fit: { w, d, h } }) и UB.models3d([{ …, fit }]) — вписать модель в коробку (наибольший размер, пропорции свои) вместо высоты h.
Студиянабор мебели в плане пишите с / на конце (assets/furniture-kit/) — тогда Студия кладёт в игру всю папку набора.
Город по плану, стены из модели, граф ходьбы («Звёздный город» 2.0, этап 1)
ДвижокUB.cityPlan3d(plan) — свой городок по плану-данным (city.plan.json в проекте: import plan from './city.plan.json'). Улицы вдоль x или z, перекрёстки и Т-перекрёстки находятся сами (зебры, разметка), тротуары с бордюром, фонари (вечером и ночью — настоящий свет). Участки: дом, магазин, кафе, офис, гараж, парк с фонтаном, площадь, парковка; дом смотрит на ближайшую улицу. Дом, в который заходят (enter: true, rooms: ['living', 'kitchen', 'bedroom', 'bath']), — комнаты в два ряда с проёмами, мебель по виду комнаты (диван и телевизор, кухня и холодильник, кровать и шкаф, ванна…), лампа в каждой комнате, дверь открывается на E, крыша прячется, пока герой внутри. Машины на парковке — сесть на E и ехать, сквозь дома не проехать. city.roomAt(x, z) — в какой комнате герой, city.houses, city.pushOut (дома как стены для UB.car3d), city.warnings — участки на дороге. Вид — общие сетки, стены — невидимые коробки: городок из 11 участков — около 100 объектов.
ДвижокUB.vehicle — машины-заготовки (UB.prefab('car') и др.) ехали задом наперёд: они смотрят на −z, а езда шла по +z. Теперь — носом вперёд, водитель сидит лицом вперёд; свои коробки и модели сцены — как раньше (forward: -1 | 1 — задать самому). Новое: pushOut(x, z, r) — свои стены для машины.
Студияредактор сцены — «Стены из модели» (выбрана модель карты): невидимые коробки по её GLB — полы (где стоять) и стены (вертикальные грани — повёрнутые коробки по плоскостям, дверные проёмы не закрываются); группа «Walls: <имя>», при повторе заменяется. Невидимые стены в редакторе — полупрозрачные розовые. Детальная модель (склоны, косые стены, мелочь, как карта CS) даёт тысячи коробок — Студия предупреждает.
Студияредактор сцены — «Построить граф ходьбы» (ничего не выбрано): где может встать игрок — по твёрдым коробкам, невидимым стенам, пандусам, заготовкам и рельефу (шаг до 0,55 м, место над головой, ступеньки и пороги не рвут граф); только куски, связанные с точками появления. Файл maps/<сцена>.nav.json, в игре — UB.navGraph(nav); граф виден точками поверх сцены.
Для ИИ-агентов:node .upbilim/scene.mjs walls <сцена> <модель> и node .upbilim/scene.mjs nav <сцена> — то же командами (--top — отрезать небо и дальние декорации, --cell); общий код — .upbilim/mapkit.mjs. В engine-3d.md — UB.cityPlan3d и формат плана.
Студия: нижняя панель как в VS Code, луна в невысоком окне игры
Студияпроводник слева — на всю высоту окна, нижняя панель (файлы игры, консоль, терминал) — только под редактором и игрой, как в VS Code; правая панель — тоже на всю высоту.
Студиязаставка «Игра» (луна над тумбой) в невысоком окне игры больше не переворачивается и не вылезает на нижнюю панель — луна уменьшается, в совсем низком окне прячется.
«Проверка моделей»: крестик и кнопки после сжатия
Студияв окне «Проверка моделей» — крестик (закрыть, модели как есть). После «Сжать» кнопки больше не застревают: можно сразу «Упростить», а «Упростить» — ещё раз, если треугольников всё ещё много. У моделей из Tripo почти весь вес — треугольники (1,5 млн), «Сжать» убирает мало, для телефона нужен «Упростить». В панели «Изменить модель» (вкладка модели) — «Упростить»: 50 / 25 / 10 / 5 / 2 % треугольников, результат сразу в предпросмотре, цифры «было → стало»; «Сохранить копию» оставляет исходник.
«Создать по описанию»: модели снова создаются
Студияключ Tripo проверялся («Ключ работает»), но «Создать» ничего не давало: Tripo V3 требует версию модели в запросе (model), без неё отвечает ошибкой. Теперь Студия передаёт v3.1-20260211 (проверено: модель за ~2,5 минуты, 20 кредитов Tripo). Строка ожидания (крутилка и проценты, ошибка — красным) после «Создать» прокручивается в вид — раньше пряталась за краем окна. Пока модель делается, на кнопке «Создать» — крутилка и шаг («В очереди», «Ждём… 45 %»), второй раз она не нажимается. В невысоком окне Студии список готовых моделей и предпросмотр больше не сжимаются в полоску — окно «Создать по описанию» прокручивается.
Машина: кнопка заднего хода
Движокна пульте машины — кнопка «R» (задний ход, back = клавиша R); педаль тормоза на телефоне теперь только тормозит. На клавиатуре стрелка вниз — как раньше: тормоз, а на месте — назад. «Ночные улицы» — с кнопкой «R».
Машины: пульт как в мобильных гонках, свет под машиной, фары ночью
ДвижокUB.touchControls([...], { car: true }) — пульт машины на телефоне: слева большие стрелки руля, справа педаль тормоза (и газа, если газ не сам) и нитро с молнией. Спидометр, полоски нитро и бензина, тахометр встают над пультом (UB.__padLift). «Ночные улицы» и «Горы и грязь» — на нём (вместо джойстика).
ДвижокUB.car3d({ underglow, headlights }) — подсветка под машиной теперь настоящий цветной свет на асфальт (в Плеере — лампа, в браузере — мягкое пятно), а не плоская светящаяся плашка; фары сами включаются ночью (headlights: 'night' по умолчанию, true — всегда, false — нет) и светят на дорогу впереди. UB.lightMood — текущее освещение ('day' | 'night' | …), lp.move(x, y, z) у UB.lamp3d.
Плеер: HUD игр рисует видеокарта
Плеер (ubrt): экранный холст игры (HUD: кнопки, надписи, спидометр, миникарта) больше не рисуется целиком на процессоре. Каждая команда рисования превращается в маленькую картинку один раз; картинки лежат в общем атласе в видеокарте, кадр собирается из них. Неподвижное (кнопки, плашки, подписи) не рисуется и не грузится заново — только то, что меняется. drawImage (миникарта, спрайты) — сразу видеокартой: источник — текстура, обрезка (круглая миникарта) — маской.
Цифры (Mac, «Ночные улицы» в гонке, HUD 2560×1440): рисование HUD 5,0–5,4 → 2,4–3,0 мс на кадр; в видеокарту уходит 0,4–0,5 млн точек за кадр вместо 3 млн. iPhone 16 Pro: HUD 1,03 → 0,30 мс на кадр.
Где остаётся старый путь (сам): холст — источник для другого холста или текстура 3D, getImageData, putImageData, частичное стирание, необычное смешивание, рисунок больше четверти экрана (заставки и меню во весь экран). UB_NOGPUHUD=1 — выключить новый путь для сравнения.
«Создать по описанию»: ключ Tripo из любого региона
Студияключ Tripo tsk_… отвечал «401: Invalid API key», хотя был рабочим. Tripo V3 принимает ключ только в его регионе: международный — openapi.tripo3d.ai, китайский — openapi.tripo3d.com, а Студия всегда ходила на китайский. Теперь Студия сама узнаёт регион ключа (по балансу) и запоминает его. «Где взять ключ» ведёт в новую консоль developers.tripo3d.ai.
«Площадка»: где ждут друзья в «Своей комнате»
Сервер: площадка — встроенная игра движка Студии (общий мир UB.world без раунда и очков), в базе игр её нет.
Плеер 0.1.2 (сборка 5) для iPhone и iPad
Плеер (iOS): сборка 5, версия 0.1.2, — первая для iPhone и iPad вместе; загружена в App Store Connect.
Плеер (ubrt): проверочное нажатие клавиш и нажатие в точку (UB_PRESS, Click:x:y@с) работают и во встроенном движке iPhone/iPad; UPBILIM_OPEN=phone:game=<id> / phone:tab=charts — страница игры или вкладка на телефоне; отладочный запуск UPBILIM_OPEN=view:charts открывает раздел библиотеки (снимки для App Store без нажатий).
«Звёздный город» спрятан, большие игры — флагом с сервера
Мир школы: на автовокзале нет автобуса в спрятанную игру.
Плеер на iPad: игра во весь экран, «назад» на одном месте
Плеер (iPad): игра в портрете выходила из полного экрана в плавающее окно: Плеер просил повернуть экран «лёжа», а на iPadOS 26 такая просьба превращает приложение в окно. На iPad экран больше не поворачиваем — игра идёт так, как держат планшет.
Плеер (ubrt, iPad и симулятор): 3D-игры показывали чёрный экран: сглаживание 2× (включено для iPhone ради скорости) просили у любой видеокарты с нужной фичей, а у части iPad и в симуляторе форматы умеют только 1× и 4×. Теперь 2× — только если видеокарта его умеет для экрана и глубины, иначе 4×.
Плеер (iPad): кнопка «назад» в игре пряталась под кнопками окна iPadOS 26 (слева сверху), а в браузерных играх стояла посередине. Теперь везде одно правило: слева сверху, на iPad правее кнопок окна. Правило записано в docs/engine/hud-style.md.
Страница игры: видео и скриншоты одной лентой
Плеер (телефон): наверху страницы игры теперь одна лента — видео автора играет само, без звука, по кругу; пальцем влево-вправо листаются обложка и скриншоты (точки внизу показывают, где ты). Видео играет, только пока его видно; кнопка звука справа сверху. Раньше было две части: картинка сверху и отдельно чёрное окно видео с кнопкой «пуск».
Плеер (iPad, компьютер): в чартах длинные названия раздвигали колонки, и страница уезжала вбок — колонки больше не шире экрана.
Плеер на iPad
Плеер (iPad): приложение шло в узком окне «для iPhone» посередине экрана — теперь собирается и для iPad: во весь экран, настольная раскладка (колонка слева, поиск, плитки), но повадки телефона — поворот под игру, строка состояния, игра нашим движком поверх, «Поделиться», push; отступы под часы и «остров», кнопки полного экрана нет. Поддержка iPad — это и новые снимки экрана для App Store при следующей отправке.
Сайт studio.upbilim.com: кнопка «Скачать» — ровный фирменный красный без градиента и розового свечения.
Пульт на телефоне в Плеере и круглый джойстик
Плеер (ubrt): в играх на телефоне не было экранного пульта: прослойка DOM понимала только inline-стили, а пульт движка стилизован классом .ub-pad из <style> страницы. Теперь есть таблицы стилей (селекторы по тегу, классу, id и потомкам; <style> страницы приходит из Rust, <style> игры — при добавлении), env(safe-area-inset-…) в calc(), transform: rotate() у значков. Пульт на месте, значки стрелок правильные.
ДвижокUB.touchControls вместо кнопок-стрелок ставит круглый джойстик (как в мобильных играх): отклонение даёт только те стрелки, что просил набор (в гонках — влево, вправо, вниз), мёртвая зона; UB.joy — отклонение как есть для наборов с плавным рулём. Кнопки действий — справа, как были. Касается всех 12 наборов с пультом.
Ядро:scripts/player-bench-page.mjs подменяет в странице и стили.
Ускорение: видеокарта и нагрев на iPhone
Плеер (ubrt, iPhone): сглаживание MSAA 2× вместо 4× и дальние карты теней не каждый кадр (ближняя — каждый, средняя — через кадр, дальняя — каждый третий): меньше работы видеокарты, телефон греется медленнее и дольше держит 60 кадров. На компьютере ничего не меняется.
Ускорение: three_native на телефоне
Плеер (ubrt): обход сцены для видеокарты переписан под JavaScriptCore без JIT (iPhone): материал готовится раз в кадр, копии травы, пачек и толпы умножаются прямо в запись, геометрия без WeakMap, светильники — раз в 4 кадра. На iPhone 16 Pro в «Ночных улицах» — с 4,3–5,5 до 3,2–4,2 мс на кадр (около −25 %). UB_FPSLOG=1 теперь печатает, из чего состоит JS-кадр: игра + движок, three_native (и матрицы three), холсты.
Ускорение: первая волна
Движокна телефоне в браузере свечение и цветокоррекция (композер с MSAA 4×) включаются только если игра просит (bloom: true), пиксели 1,25×, карта теней обновляется через кадр и когда солнце шагнуло, экономная графика включается через секунду тормозов, а не через пять; мелкие предметы (< 0,6 м) не отбрасывают тень; статичные модели отсекаются за кадром.
Движокменьше работы процессора в кадре: поза объектов сравнивается числами (а не строкой на каждый объект), спящие в пачке объекты не пересчитываются у three, флаг вместо поиска по списку у ботов / подсказок / звуков / анимаций, без лишних массивов и векторов в видимости камеры и экранных координатах; фонарик в хорроре — расстояние до стены по коробкам раз в 3 кадра вместо луча по всем треугольникам мира.
«Ночные улицы»: миникарта рисуется из кэша (кварталы и дороги — один раз на клетку), а не 65 фигур под поворотом каждый кадр.
Плеер (ubrt): HUD-холст на телефоне 1,5× вместо 2×; повёрнутые прямоугольники без сглаживания (вдвое дешевле); drawImage без копии источника. Замер на Mac: «Ночные улицы» в игре — JS-время кадра −10 %, холст HUD −13 %.
Ядро:scripts/player-bench-page.mjs — страница игры с текущим движком для замера ubrt (как мерить — в docs/engine/player-audit-2026-10-22.md, §4.5).
Плеер: четвёртая волна после проверки
Движок (ubrt): у текстур появились мипмапы — повторяющаяся земля и дороги вдали больше не муарят и не мерцают (как в браузере); текстуры с краем (ClampToEdge — у three.js так по умолчанию) больше не повторяются по ошибке; canvas.toDataURL('image/png') отдаёт настоящую картинку — снимок игры для обложки и снимок карты из Плеера теперь приходят на сервер; на iPhone игры «Своей идеи» с touchstart / touchmove / touchend получают касания.
Плеер: третья волна после проверки
Плеер (iPhone): звук игры возвращается после звонка; «Поделиться» честно говорит оболочке, показалось ли окно; Android: библиотеки раскладываются атомарно и не одновременно.
Движок (ubrt):canvas.width = … того же размера очищает холст; removeAttribute('hidden') показывает элемент; setInterval держит ритм (пульт 50 мс шёл 66) и переживает исключение; clearTimeout в том же тике отменяет; AudioParam.value = x не стирает запланированные переходы; disconnect(узел) рвёт только эту связь; start(when, offset, duration); setAnimationLoop(null) останавливает; LOD показывает один уровень; картинки зданий (render в цель) видят холсты этого кадра; кривые индексы геометрии и слишком глубокий звуковой граф не роняют игру.
Плеер: вторая волна после проверки
Плеер (Windows / Linux): «Запустить в Плеере» из Студии больше не открывает второй плеер — ссылка уходит в уже открытый; рядом с игрой нашим движком не появляется чёрное консольное окно.
Плеер (iPhone): игра ставит кадры на паузу, когда плеер уходит в фон, при звонке и пока открыт лист «Комната» (раньше рисовала в скрытый слой, а iOS могла убить приложение); звук игры не глушит голос комнаты и уважает переключатель «без звука»; push-события идут через очередь (вылет при push в открытом плеере); нажатый push не «всплывает» заново через день при холодном старте; нет видеокарты или файла игры — сообщение, а не падение плеера.
Плеер (Android): поворот экрана и скрытие полос в release-сборке — методы защищены от R8.
Движок (ubrt):texture.dispose() освобождает холст / картинку в памяти и видеокарте (раньше ярлыки и плитки копились без предела); звуки сообщают onended (движок ждал !snd.playing вечно); игра, зовущая то, чего в плеере нет, уходит в браузерный с причиной api:<имя>, а new URL, TextEncoder, crypto, structuredClone, requestIdleCallback, Headers, Request, AbortController теперь есть; на iPhone аргументы вызовов защищены от сборщика JSC; воксельный мир другого размера не пишет в освобождённую память.
Плеер: проверка на всех системах, 16 критичных ошибок
Плеер (iPhone): если движок не запустился — чёрное окно не остаётся навсегда; закрытие игры не читает уже освобождённый вид; push «позвали в комнату» во время игры сначала закрывает её.
Движок (ubrt): ошибка проверки видеокарты пишется в журнал, а не роняет игру (на iPhone — весь плеер); потеря видеокарты — код 3 (игра откроется в браузерном); картинки и холсты больше предела видеокарты пропускаются; пустой зацикленный звук, шрифт 0px, надпись с тенью при переполнении кэша, arc() с огромным углом и пустой Float32Array больше не роняют игру; ошибка в кадре игры — код 2, а не «вышли сами».
Движок (ubrt):localStorage игры сохраняется между запусками (<игра>.store.json рядом со страницей; пишется раз в секунду и при выходе); performance.now() идёт внутри кадра (цикл по времени в коде игры больше не вешает плеер); игры с травой не уходят в браузерный запасной путь; geometry.dispose() общей геометрии не делает второй объект невидимым навсегда.
Студия для Windows
СтудияUpBilim Studio для Windows 10 / 11 — «Скачать для Windows» на studio.upbilim.com (установщик на русском и английском, без прав администратора; пока без подписи: «Подробнее» → «Выполнить в любом случае»).
Студия, Плеер: на Windows игра «через видеокарту» (ubrt) не запускалась — «нет файла …\\lib/studio/three…js (os error 123)»: путь к ресурсам в «длинной» форме \\?\ не терпит «/». Теперь путь обычный.
«Исправить» — своим ИИ
Студиякнопка «Исправить» у ошибки в Консоли отдаёт ошибку своему ИИ в терминале Студии (Claude Code, с ⌥ — Codex; выбор запоминается): ИИ уже идёт — задача ему текстом, нет — запускается с задачей. У своего ИИ весь проект — нет предела размера файлов, как у Bilimai (большие игры вроде Dust2 упирались в 300 000 знаков).
Игры из нескольких файлов снова собираются
Студияигра с import (Dust2 и другие из нескольких файлов) не запускалась: «WebAssembly.Module doesn't parse…» — сборщик в Студии загружался не тем файлом, и сбой оставался до перезапуска Студии. Теперь сборщик вшит в программу Студии и приходит отдельной командой (запасной путь — файл окна, проверка и до 3 попыток; при сбое в Консоли видно, что пришло). «Файлы игры» не строят превью для моделей больше 20 МБ (карта целиком).
Строительство, соединения, вода и пещеры, общие заготовки
Студиярежим «Размер» (R) у ящика, пандуса и зоны — ручки на каждой грани: тянешь грань — растёт одна сторона, противоположная стоит (как Resize в Roblox); с «Сеткой» — шагом 0,25 м.
Студиявыбрано несколько — «Свойства» → «Несколько»: выровнять по краю или середине (x, y, z); «Вырезать дыру» — выбранный последним ящик вырезает окно или дверь в стене (стена становится ящиками вокруг дыры, столкновения как у ящиков); «Сложить» — одна группа.
Студия«Свойства» → «Физика»: тело (стоит / падает и толкается / двигает игра), сиденье (машина, лодка, самолёт — E сесть), соединения: к миру — дверь (петля у края), петля, мотор, верёвка, пружина; между двумя — петля, шарнир, верёвка, пружина, мотор; ось петли и мотора. Соединения видны линиями.
Движоксцена: physics, vehicle у объекта и joints (hinge / ball / rope / spring / motor) — UB.loadScene ставит сам, lvl.joints; UB.joint(a, b, { type: 'motor', speed }) — петля, которая крутит сама, .setSpeed(n). Физика грузится сама, если она есть в сцене.
Студия«Добавить» → «Вода» (озеро на уровне, в нём плавают; рельеф ниже — котлован) и «Пещера» (туннель в скале).
ДвижокUB.cave3d({ x, y, z, w, h, d, rotY }) — пещера: стены и свод твёрдые, валуны снаружи и камни внутри; в сцене — kind: 'water' и kind: 'cave'.
Студияобщие заготовки (как Packages в Roblox): во вкладке заготовки — «Сделать общей» (копия с моделями в Документы/UpBilim/packages, версия +1); «Файлы игры» → «Общие» — добавить в любой проект, вышла новее — «Обновить до vN».
Студияредактор сцены больше не теряет поля файла сцены, которых не знает (посчитанный свет, base / over варианта, соединения).
Анимация персонажа
Студия«Анимация» (как Animation Editor в Roblox Studio) — своё движение персонажа по ключам: «Файлы игры» → «Анимация», справа суставы ползунками (голова, наклон, поворот, руки, локти, ноги, колени, вверх-вниз), подвинул — ключ в этом времени; снизу полоса времени, ключи тянутся мышью; пробел — смотреть; длина, «по кругу», человек / солдат / зверь. Файл anims/<имя>.anim.json.
Движокhero.play('<имя>') — своё движение из anims/ (по кругу) или разово { once: true }; UB.defineMove3d(имя, { length, loop, keys }) — то же из кода (суставы в градусах); работает и у зверей. В ролике ключ дорожки { t, play: 'wave' } — персонаж делает движение.
«Играть отсюда» на больших картах
Студияна большой карте (Dust2, тысячи объектов) список живых объектов приходил обрезанным — «Мир» показывал 0, а Студия падала при перерисовке вкладок и могла не запустить «Играть отсюда» (и «Играть») во второй раз. Теперь список читается целиком.
Свойства по разделам, превью моделей, ночные цвета
Студия«Свойства» по разделам, которые сворачиваются (Основное, Материал, Правки экземпляра, Свои свойства, Солнце и тени, Рельеф…; запоминается), и поиск по свойствам сверху.
Студия«Файлы игры» — у моделей 3D-превью; модель или заготовку можно перетащить мышью в окно сцены — встанет туда, где отпустили.
Студияновые цвета — ночное небо (тёмно-синий) и луна UpBilim; прежняя серая тема — «UpBilim Grey» в «Темах».
Студияснимки на studio.upbilim.com — новая Студия.
Студия — программа для игр
Студияновый вид, как в Unity и Roblox Studio, а не как у редактора кода. Сверху — «Играть» / «Остановить», окно через видеокарту, отладка, «Добавить», «Тестер», «Выпустить». Слева — «Мир» (вкладки «Мир» · «Файлы» · поиск · Git · мои игры). В центре — «Игра» (большое окно игры), сцены («Сцена valley») и код вкладками. Справа — «Свойства» (объекта сцены или живого объекта игры) и Bilimai. Внизу — «Файлы игры», Консоль, Терминал, Профайлер, Проблемы.
Студияпроект открывается сценой, а не кодом; «Играть» сразу показывает игру во весь центр, переключение на код и обратно игру не перезапускает.
Студия«Файлы игры» — модели, звуки (послушать), картинки (превью), сцены и заготовки карточками, фильтр и поиск; двойное нажатие на модель или заготовку — поставить в открытую сцену.
Студиянажатие на живой объект в «Мир» — его свойства справа (место, поворот, здоровье, видимость, твёрдость, цвет) и «Оставить в сцене».
«Мир»: игра и сцены одним деревом
Студиявкладка «Мир» на полосе слева (как Explorer в Roblox Studio): одно дерево — идущая игра (герой, объекты из сцены, части заготовок под своим экземпляром, объекты из кода по видам) и сцены проекта (объекты файлов по группам). Нажатие на живой объект — он обводится в игре и открывается в «Объектах»; на объект сцены — сцена открывается с ним; поиск по имени.
Студияправки в идущей игре (место, поворот, цвет, «Твёрдый» в окне «Объекты») — «Оставить в сцене»: переносятся в файл сцены и после остановки игры. Идёт только то, что поменяли руками (сдвиг — разницей: физика и код игры свои сдвиги не добавляют); часть заготовки двигает весь экземпляр, её цвет — правка экземпляра. Неперенесённые правки — точка на значке «Мир».
Движоку живых объектов для Студии — сцена, id объекта и экземпляр заготовки (UB.__live).
«Что нового» — не файл
Студиявкладка называется «Что нового» (а не CHANGELOG.md), только для чтения: без пути над текстом и без кнопки «Править».
«Что нового» без времени
Студиявкладка «Что нового» — по дням, как окно и сайт: дата одна, под ней записи дня, без времени.
«Что нового» вкладкой
Студияпосле обновления Студии «Что нового» открывается само вкладкой рядом с кодом при открытии проекта (один раз, как в VS Code); пункт «Справка» → «Что нового» — тоже вкладкой.
Материалы, краска рельефа, варианты заготовок, ролики
Студияу ящиков и фигур — раздел «Материал»: шероховатость, металл, непрозрачность, свечение, поверхность (асфальт, плитка, бетон) и готовые наборы (матовый, пластик, металл, стекло, неон).
Движокrough, metal, opacity, glow, tex у объектов сцены — в игре так же, как в редакторе.
Студиярельеф — «Краска» (трава, песок, земля, камень, снег кистью) и «Посадка» (деревья, ели, кусты, цветы, камни кистью, с разбросом).
Движоккраска рельефа (terrain.paint, свои цвета — terrain.paints) видна и на ровной земле.
Студия«Правки этого экземпляра» — свой цвет у копии заготовки; «Сделать вариантом» — новая заготовка на основе этой (base + over): поменяли основу — вариант меняется тоже.
Движокварианты заготовок (base, over по имени части или * для всех) и правки экземпляра (over) — до 4 уровней.
Студия«Ролик» в редакторе сцены — полоса времени под сценой: ключ камеры (где стоит камера сейчас), ключ объекта (выбранный, по имени), субтитры, звуки; ключи тянутся мышью, «Смотреть» — показ прямо в сцене; файл cutscenes/<имя>.cut.json.
ДвижокUB.cutscene('имя', { onEnd }) — ролик: камера и объекты по ключам, полосы кино, субтитры, звуки, игра стоит, Esc / пробел / касание — пропустить; UB.animate3d(объект, ключи, { loop, pingpong }) — объект по ключам (двери, лифты, патрули).
Студия«Что нового» — теперь и в меню «Справка».
Микшер, отладчик кадра, перевод игры
Студия«Микшер» (кнопка в панели «Игра») — громкость музыки, звуков игры и фона, «тише за стеной»; сразу в идущей игре, «Записать в код» — UB.mixer({…}).
Движокзвуки разошлись по группам: музыка, звуки игры, фон — UB.mixer({ music, sfx, ambience, occlude }); звук в мире за стеной тише; ключи настроек music и sfx (UB.settings.define) — ползунки игрока сами в микшер; UB.sound(файл, { bus: 'music' }).
Студия«Профайлер» → «Что рисуется» (отладчик кадра): самые тяжёлые объекты по треугольникам и частям (и склеенные в пачку), нажатие — объект обводится в игре; текстуры, модели и шейдеры в памяти; совет, если модель тяжёлая.
Студия«Перевод» (меню «Запуск») — таблица текстов игры ключ → ru / uz / en в i18n.json, «Перевести пустые» с языка проекта (сервер UpBilim); таблица уходит в игру и на сайт сама.
ДвижокUB.t('ключ', { n }) — текст на языке игрока (нет перевода — русский, нет ключа — ключ), UB.strings({…}) — таблица из кода.
Объекты игры, свои частицы, показ столкновений
Студия«Объекты» (кнопка в панели «Игра», меню «Запуск») — живое дерево идущей 3D-игры, как Hierarchy и Inspector в Unity: все объекты по группам, поиск, пауза мира, выбор — объект обводится в игре, правка на ходу: место, поворот, видимость, твёрдость, здоровье, цвет.
Студия«Редактор частиц» (меню рядом с «Редактором эффектов») — свой эффект с нуля: разовый или струйка, жизнь, размер и видимость в начале и в конце, цвета, свечение, форма точки, вылет (во все стороны, вверх, конусом, на месте), скорость, тяжесть, сопротивление, завихрение, покачивание; начала — от готовых (искры, огонь, дым, магия, взрыв, конфетти); живой просмотр; «Записать в код».
ДвижокUB.defineEffect3d('имя', {…}) — свой эффект частиц, потом UB.effect3d('имя', { x, y, z }); или сразу данными UB.effect3d({…}, { x, y, z }).
Студия«Показать» (кнопка в панели «Игра») — поверх идущей 3D-игры: каркасы столкновений (невидимые стены — розовым), где боты могут ходить, куда боты идут сейчас, лучи видимости (зелёный — видно, красный — закрыто).
Правая кнопка мыши — своя
Движокправая кнопка мыши больше не нажимает, как левая: раньше правый щелчок жал кнопки меню и стрелял (UB.pointer.down). Теперь у неё своё — UB.pointer.right (держат) и UB.pressed('mouseRight'): прицел, второе действие. Меню браузера по правому щелчку на игре не открывается.
Сочность, профайлер, проверка сети
Студия«Сочность» (молния в панели «Игра», меню «Запуск») — ползунки: тряска экрана, вспышки, частицы, замирание при победе над врагом, отдача и толчок; наборы «Выключить / Как есть / Сочно / Очень сочно». Меняется сразу в идущей игре, «Записать в код» — строка UB.juice({…}) в главном файле.
ДвижокUB.juice({ shake, flash, parts, stop, kick }) (0 — выключено, 1 — как есть, 2 — сильно) и UB.hitstop(мс) — игра замирает на миг (удар весомее).
Студиявкладка «Профайлер» в нижней панели — куда уходит время кадра: код игры (update, draw), рисование 3D, физика, бой, ходьба ботов, проверки видимости; мс и вызовы за кадр, полоски, советы, что сделать, и где это в коде (нажатие — к строке). Нужен включённый счётчик кадров.
Студияпроверка сети в «2–4 игроках» (меню «Запуск» → «Сеть в игре 2–4 игроков») — мобильная, плохая 3G, очень плохая (задержка и скачки, порядок сообщений как в настоящем соединении) и обрыв: игрок 2 выпадает на 6 с и возвращается.
«Телефон»: складной iPhone Duo
Студияв «Телефоне» панели «Игра» — iPhone Duo сложенный (466×678 точек) и раскрытый (626×890, с линией сгиба). Размеры — по обзорам (1398×2034 и 1878×2670 пикселей).
Окно «через видеокарту» снова большое
Студияигра через видеокарту открывается на месте панели «Игра», даже если панель была закрыта или открыта вкладка Bilimai (раньше окно было крошечным, 320×240 в углу). Панели нет совсем — окно 1280×720 по центру.
Свой «Телефон» в панели «Игра»
Студиякнопка «Телефон» в панели «Игра» — игра в рамке телефона: iPhone 16 Pro и Pro Max, iPhone SE, Android, iPad mini; лёжа или стоя; «остров» и поля, как в UpBilim Player на iPhone. Кнопки на экране как на телефоне, мышь — палец (вести по экрану — смотреть, по джойстику — идти). Выбор запоминается; выключить — «Без телефона» в том же меню. Работает и на Windows, Xcode не нужен.
Шутер на телефоне — как PUBG
ДвижокUB.gun3d на телефоне сам ставит управление шутера: джойстик — где коснулся левый палец, справа большая кнопка огня (держать — стрелять, вести пальцем по ней — целиться), слева над джойстиком — маленькая, прыжок, присед (нажал — сел, ещё раз — встал), перезарядка — значками. Свои кнопки игры (E и другие) — столбиком справа. В UpBilim Player на iPhone раньше не было кнопки огня вовсе. UB.gun3d({ touch: false }) — своё управление.
Из Dust2 в движок: лестницы, дым, слух, камера за спиной
ДвижокUB.goTo3d — боты ходят вверх и вниз по лестницам графа ходьбы (UB.navGraph): раньше бот вставал на высоту пола рядом, упирался в ступени и стоял. Посреди спуска путь находится снова.
ДвижокUB.goTo3d(bot, цель, скорость, dt, { smoke: true }) — бот ждёт перед дымом на пути и смотрит в него, как игрок.
ДвижокUB.sees3d(бот, враг) — видит ли: поле зрения, стены и дым, присевший прячется за низкой стенкой.
Движокшаги и слух — UB.steps3d (шаг из-под ног по пройденному пути, тихо — без шагов), UB.noise3d, UB.heard3d; выстрелы UB.gun3d слышно сами.
ДвижокUB.throw3d({ from, to }) — бросок в точку: скорость подбирается сама (боты бросают гранаты).
Движоккамера follow с behind: true — за спиной цели и поворачивается с ней (смотреть за напарником); стены под углом теперь тоже не пускают камеру за себя.
Движокстраховка героя UB.player3d: вошёл в стену — назад; есть пути ботов, а под ногами нет пола карты (провалился под карту) — назад на пол. guard: false — без неё.
ДвижокUB.hud.board — таблица счёта (держать Tab), UB.spotNear3d — свободное место рядом на том же этаже.
Режим чтения для .md
Студияфайлы .md (планы, заметки, AGENTS.md) открываются для чтения: заголовки, таблицы, списки, галочки, код, цитаты; длинные строки переносятся. Кнопка «Править» справа над текстом — в редактор, «Читать» — обратно. Ссылки на файлы проекта открывают их, ссылки на сайты — в браузере. Свой ИИ поменял файл — текст обновляется сам.
Окна версий и нового проекта
Студияокно «Игра на сайте» (версии) — шире: описание версии, метки и кнопки «Сравнить» / «Взять эту версию» больше не обрезаются справа.
Студия«Новый проект» — галочка «TypeScript» снова маленькая и не наезжает на кнопку «Создать».
Шаблоны PRO «с хорошим ощущением»
Студия«Новый проект» — три шаблона PRO с открытым кодом (не набор, всё видно и правится): «Шутер с ботами» (от первого лица, арена, волны роботов, автомат, здоровье понемногу возвращается), «Гонка в горах» (горная дорога, соперники разного цвета, отсчёт, места, R — обратно на дорогу), «Паркур (обби)» (трасса из строк, чекпоинты, монеты, секундомер, рекорд). В каждом — своё меню (Играть / Настройки / Управление), пауза на Esc, экран итогов «Ещё раз»; числа ощущения — в CONFIG в начале game.js (во время игры наведите на число — ползунок), надписи — в TEXT на языке проекта.
ДвижокUB.menu — Enter, пока стрелками ничего не выбрано, нажимает главный пункт («Играть», «Ещё раз», «Продолжить»). Раньше Enter работал только после стрелок.
ИИ ходит сам, звук легче, видео на странице игры
Студиямост для своего ИИ — walk x z (герой сам идёт пешком по путям ботов) и do "walk 12 -4; key Space; wait 1; shot door" (много шагов одной командой): меньше раздумий между шагами, герой движется плавно. В AGENTS.md: проверки — Тестером, вручную — только одно место.
ДвижокUB.__walkTo (только в Студии) — дойти пешком: от первого лица — взгляд на точку и W, камера сзади — нужные WASD.
Студия«Сжать игру» сжимает и звуки WAV (тот же формат и имя: реже частота, моно, без тишины в начале и конце) — обычно в 4–8 раз легче.
Студия«Выпустить» → «Видео игры»: запись «Записать видео» или свой файл (mp4 / webm, до 60 МБ) — над скриншотами на странице игры в Плеере.
ИИ играет в Студии, звук и видео
Студиясвой ИИ запускает node .upbilim/playtest.mjs — при открытой Студии играет её Тестер (окошко в углу, его можно развернуть и смотреть), а не невидимый Chrome; Студия закрыта или --chrome — как раньше, Chrome без окна (звук выключен).
Студияу Тестера кнопка «Звук» (включить / выключить на ходу, по умолчанию выключен) и «Записать видео» (каждый способ игры — свой файл). В панели «Игра» — «Записать видео» и для своей игры. Видео с картинкой и звуком — в «Фильмы / UpBilim Studio», сразу показывается в Finder.
Движокзапись видео игры в Студии — 3D, надписи поверх и звук (mp4, где умеет браузер, иначе webm; до 5 минут).
Студиябыстрая проверка check.mjs и макет maquette.mjs в Chrome без окна — без звука.
«Что нового» по дням; выпуск больших игр
Студия«Что нового» — по дням: одна дата, под ней все записи дня, без времени (и на studio.upbilim.com).
Студия«Выпустить» снова видит игру на сайте у больших игр (с несколькими версиями ответ сайта больше 10 МБ — Студия его не читала и писала «Ещё не в Плеере», номер 1.0); не вышло прочитать — так и пишет в окне. Запросы к сайту обрываются, только если сервер молчит 30 с.
Тестер: интересно ли играть
СтудияТестер не только ищет баги, но и говорит, интересно ли играть: через сколько секунд первое событие (очко, отметка, конец), где застревает (жмёт «вперёд», а герой стоит), как часто и как рано погибает, сколько карты обошёл, растут ли очки — с советами. То же — в .upbilim/playtest/report.md («Is it fun?») для своего ИИ и в node .upbilim/playtest.mjs.
Движокв режиме Тестера движок записывает события игры (UB.score, UB.finish, UB.mark); battle3d сам отмечает kill — герой победил врага.
Сжать игру
Студия«Файл → Сжать игру» (⌥⌘K): модели и картинки из assets/ легче — повторы и лишнее убраны, текстуры не больше 2048 / 1024 точек, непрозрачные PNG внутри моделей — JPEG; «Сильно» — ещё и вдвое меньше треугольников. Имена файлов и код игры те же. Исходники — в .upbilim/originals/ (не в Git и не в выпуск), «Вернуть исходники». Подсказка — в «Выпустить», если игра тяжелее 30 МБ.
Карта игроков и сравнение версий
Движок«Карта игроков» — движок сам запоминает, где герой проводит время (клетки 2×2 м), где погибает (battle3d), выигрывает, где кончил игру и вышел; UB.mark('вид') — своя отметка. Плеер и сайт отправляют это с сеансом; версия игры — в странице (__UB_VER).
Студиякнопка «Карта игроков» в панели «Игра» — цветные плитки прямо в мире идущей игры: где проводят время, погибают, бросают, выигрывают; по версиям.
Студиясравнение версий — в «Выпустить» галочка «Половине игроков»: новая версия идёт половине (B), остальные играют прежнюю (A). «Статистика» → «Сравнение версий»: сеансы, время, дошли до конца, бросили в первую минуту, смертей за сеанс; кнопки «Оставить новую» / «Вернуть старую».
3D по картинке на компьютере
Студиятретий генератор на компьютере — TripoSR (лицензия MIT, без токенов): 3D-модель по картинке, фон убирается сам, модель с цветами (GLB), без скелета. «Создать по описанию» → «Модель» → источник TripoSR → «Или по картинке». Около 6 ГБ, от 8 ГБ памяти; пока Mac (Apple Silicon) и Linux.
Звуки на компьютере
Студиявторой генератор на компьютере — Stable Audio 3 SFX (звуковые эффекты по описанию, модель small-sfx от Stability AI, обучена на лицензированных звуках; продавать игры можно при доходе до $1 млн в год). Модель закрытая — в окне три шага: принять условия на Hugging Face, создать токен, вставить (хранится в Связке ключей). Генераторы теперь бывают двух видов: сервер (ACE-Step) и «одна команда — один файл».
Генераторы на компьютере
Студияновый тип расширения «Генератор» — открытые модели на своём компьютере, бесплатно и без интернета после установки. В «Создать по описанию» — выбор источника: облако со своим ключом или генератор на компьютере. Первый — ACE-Step 1.5 (музыка, лицензия MIT, около 12 ГБ, от 8 ГБ памяти). Установка — одной кнопкой, ход виден в окне; Студия ставит только проверенные версии и запускает генератор только для этого компьютера (127.0.0.1), выключает при выходе. Нужны git и uv.
Создать по описанию
Студия«Файл → Создать по описанию» (⌥⌘G, и кнопка в Библиотеке): 3D-модель по описанию или по картинке (Tripo), звук и музыка по описанию (ElevenLabs) — своими ключами. Ключ хранится в Связке ключей компьютера (не в проекте), платишь сервису сам. Модель крутится прямо в окне, звук играет; «Ещё вариант» или «Взять» — файл в assets/ и вкладка со строкой кода для игры.
Живые числа
Студияпока игра идёт в Студии, числа в коде подчёркнуты пунктиром: наведи — ползунок, тяни — игра меняется сразу, без перезапуска; можно и просто перепечатать число. Число в коде тоже меняется (сохранить — ⌘S). Если игра берёт число один раз при запуске (например UB.player3d(hero, { speed: 7 })), Студия, когда отпустишь ползунок, сама перезапускает игру с того же места. Кнопка «Живые числа» в панели «Игра» — включить / выключить.
Git обновляется сам
Студиякоммит, git add или другая ветка снаружи (свой ИИ в терминале, другая программа) — «Контроль версий» и строка состояния обновляются сами, переключать вкладки не нужно. Чтение git (status, log) больше не переписывает .git/index.
Студияв терминале Shift+Enter и ⌥+Enter — новая строка в сообщении Claude Code / Codex (раньше сообщение сразу уходило), Enter — отправить.
Открепить «Игру»
Студиякнопка «Открепить» в панели «Игра» — игра идёт в отдельном окне (двигать, растягивать, на второй монитор); Консоль, ошибки со ссылками на строки, отладка, мост для ИИ (.upbilim/game.mjs), снимки, «Записать баг» и горячая перезагрузка работают как в панели. Мышь в игре держит это окно. Закрыли окно или «Вернуть сюда» — игра снова в панели.
Захват мыши в «Игре» Студии
Студияигра от первого лица в окне «Игра» снова захватывает мышь: курсор держит и прячет окно Студии (встроенный браузер Mac сам этого не умеет), Escape — отпустить. Как в Плеере.
Движокwindow.__UB_LOCKHOST — хозяин страницы держит курсор сам (сообщения ub:lock), как в Плеере на компьютере.
Редактор понимает код
Студиякак в VS Code — для .js и .ts проекта: наведение на функцию или переменную — её описание (подпись и комментарий над ней), F12 или ⌘-клик — к месту, где она написана (в любом файле), ⇧F12 — где используется (список в «Поиске»), F2 — переименовать везде (во всех файлах; ⌘Z отменяет в открытых). Ещё курсор — теперь ⌥-клик.
Студияошибки при наборе — красная волна под ошибкой (синтаксис; в .ts — и типы), вкладка «Проблемы» внизу со всеми ошибками проекта и их числом.
Картинка в терминал
СтудияCtrl+V или ⌘V в терминале, когда в буфере картинка (скриншот), — Студия сохраняет её во временный PNG и вписывает путь: Claude Code и Codex берут картинку.
Студияфайл, брошенный на терминал (скриншот, картинка), — его путь в строке терминала, как в Terminal на Mac: Claude Code и Codex подхватывают картинку. Раньше картинка молча копировалась в assets/ проекта.
Номер выпуска
Студияномер выпуска считается от версии, которая сейчас в Плеере: в Плеере 0.2.1 — предлагается 0.2.2 (кнопки «Исправление 0.2.2», «Обновление 0.3», «Большое обновление 1.0»). Номер неудавшегося выпуска (версия загрузилась, а в Плеер не попала) снова можно взять.
Мини-карта с планом и большая карта
ДвижокUB.hud.radar в 3D сам рисует план карты под точками — где можно ходить (по путям ботов UB.navGraph / UB.nav3d, выше — светлее; путей нет — твёрдые коробки), ты — жёлтая стрелка носом туда, куда смотришь.
Движокбольшая карта на весь экран встроена в радар: M или нажатие на радар (телефон) — открыть / закрыть; labels: [{ x, z, text }] — подписи (точки, базы), bigTitle — заголовок, bigKey: false — без неё. Отдельно — UB.hud.bigMap.
Проверка на компьютере и телефоне, загрузка больших игр
Студия«Выпустить» проверяет игру в браузере как на компьютере и как на телефоне: Тестер жмёт все кнопки меню и играет, потом играет на экране телефона (лёжа, с экранными кнопками) и смотрит, есть ли пульт. Ошибки (игра падает, чёрный экран, не запустилась, не загрузилась модель, провал под карту, на телефоне нет кнопок) — выпустить нельзя; замечания (мало кадров, игра больше 30 МБ, кнопка ничего не делает) — можно. Итог — строки «Компьютер / Телефон / Вес игры».
Студияу Тестера новый способ «Телефон» (node .upbilim/playtest.mjs --only phone).
Движоккамера «сзади» делает стены между собой и героем прозрачными; при смене на вид от первого лица (например, взял бота под управление) они снова целые — раньше оставались прозрачными.
Игры Студии Pro на сайте
Сайт: игра из UpBilim Studio на сайте (страница игры у автора, проверка перед публикацией) запускается с файлами из assets/ (карта, модели, звуки, картинки) и сразу со своим меню игры (UB.menu) — так же, как в Плеере.
Выпуск: страница игры и черновик описания
Студия«Выпустить» больше не останавливается на шаге «Страница игры» (скриншоты, перевод и статистика уходят на сайт).
Студияописание игры (все три языка и возраст) сохраняется в проекте сразу — после правки, «Заполнить с Claude» и «Перевести»; при следующем выпуске просить Claude заново не нужно.
Тесты движка
Движок19 сцен-проверок (герой у стен, ступени, пандус, стремянка, невидимые стены, взять / бросить, касания, дороги, боты, меню) — каждое изменение движка проверяется ими; найденный баг сначала становится сценой. Тесты запускаются на каждый коммит движка.
Взять и бросить, касания, дороги по рельефу, подсказки клавиш
ДвижокUB.grabbable(obj, { key, throwKey, weight, onGrab, onDrop, onThrow, onLand }) — взять (E), нести, поставить (E), бросить (F) по дуге; UB.held() — что в руках.
ДвижокUB.path3d(точки, { width }) — дорога сплайном по рельефу; road.carve(высота) для UB.terrain3d — ровная земля под дорогой; road.dist, road.at.
ДвижокUB.scatter — на рельеф, avoid (дороги), along (вдоль дороги), slope, minH / maxH; UB.grass3d — avoid, slope.
ДвижокUB.hud.hints([...]), UB.hud.key, UB.keyName, UB.padName — подсказки клавиш под устройство (клавиатура, геймпад A / B / X / Y, телефон); плашки UB.prompt3d показывают нужную кнопку сами.
Движокдлинная страница UB.menu / UB.pauseMenu («Управление») — клавиши в две колонки, «Назад» всегда на экране.
Проводник как в VS Code
Студияпустые папки видны; выбор нескольких (⌘ / ⇧ + щелчок, ⌘A); клавиши — стрелки, Enter, F2, ⌘⌫, ⌘C / ⌘X / ⌘V, ⌘D; перенос мышью (с ⌥ — копия); из Finder — любые файлы в папку под курсором; фильтр, «Обновить», «Свернуть всё»; файлы с ошибками — красным; размер при наведении; меню правой кнопки с клавишами.
Запись бага для ИИ, проверка без запуска, сцены и модели командами
Студия«Записать баг для ИИ» (флажок над игрой, ⇧⌘B) — нажатия с начала игры и зерно случайности в .upbilim/replays/; агент повторяет: node .upbilim/playtest.mjs --replay <файл>.
Студияnode .upbilim/lint.mjs — без запуска: несуществующие UB.*, сеть / DOM / localStorage, файлы и сцены, которых нет, битые сцены, плоские картинки в 3D.
Студияnode .upbilim/scene.mjs — сцены командами (find, add, set, move, copy, remove, env); node .upbilim/assets.mjs search бочка / add — модели CC0 из библиотеки (ru / uz / en).
СтудияТестер — способ «Стены» (прыжки у стен в разных местах карты) и сторож «Герой под картой».
Движокпотолок — только когда коробка над головой (касание боком — стена); соседняя плита больше не толкает героя в стену; UB.rand, UB.pick, UB.clamp, UB.shuffle и др. теперь есть в ub.d.ts (раньше редактор считал их ошибкой).
Карта проекта и мост к игре
Студия.upbilim/project.md — карта проекта после каждого изменения: код (и что не входит в игру), сцены (объекты по именам, точки, зоны, модели), файлы assets/ (размер, используется ли, сколько уйдёт в выпуск). Читать её до больших файлов.
Студияnode .upbilim/game.mjs — мост к игре, что идёт в Студии: status, run, eval, key KeyW 2, press Играть, goto x z, where, shot, log.
Тестер
Студия«Тестер» (⇧⌘T) — ИИ играет в игру способами «Меню», «Исследователь», «Клавиши игры», «Обезьяна», «Перезапуск», «Без рук», «Экраны» и ищет баги (ошибки, NaN, провалы, подбросы, застывший / чёрный экран, мало кадров, утечки, кнопки за краем). Режимы «Смотреть» и «В фоне». Отчёт — .upbilim/playtest/report.md, «Исправить с Claude Code / Codex». Агентам: node .upbilim/playtest.mjs [секунд] [--only …] [--seed …] [--show].
Движокгерой внутри большой коробки встаёт наверх (до 1,6 м) или возвращается назад, а не уезжает к её краю; склейка неподвижных объектов без предупреждений three.js.
Детали большой тестовой карты — в движок
ДвижокUB.spawn({ collider: true }) и коробки сцены «Collider» — невидимые стены (держат героя и ботов, закрывают выстрелы и вид); UB.ladder3d и зоны сцены «ladder …»; точки сцены «sound:<файл>» — звуки мест; UB.navGraph — пути ботов по готовому графу; UB.goTo3d — бот к цели (обход, «застрял»); UB.tracer3d — лучи выстрелов; красный край экрана при попадании в UB.battle3d.
Движокгероя больше не ставит на верх высокой стены, уходящей под пол.
Файлы игры в выпуске
Студия«Выпустить» собирает игру и сразу отправляет модели, звуки и картинки из assets/, которые игра упоминает (копия отправленного — .build/). Сервер проверяет каждый файл.
«Выпустить», статистика, «Мои игры»
Студия«Выпустить» (⇧⌘R) — проверка, сборка, загрузка, публикация; номера выпусков (1.0, 1.1), «Что нового», откат; страница игры на трёх языках, возраст, обложка и скриншоты; статистика (запуски, время, где бросают по сценам, ошибки игроков); вкладка «Мои игры» (⇧⌘M).
Свой интерфейс игр Студии Pro, макет сцены
Движокдетали своего интерфейса игры — UB.menu, UB.pauseMenu, UB.gui, UB.settings; у игр Студии Pro своё меню, без общей заставки.
Студияв редакторе сцены — «Макет» (вся карта сверху, как настольный макет) и «Снимок»; node .upbilim/maquette.mjs.
Bilimai, свет, «Ночной город», редактор сцены
СтудияBilimai справа, как чат в VS Code; «Посчитать свет» в редакторе сцены; режим «Глазами героя»; снимки Студии для сайта.
ДвижокUB.lights3d, UB.models3d, UB.grass3d, UB.chunks3d, UB.quality3d.tier; набор «Ночной город».
Общий мир в 2D
ДвижокUB.world2d — общий мир для 2D-игр: «вместе, у каждого свой экран»; «Битва героев» — вместе.
Общий мир в комнатах
Движокв 3D-играх «Своя идея» враги и предметы в комнате общие для всех игроков (UB.world).
«Битва баз»: 600 юнитов
Движоктолпа в 600 юнитов при 60 кадрах в секунду, строй по ролям, одна скорость группы.
Единый движок, первый шаг
Движокодин движок для браузера и Плеера: кубы, небо и туман выглядят одинаково; большие игры — прямо на видеокарте, без сервера игры.
Шутер от первого лица
Движокнабор «Арена» — шутер от первого лица (лазертаг), режимы «маяк», «Звёздная зона», «Захват флага»; ступени.
Пакет 3D-движка
Движок@upbilim/engine3d — общий 3D для всех игр UpBilim.
Сохранения, «Строй сам», игра с телефонов
Движокпрогресс игры между заходами; жанр «Приключение»; «Строй сам» — игрок ставит платформы, герой бежит по ним; обби и гонку проходят вместе с телефонов — сетевой код даёт движок.
Персонаж из кубиков
Движоквместо капсулы — персонаж из кубиков во всех играх, «Мой персонаж»; Bilimai сама пользуется новыми деталями движка.
Общие кубы
Движок@upbilim/blocks — 75 готовых кубов с текстурами для всех игр (миры из кубов в одну отрисовку); ускорение на слабых телефонах.