2

Обход кэширования игр, сделанных на Construct 3

Добрый день!

Меня зовут Руслан.
С 2016 года делаю игры в редакторе Construct 3 (раньше он назывался Construct 2), преимущественно без использования "настоящего" кода.

Что-то в последнее время у меня загорелось начать где-то сохранять свой опыт работы с этим редактором. И пока идут праздники, решил попробовать.

В этом посте описан мой способ обновлять игры, сделанные на Construct 3.

Сегодня китайская нейросеть сподобилась выдать работающую версию скрипта для автоматического обновления игры. Хочу поделиться результатом.

Суть проблемы:

Браузеры любят всё кэшировать. Они распихивают себе по кармашкам (в кэш) все скрипты игры, картинки, звуки и прочее, из чего состоит игра.

В итоге, когда мы заливаем на сервер новую версию, то может произойти вот что.

1. Игрок, который раньше уже играл в эту игру, запускает её у себя в браузере,

2. Браузер показывает ему устаревшую версию, загруженную из кэша, а не с сервера. Вроде как это снижает нагрузку на сервер, но в итоге игрок не увидит обновление.

Как это решается теперь в наших проектах:

1. Чтобы понять, новая это версия или старая, я стараюсь всегда выводить на экран номер версии, где-нибудь в нижнем углу, бледненько, но читаемо.

Как я указываю версию проекта на экране игры.

Как я указываю версию проекта на экране игры.

При старте каждого экрана в это текст вывожу номер версии из системной переменной projectversion.

Вывод версии на старте каждого экрана.

Вывод версии на старте каждого экрана.

Иначе можно бесконечно чинить баги, не понимая, это старая версия загружена или просто новая сломалась.

2. Добавляю в проект группу с группами, в которой происходит обработка автоматического обновления.

Список групп для обработки Обновления игры.

Список групп для обработки Обновления игры.

Немного ниже покажу содержимое этих групп подробнее.

3. Создаю отдельный слой update, на котором располагаю одноцветный фон, вращающуюся иконку загрузки, кнопку обновления и текст с оповещением, что найдена новая версия.

Так это выглядит в игре.

Так это выглядит в игре.

Фон растягиваю на весь экран.

4. Прозрачность слоя update привязываю к прозрачности иконки на этом слое. Иконке заданы поведения Rotate и Tween, что позволяет ей бесконечно крутиться и плавно менять прозрачность.

То есть, теперь можно управлять прозрачностью слоя, задавая прозрачность иконки.

На старте каждого экрана делаю иконку и фон полностью прозрачными, чтобы они не появились раньше времени.

Действия на старте экрана и привязка прозрачности слоя Обновления к иконке.

Действия на старте экрана и привязка прозрачности слоя Обновления к иконке.

5. Далее, используем плагин Browser. Когда он сигнализирует, что нашёл обновление - включаем окно (точнее сказать - слой) Обновления.

Действия при обнаружении Обновления и включение окна (слоя) Обновления.

Действия при обнаружении Обновления и включение окна (слоя) Обновления.

Важный момент. Как Браузер понимает, что есть новая версия игры?

По номеру версии!

Поэтому стараемся не забывать обновлять этот номер в поле Version (в главных настройках проекта в самом верху.

Где указывается номер текущей версии проекта.

Где указывается номер текущей версии проекта.

Для удобства, я нумерую версии текущей датой и примерным временем сохранения проекта.

6. Параллельно с включением окна (слоя) Обновления у меня блокируются все активные игровые слои, чтобы игрок не ускакал случайно на другой экран.

Также включаю вращение иконки (Rotate, до включения слоя она не вращается, чтобы не тратить системные ресурсы).

И затем с помощью Tween плавно делаю иконку, а за ней и весь слой непрозрачным, чтобы игрок увидел предупреждение о новой версии, которая в данный момент загружается.

Здесь иконка вращается посредством поведения Rotate.

Здесь иконка вращается посредством поведения Rotate.

7. Когда обновление наконец загрузилось (определяем это с помощью того же плагина Browser), проверяем, если иконка Обновления ещё не включалась (может случиться и такое), то включаем её и показываем поверх кнопку "Обновить".

Обработка обнаруженной новой версии.

Обработка обнаруженной новой версии.

Включение кнопки Обновить.

Включение кнопки Обновить.

Если же экран обновления уже включен, то просто включаем кнопку, чтобы игрок мог сам нажать её в удобный для него момент.

Также меняем текст на новый.

Включаем кнопку, которая закрывает собой иконку и меняем текст.

Включаем кнопку, которая закрывает собой иконку и меняем текст.

8. И наконец последнее - обработка нажатия кнопки.

Обработка нажатия кнопки Обновить.

Обработка нажатия кнопки Обновить.

Тут всплыла та самая закавыка со скриптом, из-за которой пришлось напрягать китайскую нейросеть.

В браузерах Chrome, Opera, Yandex - в целом всё работает нормально и без скрипта. Когда кнопка нажата - страница просто обновляется с помощью Browser - Reload и всё ок - грузится новая версия.

Но Firefox решил выпендриться и в нём эта конструкция уходит в бесконечную перезагрузку: Грузится старая версия и снова появляется окно Обновления, пока игрок не догадается нажать Shift-F5, чтобы вручную загрузить самую новую версию.

if ('serviceWorker' in navigator) {

navigator.serviceWorker.getRegistrations().then(function(registrations) {

// 1. Удаляем все сервис-воркеры

for (let registration of registrations) {

registration.unregister();

}

// 2. Очищаем кеш (если доступно)

if ('caches' in window) {

caches.keys().then(function(cacheNames) {

cacheNames.forEach(function(cacheName) {

caches.delete(cacheName);

});

});

}

// 3. Задержка 500 мс + жесткая перезагрузка

setTimeout(() => {

window.location.reload(); // Или window.location.href = window.location.href;

}, 1000);

});

} else {

// Просто перезагружаем, если сервис-воркеров нет

window.location.reload();

}

Поэтому здесь пришлось прикрутить вышеупомянутый JS-скрипт, сгенерированный нейросетью с 20-й попытки.

Переменную browserName пришлось завести вручную, чтобы определять, в каком браузере запущена игра.

Узнаём что за браузер у игрока.

Узнаём что за браузер у игрока.

var userAgent = navigator.userAgent;

if (userAgent.indexOf("Chrome") > -1) {

runtime.globalVars.browserName = "Chrome";

} else if (userAgent.indexOf("Firefox") > -1) {

runtime.globalVars.browserName = "Firefox";

} else if (userAgent.indexOf("Safari") > -1) {

runtime.globalVars.browserName = "Safari";

} else if (userAgent.indexOf("Edge") > -1) {

runtime.globalVars.browserName = "Edge";

} else if (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident") > -1) {

runtime.globalVars.browserName = "Internet Explorer";

} else {

runtime.globalVars.browserName = "Unknown";

}

// Теперь вы можете использовать переменную browserName в вашем проекте

console.log("Browser: " + runtime.globalVars.browserName);

Соответственно, для Firefox используем чудо-скрипт на JS, а в остальных браузерах, стандартный Browser - Reload.

У меня этот способ сработал. Возможно в каких-то ещё браузерах тоже нужно обрабатывать нажатие кнопки с помощью скрипта.


P.S. В следующих постах планирую выкладывать другие нюансы работы в Construct 3, которые применяю в своей работе.

P.P.S. Для более надёжного хранения завёл также телеграм-канал Игрушечный программист: https://t.me/toyprogrammer

0
Автор поста оценил этот комментарий
DeepSeek не пробовал, пробовал ЧатГпт и МашаГпт. Попробую DeepSeek, спасибо за совет👍
раскрыть ветку (1)
1
Автор поста оценил этот комментарий
На здоровье :)
Скорее всего DeepSeek не лучше чем последний ChatGPT.
Но определённо лучше бесплатной версии 3.5.
И не так сильно цензурирован, как наш GigaChat.
0
Автор поста оценил этот комментарий
Верно, нейросетка пока не может что-то нормально советовать по C3. Плюсую за полезный пост)
раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо!
На самом деле, кое-что может. Довольно часто советуюсь с DeepSeek когда не хочется копать документацию. Он конечно больше предлагает решения в формате JavaScript, но некоторые моменты по C3 всё же подсказывает, где что искать в событиях или настройках.
Полезная штука.

показать ответы
0
Автор поста оценил этот комментарий

Самому не стремно быть настолько не понимающим что нужно использовать нейросетевой чат для написания подобного скрипта?

Вот таким "рукоделов" нейросети постепенно заменят полностью, к счастью. Останутся только программисты/архитекторы.

Успехов в освоении чего-то полезного и накоплении багажа знаний, а не набора костылей.

Иллюстрация к комментарию
раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Привет!
Поясни пожалуйста свою мысль.
Те 2 скрипта, которые вставлены в проект написаны нейросетью - всё верно.
Остальной "код" - мой.
Насколько я знаю, нейросеть пока не может напрямую написать события для Construct 3.

показать ответы
0
Автор поста оценил этот комментарий

Нет никакого смысла спрашивать у нейросправочника подобное. Оно "врет" обо всем и всегда, кто-то подумал что отличная идея назвать это галлюцинациями. Никаким ответам нельзя доверять, лишь информация для обозрения.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Хорошо :)

Главное, чтобы полезные ответы выдавал, которые работают на практике

0
Автор поста оценил этот комментарий

"Общение со стеной или книгой в некоторых учреждениях считается патологией".

Зачем разговаривать с нейросправочником?:))

Решать конкретные задачи могут все нейросети, количество токенов напрямую не влияет, это же не chatgpt, тут все разбито на мелкие сетки.

Обратите внимание на количество разных моделей в qwen, для "общения" там подходят не все, как и для написания кода. Универсальной серебряной пули не будет.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Хм... Ок :)

Ради интереса спросил обе модели друг про друга: "Ты лучше или хуже, чем он?"

Если вкратце, то Qwen сам говорит, что он лучше работает с китайским и английским.

"- Я сам могу быть лучше в китайскоязычном сценарии, но уступать другим в других языках или специализированных задачах."

Мне кстати тоже показалось, что "анекдоты" которые он сочиняет имеют больше английский формат из серии "тук-тук, кто там?".

DeepSeek говорит:

"- Русский язык – Моя тренировка включала глубокую оптимизацию под русскоязычные запросы (но Qwen3 тоже неплох)."

Соглашусь с ним - его ответы более "русские" на мой взгляд.

Но не исключаю, что в задачах на кодирование он будет и послабее. Буду пробовать обе модели.

показать ответы
1
Автор поста оценил этот комментарий

Qwen при нормальном запросе пишет удивительно рабочий код, но в 1 запросе не получится получить сразу проект, надо разбить на несколько задач. В конце каждого запроса дописывать "без объяснения, но с комментариями в коде и разметкой для автоматической генерации документации с помощью doxygen", экономит токены, а значит больше пойдёт на "решение задачи". Как пример.


Если нужно объяснение - на последнем этапе можно запросить, будет точнее.


Если в базе нейроспрпвочника нет ваших языков программирования или скриптового языка, вы всегда можете загрузить пример и на основе него "попросить", "сделай по аналогии".

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Спасибо, поставил себе ради интереса.

Правда он похоже немного проигрывает DeepSeek в плане количества токенов:
32k у Qwen против 128k у DeepSeek.

И пока DeepSeek в диалоге показался мне более интересным собеседником.
Но, возможно это просто вкусовщина :)

показать ответы
1
Автор поста оценил этот комментарий

Меня зовут Руслан с 2016 года. А до этого как звали? Наташа? 😁

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Там точка после имени :)
Но ок.
Добавил перенос строки для понятности :)

показать ответы