Нативный движок для игр и приложений в одном TypeScript-проекте

3D на Filament, физика Jolt и Box2D, скелетная анимация с IK, навмеш, частицы, ландшафт, 2D-движок и AR — всё в рантайме на C++, а не в браузерной обёртке. Один бандл запускается на телефонах, компьютерах, в VR-шлеме и в вебе.

iOSAndroidQuestWindowsLinuxmacOSWeb
7платформ из одного бандла
3графических API: Metal, Vulkan, OpenGL
~6 МБприложение с 3D и физикой
<1 скомпиляция всего проекта
Рендеринг

3D-рендеринг на Filament.

PBR-материалы и освещение

Metallic-roughness материалы, окружение IBL из KTX, солнце с тенями, скайбокс, туман по высоте, bloom и тонмаппинг — ACES, filmic или neutral. Статику уровня lecodes lightmap запекает в лайтмапы, динамика живёт поверх в реальном времени.

Свои шейдеры

Материалы .mat на языке Filament компилируются локально командой lecodes shaders и подхватываются Material.load на всех целях. Обновил движок — lecodes shaders update перекомпилировал всё за тебя.

Большие миры

Ландшафт, растительность, инстансинг для тысяч одинаковых объектов, декали, система частиц с лентами и mesh-частицами, шум для процедурного контента. Всё это — классы SDK, а не плагины со стороны.

Физика и персонажи

Jolt, анимация и навигация.

Физика Jolt

Тела и формы, триггеры, события контактов, рейкасты и зонд земли, рэгдоллы, контроллер персонажа поверх CharacterVirtual и машины с колёсами. Одна и та же симуляция на всех хостах, включая headless-прогон — физика в тесте настоящая, а не заглушка.

Скелетная анимация

Клипы, слои и смешивание, IK, root motion, локомоция, постановка ног на неровности и динамические кости для хвостов и плащей. Модели из Mixamo, Unity и Unreal переносятся конвейером ассетов, включая ретаргет на другой скелет.

Навигация, ввод и звук

Навмеш на Recast/Detour: lecodes navmesh запекает, агенты ходят по нему в рантайме. Один Input для клавиатуры, мыши, тача и геймпада — кнопка геймпада это просто клавиша. Позиционный звук: источники и зоны, привязанные к узлам сцены.

2D

Отдельный 2D-движок для игр.

Спрайты и анимация

Спрайты, спрайт-листы и покадровая анимация, слои с сортировкой по Y для псевдо-3D, своя камера с зумом и слежением. Клик или тап по сцене отдаёт объект, в который попал.

Тайловые карты

Тайлмапы и тайлсеты с автотайлингом: рисуешь область — движок сам подбирает края и углы. Карта — такой же узел сцены, как и всё остальное.

Физика Box2D

Тела, формы, триггеры, контроллер 2D-персонажа и односторонние платформы для платформеров. Столкновения приходят событиями на узел. Узлы, аспекты и игровой цикл устроены так же, как в 3D.

Вокруг движка

AR, интерфейс и проверяемость.

AR

ARScene — та же сцена, только с якорями в реальном мире: модель ставится на стол или привязывается к картинке, жесты управления добавляются одной строкой. Работает в приложении le.codes на iOS и Android.

Интерфейс поверх сцены

HUD, меню и экраны — на flexbox-раскладке Yoga в том же файле, что и сцена. Сигналы обновляют текст без перерисовки, списки виртуализированы нативно. Второй проект для интерфейса не нужен.

Детерминированное время

В headless-прогоне setLoop, физика и аспекты идут фиксированным шагом 1/60 от сценария, а не от часов: тест, прошедший однажды, проходит всегда. Упавший шаг сохраняет JSON и PNG кадра — красный шаг объясняет себя сам.

Как это выглядит в коде

Сцена, свет, тени, физика и управление — один файл. Ни импортов, ни node_modules: весь SDK доступен как глобалы, а в бандл попадает только то, на что проект ссылается. Поведение узла — Aspect, логика всей сцены — System; никаких пустых узлов с циклом и рукописных tick(), а имя аксессора выводит компилятор: Aspect<'health', …> становится node.health.

TypeScript
const scene = new Scene({ skybox: '#202030', bloom: true })

const ground = Mesh.plane({ material: Material.lit({ color: '#333' }), normal: [0, 1, 0], scale: 20 })
  .aspect(Shape, { box: [10, 0.1, 10] })
  .aspect(Physics, { motion: 'static' })

const crate = Mesh.box({ material: Material.lit({ color: '#e33' }), position: [0, 4, 0] })
  .aspect(Shape, {})                       // форма подбирается по мешу
  .aspect(Physics, { mass: 2 })            // динамическое тело по умолчанию

crate.addEventListener('enter', other => console.log('удар:', other.name))

scene.add(Light.sun({ shadowsQuality: 2 }), ground, crate)
scene.camera.position = [0, 3, 6]
scene.open()

setLoop(() => {
  if (Input.key('Space')) crate.physics.applyImpulse([0, 6, 0])
})

2D-сцена — тем же языком:

TypeScript
const scene = new Scene2D({ background: '#10131a' })
scene.layer(1).ySort()                       // слой 1 сортируется по Y

const load = async () => {
  const tex = await Texture2D.load(asset('./hero.png'))
  scene.add(new Sprite({ texture: tex, anchor: [0.5, 1], layer: 1 }))
}
load()

scene.addEventListener('click', ev => {
  console.log('тап по', ev.target?.id ?? 'пустому месту', ev.worldX, ev.worldY)
})
scene.open()

Оба примера собираются командой lecodes compile меньше чем за секунду в один app.js, который одинаково исполняется на всех платформах.

Что вокруг движка

Инструменты

Сцена, ассеты и тесты — в терминале и в редакторе, без сторонних программ.

scene.3d

Редактор сцен

Вкладка «3D-сцена» в редакторе и `lecodes scene` локально: дерево, инспектор, гизмо, материалы. Правки пишутся прямо в `.scene.ts`, а правки из IDE подхватываются на лету — редактор и код не спорят, кто главный.

ui.editor

Конвейер ассетов

FBX → GLB с текстурами внутри, `doctor` для GLB (лимит костей, KTX2, масштаб), ретаргет анимаций с другого скелета — в том числе Mixamo, `.anim` из Unity и чтение `.uasset` из Unreal. Всё это — `lecodes assets`.

build.ts

Headless-рендер и тесты

`lecodes render` и `lecodes test` гоняют настоящий бандл с настоящей физикой без устройства и браузера. 3D в headless приходит как JSON, за пикселями — `--desktop` через нативный хост.

Модули отключаемые — не подключил 3D, и он не попал в бандл. Приложение без сцены весит около 2 МБ, с 3D и физикой — около 6.

Как устроен

Движок — это набор нативных библиотек на C++, к которым JavaScript-код приложения обращается через узкий мост. Скрипты исполняет QuickJS, а раскладку, отрисовку, физику и анимацию делает натив — поэтому 60 кадров в секунду не зависят от скорости JS.

ПодсистемаБиблиотекаЧто делает
3D-рендерFilamentPBR, IBL, тени, bloom, лайтмапы, KTX2
3D-физикаJoltтела, персонажи, машины, рэгдоллы, события
Анимацияcreator-animклипы, слои, IK, root motion, динамические кости
Частицыcreator-particlesэмиттеры, кривые, ленты, mesh-частицы
НавигацияRecast / Detourнавмеш и агенты
2Dsokol + Box2Dспрайты, тайлмапы, 2D-физика
ИнтерфейсYogaflexbox-раскладка, отрисовка хостом

Компилятор chisel на Rust собирает проект в один app.js и вырезает всё неиспользуемое вплоть до отдельных методов классов. Заголовок бандла говорит хосту, какие движки поднимать: приложение без 3D не грузит Filament вообще. Подробное инженерное описание — на странице Состав и архитектура.

Платформы и графические API

ПлатформаГрафикаХост
iOS, macOSMetalSwift, одна кодовая база на оба
AndroidOpenGL ESKotlin + нативное ядро; отдельная сборка для Quest под OpenXR
Windows, Linux, Astra LinuxVulkan или OpenGLC++ хост, один процесс, ~11 МБ на диске
WebWebGL 2полный хост на wasm или лёгкий на ~31 КБ без wasm
HeadlessBun: настоящая физика, 3D как JSON — для тестов и ИИ-агентов

Честно о границах: AR работает только в приложении, не в вебе; лёгкий веб-хост не умеет 2D; headless не растеризует 3D. Новые возможности движка — анимация v2, 2D-физика, машины, ландшафт, лайтмапы — появляются сначала на десктопе и затем доходят до мобильных хостов; паритет платформ проверяется автоматической матрицей по каждому члену API.

Что дальше

  • Мультиплеер. Сетевой слой на yojimbo (UDP) уже собран вместе с ядром репликации; идёт работа над остальными фазами. Цели — десктоп, Android и iOS: в вебе UDP нет по построению.
  • Редактор 2D-сцен и трек 2D-игр в документации.
  • Видео. Обзор движка появится на этой странице.

Ассистент платформы знает движок по той же документации, что и вы: он пишет сцены, физику и аспекты этим же API и видит результат своего кода через headless-рендер. Но движок не требует ассистента — это обычный TypeScript в вашей папке, и lecodes compile собирает его без сервера и аккаунта.

Попробуй движок прямо сейчас

Редактор, движок и сборка бесплатные. Подпишитесь на наш Telegram и введите промокод tg_sub26 при первом пополнении: скидка 50% и 2 500 кредитов в подарок.

Открыть редактор
Сотрудничество

Обсудим ваш проект.

Игра, приложение с 3D, встраивание движка в свой продукт или вопрос по возможностям — напишите, и мы ответим на указанный email.

Защищено Яндекс SmartCaptcha. Отправляя форму, вы соглашаетесь на обработку данных.