Фронтенд и статика
Где выложить браузерную игру: HTML5, Phaser, Godot или Unity WebGL
Коротко
Браузерную игру выкладывают как статический сайт: в корне папки лежит index.html, рядом — скрипты, файлы .wasm и ресурсы, и всё это раздаётся по ссылке с HTTPS. Игру на чистом HTML5 или Phaser достаточно загрузить готовой папкой, а у Godot и Unity есть по одной настройке экспорта, от которой зависит, запустится ли игра на обычном хостинге: потоки в Godot и сжатие в Unity. В Netrun такая игра публикуется загрузкой архива, и для неё подходит бесплатный тариф: сайт без посетителей засыпает и просыпается сам, когда игру открывают.
- Начиная с Godot 4.3 веб-экспорт по умолчанию однопоточный и запускается без заголовков Cross-Origin-Opener-Policy и Cross-Origin-Embedder-Policy.
- Экспорт Godot с включённой опцией Thread Support работает только на сервере, который отдаёт заголовки Cross-Origin-Opener-Policy и Cross-Origin-Embedder-Policy.
- Сжатая сборка Unity WebGL (файлы .br или .gz) требует от сервера заголовка Content-Encoding, а без него запускается только с включённой опцией Decompression Fallback.
- Игры на Godot и Unity WebGL не запускаются, если открыть index.html прямо с диска: им нужна загрузка через веб-сервер.
- Мультиплеер в реальном времени не работает на одной статике: соединения игроков держит отдельный сервер.
Игра собрана, в редакторе всё бегает, и хочется отправить друзьям ссылку, а не архив с инструкцией. Хорошая новость: браузерная игра для хостинга — это обычный статический сайт. Главная страница index.html, рядом скрипты, файл WebAssembly с движком и ресурсы игры. Сервер ничего не вычисляет, он только отдаёт файлы, а играет уже браузер игрока.
Подвохов два, и оба в настройках экспорта. Godot в многопоточном режиме требует от сервера особых заголовков, а Unity по умолчанию сжимает файлы так, что без правильной настройки сервера игра не распакуется. Ниже — как собрать игру так, чтобы она запустилась на обычном хостинге, и что делать, если нужен мультиплеер. Если сайт на HTML для вас пока в новинку, начните с инструкции про статический сайт.
| Движок | Что загрузить | На что обратить внимание |
|---|---|---|
| HTML5 и Canvas без сборки | Папку с index.html, скриптами, картинками и звуками | Пути к файлам относительные, регистр букв в именах совпадает с тем, что написано в коде |
| Phaser со сборщиком (Vite, webpack) | Содержимое папки сборки после npm run build, обычно dist | Загружайте собранную папку, а не исходники; index.html должен лежать в её корне |
| Godot 4.3 и новее | index.html, файлы .js, .wasm, .pck и картинки из папки экспорта | Опция Thread Support выключена — тогда особые заголовки сервера не нужны |
| Godot 4.0–4.2 | Те же файлы экспорта | Нужны заголовки COOP и COEP; проще пересобрать игру в 4.3 или новее |
| Unity WebGL | index.html, папки Build и TemplateData | Compression Format: Disabled или включённая опция Decompression Fallback |
| Мультиплеер на любом движке | Клиент — как статику, сервер — отдельным проектом | Сервер слушает адрес 0.0.0.0 и порт из переменной PORT |
Соберите веб-версию игры#
Игру на чистом HTML5 собирать не нужно: это уже готовая папка с index.html. Если проект на Phaser создан из шаблона со сборщиком, выполните npm run build и берите папку сборки, обычно dist, а не исходники. В Godot экспортируйте проект через пресет Web и назовите файл index.html, в Unity выберите платформу Web (WebGL) и соберите проект в отдельную папку. Перед загрузкой не пытайтесь открыть index.html двойным щелчком: Godot и Unity с диска не стартуют, им нужен веб-сервер.
Проверьте, что index.html лежит в корне#
Хостинг открывает index.html из корня загруженной папки, поэтому он не должен прятаться во вложенной папке вроде game или build. Пути к картинкам, звукам и скриптам должны быть относительными, без адресов вашего диска. На серверах регистр букв в именах файлов важен: Hero.png и hero.png — разные файлы, и то, что работало на Windows, на сервере может не найтись. Проверьте имена в коде и в папке ещё раз.
Выключите потоки в Godot#
Начиная с Godot 4.3 веб-экспорт по умолчанию собирается без потоков, и такой игре не нужны никакие особые заголовки сервера. Если в пресете Web включена опция Thread Support, игре нужны заголовки Cross-Origin-Opener-Policy и Cross-Origin-Embedder-Policy, без них она останавливается с ошибкой про SharedArrayBuffer. Для большинства игр проще всего выключить Thread Support и пересобрать. Если потоки действительно нужны, есть два пути: опция Progressive Web App с включённым Ensure Cross Origin Isolation Headers, которая добавляет заголовки через служебный скрипт, или свой Dockerfile с nginx, который отдаёт эти заголовки сам.
Настройте сжатие в Unity#
Unity по умолчанию сжимает файлы сборки в Brotli или Gzip, и сервер обязан отдавать их с заголовком Content-Encoding. Netrun раздаёт статику как есть и такой заголовок к файлам .br и .gz не добавляет, поэтому в Player Settings, в разделе Publishing Settings, выберите Compression Format: Disabled или включите Decompression Fallback. Первый вариант даёт файлы крупнее, второй распаковывает их скриптом в браузере, и загрузка идёт чуть медленнее. Если важен каждый мегабайт, раздавайте сборку своим Dockerfile с nginx и правильными заголовками.
Загрузите игру и откройте ссылку#
Запакуйте папку с игрой в ZIP или загрузите её целиком: Netrun распознает статический сайт и выдаст ссылку с HTTPS. Откройте игру на компьютере и на телефоне, а если экран остаётся чёрным, загляните в консоль браузера — там обычно прямо написано, какой файл не нашёлся. У загрузки есть ограничение по размеру, актуальное видно при загрузке; тяжёлые игры на Unity лучше собирать без лишних ресурсов. На бесплатном тарифе игра засыпает без игроков, и первое открытие после сна занимает несколько секунд.
Вынесите мультиплеер и рекорды на сервер#
Пока игра идёт целиком в браузере, ей хватает статики. Как только нужны общая комната, чат игроков или таблица рекордов, понадобится сервер: он держит соединения и хранит результаты. Такой сервер публикуется отдельным проектом, слушает адрес 0.0.0.0 и порт из переменной PORT, а результаты хранит в папке /data, которая переживает обновление кода. Для игры, в которую играют постоянно, нужен тариф Pro, чтобы сервер работал круглосуточно.
Браузерная игра без сервера — самый простой проект, который вообще можно выложить: собрали веб-версию, проверили настройку потоков в Godot или сжатия в Unity, загрузили папку и получили ссылку. Если игре нужна аудитория, честно посмотрите и на itch.io: это каталог игр с игроками, бесплатной публикацией HTML5 и галочкой для поддержки SharedArrayBuffer. Своя ссылка нужна, когда игра живёт отдельно от каталога: портфолио, свой домен, игра для мероприятия или собственный сервер для мультиплеера. В Netrun статическая игра работает на бесплатном тарифе, а свой домен и сервер без сна — на Pro. Попробовать Netrun.
Частые вопросы
Можно ли выложить браузерную игру бесплатно?
Да, если игра целиком работает в браузере. Для хостинга это статический сайт, а сайт на бесплатном тарифе Netrun живёт сколько угодно: без игроков он засыпает и просыпается, когда игру открывают. Платить понадобится, если нужен свой домен, сервер для мультиплеера или игра без паузы на пробуждение.
Почему игра на Godot пишет про SharedArrayBuffer или Cross-Origin Isolation?
Так ведёт себя экспорт с включённой опцией Thread Support: многопоточной сборке нужны заголовки Cross-Origin-Opener-Policy и Cross-Origin-Embedder-Policy, а обычный хостинг их не отдаёт. Выключите Thread Support в пресете Web и пересоберите игру — в Godot 4.3 и новее однопоточная сборка работает без особых заголовков. В Godot 4.0–4.2 однопоточного веб-экспорта нет, поэтому лучше обновить движок.
Что делать, если Unity-игра пишет Unable to parse и ругается на Content-Encoding?
Это значит, что сборка сжата в Brotli или Gzip, а сервер отдаёт файлы без заголовка Content-Encoding. В Player Settings, в разделе Publishing Settings, выберите Compression Format: Disabled или включите Decompression Fallback и пересоберите игру. После повторной загрузки она запустится.
Чем своя ссылка лучше, чем itch.io?
Не лучше и не хуже, это разные задачи. На itch.io есть игроки, комментарии и витрина, и для инди-игры это сильный аргумент. Своя ссылка нужна, когда игра живёт отдельно: в портфолио, на своём домене, вместе с собственным сервером для мультиплеера или таблицы рекордов. Многие делают и то и другое.
Можно ли сделать мультиплеер, если игра — статический сайт?
Только с отдельным сервером. Статика лишь отдаёт файлы игры, а обмен ходами между игроками идёт через сервер, который держит соединения, обычно по WebSocket. Такой сервер публикуется вторым проектом и должен работать постоянно, поэтому для него нужен тариф Pro.
Почему игра долго грузится в первый раз?
Причин обычно две. Сборки Godot и Unity весят десятки мегабайт, и браузер скачивает их целиком перед запуском. А на бесплатном тарифе сайт без посетителей засыпает, и первое открытие после сна занимает ещё несколько секунд. Помогают сборка без лишних ресурсов и тариф Pro, на котором сайт не засыпает.
Как выложить сайт в интернет?
Загрузите код сайта ZIP-архивом или из GitHub — Netrun соберёт его и выдаст рабочую ссылку с HTTPS. Подойдёт статический сайт (HTML, CSS, JS), приложение на React или сайт на Python. Покупать домен, настраивать сервер и сертификаты не нужно.
Почему мой сайт иногда засыпает?
На бесплатном тарифе сайты засыпают после простоя и просыпаются за пару секунд при первом запросе. На тарифе Pro проект работает без сна.
Есть ли ограничение на размер проекта?
Да, у загрузки есть ограничение по размеру. Для больших проектов может понадобиться платный тариф, актуальный лимит виден в кабинете при загрузке.