Последние несколько лет я специализируюсь на разработке 3D-конфигураторов разной сложности, используя стэк Three.js, R3F и различные WebGL-библиотеки. С PlayCanvas вплотную я не сталкивался, но все изменилось пару месяцев назад, когда мне пришлось зайти в проект именно на этом движке.
Более того, работать предстояло не в одиночку, а в команде, состоящей как из разработчиков, так и из 3D-артистов. И здесь мы моментально уперлись в главную проблему — синхронизацию изменений. Встроенный редак��ор PlayCanvas оказался совершенно не приспособлен к одновременной работе нескольких человек в реальном времени.
Мы столкнулись с классическим «code hell»: код перезатирался другими разработчиками, конфликты превращали файлы в кашу, а любые правки геометрии или настроек сцены, сделанные артистами, иногда непредсказуемо влияли на сохранение скриптов. Работать в таких условиях было, мягко говоря, сложно.
Увидев этот процесс изнутри, я сразу задумался об оптимизации. Мне критически не хватало привычного флоу: контроля версий через GitHub, возможности работать в ветках и, самое главное, писать код в любимом IDE (VS Code/Zed), а не в браузере.
Главная загвоздка заключалась в архитектуре: как писать код локально, изолированно от других, но запускать проект с актуальными 3D-данными (модели, материалы, настройки сцены), которые лежат в облаке PlayCanvas? Обдумав детали, я пришел к гибридному решению, которое, как мне кажется, кардинально меняет опыт разработки под PlayCanvas.
О том, как это реализовано, я и расскажу в этой статье.
Суть решения: Local Bridge
Моя идея заключалась в том, чтобы разделить ответственность. PlayCanvas отлично справляется с хранением ассетов и сборкой сцены, но код должен жить там, где ему место — в Git-репозитории.
Я реализовал систему, которую назвал "Local Bridge".
Флоу работает следующим образом:
Код игры хранится в отдельном Git-репозитории и клонируется на компьютер разработчика.
Локальный сервер на Node.js раздает эти файлы прямо с компьютера разработчика через HTTPS.
-
В самом PlayCanvas работает специальный скрипт-перехватчик (Dev Hook), который "смотрит" на URL запуска.
Если мы запускаем игру с параметром
?local=true, перехватчик заставляет движок грузить скрипты не из облака, а с вашегоlocalhost.Если параметра нет (продакшен или тест артистов), игра грузит файлы как обычно из облака PlayCanvas.
Таким образом, я могу писать сложную логику в VS Code, нажимать Ctrl+S, и сразу видеть результат в браузере, при этом работая с актуальной сценой, которую параллельно может править 3D-артист.
Вот диаграмма архитектуры:

Техническая реализация
Для реализации этой схемы потребовалось решить три задачи: HTTPS на локалке, перехват загрузки в движке и CI/CD для деплоя.
1. Локальный сервер и HTTPS
PlayCanvas работает только по HTTPS, поэтому просто поднять http://localhost:3000 недостаточно — браузер заблокирует смешанный контент. Я использовал утилиту mkcert для генерации локально доверенных SSL-сертификатов и написал простой сервер на Express, который отдает файлы из папки src и генерирует JSON карту файлов (file-map).
Ссылка на репозиторий с сервером и инструкцией по установке: playcanvas-local-bridge
2. Monkey Patching и Dev Hook
Самое интересное происходит внутри PlayCanvas. Я написал скрипт dev-hook.js, который в проекте нужно поставить первым в порядк�� загрузки (Loading Order).
Он делает "Monkey Patching" стандартного метода pc.Asset.prototype.getFileUrl. Логика следующая:
Скрипт проверяет наличие
?local=trueв URL.Если режим локальный — он скачивает карту файлов с нашего локального сервера.
При запросе скрипта движком, он подменяет URL на локальный.
Если режим обычный (Production) — он работает как "Bootstrap Loader", принудительно загружая скрипты, у которых мы в редакторе сняли галочку "Preload".
3. Синхронизация и Deploy (CI/CD)
Конечно, локальная разработка — это хорошо, но код должен попадать обратно в PlayCanvas, чтобы его видели остальные члены команды.
Здесь на помощь приходит GitHub Actions и утилита playcanvas-sync. Я настроил пайплайн, который при пуше в mainжестко синхронизирует файлы. Ва��ный момент: мы используем переменную PLAYCANVAS_FORCE_REG, чтобы решить проблему с глубокой вложенностью файлов, когда стандартная проверка изменений иногда дает сбой.
Конфиг Action
name: Sync to PlayCanvas
on:
push:
branches: [ "main" ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install Tool
run: npm install -g playcanvas-sync
- name: Push to PlayCanvas
env:
PLAYCANVAS_API_KEY: ${{ secrets.PC_API_KEY }}
PLAYCANVAS_PROJECT_ID: ${{ secrets.PC_PROJECT_ID }}
PLAYCANVAS_BRANCH_ID: ${{ secrets.PC_BRANCH_ID }}
PLAYCANVAS_TARGET_DIR: "."
PLAYCANVAS_INCLUDE_REG: "Scripts/.*"
PLAYCANVAS_FORCE_REG: "^Scripts\\/.*"
PLAYCANVAS_BAD_FILE_REG: "^\\.|~$|jsconfig|pcconfig|\\.yml$"
PLAYCANVAS_BAD_FOLDER_REG: "^\\.|node_modules"
PLAYCANVAS_VERBOSE: 1
run: |
echo "? Checking diff..."
pcsync diffAll
echo "? Pushing..."
# Auto-confirm overwrites
pcsync pushAll --yes
Таким образом, GitHub становится источником правды. Мы больше не боимся, что кто-то случайно удалит кусок кода в онлайн-редакторе — при следующем пуше все восстановится из Git.
Итог
В результате внедрения этого подхода мы получили:
DX (Developer Experience): Работа в любимой IDE, линтинг, Copilot и весь комфорт локальной разработки.
Безопасность: Код версионируется. Любое изменение можно откатить.
Параллельная работа: Артисты двигают кубики в редакторе, программисты пишут код в VS Code. Никто никому не мешает.
Если вы тоже страдаете от "браузерной разработки" в PlayCanvas, рекомендую попробовать этот метод.
? Связь со мной и Мои Ресурсы
Спасибо, что дочитали до конца! Надеюсь, этот гайд поможет вам и вашей команде выстроить «здоровый» процесс разработки в PlayCanvas, забыть о конфликтах при сохранении и наконец-то писать код с удовольствием в любимой IDE.
Если у вас есть идеи по улучшению Local Bridge или вопросы по настройке пайплайна — пишите в комментариях или заходите в мой Telegram-канал.