Последние несколько лет я специализируюсь на разработке 3D-конфигураторов разной сложности, используя стэк Three.js, R3F и различные WebGL-библиотеки. С PlayCanvas вплотную я не сталкивался, но все изменилось пару месяцев назад, когда мне пришлось зайти в проект именно на этом движке.

Более того, работать предстояло не в одиночку, а в команде, состоящей как из разработчиков, так и из 3D-артистов. И здесь мы моментально уперлись в главную проблему — синхронизацию изменений. Встроенный редак��ор PlayCanvas оказался совершенно не приспособлен к одновременной работе нескольких человек в реальном времени.

Мы столкнулись с классическим «code hell»: код перезатирался другими разработчиками, конфликты превращали файлы в кашу, а любые правки геометрии или настроек сцены, сделанные артистами, иногда непредсказуемо влияли на сохранение скриптов. Работать в таких условиях было, мягко говоря, сложно.

Увидев этот процесс изнутри, я сразу задумался об оптимизации. Мне критически не хватало привычного флоу: контроля версий через GitHub, возможности работать в ветках и, самое главное, писать код в любимом IDE (VS Code/Zed), а не в браузере.

Главная загвоздка заключалась в архитектуре: как писать код локально, изолированно от других, но запускать проект с актуальными 3D-данными (модели, материалы, настройки сцены), которые лежат в облаке PlayCanvas? Обдумав детали, я пришел к гибридному решению, которое, как мне кажется, кардинально меняет опыт разработки под PlayCanvas.

О том, как это реализовано, я и расскажу в этой статье.

Суть решения: Local Bridge

Моя идея заключалась в том, чтобы разделить ответственность. PlayCanvas отлично справляется с хранением ассетов и сборкой сцены, но код должен жить там, где ему место — в Git-репозитории.

Я реализовал систему, которую назвал "Local Bridge".

Флоу работает следующим образом:

  1. Код игры хранится в отдельном Git-репозитории и клонируется на компьютер разработчика.

  2. Локальный сервер на Node.js раздает эти файлы прямо с компьютера разработчика через HTTPS.

  3. В самом 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. Логика следующая:

  1. Скрипт проверяет наличие ?local=true в URL.

  2. Если режим локальный — он скачивает карту файлов с нашего локального сервера.

  3. При запросе скрипта движком, он подменяет URL на локальный.

  4. Если режим обычный (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.

Итог

В результате внедрения этого подхода мы получили:

  1. DX (Developer Experience): Работа в любимой IDE, линтинг, Copilot и весь комфорт локальной разработки.

  2. Безопасность: Код версионируется. Любое изменение можно откатить.

  3. Параллельная работа: Артисты двигают кубики в редакторе, программисты пишут код в VS Code. Никто никому не мешает.

Если вы тоже страдаете от "браузерной разработки" в PlayCanvas, рекомендую попробовать этот метод.

? Связь со мной и Мои Ресурсы

Спасибо, что дочитали до конца! Надеюсь, этот гайд поможет вам и вашей команде выстроить «здоровый» процесс разработки в PlayCanvas, забыть о конфликтах при сохранении и наконец-то писать код с удовольствием в любимой IDE.

Если у вас есть идеи по улучшению Local Bridge или вопросы по настройке пайплайна — пишите в комментариях или заходите в мой Telegram-канал.

Подписывайтесь на мои ресурсы:
Telegram
Github

pproger@pproger.me

Комментарии (0)