Сейчас мы будем заниматься шрексом. Знакомство с Godot через разработку раннера для... Яндекс Игр
Прости меня Шрек, ибо я согрешил и сделал про тебя раннер для Яндекс Игр. Делюсь впечатлениями о Godot, рассказываю как я докатился до жизни такой и как подружить Godot c HTML5 и Яндекс SDK.
Мне всегда хотелось собрать для себя джентльменский набор инструментов для разработки игр. Unreal Engine прекрасно подходит для карьеры и крутых, красивых и сложных проектов. Но совершенно не подходит для 2D и маленьких проектов для души, которые запустятся на любом ведре.
Я уже имел опыт с Unity и учитывая недавние действия их эффективных менеджеров - возвращаться к нему не было никакого желания, да и по требованиям он пролетает мимо (огромный проприетарный комбайн с закрытым исходным кодом в две тысячи то двадцать четвертом году)
Godot же давно был у меня на примете, и вот я решил сделать на нем проект, который можно будет конвертировать в какой-нибудь профит (лулзы - тоже профит) и заодно привыкнуть к движку.
Яндекс игры? Ходим по дну геймдева.
Я хотел подучить Godot, и для учебы нужен какой-нибудь проект. На dtf в последнее время много статей про Яндекс Игры и я посмотрел, что это такое. Открыл сайт, словил двести баннеров с рекламой (которые смогли обойти ДВА моих adblocker'а), кринжанул, закрыл и забыл.
Но перед этим я приметил, что на сайте видимо модерация пропускает вообще все что угодно и на авторские права всем по боку.
Наверняка это всё игры по лицензии от Dream Works, правда?
После этого где-то недельку в моей голове медленно прели следующие мысли:
У тебя куча готовых ассетов от Shrek 2 Remake, сделай c ними что-нибудь на Godot
Игра может быть и не пройдет модерацию на сайте, но зато получишь опыт работы на Godot
А если пройдет, то заработаешь целых 0.69 рублей и репутацию долбаеба
Спустя время я созрел, переступил через моральные принципы и приступил к работе.
У нас есть идея и желание. Но нет знаний о Godot. С чего начать?
Я уже опытный разработчик и мне хватило курса молодого бойца состоящего из двух уроков от Brackeys. Чувак легендарно вернулся после трех летнего перерыва и принес два шикарных видоса про Godot - вот они:
Первое знакомство с Godot
Основы GDScript
Качаем Godot последней версии (это ошибка для Web игры, о чем будет далее), удивляемся что он весит всего лишь около 100 мб (привет Unreal Engine собранный из исходников весом в 200 гб), запускаем и начинаем творить!
Первые шаги
Сначала я поковырял движок, привык к интерфейсу, пощупал GDScript, который оказался Python-like и мне как человеку хорошо знакомым с Python не пришлось привыкать к GDScript.
На контрасте с Unreal Engine - Godot ощущается как молоток с гвоздями - в хорошем смысле.
Он дает тебе все что нужно от игрового движка, без множества готовых оберток и компонентов, поэтому даже базовые вещи приходиться делать с нуля. Для меня это кристаллизованный кайф, потому что я люблю изобретать велосипеды.
Все что нужно в Unreal Engine для реализации простейшего передвижения персонажа и прыжка.
Что нужно Godot для перемещения и прыжка
В принципе, если вы уже знакомы с несколькими движками и с Python, то Godot и GDScript осваивается очень быстро. У него прекрасная документация не брезгующая примерами и подробным описанием функций.
Накидал это на следующий день после знакомства с Godot
Godot и HTML5
Перед тем, как приступать к чему-то серьезному, нужно понять как Godot работает с HTML 5.
Для начала читаем в документации, что Godot версии 4.x плохо подходит для Web игр, а на IOS и Mac так вообще не запускается, поэтому рекомендуется использовать версию 3.x. Я работал на четвертой версии Godot - пришлось качать версию 3.5.3 и работать с ней.
Первая неделя
За первую неделю я заложил всю базу для раннера. Сделал рандомную генерацию бесконечных уровней. Игра последовательно спавнит вручную созданные уровни, на которых раставленны точки спавна рандомных препятствий в перемешку с фиксированными препятствиями.
Пример уровня
С таким подходом имея даже небольшое количество уровней можно добиться неплохой реиграбельности.
Результат первой недели. Можно видеть большое количество растительности, которую выпилил в дальнейшем из-за проблем с производительностью.
Фиксим прыжок
Как сделать так, чтобы при разной скорости движения персонажа, длина его прыжка оставалась неизменной? Если не решить эту проблему, то все выверенные прыжки и расстояния, работающие в начале игры - сломаются в конце, когда скорость персонажа увеличивается почти на 45%.
export var MaxJumpHeight = 2.1
export var JumpDistance = 0.4
var JumpImpulse = 0
var Gravity = 0
func _ready():
JumpImpulse = 4 * MaxJumpHeight / JumpDistance
Gravity = 0.5 / MaxJumpHeight
func _physics_process(delta):
if IsJump:
Velocity.y -= pow((JumpImpulse * Global.SpeedAlpha), 2) * Gravity * delta
else:
Velocity.y = -9.8
Впадаем в депрессию
После экспорта проекта в Web я залил его в черновик на Яндекс Игры и протестировал на 4 мобильных устройствах, на двух из которых были артефакты графики. Выпускать игру, которая в выборке из четырех устройств не работает на двух из них - плохая идея.
Я же вроде не хоррор начинал делать
На решение проблемы я убил часов 8 и уже начал сомневаться что решу проблему. В интернете было НОЛЬ информации. Видимо потому, что я один из первых извращенцев делающих на Godot что-то в 3D для Web.
РЕШЕНИЕ ПРОБЛЕМЫ. ЭКСЛЮЗИВНЫЙ КОНТЕНТ ДЛЯ ДАУН ТУ ФАК.
Как это всегда и бывает - дело оказалось в трех галочках. Заходим в Project Settings\Rendering\Quality и выставляем галочки как на картинке.
После выставления этих галочек артефакты начали появляться и на ПК, то есть я уравнял все устройства - игра перестала работать везде. Осталось сделать наоборот.
Я заметил, что артефакты проявляются только у мешей, которые имеют Skeleton. Обычные Mesh Instance отображаются без проблем. На рандоме я тыкнул в эту галочку и все проблемы решились.
Эту галочку надо снимать для всех мешей у который есть Skeleton, все остальные меши можно не трогать.
Кстати, если не отображаются текстуры на некоторых устройствах - попробуйте потыкать эту галочку в настройках экспорта.
С чувством великой удовлетворенности своим успехом продолжаем работу.
Оптимизируем
С тем уровнем графики на который я замахнулся игра шла на моем трехлетнем китайце за 8 000 в 20 FPS. Больше всего жрет растительность, поэтому от нее пришлось отказаться и оставить только большие и красивые кусты с маленьким количество полигонов.
Ландшафт вручную сделан в Blender из малого количества полигонов. Полигоны которые не видит игрок я тоже на всякий случай выпилил.
Тоже самое касается и всех остальных мешей - полигоны, которые не видит игрок просто вырезаны.
Простите
Во время игры одновременно живут только четыре уровня с препятствиями - предыдущий удаляется на середине следующего и в конец добавляется новый уровень. В моей случае постоянная выгрузка и загрузка уровней не сажает FPS.
Но все эти труды сливаются в никуда, если яндекс захочет врубить в Sticky-баннере анимированную рекламу, которая роняет FPS до не играбельного состояния. Можно конечно его вырубить в консоли разработчика, но от него вроде бы капает больше всего дохода.
Да и в принципе делать 3D игру на Godot для HTML5 с таргетом на мобильные устройства - плохая идея. Лично я не доволен тому, как игра работает на мобильных устройствах, но поделать с этим ничего не могу. Разве что вырезать все текстуры и вместо моделей использовать абстракции.
Изначально я назвал игру "Бегущий Шрек", но такая игра уже есть на Яндекс играх. Сделана она на Unity.
UI
Моих художественных способностей недостаточно, чтобы нарисовать какой либо красивый UI и иконки, поэтому на помощь приходят бесплатные ассеты, которые я взял с itch.io
Чтобы UI нормально растягивался и работал с разными разрешениями экрана нужно проставить следующие параметры в Godot
UI будет растягивать исходя из разрешения выставленного здесь. Если проставить например 1280 на 720, то на Full HD мониторах все иконки будут зашакалены.
В этой же вкладке листаем в самый низ и настраиваем Stretch.
Выполняем требования Яндекс игр
Выделить стоит следующие требования:
Должен быть интегрирован Яндекс SDK.
Игра должна быть локализована на выбранные языки.
При сворачивании страницы с игрой на десктопных и мобильных устройствах звук прекращает воспроизводиться.
При отображении полноэкранного банера с рекламой и видео рекламы звук игры должен выключаться и игра должна ставиться на паузу.
Интегрируем Yandex SDK
Вообще для этого уже есть готовые плагины, но это выбор для слабых духом, слабоумные же пишут все сами.
На самом деле все просто, но с нюансами. Godot дает возможность вставить что угодно в HTML Head и вызывать от туда JS код.
JS Код вставляется сюда в настройках экспорта проекта.
Получаем доступ к window, а из него доступ ко всем объявленным в Header переменным и функциям:
var window = JavaScript.get_interface("window")
func _ready():
window.initSDK()
func ShowAdvBanner():
window.showAdvBanner()
HTML Header при этом должен выглядеть примерно так:
<!-- Yandex Games SDK -->
<script src="https://yandex.ru/games/sdk/v2"/>
<script>
ysdk = null;
function initSDK(params) {)
YaGames.init(params)
.then((_sdk) => {
ysdk = _sdk;
})
.catch(console.error);
}
function showAdvBanner(){
ysdk.adv.showFullscreenAdv()
}
</script>
Чтобы получить Callback из JS функции - создаем его в GDScript:
var OnLoadDataCallback = JavaScript.create_callback(self, "OnLoadData")
var window = JavaScript.get_interface("window")
func _ready():
window.onLoadDataCallback = OnLoadDataCallback
# ВНИМАНИЕ Всегда добавляете аргумент args,
даже если не собираетесь передавать никаких аргументов
иначе функция не вызовется.
Проверенно опытным путем убитых 40 минут в стиле А ПАЧЕМУ НИРАБОТАЕТ
func OnLoadData(args):
pass
JS:
<script>
onLoadDataCallback = null;
fuction foo() {
// Вызовит функции в Godot
onLoadDataCallback()
}
</script>
Кстати, для того, чтобы передать массив в JS нужно сначала его конвертировать в JS Array. Я об этом не знал и не мог понять, почему не сохраняются купленные скины.
var array = ["1", "2", "3"]
var jsArray = JavaScript.create_object("Array")
for item in array:
jsArray.push(item)
window.foo(jsArray )
Выключаем звук при сворачивании игры и показе рекламы
Для понимания, что игрок свернул или развернул игру я использовал следующий код вставленный в HTML Header :
func TabActivated(args):
var MasterIndex = AudioServer.get_bus_index("Master")
AudioServer.set_bus_mute(MasterIndex, false)
func TabDeactivated(args):
var MasterIndex = AudioServer.get_bus_index("Master")
AudioServer.set_bus_mute(MasterIndex, true)
Такой же подход используется для выключения звука при показе рекламы.
Локализация
Я просто следовал документации Godot по добавлению локализации в игру. У меня она занимает один *.csv файлик с 11 строками данных.
Чтобы получить текущий язык, нужно использовать переменную из SDK ysdk.environment.i18n.lang
Весь код на стороне игры для локализации примерно такой:
// Для be, kk, uk и uz яндекс рекомендует включать русский язык.
var LangReferences = {
"be": "ru",
"kk": "ru",
"uk": "ru",
"uz": "ru",
"ru": "ru",
}
func OnSDKInit(args):
var locale = LangReferences.get(window.ysdk.environment.i18n.lang, 'en')
TranslationServer.set_locale(locale)
Скины?
В игре есть монетки, которые надо на что-то тратить. Нормальные люди делают скины на персонажей и продают усилители. Но это в нормальных играх, а у нас тут раннер про Шрека для Яндекс Игр, поэтому в мою альтернативно одаренную голову пришла идея продавать скины для... сортира.
Скин с клоуном можно получить за просмотр рекламы.
Вдохновляемся скинами из CS GO и клепаем следующий кринж. Хотели сортир в стиле скина "Азимов"? Я тоже нет, а он теперь есть и обществу придется с этим жить. Несмотря на всю кринжовость и лоск "How Do You Do, Fellow Kids" наклепал 15 скинов и некоторые мне даже нравятся.
Прохождение модерации
Перед прохождением модерации пришлось подключаться к РСЯ (рекламная сеть яндекса) и заполнять бумажки. Делается все легко, учитывая, что самозанятость у меня уже открыта. На следующие сутки мой аккаунт прошел проверку и офферта была ацептована.
Тем не менее в консоли разработчика на вкладке "Панель управления" по прежнему горела красная ошибка о том, что монетизация не подключена, при этом я сделал все согласно их документации. Видимо это баг яндекса - но данная ошибка исчезает если один раз отправить игру на модерацию.
Вместе с "Игра не опубликована" висело предупреждение, что "Монетизация не подключена"
Я до последнего момента не был уверен что игра пройдет модерацию, потому что я не знаю примера успешной публикации 3D игры на Godot на Яндекс игры. Могло оказаться, что игра не работает в каком либо браузере или производительность игры окажется критичной и мне откажут.
Начало клаун фиесты
Отправив игру на модерацию я ждал, что она затянется на 3-5 дней, но уже на следующий день мне пришел отказ в публикации. Модератор нашел несколько проблем:
Ошибки в переводе. Я забыл перевести магазин. На скриншотах для ру региона магазин тоже был с английским текстом.
Неправильный показ рекламы. Я показывал ее в момент проигрыша, что по мнению модерации прерывает игровой процесс. Поэтому я перенес показ рекламы при выходе в главное меню.
С одной стороны я обрадовался, что игра оказалась вроде бы как рабочей и серьезных проблем не нашли.
Но с другой стороны я до сих пор не понимал как работает модерация. Что если они провели поверхностное исследование и при следующей отправке на модерацию они уже перейдут к следующим этапам и окажется что Godot не годен для Яндекс игр?
Исправив проблемы я отправил игру на повторную модерацию.
Дубль два
Опасения оказались верны, модерация не проверяет всю игру сразу, а видимо находит первые попавшиеся проблемы, отказывает и дальше игру не смотрит. В этот раз проблемы нашли следующие:
Гифка для промо материалов имеет артефакты сжатия.
В описании игры на русском языке (которое я сгенерировал нейронкой 🤡) имеются ошибки пунктуации и орфографии. Там действительно было поломано целое предложение и окончания у слов.
При показе рекламного баннера не выключается звук. Я упустил это из-за того, что перенес показ рекламы с момента смерти на выход в меню.
Почему на первые две проблемы не указали при прошлой проверке - для меня не понятно.
Конечно это не отменяет того факта, что я невнимательное быдло, которые пытается запостить игру с очевидными ошибками.
Публикация
Не смотря на все, но с третьей попытки игру все таки опубликовали. Если среди комунити DTF есть такие же извращенцы как и я, то смело можете пытаться делать 3D игру на Godot для Яндекс игр.
Я уверен, что будут жалобы на производительность игры (и не только), поэтому я сомневаюсь, что стоит рекомендовать Godot для 3D HTML5 игр, но для 2D это отличный на мой взгляд выбор.
Тем не менее - мне есть чем гордиться - я засрал Яндекс игры очередной безыдейной кривой говно-подделкой паразитирующей на чужой интеллектуальной собственности и сделанной за месяц на коленке в после-рабочее время.
Чтобы получить Callback из JS функции - создаем его в GDScript:
"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"var OnLoadDataCallback = JavaScript.create_callback(self, \"OnLoadData\")\nvar window = JavaScript.get_interface(\"window\")\n\nfunc _ready():\n window.onLoadDataCallback = OnLoadDataCallback\n\n# ВНИМАНИЕ Всегда добавляете аргумент args,\nдаже если не собираетесь передавать никаких аргументов\nиначе функция не вызовется.\nПроверенно опытным путем убитых 40 минут в стиле А ПАЧЕМУ НИРАБОТАЕТ\nfunc OnLoadData(args):\n pass","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Кстати, для того, чтобы передать массив в JS нужно сначала его конвертировать в JS Array. Я об этом не знал и не мог понять, почему не сохраняются купленные скины.
"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"var array = [\"1\", \"2\", \"3\"]\nvar jsArray = JavaScript.create_object(\"Array\")\nfor item in array:\n\tjsArray.push(item)\nwindow.foo(jsArray )","lang":""}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Выключаем звук при сворачивании игры и показе рекламы"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Для понимания, что игрок свернул или развернул игру я использовал следующий код вставленный в HTML Header :
Весь код на стороне игры для локализации примерно такой:
"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"// Для be, kk, uk и uz яндекс рекомендует включать русский язык.\nvar LangReferences = {\n\t\"be\": \"ru\",\n\t\"kk\": \"ru\",\n\t\"uk\": \"ru\",\n\t\"uz\": \"ru\",\n\t\"ru\": \"ru\",\n}\n\nfunc OnSDKInit(args):\n\tvar locale = LangReferences.get(window.ysdk.environment.i18n.lang, 'en')\n\tTranslationServer.set_locale(locale)","lang":""}},{"type":"delimiter","cover":false,"hidden":false,"anchor":"","data":{"type":"default"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Скины?"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
В игре есть монетки, которые надо на что-то тратить. Нормальные люди делают скины на персонажей и продают усилители. Но это в нормальных играх, а у нас тут раннер про Шрека для Яндекс Игр, поэтому в мою альтернативно одаренную голову пришла идея продавать скины для... сортира.
"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"Скин с клоуном можно получить за просмотр рекламы.","image":{"type":"image","data":{"uuid":"bad745ef-1bba-5f52-a417-fe65e144898d","width":1080,"height":1920,"size":447066,"type":"png","color":"404041","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAdgB2AAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAABgf/xAAjEAACAgEDAwUAAAAAAAAAAAABAgMEBQARISIxQgYSExVR/8QAFgEBAQEAAAAAAAAAAAAAAAAABQQG/8QAJhEAAgAFAgUFAAAAAAAAAAAAAQIAAxEhQRIxEyJRYYFxkZKx4v/aAAwDAQACEQMRAD8AdYzK2IKFaK36uMbOswhjMMm3xrCCFPRsSh6nPPGpSFeZWQj0BOrmz8s46dor4tEoXXYY/OM9e8GpbccsryHKWZi7FjLHC4R9/JR7eAe40ioIAsfJv5vvEJNTWoPoLeLbRXK2DwtjBUHsYilK31++710Y7ugVzyPIcH9HB1m0mzFL6WI5nzDYkSiAdI2XHU394nuSo0YMjaggpwRxxzuiIkYCqoYgAAdgNOSHZpSkm9B9QbORVmMAMmP/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Вдохновляемся скинами из CS GO и клепаем следующий кринж. Хотели сортир в стиле скина \"Азимов\"? Я тоже нет, а он теперь есть и обществу придется с этим жить. Несмотря на всю кринжовость и лоск \"How Do You Do, Fellow Kids\" наклепал 15 скинов и некоторые мне даже нравятся.
Перед прохождением модерации пришлось подключаться к РСЯ (рекламная сеть яндекса) и заполнять бумажки. Делается все легко, учитывая, что самозанятость у меня уже открыта. На следующие сутки мой аккаунт прошел проверку и офферта была ацептована.
Тем не менее в консоли разработчика на вкладке \"Панель управления\" по прежнему горела красная ошибка о том, что монетизация не подключена, при этом я сделал все согласно их документации. Видимо это баг яндекса - но данная ошибка исчезает если один раз отправить игру на модерацию.
"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"Вместе с \"Игра не опубликована\" висело предупреждение, что \"Монетизация не подключена\"","image":{"type":"image","data":{"uuid":"12c27d3c-4c8c-596c-b682-8d22b2a4a312","width":1235,"height":318,"size":39840,"type":"png","color":"f3f1ed","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAEJ/8QAIhABAAECBAcAAAAAAAAAAAAAAQIAEQMEEjEFBiIyUZGi/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAL/xAAXEQEAAwAAAAAAAAAAAAAAAAAAESJh/9oADAMBAAIRAxEAPwDULDyuNLrngwjEe1G6eRJJVVjQSWdYyYnLvEZWbXCFn6qQ4WI6VL72oJpi7xPVB//Z"}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Я до последнего момента не был уверен что игра пройдет модерацию, потому что я не знаю примера успешной публикации 3D игры на Godot на Яндекс игры. Могло оказаться, что игра не работает в каком либо браузере или производительность игры окажется критичной и мне откажут.
Отправив игру на модерацию я ждал, что она затянется на 3-5 дней, но уже на следующий день мне пришел отказ в публикации. Модератор нашел несколько проблем:
"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Ошибки в переводе. Я забыл перевести магазин. На скриншотах для ру региона магазин тоже был с английским текстом.","Неправильный показ рекламы. Я показывал ее в момент проигрыша, что по мнению модерации прерывает игровой процесс. Поэтому я перенес показ рекламы при выходе в главное меню."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
С одной стороны я обрадовался, что игра оказалась вроде бы как рабочей и серьезных проблем не нашли.
Но с другой стороны я до сих пор не понимал как работает модерация. Что если они провели поверхностное исследование и при следующей отправке на модерацию они уже перейдут к следующим этапам и окажется что Godot не годен для Яндекс игр?
Опасения оказались верны, модерация не проверяет всю игру сразу, а видимо находит первые попавшиеся проблемы, отказывает и дальше игру не смотрит. В этот раз проблемы нашли следующие:
"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Гифка для промо материалов имеет артефакты сжатия.","В описании игры на русском языке (которое я сгенерировал нейронкой 🤡) имеются ошибки пунктуации и орфографии. Там действительно было поломано целое предложение и окончания у слов.","При показе рекламного баннера не выключается звук. Я упустил это из-за того, что перенес показ рекламы с момента смерти на выход в меню."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Почему на первые две проблемы не указали при прошлой проверке - для меня не понятно.
Не смотря на все, но с третьей попытки игру все таки опубликовали. Если среди комунити DTF есть такие же извращенцы как и я, то смело можете пытаться делать 3D игру на Godot для Яндекс игр.
"}},{"type":"link","cover":false,"hidden":false,"anchor":"","data":{"link":{"type":"link","data":{"url":"https://api.dtf.ru/v2.8/redirect?to=https%3A%2F%2Fyandex.ru%2Fgames%2Fapp%2F346969%3Flang%3Dru%23info&postId=2745138","title":"Шрек: Бесконечный Забег — Яндекс Игры","description":"Проверь свою ловкость в игре про любимого персонажа. Установи новый рекорд и соревнуйся с друзьями.","image":{"type":"image","data":{"uuid":"f1a89b7f-8b67-4ef5-91cd-df0eb734afde","width":180,"height":180,"size":1925,"type":"png","color":"fc0404","hash":"","external_service":[]}},"v":1,"hostname":"yandex.ru"}}}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"
Я уверен, что будут жалобы на производительность игры (и не только), поэтому я сомневаюсь, что стоит рекомендовать Godot для 3D HTML5 игр, но для 2D это отличный на мой взгляд выбор.
Тем не менее - мне есть чем гордиться - я засрал Яндекс игры очередной безыдейной кривой говно-подделкой паразитирующей на чужой интеллектуальной собственности и сделанной за месяц на коленке в после-рабочее время.
"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"0d514a51-b3fb-54cf-a4ba-ea6819b2009d","width":700,"height":522,"size":227194,"type":"png","color":"bcb5b3","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABgQH/8QAJBAAAQMDAgcBAAAAAAAAAAAAAQIDBAAFERJBExQhJDFTYXH/xAAXAQADAQAAAAAAAAAAAAAAAAADBAUC/8QAHxEAAQQBBQEAAAAAAAAAAAAAAQACAxEVIkFhkaHh/9oADAMBAAIRAxEAPwDX4sFqVDajXWQ5xXF6mi04CpDisAA53ztmlwGwPLTeobJ985nAkaG6Tv8APEjbs09CEo59k6QBlQaJP71omMi58SmXl46KlvoBMQkZIdSR8IUmqkjQSLCkROcAaKRibMwO7e8ew1uyg0F//9k="}}}]}}],"summaryContent":null,"isExistSummaryContent":false,"warningFromEditor":null,"warningFromEditorTitle":null,"counters":{"comments":20,"favorites":35,"reposts":0,"views":4938,"hits":4695,"reads":null,"online":0},"dateFavorite":0,"hitsCount":4695,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"isFavorited":false,"isPinned":false,"repostId":null,"repostData":null,"subscribedToTreads":false,"isEditorial":false,"isAudioAvailable":true,"audioUrl":null,"isAudioAvailableToGenerate":false,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"isBlur":false,"isPublished":true,"isDisabledAd":false,"withheld":[],"ogTitle":null,"ogDescription":null,"url":"https://dtf.ru/indie/2745138-seichas-my-budem-zanimatsya-shreksom-znakomstvo-s-godot-cherez-razrabotku-rannera-dlya-yandeks-igr","author":{"id":131399,"name":"Kaboms","nickname":null,"description":"Unreal Engine Developer","uri":"","avatar":{"type":"image","data":{"uuid":"4b49ba89-acb4-5eee-a384-121c6baeeefb","width":2160,"height":3840,"size":566426,"type":"jpg","color":"2d2c25","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAKAAoDASEAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABwII/8QAIRAAAgIBBAIDAAAAAAAAAAAAAQIDBBEABRIUBiETFTH/xAAWAQEBAQAAAAAAAAAAAAAAAAAFAAP/xAAcEQACAwADAQAAAAAAAAAAAAABEQACIQMFEnH/2gAMAwEAAhEDEQA/ACLwuTaaNF/Kdynkiljt9JKzwkcWZc8y2cY9EHSEjwyIJEKMrDIIPog6K7LhFfBA1bKr2Z4u3rv216n3LHWaVmaH5TwJH4eOcatLdoIALMwAGAA50hfU5utP2f/Z"}},"cover":{"cover":{"type":"image","data":{"uuid":"7e84a214-0bef-5c8a-98c7-33a1722a2e48","width":2560,"height":1600,"size":1031842,"type":"jpg","color":"131313","hash":"","external_service":[]}},"cover_y":0},"achievements":[{"title":"Год на DTF","code":"registration_1_year","description":"Первый год с DTF. Получена 2 июня 2025.","previewUuid":"d6655520-3ebc-52c3-8b92-696b019b5788","formats":{"glb":"https://static.dtf.ru/achievements/egg-01.glb","usdz":"https://static.dtf.ru/achievements/egg-01.usdz"},"viewData":{"contentColor":"#1F97D4","textMaxWidth":0.62890625,"textX":0.5,"textY":0.6943359375,"logoX":0.5,"logoY":0.818359375,"logoXNoText":0.5,"logoYNoText":0.6865234375},"id":1728456,"userId":131399,"count":0,"shareImage":"https://api.dtf.ru/achievements/share/1728456"},{"title":"5 лет на DTF","code":"registration_5_years","description":"Провёл 5 лет вместе с DTF. Получена 2 июня 2025.","previewUuid":"1cfb91f8-db3e-5624-9beb-4b71082eecc5","formats":{"glb":"https://static.dtf.ru/achievements/egg-02.glb","usdz":"https://static.dtf.ru/achievements/egg-02.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.625,"textX":0.5,"textY":0.533203125,"logoX":0.5,"logoY":0.6572265625,"logoXNoText":0.5,"logoYNoText":0.5390625},"id":123810,"userId":131399,"count":0,"shareImage":"https://api.dtf.ru/achievements/share/123810"}],"lastModificationDate":1763082716,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":true,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":false,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":64960,"name":"Инди","description":"Истории из жизни инди-разработчиков. Если вы делаете свою игру — это лучшее место, где о ней можно рассказать всему DTF.","uri":"/indie","avatar":{"type":"image","data":{"uuid":"044c3d8c-3200-4bdc-c4e3-40e99fec6777","width":0,"height":0,"size":0,"type":"jpg","color":"","hash":"","external_service":[]}},"cover":{"type":"image","data":{"uuid":"fa9323db-0b02-8abe-5ee4-ec31b8d32568","width":800,"height":450,"size":14309,"type":"jpg","color":"a454ef","hash":"","external_service":[]}},"lastModificationDate":1631402619,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"indie","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"reactions":{"counters":[{"id":1,"count":47}],"reactionId":0},"isNews":false,"source":null,"clusters":[],"donations":{"amount":0,"isDonated":false},"commentsSeenCount":null,"keywords":[],"media":{"type":"image","data":{"uuid":"0aa3fcf3-919e-52c6-92b0-f7cfcc800c56","width":1256,"height":706,"size":12253463,"type":"gif","color":"426e38","hash":"","external_service":[],"duration":20.866667,"isVideo":false,"has_audio":false}},"customCover":null,"robotsTag":null,"categories":[10],"isAnonymized":true}};